diff --git a/Kepler/.svn/all-wcprops b/Kepler/.svn/all-wcprops
new file mode 100644
index 0000000..b1e7a6f
--- /dev/null
+++ b/Kepler/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 50
+/guest/lhcb/!svn/ver/201951/Kepler/trunk/Tb/Kepler
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/188501/Kepler/trunk/Tb/Kepler/CMakeLists.txt
+END
diff --git a/Kepler/.svn/entries b/Kepler/.svn/entries
new file mode 100644
index 0000000..f0017f2
--- /dev/null
+++ b/Kepler/.svn/entries
@@ -0,0 +1,83 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:54:37.186085Z
+201951
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+python
+dir
+
+tests
+dir
+
+cmt
+dir
+
+doc
+dir
+
+Scripts
+dir
+
+options
+dir
+
+GangaPlugin
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+d8de70e4b74cdd797fd610f63ca1899c
+2015-05-19T11:48:07.231852Z
+188501
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+536
+
diff --git a/Kepler/.svn/text-base/CMakeLists.txt.svn-base b/Kepler/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..f161f24
--- /dev/null
+++ b/Kepler/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,17 @@
+################################################################################
+# Package: Kepler 
+################################################################################
+gaudi_subdir(Kepler v3r0)
+
+gaudi_depends_on_subdirs(Tb/TbAlgorithms
+                         Tb/TbIO
+                         Tb/TbKernel
+                         Gaudi
+                         GaudiConf
+                         GaudiKernel)
+
+gaudi_install_python_modules()
+
+gaudi_env(SET KEPLEROPTS \${KEPLERROOT}/options)
+
+gaudi_add_test(QMTest QMTEST)
diff --git a/Kepler/CMakeLists.txt b/Kepler/CMakeLists.txt
new file mode 100644
index 0000000..f161f24
--- /dev/null
+++ b/Kepler/CMakeLists.txt
@@ -0,0 +1,17 @@
+################################################################################
+# Package: Kepler 
+################################################################################
+gaudi_subdir(Kepler v3r0)
+
+gaudi_depends_on_subdirs(Tb/TbAlgorithms
+                         Tb/TbIO
+                         Tb/TbKernel
+                         Gaudi
+                         GaudiConf
+                         GaudiKernel)
+
+gaudi_install_python_modules()
+
+gaudi_env(SET KEPLEROPTS \${KEPLERROOT}/options)
+
+gaudi_add_test(QMTest QMTEST)
diff --git a/Kepler/GangaPlugin/.svn/all-wcprops b/Kepler/GangaPlugin/.svn/all-wcprops
new file mode 100644
index 0000000..7595982
--- /dev/null
+++ b/Kepler/GangaPlugin/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/guest/lhcb/!svn/ver/191710/Kepler/trunk/Tb/Kepler/GangaPlugin
+END
+PACKAGE.py
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/181040/Kepler/trunk/Tb/Kepler/GangaPlugin/PACKAGE.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/181040/Kepler/trunk/Tb/Kepler/GangaPlugin/__init__.py
+END
diff --git a/Kepler/GangaPlugin/.svn/entries b/Kepler/GangaPlugin/.svn/entries
new file mode 100644
index 0000000..6c6c174
--- /dev/null
+++ b/Kepler/GangaPlugin/.svn/entries
@@ -0,0 +1,99 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/GangaPlugin
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-07-11T15:08:56.796151Z
+191710
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+PACKAGE.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+a22dc58bad8f0b1505056a3ee94855a5
+2014-12-02T16:29:08.269559Z
+181040
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+945
+
+Lib
+dir
+
+__init__.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+d08ef8ba392e7331032bc5e459d1154a
+2014-12-02T16:29:08.269559Z
+181040
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+47
+
diff --git a/Kepler/GangaPlugin/.svn/prop-base/PACKAGE.py.svn-base b/Kepler/GangaPlugin/.svn/prop-base/PACKAGE.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/GangaPlugin/.svn/prop-base/PACKAGE.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/GangaPlugin/.svn/prop-base/__init__.py.svn-base b/Kepler/GangaPlugin/.svn/prop-base/__init__.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/GangaPlugin/.svn/prop-base/__init__.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/GangaPlugin/.svn/text-base/PACKAGE.py.svn-base b/Kepler/GangaPlugin/.svn/text-base/PACKAGE.py.svn-base
new file mode 100644
index 0000000..aa9cb40
--- /dev/null
+++ b/Kepler/GangaPlugin/.svn/text-base/PACKAGE.py.svn-base
@@ -0,0 +1,23 @@
+################################################################################
+# Ganga Project. http://cern.ch/ganga
+#
+# $Id: PACKAGE.py,v 1.2 2008-08-21 12:35:21 hclee Exp $
+################################################################################
+
+""" Refer to Ganga/PACKAGE.py for details on the purpose of this module.
+"""
+external_packages = {
+   'matplotlib' : {'version' : '0.99.0', 'PYTHONPATH':'lib/python2.5/site-packages'},
+   'numpy'      : {'version' : '1.3.0', 'PYTHONPATH':'lib/python2.5/site-packages', 'PATH' : 'bin'},
+   'pyqt'       : {'version' : '3.18.1_python2.5', 'PYTHONPATH':'lib/python2.5/site-packages', 'LD_LIBRARY_PATH' :'lib'}
+   }
+
+from Ganga.Utility.Setup import PackageSetup
+
+setup = PackageSetup(external_packages)
+
+def standardSetup(setup=setup):
+    for p in setup.packages:
+        setup.prependPath(p,'PYTHONPATH')
+        setup.prependPath(p,'LD_LIBRARY_PATH')
+        setup.prependPath(p,'PATH')
diff --git a/Kepler/GangaPlugin/.svn/text-base/__init__.py.svn-base b/Kepler/GangaPlugin/.svn/text-base/__init__.py.svn-base
new file mode 100644
index 0000000..0922e46
--- /dev/null
+++ b/Kepler/GangaPlugin/.svn/text-base/__init__.py.svn-base
@@ -0,0 +1,2 @@
+def loadPlugins( config = {} ):
+    import Lib
diff --git a/Kepler/GangaPlugin/Lib/.svn/all-wcprops b/Kepler/GangaPlugin/Lib/.svn/all-wcprops
new file mode 100644
index 0000000..92f18ae
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/all-wcprops
@@ -0,0 +1,65 @@
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/191710/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib
+END
+TbFileChecker.py
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/188391/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbFileChecker.py
+END
+TbDataset.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/188391/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbDataset.py
+END
+TbQuery.py
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/185115/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbQuery.py
+END
+TbStack.py
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/191710/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbStack.py
+END
+RecursiveSearch.py
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/181396/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/RecursiveSearch.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/188391/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/__init__.py
+END
+TbEosUpload.py
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/188391/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbEosUpload.py
+END
+TbMetaAnalysisMerger.py
+K 25
+svn:wc:ra_dav:version-url
+V 90
+/guest/lhcb/!svn/ver/181576/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbMetaAnalysisMerger.py
+END
+TbMetaAnaylsisMerger.py
+K 25
+svn:wc:ra_dav:version-url
+V 90
+/guest/lhcb/!svn/ver/181040/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/TbMetaAnaylsisMerger.py
+END
+KeplerApp.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/181040/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib/KeplerApp.py
+END
diff --git a/Kepler/GangaPlugin/Lib/.svn/entries b/Kepler/GangaPlugin/Lib/.svn/entries
new file mode 100644
index 0000000..0ed06cd
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/entries
@@ -0,0 +1,368 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/GangaPlugin/Lib
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-07-11T15:08:56.796151Z
+191710
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbFileChecker.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+9877f074e227de4fd9e67bfb8c9719db
+2015-05-18T12:16:24.810119Z
+188391
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3232
+
+TbDataset.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+57153a9055dd95cfd2939c4ef7f1610f
+2015-05-18T12:16:24.810119Z
+188391
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3464
+
+TbQuery.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+3eb40edad33fad63942ce363c1a2800d
+2015-03-09T15:49:35.540995Z
+185115
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1229
+
+TbStack.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+90aba4190c4e51d2acb2d6529e02d1da
+2015-07-11T15:08:56.796151Z
+191710
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3250
+
+RecursiveSearch.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+b785c3ae5adb84bac44d20c16f4bf2e5
+2014-12-11T15:21:40.788791Z
+181396
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1070
+
+__init__.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+3adb378dac75e00c28bd559ff88c86d6
+2015-05-18T12:16:24.810119Z
+188391
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+180
+
+TbEosUpload.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+81ae5fdb3bf653d5b970f24c894c52a1
+2015-05-18T12:16:24.810119Z
+188391
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1949
+
+TbMetaAnalysisMerger.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+44c355cc03164fe34ee604d73efabee5
+2014-12-14T09:02:44.425677Z
+181576
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5236
+
+TbMetaAnaylsisMerger.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+8641e9f43602a6b190facf59a71fe489
+2014-12-02T16:29:08.269559Z
+181040
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1128
+
+KeplerApp.py
+file
+
+
+
+
+2016-05-09T14:27:50.000000Z
+04fe1424bcc16a11db267fb5ce8026e8
+2014-12-02T16:29:08.269559Z
+181040
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10755
+
diff --git a/Kepler/GangaPlugin/Lib/.svn/prop-base/TbStack.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/prop-base/TbStack.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/prop-base/TbStack.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/GangaPlugin/Lib/.svn/prop-base/__init__.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/prop-base/__init__.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/prop-base/__init__.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/KeplerApp.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/KeplerApp.py.svn-base
new file mode 100644
index 0000000..00e014e
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/KeplerApp.py.svn-base
@@ -0,0 +1,242 @@
+## Note that the special string AppName will be replaced upon initialisation
+## in all cases with the relavent app name (DaVinci, Gauss etc...)
+import os, tempfile, pprint, sys
+from GangaGaudi.Lib.Applications.Gaudi import Gaudi
+from GangaGaudi.Lib.Applications.GaudiUtils import fillPackedSandbox
+from GangaLHCb.Lib.Applications.AppsBaseUtils import available_apps, guess_version, available_packs
+from GangaLHCb.Lib.Applications.AppsBaseUtils import backend_handlers, activeSummaryItems
+from Ganga.GPIDev.Lib.File.FileBuffer import FileBuffer
+from Ganga.GPIDev.Base.Proxy import GPIProxyObjectFactory
+from Ganga.GPIDev.Schema import *
+from Ganga.Utility.Shell import Shell
+from GangaLHCb.Lib.Applications.PythonOptionsParser import PythonOptionsParser
+from Ganga.GPIDev.Adapters.StandardJobConfig import StandardJobConfig
+from Ganga.Utility.Config import getConfig
+from Ganga.Utility.files import expandfilename
+from Ganga.Utility.execute import execute
+import Ganga.Utility.logging
+import GangaLHCb.Lib.Applications.CMTscript
+import pickle
+import subprocess
+from GangaLHCb.Lib.Applications import XMLPostProcessor
+from Ganga.Core.exceptions import ApplicationConfigurationError
+
+logger = Ganga.Utility.logging.getLogger()
+
+class Kepler(Gaudi):
+    _name = 'Kepler'
+    _category = 'applications'
+    #__doc__ = GaudiDocString('AppName')
+    _schema = Gaudi._schema.inherit_copy()
+    docstr = 'The package the application belongs to (e.g. "Sim", "Phys")'
+    _schema.datadict['package'] = SimpleItem(defvalue=None,
+                                             typelist=['str','type(None)'],
+                                             doc=docstr)
+    docstr = 'The package where your top level requirements file is read '  \
+             'from. Can be written either as a path '  \
+             '\"Tutorial/Analysis/v6r0\" or in a CMT style notation '  \
+             '\"Analysis v6r0 Tutorial\"'
+    _schema.datadict['masterpackage'] = SimpleItem(defvalue=None,
+                                                   typelist=['str','type(None)'],
+                                                   doc=docstr)
+    _schema.datadict['platform'] = SimpleItem( defvalue="x86_64-slc6-gcc48-opt" )
+    docstr = 'Extra options to be passed onto the SetupProject command '\
+             'used for configuring the environment. As an example '\
+             'setting it to \'--dev\' will give access to the DEV area. '\
+             'For full documentation of the available options see '\
+             'https://twiki.cern.ch/twiki/bin/view/LHCb/SetupProject'
+    _schema.datadict['setupProjectOptions'] = SimpleItem(defvalue='',
+                                                         typelist=['str','type(None)'],
+                                                         doc=docstr)    
+    _exportmethods = Gaudi._exportmethods[:]
+    _exportmethods += ['readInputData']
+    
+    def _get_default_version(self, gaudi_app):
+        return guess_version(gaudi_app)
+    
+               
+    def _auto__init__(self):
+        self.appname='Kepler'
+      #  super(self.appname, self)._auto__init__()
+
+    def postprocess(self):
+        XMLPostProcessor.postprocess(self,logger)
+
+    def readInputData(self,optsfiles,extraopts=False):
+        def dummyfile():
+            temp_fd,temp_filename=tempfile.mkstemp(text=True,suffix='.py')
+            os.write(temp_fd,"Dummy file to keep the Optionsparser happy")
+            os.close(temp_fd)
+            return temp_filename
+
+        if type(optsfiles)!=type([]): optsfiles=[optsfiles]
+        
+        if len(optsfiles)==0: optsfiles.append(dummyfile())
+        
+        if extraopts: extraopts=self.extraopts
+        
+        else: extraopts=""
+            
+       # parser = check_inputs(optsfiles, extraopts, self.env) 
+        try:
+            parser = PythonOptionsParser(optsfiles,extraopts,self.getenv(False))
+        except Exception, e:
+            msg = 'Unable to parse the job options. Please check options ' \
+                  'files and extraopts.'
+            raise ApplicationConfigurationError(None,msg)
+
+        return GPIProxyObjectFactory(parser.get_input_data())
+
+    def getpack(self, options=''):
+        """Performs a getpack on the package given within the environment
+           of the application. The unix exit code is returned
+        """
+        command = 'getpack ' + options + '\n'
+        if options == '':
+            command = 'getpack -i'
+        return CMTscript.CMTscript(self,command)
+        
+    def make(self, argument=None):
+        """Performs a CMT make on the application. The unix exit code is 
+           returned. Any arguments given are passed onto CMT as in
+           dv.make('clean').
+        """
+        config = Ganga.Utility.Config.getConfig('GAUDI')
+        command = config['make_cmd']
+        if argument:
+            command+=' '+argument
+        return CMTscript.CMTscript(self,command)
+
+    def cmt(self, command):
+        """Execute a cmt command in the cmt user area pointed to by the
+        application. Will execute the command "cmt <command>" after the
+        proper configuration. Do not include the word "cmt" yourself. The 
+        unix exit code is returned."""
+        command = '###CMT### ' + command
+        return CMTscript.CMTscript(self,command)
+
+    def _getshell(self):
+        opts = ''
+        if self.setupProjectOptions: opts = self.setupProjectOptions
+
+        fd = tempfile.NamedTemporaryFile()
+        script = '#!/bin/sh\n'
+        if self.user_release_area:
+            script += 'User_release_area=%s; export User_release_area\n' % \
+                      expandfilename(self.user_release_area)
+        if self.platform:    
+            script += '. `which LbLogin.sh` -c %s\n' % self.platform
+        useflag = ''
+        cmd = '. SetupProject.sh %s %s %s %s' % (useflag, opts, self.appname, self.version) 
+        script += '%s \n' % cmd
+        fd.write(script)
+        fd.flush()
+        logger.debug(script)
+
+        self.shell = Shell(setup=fd.name)
+        if (not self.shell): raise ApplicationConfigurationError(None,'Shell not created.')
+        
+        logger.debug(pprint.pformat(self.shell.env))
+        
+        fd.close()
+        app_ok = False
+        ver_ok = False
+        for var in self.shell.env:
+            if var.find(self.appname) >= 0: app_ok = True
+            if self.shell.env[var].find(self.version) >= 0: ver_ok = True
+        if not app_ok or not ver_ok:
+            msg = 'Command "%s" failed to properly setup environment.' % cmd
+            logger.error(msg)
+            raise ApplicationConfigurationError(None,msg)
+
+        import copy
+        self.env = copy.deepcopy( self.shell.env )
+
+        return self.shell.env
+
+
+    def _get_parser(self):
+        optsfiles = [fileitem.name for fileitem in self.optsfile]
+        # add on XML summary
+
+        extraopts = ''
+        if self.extraopts:
+            extraopts += self.extraopts
+            
+        try:
+            parser = PythonOptionsParser(optsfiles,extraopts,self.getenv(False))
+        except ApplicationConfigurationError, e:
+            # fix this when preparing not attached to job
+            
+            msg2=''
+            try:
+                debug_dir = self.getJobObject().getDebugWorkspace().getPath()
+                msg2+='You can also view this from within ganga '\
+                       'by doing job.peek(\'../debug/gaudirun.<whatever>\').'
+            except:
+                debug_dir = tempfile.mkdtemp()
+                    
+            messages = e.message.split('###SPLIT###')
+            if len(messages) is 2:
+                stdout = open(debug_dir + '/gaudirun.stdout','w')
+                stderr = open(debug_dir + '/gaudirun.stderr','w')
+                stdout.write(messages[0])
+                stderr.write(messages[1])
+                stdout.close()
+                stderr.close()
+                msg = 'Unable to parse job options! Please check options ' \
+                      'files and extraopts. The output and error streams from gaudirun.py can be ' \
+                      'found in %s and %s respectively . ' % (stdout.name, stderr.name)
+            else:
+                f = open(debug_dir + '/gaudirun.out','w')
+                f.write(e.message)
+                f.close()
+                msg = 'Unable to parse job options! Please check options ' \
+                      'files and extraopts. The output from gaudirun.py can be ' \
+                      'found in %s . ' % f.name
+            msg+=msg2
+            # logger.error(msg)
+            raise ApplicationConfigurationError(None,msg)
+        return parser
+
+
+    def _parse_options(self):
+        try:
+            parser = self._get_parser()
+        except ApplicationConfigurationError, e:
+            raise e
+
+        share_dir = os.path.join(expandfilename(getConfig('Configuration')['gangadir']),
+                                 'shared',
+                                 getConfig('Configuration')['user'],
+                                 self.is_prepared.name)
+        fillPackedSandbox([FileBuffer('options.pkl',parser.opts_pkl_str)],
+                          os.path.join(share_dir,
+                                       'inputsandbox',
+                                       '_input_sandbox_%s.tar' % self.is_prepared.name))
+        inputdata = parser.get_input_data()
+        if len(inputdata.files) > 0:
+            logger.warning('Found inputdataset defined in optsfile, '\
+                           'this will get pickled up and stored in the '\
+                           'prepared state. Any change to the options/data will '\
+                           'therefore require an unprepare first.')
+            logger.warning('NOTE: the prefered way of working '\
+                           'is to define inputdata in the job.inputdata field. ')
+            logger.warning('Data defined in job.inputdata will superseed optsfile data!')
+            logger.warning('Inputdata can be transfered from optsfiles to the job.inputdata field '\
+                           'using job.inputdata = job.application.readInputData(optsfiles)')
+            share_path = os.path.join(share_dir,'inputdata')
+            if not os.path.isdir(share_path): os.makedirs(share_path)
+            f=open(os.path.join(share_path,'options_data.pkl'),'w+b')
+            pickle.dump(inputdata, f)
+            f.close()
+
+        share_path = os.path.join(share_dir,'output')
+        if not os.path.isdir(share_path): os.makedirs(share_path)
+        f=open(os.path.join(share_path,'options_parser.pkl'),'w+b')
+        pickle.dump(parser, f)
+        f.close()
+
+from Ganga.GPIDev.Adapters.ApplicationRuntimeHandlers import allHandlers
+for (backend, handler) in backend_handlers().iteritems():
+    allHandlers.add('Kepler', backend, handler)
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/RecursiveSearch.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/RecursiveSearch.py.svn-base
new file mode 100644
index 0000000..ae70ab9
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/RecursiveSearch.py.svn-base
@@ -0,0 +1,35 @@
+from ROOT import *
+
+def RecursiveSearch( directory , histograms, maxDepth, path="", depth=0 ):
+  if type( directory ) is not TDirectoryFile :
+    if type( directory) is not TFile :
+      if type( directory ) is TH1D :
+        histograms.append( path[:-1]  )
+      return
+        
+  if depth > maxDepth : return
+  
+  for i in range(0,directory.GetListOfKeys().GetEntries()):
+    obj = directory.GetListOfKeys().At(i)
+    RecursiveSearch( directory.Get( obj.GetName()) , histograms,maxDepth, path + obj.GetName() + "/" , depth+1)
+    
+  return
+
+def makeDirectories( filename, objects):
+  for x in objects:
+    output = TFile.Open(filename,'UPDATE')
+    directories = x.split('/')
+    output.cd() 
+    layer = output
+    path = ""
+    for ind in range( 0, len(directories) -1 ) :
+      tmpKey = layer.FindKey( directories[ind] )
+      if not tmpKey  :
+        foo = layer.mkdir( directories[ind], directories[ind] )
+        layer.cd()
+        foo.Write()
+        layer.Write()
+        layer = foo
+      else : layer = tmpKey.ReadObj()
+    output.Close("R")
+    del output 
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbDataset.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbDataset.py.svn-base
new file mode 100644
index 0000000..82897b2
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbDataset.py.svn-base
@@ -0,0 +1,98 @@
+from Ganga.GPIDev.Adapters.ISplitter import ISplitter
+from Ganga.GPIDev.Schema import *
+from TbQuery import TbQuery
+from collections import defaultdict
+from Ganga.GPIDev.Base.Proxy import addProxy, stripProxy
+
+class TbDataset(ISplitter):
+  _name = "TbDataset"
+  _schema = Schema(Version(1,0), {
+  'filesPerJob' : SimpleItem(defvalue=1),
+  'maxFiles' : SimpleItem(defvalue=1),
+  'ignoremissing': SimpleItem(defvalue=False),
+  'Files' : SimpleItem(defvalue={}),
+  'AlignmentFiles' : SimpleItem(defvalue={}),
+  'PixelConfigFiles' : SimpleItem(defvalue={}),
+  'TimingConfigFiles' : SimpleItem(defvalue={}),
+  'Month' : SimpleItem(defvalue=""),
+  'run' : SimpleItem(defvalue=0),
+  'prefix' : SimpleItem(defvalue=""),
+  'AutoConfig' : SimpleItem(defvalue=True) })
+  _exportmethods = [ 'split','optionsString' ]   
+    
+  def split(self,job):
+    from Ganga.GPIDev.Lib.Job import Job
+   
+    subjobs = []
+    for run in self.Files.keys():
+      j = addProxy(self.createSubjob(job))
+#      j.splitter = None
+#      j.merger = None
+      jp = stripProxy(j)
+      jp._splitter_data = self.optionsString(run)
+      subjobs.append(jp)
+      
+    print "Submitting jobs for %d runs" %( len(subjobs))
+    return subjobs
+  
+  def __construct__(self,args):
+    if len( args ) == 0 : return 
+    self.Month = args[0]
+    for r in args[1]:
+      query = TbQuery()
+      query.Month = self.Month
+      query.Run = r
+      print "Looking for %s/Run%d" %(self.Month, r )
+      files = query.getFiles()
+      if len(files) != 0 : self.Files[r] = []
+      for f in files:
+        self.Files[r].append(f)
+      
+      if self.AutoConfig:
+        config_files = query.getConfiguration()
+        alignment_file = ""
+        for f in config_files:
+          if f.find("Alignment") != -1:
+            if alignment_file != "": alignment_file = f
+            elif f.find("mille") != -1: alignment_file = f
+           # elif f.find(self.prefix) != -1 : alignment_file = f
+          elif f.find("PixelConfig") != -1:
+            if r not in self.PixelConfigFiles.keys():
+              self.PixelConfigFiles[r] = []
+            self.PixelConfigFiles[r].append(f)
+          elif f.find("TimingConfig") != -1: self.TimingConfigFiles[r] = f
+        if alignment_file != "" : self.AlignmentFiles[r] = alignment_file
+      
+      
+  def optionsString(self, run):
+  
+    files_for_this_run = self.Files[run]
+    if len( files_for_this_run ) == 0 :
+      return ""
+    output = "from Configurables import TbDataSvc \n"
+    output += "TbDataSvc().Input = ['" + files_for_this_run[0] +"'"
+  
+    for f in range(1, len(files_for_this_run)):
+        output += ",'"+files_for_this_run[f]+"'"
+    output += "]"
+    # now add the configuration files ... 
+    if self.AutoConfig:
+      pixel_config = []
+      if run in self.PixelConfigFiles.keys() : 
+        pixel_config = self.PixelConfigFiles[run]
+        output+= " \nTbDataSvc().PixelConfigFile += ['" + pixel_config[0] +"'"
+        for f in range(1,len(pixel_config)):
+          output += ",'"+pixel_config[f]+"'"
+        output += "]"
+      timing_config = ""
+      if run in self.TimingConfigFiles.keys() :
+        timing_config = self.TimingConfigFiles[run]
+        output += " \nTbDataSvc().TimingConfigFile = '%s'" %(timing_config)
+        
+      alignment = ""
+      if run in self.AlignmentFiles.keys() : 
+        alignment = self.AlignmentFiles[run]
+        output += " \nTbDataSvc().AlignmentFile = '%s'" %(alignment)
+      
+    return output
+  
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbEosUpload.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbEosUpload.py.svn-base
new file mode 100644
index 0000000..0e40703
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbEosUpload.py.svn-base
@@ -0,0 +1,45 @@
+
+
+from Ganga.GPIDev.Schema import *
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Schema import *
+from Ganga.GPIDev.Adapters.IPostProcessor import IPostProcessor
+import os
+
+class TbEosUpload(IPostProcessor):
+
+  _schema = IPostProcessor._schema.inherit_copy()
+  _schema.datadict['files'] = SimpleItem(defvalue=[], doc='Files to upload')
+  _schema.datadict['prefix'] = SimpleItem(defvalue="",doc='Prefix to uploaded file')
+  _category = 'postprocessor'
+  _name = 'TbEosUpload'
+  _exportmethods = ['execute']
+
+
+  def execute(self,job,newstatus):
+    eos_cp="/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select cp"
+    counter=0
+    for run in job.splitter.Files.keys():
+      j=job.subjobs(counter)
+      if j.status == 'completed':
+        rootpath = "/eos/lhcb/testbeam/velo/timepix3/%s/RootFiles/Run%d/" %( job.splitter.Month, run )
+        if 'Alignment' in self.files:
+          source="%sAlignment_out.dat" %( j.outputdir )
+          if os.path.isfile( source ): 
+            sink="%sConditions/%sAlignment%dmille.dat" %(rootpath, self.prefix, run )
+            os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+          else : print source + " does not exist"
+        if 'Tuple' in self.files:
+          source="%sKepler-tuple.root" %( j.outputdir )
+          sink="%sOutput/%sKepler-tuple-%d.root" %(rootpath, self.prefix, run )
+          os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+        if 'Histograms' in self.files:
+          source="%sKepler-histos.root" %( j.outputdir )
+          sink="%sOutput/%sKepler-histos-%d.root" %(rootpath,self.prefix, run )
+          os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+        if 'TimingConfig' in self.files:
+          source="%sTimingConfig.dat" %( j.outputdir )
+          sink = "%sConditions/%sTimingConfig.dat" %(rootpath,self.prefix)
+          os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+      counter = counter + 1 
+    return True
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbFileChecker.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbFileChecker.py.svn-base
new file mode 100644
index 0000000..06dfa10
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbFileChecker.py.svn-base
@@ -0,0 +1,97 @@
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Adapters.IPostProcessor import PostProcessException, IPostProcessor
+from Ganga.GPIDev.Base.Proxy import GPIProxyObject
+from Ganga.GPIDev.Schema import ComponentItem, FileItem, Schema, SimpleItem, Version
+from Ganga.Utility.Config import makeConfig, ConfigError, getConfig
+from Ganga.Utility.Plugin import allPlugins
+from Ganga.Utility.logging import getLogger, log_user_exception
+import commands
+import copy
+import os
+import string
+import re
+
+class TbFileChecker(IPostProcessor):
+
+  _schema = IPostProcessor._schema.inherit_copy()
+  _schema.datadict["alignment"] = SimpleItem(False)
+  _schema.datadict["resubmit"] = SimpleItem(False) #resubmit items with no output in the errorsummary
+  _category = 'postprocessor'
+  _name = 'TbFileChecker'
+  _exportmethods = ['check','ErrorSummary']
+
+  def check(self,job):
+
+    job_objects = []
+    if len( job.subjobs ) != 0:
+      for j in job.subjobs:
+        job_objects.append(j)
+    else: job_objects.append( job )
+    result = True
+    for j in job_objects:
+      job_success = False
+      filepath = "%s/stdout" %(j.outputdir)
+     #print "Checking %d subjobs " %( len(job_objects ) )
+      if j.status != "completed": continue
+      if self.alignment:
+
+        if not os.path.isfile( j.outputdir + "Alignment_out.dat" ):
+          job_success = False
+          j.force_status('failed')
+          continue
+
+      if not os.path.isfile( filepath ): continue
+      f = reversed( open(filepath,'r').readlines() )
+      for line in f:	
+        if re.search("ApplicationMgr       INFO Application Manager Finalized successfully",line):
+          job_success = True
+          break
+      if job_success: j.force_status('completed')
+      else : j.force_status('failed')
+      result = result*job_success
+    return result 
+ 
+  def ErrorSummary(self,job):
+    job_objects = []
+    minuit_exceptions = ["MATRIX","DERIVATIVE","VALUE"] 
+    millepede_exceptions = ["Initial","Negative","diagonal"]
+    for j in job.subjobs:
+      if j.status == 'failed': job_objects.append(j)
+    for j in job_objects:
+      filepath = "%s/stdout" %(j.outputdir)
+      error = "Unknown"
+      if os.path.isfile( filepath ):
+        for line in open(filepath,'r').readlines():
+          if re.search("ERROR",line):
+            found = False
+            for e in minuit_exceptions: 
+              if re.search(e,line): 
+                found = True
+                break
+            if found : continue
+            error = line[:-1]
+            break
+          if re.search("error",line):
+            found = False
+            for e in millepede_exceptions: 
+              if re.search(e,line): 
+                found = True
+                break
+            if found : continue
+
+            error = line[:-1]
+            break
+          if re.search("Error",line):
+            found = False
+            for e in millepede_exceptions: 
+              if re.search(e,line): 
+                found = True
+                break
+            if found : continue
+
+            error = line[:-1]
+            break
+      else: 
+        error = "No output files"
+        if self.resubmit: j.resubmit()
+      print "%s (%d.%3d) : %s" %( j.name, job.id, j.id, error ) 
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbMetaAnalysisMerger.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbMetaAnalysisMerger.py.svn-base
new file mode 100644
index 0000000..cb1706d
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbMetaAnalysisMerger.py.svn-base
@@ -0,0 +1,177 @@
+from ROOT import *
+from RecursiveSearch import RecursiveSearch, makeDirectories
+import os
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Base.Proxy import GPIProxyObjectFactory
+from Ganga.GPIDev.Schema import *
+import operator
+
+class TbBinning2D :
+  name = ""
+  title = ""
+  minY = 0
+  widthY = 0
+  nBinsY = 0
+  minX = 0 
+  widthX = 0 
+  nBinsX = 0 
+  maxX = 0 
+  maxY = 0 
+  path = ""
+  def __init__(self,name,title,path,minX,widthX,nBinsX,minY,widthY,nBinsY) :
+    self.name = name
+    self.title = title
+    self.path = path
+    self.minX = minX
+    self.widthX = widthX
+    self.nBinsX = nBinsX
+    self.minY = minY
+    self.widthY = widthY
+    self.nBinsY = nBinsY
+    self.maxX = self.minX + self.nBinsX*self.widthX
+    self.maxY = self.minY + self.nBinsY*self.widthY
+   
+class TbProfile :
+  path = ""
+  title = ""
+  name = ""
+  def __init__(self,name,title,path):
+    self.title = title
+    self.path = path
+    self.name = name
+  
+
+class TbMetaAnalysisMerger(GangaObject):
+
+  _category = 'postprocessor'
+  _exportmethods = ['merge']
+  _name = 'TbMetaAnalysisMerger'
+  f2L = {}
+  _schema = Schema(Version(1,0), {
+    'Mode' : SimpleItem(defvalue="Profile"),
+    'Output' : SimpleItem(defvalue="Kepler-Meta-Histos.root"),
+    'Top' : SimpleItem(defvalue=[]),
+    'Labels' : SimpleItem(defvalue={})
+  })
+
+  def write2D( self, files, hists ):
+    prev_path = ""
+    for h in hists:
+      if h.path != prev_path :
+        print "Making histogram for: %s" %h.path
+        prev_path = h.path
+      out_file = TFile.Open(self.Output,'UPDATE')
+      hist = TH2D( h.name, h.title, h.nBinsX, h.minX, h.maxX, h.nBinsY, h.minY, h.maxY )
+      for f in files:
+        in_file = TFile(f ,'READ')
+        obj = in_file.Get(h.path +"/"+ h.name )
+        if obj :
+          if obj.GetEntries() != 0: obj.Scale(1/obj.GetEntries());
+          for l in range(0, obj.GetNbinsX() ):
+            hist.SetBinContent( self.f2L[f] - h.minX, l, obj.GetBinContent(l) )
+          del obj
+        else :
+          print "ERROR: %s not found in %s" %(h.path + "/" + h.name,f)
+        in_file.Close("R")
+        del in_file
+      out_file.cd(h.path)      
+      hist.Write()
+      out_file.Close("R")
+      del out_file
+ 
+  def write1D( self, files, graphs) :
+    means = []
+    sigmas = []
+    sorted_f2L = sorted(self.f2L.items(), key=operator.itemgetter(1))
+    p = 0
+    n = {}
+    for f in sorted_f2L:
+      print f
+      n[f[0]] = p
+      p = p + 1
+      
+    print n
+    for g in graphs:
+      mean = TGraphErrors()
+      mean.SetNameTitle( g.name + "_m", g.title)
+      sigma = TGraphErrors()
+      sigma.SetNameTitle( g.name + "_s", g.title)
+      means.append( mean)
+      sigmas.append( sigma )
+  
+    for f in files:
+      in_file = TFile(f,'READ')
+      for x in range(0,len(graphs)):
+        print "Making histogram for: %s" %(g.path + "/" + g.name)
+        g = graphs[x]
+        obj = in_file.Get( g.path + "/" + g.name )
+        if obj :
+         if( obj.GetEntries() != 0 ):
+            means[x].SetPoint( n[f] , self.f2L[f] , obj.GetMean() )
+            sigmas[x].SetPoint( n[f], self.f2L[f] , obj.GetRMS() )
+            means[x].SetPointError( n[f] , 0 , obj.GetRMS()/sqrt(obj.GetEntries()) )
+            sigmas[x].SetPointError( n[f], 0 , obj.GetRMS()/sqrt(obj.GetEntries()) )
+      in_file.Close("R")
+      del in_file
+    out_file = TFile.Open(self.Output,'UPDATE')
+
+    for g in range(0,len(graphs)):
+      out_file.cd(graphs[g].path)
+      means[g].Write()
+      sigmas[g].Write()
+    out_file.Close()
+  
+  
+  def merge(self, list ):
+    
+    file0 = TFile() 
+    found = False
+    files = []
+    
+    for j in list:
+      if j.status == 'completed':
+        fname = j.outputdir + "/Kepler-histos.root"
+        if os.path.isfile(fname) :
+          if found == False :
+            file0 = TFile(fname ,'READ')
+            found = True
+          files.append(fname)
+          if j.inputdata.run in self.Labels : 
+            self.f2L[fname] = self.Labels[j.inputdata.run]
+          else : 
+            self.f2L[fname] = j.inputdata.run
+      
+    all_histograms = []
+    print "Searching for histograms..."
+    RecursiveSearch( file0, all_histograms , 7 )
+    histograms = []
+    for x in all_histograms: 
+      for t in self.Top:
+        if x.find(t) != -1 : 
+          if x not in histograms : histograms.append(x)
+      
+    hists = []
+    graphs = []
+    print "Building histogram objects..."
+    for x in histograms:
+      obj = file0.Get( x )
+      k = x.rfind('/')
+      if self.Mode == "Profile":
+        profile = TbProfile(x[k+1:], obj.GetTitle(), x[:k] )
+        graphs.append( profile )
+      if self.Mode == "2D":
+        Runs = job.inputdata.Runs
+        hists.append( TbBinning2D( x[k+1:],obj.GetTitle(),x[:k],Runs[0],1,Runs[len(Runs)-1] - Runs[0] +1,
+                       obj.GetBinLowEdge(0), obj.GetBinWidth(0), obj.GetNbinsX() ) )
+        
+    file0.Close()
+    del file0
+    
+    output = TFile.Open(self.Output,'RECREATE')
+    output.Close("R")
+    del output
+    makeDirectories( self.Output, histograms )
+    print "Filling %d histograms / graphs" %(len( hists ) + len(graphs ) )
+    if self.Mode == "2D": self.write2D( files, hists )
+    if self.Mode == "Profile": self.write1D( files, graphs )
+    
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbMetaAnaylsisMerger.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbMetaAnaylsisMerger.py.svn-base
new file mode 100644
index 0000000..5bd7cd3
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbMetaAnaylsisMerger.py.svn-base
@@ -0,0 +1,56 @@
+from ROOT import *
+from RecursiveSearch import RecursiveSearch
+
+ # main programme 
+ 
+
+
+all_histograms = []
+RecursiveSearch( f, all_histograms , 5 )
+
+output = TFile('Meta-graphs.root','RECREATE')
+
+# clone the directory structure
+
+for x in all_histograms:
+  directories = x.split('/')
+  layer = output
+  path = ""
+  for ind in range( 0, len(directories) -1 ) :
+    tmpKey = layer.FindKey( directories[ind] )
+    if not tmpKey  :
+      foo = layer.mkdir( directories[ind], directories[ind] )
+      layer.cd()
+      foo.Write()
+      layer.Write()
+      layer = foo
+    else : layer = tmpKey.ReadObj() 
+
+output.Write()
+
+output.Close()
+
+output = TFile('Meta-graphs.root','UPDATE')
+
+for x in all_histograms:
+  obj = f.Get( x )
+
+  k = x.rfind('/')
+  path = x[:k]
+  name = x[k+1:]
+  output.cd( path )
+
+  graph_mean = TGraph( )
+  graph_mean.SetNameTitle( name + "_mean" , obj.GetTitle() )
+  graph_mean.SetPoint( graph_mean.GetN() , 0, obj.GetMean() )
+  graph_mean.Write()
+
+  graph = TGraph( )
+  graph.SetNameTitle( name + "_sigma" , obj.GetTitle() )
+  graph.SetPoint( graph.GetN() , 0, obj.GetRMS() )
+  graph.Write()
+
+
+
+output.Write()
+  
\ No newline at end of file
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbQuery.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbQuery.py.svn-base
new file mode 100644
index 0000000..d4f42f0
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbQuery.py.svn-base
@@ -0,0 +1,39 @@
+
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Base.Proxy import GPIProxyObjectFactory
+from Ganga.GPIDev.Schema import *
+
+def ListFiles( path ,extension) :
+  import subprocess
+  proc = subprocess.Popen(["/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select","ls",path],stdout=subprocess.PIPE)
+  out=""
+  err=""
+  files = []
+  (out,err) = proc.communicate()
+  files = out.split('\n')
+  output = []
+  for f in files:
+    if f.find(extension) != -1:
+      output.append( path + f)
+  return output
+  
+class TbQuery( GangaObject ) :
+  path = ""
+  _schema = Schema(Version(1,0), {
+        'Month' : SimpleItem(defvalue='',doc='Testbeam period to look for data'),
+        'Run' : SimpleItem(defvalue=0,doc='Run to look at')
+        } )
+  _name = "TbQuery"
+  _exportmethods = ['getOptions','getFiles']
+  _category = 'query'
+  _data = ''
+          
+  def getFiles(self):
+    path = "eos/lhcb/testbeam/velo/timepix3/%s/RawData/Run%d/" %( self.Month, self.Run )
+    return ListFiles(path,".dat")
+    
+  def getConfiguration(self):
+    path = "eos/lhcb/testbeam/velo/timepix3/%s/RootFiles/Run%d/Conditions/" %(self.Month,self.Run)
+    return ListFiles(path,".dat")
+  _exportmethods = ['getConfiguration','getFiles']
+    
\ No newline at end of file
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/TbStack.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/TbStack.py.svn-base
new file mode 100644
index 0000000..27d89d1
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/TbStack.py.svn-base
@@ -0,0 +1,93 @@
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Adapters.IPostProcessor import PostProcessException, IPostProcessor
+from Ganga.GPIDev.Base.Proxy import GPIProxyObject
+from Ganga.GPIDev.Schema import ComponentItem, FileItem, Schema, SimpleItem, Version
+from Ganga.Utility.Config import makeConfig, ConfigError, getConfig
+from Ganga.Utility.Plugin import allPlugins
+from Ganga.Utility.logging import getLogger, log_user_exception
+import commands
+import copy
+import os
+import string
+import re
+from ROOT import *
+
+def displace(th1, dist=0,name=""):
+  graph = TGraphErrors()
+  counter=0
+  for x in range( 0 , th1.GetNbinsX() ) :
+   # print "Setting point %d %f %f" %( x, dist + x*th1.GetBinWidth(0), th1.GetBinContent(x) )
+    if th1.GetBinContent(x) == 0 : continue
+    graph.SetPoint( counter , dist + x*th1.GetBinWidth(0) , th1.GetBinContent(x) )
+    graph.SetPointError( counter, 0, th1.GetBinError(x) )
+    counter = counter + 1
+  return graph
+class TbStack(GangaObject):
+
+  _category = 'postprocessor'
+  _exportmethods = ['merge']
+  _name = 'TbStack'
+  _schema = Schema(Version(1,0), {
+    'Output' : SimpleItem(defvalue="Kepler-Meta-Histos.root"),
+    'Labels' : SimpleItem(defvalue={}),
+    'DrawOptions' : SimpleItem(defvalue=""),
+    'StackOptions' : SimpleItem(defvalue=""),
+    'Hist' : SimpleItem(defvalue={}),
+    'Displace' : SimpleItem(defvalue={}),
+    'Title' : SimpleItem(defvalue="")
+  })
+  def merge(self, job):
+    out_file = TFile(self.Output,"UPDATE")
+    for key in self.Hist:
+      print "Making histogram: " + key
+      histogram_name = self.Hist[key]
+      stack = TMultiGraph(key, self.Title ) 
+      legend = TLegend(0.8,0.3,0.995,0.4)
+      counter=0
+      color_counter=1
+      xtitle=""
+      ytitle=""
+      for run in job.splitter.Files.keys():
+        if run not in self.Labels.keys(): 
+          counter = counter + 1
+          continue 
+          
+        j=job.subjobs(counter)
+        print "Reading " + j.name + " output files"
+        in_file = TFile(j.outputdir+"Kepler-histos.root" ,'READ')
+        
+        if in_file.IsOpen() == False: continue
+        obj = in_file.Get(histogram_name)
+        if obj == 0: continue 
+        gROOT.cd()
+        dd = 0
+        if run in self.Displace.keys(): dd = self.Displace[run]
+        if self.Title == "": title = obj.GetTitle()
+        if xtitle == "": xtitle = obj.GetXaxis().GetTitle()
+        if ytitle == "": ytitle = obj.GetYaxis().GetTitle()
+        thing = displace( obj, dd , j.name )
+        thing.SetLineColor( color_counter )
+        thing.SetLineWidth( 1 )
+        stack.Add( thing , self.DrawOptions )
+        legend.AddEntry( thing, self.Labels[ run ],"L")
+        in_file.Close()
+        del in_file
+        counter = counter + 1
+        color_counter = color_counter + 1 
+      stack.SetDrawOption("nostack")
+      stack.ls()
+      out_file.cd()
+      stack.Write()
+      legend.Write()
+      c1 = TCanvas(key+"_canvas","",800,600)
+      # c1.SetLogy() 
+      stack.Draw(self.StackOptions)
+      print "Titles = %s %s %s" %( title, xtitle, ytitle)
+      stack.GetXaxis().SetTitle(xtitle)
+      stack.GetYaxis().SetTitle(ytitle)
+      stack.SetTitle(self.Title) 
+      stack.Draw(self.StackOptions)
+      legend.Draw()
+      c1.Write()
+    
+
diff --git a/Kepler/GangaPlugin/Lib/.svn/text-base/__init__.py.svn-base b/Kepler/GangaPlugin/Lib/.svn/text-base/__init__.py.svn-base
new file mode 100644
index 0000000..c602229
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/.svn/text-base/__init__.py.svn-base
@@ -0,0 +1,7 @@
+from TbQuery import *
+from KeplerApp import *
+from TbDataset import *
+from TbFileChecker import *
+from TbEosUpload import *
+from TbMetaAnalysisMerger import *
+from TbStack import *
\ No newline at end of file
diff --git a/Kepler/GangaPlugin/Lib/KeplerApp.py b/Kepler/GangaPlugin/Lib/KeplerApp.py
new file mode 100644
index 0000000..00e014e
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/KeplerApp.py
@@ -0,0 +1,242 @@
+## Note that the special string AppName will be replaced upon initialisation
+## in all cases with the relavent app name (DaVinci, Gauss etc...)
+import os, tempfile, pprint, sys
+from GangaGaudi.Lib.Applications.Gaudi import Gaudi
+from GangaGaudi.Lib.Applications.GaudiUtils import fillPackedSandbox
+from GangaLHCb.Lib.Applications.AppsBaseUtils import available_apps, guess_version, available_packs
+from GangaLHCb.Lib.Applications.AppsBaseUtils import backend_handlers, activeSummaryItems
+from Ganga.GPIDev.Lib.File.FileBuffer import FileBuffer
+from Ganga.GPIDev.Base.Proxy import GPIProxyObjectFactory
+from Ganga.GPIDev.Schema import *
+from Ganga.Utility.Shell import Shell
+from GangaLHCb.Lib.Applications.PythonOptionsParser import PythonOptionsParser
+from Ganga.GPIDev.Adapters.StandardJobConfig import StandardJobConfig
+from Ganga.Utility.Config import getConfig
+from Ganga.Utility.files import expandfilename
+from Ganga.Utility.execute import execute
+import Ganga.Utility.logging
+import GangaLHCb.Lib.Applications.CMTscript
+import pickle
+import subprocess
+from GangaLHCb.Lib.Applications import XMLPostProcessor
+from Ganga.Core.exceptions import ApplicationConfigurationError
+
+logger = Ganga.Utility.logging.getLogger()
+
+class Kepler(Gaudi):
+    _name = 'Kepler'
+    _category = 'applications'
+    #__doc__ = GaudiDocString('AppName')
+    _schema = Gaudi._schema.inherit_copy()
+    docstr = 'The package the application belongs to (e.g. "Sim", "Phys")'
+    _schema.datadict['package'] = SimpleItem(defvalue=None,
+                                             typelist=['str','type(None)'],
+                                             doc=docstr)
+    docstr = 'The package where your top level requirements file is read '  \
+             'from. Can be written either as a path '  \
+             '\"Tutorial/Analysis/v6r0\" or in a CMT style notation '  \
+             '\"Analysis v6r0 Tutorial\"'
+    _schema.datadict['masterpackage'] = SimpleItem(defvalue=None,
+                                                   typelist=['str','type(None)'],
+                                                   doc=docstr)
+    _schema.datadict['platform'] = SimpleItem( defvalue="x86_64-slc6-gcc48-opt" )
+    docstr = 'Extra options to be passed onto the SetupProject command '\
+             'used for configuring the environment. As an example '\
+             'setting it to \'--dev\' will give access to the DEV area. '\
+             'For full documentation of the available options see '\
+             'https://twiki.cern.ch/twiki/bin/view/LHCb/SetupProject'
+    _schema.datadict['setupProjectOptions'] = SimpleItem(defvalue='',
+                                                         typelist=['str','type(None)'],
+                                                         doc=docstr)    
+    _exportmethods = Gaudi._exportmethods[:]
+    _exportmethods += ['readInputData']
+    
+    def _get_default_version(self, gaudi_app):
+        return guess_version(gaudi_app)
+    
+               
+    def _auto__init__(self):
+        self.appname='Kepler'
+      #  super(self.appname, self)._auto__init__()
+
+    def postprocess(self):
+        XMLPostProcessor.postprocess(self,logger)
+
+    def readInputData(self,optsfiles,extraopts=False):
+        def dummyfile():
+            temp_fd,temp_filename=tempfile.mkstemp(text=True,suffix='.py')
+            os.write(temp_fd,"Dummy file to keep the Optionsparser happy")
+            os.close(temp_fd)
+            return temp_filename
+
+        if type(optsfiles)!=type([]): optsfiles=[optsfiles]
+        
+        if len(optsfiles)==0: optsfiles.append(dummyfile())
+        
+        if extraopts: extraopts=self.extraopts
+        
+        else: extraopts=""
+            
+       # parser = check_inputs(optsfiles, extraopts, self.env) 
+        try:
+            parser = PythonOptionsParser(optsfiles,extraopts,self.getenv(False))
+        except Exception, e:
+            msg = 'Unable to parse the job options. Please check options ' \
+                  'files and extraopts.'
+            raise ApplicationConfigurationError(None,msg)
+
+        return GPIProxyObjectFactory(parser.get_input_data())
+
+    def getpack(self, options=''):
+        """Performs a getpack on the package given within the environment
+           of the application. The unix exit code is returned
+        """
+        command = 'getpack ' + options + '\n'
+        if options == '':
+            command = 'getpack -i'
+        return CMTscript.CMTscript(self,command)
+        
+    def make(self, argument=None):
+        """Performs a CMT make on the application. The unix exit code is 
+           returned. Any arguments given are passed onto CMT as in
+           dv.make('clean').
+        """
+        config = Ganga.Utility.Config.getConfig('GAUDI')
+        command = config['make_cmd']
+        if argument:
+            command+=' '+argument
+        return CMTscript.CMTscript(self,command)
+
+    def cmt(self, command):
+        """Execute a cmt command in the cmt user area pointed to by the
+        application. Will execute the command "cmt <command>" after the
+        proper configuration. Do not include the word "cmt" yourself. The 
+        unix exit code is returned."""
+        command = '###CMT### ' + command
+        return CMTscript.CMTscript(self,command)
+
+    def _getshell(self):
+        opts = ''
+        if self.setupProjectOptions: opts = self.setupProjectOptions
+
+        fd = tempfile.NamedTemporaryFile()
+        script = '#!/bin/sh\n'
+        if self.user_release_area:
+            script += 'User_release_area=%s; export User_release_area\n' % \
+                      expandfilename(self.user_release_area)
+        if self.platform:    
+            script += '. `which LbLogin.sh` -c %s\n' % self.platform
+        useflag = ''
+        cmd = '. SetupProject.sh %s %s %s %s' % (useflag, opts, self.appname, self.version) 
+        script += '%s \n' % cmd
+        fd.write(script)
+        fd.flush()
+        logger.debug(script)
+
+        self.shell = Shell(setup=fd.name)
+        if (not self.shell): raise ApplicationConfigurationError(None,'Shell not created.')
+        
+        logger.debug(pprint.pformat(self.shell.env))
+        
+        fd.close()
+        app_ok = False
+        ver_ok = False
+        for var in self.shell.env:
+            if var.find(self.appname) >= 0: app_ok = True
+            if self.shell.env[var].find(self.version) >= 0: ver_ok = True
+        if not app_ok or not ver_ok:
+            msg = 'Command "%s" failed to properly setup environment.' % cmd
+            logger.error(msg)
+            raise ApplicationConfigurationError(None,msg)
+
+        import copy
+        self.env = copy.deepcopy( self.shell.env )
+
+        return self.shell.env
+
+
+    def _get_parser(self):
+        optsfiles = [fileitem.name for fileitem in self.optsfile]
+        # add on XML summary
+
+        extraopts = ''
+        if self.extraopts:
+            extraopts += self.extraopts
+            
+        try:
+            parser = PythonOptionsParser(optsfiles,extraopts,self.getenv(False))
+        except ApplicationConfigurationError, e:
+            # fix this when preparing not attached to job
+            
+            msg2=''
+            try:
+                debug_dir = self.getJobObject().getDebugWorkspace().getPath()
+                msg2+='You can also view this from within ganga '\
+                       'by doing job.peek(\'../debug/gaudirun.<whatever>\').'
+            except:
+                debug_dir = tempfile.mkdtemp()
+                    
+            messages = e.message.split('###SPLIT###')
+            if len(messages) is 2:
+                stdout = open(debug_dir + '/gaudirun.stdout','w')
+                stderr = open(debug_dir + '/gaudirun.stderr','w')
+                stdout.write(messages[0])
+                stderr.write(messages[1])
+                stdout.close()
+                stderr.close()
+                msg = 'Unable to parse job options! Please check options ' \
+                      'files and extraopts. The output and error streams from gaudirun.py can be ' \
+                      'found in %s and %s respectively . ' % (stdout.name, stderr.name)
+            else:
+                f = open(debug_dir + '/gaudirun.out','w')
+                f.write(e.message)
+                f.close()
+                msg = 'Unable to parse job options! Please check options ' \
+                      'files and extraopts. The output from gaudirun.py can be ' \
+                      'found in %s . ' % f.name
+            msg+=msg2
+            # logger.error(msg)
+            raise ApplicationConfigurationError(None,msg)
+        return parser
+
+
+    def _parse_options(self):
+        try:
+            parser = self._get_parser()
+        except ApplicationConfigurationError, e:
+            raise e
+
+        share_dir = os.path.join(expandfilename(getConfig('Configuration')['gangadir']),
+                                 'shared',
+                                 getConfig('Configuration')['user'],
+                                 self.is_prepared.name)
+        fillPackedSandbox([FileBuffer('options.pkl',parser.opts_pkl_str)],
+                          os.path.join(share_dir,
+                                       'inputsandbox',
+                                       '_input_sandbox_%s.tar' % self.is_prepared.name))
+        inputdata = parser.get_input_data()
+        if len(inputdata.files) > 0:
+            logger.warning('Found inputdataset defined in optsfile, '\
+                           'this will get pickled up and stored in the '\
+                           'prepared state. Any change to the options/data will '\
+                           'therefore require an unprepare first.')
+            logger.warning('NOTE: the prefered way of working '\
+                           'is to define inputdata in the job.inputdata field. ')
+            logger.warning('Data defined in job.inputdata will superseed optsfile data!')
+            logger.warning('Inputdata can be transfered from optsfiles to the job.inputdata field '\
+                           'using job.inputdata = job.application.readInputData(optsfiles)')
+            share_path = os.path.join(share_dir,'inputdata')
+            if not os.path.isdir(share_path): os.makedirs(share_path)
+            f=open(os.path.join(share_path,'options_data.pkl'),'w+b')
+            pickle.dump(inputdata, f)
+            f.close()
+
+        share_path = os.path.join(share_dir,'output')
+        if not os.path.isdir(share_path): os.makedirs(share_path)
+        f=open(os.path.join(share_path,'options_parser.pkl'),'w+b')
+        pickle.dump(parser, f)
+        f.close()
+
+from Ganga.GPIDev.Adapters.ApplicationRuntimeHandlers import allHandlers
+for (backend, handler) in backend_handlers().iteritems():
+    allHandlers.add('Kepler', backend, handler)
diff --git a/Kepler/GangaPlugin/Lib/RecursiveSearch.py b/Kepler/GangaPlugin/Lib/RecursiveSearch.py
new file mode 100644
index 0000000..ae70ab9
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/RecursiveSearch.py
@@ -0,0 +1,35 @@
+from ROOT import *
+
+def RecursiveSearch( directory , histograms, maxDepth, path="", depth=0 ):
+  if type( directory ) is not TDirectoryFile :
+    if type( directory) is not TFile :
+      if type( directory ) is TH1D :
+        histograms.append( path[:-1]  )
+      return
+        
+  if depth > maxDepth : return
+  
+  for i in range(0,directory.GetListOfKeys().GetEntries()):
+    obj = directory.GetListOfKeys().At(i)
+    RecursiveSearch( directory.Get( obj.GetName()) , histograms,maxDepth, path + obj.GetName() + "/" , depth+1)
+    
+  return
+
+def makeDirectories( filename, objects):
+  for x in objects:
+    output = TFile.Open(filename,'UPDATE')
+    directories = x.split('/')
+    output.cd() 
+    layer = output
+    path = ""
+    for ind in range( 0, len(directories) -1 ) :
+      tmpKey = layer.FindKey( directories[ind] )
+      if not tmpKey  :
+        foo = layer.mkdir( directories[ind], directories[ind] )
+        layer.cd()
+        foo.Write()
+        layer.Write()
+        layer = foo
+      else : layer = tmpKey.ReadObj()
+    output.Close("R")
+    del output 
diff --git a/Kepler/GangaPlugin/Lib/TbDataset.py b/Kepler/GangaPlugin/Lib/TbDataset.py
new file mode 100644
index 0000000..82897b2
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbDataset.py
@@ -0,0 +1,98 @@
+from Ganga.GPIDev.Adapters.ISplitter import ISplitter
+from Ganga.GPIDev.Schema import *
+from TbQuery import TbQuery
+from collections import defaultdict
+from Ganga.GPIDev.Base.Proxy import addProxy, stripProxy
+
+class TbDataset(ISplitter):
+  _name = "TbDataset"
+  _schema = Schema(Version(1,0), {
+  'filesPerJob' : SimpleItem(defvalue=1),
+  'maxFiles' : SimpleItem(defvalue=1),
+  'ignoremissing': SimpleItem(defvalue=False),
+  'Files' : SimpleItem(defvalue={}),
+  'AlignmentFiles' : SimpleItem(defvalue={}),
+  'PixelConfigFiles' : SimpleItem(defvalue={}),
+  'TimingConfigFiles' : SimpleItem(defvalue={}),
+  'Month' : SimpleItem(defvalue=""),
+  'run' : SimpleItem(defvalue=0),
+  'prefix' : SimpleItem(defvalue=""),
+  'AutoConfig' : SimpleItem(defvalue=True) })
+  _exportmethods = [ 'split','optionsString' ]   
+    
+  def split(self,job):
+    from Ganga.GPIDev.Lib.Job import Job
+   
+    subjobs = []
+    for run in self.Files.keys():
+      j = addProxy(self.createSubjob(job))
+#      j.splitter = None
+#      j.merger = None
+      jp = stripProxy(j)
+      jp._splitter_data = self.optionsString(run)
+      subjobs.append(jp)
+      
+    print "Submitting jobs for %d runs" %( len(subjobs))
+    return subjobs
+  
+  def __construct__(self,args):
+    if len( args ) == 0 : return 
+    self.Month = args[0]
+    for r in args[1]:
+      query = TbQuery()
+      query.Month = self.Month
+      query.Run = r
+      print "Looking for %s/Run%d" %(self.Month, r )
+      files = query.getFiles()
+      if len(files) != 0 : self.Files[r] = []
+      for f in files:
+        self.Files[r].append(f)
+      
+      if self.AutoConfig:
+        config_files = query.getConfiguration()
+        alignment_file = ""
+        for f in config_files:
+          if f.find("Alignment") != -1:
+            if alignment_file != "": alignment_file = f
+            elif f.find("mille") != -1: alignment_file = f
+           # elif f.find(self.prefix) != -1 : alignment_file = f
+          elif f.find("PixelConfig") != -1:
+            if r not in self.PixelConfigFiles.keys():
+              self.PixelConfigFiles[r] = []
+            self.PixelConfigFiles[r].append(f)
+          elif f.find("TimingConfig") != -1: self.TimingConfigFiles[r] = f
+        if alignment_file != "" : self.AlignmentFiles[r] = alignment_file
+      
+      
+  def optionsString(self, run):
+  
+    files_for_this_run = self.Files[run]
+    if len( files_for_this_run ) == 0 :
+      return ""
+    output = "from Configurables import TbDataSvc \n"
+    output += "TbDataSvc().Input = ['" + files_for_this_run[0] +"'"
+  
+    for f in range(1, len(files_for_this_run)):
+        output += ",'"+files_for_this_run[f]+"'"
+    output += "]"
+    # now add the configuration files ... 
+    if self.AutoConfig:
+      pixel_config = []
+      if run in self.PixelConfigFiles.keys() : 
+        pixel_config = self.PixelConfigFiles[run]
+        output+= " \nTbDataSvc().PixelConfigFile += ['" + pixel_config[0] +"'"
+        for f in range(1,len(pixel_config)):
+          output += ",'"+pixel_config[f]+"'"
+        output += "]"
+      timing_config = ""
+      if run in self.TimingConfigFiles.keys() :
+        timing_config = self.TimingConfigFiles[run]
+        output += " \nTbDataSvc().TimingConfigFile = '%s'" %(timing_config)
+        
+      alignment = ""
+      if run in self.AlignmentFiles.keys() : 
+        alignment = self.AlignmentFiles[run]
+        output += " \nTbDataSvc().AlignmentFile = '%s'" %(alignment)
+      
+    return output
+  
diff --git a/Kepler/GangaPlugin/Lib/TbEosUpload.py b/Kepler/GangaPlugin/Lib/TbEosUpload.py
new file mode 100644
index 0000000..0e40703
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbEosUpload.py
@@ -0,0 +1,45 @@
+
+
+from Ganga.GPIDev.Schema import *
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Schema import *
+from Ganga.GPIDev.Adapters.IPostProcessor import IPostProcessor
+import os
+
+class TbEosUpload(IPostProcessor):
+
+  _schema = IPostProcessor._schema.inherit_copy()
+  _schema.datadict['files'] = SimpleItem(defvalue=[], doc='Files to upload')
+  _schema.datadict['prefix'] = SimpleItem(defvalue="",doc='Prefix to uploaded file')
+  _category = 'postprocessor'
+  _name = 'TbEosUpload'
+  _exportmethods = ['execute']
+
+
+  def execute(self,job,newstatus):
+    eos_cp="/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select cp"
+    counter=0
+    for run in job.splitter.Files.keys():
+      j=job.subjobs(counter)
+      if j.status == 'completed':
+        rootpath = "/eos/lhcb/testbeam/velo/timepix3/%s/RootFiles/Run%d/" %( job.splitter.Month, run )
+        if 'Alignment' in self.files:
+          source="%sAlignment_out.dat" %( j.outputdir )
+          if os.path.isfile( source ): 
+            sink="%sConditions/%sAlignment%dmille.dat" %(rootpath, self.prefix, run )
+            os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+          else : print source + " does not exist"
+        if 'Tuple' in self.files:
+          source="%sKepler-tuple.root" %( j.outputdir )
+          sink="%sOutput/%sKepler-tuple-%d.root" %(rootpath, self.prefix, run )
+          os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+        if 'Histograms' in self.files:
+          source="%sKepler-histos.root" %( j.outputdir )
+          sink="%sOutput/%sKepler-histos-%d.root" %(rootpath,self.prefix, run )
+          os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+        if 'TimingConfig' in self.files:
+          source="%sTimingConfig.dat" %( j.outputdir )
+          sink = "%sConditions/%sTimingConfig.dat" %(rootpath,self.prefix)
+          os.system(eos_cp+" "+source+" "+sink+" "+">/dev/null")
+      counter = counter + 1 
+    return True
diff --git a/Kepler/GangaPlugin/Lib/TbFileChecker.py b/Kepler/GangaPlugin/Lib/TbFileChecker.py
new file mode 100644
index 0000000..06dfa10
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbFileChecker.py
@@ -0,0 +1,97 @@
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Adapters.IPostProcessor import PostProcessException, IPostProcessor
+from Ganga.GPIDev.Base.Proxy import GPIProxyObject
+from Ganga.GPIDev.Schema import ComponentItem, FileItem, Schema, SimpleItem, Version
+from Ganga.Utility.Config import makeConfig, ConfigError, getConfig
+from Ganga.Utility.Plugin import allPlugins
+from Ganga.Utility.logging import getLogger, log_user_exception
+import commands
+import copy
+import os
+import string
+import re
+
+class TbFileChecker(IPostProcessor):
+
+  _schema = IPostProcessor._schema.inherit_copy()
+  _schema.datadict["alignment"] = SimpleItem(False)
+  _schema.datadict["resubmit"] = SimpleItem(False) #resubmit items with no output in the errorsummary
+  _category = 'postprocessor'
+  _name = 'TbFileChecker'
+  _exportmethods = ['check','ErrorSummary']
+
+  def check(self,job):
+
+    job_objects = []
+    if len( job.subjobs ) != 0:
+      for j in job.subjobs:
+        job_objects.append(j)
+    else: job_objects.append( job )
+    result = True
+    for j in job_objects:
+      job_success = False
+      filepath = "%s/stdout" %(j.outputdir)
+     #print "Checking %d subjobs " %( len(job_objects ) )
+      if j.status != "completed": continue
+      if self.alignment:
+
+        if not os.path.isfile( j.outputdir + "Alignment_out.dat" ):
+          job_success = False
+          j.force_status('failed')
+          continue
+
+      if not os.path.isfile( filepath ): continue
+      f = reversed( open(filepath,'r').readlines() )
+      for line in f:	
+        if re.search("ApplicationMgr       INFO Application Manager Finalized successfully",line):
+          job_success = True
+          break
+      if job_success: j.force_status('completed')
+      else : j.force_status('failed')
+      result = result*job_success
+    return result 
+ 
+  def ErrorSummary(self,job):
+    job_objects = []
+    minuit_exceptions = ["MATRIX","DERIVATIVE","VALUE"] 
+    millepede_exceptions = ["Initial","Negative","diagonal"]
+    for j in job.subjobs:
+      if j.status == 'failed': job_objects.append(j)
+    for j in job_objects:
+      filepath = "%s/stdout" %(j.outputdir)
+      error = "Unknown"
+      if os.path.isfile( filepath ):
+        for line in open(filepath,'r').readlines():
+          if re.search("ERROR",line):
+            found = False
+            for e in minuit_exceptions: 
+              if re.search(e,line): 
+                found = True
+                break
+            if found : continue
+            error = line[:-1]
+            break
+          if re.search("error",line):
+            found = False
+            for e in millepede_exceptions: 
+              if re.search(e,line): 
+                found = True
+                break
+            if found : continue
+
+            error = line[:-1]
+            break
+          if re.search("Error",line):
+            found = False
+            for e in millepede_exceptions: 
+              if re.search(e,line): 
+                found = True
+                break
+            if found : continue
+
+            error = line[:-1]
+            break
+      else: 
+        error = "No output files"
+        if self.resubmit: j.resubmit()
+      print "%s (%d.%3d) : %s" %( j.name, job.id, j.id, error ) 
diff --git a/Kepler/GangaPlugin/Lib/TbMetaAnalysisMerger.py b/Kepler/GangaPlugin/Lib/TbMetaAnalysisMerger.py
new file mode 100644
index 0000000..cb1706d
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbMetaAnalysisMerger.py
@@ -0,0 +1,177 @@
+from ROOT import *
+from RecursiveSearch import RecursiveSearch, makeDirectories
+import os
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Base.Proxy import GPIProxyObjectFactory
+from Ganga.GPIDev.Schema import *
+import operator
+
+class TbBinning2D :
+  name = ""
+  title = ""
+  minY = 0
+  widthY = 0
+  nBinsY = 0
+  minX = 0 
+  widthX = 0 
+  nBinsX = 0 
+  maxX = 0 
+  maxY = 0 
+  path = ""
+  def __init__(self,name,title,path,minX,widthX,nBinsX,minY,widthY,nBinsY) :
+    self.name = name
+    self.title = title
+    self.path = path
+    self.minX = minX
+    self.widthX = widthX
+    self.nBinsX = nBinsX
+    self.minY = minY
+    self.widthY = widthY
+    self.nBinsY = nBinsY
+    self.maxX = self.minX + self.nBinsX*self.widthX
+    self.maxY = self.minY + self.nBinsY*self.widthY
+   
+class TbProfile :
+  path = ""
+  title = ""
+  name = ""
+  def __init__(self,name,title,path):
+    self.title = title
+    self.path = path
+    self.name = name
+  
+
+class TbMetaAnalysisMerger(GangaObject):
+
+  _category = 'postprocessor'
+  _exportmethods = ['merge']
+  _name = 'TbMetaAnalysisMerger'
+  f2L = {}
+  _schema = Schema(Version(1,0), {
+    'Mode' : SimpleItem(defvalue="Profile"),
+    'Output' : SimpleItem(defvalue="Kepler-Meta-Histos.root"),
+    'Top' : SimpleItem(defvalue=[]),
+    'Labels' : SimpleItem(defvalue={})
+  })
+
+  def write2D( self, files, hists ):
+    prev_path = ""
+    for h in hists:
+      if h.path != prev_path :
+        print "Making histogram for: %s" %h.path
+        prev_path = h.path
+      out_file = TFile.Open(self.Output,'UPDATE')
+      hist = TH2D( h.name, h.title, h.nBinsX, h.minX, h.maxX, h.nBinsY, h.minY, h.maxY )
+      for f in files:
+        in_file = TFile(f ,'READ')
+        obj = in_file.Get(h.path +"/"+ h.name )
+        if obj :
+          if obj.GetEntries() != 0: obj.Scale(1/obj.GetEntries());
+          for l in range(0, obj.GetNbinsX() ):
+            hist.SetBinContent( self.f2L[f] - h.minX, l, obj.GetBinContent(l) )
+          del obj
+        else :
+          print "ERROR: %s not found in %s" %(h.path + "/" + h.name,f)
+        in_file.Close("R")
+        del in_file
+      out_file.cd(h.path)      
+      hist.Write()
+      out_file.Close("R")
+      del out_file
+ 
+  def write1D( self, files, graphs) :
+    means = []
+    sigmas = []
+    sorted_f2L = sorted(self.f2L.items(), key=operator.itemgetter(1))
+    p = 0
+    n = {}
+    for f in sorted_f2L:
+      print f
+      n[f[0]] = p
+      p = p + 1
+      
+    print n
+    for g in graphs:
+      mean = TGraphErrors()
+      mean.SetNameTitle( g.name + "_m", g.title)
+      sigma = TGraphErrors()
+      sigma.SetNameTitle( g.name + "_s", g.title)
+      means.append( mean)
+      sigmas.append( sigma )
+  
+    for f in files:
+      in_file = TFile(f,'READ')
+      for x in range(0,len(graphs)):
+        print "Making histogram for: %s" %(g.path + "/" + g.name)
+        g = graphs[x]
+        obj = in_file.Get( g.path + "/" + g.name )
+        if obj :
+         if( obj.GetEntries() != 0 ):
+            means[x].SetPoint( n[f] , self.f2L[f] , obj.GetMean() )
+            sigmas[x].SetPoint( n[f], self.f2L[f] , obj.GetRMS() )
+            means[x].SetPointError( n[f] , 0 , obj.GetRMS()/sqrt(obj.GetEntries()) )
+            sigmas[x].SetPointError( n[f], 0 , obj.GetRMS()/sqrt(obj.GetEntries()) )
+      in_file.Close("R")
+      del in_file
+    out_file = TFile.Open(self.Output,'UPDATE')
+
+    for g in range(0,len(graphs)):
+      out_file.cd(graphs[g].path)
+      means[g].Write()
+      sigmas[g].Write()
+    out_file.Close()
+  
+  
+  def merge(self, list ):
+    
+    file0 = TFile() 
+    found = False
+    files = []
+    
+    for j in list:
+      if j.status == 'completed':
+        fname = j.outputdir + "/Kepler-histos.root"
+        if os.path.isfile(fname) :
+          if found == False :
+            file0 = TFile(fname ,'READ')
+            found = True
+          files.append(fname)
+          if j.inputdata.run in self.Labels : 
+            self.f2L[fname] = self.Labels[j.inputdata.run]
+          else : 
+            self.f2L[fname] = j.inputdata.run
+      
+    all_histograms = []
+    print "Searching for histograms..."
+    RecursiveSearch( file0, all_histograms , 7 )
+    histograms = []
+    for x in all_histograms: 
+      for t in self.Top:
+        if x.find(t) != -1 : 
+          if x not in histograms : histograms.append(x)
+      
+    hists = []
+    graphs = []
+    print "Building histogram objects..."
+    for x in histograms:
+      obj = file0.Get( x )
+      k = x.rfind('/')
+      if self.Mode == "Profile":
+        profile = TbProfile(x[k+1:], obj.GetTitle(), x[:k] )
+        graphs.append( profile )
+      if self.Mode == "2D":
+        Runs = job.inputdata.Runs
+        hists.append( TbBinning2D( x[k+1:],obj.GetTitle(),x[:k],Runs[0],1,Runs[len(Runs)-1] - Runs[0] +1,
+                       obj.GetBinLowEdge(0), obj.GetBinWidth(0), obj.GetNbinsX() ) )
+        
+    file0.Close()
+    del file0
+    
+    output = TFile.Open(self.Output,'RECREATE')
+    output.Close("R")
+    del output
+    makeDirectories( self.Output, histograms )
+    print "Filling %d histograms / graphs" %(len( hists ) + len(graphs ) )
+    if self.Mode == "2D": self.write2D( files, hists )
+    if self.Mode == "Profile": self.write1D( files, graphs )
+    
diff --git a/Kepler/GangaPlugin/Lib/TbMetaAnaylsisMerger.py b/Kepler/GangaPlugin/Lib/TbMetaAnaylsisMerger.py
new file mode 100644
index 0000000..5bd7cd3
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbMetaAnaylsisMerger.py
@@ -0,0 +1,56 @@
+from ROOT import *
+from RecursiveSearch import RecursiveSearch
+
+ # main programme 
+ 
+
+
+all_histograms = []
+RecursiveSearch( f, all_histograms , 5 )
+
+output = TFile('Meta-graphs.root','RECREATE')
+
+# clone the directory structure
+
+for x in all_histograms:
+  directories = x.split('/')
+  layer = output
+  path = ""
+  for ind in range( 0, len(directories) -1 ) :
+    tmpKey = layer.FindKey( directories[ind] )
+    if not tmpKey  :
+      foo = layer.mkdir( directories[ind], directories[ind] )
+      layer.cd()
+      foo.Write()
+      layer.Write()
+      layer = foo
+    else : layer = tmpKey.ReadObj() 
+
+output.Write()
+
+output.Close()
+
+output = TFile('Meta-graphs.root','UPDATE')
+
+for x in all_histograms:
+  obj = f.Get( x )
+
+  k = x.rfind('/')
+  path = x[:k]
+  name = x[k+1:]
+  output.cd( path )
+
+  graph_mean = TGraph( )
+  graph_mean.SetNameTitle( name + "_mean" , obj.GetTitle() )
+  graph_mean.SetPoint( graph_mean.GetN() , 0, obj.GetMean() )
+  graph_mean.Write()
+
+  graph = TGraph( )
+  graph.SetNameTitle( name + "_sigma" , obj.GetTitle() )
+  graph.SetPoint( graph.GetN() , 0, obj.GetRMS() )
+  graph.Write()
+
+
+
+output.Write()
+  
\ No newline at end of file
diff --git a/Kepler/GangaPlugin/Lib/TbQuery.py b/Kepler/GangaPlugin/Lib/TbQuery.py
new file mode 100644
index 0000000..d4f42f0
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbQuery.py
@@ -0,0 +1,39 @@
+
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Base.Proxy import GPIProxyObjectFactory
+from Ganga.GPIDev.Schema import *
+
+def ListFiles( path ,extension) :
+  import subprocess
+  proc = subprocess.Popen(["/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select","ls",path],stdout=subprocess.PIPE)
+  out=""
+  err=""
+  files = []
+  (out,err) = proc.communicate()
+  files = out.split('\n')
+  output = []
+  for f in files:
+    if f.find(extension) != -1:
+      output.append( path + f)
+  return output
+  
+class TbQuery( GangaObject ) :
+  path = ""
+  _schema = Schema(Version(1,0), {
+        'Month' : SimpleItem(defvalue='',doc='Testbeam period to look for data'),
+        'Run' : SimpleItem(defvalue=0,doc='Run to look at')
+        } )
+  _name = "TbQuery"
+  _exportmethods = ['getOptions','getFiles']
+  _category = 'query'
+  _data = ''
+          
+  def getFiles(self):
+    path = "eos/lhcb/testbeam/velo/timepix3/%s/RawData/Run%d/" %( self.Month, self.Run )
+    return ListFiles(path,".dat")
+    
+  def getConfiguration(self):
+    path = "eos/lhcb/testbeam/velo/timepix3/%s/RootFiles/Run%d/Conditions/" %(self.Month,self.Run)
+    return ListFiles(path,".dat")
+  _exportmethods = ['getConfiguration','getFiles']
+    
\ No newline at end of file
diff --git a/Kepler/GangaPlugin/Lib/TbStack.py b/Kepler/GangaPlugin/Lib/TbStack.py
new file mode 100755
index 0000000..27d89d1
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/TbStack.py
@@ -0,0 +1,93 @@
+from Ganga.GPIDev.Base import GangaObject
+from Ganga.GPIDev.Adapters.IPostProcessor import PostProcessException, IPostProcessor
+from Ganga.GPIDev.Base.Proxy import GPIProxyObject
+from Ganga.GPIDev.Schema import ComponentItem, FileItem, Schema, SimpleItem, Version
+from Ganga.Utility.Config import makeConfig, ConfigError, getConfig
+from Ganga.Utility.Plugin import allPlugins
+from Ganga.Utility.logging import getLogger, log_user_exception
+import commands
+import copy
+import os
+import string
+import re
+from ROOT import *
+
+def displace(th1, dist=0,name=""):
+  graph = TGraphErrors()
+  counter=0
+  for x in range( 0 , th1.GetNbinsX() ) :
+   # print "Setting point %d %f %f" %( x, dist + x*th1.GetBinWidth(0), th1.GetBinContent(x) )
+    if th1.GetBinContent(x) == 0 : continue
+    graph.SetPoint( counter , dist + x*th1.GetBinWidth(0) , th1.GetBinContent(x) )
+    graph.SetPointError( counter, 0, th1.GetBinError(x) )
+    counter = counter + 1
+  return graph
+class TbStack(GangaObject):
+
+  _category = 'postprocessor'
+  _exportmethods = ['merge']
+  _name = 'TbStack'
+  _schema = Schema(Version(1,0), {
+    'Output' : SimpleItem(defvalue="Kepler-Meta-Histos.root"),
+    'Labels' : SimpleItem(defvalue={}),
+    'DrawOptions' : SimpleItem(defvalue=""),
+    'StackOptions' : SimpleItem(defvalue=""),
+    'Hist' : SimpleItem(defvalue={}),
+    'Displace' : SimpleItem(defvalue={}),
+    'Title' : SimpleItem(defvalue="")
+  })
+  def merge(self, job):
+    out_file = TFile(self.Output,"UPDATE")
+    for key in self.Hist:
+      print "Making histogram: " + key
+      histogram_name = self.Hist[key]
+      stack = TMultiGraph(key, self.Title ) 
+      legend = TLegend(0.8,0.3,0.995,0.4)
+      counter=0
+      color_counter=1
+      xtitle=""
+      ytitle=""
+      for run in job.splitter.Files.keys():
+        if run not in self.Labels.keys(): 
+          counter = counter + 1
+          continue 
+          
+        j=job.subjobs(counter)
+        print "Reading " + j.name + " output files"
+        in_file = TFile(j.outputdir+"Kepler-histos.root" ,'READ')
+        
+        if in_file.IsOpen() == False: continue
+        obj = in_file.Get(histogram_name)
+        if obj == 0: continue 
+        gROOT.cd()
+        dd = 0
+        if run in self.Displace.keys(): dd = self.Displace[run]
+        if self.Title == "": title = obj.GetTitle()
+        if xtitle == "": xtitle = obj.GetXaxis().GetTitle()
+        if ytitle == "": ytitle = obj.GetYaxis().GetTitle()
+        thing = displace( obj, dd , j.name )
+        thing.SetLineColor( color_counter )
+        thing.SetLineWidth( 1 )
+        stack.Add( thing , self.DrawOptions )
+        legend.AddEntry( thing, self.Labels[ run ],"L")
+        in_file.Close()
+        del in_file
+        counter = counter + 1
+        color_counter = color_counter + 1 
+      stack.SetDrawOption("nostack")
+      stack.ls()
+      out_file.cd()
+      stack.Write()
+      legend.Write()
+      c1 = TCanvas(key+"_canvas","",800,600)
+      # c1.SetLogy() 
+      stack.Draw(self.StackOptions)
+      print "Titles = %s %s %s" %( title, xtitle, ytitle)
+      stack.GetXaxis().SetTitle(xtitle)
+      stack.GetYaxis().SetTitle(ytitle)
+      stack.SetTitle(self.Title) 
+      stack.Draw(self.StackOptions)
+      legend.Draw()
+      c1.Write()
+    
+
diff --git a/Kepler/GangaPlugin/Lib/__init__.py b/Kepler/GangaPlugin/Lib/__init__.py
new file mode 100755
index 0000000..c602229
--- /dev/null
+++ b/Kepler/GangaPlugin/Lib/__init__.py
@@ -0,0 +1,7 @@
+from TbQuery import *
+from KeplerApp import *
+from TbDataset import *
+from TbFileChecker import *
+from TbEosUpload import *
+from TbMetaAnalysisMerger import *
+from TbStack import *
\ No newline at end of file
diff --git a/Kepler/GangaPlugin/PACKAGE.py b/Kepler/GangaPlugin/PACKAGE.py
new file mode 100755
index 0000000..aa9cb40
--- /dev/null
+++ b/Kepler/GangaPlugin/PACKAGE.py
@@ -0,0 +1,23 @@
+################################################################################
+# Ganga Project. http://cern.ch/ganga
+#
+# $Id: PACKAGE.py,v 1.2 2008-08-21 12:35:21 hclee Exp $
+################################################################################
+
+""" Refer to Ganga/PACKAGE.py for details on the purpose of this module.
+"""
+external_packages = {
+   'matplotlib' : {'version' : '0.99.0', 'PYTHONPATH':'lib/python2.5/site-packages'},
+   'numpy'      : {'version' : '1.3.0', 'PYTHONPATH':'lib/python2.5/site-packages', 'PATH' : 'bin'},
+   'pyqt'       : {'version' : '3.18.1_python2.5', 'PYTHONPATH':'lib/python2.5/site-packages', 'LD_LIBRARY_PATH' :'lib'}
+   }
+
+from Ganga.Utility.Setup import PackageSetup
+
+setup = PackageSetup(external_packages)
+
+def standardSetup(setup=setup):
+    for p in setup.packages:
+        setup.prependPath(p,'PYTHONPATH')
+        setup.prependPath(p,'LD_LIBRARY_PATH')
+        setup.prependPath(p,'PATH')
diff --git a/Kepler/GangaPlugin/__init__.py b/Kepler/GangaPlugin/__init__.py
new file mode 100755
index 0000000..0922e46
--- /dev/null
+++ b/Kepler/GangaPlugin/__init__.py
@@ -0,0 +1,2 @@
+def loadPlugins( config = {} ):
+    import Lib
diff --git a/Kepler/Scripts/.svn/all-wcprops b/Kepler/Scripts/.svn/all-wcprops
new file mode 100644
index 0000000..061bb2b
--- /dev/null
+++ b/Kepler/Scripts/.svn/all-wcprops
@@ -0,0 +1,47 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/guest/lhcb/!svn/ver/197454/Kepler/trunk/Tb/Kepler/Scripts
+END
+DaemonScript.sh
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197451/Kepler/trunk/Tb/Kepler/Scripts/DaemonScript.sh
+END
+Kepler
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/197371/Kepler/trunk/Tb/Kepler/Scripts/Kepler
+END
+PixelMapAnalysis.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/176307/Kepler/trunk/Tb/Kepler/Scripts/PixelMapAnalysis.cpp
+END
+spatialEfficiency.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/176372/Kepler/trunk/Tb/Kepler/Scripts/spatialEfficiency.py
+END
+UTDaemonScript.sh
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197454/Kepler/trunk/Tb/Kepler/Scripts/UTDaemonScript.sh
+END
+PixelMapAnalysis_Kepler.h
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/175890/Kepler/trunk/Tb/Kepler/Scripts/PixelMapAnalysis_Kepler.h
+END
+PixelMapAnalysis_KeplerConfig.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 92
+/guest/lhcb/!svn/ver/175613/Kepler/trunk/Tb/Kepler/Scripts/PixelMapAnalysis_KeplerConfig.cpp
+END
diff --git a/Kepler/Scripts/.svn/entries b/Kepler/Scripts/.svn/entries
new file mode 100644
index 0000000..fb00de4
--- /dev/null
+++ b/Kepler/Scripts/.svn/entries
@@ -0,0 +1,266 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/Scripts
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-11T10:34:01.998798Z
+197454
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+DaemonScript.sh
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+277dbebd71065c1c0ff14f6ed92d3f59
+2015-11-11T10:19:10.842818Z
+197451
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1198
+
+Kepler
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+1f2dc6c4e5bc6b769af1595092cded8a
+2015-11-09T14:58:52.060865Z
+197371
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2792
+
+PixelMapAnalysis.cpp
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+9d36fbf4459321de46a669f7ec838572
+2014-08-13T19:35:06.427094Z
+176307
+snoek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4263
+
+spatialEfficiency.py
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+222415ff2297bd8a124309ad0f38af47
+2014-08-15T12:23:45.657594Z
+176372
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+909
+
+UTDaemonScript.sh
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+6231c26fa65788b087c8b96e5ec59aed
+2015-11-11T10:34:01.998798Z
+197454
+tevans
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1249
+
+PixelMapAnalysis_Kepler.h
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+98d305e6169cc4be949c79f5dcae6406
+2014-07-31T13:54:18.832554Z
+175890
+lhcbvelo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1932
+
+PixelMapAnalysis_KeplerConfig.cpp
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+070b0f5ff369c8358b9441a5367510a0
+2014-07-28T08:44:44.606902Z
+175613
+lhcbvelo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3460
+
diff --git a/Kepler/Scripts/.svn/prop-base/DaemonScript.sh.svn-base b/Kepler/Scripts/.svn/prop-base/DaemonScript.sh.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/Scripts/.svn/prop-base/DaemonScript.sh.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/Scripts/.svn/prop-base/Kepler.svn-base b/Kepler/Scripts/.svn/prop-base/Kepler.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/Scripts/.svn/prop-base/Kepler.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/Scripts/.svn/prop-base/UTDaemonScript.sh.svn-base b/Kepler/Scripts/.svn/prop-base/UTDaemonScript.sh.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/Scripts/.svn/prop-base/UTDaemonScript.sh.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/Scripts/.svn/text-base/DaemonScript.sh.svn-base b/Kepler/Scripts/.svn/text-base/DaemonScript.sh.svn-base
new file mode 100644
index 0000000..e16e7f9
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/DaemonScript.sh.svn-base
@@ -0,0 +1,27 @@
+#!/bin/bash
+. /etc/bashrc
+
+shopt -s expand_aliases
+
+EOS_PATH=/eos/lhcb/testbeam/velo/timepix3/Nov2015/
+EOS_CMD=/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select
+KEPLER=/afs/cern.ch/user/t/tevans/cmtuser/KEPLER/KEPLER_v3r0/Tb/Kepler/Scripts/Kepler
+OPT_PATH=/afs/cern.ch/user/t/tevans/cmtuser/KEPLER/KEPLER_v3r0/Tb/Kepler/options/
+OutputFolder=$EOS_PATH/RootFiles/Run$1/
+hist=$(pwd)/Kepler-histos.root
+tree=$(pwd)/Kepler-tuple.root 
+
+if [ -n "$2" ] ; then
+  echo "Running alignment of run $1 ($2)"
+  AlignmentFile=eos/lhcb/user/t/tevans/Alignment/Nov2015/Default_$2.dat
+  $KEPLER $1 -a $AlignmentFile -o $OPT_PATH/align.py -h $hist -t $tree | tee Alignment_Run$1.std.out
+  $EOS_CMD cp $(pwd)/Alignment_out.dat $EOS_PATH/RootFiles/Run$1/Conditions/Alignment$1mille.dat
+  $EOS_CMD cp $(pwd)/Alignment_Run$1.std.out $EOS_PATH/RootFiles/Run$1/Output/Alignment_Run$1.std.out
+fi
+
+$KEPLER $1 -o $OPT_PATH/tuple.py -h $hist -t $tree | tee Batch_Run$1.std.out
+
+$EOS_CMD cp $(pwd)/Batch_Run$1.std.out $OutputFolder/Output/Batch_Run$1.std.out
+$EOS_CMD cp $(pwd)/Kepler-histos.root  $OutputFolder/Output/Kepler-histos.root
+$EOS_CMD cp $(pwd)/Kepler-tuple.root   $OutputFolder/Output/Kepler-tuple.root
+
diff --git a/Kepler/Scripts/.svn/text-base/Kepler.svn-base b/Kepler/Scripts/.svn/text-base/Kepler.svn-base
new file mode 100644
index 0000000..e4c3a78
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/Kepler.svn-base
@@ -0,0 +1,97 @@
+#!/bin/bash
+. /etc/bashrc
+
+scratch=$(pwd)
+shopt -s expand_aliases
+export eospath=eos/lhcb/testbeam/velo/timepix3/
+
+if [ -z $KEPLERSYS ]; then . SetupProject.sh Kepler v3r0; fi
+
+tb=July2014
+if [ "$1" -gt "2000" ]; then tb=Oct2014; fi
+if [ "$1" -gt "3000" ]; then tb=Nov2014; fi
+if [ "$1" -gt "3999" ]; then tb=Dec2014; fi
+if [ "$1" -gt "4999" ]; then tb=May2015; fi
+if [ "$1" -gt "6733" ]; then tb=July2015; fi
+if [ "$1" -gt "12000" ]; then tb=Sep2015; fi
+if [ "$1" -gt "13509" ]; then tb=Nov2015; fi
+# TBDATA
+if [ -z "$DATADIR" ]; then
+  echo "No output directory defined - define variable $DATADIR"
+fi
+TBDATA=$DATADIR/public/
+
+mkdir -p $TBDATA/$tb/Run$1/
+
+RUN=$1
+echo "Processing Run $1"
+
+condFolder="$eospath/$tb/RootFiles/Run$1/Conditions/"
+input_option="Kepler().InputFiles=['$eospath/$tb/RawData/Run$RUN/']"
+alignment="Kepler().AlignmentFile='$condFolder/Alignment$1mille.dat'"
+job="../options/batch.py"
+
+histo_file="Kepler().HistogramFile='$TBDATA/$tb/Run$RUN/Kepler-histos.root'"
+tuple_file="Kepler().TupleFile='$TBDATA/$tb/Run$RUN/Kepler-tuple.root'"
+log_file=$TBDATA/$tb/Run$1/Run$1.std.out
+alignment_out="TbAlignment().OutputAlignmentFile='Alignment_out.dat'"
+
+while [[ $# > 1 ]]
+do
+  key="$1"
+  case $key in
+    -o|--options) # specify the options file to use 
+      job="$2"
+      shift # past argument
+      ;;
+    -a|--alignment) #specify an alignment file 
+      alignment="Kepler().AlignmentFile='$2'"
+      shift # past argument
+      ;;
+    -ao|--alignmentOut) #specify alignment file output
+      alignment_out="TbAlignment().OutputAlignmentFile='$2'"
+      shift
+      ;;
+    -i|--input)
+      input_option="Kepler().InputFiles=['$2']"
+      shift
+      ;;
+    -h|--hist) #specify histogram output
+      histo_file="Kepler().HistogramFile='$2'"
+      shift
+      ;;
+    -t|--nTuple) #specify nTuple output
+      tuple_file="Kepler().TupleFile='$2'"
+      shift
+      ;;
+    -lg|--log) #specify text log location
+      log_file=$2
+      shift
+      ;;
+    -l|--local) #use "local" mode for H8 operations
+      input_option="Kepler().InputFiles=["
+      FILES=""
+      for f in {0..10}; do
+        for file in /mnt/DATA/Dev$f/Run$RUN/*.dat ; do
+          FILES+="'$file',"
+        done
+      done
+      input_option+=`echo $FILES | sed 's/.$//'`
+      input_option+="]"
+      echo $input_option
+      ;;
+    -n|--nEvents) #specify a number of events
+      nEvents="Kepler().EvtMax=$2"
+      shift
+      ;;
+    --default)
+      DEFAULT=YES
+      ;;
+    *)
+      # unknown option
+      ;;
+  esac
+  shift # past argument or value
+done
+
+gaudirun.py --option="from Configurables import Kepler, TbAlignment" --option=$histo_file --option=$tuple_file --option=$alignment_out --option=$nEvents  --option=$alignment --option=$input_option $job |& tee $TBDATA/$tb/Run$1/Run$1.std.out
diff --git a/Kepler/Scripts/.svn/text-base/PixelMapAnalysis.cpp.svn-base b/Kepler/Scripts/.svn/text-base/PixelMapAnalysis.cpp.svn-base
new file mode 100644
index 0000000..2cbc2a8
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/PixelMapAnalysis.cpp.svn-base
@@ -0,0 +1,144 @@
+#include "TFile.h"
+#include "TH2D.h"
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include "TROOT.h"
+#include "TKey.h"
+#include "TIterator.h"
+
+/*
+......................................................................
+Author: Hella Snoek (hella.snoek@cern.ch)
+Date:   22.07.2014
+
+Simple ROOT analysis code to analyse the pixel hit maps for 
+ - DEAD: no hits
+ - HOT:  too many hits
+ - LOW:  too few hits
+pixel hits. 
+
+A pixel cell is compared to its 8 neighbouring (exception for pixel on
+the edge below) pixel cells. The 2 highest and 2 lowest hit counts
+are removed before making an average of the surrounding pixel cells.
+The minimum required count in a cell for the analysis is 20. 
+A HOT cell is 40 times higher than the average. 
+A LOW cell is 4  std deviations (sqrt) lower.
+
+For the cells on the edge of the sensor the highest and lowest hits
+are not removed for the average. 
+
+Three text files are produced. With the format
+col row
+
+Run this code as:
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\"\)
+or
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\",true\)
+for the verbose version.
+
+or call it with a hitmap:
+.L PixelMapAnalysis.cpp+
+PixelMapAnalysis(yourTH2D,"outputname",true);
+
+
+......................................................................
+ */
+
+using namespace std;
+ 
+void PixelMapAnalysis(TH2D* hist, const char* outname, bool verbose=false){
+ 
+  ofstream deadF(Form("%s_dead.txt",outname));
+  ofstream hotF(Form("%s_hot.txt",outname));
+  ofstream lowF(Form("%s_low.txt",outname));
+  
+  for (int col=0;col<256;col++){
+    for (int row=0;row<256;row++){
+      double count =     hist->GetBinContent(col+1,row+1);   
+
+      if (count ==0 ) {
+	if (verbose)	std::cout << "DEAD " << col << " " << row << endl;
+	deadF << setw(3) << col << " " << row <<  endl;
+	continue;
+      }
+
+      vector<double> neighbours{
+      	hist->GetBinContent(col,row),   
+ 	  hist->GetBinContent(col+1,row),   
+ 	  hist->GetBinContent(col+2,row),
+ 	  hist->GetBinContent(col,row+1),   
+ 	  hist->GetBinContent(col+2,row+1),
+ 	  hist->GetBinContent(col,row+2),
+ 	  hist->GetBinContent(col+1,row+2),
+ 	  hist->GetBinContent(col+2,row+2)
+ 	  }  ;
+      std::sort( neighbours.begin(),neighbours.end());
+
+      if (col>0&&col<255&&row>0&&row<255) {
+	neighbours.erase(neighbours.begin(),neighbours.begin()+2);
+	neighbours.erase(neighbours.end()-2,neighbours.end());
+
+	double total(0.);
+	for (uint i=0;i<neighbours.size();i++) {
+	  //	  cout << neighbours[i] << " " ;
+	  total=total+neighbours[i];
+	  //	  cout << total<< " ";
+	}
+
+	if (count >10*total) {
+	  if (verbose)	  std::cout << "HOT  " << col << " " << row << endl;
+	  hotF << setw(3) << col << " "<< row << endl;
+	  continue;
+	}
+	if (count>20 && (count)<(total/neighbours.size()-4*sqrt(total/neighbours.size()))){
+	  if (verbose)	  std::cout << "LOW  " << col << " " << row <<  endl;
+	  lowF << setw(3) << col << " " << row << endl;
+	  continue;
+	}
+      }
+      
+      else  {
+	std::sort( neighbours.begin(),neighbours.end());
+	while(neighbours.front()==0) neighbours.erase(neighbours.begin());
+	double total(0);
+	for (uint i=0;i<neighbours.size();i++) {
+	  total=total+neighbours[i];
+	}
+	if (count >10*total) {
+	  if (verbose)	  std::cout << "HOT  " << col << " " << row << endl;
+	  hotF << setw(3) << col << " " << row <<  endl;
+	  continue;
+	}
+	if (count>20 && (count)<(total/neighbours.size()-4*sqrt(total/neighbours.size()))){
+	  if (verbose)	  std::cout << "LOW  " << col << " " << row <<  endl;
+	  lowF << setw(3) << col << " " << row << endl;
+	  continue;
+	}
+      }
+    }
+  }
+  deadF.close();
+  hotF.close();
+  lowF.close();
+}
+
+
+void PixelMapAnalysis(const char* filename, const char* outname, bool verbose=false){
+  
+  cout << "opening filename" << filename << endl;
+  TFile file(filename,"read");
+  file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys()->Print();
+  
+  TIter nextkey(file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys());
+
+  TKey *key;
+  
+  while((key= (TKey*) nextkey())) {
+    TH2D *hist = (TH2D*) key->ReadObj();
+    std::cout << "-------Now processing: " << key->GetName() << "-----------" <<endl;
+    PixelMapAnalysis(hist,Form("%s_%s",outname,key->GetName()),verbose);
+  }
+}
diff --git a/Kepler/Scripts/.svn/text-base/PixelMapAnalysis_Kepler.h.svn-base b/Kepler/Scripts/.svn/text-base/PixelMapAnalysis_Kepler.h.svn-base
new file mode 100644
index 0000000..48b5f91
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/PixelMapAnalysis_Kepler.h.svn-base
@@ -0,0 +1,71 @@
+#include "TFile.h"
+#include "TH2D.h"
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include "TROOT.h"
+#include "TKey.h"
+#include "TIterator.h"
+#include <string>
+
+/*
+......................................................................
+Author: Hella Snoek (hella.snoek@cern.ch)
+Date:   22.07.2014
+
+Simple ROOT analysis code to analyse the pixel hit maps for 
+ - DEAD: no hits
+ - HOT:  too many hits
+ - LOW:  too few hits
+pixel hits. 
+
+A pixel cell is compared to its 8 neighbouring (exception for pixel on
+the edge below) pixel cells. The 2 highest and 2 lowest hit counts
+are removed before making an average of the surrounding pixel cells.
+The minimum required count in a cell for the analysis is 20. 
+A HOT cell is 40 times higher than the average. 
+A LOW cell is 4  std deviations (sqrt) lower.
+
+For the cells on the edge of the sensor the highest and lowest hits
+are not removed for the average. 
+
+......................................................................
+ */ 
+
+using namespace std;
+ 
+void PixelMapAnalysis(TH2D* hist, unsigned int plane, ostream& os = std::cout ){
+ 
+  for (int col=0;col<256;col++){
+    for (int row=0;row<256;row++)
+    {
+       double count =     hist->GetBinContent(col+1,row+1);   
+
+       vector<double> neighbours;
+        for( int i = 0 ; i < 3; i++)
+        {
+          for(int j=0; j < 3; j++)
+          {
+            if( i == 1 && j == 1) continue;
+            neighbours.push_back( hist->GetBinContent( col +i, row +j ));
+          }
+        }
+	double total(0.);
+      if (col>0&&col<255&&row>0&&row<255) {
+	for (uint i=2;i<neighbours.size()-2;i++) total=total+neighbours[i];
+
+	if (count >10*total)
+	  os << plane << " "<< col << " "<< row << endl;
+      }
+      else  {
+	for (uint i=0;i<neighbours.size();i++)
+	  total=total+neighbours[i];
+
+	if (count >10*total)
+	  os << plane << " "<< col << " "<< row << endl;
+      }
+    }
+  }
+}
diff --git a/Kepler/Scripts/.svn/text-base/PixelMapAnalysis_KeplerConfig.cpp.svn-base b/Kepler/Scripts/.svn/text-base/PixelMapAnalysis_KeplerConfig.cpp.svn-base
new file mode 100644
index 0000000..022c1cd
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/PixelMapAnalysis_KeplerConfig.cpp.svn-base
@@ -0,0 +1,128 @@
+#include "TFile.h"
+#include "TH2D.h"
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include "TROOT.h"
+#include "TKey.h"
+#include "TIterator.h"
+
+/*
+......................................................................
+Author: Hella Snoek (hella.snoek@cern.ch)
+Date:   22.07.2014
+
+Simple ROOT analysis code to analyse the pixel hit maps for 
+ - DEAD: no hits
+ - HOT:  too many hits
+ - LOW:  too few hits
+pixel hits. 
+
+A pixel cell is compared to its 8 neighbouring (exception for pixel on
+the edge below) pixel cells. The 2 highest and 2 lowest hit counts
+are removed before making an average of the surrounding pixel cells.
+The minimum required count in a cell for the analysis is 20. 
+A HOT cell is 40 times higher than the average. 
+A LOW cell is 4  std deviations (sqrt) lower.
+
+For the cells on the edge of the sensor the highest and lowest hits
+are not removed for the average. 
+
+Three text files are produced. With the format
+col row
+
+Run this code as:
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\"\)
+or
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\",true\)
+for the verbose version.
+
+or call it with a hitmap:
+.L PixelMapAnalysis.cpp+
+PixelMapAnalysis(yourTH2D,"outputname",true);
+
+
+......................................................................
+ */
+ .* 
+
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+ 
+void PixelMapAnalysis(TH2D* hist, unsigned int plane, ostream& os = std::cout ){
+ 
+  for (int col=0;col<256;col++){
+    for (int row=0;row<256;row++){
+      double count =     hist->GetBinContent(col+1,row+1);   
+
+      vector<double> neighbours{
+      	hist->GetBinContent(col,row),   
+ 	  hist->GetBinContent(col+1,row),   
+ 	  hist->GetBinContent(col+2,row),
+ 	  hist->GetBinContent(col,row+1),   
+ 	  hist->GetBinContent(col+2,row+1),
+ 	  hist->GetBinContent(col,row+2),
+ 	  hist->GetBinContent(col+1,row+2),
+ 	  hist->GetBinContent(col+2,row+2)
+ 	  }  ;
+
+
+      if (col>0&&col<255&&row>0&&row<255) {
+	std::sort( neighbours.begin(),neighbours.end());
+	neighbours.erase(neighbours.begin(),neighbours.begin()+2);
+	neighbours.erase(neighbours.end()-2,neighbours.end());
+	double total(0.);
+	for (uint i=0;i<neighbours.size();i++) {
+	  //cout << neighbours[i] << " " ;
+	  total=total+neighbours[i];
+	  //	  cout << total<< " ";
+	}
+
+	if (count >10*total) {
+	  os << plane << setw(3) << " "<< setw(3) << col << " "<< row << endl;
+	}
+      }
+      
+      else  {
+	std::sort( neighbours.begin(),neighbours.end());
+	double total(0);
+	int active(neighbours.size());
+	for (uint i=0;i<neighbours.size();i++) {
+	  active=active-1;
+	  total=total+neighbours[i];
+	}
+	if (count >10*total) {
+	  os << setw(3) << col << " " << row <<  endl;
+	  continue;
+	}
+      }
+    }
+  }
+}
+
+
+void PixelMapAnalysis_KeplerConfig(const char* filename){
+  
+  cout << "opening filename" << endl;
+  TFile file(filename,"read");
+  file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys()->Print();
+
+  ofstream hotF(Form("%s_hot.dat",filename));
+  TIter nextkey(file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys());
+
+  TKey *key;
+  
+  while((key= (TKey*) nextkey())) {
+    TH2D *hist = (TH2D*) key->ReadObj();
+    std::cout << "-------Now processing: " << key->GetName() << "-----------" <<endl;
+    std::string name = key->GetName();
+    int plane(0);
+    sscanf( &name.back(), "%d", &plane );
+    PixelMapAnalysis(hist, plane, hotF);
+  }
+  hotF.close();
+}
diff --git a/Kepler/Scripts/.svn/text-base/UTDaemonScript.sh.svn-base b/Kepler/Scripts/.svn/text-base/UTDaemonScript.sh.svn-base
new file mode 100644
index 0000000..42f1696
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/UTDaemonScript.sh.svn-base
@@ -0,0 +1,27 @@
+#!/bin/bash
+. /etc/bashrc
+
+shopt -s expand_aliases
+
+. SetupProject.sh Kepler v3r0
+
+EOS_PATH=eos/lhcb/testbeam/ut/TelescopeData/Sept2015/
+EOS_CMD=/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select
+KEPLER=$KEPLERROOT/Scripts/Kepler
+OPT_PATH=$KEPLERROOT/options/
+OutputFolder=$EOS_PATH/RootFiles/Run$1/
+hist=$(pwd)/Kepler-histos.root
+tree=$(pwd)/Kepler-tuple.root 
+
+if [ -n "$2" ] ; then
+  echo "Running alignment of run $1 ($2)"
+  AlignmentFile=eos/lhcb/user/t/tevans/Alignment/Nov2015/Default_$2.dat
+  $KEPLER $1 -i $EOS_PATH/RawData/Run$1/ -a $AlignmentFile -o $OPT_PATH/align.py -h $hist -t $tree | tee Alignment_Run$1.std.out
+#  $EOS_CMD cp $(pwd)/Alignment_out.dat $EOS_PATH/RootFiles/Run$1/Conditions/Alignment$1mille.dat
+#  $EOS_CMD cp $(pwd)/Alignment_Run$1.std.out $EOS_PATH/RootFiles/Run$1/Output/Alignment_Run$1.std.out
+fi
+
+$KEPLER $1 -i $EOS_PATH/RawData/Run$1/  -a $EOS_PATH/RootFiles/Run$1/Conditions/Alignment$1mille.dat -o $OPT_PATH/tuple.py -h $hist -t $tree | tee Batch_Run$1.std.out
+#$EOS_CMD cp $(pwd)/Batch_Run$1.std.out $OutputFolder/Output/Batch_Run$1.std.out
+#$EOS_CMD cp $(pwd)/Kepler-histos.root  $OutputFolder/Output/Kepler-histos.root
+#$EOS_CMD cp $(pwd)/Kepler-tuple.root   $OutputFolder/Output/Kepler-tuple.root
diff --git a/Kepler/Scripts/.svn/text-base/spatialEfficiency.py.svn-base b/Kepler/Scripts/.svn/text-base/spatialEfficiency.py.svn-base
new file mode 100644
index 0000000..fb1c29d
--- /dev/null
+++ b/Kepler/Scripts/.svn/text-base/spatialEfficiency.py.svn-base
@@ -0,0 +1,32 @@
+from ROOT import *
+
+#gROOT.ProcessLine(".x lhcbStyle.C")
+gStyle.SetPalette(1)
+
+infile = TFile("Kepler-histos.root")
+infile.cd("Tb/TbClusterPlots")
+
+nPlanes = 8
+efficiencies = []
+for i in range(nPlanes):
+  histoname = "Plane" + repr(i)
+  hTotal = gDirectory.Get("Positions/" + histoname)
+  hPassed = gDirectory.Get("PositionsAssociated/" + histoname)
+  eff = TEfficiency(hPassed, hTotal)
+  eff.SetDirectory(0)
+  efficiencies.append(eff)
+infile.Close()
+
+gStyle.SetPaintTextFormat("3.2g")
+c = TCanvas("c", "c", 1200, 600)
+c.Divide(4, 2, 0, 0)
+for i in range(nPlanes):
+  c.cd(i + 1)
+  efficiencies[i].Draw("col")
+  #efficiencies[i].Draw("textsame")
+  efficiencies[i].Paint("col")
+  efficiencies[i].GetPaintedHistogram().GetXaxis().SetTitle("#font[12]{x} [mm]")
+  efficiencies[i].GetPaintedHistogram().GetYaxis().SetTitle("#font[12]{y} [mm]")
+  efficiencies[i].GetPaintedHistogram().SetMaximum(1.0)
+  c.Update()
+ 
diff --git a/Kepler/Scripts/DaemonScript.sh b/Kepler/Scripts/DaemonScript.sh
new file mode 100755
index 0000000..e16e7f9
--- /dev/null
+++ b/Kepler/Scripts/DaemonScript.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+. /etc/bashrc
+
+shopt -s expand_aliases
+
+EOS_PATH=/eos/lhcb/testbeam/velo/timepix3/Nov2015/
+EOS_CMD=/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select
+KEPLER=/afs/cern.ch/user/t/tevans/cmtuser/KEPLER/KEPLER_v3r0/Tb/Kepler/Scripts/Kepler
+OPT_PATH=/afs/cern.ch/user/t/tevans/cmtuser/KEPLER/KEPLER_v3r0/Tb/Kepler/options/
+OutputFolder=$EOS_PATH/RootFiles/Run$1/
+hist=$(pwd)/Kepler-histos.root
+tree=$(pwd)/Kepler-tuple.root 
+
+if [ -n "$2" ] ; then
+  echo "Running alignment of run $1 ($2)"
+  AlignmentFile=eos/lhcb/user/t/tevans/Alignment/Nov2015/Default_$2.dat
+  $KEPLER $1 -a $AlignmentFile -o $OPT_PATH/align.py -h $hist -t $tree | tee Alignment_Run$1.std.out
+  $EOS_CMD cp $(pwd)/Alignment_out.dat $EOS_PATH/RootFiles/Run$1/Conditions/Alignment$1mille.dat
+  $EOS_CMD cp $(pwd)/Alignment_Run$1.std.out $EOS_PATH/RootFiles/Run$1/Output/Alignment_Run$1.std.out
+fi
+
+$KEPLER $1 -o $OPT_PATH/tuple.py -h $hist -t $tree | tee Batch_Run$1.std.out
+
+$EOS_CMD cp $(pwd)/Batch_Run$1.std.out $OutputFolder/Output/Batch_Run$1.std.out
+$EOS_CMD cp $(pwd)/Kepler-histos.root  $OutputFolder/Output/Kepler-histos.root
+$EOS_CMD cp $(pwd)/Kepler-tuple.root   $OutputFolder/Output/Kepler-tuple.root
+
diff --git a/Kepler/Scripts/Kepler b/Kepler/Scripts/Kepler
new file mode 100755
index 0000000..e4c3a78
--- /dev/null
+++ b/Kepler/Scripts/Kepler
@@ -0,0 +1,97 @@
+#!/bin/bash
+. /etc/bashrc
+
+scratch=$(pwd)
+shopt -s expand_aliases
+export eospath=eos/lhcb/testbeam/velo/timepix3/
+
+if [ -z $KEPLERSYS ]; then . SetupProject.sh Kepler v3r0; fi
+
+tb=July2014
+if [ "$1" -gt "2000" ]; then tb=Oct2014; fi
+if [ "$1" -gt "3000" ]; then tb=Nov2014; fi
+if [ "$1" -gt "3999" ]; then tb=Dec2014; fi
+if [ "$1" -gt "4999" ]; then tb=May2015; fi
+if [ "$1" -gt "6733" ]; then tb=July2015; fi
+if [ "$1" -gt "12000" ]; then tb=Sep2015; fi
+if [ "$1" -gt "13509" ]; then tb=Nov2015; fi
+# TBDATA
+if [ -z "$DATADIR" ]; then
+  echo "No output directory defined - define variable $DATADIR"
+fi
+TBDATA=$DATADIR/public/
+
+mkdir -p $TBDATA/$tb/Run$1/
+
+RUN=$1
+echo "Processing Run $1"
+
+condFolder="$eospath/$tb/RootFiles/Run$1/Conditions/"
+input_option="Kepler().InputFiles=['$eospath/$tb/RawData/Run$RUN/']"
+alignment="Kepler().AlignmentFile='$condFolder/Alignment$1mille.dat'"
+job="../options/batch.py"
+
+histo_file="Kepler().HistogramFile='$TBDATA/$tb/Run$RUN/Kepler-histos.root'"
+tuple_file="Kepler().TupleFile='$TBDATA/$tb/Run$RUN/Kepler-tuple.root'"
+log_file=$TBDATA/$tb/Run$1/Run$1.std.out
+alignment_out="TbAlignment().OutputAlignmentFile='Alignment_out.dat'"
+
+while [[ $# > 1 ]]
+do
+  key="$1"
+  case $key in
+    -o|--options) # specify the options file to use 
+      job="$2"
+      shift # past argument
+      ;;
+    -a|--alignment) #specify an alignment file 
+      alignment="Kepler().AlignmentFile='$2'"
+      shift # past argument
+      ;;
+    -ao|--alignmentOut) #specify alignment file output
+      alignment_out="TbAlignment().OutputAlignmentFile='$2'"
+      shift
+      ;;
+    -i|--input)
+      input_option="Kepler().InputFiles=['$2']"
+      shift
+      ;;
+    -h|--hist) #specify histogram output
+      histo_file="Kepler().HistogramFile='$2'"
+      shift
+      ;;
+    -t|--nTuple) #specify nTuple output
+      tuple_file="Kepler().TupleFile='$2'"
+      shift
+      ;;
+    -lg|--log) #specify text log location
+      log_file=$2
+      shift
+      ;;
+    -l|--local) #use "local" mode for H8 operations
+      input_option="Kepler().InputFiles=["
+      FILES=""
+      for f in {0..10}; do
+        for file in /mnt/DATA/Dev$f/Run$RUN/*.dat ; do
+          FILES+="'$file',"
+        done
+      done
+      input_option+=`echo $FILES | sed 's/.$//'`
+      input_option+="]"
+      echo $input_option
+      ;;
+    -n|--nEvents) #specify a number of events
+      nEvents="Kepler().EvtMax=$2"
+      shift
+      ;;
+    --default)
+      DEFAULT=YES
+      ;;
+    *)
+      # unknown option
+      ;;
+  esac
+  shift # past argument or value
+done
+
+gaudirun.py --option="from Configurables import Kepler, TbAlignment" --option=$histo_file --option=$tuple_file --option=$alignment_out --option=$nEvents  --option=$alignment --option=$input_option $job |& tee $TBDATA/$tb/Run$1/Run$1.std.out
diff --git a/Kepler/Scripts/PixelMapAnalysis.cpp b/Kepler/Scripts/PixelMapAnalysis.cpp
new file mode 100644
index 0000000..2cbc2a8
--- /dev/null
+++ b/Kepler/Scripts/PixelMapAnalysis.cpp
@@ -0,0 +1,144 @@
+#include "TFile.h"
+#include "TH2D.h"
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include "TROOT.h"
+#include "TKey.h"
+#include "TIterator.h"
+
+/*
+......................................................................
+Author: Hella Snoek (hella.snoek@cern.ch)
+Date:   22.07.2014
+
+Simple ROOT analysis code to analyse the pixel hit maps for 
+ - DEAD: no hits
+ - HOT:  too many hits
+ - LOW:  too few hits
+pixel hits. 
+
+A pixel cell is compared to its 8 neighbouring (exception for pixel on
+the edge below) pixel cells. The 2 highest and 2 lowest hit counts
+are removed before making an average of the surrounding pixel cells.
+The minimum required count in a cell for the analysis is 20. 
+A HOT cell is 40 times higher than the average. 
+A LOW cell is 4  std deviations (sqrt) lower.
+
+For the cells on the edge of the sensor the highest and lowest hits
+are not removed for the average. 
+
+Three text files are produced. With the format
+col row
+
+Run this code as:
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\"\)
+or
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\",true\)
+for the verbose version.
+
+or call it with a hitmap:
+.L PixelMapAnalysis.cpp+
+PixelMapAnalysis(yourTH2D,"outputname",true);
+
+
+......................................................................
+ */
+
+using namespace std;
+ 
+void PixelMapAnalysis(TH2D* hist, const char* outname, bool verbose=false){
+ 
+  ofstream deadF(Form("%s_dead.txt",outname));
+  ofstream hotF(Form("%s_hot.txt",outname));
+  ofstream lowF(Form("%s_low.txt",outname));
+  
+  for (int col=0;col<256;col++){
+    for (int row=0;row<256;row++){
+      double count =     hist->GetBinContent(col+1,row+1);   
+
+      if (count ==0 ) {
+	if (verbose)	std::cout << "DEAD " << col << " " << row << endl;
+	deadF << setw(3) << col << " " << row <<  endl;
+	continue;
+      }
+
+      vector<double> neighbours{
+      	hist->GetBinContent(col,row),   
+ 	  hist->GetBinContent(col+1,row),   
+ 	  hist->GetBinContent(col+2,row),
+ 	  hist->GetBinContent(col,row+1),   
+ 	  hist->GetBinContent(col+2,row+1),
+ 	  hist->GetBinContent(col,row+2),
+ 	  hist->GetBinContent(col+1,row+2),
+ 	  hist->GetBinContent(col+2,row+2)
+ 	  }  ;
+      std::sort( neighbours.begin(),neighbours.end());
+
+      if (col>0&&col<255&&row>0&&row<255) {
+	neighbours.erase(neighbours.begin(),neighbours.begin()+2);
+	neighbours.erase(neighbours.end()-2,neighbours.end());
+
+	double total(0.);
+	for (uint i=0;i<neighbours.size();i++) {
+	  //	  cout << neighbours[i] << " " ;
+	  total=total+neighbours[i];
+	  //	  cout << total<< " ";
+	}
+
+	if (count >10*total) {
+	  if (verbose)	  std::cout << "HOT  " << col << " " << row << endl;
+	  hotF << setw(3) << col << " "<< row << endl;
+	  continue;
+	}
+	if (count>20 && (count)<(total/neighbours.size()-4*sqrt(total/neighbours.size()))){
+	  if (verbose)	  std::cout << "LOW  " << col << " " << row <<  endl;
+	  lowF << setw(3) << col << " " << row << endl;
+	  continue;
+	}
+      }
+      
+      else  {
+	std::sort( neighbours.begin(),neighbours.end());
+	while(neighbours.front()==0) neighbours.erase(neighbours.begin());
+	double total(0);
+	for (uint i=0;i<neighbours.size();i++) {
+	  total=total+neighbours[i];
+	}
+	if (count >10*total) {
+	  if (verbose)	  std::cout << "HOT  " << col << " " << row << endl;
+	  hotF << setw(3) << col << " " << row <<  endl;
+	  continue;
+	}
+	if (count>20 && (count)<(total/neighbours.size()-4*sqrt(total/neighbours.size()))){
+	  if (verbose)	  std::cout << "LOW  " << col << " " << row <<  endl;
+	  lowF << setw(3) << col << " " << row << endl;
+	  continue;
+	}
+      }
+    }
+  }
+  deadF.close();
+  hotF.close();
+  lowF.close();
+}
+
+
+void PixelMapAnalysis(const char* filename, const char* outname, bool verbose=false){
+  
+  cout << "opening filename" << filename << endl;
+  TFile file(filename,"read");
+  file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys()->Print();
+  
+  TIter nextkey(file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys());
+
+  TKey *key;
+  
+  while((key= (TKey*) nextkey())) {
+    TH2D *hist = (TH2D*) key->ReadObj();
+    std::cout << "-------Now processing: " << key->GetName() << "-----------" <<endl;
+    PixelMapAnalysis(hist,Form("%s_%s",outname,key->GetName()),verbose);
+  }
+}
diff --git a/Kepler/Scripts/PixelMapAnalysis_Kepler.h b/Kepler/Scripts/PixelMapAnalysis_Kepler.h
new file mode 100644
index 0000000..48b5f91
--- /dev/null
+++ b/Kepler/Scripts/PixelMapAnalysis_Kepler.h
@@ -0,0 +1,71 @@
+#include "TFile.h"
+#include "TH2D.h"
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include "TROOT.h"
+#include "TKey.h"
+#include "TIterator.h"
+#include <string>
+
+/*
+......................................................................
+Author: Hella Snoek (hella.snoek@cern.ch)
+Date:   22.07.2014
+
+Simple ROOT analysis code to analyse the pixel hit maps for 
+ - DEAD: no hits
+ - HOT:  too many hits
+ - LOW:  too few hits
+pixel hits. 
+
+A pixel cell is compared to its 8 neighbouring (exception for pixel on
+the edge below) pixel cells. The 2 highest and 2 lowest hit counts
+are removed before making an average of the surrounding pixel cells.
+The minimum required count in a cell for the analysis is 20. 
+A HOT cell is 40 times higher than the average. 
+A LOW cell is 4  std deviations (sqrt) lower.
+
+For the cells on the edge of the sensor the highest and lowest hits
+are not removed for the average. 
+
+......................................................................
+ */ 
+
+using namespace std;
+ 
+void PixelMapAnalysis(TH2D* hist, unsigned int plane, ostream& os = std::cout ){
+ 
+  for (int col=0;col<256;col++){
+    for (int row=0;row<256;row++)
+    {
+       double count =     hist->GetBinContent(col+1,row+1);   
+
+       vector<double> neighbours;
+        for( int i = 0 ; i < 3; i++)
+        {
+          for(int j=0; j < 3; j++)
+          {
+            if( i == 1 && j == 1) continue;
+            neighbours.push_back( hist->GetBinContent( col +i, row +j ));
+          }
+        }
+	double total(0.);
+      if (col>0&&col<255&&row>0&&row<255) {
+	for (uint i=2;i<neighbours.size()-2;i++) total=total+neighbours[i];
+
+	if (count >10*total)
+	  os << plane << " "<< col << " "<< row << endl;
+      }
+      else  {
+	for (uint i=0;i<neighbours.size();i++)
+	  total=total+neighbours[i];
+
+	if (count >10*total)
+	  os << plane << " "<< col << " "<< row << endl;
+      }
+    }
+  }
+}
diff --git a/Kepler/Scripts/PixelMapAnalysis_KeplerConfig.cpp b/Kepler/Scripts/PixelMapAnalysis_KeplerConfig.cpp
new file mode 100644
index 0000000..022c1cd
--- /dev/null
+++ b/Kepler/Scripts/PixelMapAnalysis_KeplerConfig.cpp
@@ -0,0 +1,128 @@
+#include "TFile.h"
+#include "TH2D.h"
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include "TROOT.h"
+#include "TKey.h"
+#include "TIterator.h"
+
+/*
+......................................................................
+Author: Hella Snoek (hella.snoek@cern.ch)
+Date:   22.07.2014
+
+Simple ROOT analysis code to analyse the pixel hit maps for 
+ - DEAD: no hits
+ - HOT:  too many hits
+ - LOW:  too few hits
+pixel hits. 
+
+A pixel cell is compared to its 8 neighbouring (exception for pixel on
+the edge below) pixel cells. The 2 highest and 2 lowest hit counts
+are removed before making an average of the surrounding pixel cells.
+The minimum required count in a cell for the analysis is 20. 
+A HOT cell is 40 times higher than the average. 
+A LOW cell is 4  std deviations (sqrt) lower.
+
+For the cells on the edge of the sensor the highest and lowest hits
+are not removed for the average. 
+
+Three text files are produced. With the format
+col row
+
+Run this code as:
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\"\)
+or
+root -b -q PixelMapAnalysis.cpp+\(\"inputfilename\",\"outputname\",true\)
+for the verbose version.
+
+or call it with a hitmap:
+.L PixelMapAnalysis.cpp+
+PixelMapAnalysis(yourTH2D,"outputname",true);
+
+
+......................................................................
+ */
+ .* 
+
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+ 
+void PixelMapAnalysis(TH2D* hist, unsigned int plane, ostream& os = std::cout ){
+ 
+  for (int col=0;col<256;col++){
+    for (int row=0;row<256;row++){
+      double count =     hist->GetBinContent(col+1,row+1);   
+
+      vector<double> neighbours{
+      	hist->GetBinContent(col,row),   
+ 	  hist->GetBinContent(col+1,row),   
+ 	  hist->GetBinContent(col+2,row),
+ 	  hist->GetBinContent(col,row+1),   
+ 	  hist->GetBinContent(col+2,row+1),
+ 	  hist->GetBinContent(col,row+2),
+ 	  hist->GetBinContent(col+1,row+2),
+ 	  hist->GetBinContent(col+2,row+2)
+ 	  }  ;
+
+
+      if (col>0&&col<255&&row>0&&row<255) {
+	std::sort( neighbours.begin(),neighbours.end());
+	neighbours.erase(neighbours.begin(),neighbours.begin()+2);
+	neighbours.erase(neighbours.end()-2,neighbours.end());
+	double total(0.);
+	for (uint i=0;i<neighbours.size();i++) {
+	  //cout << neighbours[i] << " " ;
+	  total=total+neighbours[i];
+	  //	  cout << total<< " ";
+	}
+
+	if (count >10*total) {
+	  os << plane << setw(3) << " "<< setw(3) << col << " "<< row << endl;
+	}
+      }
+      
+      else  {
+	std::sort( neighbours.begin(),neighbours.end());
+	double total(0);
+	int active(neighbours.size());
+	for (uint i=0;i<neighbours.size();i++) {
+	  active=active-1;
+	  total=total+neighbours[i];
+	}
+	if (count >10*total) {
+	  os << setw(3) << col << " " << row <<  endl;
+	  continue;
+	}
+      }
+    }
+  }
+}
+
+
+void PixelMapAnalysis_KeplerConfig(const char* filename){
+  
+  cout << "opening filename" << endl;
+  TFile file(filename,"read");
+  file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys()->Print();
+
+  ofstream hotF(Form("%s_hot.dat",filename));
+  TIter nextkey(file.GetDirectory("Tb/TbHitMonitor/HitMap")->GetListOfKeys());
+
+  TKey *key;
+  
+  while((key= (TKey*) nextkey())) {
+    TH2D *hist = (TH2D*) key->ReadObj();
+    std::cout << "-------Now processing: " << key->GetName() << "-----------" <<endl;
+    std::string name = key->GetName();
+    int plane(0);
+    sscanf( &name.back(), "%d", &plane );
+    PixelMapAnalysis(hist, plane, hotF);
+  }
+  hotF.close();
+}
diff --git a/Kepler/Scripts/UTDaemonScript.sh b/Kepler/Scripts/UTDaemonScript.sh
new file mode 100755
index 0000000..42f1696
--- /dev/null
+++ b/Kepler/Scripts/UTDaemonScript.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+. /etc/bashrc
+
+shopt -s expand_aliases
+
+. SetupProject.sh Kepler v3r0
+
+EOS_PATH=eos/lhcb/testbeam/ut/TelescopeData/Sept2015/
+EOS_CMD=/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select
+KEPLER=$KEPLERROOT/Scripts/Kepler
+OPT_PATH=$KEPLERROOT/options/
+OutputFolder=$EOS_PATH/RootFiles/Run$1/
+hist=$(pwd)/Kepler-histos.root
+tree=$(pwd)/Kepler-tuple.root 
+
+if [ -n "$2" ] ; then
+  echo "Running alignment of run $1 ($2)"
+  AlignmentFile=eos/lhcb/user/t/tevans/Alignment/Nov2015/Default_$2.dat
+  $KEPLER $1 -i $EOS_PATH/RawData/Run$1/ -a $AlignmentFile -o $OPT_PATH/align.py -h $hist -t $tree | tee Alignment_Run$1.std.out
+#  $EOS_CMD cp $(pwd)/Alignment_out.dat $EOS_PATH/RootFiles/Run$1/Conditions/Alignment$1mille.dat
+#  $EOS_CMD cp $(pwd)/Alignment_Run$1.std.out $EOS_PATH/RootFiles/Run$1/Output/Alignment_Run$1.std.out
+fi
+
+$KEPLER $1 -i $EOS_PATH/RawData/Run$1/  -a $EOS_PATH/RootFiles/Run$1/Conditions/Alignment$1mille.dat -o $OPT_PATH/tuple.py -h $hist -t $tree | tee Batch_Run$1.std.out
+#$EOS_CMD cp $(pwd)/Batch_Run$1.std.out $OutputFolder/Output/Batch_Run$1.std.out
+#$EOS_CMD cp $(pwd)/Kepler-histos.root  $OutputFolder/Output/Kepler-histos.root
+#$EOS_CMD cp $(pwd)/Kepler-tuple.root   $OutputFolder/Output/Kepler-tuple.root
diff --git a/Kepler/Scripts/spatialEfficiency.py b/Kepler/Scripts/spatialEfficiency.py
new file mode 100644
index 0000000..fb1c29d
--- /dev/null
+++ b/Kepler/Scripts/spatialEfficiency.py
@@ -0,0 +1,32 @@
+from ROOT import *
+
+#gROOT.ProcessLine(".x lhcbStyle.C")
+gStyle.SetPalette(1)
+
+infile = TFile("Kepler-histos.root")
+infile.cd("Tb/TbClusterPlots")
+
+nPlanes = 8
+efficiencies = []
+for i in range(nPlanes):
+  histoname = "Plane" + repr(i)
+  hTotal = gDirectory.Get("Positions/" + histoname)
+  hPassed = gDirectory.Get("PositionsAssociated/" + histoname)
+  eff = TEfficiency(hPassed, hTotal)
+  eff.SetDirectory(0)
+  efficiencies.append(eff)
+infile.Close()
+
+gStyle.SetPaintTextFormat("3.2g")
+c = TCanvas("c", "c", 1200, 600)
+c.Divide(4, 2, 0, 0)
+for i in range(nPlanes):
+  c.cd(i + 1)
+  efficiencies[i].Draw("col")
+  #efficiencies[i].Draw("textsame")
+  efficiencies[i].Paint("col")
+  efficiencies[i].GetPaintedHistogram().GetXaxis().SetTitle("#font[12]{x} [mm]")
+  efficiencies[i].GetPaintedHistogram().GetYaxis().SetTitle("#font[12]{y} [mm]")
+  efficiencies[i].GetPaintedHistogram().SetMaximum(1.0)
+  c.Update()
+ 
diff --git a/Kepler/cmt/.svn/all-wcprops b/Kepler/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..14e4296
--- /dev/null
+++ b/Kepler/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/guest/lhcb/!svn/ver/188501/Kepler/trunk/Tb/Kepler/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/188501/Kepler/trunk/Tb/Kepler/cmt/requirements
+END
diff --git a/Kepler/cmt/.svn/entries b/Kepler/cmt/.svn/entries
new file mode 100644
index 0000000..88c326e
--- /dev/null
+++ b/Kepler/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T11:48:07.231852Z
+188501
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:46.000000Z
+8f1af8a98aab3013e62717fb6945e536
+2015-05-19T11:48:07.231852Z
+188501
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1172
+
diff --git a/Kepler/cmt/.svn/text-base/requirements.svn-base b/Kepler/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..682d264
--- /dev/null
+++ b/Kepler/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,36 @@
+package Kepler
+version v3r0
+
+branches doc cmt options tests
+
+# Packages needed to compile and link the application
+use GaudiConf          v*           -no_auto_imports
+use GaudiKernel        v*
+
+# Packages needed to resolve external dependencies at run time
+use Python             v*    LCG_Interfaces -no_auto_imports
+
+# The rest are needed only to set up environment variables for job options
+# and to give a cmt broadcast dependency for user checked out component packages
+
+# From GAUDI project
+use GaudiSvc           v*           -no_auto_imports
+use GaudiPython        v*           -no_auto_imports
+use Gaudi              v*           -no_auto_imports
+#use GaudiOnline        v*    Online -no_auto_imports
+
+# Testbeam specific packages
+use TbAlgorithms       v*    Tb     -no_auto_imports
+use TbIO               v*    Tb     -no_auto_imports
+use TbKernel           v*    Tb
+
+# Requirements to use Ganga
+use DDDB                       v*     Det     -no_auto_imports
+use LHCbAlgs                   v*    Kernel   -no_auto_imports
+
+# Setup the application
+apply_pattern application_path
+apply_pattern install_python_modules
+apply_pattern GaudiApp
+apply_pattern QMTest
+
diff --git a/Kepler/cmt/requirements b/Kepler/cmt/requirements
new file mode 100644
index 0000000..682d264
--- /dev/null
+++ b/Kepler/cmt/requirements
@@ -0,0 +1,36 @@
+package Kepler
+version v3r0
+
+branches doc cmt options tests
+
+# Packages needed to compile and link the application
+use GaudiConf          v*           -no_auto_imports
+use GaudiKernel        v*
+
+# Packages needed to resolve external dependencies at run time
+use Python             v*    LCG_Interfaces -no_auto_imports
+
+# The rest are needed only to set up environment variables for job options
+# and to give a cmt broadcast dependency for user checked out component packages
+
+# From GAUDI project
+use GaudiSvc           v*           -no_auto_imports
+use GaudiPython        v*           -no_auto_imports
+use Gaudi              v*           -no_auto_imports
+#use GaudiOnline        v*    Online -no_auto_imports
+
+# Testbeam specific packages
+use TbAlgorithms       v*    Tb     -no_auto_imports
+use TbIO               v*    Tb     -no_auto_imports
+use TbKernel           v*    Tb
+
+# Requirements to use Ganga
+use DDDB                       v*     Det     -no_auto_imports
+use LHCbAlgs                   v*    Kernel   -no_auto_imports
+
+# Setup the application
+apply_pattern application_path
+apply_pattern install_python_modules
+apply_pattern GaudiApp
+apply_pattern QMTest
+
diff --git a/Kepler/doc/.svn/all-wcprops b/Kepler/doc/.svn/all-wcprops
new file mode 100644
index 0000000..7d1e609
--- /dev/null
+++ b/Kepler/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/guest/lhcb/!svn/ver/188501/Kepler/trunk/Tb/Kepler/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/188501/Kepler/trunk/Tb/Kepler/doc/release.notes
+END
diff --git a/Kepler/doc/.svn/entries b/Kepler/doc/.svn/entries
new file mode 100644
index 0000000..24a79f4
--- /dev/null
+++ b/Kepler/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T11:48:07.231852Z
+188501
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+b9989803386d96e76635c55d6bfb9d74
+2015-05-19T11:48:07.231852Z
+188501
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+964
+
diff --git a/Kepler/doc/.svn/prop-base/release.notes.svn-base b/Kepler/doc/.svn/prop-base/release.notes.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/Kepler/doc/.svn/prop-base/release.notes.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/Kepler/doc/.svn/text-base/release.notes.svn-base b/Kepler/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..e357f8b
--- /dev/null
+++ b/Kepler/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,30 @@
+<PRE>
+Package: Tb/Kepler
+Package Coordinator: Tim Evans and Heinrich Schindler
+Purpose: testbeam analysis program
+</PRE>
+
+<H1><A NAME=v3r0>2015-05-19 Kepler v3r0</A></H1>
+
+ - Add Ganga plugin.
+ - Add TbClusterAssociator and TbDUTMonitor to Telescope/Monitoring sequence.
+
+<H1><A NAME=v2r1>2014-11-30 Kepler v2r1</A></H1>
+
+- New flag to switch on/off tracking.
+- New sequence UserAlgorithms.
+- Updated QMTest.
+ 
+<H1><A NAME=v2r0>2014-08-19 Kepler v2r0</A></H1>
+
+- Release of the application as used at the end of the July/August PS testbeam
+  . Add flags to switch on/off alignment, monitoring, and tuple output.
+  . Add property PixelConfigFile.
+  . Add TbPixelSvc and TbTimingSvc to services.
+  . Add option files for Minuit and Millepede alignment.
+  . Add directory Scripts with post-processing analysis scripts. 
+  . QMTest based on real data.
+
+<H1><A NAME=v1r0>2014-05-30 Kepler v1r0</A></H1>
+
+- First version of Timepix3 telescope reconstruction application
diff --git a/Kepler/doc/release.notes b/Kepler/doc/release.notes
new file mode 100755
index 0000000..e357f8b
--- /dev/null
+++ b/Kepler/doc/release.notes
@@ -0,0 +1,30 @@
+<PRE>
+Package: Tb/Kepler
+Package Coordinator: Tim Evans and Heinrich Schindler
+Purpose: testbeam analysis program
+</PRE>
+
+<H1><A NAME=v3r0>2015-05-19 Kepler v3r0</A></H1>
+
+ - Add Ganga plugin.
+ - Add TbClusterAssociator and TbDUTMonitor to Telescope/Monitoring sequence.
+
+<H1><A NAME=v2r1>2014-11-30 Kepler v2r1</A></H1>
+
+- New flag to switch on/off tracking.
+- New sequence UserAlgorithms.
+- Updated QMTest.
+ 
+<H1><A NAME=v2r0>2014-08-19 Kepler v2r0</A></H1>
+
+- Release of the application as used at the end of the July/August PS testbeam
+  . Add flags to switch on/off alignment, monitoring, and tuple output.
+  . Add property PixelConfigFile.
+  . Add TbPixelSvc and TbTimingSvc to services.
+  . Add option files for Minuit and Millepede alignment.
+  . Add directory Scripts with post-processing analysis scripts. 
+  . QMTest based on real data.
+
+<H1><A NAME=v1r0>2014-05-30 Kepler v1r0</A></H1>
+
+- First version of Timepix3 telescope reconstruction application
diff --git a/Kepler/options/.svn/all-wcprops b/Kepler/options/.svn/all-wcprops
new file mode 100644
index 0000000..2909906
--- /dev/null
+++ b/Kepler/options/.svn/all-wcprops
@@ -0,0 +1,59 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/guest/lhcb/!svn/ver/197726/Kepler/trunk/Tb/Kepler/options
+END
+example.py
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/197520/Kepler/trunk/Tb/Kepler/options/example.py
+END
+EmptyPixelMask.dat
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/178010/Kepler/trunk/Tb/Kepler/options/EmptyPixelMask.dat
+END
+MaskPixels.dat
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/176251/Kepler/trunk/Tb/Kepler/options/MaskPixels.dat
+END
+batch.py
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/batch.py
+END
+singleChipExample.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/178010/Kepler/trunk/Tb/Kepler/options/singleChipExample.py
+END
+TbTrackingWithKalman.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/178725/Kepler/trunk/Tb/Kepler/options/TbTrackingWithKalman.cpp
+END
+efficiency.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197726/Kepler/trunk/Tb/Kepler/options/efficiency.py
+END
+debug.py
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/176280/Kepler/trunk/Tb/Kepler/options/debug.py
+END
+TbTrackingWithKalman.h
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/178726/Kepler/trunk/Tb/Kepler/options/TbTrackingWithKalman.h
+END
diff --git a/Kepler/options/.svn/entries b/Kepler/options/.svn/entries
new file mode 100644
index 0000000..ac9e53a
--- /dev/null
+++ b/Kepler/options/.svn/entries
@@ -0,0 +1,352 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-17T13:18:40.094527Z
+197726
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+example.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+f905f98f12fb64899d3a9851c858f8d6
+2015-11-12T16:32:14.477020Z
+197520
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1188
+
+EmptyPixelMask.dat
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+571422dc8d79730cdd4d839ff0dc8c2f
+2014-09-26T19:44:39.626662Z
+178010
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+22
+
+online
+dir
+
+MaskPixels.dat
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+1ce17e27110bedd69c6ee1bd5606b5e1
+2014-08-11T14:54:15.630649Z
+176251
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+132
+
+singleChipExample.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+3852d5610e7b0528ae1074fd16219511
+2014-09-26T19:44:39.626662Z
+178010
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+983
+
+TbTrackingWithKalman.cpp
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+0ff4ba9d4ee94e82ca24c6faf4a40204
+2014-10-12T09:43:57.711037Z
+178725
+ptsopela
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21913
+
+ResStudies
+dir
+
+efficiency.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+a6a5ecb632688a58ed92bdb53b9047d6
+2015-11-17T13:18:40.094527Z
+197726
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3649
+
+TbTrackingWithKalman.h
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+48dfd50efccb18ebb3084343e532cb63
+2014-10-12T09:44:10.893545Z
+178726
+ptsopela
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3854
+
+tracking
+dir
+
+combat
+dir
+
+trackfit
+dir
+
+batch.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+d4c6c756e7d720ec1ecf45267433f734
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+689
+
+debug.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+eed868663175383e09c68251a25082e9
+2014-08-12T21:49:58.392398Z
+176280
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+355
+
+alignment
+dir
+
diff --git a/Kepler/options/.svn/text-base/EmptyPixelMask.dat.svn-base b/Kepler/options/.svn/text-base/EmptyPixelMask.dat.svn-base
new file mode 100644
index 0000000..1ebde38
--- /dev/null
+++ b/Kepler/options/.svn/text-base/EmptyPixelMask.dat.svn-base
@@ -0,0 +1 @@
+# ChipName column row
diff --git a/Kepler/options/.svn/text-base/MaskPixels.dat.svn-base b/Kepler/options/.svn/text-base/MaskPixels.dat.svn-base
new file mode 100644
index 0000000..6c54a4e
--- /dev/null
+++ b/Kepler/options/.svn/text-base/MaskPixels.dat.svn-base
@@ -0,0 +1,6 @@
+# Device   column row
+W0002_J06   139   162
+W0002_E05     6   217
+W0002_E05     7    35
+W0002_E05   155    40
+W0002_E05   156    40
diff --git a/Kepler/options/.svn/text-base/TbTrackingWithKalman.cpp.svn-base b/Kepler/options/.svn/text-base/TbTrackingWithKalman.cpp.svn-base
new file mode 100644
index 0000000..9ec4850
--- /dev/null
+++ b/Kepler/options/.svn/text-base/TbTrackingWithKalman.cpp.svn-base
@@ -0,0 +1,548 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiKernel/AlgFactory.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+
+// ROOT
+#include "TMath.h"
+
+#include <iostream>
+#include <math.h>
+
+// Local
+#include "TbTracking.h"
+#include <algorithm>
+
+DECLARE_ALGORITHM_FACTORY(TbTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTracking::TbTracking(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_tracks(NULL),
+      m_trackFit(NULL),
+      m_clusterFinder(NULL) {
+
+  lowR = -0.2;
+  highR = 0.2;
+  binsR = 500;
+  
+  lowS = -0.02;
+  highS = 0.02;
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("Monitoring", m_monitoring = false);
+  declareProperty("HitError2", m_hiterror2 = 1.6e-5);
+  declareProperty("Scat2", m_scat2 = 1.2e-8);
+  declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
+  declareProperty("MinNClusters", m_MinNClusters = 7);
+  declareProperty("SearchRadius", m_vol_radius = 1 * Gaudi::Units::mm);
+  declareProperty("SearchRadiusY", m_vol_radiusY = 1 * Gaudi::Units::mm);
+  declareProperty("MaxChi2", m_ChiSqRedCut = 20000.);
+  declareProperty("SearchVolume", m_search_3vol = "diabolo");
+  declareProperty("VolumeAngle", m_vol_theta = 0.015);
+  declareProperty("VolumeAngleY", m_vol_thetaY = 0.005);
+  declareProperty("SearchVolumeFillAlgorithm",
+                  m_ClusterFinderSearchAlgorithm = "adap_seq");
+  declareProperty("nComboCut", m_nComboCut = 300);
+  declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTracking::~TbTracking() {
+
+  if (m_clusterFinder) delete m_clusterFinder;
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTracking::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  // Set up the cluster finder.
+  m_clusterFinder =
+      new TbClusterFinder(m_ClusterFinderSearchAlgorithm, m_nPlanes);
+  
+  // setup Kalman histos
+  setup_hists();
+  
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTracking::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      error() << "No clusters in " << clusterLocation << endmsg;
+      return StatusCode::FAILURE;
+    }
+    // Store the cluster iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+  }
+  
+  // Clear Kalman track container
+  ktracks_vec.clear();
+
+
+  // Create a track container and transfer its ownership to the TES.
+  m_tracks = new LHCb::TbTracks();
+  put(m_tracks, LHCb::TbTrackLocation::Default);
+
+  // Do the tracking and time order.
+  performTracking();
+  timeOrderTracks();
+
+  // fill the histos with the Kalman fit results
+  fill_khists(ktracks_vec);
+
+  counter("NumberOfTracks") += m_tracks->size();
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Actual tracking
+//=============================================================================
+void TbTracking::performTracking() {
+  // The working of this algorithm is similar to the cluster maker, such that:
+  // - Loop over some set of seed clusters (those on the m_SeedPlanes).
+  // - Create a container (TbTrackVolume) centered on each seed cluster
+  // (in space and time).
+  // - Impose the condition that any formed track must contain this seed.
+  // - Evaluate that 4-volume, to see if it contained a track.
+  // - If a choice (e.g. more than one possible combination of clusters),
+  // take the best fitting. Priority is given to more complete tracks.
+  // - If another track happened to be in the 4volume, but not
+  //   containing this seed, then it will be found later.
+
+  // Iterate over planes in the specified order.
+  for (const auto& plane : m_PlaneSearchOrder) {
+    // Iterate over this planes' clusters - first check for any.
+    if (masked(plane) || m_clusterFinder->empty(plane)) continue;
+    auto ic = m_clusterFinder->first(plane);
+    const auto end = m_clusterFinder->end(plane);
+    for (; ic != end; ++ic) {
+
+      // Check if the seed has already been used.
+      if ((*ic)->tracked()) continue;
+      // Form the TbTrackVolume container, and fill with clusters that fall
+      // in its space-time volume.
+      TbTrackVolume* track_volume =
+          new TbTrackVolume((*ic), m_search_3vol, m_nPlanes, m_twindow,
+                            m_vol_radius, m_vol_radiusY, m_vol_theta,
+                            m_vol_thetaY, m_MinNClusters);
+      fillATrackVolume(track_volume);
+
+      // Look for a track - automatically keeps if suitable.
+      evaluateTrackVolume(track_volume);
+      // PoorMansEvaluation(track_volume); // Alternative evaluator.
+
+      delete track_volume;
+    }
+  }
+}
+
+//=============================================================================
+// Fill 4volume.
+//=============================================================================
+void TbTracking::fillATrackVolume(TbTrackVolume* track_volume) {
+  // Fills the given TbTrackVolume (that has a particular space-time volume)
+  // with clusters from all planes (ie m_clusters) that fall in this space-time
+  // volume.
+
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    // Check for any clusters, or track contains seed condition.
+    if (m_clusterFinder->empty(iplane) ||
+        iplane == track_volume->seed()->plane() || masked(iplane))
+      continue;
+
+    // Create an iterator and find the appropriate cluster on the ith plane
+    // whose TOA is at the start of this TbTrackVolumes' time window.
+    auto ic = m_clusterFinder->getIterator(track_volume->t_lower(), iplane);
+    const auto end = m_clusterFinder->end(iplane);
+    // Loop until the TOA reaches the end of this TbTrackVolumes' time window.
+    // (dummy end condition used in the for loop).
+    for (; ic != end; ++ic) {
+      // Add cluster if inside and not already tracked.
+      track_volume->consider_cluster((*ic));
+      // Stop if too far ahead in time.
+      if ((*ic)->htime() > track_volume->t_upper()) break;
+    }
+  }
+}
+
+//=============================================================================
+// Finding the best tracks
+//=============================================================================
+void TbTracking::evaluateTrackVolume(TbTrackVolume* track_volume) {
+  // CURRENTLY, finds the most likely track containing either clusters on all
+  // planes,
+  // or tracks with one cluster missing.
+
+  // Declare some variables to be used.
+  LHCb::TbTrack* best_track = NULL;
+  double best_chi_dof = -1;  // Something unphysical.
+
+  // Get the number of combinations to check (depends on the size of the track
+  // to be formed).
+  int ncombos = track_volume->nCombos();
+
+  track_volume->ResetComboCounters();
+  // Do the search over this number of combinations - the TbTrackVolume has
+  // methods
+  // to retrive a particular combination of clusters forming a track (specified
+  // by icombo).
+  for (int icombo = 0; icombo < ncombos && icombo < m_nComboCut; icombo++) {
+
+    // Get the icombo'th track and fit.
+    LHCb::TbTrack* trial_track = track_volume->get_track_combo();
+    // Sort the clusters by z-position.
+    SmartRefVector<LHCb::TbCluster>& clusters =
+      const_cast<SmartRefVector<LHCb::TbCluster>&>(trial_track->clusters());
+    std::sort(clusters.begin(), clusters.end(),
+              TbFunctors::LessByZ<const LHCb::TbCluster*>());
+    m_trackFit->fit(trial_track);
+
+    // Evaluate this track.
+    const double chi2_per_dof = trial_track->chi2PerNdof();
+
+    // First combination tried case.
+    if (icombo == 0) {
+      best_chi_dof = chi2_per_dof;
+      best_track = trial_track;
+      track_volume->update_best();  // TbTrackVolumes keep a record of the best
+      // fitting combination of clusters internally.
+    } else if (chi2_per_dof < best_chi_dof) {
+      // Case of better combination.
+      delete best_track;
+      best_chi_dof = chi2_per_dof;
+      best_track = trial_track;
+      track_volume->update_best();
+    } else
+      delete trial_track;
+    // Prepare for next combination.
+    track_volume->increment_combo_counters();
+  }
+
+  if (best_track) {
+    // At this point, found the best fitting track in the volume. Apply chi cut,
+    // and save.
+    if (best_chi_dof < m_ChiSqRedCut) {
+
+      SmartRefVector<LHCb::TbCluster>& clusters =
+        const_cast<SmartRefVector<LHCb::TbCluster>&>(best_track->clusters());
+      auto earliest_hit = std::min_element(clusters.begin(), clusters.end(),
+              TbFunctors::LessByTime<const LHCb::TbCluster*>());
+
+      if( timingSvc()->beforeOverlap( (*earliest_hit)->time() ) ){
+
+        track_volume->set_tracked_clusters();
+        m_tracks->insert(best_track);
+        
+        // =========================== Kalman code =======================================
+        // create a fit track object (which is actually also a TbTrack)
+        LHCb::TbKalmanTrack* ktrack = new LHCb::TbKalmanTrack(*best_track, m_hiterror2, m_scat2) ;
+        // fit it
+        ktrack->fit() ;
+        // store the ktrack in the track vector
+        ktracks_vec.push_back(ktrack);
+        // ===============================================================================
+        
+        best_track->setTime(timingSvc()->localToGlobal(best_track->htime()));
+        if (m_monitoring) {
+          plot(track_volume->nCombos(), "nComboDist_of_TrackVolumes",
+               "nComboDist_of_TrackVolumes", 0., 1100., 1100);
+          plot(track_volume->nclusters(), "nCluster_in_TrackVolumes",
+               "nCluster_in_TrackVolumes", 0., 100., 100);
+        }
+      } 
+      else{
+  //      info() << "Earliest track time is within overlap, deleting" << endmsg;
+ //       info() << *best_track << endmsg;
+        delete best_track;
+      }
+     }
+     else delete best_track;
+  }
+}
+
+//=============================================================================
+/// Poor mans tracker (useful for testing). - only finds complete tracks.
+//=============================================================================
+void TbTracking::poorMansEvaluation(TbTrackVolume* track_volume) {
+  // Only accept tracks with at least one cluster on each plane.
+  bool one_per_plane = true;  // Assumed, now checked.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    if (track_volume->m_clusters[i].size() == 0) {
+      one_per_plane = false;
+      break;
+    }
+  }
+
+  if (one_per_plane) {
+    double t = 0.0;
+    // We have a track!
+    LHCb::TbTrack* track = new LHCb::TbTrack();
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      LHCb::TbCluster* c = track_volume->nearest_cluster(i);
+      t += c->htime();
+      c->setAssociated(true);
+      track->addToClusters(c);
+    }
+    t /= (double)m_nPlanes;
+    m_trackFit->fit(track);
+    m_tracks->insert(track);
+    track->setTime(timingSvc()->localToGlobal(t));
+  }
+}
+
+//=============================================================================
+// Track time ordering - honeycomb
+//=============================================================================
+void TbTracking::timeOrderTracks() {
+
+  const double s_factor = 1.3;
+  LHCb::TbTrack* track1;
+  LHCb::TbTrack* track2;
+  unsigned int gap = m_tracks->size() / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    LHCb::TbTracks::iterator itt;
+    for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
+      track1 = *itt;
+      track2 = *(itt + gap);
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        std::iter_swap(itt, itt + gap);
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Fill Histograms for TbKalmanTracks
+//=============================================================================
+void TbTracking::fill_khists(std::vector<LHCb::TbKalmanTrack*>& ktracks) {
+  
+  std::vector<LHCb::TbKalmanTrack*>::iterator icktra;
+  for (icktra = ktracks.begin(); icktra != ktracks.end(); icktra++) {
+    
+    // Fill the track histos
+    m_Kfit_chi2->Fill((*icktra)->chi2());
+    m_Kfit_prob->Fill( TMath::Prob((*icktra)->chi2(), (*icktra)->ndof()) );
+    
+    // Get the nodes of this TbKalmanTrack
+    //const std::vector<LHCb::TbKalmanNode*>& knodes = (*icktra)->nodes();
+    
+    // Loop through the nodes of this TbKalmanTrack
+    for( auto node : (*icktra)->nodes() ) {
+      auto pixnode = dynamic_cast< LHCb::TbKalmanPixelMeasurement*>( node) ;
+      if( pixnode ) {
+        int ichip = pixnode->cluster().plane();
+        
+        // Fill unbiased residuals
+        m_XunresKfit[ichip]->Fill( pixnode->residualX() * pixnode->covX() / pixnode->residualCovX() );
+        m_YunresKfit[ichip]->Fill( pixnode->residualY() * pixnode->covY() / pixnode->residualCovY() );
+        
+        // Fill biased residuals
+        m_XresKfit[ichip]->Fill( pixnode->residualX() );
+        m_YresKfit[ichip]->Fill( pixnode->residualY() );
+        
+        // Fill biased residuals on X,Y
+        m_XresKfitOnX[ichip]->Fill( pixnode->cluster().x() , pixnode->residualX() );
+        m_XresKfitOnY[ichip]->Fill( pixnode->cluster().y(),  pixnode->residualX() );
+        
+        m_YresKfitOnY[ichip]->Fill( pixnode->cluster().y() , pixnode->residualY() );
+        m_YresKfitOnX[ichip]->Fill( pixnode->cluster().x(),  pixnode->residualY() );
+        
+        // Fill biased residuals on X,Y slopes
+        m_XresKfitOnTX[ichip]->Fill( pixnode->state().tx()  , pixnode->residualX() );
+        m_XresKfitOnTY[ichip]->Fill( pixnode->state().ty() ,  pixnode->residualX() );
+        
+        m_YresKfitOnTY[ichip]->Fill( pixnode->state().ty()  , pixnode->residualY() );
+        m_YresKfitOnTX[ichip]->Fill( pixnode->state().tx() ,  pixnode->residualY() );
+        
+        
+        // Fill residual errors
+        m_XreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovX()) );
+        m_YreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovY()) );
+        
+        // Fill residual pulls
+        m_XrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
+        m_YrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
+        
+        // Fill chi2 quality histos :
+        // take the chi2 of the track..
+        LHCb::ChiSquare chi2 ( (*icktra)->chi2(), (*icktra)->ndof() ) ;
+        // we should add a proper function to KalmanTrack, or store it
+        
+        // ..now calculate and subtract the chi2 of this hit: should become a function of node as well
+        double resX = pixnode->residualX() ;
+        double resY = pixnode->residualY() ;
+        int nd = 2 * (  (*icktra)->nodes().size()  -1 ) - 4;
+        LHCb::ChiSquare chi2hit  ( resX*resX / pixnode->residualCovX() + resY*resY / pixnode->residualCovY() , nd );
+        chi2 -= chi2hit;
+        // apply quality check
+        if (chi2.chi2()/chi2.nDoF()<4) {
+          // Fill quality biased residuals for this hit
+          m_qXresKfit[ichip]->Fill( pixnode->residualX() );
+          m_qYresKfit[ichip]->Fill( pixnode->residualY() );
+          
+          // Fill quality residual pulls for this hit
+          m_qXrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
+          m_qYrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
+        }
+        
+      } // end of node check
+    } // end of node loop
+  }  // end of Ktrack loop
+}
+
+
+//=============================================================================
+/// Setup Histograms
+//=============================================================================
+void TbTracking::setup_hists() {
+  
+  // TbKalmanTrack parameters plots
+  m_Kfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
+          book1D("KalmanFit/chi2", "Chi2", -0.5, 49.5, 100));
+  
+  m_Kfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
+          book1D("KalmanFit/probability", "Chi2 prob of K fit", 0.0, 1.0, 100));
+  
+    
+  // Kalman fit plots
+  std::string hist_name;
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    std::stringstream ss_chip;
+    ss_chip << i;
+    
+    
+    hist_name = "KalmanFit/UnbiasedResidualsX/plane_" + ss_chip.str();
+    m_XunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    
+    hist_name = "KalmanFit/UnbiasedResidualsY/plane_" + ss_chip.str();
+    m_YunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    //
+    
+    hist_name = "KalmanFit/BiasedResidualsX/plane_" + ss_chip.str();
+    m_XresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/BiasedResidualsY/plane_" + ss_chip.str();
+    m_YresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    //
+    
+    hist_name = "KalmanFit/ResidualsX_on_X/plane_" + ss_chip.str();
+    m_XresKfitOnX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsX_on_Y/plane_" + ss_chip.str();
+    m_XresKfitOnY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    
+    
+    hist_name = "KalmanFit/ResidualsY_on_Y/plane_" + ss_chip.str();
+    m_YresKfitOnY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsY_on_X/plane_" + ss_chip.str();
+    m_YresKfitOnX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    //
+    
+    hist_name = "KalmanFit/ResidualsX_on_slopeX/plane_" + ss_chip.str();
+    m_XresKfitOnTX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsX_on_slopeY/plane_" + ss_chip.str();
+    m_XresKfitOnTY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    
+    hist_name = "KalmanFit/ResidualsY_on_slopeY/plane_" + ss_chip.str();
+    m_YresKfitOnTY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsY_on_slopeX/plane_" + ss_chip.str();
+    m_YresKfitOnTX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    //
+    
+    hist_name = "KalmanFit/Residual_errors_on_X/plane_" + ss_chip.str();
+    m_XreserrKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/Residual_errors_on_Y/plane_" + ss_chip.str();
+    m_YreserrKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_X/plane_" + ss_chip.str();
+    m_XrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_Y/plane_" + ss_chip.str();
+    m_YrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    //
+    
+    hist_name = "KalmanFit/BiasedResidualsX_after_chi2_cut/plane_" + ss_chip.str();
+    m_qXresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/BiasedResidualsY_after_chi2_cut/plane_" + ss_chip.str();
+    m_qYresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    //
+    
+    hist_name = "KalmanFit/ResidualPull_on_X_after_chi2_cut/plane_" + ss_chip.str();
+    m_qXrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_Y_after_chi2_cut/plane_" + ss_chip.str();
+    m_qYrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+  }
+}
+
diff --git a/Kepler/options/.svn/text-base/TbTrackingWithKalman.h.svn-base b/Kepler/options/.svn/text-base/TbTrackingWithKalman.h.svn-base
new file mode 100644
index 0000000..0e334de
--- /dev/null
+++ b/Kepler/options/.svn/text-base/TbTrackingWithKalman.h.svn-base
@@ -0,0 +1,146 @@
+#ifndef TB_TRACKING_H
+#define TB_TRACKING_H 1
+
+// Root
+#include "TH1.h"
+#include "TH2.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+// Kalman classes in TbEvent
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanNode.h"
+#include "Event/TbKalmanPixelMeasurement.h"
+
+// Local
+#include "TbClusterFinder.h"
+#include "TbTrackVolume.h"
+
+/** @class TbTracking TbTracking.h
+ *
+ *  Algorithm for track reconstruction in Timepix3 telescope
+ *
+ * @author Dan Saunders
+ */
+
+class TbTracking : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbTracking();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// Track container (to be filled).
+  LHCb::TbTracks *m_tracks;
+
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+  /// Tool to find particular clusters.
+  TbClusterFinder *m_clusterFinder;
+
+  // Tracking specific options.
+  /// TES location of cluster containers.
+  std::string m_clusterLocation;
+  /// Flag to fill (or not) monitoring histograms.
+  bool m_monitoring;
+  /// Time width (in ns) of TbTrackVolumes.
+  double m_twindow;
+  /// Minimum number of clusters to form a track.
+  unsigned int m_MinNClusters;
+  /// Spatial shapes of TbTrackVolumes {cylinder, diabolo}.
+  std::string m_search_3vol;
+  /// Spatial shape parameter.
+  double m_vol_radius;
+  double m_vol_radiusY;
+  /// Spatial shape parameter.
+  double m_vol_theta;
+  double m_vol_thetaY;
+  /// Chi2 cut.
+  double m_ChiSqRedCut;
+  /// Upper cut on the number of cominations to try in a TbTrackVolume.
+  /// Useful for speed, and rarely used; set O(100).
+  int m_nComboCut;
+  /// Search algorithm used to fill TbTrackVolumes - {"seq", "adap_seq"}.
+  /// "adap_seq" recommeneded.
+  std::string m_ClusterFinderSearchAlgorithm;
+
+  /// For certain volumes, it's advantageous to use seeds from the center of
+  /// the telescope, so the order of the search can be specified here.
+  std::vector<unsigned int> m_PlaneSearchOrder;
+
+  void performTracking();
+  void fillATrackVolume(TbTrackVolume *);
+  void evaluateTrackVolume(TbTrackVolume *);
+  void timeOrderTracks();
+  void poorMansEvaluation(TbTrackVolume *);
+  
+  // Errors for Kalman fit
+  double  m_hiterror2;
+  double  m_scat2;
+  
+  // Histo functions
+  void setup_hists();
+  void fill_khists(std::vector<LHCb::TbKalmanTrack*>&);
+  
+  float lowR, highR, binsR, lowS, highS;
+  
+  
+  // Kalman filter histos
+  //---------------------------------------------------
+  
+  // Track parameters
+  TH1D* m_Kfit_chi2;
+  TH1D* m_Kfit_prob;
+  
+  // unbiased residuals
+  std::vector<TH1D*> m_XunresKfit;
+  std::vector<TH1D*> m_YunresKfit;
+  // biased residuals
+  std::vector<TH1D*> m_XresKfit;
+  std::vector<TH1D*> m_YresKfit;
+  // biased residuals on X,Y
+  std::vector<TH2D*> m_XresKfitOnX;
+  std::vector<TH2D*> m_XresKfitOnY;
+  
+  std::vector<TH2D*> m_YresKfitOnY;
+  std::vector<TH2D*> m_YresKfitOnX;
+  
+  // biased residuals on X,Y slopes
+  std::vector<TH2D*> m_XresKfitOnTX;
+  std::vector<TH2D*> m_XresKfitOnTY;
+  
+  std::vector<TH2D*> m_YresKfitOnTY;
+  std::vector<TH2D*> m_YresKfitOnTX;
+  
+  // biased residuals errors
+  std::vector<TH1D*> m_XreserrKfit;
+  std::vector<TH1D*> m_YreserrKfit;
+  
+  // residual pulls
+  std::vector<TH1D*> m_XrespullKfit;
+  std::vector<TH1D*> m_YrespullKfit;
+  
+  // quality biased residuals
+  std::vector<TH1D*> m_qXresKfit;
+  std::vector<TH1D*> m_qYresKfit;
+  
+  // quality residual pulls
+  std::vector<TH1D*> m_qXrespullKfit;
+  std::vector<TH1D*> m_qYrespullKfit;
+  
+  
+  // TbKalmanTrack container
+  std::vector<LHCb::TbKalmanTrack*> ktracks_vec;
+  //---------------------------------------------------
+  
+};
+#endif
diff --git a/Kepler/options/.svn/text-base/batch.py.svn-base b/Kepler/options/.svn/text-base/batch.py.svn-base
new file mode 100644
index 0000000..e0f0760
--- /dev/null
+++ b/Kepler/options/.svn/text-base/batch.py.svn-base
@@ -0,0 +1,23 @@
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+from Configurables import TbEventBuilder
+TbEventBuilder().MinPlanesWithHits = 2
+TbEventBuilder().PrintFreq = 100
+TbEventBuilder().Monitoring = True
+Kepler().EvtMax=5000
+
+Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Dec2014/RootFiles/Run4012/Conditions/Alignment4012.dat"
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+TbTracking().MinNClusters = 3
+
+TbTracking().SearchRadius = 0.5
+TbTracking().VolumeAngle = 0.2
+TbTracking().TimeWindow = 75
+TbTracking().Monitoring = False
+TbTracking().SearchPlanes = [2,3]
+TbTracking().MaskedPlanes = []
+
+from Configurables import TbTrackPlots
diff --git a/Kepler/options/.svn/text-base/debug.py.svn-base b/Kepler/options/.svn/text-base/debug.py.svn-base
new file mode 100644
index 0000000..dc070c6
--- /dev/null
+++ b/Kepler/options/.svn/text-base/debug.py.svn-base
@@ -0,0 +1,10 @@
+# This file provides examples how to increase or decrease the 
+# verbosity of the output. 
+
+# Set the output level of an individual algorithms
+from Configurables import TbEventBuilder
+TbEventBuilder().OutputLevel = DEBUG
+# Options are VERBOSE, DEBUG, INFO, WARNING, ERROR
+
+# Set the  global output level (all algorithms) 
+MessageSvc().OutputLevel = DEBUG
diff --git a/Kepler/options/.svn/text-base/efficiency.py.svn-base b/Kepler/options/.svn/text-base/efficiency.py.svn-base
new file mode 100644
index 0000000..f88660c
--- /dev/null
+++ b/Kepler/options/.svn/text-base/efficiency.py.svn-base
@@ -0,0 +1,101 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py $KEPLERROOT/options/example.py
+from Gaudi.Configuration import *
+from Configurables import Kepler
+import pickle
+import ROOT
+
+# Set the path to the directory/files to be processed
+path = 'eos/lhcb/testbeam/velo/timepix3/'
+RUN = '9110'
+# if int(RUN) < 2000:
+#   path += 'July'
+# elif int(RUN) < 2815:
+#   path += 'Oct'
+# elif int(RUN) < 4000:
+#   path += 'Nov'
+# else: 
+#   path += 'Dec'
+# path += '2014'
+
+path += 'July2015'
+
+Kepler().InputFiles =  [path + '/RawData/Run' + RUN + '/']
+Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+Kepler().AlignmentFile = path + '/RootFiles/Run' + RUN + '/Conditions/Alignment' + RUN + 'mille.dat'
+#Kepler().AlignmentFile = 'ResStudies/Alignments/dut/Alignment2509.dat'
+Kepler().HistogramFile= 'Kepler_histos_' + RUN + '.root'
+# Set the number of events to run over 
+Kepler().EvtMax = 11000000
+#Kepler().TimingConfigFile = "myTimingConfig.dat"
+
+# Set the configuration of the individual algorithms, e. g.
+from Configurables import TbEventBuilder 
+#TbEventBuilder().MinPlanesWithHits = 5
+
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbSimpleTracking
+TbSimpleTracking().PrintConfiguration = True
+
+from Configurables import TbVisualiserOutput
+TbVisualiserOutput().PrintConfiguration = True
+TbVisualiserOutput().ViewerEvent = 1049
+Kepler().UserAlgorithms = [TbVisualiserOutput()]
+
+DUT_id = pickle.load( open( "DUTnum.p", "rb" ) )
+#DUT_id = 3
+
+
+fResiduals = ROOT.TFile("UnbiasedLocalResolutionsPerPlane.root")
+gx = fResiduals.Get("xPerPlane")
+gy = fResiduals.Get("yPerPlane")
+scaling = 15
+print ((gx.GetBinContent(DUT_id+1)**2 + gy.GetBinContent(DUT_id+1)**2)**0.5)
+allowance = scaling * ((gx.GetBinContent(DUT_id+1)**2 + gy.GetBinContent(DUT_id+1)**2)**0.5)
+print 'DUT_id', DUT_id
+print 'allowance:', allowance
+
+def egRun():
+    from Configurables import TbEventBuilder, TbTrackPlots, TbCalibration, TbVisualiserOutput
+    from Configurables import TbClustering, TbClusterPlots, TbSimpleTracking, TbHitMonitor
+    from Configurables import TbClusterAssociator, TbEfficiency, TbDUTMonitor
+    
+    TbEventBuilder().PrintFreq = 10
+    
+    TbSimpleTracking().TimeWindow = 6
+    TbSimpleTracking().MaxDistance = 0
+    TbSimpleTracking().MinPlanes = 7
+    TbSimpleTracking().MaskedPlanes = [DUT_id, 4]
+    TbSimpleTracking().MaxOpeningAngle = 0.005
+    TbSimpleTracking().RecheckTrack = True
+    TbSimpleTracking().ChargeCutLow = 0
+    TbSimpleTracking().DoOccupancyCut = True
+    TbSimpleTracking().MaxClusterSize = 20
+    TbSimpleTracking().MaxOccupancy = 7 # not inclusive
+    TbTrackPlots().MaskedPlanes = [DUT_id, 4]
+        
+    TbClusterAssociator().DUTs = [DUT_id]
+    TbDUTMonitor().DUTs = [DUT_id]
+    TbClusterAssociator().TimeWindow = 10
+    TbClusterAssociator().XWindow = allowance
+    
+    TbEfficiency().CheckHitDUT = True
+    TbEfficiency().CheckHitAlivePixel = True
+    TbEfficiency().DUT = DUT_id
+    TbEfficiency().TakeDeadPixelsFromFile = True
+    TbEfficiency().nTotalTracks =500000
+    TbEfficiency().MaxChi = 2
+    
+    
+    seq = GaudiSequencer("Telescope")
+    seq.Members = [TbEventBuilder(), TbClustering(), TbSimpleTracking(), TbClusterAssociator(), TbEfficiency()]    
+    #seq.Members = [TbEventBuilder()]  
+    
+    seq = GaudiSequencer("Monitoring")
+    from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots 
+    #seq.Members = [TbHitMonitor(), TbClusterPlots(), TbTrackPlots(), TbDUTMonitor(), TbVisualiserOutput()]
+    seq.Members = [TbDUTMonitor()]
+    
+appendPostConfigAction(egRun)
\ No newline at end of file
diff --git a/Kepler/options/.svn/text-base/example.py.svn-base b/Kepler/options/.svn/text-base/example.py.svn-base
new file mode 100644
index 0000000..0ae4d92
--- /dev/null
+++ b/Kepler/options/.svn/text-base/example.py.svn-base
@@ -0,0 +1,37 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py $KEPLERROOT/options/example.py
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+# Set the path to the directory/files to be processed
+path = 'eos/lhcb/testbeam/velo/timepix3/'
+RUN = '9187'
+if int(RUN) < 2000:
+  path += 'July'
+elif int(RUN) < 2815:
+  path += 'Oct'
+elif int(RUN) < 4000:
+  path += 'Nov'
+else: 
+  path += 'Dec'
+path += '2014'
+
+Kepler().InputFiles =  [path + '/RawData/Run' + RUN + '/']
+Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+Kepler().AlignmentFile = path + '/RootFiles/Run' + RUN + '/Conditions/Alignment' + RUN + 'mille.dat'
+#Kepler().AlignmentFile = 'ResStudies/Alignments/dut/Alignment2509.dat'
+Kepler().HistogramFile= 'Kepler_histos_' + RUN + '.root'
+
+# Set the number of events to run over 
+Kepler().EvtMax = 1000
+
+# Set the configuration of the individual algorithms, e. g.
+from Configurables import TbEventBuilder
+#TbEventBuilder().MinPlanesWithHits = 5
+
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+
diff --git a/Kepler/options/.svn/text-base/singleChipExample.py.svn-base b/Kepler/options/.svn/text-base/singleChipExample.py.svn-base
new file mode 100644
index 0000000..e167d83
--- /dev/null
+++ b/Kepler/options/.svn/text-base/singleChipExample.py.svn-base
@@ -0,0 +1,31 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py singleChipExample.py
+
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+
+# Set the path to the directory/files to be processed
+Kepler().InputFiles = ["singleChipRun/"]
+# Set the alignment file
+Kepler().AlignmentFile = "singleAlignment.dat"
+# Set the masked pixels file
+Kepler().PixelConfigFile = "PixelMask.dat"
+# Set the number of events to run over 
+Kepler().EvtMax = 4300
+
+# Set the configuration of the individual algorithms
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+# Combat specific.
+def combatRun():
+     from Configurables import TbEventBuilder, TbClustering
+     seq = GaudiSequencer("Telescope")
+     seq.Members = [TbEventBuilder(), TbClustering()]
+     
+     seq = GaudiSequencer("Monitoring")
+     from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+     seq.Members = [TbHitMonitor(), TbClusterPlots()]
+
+appendPostConfigAction(combatRun)
diff --git a/Kepler/options/EmptyPixelMask.dat b/Kepler/options/EmptyPixelMask.dat
new file mode 100644
index 0000000..1ebde38
--- /dev/null
+++ b/Kepler/options/EmptyPixelMask.dat
@@ -0,0 +1 @@
+# ChipName column row
diff --git a/Kepler/options/MaskPixels.dat b/Kepler/options/MaskPixels.dat
new file mode 100644
index 0000000..6c54a4e
--- /dev/null
+++ b/Kepler/options/MaskPixels.dat
@@ -0,0 +1,6 @@
+# Device   column row
+W0002_J06   139   162
+W0002_E05     6   217
+W0002_E05     7    35
+W0002_E05   155    40
+W0002_E05   156    40
diff --git a/Kepler/options/ResStudies/.svn/all-wcprops b/Kepler/options/ResStudies/.svn/all-wcprops
new file mode 100644
index 0000000..06e2dfd
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/all-wcprops
@@ -0,0 +1,59 @@
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies
+END
+copyAligns.py
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies/copyAligns.py
+END
+submitRes.py
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies/submitRes.py
+END
+ZPos.txt
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies/ZPos.txt
+END
+lhcbStyle.C
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/188632/Kepler/trunk/Tb/Kepler/options/ResStudies/lhcbStyle.C
+END
+AlignQualy.py
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies/AlignQualy.py
+END
+res_analysis.C
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/188632/Kepler/trunk/Tb/Kepler/options/ResStudies/res_analysis.C
+END
+Runs.py
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/188051/Kepler/trunk/Tb/Kepler/options/ResStudies/Runs.py
+END
+restudies.py
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies/restudies.py
+END
+runList.txt
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/188713/Kepler/trunk/Tb/Kepler/options/ResStudies/runList.txt
+END
diff --git a/Kepler/options/ResStudies/.svn/entries b/Kepler/options/ResStudies/.svn/entries
new file mode 100644
index 0000000..4363b81
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/entries
@@ -0,0 +1,337 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/ResStudies
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+copyAligns.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+6067cd7f9b55813339b9de630c2c37d1
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1173
+
+Alignments
+dir
+
+submitRes.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+79c5c5ce1c2e8a0d6d33ac7585862bf5
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1997
+
+ZPos.txt
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+b3d99c8d4639a809ddc6c3a09d7a2e80
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+316
+
+lhcbStyle.C
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+1ee5d8770506b4b08016c0cbf38f7cd7
+2015-05-21T16:04:13.551304Z
+188632
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6500
+
+AlignQualy.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+0ad5bc78b9ed300f6597e730528bbd99
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2204
+
+res_analysis.C
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+887a109d0cc76dca8e0e89e7ba82f28a
+2015-05-21T16:04:13.551304Z
+188632
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7431
+
+Runs.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+f6ff329f3ee4d45662ecff884c0298da
+2015-05-12T10:54:52.097095Z
+188051
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2687
+
+restudies.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+383e69c43a61e51ce5b01e3873137193
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3679
+
+runList.txt
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+c48da843df9b74d83f6e9c2202d4b392
+2015-05-22T14:01:52.553303Z
+188713
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1962
+
diff --git a/Kepler/options/ResStudies/.svn/text-base/AlignQualy.py.svn-base b/Kepler/options/ResStudies/.svn/text-base/AlignQualy.py.svn-base
new file mode 100644
index 0000000..c458fa5
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/AlignQualy.py.svn-base
@@ -0,0 +1,87 @@
+from ROOT import TFile, TCanvas
+from Runs import Runs
+
+import os, sys
+block  = ['D1','D2']
+indir  = '/afs/cern.ch/work/c/chombach/Telescope/ResStudies/'
+outdir = '/afs/cern.ch/user/c/chombach/www/public/Telescope/AlignQualy/'
+
+os.system('mkdir -p '+outdir)
+
+outfile = outdir+'AlignQualy'
+for bl in block:
+    outfile += '_'+bl
+outfile += '.pdf'
+runs = Runs(block, 'run')
+runs.setOutputDir(indir)
+
+c = TCanvas('c','c',1200,600)
+c.Print(outfile+'(','pdf')
+
+def makePlots(tf, title):
+
+    c.Divide(0,0)
+    fn = 'Tb/TbTrackPlots/'
+    chi2 = tf.Get(fn+'Chi2PerDof')
+    chi2.SetTitle(title)
+    chi2.Draw()
+    c.Print(outfile,'pdf')
+
+    prob = tf.Get(fn+'Probability')
+    prob.SetTitle(title)
+    prob.Draw()
+    c.Print(outfile,'pdf')
+
+    c.Clear()
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_x = tf.Get(fn+'BiasedResiduals/GlobalX/Plane%i' % i )
+        res_x.SetTitle(title+' GlobalX Plane%i' % i)
+        res_x.Fit('gaus')
+        res_x.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_y = tf.Get(fn+'BiasedResiduals/GlobalY/Plane%i' % i )
+        res_y.SetTitle(title+' GlobalY Plane%i' % i)
+        res_y.Fit('gaus')
+        res_y.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_xvsx = tf.Get(fn+'BiasedResiduals/GlobalResXvsLocalX/Plane%i' % i )
+        res_xvsx.SetTitle(title+' GlobalXResvsX Plane%i' % i)
+        res_xvsx.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_yvsy = tf.Get(fn+'BiasedResiduals/GlobalResYvsLocalY/Plane%i' % i )
+        res_yvsy.SetTitle(title+' GlobalYResvsY Plane%i' % i)
+        res_yvsy.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+for block in runs.RUNS:
+    for run in runs.RUNS[block]:
+        rn  = run.RUN
+        ang = run.ANGLE
+        bia = run.BIAS
+        dut = run.DUT
+        block = run.BLOCK
+        title = '%s_%s_%s_%s' % (rn, dut, bia, ang)
+        fn = runs.OUTPUTDIR+block+'/Kepler_%s.root' % title
+        tf = TFile(fn)
+        makePlots(tf, title)
+        tf.Close()
+c.Print(outfile+')','pdf')
+
+
diff --git a/Kepler/options/ResStudies/.svn/text-base/Runs.py.svn-base b/Kepler/options/ResStudies/.svn/text-base/Runs.py.svn-base
new file mode 100644
index 0000000..aedcecc
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/Runs.py.svn-base
@@ -0,0 +1,88 @@
+import os
+
+
+class Run():
+    def __init__(self, r, a, b, d, bl, ad, aod):
+        self.RUN       = r
+        self.ANGLE     = a
+        self.BIAS      = b
+        self.DUT       = d
+        self.BLOCK     = bl
+        absad = os.path.abspath( ad )
+        if not os.path.exists(absad):
+            os.system('mkdir -p %s' % absad)
+        absaod = os.path.abspath( aod )
+        if not os.path.exists(absaod):
+            os.system('mkdir -p %s' % absaod)
+        self.ALIGNFILE = absad+'/Alignment'+self.RUN+'.dat'
+        self.ALIGNOUTFILE = absaod+'/Alignment'+self.RUN+'.dat' 
+
+    def createAlignFile(self):
+        devs = ['', 'W0002_J06','W0002_B05','W0002_C05','W0002_D05',self.DUT,'W0002_G05','W0002_F05','W0002_H07','W0002_E05']
+        s = ''
+        zfile = open('ZPos.txt','r')
+        for ll in zfile.readlines():
+            l = ll.split()
+            if '#' in l[0]:
+                continue
+            if l[0] == self.BLOCK:
+                z  = l
+        for i in range(9):
+            if i < 4:
+                s+= '%s 14.03 14.03 %s 2.9845 3.299 0.\n' %  (devs[i+1], z[i+1])
+            elif i == 4:
+                s+= '%s 0.0 14.03 %s 3.141 %f 0.\n' %  (devs[i+1], z[i+1], float(self.ANGLE)*3.141/180. )
+            else:
+                s+= '%s 0.0 14.03 %s 3.299 0.157 0.\n' %  (devs[i+1], z[i+1])
+
+        af = open(self.ALIGNFILE, 'w')
+        af.write(s)
+        af.close
+
+class Runs():
+    def __init__(self, b, type):
+        self.BLOCKS = b
+        if type == 'survey':
+            ad = 'init'
+        elif type == 'mille':
+            ad = 'survey'
+        elif type == 'dut':
+            ad = 'mille'
+        else:
+            ad = 'dut'
+        self.TYPE        = type
+        self.ALIGNDIR    = "Alignments/%s/" % (ad)
+        print self.ALIGNDIR
+        self.ALIGNOUTDIR = "Alignments/%s/" % (type) 
+        self.RUNS        = self.defRuns()
+        self.OUTPUTDIR   = ''
+
+    def defRuns(self):
+        rs = {}
+        f  = open('runList.txt','r')
+        for ll in f.readlines():
+            l = ll.split()
+            if '#' in l[0]:
+                continue
+            r = l[0]
+            a = l[1]
+            b = l[2]
+            d = l[3]
+            bl= l[4]
+            if bl in self.BLOCKS:
+                run = Run(r,a,b,d, bl, self.ALIGNDIR, self.ALIGNOUTDIR)
+                if bl in rs:
+                    rs[bl].append(run)
+                else:
+                    rs[bl] = [run]
+        f.close()
+        return rs
+
+    def findRun(self, rn):
+        for b in self.RUNS:
+            for r in self.RUNS[b]:
+                if r.RUN == rn:
+                    return r
+    
+    def setOutputDir(self, od):
+        self.OUTPUTDIR = od
diff --git a/Kepler/options/ResStudies/.svn/text-base/ZPos.txt.svn-base b/Kepler/options/ResStudies/.svn/text-base/ZPos.txt.svn-base
new file mode 100644
index 0000000..428f538
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/ZPos.txt.svn-base
@@ -0,0 +1,4 @@
+#BLOCK	W0002_J06	W0002_B05	W0002_C05	W0002_D05	DUT	W0002_G05	W0002_F05	W0002_H07    W0002_E05
+A	0		60		120		180		390	530		590		654	     715
+D1	0		60		120		180		300	425		485		549	     610
+D2      0               60              120             180             300     425             485             549          610
diff --git a/Kepler/options/ResStudies/.svn/text-base/copyAligns.py.svn-base b/Kepler/options/ResStudies/.svn/text-base/copyAligns.py.svn-base
new file mode 100644
index 0000000..62def68
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/copyAligns.py.svn-base
@@ -0,0 +1,42 @@
+import os,sys
+import Runs
+jobnr    = 2870
+
+#Set blocks to run over and alignment-method
+blocks   = ['D2']
+method   = 'run'
+#
+
+
+gangadir   = '/afs/cern.ch/work/c/chombach/gangadir/workspace/chombach/LocalXML/%i/' % jobnr
+rootout    = '/afs/cern.ch/work/c/chombach/Telescope/ResStudies/' 
+for bl in blocks:
+    rootout += bl
+    rootout +=  '/'
+    os.system( 'mkdir -p %s' % rootout )
+def findRunNo( so ):
+    sof = open( so )
+    for ll in sof.readlines():
+        l = ll.split()
+        if len(l) == 0:
+            continue
+        if l[0] == 'TbDataSvc':
+            ind = l[4].find('Run')
+            return l[4][ind+3:ind+7]
+
+runs = Runs.Runs(blocks, method)
+
+if method == 'run':
+    runs.setOutputDir( rootout )
+    
+for dd in os.listdir(gangadir):
+    if dd == 'debug':
+        continue
+    rn = findRunNo(gangadir+dd+'/output/stdout')
+    run = runs.findRun( rn )
+    
+    os.system('cp %s %s' % ( gangadir+dd+'/output/Alignment_out.dat', run.ALIGNOUTFILE) )
+    if method == 'run':
+        outfile = runs.OUTPUTDIR+'Kepler_%s_%s_%s_%s.root' % (rn, run.DUT, run.BIAS, run.ANGLE)
+        os.system('cp %s %s' % ( gangadir+dd+'/output/Kepler-histos.root', outfile) )
+
diff --git a/Kepler/options/ResStudies/.svn/text-base/lhcbStyle.C.svn-base b/Kepler/options/ResStudies/.svn/text-base/lhcbStyle.C.svn-base
new file mode 100644
index 0000000..39e0657
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/lhcbStyle.C.svn-base
@@ -0,0 +1,196 @@
+// all users - please change the name of this file to lhcbStyle.C
+// Commits to lhcbdocs svn of .C files are not allowed
+{
+
+  // define names for colours
+  Int_t black  = 1;
+  Int_t red    = 2;
+  Int_t green  = 3;
+  Int_t blue   = 4;
+  Int_t yellow = 5; 
+  Int_t magenta= 6;
+  Int_t cyan   = 7;
+  Int_t purple = 9;
+  
+
+////////////////////////////////////////////////////////////////////
+// PURPOSE:
+//
+// This macro defines a standard style for (black-and-white) 
+// "publication quality" LHCb ROOT plots. 
+//
+// USAGE:
+//
+// Include the lines
+//   gROOT->ProcessLine(".L lhcbstyle.C");
+//   lhcbStyle();
+// at the beginning of your root macro.
+//
+// Example usage is given in myPlot.C
+//
+// COMMENTS:
+//
+// Font:
+// 
+// The font is chosen to be 132, this is Times New Roman (like the text of
+//  your document) with precision 2.
+//
+// "Landscape histograms":
+//
+// The style here is designed for more or less square plots.
+// For longer histograms, or canvas with many pads, adjustements are needed. 
+// For instance, for a canvas with 1x5 histograms:
+//  TCanvas* c1 = new TCanvas("c1", "L0 muons", 600, 800);
+//  c1->Divide(1,5);
+//  Adaptions like the following will be needed:
+//  gStyle->SetTickLength(0.05,"x");
+//  gStyle->SetTickLength(0.01,"y");
+//  gStyle->SetLabelSize(0.15,"x");
+//  gStyle->SetLabelSize(0.1,"y");
+//  gStyle->SetStatW(0.15);
+//  gStyle->SetStatH(0.5);
+//
+// Authors: Thomas Schietinger, Andrew Powell, Chris Parkes, Niels Tuning
+// Maintained by Editorial board member (currently Niels)
+///////////////////////////////////////////////////////////////////
+
+  // Use times new roman, precision 2 
+  Int_t lhcbFont        = 132;  // Old LHCb style: 62;
+  // Line thickness
+  Double_t lhcbWidth    = 2.00; // Old LHCb style: 3.00;
+  // Text size
+  Double_t lhcbTSize    = 0.06; 
+  
+  // use plain black on white colors
+  gROOT->SetStyle("Plain"); 
+  TStyle *lhcbStyle= new TStyle("lhcbStyle","LHCb plots style");
+  
+  //lhcbStyle->SetErrorX(0); //  don't suppress the error bar along X
+
+  lhcbStyle->SetFillColor(1);
+  lhcbStyle->SetFillStyle(1001);   // solid
+  lhcbStyle->SetFrameFillColor(0);
+  lhcbStyle->SetFrameBorderMode(0);
+  lhcbStyle->SetPadBorderMode(0);
+  lhcbStyle->SetPadColor(0);
+  lhcbStyle->SetCanvasBorderMode(0);
+  lhcbStyle->SetCanvasColor(0);
+  lhcbStyle->SetStatColor(0);
+  lhcbStyle->SetLegendBorderSize(0);
+  lhcbStyle->SetLegendFont(132);
+
+  // If you want the usual gradient palette (blue -> red)
+  lhcbStyle->SetPalette(1);
+  // If you want colors that correspond to gray scale in black and white:
+  int colors[8] = {0,5,7,3,6,2,4,1};
+  // lhcbStyle->SetPalette(8,colors);
+
+  // set the paper & margin sizes
+  lhcbStyle->SetPaperSize(20,26);
+  lhcbStyle->SetPadTopMargin(0.05);
+  lhcbStyle->SetPadRightMargin(0.05); // increase for colz plots
+  lhcbStyle->SetPadBottomMargin(0.16);
+  lhcbStyle->SetPadLeftMargin(0.14);
+  
+  // use large fonts
+  lhcbStyle->SetTextFont(lhcbFont);
+  lhcbStyle->SetTextSize(lhcbTSize);
+  lhcbStyle->SetLabelFont(lhcbFont,"x");
+  lhcbStyle->SetLabelFont(lhcbFont,"y");
+  lhcbStyle->SetLabelFont(lhcbFont,"z");
+  lhcbStyle->SetLabelSize(lhcbTSize,"x");
+  lhcbStyle->SetLabelSize(lhcbTSize,"y");
+  lhcbStyle->SetLabelSize(lhcbTSize,"z");
+  lhcbStyle->SetTitleFont(lhcbFont);
+  lhcbStyle->SetTitleFont(lhcbFont,"x");
+  lhcbStyle->SetTitleFont(lhcbFont,"y");
+  lhcbStyle->SetTitleFont(lhcbFont,"z");
+  lhcbStyle->SetTitleSize(1.2*lhcbTSize,"x");
+  lhcbStyle->SetTitleSize(1.2*lhcbTSize,"y");
+  lhcbStyle->SetTitleSize(1.2*lhcbTSize,"z");
+
+  // use medium bold lines and thick markers
+  lhcbStyle->SetLineWidth(lhcbWidth);
+  lhcbStyle->SetFrameLineWidth(lhcbWidth);
+  lhcbStyle->SetHistLineWidth(lhcbWidth);
+  lhcbStyle->SetFuncWidth(lhcbWidth);
+  lhcbStyle->SetGridWidth(lhcbWidth);
+  lhcbStyle->SetLineStyleString(2,"[12 12]"); // postscript dashes
+  lhcbStyle->SetMarkerStyle(20);
+  lhcbStyle->SetMarkerSize(1.0);
+
+  // label offsets
+  lhcbStyle->SetLabelOffset(0.010,"X");
+  lhcbStyle->SetLabelOffset(0.010,"Y");
+
+  // by default, do not display histogram decorations:
+  lhcbStyle->SetOptStat(0);  
+  //lhcbStyle->SetOptStat("emr");  // show only nent -e , mean - m , rms -r
+  // full opts at http://root.cern.ch/root/html/TStyle.html#TStyle:SetOptStat
+  lhcbStyle->SetStatFormat("6.3g"); // specified as c printf options
+  lhcbStyle->SetOptTitle(0);
+  lhcbStyle->SetOptFit(0);
+  //lhcbStyle->SetOptFit(1011); // order is probability, Chi2, errors, parameters
+  //titles
+  lhcbStyle->SetTitleOffset(0.95,"X");
+  lhcbStyle->SetTitleOffset(0.95,"Y");
+  lhcbStyle->SetTitleOffset(1.2,"Z");
+  lhcbStyle->SetTitleFillColor(0);
+  lhcbStyle->SetTitleStyle(0);
+  lhcbStyle->SetTitleBorderSize(0);
+  lhcbStyle->SetTitleFont(lhcbFont,"title");
+  lhcbStyle->SetTitleX(0.0);
+  lhcbStyle->SetTitleY(1.0); 
+  lhcbStyle->SetTitleW(1.0);
+  lhcbStyle->SetTitleH(0.05);
+  
+  // look of the statistics box:
+  lhcbStyle->SetStatBorderSize(0);
+  lhcbStyle->SetStatFont(lhcbFont);
+  lhcbStyle->SetStatFontSize(0.05);
+  lhcbStyle->SetStatX(0.9);
+  lhcbStyle->SetStatY(0.9);
+  lhcbStyle->SetStatW(0.25);
+  lhcbStyle->SetStatH(0.15);
+
+  // put tick marks on top and RHS of plots
+  lhcbStyle->SetPadTickX(1);
+  lhcbStyle->SetPadTickY(1);
+
+  // histogram divisions: only 5 in x to avoid label overlaps
+  lhcbStyle->SetNdivisions(505,"x");
+  lhcbStyle->SetNdivisions(510,"y");
+  
+  gROOT->SetStyle("lhcbStyle");
+  gROOT->ForceStyle();
+
+  // add LHCb label
+  lhcbName = new TPaveText(gStyle->GetPadLeftMargin() + 0.05,
+                           0.87 - gStyle->GetPadTopMargin(),
+                           gStyle->GetPadLeftMargin() + 0.20,
+                           0.95 - gStyle->GetPadTopMargin(),
+                           "BRNDC");
+  lhcbName->AddText("LHCb");
+  lhcbName->SetFillColor(0);
+  lhcbName->SetTextAlign(12);
+  lhcbName->SetBorderSize(0);
+
+  TText *lhcbLabel = new TText();
+  lhcbLabel->SetTextFont(lhcbFont);
+  lhcbLabel->SetTextColor(1);
+  lhcbLabel->SetTextSize(lhcbTSize);
+  lhcbLabel->SetTextAlign(12);
+
+  TLatex *lhcbLatex = new TLatex();
+  lhcbLatex->SetTextFont(lhcbFont);
+  lhcbLatex->SetTextColor(1);
+  lhcbLatex->SetTextSize(lhcbTSize);
+  lhcbLatex->SetTextAlign(12);
+
+  cout << "-------------------------" << endl;  
+  cout << "Set LHCb Style - Feb 2012" << endl;
+  cout << "-------------------------" << endl;  
+  
+}
+
+
diff --git a/Kepler/options/ResStudies/.svn/text-base/res_analysis.C.svn-base b/Kepler/options/ResStudies/.svn/text-base/res_analysis.C.svn-base
new file mode 100644
index 0000000..ffffc3d
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/res_analysis.C.svn-base
@@ -0,0 +1,180 @@
+#include "TFile.h"
+#include "TH2.h"
+#include "TH1.h"
+#include "TF1.h"
+#include "TGraphErrors.h"
+#include "iostream"
+#include <stdio.h>
+#include "Riostream.h"
+#include <math.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include "TRandom.h"
+#include "TGraph.h"
+#include "TMultiGraph.h"
+#include "TCanvas.h"
+#include "TMath.h"
+#include "TLegend.h"
+//script opens the kepler-histograms sent by submitRes.py to the grid, specifically taking the unbiased residual for the DUT (plane 4) for both X and Y. 
+//Fits a guassian to each of the residuals and stores the mean and rms. 
+//Plots them as a function of Bias or Angle, where the bias and angle values are stored in runList.txt 
+//stores them as a .png and .root file format (in LHCb style)
+//run as root -b if you dont want canvas printed to screen. 
+//MAY need to change path in ~L62 to your own!!!!!
+//Emma Buchanan May 2015 (emma.buchanan@cern.ch) 
+
+void res_analysis(){
+  //-------Change Parameters Here------//
+  const int job = 9; //job number
+  const int run =5; //number of subjobs in this job 
+  const int beg= 13; //from runList.txt what is the range of the "Block" begining->end
+  const int end= 17; 
+  int choice =0; //Is this an Bias or angle scan?  (0 for Bias, 1 for angle)
+  const int iplane =4; //number of the plane you wish to analyse (DUT =4)
+
+  //saving the final plot as a .png, and/or root file 
+  char plot_bias[200]; //the name of the plot, will be printed to a .png at the end of this script.
+  sprintf(plot_bias, "%s", "sensor_bias_scan.png");
+  char plot_angle[200];
+  sprintf(plot_angle, "%s", "sensor_angle_scan.png");
+  char root_plotb[100]; //this .root file will contain the final plot/s
+  sprintf(root_plotb, "%s", "sensor_bias_scan.root");
+  char root_plota[100]; //this .root file will contain the final plot/s
+  sprintf(root_plota, "%s", "sensor_angle_scan.root");
+  //----------end of parameters--------//
+
+
+  //Reading kepler histograms and fitting gaussian to DUT
+  float DUT_meanX[run];  float DUT_rmsX[run]; //fit parameters for X
+  float DUT_meanY[run];  float DUT_rmsY[run]; //fit parameters for Y
+  TF1 *gauss = new TF1("gauss","gaus");
+  TH1F *XDUT[run];
+  TH1F *YDUT[run];
+  TCanvas *Xcanvas[run];
+  TCanvas *Ycanvas[run];
+ 
+  //opening the DUT (plane 4) from the kepler-histos and fitting a gaussian to each.  
+  char filename[100];
+  char locationX[100];  char locationY[100];
+  TFile *openFile[100]; 
+  for (int subjob =0; subjob<run; subjob++){
+      sprintf(filename, "%s%d%s%d%s","/afs/cern.ch/user/e/ebuchana/gangadir/workspace/ebuchana/LocalXML/",job,"/",subjob,"/output/Kepler-histos.root "); //the location of each root file for each run 
+      sprintf(locationX, "%s%d", "Tb/TbTrackPlots/BiasedResiduals/GlobalX/Plane",iplane); //location of the biased residual of the DUT
+      sprintf(locationY, "%s%d", "Tb/TbTrackPlots/BiasedResiduals/GlobalY/Plane",iplane); //location of the biased residual of the DUT
+      cout << filename << endl;
+      openFile[subjob] = new TFile(filename); //opening the root files
+
+      //------------------ For X ------------------//
+      cout << locationX << endl;
+      Xcanvas[subjob] = new TCanvas(); //creating a canvas for each histogram 
+      Xcanvas[subjob]->SetTitle("X Biased Residal for DUT"); //setting canvas title 
+      XDUT[subjob] = (TH1F*)openFile[subjob]->Get(locationX); //getting each of the histograms from the kepler root files
+      XDUT[subjob]->Fit("gauss", "R"); //fitting guassian
+      DUT_meanX[subjob]=XDUT[subjob]->GetFunction("gauss")->GetParameter(1); //getting the mean of the postion 
+      DUT_rmsX[subjob]=XDUT[subjob]->GetFunction("gauss")->GetParameter(2); //this should be the RMS 
+      cout << "DUT mean X\t" << DUT_meanX[subjob] <<endl;
+      cout << "DUT rms X\t" << DUT_rmsX[subjob] <<endl;      
+
+      //------------------ For Y ------------------//
+      cout << locationY << endl;
+      Ycanvas[subjob] = new TCanvas(); //creating a canvas for each histogram
+      Ycanvas[subjob]->SetTitle("Y Biased Residal for DUT"); //setting canvas title      
+      YDUT[subjob] = (TH1F*)openFile[subjob]->Get(locationY); //getting each of the histograms from the kepler root files      
+      YDUT[subjob]->Fit("gauss", "R"); //fitting guassian      
+      DUT_meanY[subjob]=YDUT[subjob]->GetFunction("gauss")->GetParameter(1); //getting the mean of the postion      
+      DUT_rmsY[subjob]=YDUT[subjob]->GetFunction("gauss")->GetParameter(2); //this should be the RMS      
+      cout << "DUT mean Y\t" << DUT_meanY[subjob] <<endl;
+      cout << "DUT rms Y\t" << DUT_rmsY[subjob] <<endl;
+
+  }
+
+  //Printing to the DUT histograms and gaussian fits to a new root file 
+  char rootFile[100];
+  sprintf(rootFile, "%s", "root_res_analysis.root");
+  cout << "creating\t" << rootFile << endl;
+  TFile *myfile =  new TFile(rootFile,"RECREATE"); // creating rootfile
+  for (int subjob =0; subjob<run; subjob++){
+    XDUT[subjob]->Write(); //writing the plots to file 
+    YDUT[subjob]->Write(); //writing the plots to file 
+  }
+  
+  //Reading in the parameters from runList.txt
+  char runList[100];
+  char str1[10],str2[10],str3[10],str4[10],str5[10],str6[10];
+  float a,b,c,f; char d[100], e[100]; 
+  float full_Angle[100], full_Bias[100], length[100];
+  float Angle[run], Bias[run], rmsX[run];
+  int r =0;
+  sprintf(runList, "%s", "/afs/cern.ch/user/e/ebuchana/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/runList.txt");
+ 
+  FILE * runFile = fopen (runList,"read");
+  cout << "reading in runList.txt " << endl;
+  fscanf(runFile, "%s \t %s \t %s \t %s \t %s \t %s", str1,str2,str3,str4,str5,str6);
+  
+  while (!feof(runFile)){
+    fscanf(runFile,"%f \t %f \t %f \t %s \t %s \t %f", &a, &b, &c, d, e, &f); 
+    full_Angle[r]=b;// all angles in runList.txt
+    full_Bias[r]=c; // all bias voltages in runList.txt
+    length[r]=f; // number of line in runList.txt
+    r++;
+  }
+  
+  //initalisng arrays (may not be needed)
+  for (int range =beg-1; range <end; range ++){
+    Angle[range]=0;
+    Bias[range]=0;
+  }
+ 
+  //saving the range of bias and angles that you need from the full set of parameters  
+  int in =0;
+  for (int range =beg-1; range <end; range ++){
+    Angle[in]=full_Angle[range];
+    Bias[in]=full_Bias[range];
+    in++;
+  }
+
+   
+  //Plots after this line will be in the LHCb style format.
+  gROOT->  ProcessLine(".x lhcbStyle.C");
+  
+  
+  if (choice==0){ //if Bias scan
+    //--------- for X ----------//
+    TCanvas *c1 = new TCanvas("c1", "Bias vs Xrms (DUT)");
+    TGraph *g1 = new TGraph(run, Bias, DUT_rmsX); 
+    g1->Draw("ap");
+    g1->SetTitle("Bias vs. DUT rms; Bias Voltage; DUT X spatial resolution "); 
+    c1->Print(plot_bias);
+    c1->Print(root_plotb);
+    //--------- for Y ----------//
+    TCanvas *c2 = new TCanvas("c2", "Bias vs Yrms (DUT)");
+    TGraph *g2 = new TGraph(run, Bias, DUT_rmsY);
+    g2->Draw("ap");
+    g2->SetTitle("Bias vs. DUT rms; Bias Voltage; DUT Y spatial resolution ");
+      // c2->Print(plot_bias);
+      //  c2->Print(root_plotb);
+    
+  }
+  
+  else{ //if angle scan
+    
+    TCanvas *c3 = new TCanvas("c3", "Angle vs Xrms (DUT)");
+    TGraph *g3 = new TGraph(run, Angle, DUT_rmsX); 
+    g3->Draw("ap");
+    c3->Print(plot_angle);
+    c3->Print(root_plota);
+    
+    TCanvas *c4 = new TCanvas("c4", "Angle vs Yrms (DUT)");
+    TGraph *g4 = new TGraph(run, Angle, DUT_rmsY);
+    g4->Draw("ap");
+    // c4->Print(plot_angle);
+    // c4->Print(root_plota);
+    
+  }
+  
+  
+}
+
+
+
diff --git a/Kepler/options/ResStudies/.svn/text-base/restudies.py.svn-base b/Kepler/options/ResStudies/.svn/text-base/restudies.py.svn-base
new file mode 100644
index 0000000..e04322b
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/restudies.py.svn-base
@@ -0,0 +1,106 @@
+# Configuration file for residual studies. 
+
+from os.path import join, abspath
+from sys     import path
+
+import pickle
+
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+cdir = "eos/lhcb/testbeam/velo/timepix3/LabData/TP/SurrogateParameterFiles/"
+cfile = {"W0009_J04"                    : [ cdir+"S20_Coarse64_26022015_SpidrTime_surrog_fitpars_perpix_NNsmoothingON.dat" ],
+         "W0009_H08,W0009_D09,W0009_E09": [ cdir+"T2_200V_TestPulse_SpidrTime_130315_CHIP0_surrog_fitpars_perpix_NNsmoothingON.dat",
+                                            cdir+"T2_200V_TestPulse_SpidrTime_130315_CHIP1_surrog_fitpars_perpix_NNsmoothingON.dat",
+                                            cdir+"T2_200V_TestPulse_SpidrTime_130315_CHIP2_surrog_fitpars_perpix_NNsmoothingON.dat"]
+         }
+
+PATH_TO_OPTS= abspath('/afs/cern.ch/user/c/chombach/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/')
+path.append( PATH_TO_OPTS )
+from Runs import Runs
+
+pickled_runs = PATH_TO_OPTS+'/Runs.pkl'
+runs = pickle.load( open( pickled_runs ) )
+
+block = runs.BLOCKS[0]
+rdut = runs.RUNS[block][0].DUT
+#runs = Runs('A','run')
+
+if runs.TYPE == 'survey':
+    Kepler().Alignment = True
+    Kepler().EvtMax = 100
+
+    from Configurables import TbClusterPlots
+    # Set the reference plane.
+    TbClusterPlots().ReferencePlane = 3
+
+    # Widen the range of the difference histograms if needed.
+    TbClusterPlots().ParametersDifferenceXY = ('', -30., 30., 600)
+    from Configurables import TbAlignment
+    TbAlignment().AlignmentTechnique = "survey"
+
+    from Configurables import TbEventBuilder
+    TbEventBuilder().MinPlanesWithHits = 5
+
+elif runs.TYPE == 'mille':
+    Kepler().Alignment = True
+    Kepler().EvtMax = 100
+    
+    # List of devices under test
+    duts = [4]
+    from Configurables import TbTracking
+    # Exclude DUTs from the pattern recognition.
+    TbTracking().MaskedPlanes = duts
+    # Require clusters on all telescope planes.
+    TbTracking().MinNClusters = 8
+    from Configurables import TbClusterPlots
+    # Set the reference plane.
+    TbClusterPlots().ReferencePlane = 3
+    TbClusterPlots().ParametersDifferenceXY = ('', -10., 10., 200)
+    from Configurables import TbAlignment
+    
+    # Set the number of tracks to process.
+    TbAlignment().NTracks = 10000
+    # Set the reference plane (fixed position).
+    TbAlignment().ReferencePlane = 3
+    # Set the degrees of freedom (x, y, z, rx, ry, rz).
+    TbAlignment().DoFs = [1, 1, 0, 1, 1, 1]
+    TbAlignment().ParametersResidualsXY = ("", -0.2, 0.2, 100)
+    TbAlignment().MaskedPlanes = duts
+    TbAlignment().PrintConfiguration = True
+    TbAlignment().ResCutInit = 1.3
+    TbAlignment().ResCut = 0.06
+    TbAlignment().NIterations = 6
+    
+    TbAlignment().AlignmentTechnique = "Millepede"
+
+    from Configurables import TbMillepede
+    TbMillepede().OutputLevel = 2
+    from Configurables import TbEventBuilder
+    TbEventBuilder().MinPlanesWithHits = 5
+
+elif runs.TYPE == 'dut':
+    Kepler().Alignment = True
+    Kepler().EvtMax = 100
+
+    from Configurables import TbAlignment
+    TbAlignment().AlignmentTechnique = "Millepede"
+    TbAlignment().MilleDUT = True
+    TbAlignment().DeviceToAlign = 4
+    TbAlignment().DoFs = [1, 1, 0, 1, 1, 1]
+    # Set the number of tracks to process.
+    TbAlignment().NTracks = 10000
+
+    from Configurables import TbEventBuilder
+    TbEventBuilder().MinPlanesWithHits = 5
+elif runs.TYPE == 'run':
+    Kepler().Alignment = False
+    Kepler().EvtMax = 1000
+
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+
+Kepler().PixelConfigFile = cfile[ rdut ]
diff --git a/Kepler/options/ResStudies/.svn/text-base/runList.txt.svn-base b/Kepler/options/ResStudies/.svn/text-base/runList.txt.svn-base
new file mode 100644
index 0000000..c5718f6
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/runList.txt.svn-base
@@ -0,0 +1,53 @@
+#RUN	#ANGLE	#BIAS	#DUT		#BLOCK	#number			 
+2501	0	-40	W0009_J04	A	1
+2502	0	-80	W0009_J04	A	2
+2503	0	-100	W0009_J04	A	3
+2504	0	-120	W0009_J04	A	4	
+2506	0	-140	W0009_J04	A	5
+2507	0	-160	W0009_J04	A	6
+2508	0	-180	W0009_J04	A	7
+2509	0	-200	W0009_J04	A	8
+2510	0	-225	W0009_J04	A	9	
+2511	0	-250	W0009_J04	A	10
+2512	0	-275	W0009_J04	A	11	
+2513	0	-300	W0009_J04	A	12
+2603	0	-350	W0009_J04	B	13
+2604	0	-400	W0009_J04	B	14
+2605	0	-400	W0009_J04	B 	15
+2607	0	-400	W0009_J04	B	16
+2608	0	-497	W0009_J04	B	17	
+2515	-5	-200	W0009_J04	C	18
+2516	-2	-200	W0009_J04	C	19
+2517	-2	-200	W0009_J04	C	20
+2518	-2	-200	W0009_J04	C	21
+2519	-1	-200	W0009_J04	C	22
+2520	-0.5	-200	W0009_J04	C	23
+2521	0	-200	W0009_J04	C	24
+2522	0.5	-200	W0009_J04	C	25
+2523	1	-200	W0009_J04	C	26
+2524	2	-200	W0009_J04	C	27
+2525	5	-200	W0009_J04	C	28
+2526	8	-200	W0009_J04	C	29
+2527	9	-200	W0009_J04	C	30
+2528	10	-200	W0009_J04	C	31
+2529	12	-200	W0009_J04	C	32
+2530	14	-200	W0009_J04	C	33
+2531	15	-200	W0009_J04	C	34
+2532	16	-200	W0009_J04	C	35	
+2533	20	-200	W0009_J04	C	36
+3225   -3.25    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3226   -1.25    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3227    0.75	-150	W0009_H08,W0009_D09,W0009_E09	D1
+3230    3.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3233    8.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3234   13.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3235   18.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3236   23.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3237   28.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3239   -1.25    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3243   -20.25   -150    W0009_H08,W0009_D09,W0009_E09   D1
+3244   -20.25   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3245    18.75   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3246    23.75   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3247    28.75   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3248   -1.25    -150    W0009_H08,W0009_D09,W0009_E09   D2
diff --git a/Kepler/options/ResStudies/.svn/text-base/submitRes.py.svn-base b/Kepler/options/ResStudies/.svn/text-base/submitRes.py.svn-base
new file mode 100644
index 0000000..42c78cc
--- /dev/null
+++ b/Kepler/options/ResStudies/.svn/text-base/submitRes.py.svn-base
@@ -0,0 +1,72 @@
+########################################################################
+#  script to submit resolution study jobs to grid
+#  Define runs in runList.txt and combine those in a common block
+#  Define z-position configuration of block in ZPos.txt
+#  Define which block to run over and analysis step you want to perform
+#      -survey   :  Survey alignment
+#      -mille    :  Millepede alignmnet
+#      -dut      :  DUT run
+#      -run      :  Dry run using DUT alignment
+#
+#  for questions:   chris.hombach@gmail.com
+########################################################################
+import pickle
+from sys      import path
+from os.path  import abspath
+
+PATH_TO_OPTS= abspath('$HOME/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/')
+path.append( PATH_TO_OPTS )
+import Runs
+
+#Set blocks to run over and alignment-method
+blocks   = ['D1','D2']
+method   = 'run'  #survey, mille, dut, run
+######
+
+optsdir  = '$HOME/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/'
+
+opts     = '%srestudies.py' % optsdir
+kepler   = Kepler( optsfile=[ opts ] , version = 'HEAD' )
+BACKEND  = Local()#LSF(queue='1nh')#Dirac()
+#BACKEND  = Dirac()
+
+runs     = Runs.Runs(blocks, method)
+pickled_runs = 'Runs.pkl'
+pickle.dump( runs, open( pickled_runs , 'wb' ) )
+
+
+   
+
+for bl in blocks:
+    alfs     = {}
+    tbruns   = []    
+    for rn in runs.RUNS[bl]:
+        r  = rn.RUN
+        a  = rn.ANGLE
+        b  = rn.BIAS
+        d  = rn.DUT
+        af = rn.ALIGNFILE 
+        tbruns.append( int(r) )
+        if method == 'survey':
+            rn.createAlignFile()
+        alfs[int(r)] = af
+
+    if tbruns[0] < 2000:
+        m = 'July2014'
+    elif tbruns[0] < 3000:
+        m = 'Oct2014'
+    elif tbruns[0] < 4000:
+        m = 'Nov2014'
+    else:
+        m = 'Dec2014'
+    tbds     = TbDataset( m, tbruns )
+    tbds.AlignmentFiles = alfs
+
+
+    SPLITTER = tbds
+    j        = Job(application = kepler)
+    j.backend     = BACKEND
+    j.splitter    = SPLITTER
+    j.outputfiles = ['*.dat']
+
+    j.submit()
diff --git a/Kepler/options/ResStudies/AlignQualy.py b/Kepler/options/ResStudies/AlignQualy.py
new file mode 100644
index 0000000..c458fa5
--- /dev/null
+++ b/Kepler/options/ResStudies/AlignQualy.py
@@ -0,0 +1,87 @@
+from ROOT import TFile, TCanvas
+from Runs import Runs
+
+import os, sys
+block  = ['D1','D2']
+indir  = '/afs/cern.ch/work/c/chombach/Telescope/ResStudies/'
+outdir = '/afs/cern.ch/user/c/chombach/www/public/Telescope/AlignQualy/'
+
+os.system('mkdir -p '+outdir)
+
+outfile = outdir+'AlignQualy'
+for bl in block:
+    outfile += '_'+bl
+outfile += '.pdf'
+runs = Runs(block, 'run')
+runs.setOutputDir(indir)
+
+c = TCanvas('c','c',1200,600)
+c.Print(outfile+'(','pdf')
+
+def makePlots(tf, title):
+
+    c.Divide(0,0)
+    fn = 'Tb/TbTrackPlots/'
+    chi2 = tf.Get(fn+'Chi2PerDof')
+    chi2.SetTitle(title)
+    chi2.Draw()
+    c.Print(outfile,'pdf')
+
+    prob = tf.Get(fn+'Probability')
+    prob.SetTitle(title)
+    prob.Draw()
+    c.Print(outfile,'pdf')
+
+    c.Clear()
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_x = tf.Get(fn+'BiasedResiduals/GlobalX/Plane%i' % i )
+        res_x.SetTitle(title+' GlobalX Plane%i' % i)
+        res_x.Fit('gaus')
+        res_x.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_y = tf.Get(fn+'BiasedResiduals/GlobalY/Plane%i' % i )
+        res_y.SetTitle(title+' GlobalY Plane%i' % i)
+        res_y.Fit('gaus')
+        res_y.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_xvsx = tf.Get(fn+'BiasedResiduals/GlobalResXvsLocalX/Plane%i' % i )
+        res_xvsx.SetTitle(title+' GlobalXResvsX Plane%i' % i)
+        res_xvsx.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+
+    c.Divide(5,2)
+    for i in range(9):
+        c.cd(i+1)
+        res_yvsy = tf.Get(fn+'BiasedResiduals/GlobalResYvsLocalY/Plane%i' % i )
+        res_yvsy.SetTitle(title+' GlobalYResvsY Plane%i' % i)
+        res_yvsy.Draw()
+    c.Print(outfile,'pdf')
+    c.Clear()
+for block in runs.RUNS:
+    for run in runs.RUNS[block]:
+        rn  = run.RUN
+        ang = run.ANGLE
+        bia = run.BIAS
+        dut = run.DUT
+        block = run.BLOCK
+        title = '%s_%s_%s_%s' % (rn, dut, bia, ang)
+        fn = runs.OUTPUTDIR+block+'/Kepler_%s.root' % title
+        tf = TFile(fn)
+        makePlots(tf, title)
+        tf.Close()
+c.Print(outfile+')','pdf')
+
+
diff --git a/Kepler/options/ResStudies/Alignments/.svn/all-wcprops b/Kepler/options/ResStudies/Alignments/.svn/all-wcprops
new file mode 100644
index 0000000..4a88727
--- /dev/null
+++ b/Kepler/options/ResStudies/Alignments/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/188051/Kepler/trunk/Tb/Kepler/options/ResStudies/Alignments
+END
diff --git a/Kepler/options/ResStudies/Alignments/.svn/entries b/Kepler/options/ResStudies/Alignments/.svn/entries
new file mode 100644
index 0000000..d974aaa
--- /dev/null
+++ b/Kepler/options/ResStudies/Alignments/.svn/entries
@@ -0,0 +1,28 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/ResStudies/Alignments
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-12T10:54:52.097095Z
+188051
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
diff --git a/Kepler/options/ResStudies/Runs.py b/Kepler/options/ResStudies/Runs.py
new file mode 100644
index 0000000..aedcecc
--- /dev/null
+++ b/Kepler/options/ResStudies/Runs.py
@@ -0,0 +1,88 @@
+import os
+
+
+class Run():
+    def __init__(self, r, a, b, d, bl, ad, aod):
+        self.RUN       = r
+        self.ANGLE     = a
+        self.BIAS      = b
+        self.DUT       = d
+        self.BLOCK     = bl
+        absad = os.path.abspath( ad )
+        if not os.path.exists(absad):
+            os.system('mkdir -p %s' % absad)
+        absaod = os.path.abspath( aod )
+        if not os.path.exists(absaod):
+            os.system('mkdir -p %s' % absaod)
+        self.ALIGNFILE = absad+'/Alignment'+self.RUN+'.dat'
+        self.ALIGNOUTFILE = absaod+'/Alignment'+self.RUN+'.dat' 
+
+    def createAlignFile(self):
+        devs = ['', 'W0002_J06','W0002_B05','W0002_C05','W0002_D05',self.DUT,'W0002_G05','W0002_F05','W0002_H07','W0002_E05']
+        s = ''
+        zfile = open('ZPos.txt','r')
+        for ll in zfile.readlines():
+            l = ll.split()
+            if '#' in l[0]:
+                continue
+            if l[0] == self.BLOCK:
+                z  = l
+        for i in range(9):
+            if i < 4:
+                s+= '%s 14.03 14.03 %s 2.9845 3.299 0.\n' %  (devs[i+1], z[i+1])
+            elif i == 4:
+                s+= '%s 0.0 14.03 %s 3.141 %f 0.\n' %  (devs[i+1], z[i+1], float(self.ANGLE)*3.141/180. )
+            else:
+                s+= '%s 0.0 14.03 %s 3.299 0.157 0.\n' %  (devs[i+1], z[i+1])
+
+        af = open(self.ALIGNFILE, 'w')
+        af.write(s)
+        af.close
+
+class Runs():
+    def __init__(self, b, type):
+        self.BLOCKS = b
+        if type == 'survey':
+            ad = 'init'
+        elif type == 'mille':
+            ad = 'survey'
+        elif type == 'dut':
+            ad = 'mille'
+        else:
+            ad = 'dut'
+        self.TYPE        = type
+        self.ALIGNDIR    = "Alignments/%s/" % (ad)
+        print self.ALIGNDIR
+        self.ALIGNOUTDIR = "Alignments/%s/" % (type) 
+        self.RUNS        = self.defRuns()
+        self.OUTPUTDIR   = ''
+
+    def defRuns(self):
+        rs = {}
+        f  = open('runList.txt','r')
+        for ll in f.readlines():
+            l = ll.split()
+            if '#' in l[0]:
+                continue
+            r = l[0]
+            a = l[1]
+            b = l[2]
+            d = l[3]
+            bl= l[4]
+            if bl in self.BLOCKS:
+                run = Run(r,a,b,d, bl, self.ALIGNDIR, self.ALIGNOUTDIR)
+                if bl in rs:
+                    rs[bl].append(run)
+                else:
+                    rs[bl] = [run]
+        f.close()
+        return rs
+
+    def findRun(self, rn):
+        for b in self.RUNS:
+            for r in self.RUNS[b]:
+                if r.RUN == rn:
+                    return r
+    
+    def setOutputDir(self, od):
+        self.OUTPUTDIR = od
diff --git a/Kepler/options/ResStudies/ZPos.txt b/Kepler/options/ResStudies/ZPos.txt
new file mode 100644
index 0000000..428f538
--- /dev/null
+++ b/Kepler/options/ResStudies/ZPos.txt
@@ -0,0 +1,4 @@
+#BLOCK	W0002_J06	W0002_B05	W0002_C05	W0002_D05	DUT	W0002_G05	W0002_F05	W0002_H07    W0002_E05
+A	0		60		120		180		390	530		590		654	     715
+D1	0		60		120		180		300	425		485		549	     610
+D2      0               60              120             180             300     425             485             549          610
diff --git a/Kepler/options/ResStudies/copyAligns.py b/Kepler/options/ResStudies/copyAligns.py
new file mode 100644
index 0000000..62def68
--- /dev/null
+++ b/Kepler/options/ResStudies/copyAligns.py
@@ -0,0 +1,42 @@
+import os,sys
+import Runs
+jobnr    = 2870
+
+#Set blocks to run over and alignment-method
+blocks   = ['D2']
+method   = 'run'
+#
+
+
+gangadir   = '/afs/cern.ch/work/c/chombach/gangadir/workspace/chombach/LocalXML/%i/' % jobnr
+rootout    = '/afs/cern.ch/work/c/chombach/Telescope/ResStudies/' 
+for bl in blocks:
+    rootout += bl
+    rootout +=  '/'
+    os.system( 'mkdir -p %s' % rootout )
+def findRunNo( so ):
+    sof = open( so )
+    for ll in sof.readlines():
+        l = ll.split()
+        if len(l) == 0:
+            continue
+        if l[0] == 'TbDataSvc':
+            ind = l[4].find('Run')
+            return l[4][ind+3:ind+7]
+
+runs = Runs.Runs(blocks, method)
+
+if method == 'run':
+    runs.setOutputDir( rootout )
+    
+for dd in os.listdir(gangadir):
+    if dd == 'debug':
+        continue
+    rn = findRunNo(gangadir+dd+'/output/stdout')
+    run = runs.findRun( rn )
+    
+    os.system('cp %s %s' % ( gangadir+dd+'/output/Alignment_out.dat', run.ALIGNOUTFILE) )
+    if method == 'run':
+        outfile = runs.OUTPUTDIR+'Kepler_%s_%s_%s_%s.root' % (rn, run.DUT, run.BIAS, run.ANGLE)
+        os.system('cp %s %s' % ( gangadir+dd+'/output/Kepler-histos.root', outfile) )
+
diff --git a/Kepler/options/ResStudies/lhcbStyle.C b/Kepler/options/ResStudies/lhcbStyle.C
new file mode 100644
index 0000000..39e0657
--- /dev/null
+++ b/Kepler/options/ResStudies/lhcbStyle.C
@@ -0,0 +1,196 @@
+// all users - please change the name of this file to lhcbStyle.C
+// Commits to lhcbdocs svn of .C files are not allowed
+{
+
+  // define names for colours
+  Int_t black  = 1;
+  Int_t red    = 2;
+  Int_t green  = 3;
+  Int_t blue   = 4;
+  Int_t yellow = 5; 
+  Int_t magenta= 6;
+  Int_t cyan   = 7;
+  Int_t purple = 9;
+  
+
+////////////////////////////////////////////////////////////////////
+// PURPOSE:
+//
+// This macro defines a standard style for (black-and-white) 
+// "publication quality" LHCb ROOT plots. 
+//
+// USAGE:
+//
+// Include the lines
+//   gROOT->ProcessLine(".L lhcbstyle.C");
+//   lhcbStyle();
+// at the beginning of your root macro.
+//
+// Example usage is given in myPlot.C
+//
+// COMMENTS:
+//
+// Font:
+// 
+// The font is chosen to be 132, this is Times New Roman (like the text of
+//  your document) with precision 2.
+//
+// "Landscape histograms":
+//
+// The style here is designed for more or less square plots.
+// For longer histograms, or canvas with many pads, adjustements are needed. 
+// For instance, for a canvas with 1x5 histograms:
+//  TCanvas* c1 = new TCanvas("c1", "L0 muons", 600, 800);
+//  c1->Divide(1,5);
+//  Adaptions like the following will be needed:
+//  gStyle->SetTickLength(0.05,"x");
+//  gStyle->SetTickLength(0.01,"y");
+//  gStyle->SetLabelSize(0.15,"x");
+//  gStyle->SetLabelSize(0.1,"y");
+//  gStyle->SetStatW(0.15);
+//  gStyle->SetStatH(0.5);
+//
+// Authors: Thomas Schietinger, Andrew Powell, Chris Parkes, Niels Tuning
+// Maintained by Editorial board member (currently Niels)
+///////////////////////////////////////////////////////////////////
+
+  // Use times new roman, precision 2 
+  Int_t lhcbFont        = 132;  // Old LHCb style: 62;
+  // Line thickness
+  Double_t lhcbWidth    = 2.00; // Old LHCb style: 3.00;
+  // Text size
+  Double_t lhcbTSize    = 0.06; 
+  
+  // use plain black on white colors
+  gROOT->SetStyle("Plain"); 
+  TStyle *lhcbStyle= new TStyle("lhcbStyle","LHCb plots style");
+  
+  //lhcbStyle->SetErrorX(0); //  don't suppress the error bar along X
+
+  lhcbStyle->SetFillColor(1);
+  lhcbStyle->SetFillStyle(1001);   // solid
+  lhcbStyle->SetFrameFillColor(0);
+  lhcbStyle->SetFrameBorderMode(0);
+  lhcbStyle->SetPadBorderMode(0);
+  lhcbStyle->SetPadColor(0);
+  lhcbStyle->SetCanvasBorderMode(0);
+  lhcbStyle->SetCanvasColor(0);
+  lhcbStyle->SetStatColor(0);
+  lhcbStyle->SetLegendBorderSize(0);
+  lhcbStyle->SetLegendFont(132);
+
+  // If you want the usual gradient palette (blue -> red)
+  lhcbStyle->SetPalette(1);
+  // If you want colors that correspond to gray scale in black and white:
+  int colors[8] = {0,5,7,3,6,2,4,1};
+  // lhcbStyle->SetPalette(8,colors);
+
+  // set the paper & margin sizes
+  lhcbStyle->SetPaperSize(20,26);
+  lhcbStyle->SetPadTopMargin(0.05);
+  lhcbStyle->SetPadRightMargin(0.05); // increase for colz plots
+  lhcbStyle->SetPadBottomMargin(0.16);
+  lhcbStyle->SetPadLeftMargin(0.14);
+  
+  // use large fonts
+  lhcbStyle->SetTextFont(lhcbFont);
+  lhcbStyle->SetTextSize(lhcbTSize);
+  lhcbStyle->SetLabelFont(lhcbFont,"x");
+  lhcbStyle->SetLabelFont(lhcbFont,"y");
+  lhcbStyle->SetLabelFont(lhcbFont,"z");
+  lhcbStyle->SetLabelSize(lhcbTSize,"x");
+  lhcbStyle->SetLabelSize(lhcbTSize,"y");
+  lhcbStyle->SetLabelSize(lhcbTSize,"z");
+  lhcbStyle->SetTitleFont(lhcbFont);
+  lhcbStyle->SetTitleFont(lhcbFont,"x");
+  lhcbStyle->SetTitleFont(lhcbFont,"y");
+  lhcbStyle->SetTitleFont(lhcbFont,"z");
+  lhcbStyle->SetTitleSize(1.2*lhcbTSize,"x");
+  lhcbStyle->SetTitleSize(1.2*lhcbTSize,"y");
+  lhcbStyle->SetTitleSize(1.2*lhcbTSize,"z");
+
+  // use medium bold lines and thick markers
+  lhcbStyle->SetLineWidth(lhcbWidth);
+  lhcbStyle->SetFrameLineWidth(lhcbWidth);
+  lhcbStyle->SetHistLineWidth(lhcbWidth);
+  lhcbStyle->SetFuncWidth(lhcbWidth);
+  lhcbStyle->SetGridWidth(lhcbWidth);
+  lhcbStyle->SetLineStyleString(2,"[12 12]"); // postscript dashes
+  lhcbStyle->SetMarkerStyle(20);
+  lhcbStyle->SetMarkerSize(1.0);
+
+  // label offsets
+  lhcbStyle->SetLabelOffset(0.010,"X");
+  lhcbStyle->SetLabelOffset(0.010,"Y");
+
+  // by default, do not display histogram decorations:
+  lhcbStyle->SetOptStat(0);  
+  //lhcbStyle->SetOptStat("emr");  // show only nent -e , mean - m , rms -r
+  // full opts at http://root.cern.ch/root/html/TStyle.html#TStyle:SetOptStat
+  lhcbStyle->SetStatFormat("6.3g"); // specified as c printf options
+  lhcbStyle->SetOptTitle(0);
+  lhcbStyle->SetOptFit(0);
+  //lhcbStyle->SetOptFit(1011); // order is probability, Chi2, errors, parameters
+  //titles
+  lhcbStyle->SetTitleOffset(0.95,"X");
+  lhcbStyle->SetTitleOffset(0.95,"Y");
+  lhcbStyle->SetTitleOffset(1.2,"Z");
+  lhcbStyle->SetTitleFillColor(0);
+  lhcbStyle->SetTitleStyle(0);
+  lhcbStyle->SetTitleBorderSize(0);
+  lhcbStyle->SetTitleFont(lhcbFont,"title");
+  lhcbStyle->SetTitleX(0.0);
+  lhcbStyle->SetTitleY(1.0); 
+  lhcbStyle->SetTitleW(1.0);
+  lhcbStyle->SetTitleH(0.05);
+  
+  // look of the statistics box:
+  lhcbStyle->SetStatBorderSize(0);
+  lhcbStyle->SetStatFont(lhcbFont);
+  lhcbStyle->SetStatFontSize(0.05);
+  lhcbStyle->SetStatX(0.9);
+  lhcbStyle->SetStatY(0.9);
+  lhcbStyle->SetStatW(0.25);
+  lhcbStyle->SetStatH(0.15);
+
+  // put tick marks on top and RHS of plots
+  lhcbStyle->SetPadTickX(1);
+  lhcbStyle->SetPadTickY(1);
+
+  // histogram divisions: only 5 in x to avoid label overlaps
+  lhcbStyle->SetNdivisions(505,"x");
+  lhcbStyle->SetNdivisions(510,"y");
+  
+  gROOT->SetStyle("lhcbStyle");
+  gROOT->ForceStyle();
+
+  // add LHCb label
+  lhcbName = new TPaveText(gStyle->GetPadLeftMargin() + 0.05,
+                           0.87 - gStyle->GetPadTopMargin(),
+                           gStyle->GetPadLeftMargin() + 0.20,
+                           0.95 - gStyle->GetPadTopMargin(),
+                           "BRNDC");
+  lhcbName->AddText("LHCb");
+  lhcbName->SetFillColor(0);
+  lhcbName->SetTextAlign(12);
+  lhcbName->SetBorderSize(0);
+
+  TText *lhcbLabel = new TText();
+  lhcbLabel->SetTextFont(lhcbFont);
+  lhcbLabel->SetTextColor(1);
+  lhcbLabel->SetTextSize(lhcbTSize);
+  lhcbLabel->SetTextAlign(12);
+
+  TLatex *lhcbLatex = new TLatex();
+  lhcbLatex->SetTextFont(lhcbFont);
+  lhcbLatex->SetTextColor(1);
+  lhcbLatex->SetTextSize(lhcbTSize);
+  lhcbLatex->SetTextAlign(12);
+
+  cout << "-------------------------" << endl;  
+  cout << "Set LHCb Style - Feb 2012" << endl;
+  cout << "-------------------------" << endl;  
+  
+}
+
+
diff --git a/Kepler/options/ResStudies/res_analysis.C b/Kepler/options/ResStudies/res_analysis.C
new file mode 100644
index 0000000..ffffc3d
--- /dev/null
+++ b/Kepler/options/ResStudies/res_analysis.C
@@ -0,0 +1,180 @@
+#include "TFile.h"
+#include "TH2.h"
+#include "TH1.h"
+#include "TF1.h"
+#include "TGraphErrors.h"
+#include "iostream"
+#include <stdio.h>
+#include "Riostream.h"
+#include <math.h>
+#include <stdlib.h>
+#include <string>
+#include <vector>
+#include "TRandom.h"
+#include "TGraph.h"
+#include "TMultiGraph.h"
+#include "TCanvas.h"
+#include "TMath.h"
+#include "TLegend.h"
+//script opens the kepler-histograms sent by submitRes.py to the grid, specifically taking the unbiased residual for the DUT (plane 4) for both X and Y. 
+//Fits a guassian to each of the residuals and stores the mean and rms. 
+//Plots them as a function of Bias or Angle, where the bias and angle values are stored in runList.txt 
+//stores them as a .png and .root file format (in LHCb style)
+//run as root -b if you dont want canvas printed to screen. 
+//MAY need to change path in ~L62 to your own!!!!!
+//Emma Buchanan May 2015 (emma.buchanan@cern.ch) 
+
+void res_analysis(){
+  //-------Change Parameters Here------//
+  const int job = 9; //job number
+  const int run =5; //number of subjobs in this job 
+  const int beg= 13; //from runList.txt what is the range of the "Block" begining->end
+  const int end= 17; 
+  int choice =0; //Is this an Bias or angle scan?  (0 for Bias, 1 for angle)
+  const int iplane =4; //number of the plane you wish to analyse (DUT =4)
+
+  //saving the final plot as a .png, and/or root file 
+  char plot_bias[200]; //the name of the plot, will be printed to a .png at the end of this script.
+  sprintf(plot_bias, "%s", "sensor_bias_scan.png");
+  char plot_angle[200];
+  sprintf(plot_angle, "%s", "sensor_angle_scan.png");
+  char root_plotb[100]; //this .root file will contain the final plot/s
+  sprintf(root_plotb, "%s", "sensor_bias_scan.root");
+  char root_plota[100]; //this .root file will contain the final plot/s
+  sprintf(root_plota, "%s", "sensor_angle_scan.root");
+  //----------end of parameters--------//
+
+
+  //Reading kepler histograms and fitting gaussian to DUT
+  float DUT_meanX[run];  float DUT_rmsX[run]; //fit parameters for X
+  float DUT_meanY[run];  float DUT_rmsY[run]; //fit parameters for Y
+  TF1 *gauss = new TF1("gauss","gaus");
+  TH1F *XDUT[run];
+  TH1F *YDUT[run];
+  TCanvas *Xcanvas[run];
+  TCanvas *Ycanvas[run];
+ 
+  //opening the DUT (plane 4) from the kepler-histos and fitting a gaussian to each.  
+  char filename[100];
+  char locationX[100];  char locationY[100];
+  TFile *openFile[100]; 
+  for (int subjob =0; subjob<run; subjob++){
+      sprintf(filename, "%s%d%s%d%s","/afs/cern.ch/user/e/ebuchana/gangadir/workspace/ebuchana/LocalXML/",job,"/",subjob,"/output/Kepler-histos.root "); //the location of each root file for each run 
+      sprintf(locationX, "%s%d", "Tb/TbTrackPlots/BiasedResiduals/GlobalX/Plane",iplane); //location of the biased residual of the DUT
+      sprintf(locationY, "%s%d", "Tb/TbTrackPlots/BiasedResiduals/GlobalY/Plane",iplane); //location of the biased residual of the DUT
+      cout << filename << endl;
+      openFile[subjob] = new TFile(filename); //opening the root files
+
+      //------------------ For X ------------------//
+      cout << locationX << endl;
+      Xcanvas[subjob] = new TCanvas(); //creating a canvas for each histogram 
+      Xcanvas[subjob]->SetTitle("X Biased Residal for DUT"); //setting canvas title 
+      XDUT[subjob] = (TH1F*)openFile[subjob]->Get(locationX); //getting each of the histograms from the kepler root files
+      XDUT[subjob]->Fit("gauss", "R"); //fitting guassian
+      DUT_meanX[subjob]=XDUT[subjob]->GetFunction("gauss")->GetParameter(1); //getting the mean of the postion 
+      DUT_rmsX[subjob]=XDUT[subjob]->GetFunction("gauss")->GetParameter(2); //this should be the RMS 
+      cout << "DUT mean X\t" << DUT_meanX[subjob] <<endl;
+      cout << "DUT rms X\t" << DUT_rmsX[subjob] <<endl;      
+
+      //------------------ For Y ------------------//
+      cout << locationY << endl;
+      Ycanvas[subjob] = new TCanvas(); //creating a canvas for each histogram
+      Ycanvas[subjob]->SetTitle("Y Biased Residal for DUT"); //setting canvas title      
+      YDUT[subjob] = (TH1F*)openFile[subjob]->Get(locationY); //getting each of the histograms from the kepler root files      
+      YDUT[subjob]->Fit("gauss", "R"); //fitting guassian      
+      DUT_meanY[subjob]=YDUT[subjob]->GetFunction("gauss")->GetParameter(1); //getting the mean of the postion      
+      DUT_rmsY[subjob]=YDUT[subjob]->GetFunction("gauss")->GetParameter(2); //this should be the RMS      
+      cout << "DUT mean Y\t" << DUT_meanY[subjob] <<endl;
+      cout << "DUT rms Y\t" << DUT_rmsY[subjob] <<endl;
+
+  }
+
+  //Printing to the DUT histograms and gaussian fits to a new root file 
+  char rootFile[100];
+  sprintf(rootFile, "%s", "root_res_analysis.root");
+  cout << "creating\t" << rootFile << endl;
+  TFile *myfile =  new TFile(rootFile,"RECREATE"); // creating rootfile
+  for (int subjob =0; subjob<run; subjob++){
+    XDUT[subjob]->Write(); //writing the plots to file 
+    YDUT[subjob]->Write(); //writing the plots to file 
+  }
+  
+  //Reading in the parameters from runList.txt
+  char runList[100];
+  char str1[10],str2[10],str3[10],str4[10],str5[10],str6[10];
+  float a,b,c,f; char d[100], e[100]; 
+  float full_Angle[100], full_Bias[100], length[100];
+  float Angle[run], Bias[run], rmsX[run];
+  int r =0;
+  sprintf(runList, "%s", "/afs/cern.ch/user/e/ebuchana/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/runList.txt");
+ 
+  FILE * runFile = fopen (runList,"read");
+  cout << "reading in runList.txt " << endl;
+  fscanf(runFile, "%s \t %s \t %s \t %s \t %s \t %s", str1,str2,str3,str4,str5,str6);
+  
+  while (!feof(runFile)){
+    fscanf(runFile,"%f \t %f \t %f \t %s \t %s \t %f", &a, &b, &c, d, e, &f); 
+    full_Angle[r]=b;// all angles in runList.txt
+    full_Bias[r]=c; // all bias voltages in runList.txt
+    length[r]=f; // number of line in runList.txt
+    r++;
+  }
+  
+  //initalisng arrays (may not be needed)
+  for (int range =beg-1; range <end; range ++){
+    Angle[range]=0;
+    Bias[range]=0;
+  }
+ 
+  //saving the range of bias and angles that you need from the full set of parameters  
+  int in =0;
+  for (int range =beg-1; range <end; range ++){
+    Angle[in]=full_Angle[range];
+    Bias[in]=full_Bias[range];
+    in++;
+  }
+
+   
+  //Plots after this line will be in the LHCb style format.
+  gROOT->  ProcessLine(".x lhcbStyle.C");
+  
+  
+  if (choice==0){ //if Bias scan
+    //--------- for X ----------//
+    TCanvas *c1 = new TCanvas("c1", "Bias vs Xrms (DUT)");
+    TGraph *g1 = new TGraph(run, Bias, DUT_rmsX); 
+    g1->Draw("ap");
+    g1->SetTitle("Bias vs. DUT rms; Bias Voltage; DUT X spatial resolution "); 
+    c1->Print(plot_bias);
+    c1->Print(root_plotb);
+    //--------- for Y ----------//
+    TCanvas *c2 = new TCanvas("c2", "Bias vs Yrms (DUT)");
+    TGraph *g2 = new TGraph(run, Bias, DUT_rmsY);
+    g2->Draw("ap");
+    g2->SetTitle("Bias vs. DUT rms; Bias Voltage; DUT Y spatial resolution ");
+      // c2->Print(plot_bias);
+      //  c2->Print(root_plotb);
+    
+  }
+  
+  else{ //if angle scan
+    
+    TCanvas *c3 = new TCanvas("c3", "Angle vs Xrms (DUT)");
+    TGraph *g3 = new TGraph(run, Angle, DUT_rmsX); 
+    g3->Draw("ap");
+    c3->Print(plot_angle);
+    c3->Print(root_plota);
+    
+    TCanvas *c4 = new TCanvas("c4", "Angle vs Yrms (DUT)");
+    TGraph *g4 = new TGraph(run, Angle, DUT_rmsY);
+    g4->Draw("ap");
+    // c4->Print(plot_angle);
+    // c4->Print(root_plota);
+    
+  }
+  
+  
+}
+
+
+
diff --git a/Kepler/options/ResStudies/restudies.py b/Kepler/options/ResStudies/restudies.py
new file mode 100644
index 0000000..e04322b
--- /dev/null
+++ b/Kepler/options/ResStudies/restudies.py
@@ -0,0 +1,106 @@
+# Configuration file for residual studies. 
+
+from os.path import join, abspath
+from sys     import path
+
+import pickle
+
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+cdir = "eos/lhcb/testbeam/velo/timepix3/LabData/TP/SurrogateParameterFiles/"
+cfile = {"W0009_J04"                    : [ cdir+"S20_Coarse64_26022015_SpidrTime_surrog_fitpars_perpix_NNsmoothingON.dat" ],
+         "W0009_H08,W0009_D09,W0009_E09": [ cdir+"T2_200V_TestPulse_SpidrTime_130315_CHIP0_surrog_fitpars_perpix_NNsmoothingON.dat",
+                                            cdir+"T2_200V_TestPulse_SpidrTime_130315_CHIP1_surrog_fitpars_perpix_NNsmoothingON.dat",
+                                            cdir+"T2_200V_TestPulse_SpidrTime_130315_CHIP2_surrog_fitpars_perpix_NNsmoothingON.dat"]
+         }
+
+PATH_TO_OPTS= abspath('/afs/cern.ch/user/c/chombach/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/')
+path.append( PATH_TO_OPTS )
+from Runs import Runs
+
+pickled_runs = PATH_TO_OPTS+'/Runs.pkl'
+runs = pickle.load( open( pickled_runs ) )
+
+block = runs.BLOCKS[0]
+rdut = runs.RUNS[block][0].DUT
+#runs = Runs('A','run')
+
+if runs.TYPE == 'survey':
+    Kepler().Alignment = True
+    Kepler().EvtMax = 100
+
+    from Configurables import TbClusterPlots
+    # Set the reference plane.
+    TbClusterPlots().ReferencePlane = 3
+
+    # Widen the range of the difference histograms if needed.
+    TbClusterPlots().ParametersDifferenceXY = ('', -30., 30., 600)
+    from Configurables import TbAlignment
+    TbAlignment().AlignmentTechnique = "survey"
+
+    from Configurables import TbEventBuilder
+    TbEventBuilder().MinPlanesWithHits = 5
+
+elif runs.TYPE == 'mille':
+    Kepler().Alignment = True
+    Kepler().EvtMax = 100
+    
+    # List of devices under test
+    duts = [4]
+    from Configurables import TbTracking
+    # Exclude DUTs from the pattern recognition.
+    TbTracking().MaskedPlanes = duts
+    # Require clusters on all telescope planes.
+    TbTracking().MinNClusters = 8
+    from Configurables import TbClusterPlots
+    # Set the reference plane.
+    TbClusterPlots().ReferencePlane = 3
+    TbClusterPlots().ParametersDifferenceXY = ('', -10., 10., 200)
+    from Configurables import TbAlignment
+    
+    # Set the number of tracks to process.
+    TbAlignment().NTracks = 10000
+    # Set the reference plane (fixed position).
+    TbAlignment().ReferencePlane = 3
+    # Set the degrees of freedom (x, y, z, rx, ry, rz).
+    TbAlignment().DoFs = [1, 1, 0, 1, 1, 1]
+    TbAlignment().ParametersResidualsXY = ("", -0.2, 0.2, 100)
+    TbAlignment().MaskedPlanes = duts
+    TbAlignment().PrintConfiguration = True
+    TbAlignment().ResCutInit = 1.3
+    TbAlignment().ResCut = 0.06
+    TbAlignment().NIterations = 6
+    
+    TbAlignment().AlignmentTechnique = "Millepede"
+
+    from Configurables import TbMillepede
+    TbMillepede().OutputLevel = 2
+    from Configurables import TbEventBuilder
+    TbEventBuilder().MinPlanesWithHits = 5
+
+elif runs.TYPE == 'dut':
+    Kepler().Alignment = True
+    Kepler().EvtMax = 100
+
+    from Configurables import TbAlignment
+    TbAlignment().AlignmentTechnique = "Millepede"
+    TbAlignment().MilleDUT = True
+    TbAlignment().DeviceToAlign = 4
+    TbAlignment().DoFs = [1, 1, 0, 1, 1, 1]
+    # Set the number of tracks to process.
+    TbAlignment().NTracks = 10000
+
+    from Configurables import TbEventBuilder
+    TbEventBuilder().MinPlanesWithHits = 5
+elif runs.TYPE == 'run':
+    Kepler().Alignment = False
+    Kepler().EvtMax = 1000
+
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+
+Kepler().PixelConfigFile = cfile[ rdut ]
diff --git a/Kepler/options/ResStudies/runList.txt b/Kepler/options/ResStudies/runList.txt
new file mode 100644
index 0000000..c5718f6
--- /dev/null
+++ b/Kepler/options/ResStudies/runList.txt
@@ -0,0 +1,53 @@
+#RUN	#ANGLE	#BIAS	#DUT		#BLOCK	#number			 
+2501	0	-40	W0009_J04	A	1
+2502	0	-80	W0009_J04	A	2
+2503	0	-100	W0009_J04	A	3
+2504	0	-120	W0009_J04	A	4	
+2506	0	-140	W0009_J04	A	5
+2507	0	-160	W0009_J04	A	6
+2508	0	-180	W0009_J04	A	7
+2509	0	-200	W0009_J04	A	8
+2510	0	-225	W0009_J04	A	9	
+2511	0	-250	W0009_J04	A	10
+2512	0	-275	W0009_J04	A	11	
+2513	0	-300	W0009_J04	A	12
+2603	0	-350	W0009_J04	B	13
+2604	0	-400	W0009_J04	B	14
+2605	0	-400	W0009_J04	B 	15
+2607	0	-400	W0009_J04	B	16
+2608	0	-497	W0009_J04	B	17	
+2515	-5	-200	W0009_J04	C	18
+2516	-2	-200	W0009_J04	C	19
+2517	-2	-200	W0009_J04	C	20
+2518	-2	-200	W0009_J04	C	21
+2519	-1	-200	W0009_J04	C	22
+2520	-0.5	-200	W0009_J04	C	23
+2521	0	-200	W0009_J04	C	24
+2522	0.5	-200	W0009_J04	C	25
+2523	1	-200	W0009_J04	C	26
+2524	2	-200	W0009_J04	C	27
+2525	5	-200	W0009_J04	C	28
+2526	8	-200	W0009_J04	C	29
+2527	9	-200	W0009_J04	C	30
+2528	10	-200	W0009_J04	C	31
+2529	12	-200	W0009_J04	C	32
+2530	14	-200	W0009_J04	C	33
+2531	15	-200	W0009_J04	C	34
+2532	16	-200	W0009_J04	C	35	
+2533	20	-200	W0009_J04	C	36
+3225   -3.25    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3226   -1.25    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3227    0.75	-150	W0009_H08,W0009_D09,W0009_E09	D1
+3230    3.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3233    8.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3234   13.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3235   18.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3236   23.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3237   28.75    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3239   -1.25    -150    W0009_H08,W0009_D09,W0009_E09   D1
+3243   -20.25   -150    W0009_H08,W0009_D09,W0009_E09   D1
+3244   -20.25   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3245    18.75   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3246    23.75   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3247    28.75   -150    W0009_H08,W0009_D09,W0009_E09   D2
+3248   -1.25    -150    W0009_H08,W0009_D09,W0009_E09   D2
diff --git a/Kepler/options/ResStudies/submitRes.py b/Kepler/options/ResStudies/submitRes.py
new file mode 100644
index 0000000..42c78cc
--- /dev/null
+++ b/Kepler/options/ResStudies/submitRes.py
@@ -0,0 +1,72 @@
+########################################################################
+#  script to submit resolution study jobs to grid
+#  Define runs in runList.txt and combine those in a common block
+#  Define z-position configuration of block in ZPos.txt
+#  Define which block to run over and analysis step you want to perform
+#      -survey   :  Survey alignment
+#      -mille    :  Millepede alignmnet
+#      -dut      :  DUT run
+#      -run      :  Dry run using DUT alignment
+#
+#  for questions:   chris.hombach@gmail.com
+########################################################################
+import pickle
+from sys      import path
+from os.path  import abspath
+
+PATH_TO_OPTS= abspath('$HOME/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/')
+path.append( PATH_TO_OPTS )
+import Runs
+
+#Set blocks to run over and alignment-method
+blocks   = ['D1','D2']
+method   = 'run'  #survey, mille, dut, run
+######
+
+optsdir  = '$HOME/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/options/ResStudies/'
+
+opts     = '%srestudies.py' % optsdir
+kepler   = Kepler( optsfile=[ opts ] , version = 'HEAD' )
+BACKEND  = Local()#LSF(queue='1nh')#Dirac()
+#BACKEND  = Dirac()
+
+runs     = Runs.Runs(blocks, method)
+pickled_runs = 'Runs.pkl'
+pickle.dump( runs, open( pickled_runs , 'wb' ) )
+
+
+   
+
+for bl in blocks:
+    alfs     = {}
+    tbruns   = []    
+    for rn in runs.RUNS[bl]:
+        r  = rn.RUN
+        a  = rn.ANGLE
+        b  = rn.BIAS
+        d  = rn.DUT
+        af = rn.ALIGNFILE 
+        tbruns.append( int(r) )
+        if method == 'survey':
+            rn.createAlignFile()
+        alfs[int(r)] = af
+
+    if tbruns[0] < 2000:
+        m = 'July2014'
+    elif tbruns[0] < 3000:
+        m = 'Oct2014'
+    elif tbruns[0] < 4000:
+        m = 'Nov2014'
+    else:
+        m = 'Dec2014'
+    tbds     = TbDataset( m, tbruns )
+    tbds.AlignmentFiles = alfs
+
+
+    SPLITTER = tbds
+    j        = Job(application = kepler)
+    j.backend     = BACKEND
+    j.splitter    = SPLITTER
+    j.outputfiles = ['*.dat']
+
+    j.submit()
diff --git a/Kepler/options/TbTrackingWithKalman.cpp b/Kepler/options/TbTrackingWithKalman.cpp
new file mode 100644
index 0000000..9ec4850
--- /dev/null
+++ b/Kepler/options/TbTrackingWithKalman.cpp
@@ -0,0 +1,548 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiKernel/AlgFactory.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+
+// ROOT
+#include "TMath.h"
+
+#include <iostream>
+#include <math.h>
+
+// Local
+#include "TbTracking.h"
+#include <algorithm>
+
+DECLARE_ALGORITHM_FACTORY(TbTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTracking::TbTracking(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_tracks(NULL),
+      m_trackFit(NULL),
+      m_clusterFinder(NULL) {
+
+  lowR = -0.2;
+  highR = 0.2;
+  binsR = 500;
+  
+  lowS = -0.02;
+  highS = 0.02;
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("Monitoring", m_monitoring = false);
+  declareProperty("HitError2", m_hiterror2 = 1.6e-5);
+  declareProperty("Scat2", m_scat2 = 1.2e-8);
+  declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
+  declareProperty("MinNClusters", m_MinNClusters = 7);
+  declareProperty("SearchRadius", m_vol_radius = 1 * Gaudi::Units::mm);
+  declareProperty("SearchRadiusY", m_vol_radiusY = 1 * Gaudi::Units::mm);
+  declareProperty("MaxChi2", m_ChiSqRedCut = 20000.);
+  declareProperty("SearchVolume", m_search_3vol = "diabolo");
+  declareProperty("VolumeAngle", m_vol_theta = 0.015);
+  declareProperty("VolumeAngleY", m_vol_thetaY = 0.005);
+  declareProperty("SearchVolumeFillAlgorithm",
+                  m_ClusterFinderSearchAlgorithm = "adap_seq");
+  declareProperty("nComboCut", m_nComboCut = 300);
+  declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTracking::~TbTracking() {
+
+  if (m_clusterFinder) delete m_clusterFinder;
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTracking::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  // Set up the cluster finder.
+  m_clusterFinder =
+      new TbClusterFinder(m_ClusterFinderSearchAlgorithm, m_nPlanes);
+  
+  // setup Kalman histos
+  setup_hists();
+  
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTracking::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      error() << "No clusters in " << clusterLocation << endmsg;
+      return StatusCode::FAILURE;
+    }
+    // Store the cluster iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+  }
+  
+  // Clear Kalman track container
+  ktracks_vec.clear();
+
+
+  // Create a track container and transfer its ownership to the TES.
+  m_tracks = new LHCb::TbTracks();
+  put(m_tracks, LHCb::TbTrackLocation::Default);
+
+  // Do the tracking and time order.
+  performTracking();
+  timeOrderTracks();
+
+  // fill the histos with the Kalman fit results
+  fill_khists(ktracks_vec);
+
+  counter("NumberOfTracks") += m_tracks->size();
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Actual tracking
+//=============================================================================
+void TbTracking::performTracking() {
+  // The working of this algorithm is similar to the cluster maker, such that:
+  // - Loop over some set of seed clusters (those on the m_SeedPlanes).
+  // - Create a container (TbTrackVolume) centered on each seed cluster
+  // (in space and time).
+  // - Impose the condition that any formed track must contain this seed.
+  // - Evaluate that 4-volume, to see if it contained a track.
+  // - If a choice (e.g. more than one possible combination of clusters),
+  // take the best fitting. Priority is given to more complete tracks.
+  // - If another track happened to be in the 4volume, but not
+  //   containing this seed, then it will be found later.
+
+  // Iterate over planes in the specified order.
+  for (const auto& plane : m_PlaneSearchOrder) {
+    // Iterate over this planes' clusters - first check for any.
+    if (masked(plane) || m_clusterFinder->empty(plane)) continue;
+    auto ic = m_clusterFinder->first(plane);
+    const auto end = m_clusterFinder->end(plane);
+    for (; ic != end; ++ic) {
+
+      // Check if the seed has already been used.
+      if ((*ic)->tracked()) continue;
+      // Form the TbTrackVolume container, and fill with clusters that fall
+      // in its space-time volume.
+      TbTrackVolume* track_volume =
+          new TbTrackVolume((*ic), m_search_3vol, m_nPlanes, m_twindow,
+                            m_vol_radius, m_vol_radiusY, m_vol_theta,
+                            m_vol_thetaY, m_MinNClusters);
+      fillATrackVolume(track_volume);
+
+      // Look for a track - automatically keeps if suitable.
+      evaluateTrackVolume(track_volume);
+      // PoorMansEvaluation(track_volume); // Alternative evaluator.
+
+      delete track_volume;
+    }
+  }
+}
+
+//=============================================================================
+// Fill 4volume.
+//=============================================================================
+void TbTracking::fillATrackVolume(TbTrackVolume* track_volume) {
+  // Fills the given TbTrackVolume (that has a particular space-time volume)
+  // with clusters from all planes (ie m_clusters) that fall in this space-time
+  // volume.
+
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    // Check for any clusters, or track contains seed condition.
+    if (m_clusterFinder->empty(iplane) ||
+        iplane == track_volume->seed()->plane() || masked(iplane))
+      continue;
+
+    // Create an iterator and find the appropriate cluster on the ith plane
+    // whose TOA is at the start of this TbTrackVolumes' time window.
+    auto ic = m_clusterFinder->getIterator(track_volume->t_lower(), iplane);
+    const auto end = m_clusterFinder->end(iplane);
+    // Loop until the TOA reaches the end of this TbTrackVolumes' time window.
+    // (dummy end condition used in the for loop).
+    for (; ic != end; ++ic) {
+      // Add cluster if inside and not already tracked.
+      track_volume->consider_cluster((*ic));
+      // Stop if too far ahead in time.
+      if ((*ic)->htime() > track_volume->t_upper()) break;
+    }
+  }
+}
+
+//=============================================================================
+// Finding the best tracks
+//=============================================================================
+void TbTracking::evaluateTrackVolume(TbTrackVolume* track_volume) {
+  // CURRENTLY, finds the most likely track containing either clusters on all
+  // planes,
+  // or tracks with one cluster missing.
+
+  // Declare some variables to be used.
+  LHCb::TbTrack* best_track = NULL;
+  double best_chi_dof = -1;  // Something unphysical.
+
+  // Get the number of combinations to check (depends on the size of the track
+  // to be formed).
+  int ncombos = track_volume->nCombos();
+
+  track_volume->ResetComboCounters();
+  // Do the search over this number of combinations - the TbTrackVolume has
+  // methods
+  // to retrive a particular combination of clusters forming a track (specified
+  // by icombo).
+  for (int icombo = 0; icombo < ncombos && icombo < m_nComboCut; icombo++) {
+
+    // Get the icombo'th track and fit.
+    LHCb::TbTrack* trial_track = track_volume->get_track_combo();
+    // Sort the clusters by z-position.
+    SmartRefVector<LHCb::TbCluster>& clusters =
+      const_cast<SmartRefVector<LHCb::TbCluster>&>(trial_track->clusters());
+    std::sort(clusters.begin(), clusters.end(),
+              TbFunctors::LessByZ<const LHCb::TbCluster*>());
+    m_trackFit->fit(trial_track);
+
+    // Evaluate this track.
+    const double chi2_per_dof = trial_track->chi2PerNdof();
+
+    // First combination tried case.
+    if (icombo == 0) {
+      best_chi_dof = chi2_per_dof;
+      best_track = trial_track;
+      track_volume->update_best();  // TbTrackVolumes keep a record of the best
+      // fitting combination of clusters internally.
+    } else if (chi2_per_dof < best_chi_dof) {
+      // Case of better combination.
+      delete best_track;
+      best_chi_dof = chi2_per_dof;
+      best_track = trial_track;
+      track_volume->update_best();
+    } else
+      delete trial_track;
+    // Prepare for next combination.
+    track_volume->increment_combo_counters();
+  }
+
+  if (best_track) {
+    // At this point, found the best fitting track in the volume. Apply chi cut,
+    // and save.
+    if (best_chi_dof < m_ChiSqRedCut) {
+
+      SmartRefVector<LHCb::TbCluster>& clusters =
+        const_cast<SmartRefVector<LHCb::TbCluster>&>(best_track->clusters());
+      auto earliest_hit = std::min_element(clusters.begin(), clusters.end(),
+              TbFunctors::LessByTime<const LHCb::TbCluster*>());
+
+      if( timingSvc()->beforeOverlap( (*earliest_hit)->time() ) ){
+
+        track_volume->set_tracked_clusters();
+        m_tracks->insert(best_track);
+        
+        // =========================== Kalman code =======================================
+        // create a fit track object (which is actually also a TbTrack)
+        LHCb::TbKalmanTrack* ktrack = new LHCb::TbKalmanTrack(*best_track, m_hiterror2, m_scat2) ;
+        // fit it
+        ktrack->fit() ;
+        // store the ktrack in the track vector
+        ktracks_vec.push_back(ktrack);
+        // ===============================================================================
+        
+        best_track->setTime(timingSvc()->localToGlobal(best_track->htime()));
+        if (m_monitoring) {
+          plot(track_volume->nCombos(), "nComboDist_of_TrackVolumes",
+               "nComboDist_of_TrackVolumes", 0., 1100., 1100);
+          plot(track_volume->nclusters(), "nCluster_in_TrackVolumes",
+               "nCluster_in_TrackVolumes", 0., 100., 100);
+        }
+      } 
+      else{
+  //      info() << "Earliest track time is within overlap, deleting" << endmsg;
+ //       info() << *best_track << endmsg;
+        delete best_track;
+      }
+     }
+     else delete best_track;
+  }
+}
+
+//=============================================================================
+/// Poor mans tracker (useful for testing). - only finds complete tracks.
+//=============================================================================
+void TbTracking::poorMansEvaluation(TbTrackVolume* track_volume) {
+  // Only accept tracks with at least one cluster on each plane.
+  bool one_per_plane = true;  // Assumed, now checked.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    if (track_volume->m_clusters[i].size() == 0) {
+      one_per_plane = false;
+      break;
+    }
+  }
+
+  if (one_per_plane) {
+    double t = 0.0;
+    // We have a track!
+    LHCb::TbTrack* track = new LHCb::TbTrack();
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      LHCb::TbCluster* c = track_volume->nearest_cluster(i);
+      t += c->htime();
+      c->setAssociated(true);
+      track->addToClusters(c);
+    }
+    t /= (double)m_nPlanes;
+    m_trackFit->fit(track);
+    m_tracks->insert(track);
+    track->setTime(timingSvc()->localToGlobal(t));
+  }
+}
+
+//=============================================================================
+// Track time ordering - honeycomb
+//=============================================================================
+void TbTracking::timeOrderTracks() {
+
+  const double s_factor = 1.3;
+  LHCb::TbTrack* track1;
+  LHCb::TbTrack* track2;
+  unsigned int gap = m_tracks->size() / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    LHCb::TbTracks::iterator itt;
+    for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
+      track1 = *itt;
+      track2 = *(itt + gap);
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        std::iter_swap(itt, itt + gap);
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Fill Histograms for TbKalmanTracks
+//=============================================================================
+void TbTracking::fill_khists(std::vector<LHCb::TbKalmanTrack*>& ktracks) {
+  
+  std::vector<LHCb::TbKalmanTrack*>::iterator icktra;
+  for (icktra = ktracks.begin(); icktra != ktracks.end(); icktra++) {
+    
+    // Fill the track histos
+    m_Kfit_chi2->Fill((*icktra)->chi2());
+    m_Kfit_prob->Fill( TMath::Prob((*icktra)->chi2(), (*icktra)->ndof()) );
+    
+    // Get the nodes of this TbKalmanTrack
+    //const std::vector<LHCb::TbKalmanNode*>& knodes = (*icktra)->nodes();
+    
+    // Loop through the nodes of this TbKalmanTrack
+    for( auto node : (*icktra)->nodes() ) {
+      auto pixnode = dynamic_cast< LHCb::TbKalmanPixelMeasurement*>( node) ;
+      if( pixnode ) {
+        int ichip = pixnode->cluster().plane();
+        
+        // Fill unbiased residuals
+        m_XunresKfit[ichip]->Fill( pixnode->residualX() * pixnode->covX() / pixnode->residualCovX() );
+        m_YunresKfit[ichip]->Fill( pixnode->residualY() * pixnode->covY() / pixnode->residualCovY() );
+        
+        // Fill biased residuals
+        m_XresKfit[ichip]->Fill( pixnode->residualX() );
+        m_YresKfit[ichip]->Fill( pixnode->residualY() );
+        
+        // Fill biased residuals on X,Y
+        m_XresKfitOnX[ichip]->Fill( pixnode->cluster().x() , pixnode->residualX() );
+        m_XresKfitOnY[ichip]->Fill( pixnode->cluster().y(),  pixnode->residualX() );
+        
+        m_YresKfitOnY[ichip]->Fill( pixnode->cluster().y() , pixnode->residualY() );
+        m_YresKfitOnX[ichip]->Fill( pixnode->cluster().x(),  pixnode->residualY() );
+        
+        // Fill biased residuals on X,Y slopes
+        m_XresKfitOnTX[ichip]->Fill( pixnode->state().tx()  , pixnode->residualX() );
+        m_XresKfitOnTY[ichip]->Fill( pixnode->state().ty() ,  pixnode->residualX() );
+        
+        m_YresKfitOnTY[ichip]->Fill( pixnode->state().ty()  , pixnode->residualY() );
+        m_YresKfitOnTX[ichip]->Fill( pixnode->state().tx() ,  pixnode->residualY() );
+        
+        
+        // Fill residual errors
+        m_XreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovX()) );
+        m_YreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovY()) );
+        
+        // Fill residual pulls
+        m_XrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
+        m_YrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
+        
+        // Fill chi2 quality histos :
+        // take the chi2 of the track..
+        LHCb::ChiSquare chi2 ( (*icktra)->chi2(), (*icktra)->ndof() ) ;
+        // we should add a proper function to KalmanTrack, or store it
+        
+        // ..now calculate and subtract the chi2 of this hit: should become a function of node as well
+        double resX = pixnode->residualX() ;
+        double resY = pixnode->residualY() ;
+        int nd = 2 * (  (*icktra)->nodes().size()  -1 ) - 4;
+        LHCb::ChiSquare chi2hit  ( resX*resX / pixnode->residualCovX() + resY*resY / pixnode->residualCovY() , nd );
+        chi2 -= chi2hit;
+        // apply quality check
+        if (chi2.chi2()/chi2.nDoF()<4) {
+          // Fill quality biased residuals for this hit
+          m_qXresKfit[ichip]->Fill( pixnode->residualX() );
+          m_qYresKfit[ichip]->Fill( pixnode->residualY() );
+          
+          // Fill quality residual pulls for this hit
+          m_qXrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
+          m_qYrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
+        }
+        
+      } // end of node check
+    } // end of node loop
+  }  // end of Ktrack loop
+}
+
+
+//=============================================================================
+/// Setup Histograms
+//=============================================================================
+void TbTracking::setup_hists() {
+  
+  // TbKalmanTrack parameters plots
+  m_Kfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
+          book1D("KalmanFit/chi2", "Chi2", -0.5, 49.5, 100));
+  
+  m_Kfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
+          book1D("KalmanFit/probability", "Chi2 prob of K fit", 0.0, 1.0, 100));
+  
+    
+  // Kalman fit plots
+  std::string hist_name;
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    std::stringstream ss_chip;
+    ss_chip << i;
+    
+    
+    hist_name = "KalmanFit/UnbiasedResidualsX/plane_" + ss_chip.str();
+    m_XunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    
+    hist_name = "KalmanFit/UnbiasedResidualsY/plane_" + ss_chip.str();
+    m_YunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    //
+    
+    hist_name = "KalmanFit/BiasedResidualsX/plane_" + ss_chip.str();
+    m_XresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/BiasedResidualsY/plane_" + ss_chip.str();
+    m_YresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    //
+    
+    hist_name = "KalmanFit/ResidualsX_on_X/plane_" + ss_chip.str();
+    m_XresKfitOnX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsX_on_Y/plane_" + ss_chip.str();
+    m_XresKfitOnY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    
+    
+    hist_name = "KalmanFit/ResidualsY_on_Y/plane_" + ss_chip.str();
+    m_YresKfitOnY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsY_on_X/plane_" + ss_chip.str();
+    m_YresKfitOnX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), -20., 20., 200, lowR, highR, binsR)));
+    //
+    
+    hist_name = "KalmanFit/ResidualsX_on_slopeX/plane_" + ss_chip.str();
+    m_XresKfitOnTX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsX_on_slopeY/plane_" + ss_chip.str();
+    m_XresKfitOnTY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    
+    hist_name = "KalmanFit/ResidualsY_on_slopeY/plane_" + ss_chip.str();
+    m_YresKfitOnTY.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/ResidualsY_on_slopeX/plane_" + ss_chip.str();
+    m_YresKfitOnTX.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book2D(hist_name.c_str(), hist_name.c_str(), lowS, highS, binsR, lowR, highR, binsR)));
+    
+    //
+    
+    hist_name = "KalmanFit/Residual_errors_on_X/plane_" + ss_chip.str();
+    m_XreserrKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/Residual_errors_on_Y/plane_" + ss_chip.str();
+    m_YreserrKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_X/plane_" + ss_chip.str();
+    m_XrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_Y/plane_" + ss_chip.str();
+    m_YrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    //
+    
+    hist_name = "KalmanFit/BiasedResidualsX_after_chi2_cut/plane_" + ss_chip.str();
+    m_qXresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    hist_name = "KalmanFit/BiasedResidualsY_after_chi2_cut/plane_" + ss_chip.str();
+    m_qYresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), lowR, highR, binsR)));
+    
+    //
+    
+    hist_name = "KalmanFit/ResidualPull_on_X_after_chi2_cut/plane_" + ss_chip.str();
+    m_qXrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_Y_after_chi2_cut/plane_" + ss_chip.str();
+    m_qYrespullKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+            book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+  }
+}
+
diff --git a/Kepler/options/TbTrackingWithKalman.h b/Kepler/options/TbTrackingWithKalman.h
new file mode 100644
index 0000000..0e334de
--- /dev/null
+++ b/Kepler/options/TbTrackingWithKalman.h
@@ -0,0 +1,146 @@
+#ifndef TB_TRACKING_H
+#define TB_TRACKING_H 1
+
+// Root
+#include "TH1.h"
+#include "TH2.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+// Kalman classes in TbEvent
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanNode.h"
+#include "Event/TbKalmanPixelMeasurement.h"
+
+// Local
+#include "TbClusterFinder.h"
+#include "TbTrackVolume.h"
+
+/** @class TbTracking TbTracking.h
+ *
+ *  Algorithm for track reconstruction in Timepix3 telescope
+ *
+ * @author Dan Saunders
+ */
+
+class TbTracking : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbTracking();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// Track container (to be filled).
+  LHCb::TbTracks *m_tracks;
+
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+  /// Tool to find particular clusters.
+  TbClusterFinder *m_clusterFinder;
+
+  // Tracking specific options.
+  /// TES location of cluster containers.
+  std::string m_clusterLocation;
+  /// Flag to fill (or not) monitoring histograms.
+  bool m_monitoring;
+  /// Time width (in ns) of TbTrackVolumes.
+  double m_twindow;
+  /// Minimum number of clusters to form a track.
+  unsigned int m_MinNClusters;
+  /// Spatial shapes of TbTrackVolumes {cylinder, diabolo}.
+  std::string m_search_3vol;
+  /// Spatial shape parameter.
+  double m_vol_radius;
+  double m_vol_radiusY;
+  /// Spatial shape parameter.
+  double m_vol_theta;
+  double m_vol_thetaY;
+  /// Chi2 cut.
+  double m_ChiSqRedCut;
+  /// Upper cut on the number of cominations to try in a TbTrackVolume.
+  /// Useful for speed, and rarely used; set O(100).
+  int m_nComboCut;
+  /// Search algorithm used to fill TbTrackVolumes - {"seq", "adap_seq"}.
+  /// "adap_seq" recommeneded.
+  std::string m_ClusterFinderSearchAlgorithm;
+
+  /// For certain volumes, it's advantageous to use seeds from the center of
+  /// the telescope, so the order of the search can be specified here.
+  std::vector<unsigned int> m_PlaneSearchOrder;
+
+  void performTracking();
+  void fillATrackVolume(TbTrackVolume *);
+  void evaluateTrackVolume(TbTrackVolume *);
+  void timeOrderTracks();
+  void poorMansEvaluation(TbTrackVolume *);
+  
+  // Errors for Kalman fit
+  double  m_hiterror2;
+  double  m_scat2;
+  
+  // Histo functions
+  void setup_hists();
+  void fill_khists(std::vector<LHCb::TbKalmanTrack*>&);
+  
+  float lowR, highR, binsR, lowS, highS;
+  
+  
+  // Kalman filter histos
+  //---------------------------------------------------
+  
+  // Track parameters
+  TH1D* m_Kfit_chi2;
+  TH1D* m_Kfit_prob;
+  
+  // unbiased residuals
+  std::vector<TH1D*> m_XunresKfit;
+  std::vector<TH1D*> m_YunresKfit;
+  // biased residuals
+  std::vector<TH1D*> m_XresKfit;
+  std::vector<TH1D*> m_YresKfit;
+  // biased residuals on X,Y
+  std::vector<TH2D*> m_XresKfitOnX;
+  std::vector<TH2D*> m_XresKfitOnY;
+  
+  std::vector<TH2D*> m_YresKfitOnY;
+  std::vector<TH2D*> m_YresKfitOnX;
+  
+  // biased residuals on X,Y slopes
+  std::vector<TH2D*> m_XresKfitOnTX;
+  std::vector<TH2D*> m_XresKfitOnTY;
+  
+  std::vector<TH2D*> m_YresKfitOnTY;
+  std::vector<TH2D*> m_YresKfitOnTX;
+  
+  // biased residuals errors
+  std::vector<TH1D*> m_XreserrKfit;
+  std::vector<TH1D*> m_YreserrKfit;
+  
+  // residual pulls
+  std::vector<TH1D*> m_XrespullKfit;
+  std::vector<TH1D*> m_YrespullKfit;
+  
+  // quality biased residuals
+  std::vector<TH1D*> m_qXresKfit;
+  std::vector<TH1D*> m_qYresKfit;
+  
+  // quality residual pulls
+  std::vector<TH1D*> m_qXrespullKfit;
+  std::vector<TH1D*> m_qYrespullKfit;
+  
+  
+  // TbKalmanTrack container
+  std::vector<LHCb::TbKalmanTrack*> ktracks_vec;
+  //---------------------------------------------------
+  
+};
+#endif
diff --git a/Kepler/options/alignment/.svn/all-wcprops b/Kepler/options/alignment/.svn/all-wcprops
new file mode 100644
index 0000000..f6e8cdb
--- /dev/null
+++ b/Kepler/options/alignment/.svn/all-wcprops
@@ -0,0 +1,41 @@
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/188051/Kepler/trunk/Tb/Kepler/options/alignment
+END
+dut.py
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/alignment/dut.py
+END
+survey.py
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/alignment/survey.py
+END
+alignment.sh
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/alignment/alignment.sh
+END
+millepede.py
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/188051/Kepler/trunk/Tb/Kepler/options/alignment/millepede.py
+END
+minuit_alignment.py
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/alignment/minuit_alignment.py
+END
+minuit_alignment.sh
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/Kepler/options/alignment/minuit_alignment.sh
+END
diff --git a/Kepler/options/alignment/.svn/entries b/Kepler/options/alignment/.svn/entries
new file mode 100644
index 0000000..bb97ac1
--- /dev/null
+++ b/Kepler/options/alignment/.svn/entries
@@ -0,0 +1,232 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/alignment
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-12T10:54:52.097095Z
+188051
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+dut.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+8768e912c7ac5fa6a7a3a632ee922308
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+266
+
+survey.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+4f81c8fc6792116d3edd656a07994b6e
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+614
+
+alignment.sh
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+8f806925e826b02845d00328cc5c9bc4
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+538
+
+millepede.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+7824d30c9f8716b389852e3ff78a49a3
+2015-05-12T10:54:52.097095Z
+188051
+chombach
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1049
+
+minuit_alignment.py
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+0238d2f186269a4823bea0739132df6e
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+807
+
+minuit_alignment.sh
+file
+
+
+
+
+2016-05-09T14:27:49.000000Z
+fb9e2fc212ca820209ce085411324d6e
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1940
+
diff --git a/Kepler/options/alignment/.svn/prop-base/alignment.sh.svn-base b/Kepler/options/alignment/.svn/prop-base/alignment.sh.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/options/alignment/.svn/prop-base/alignment.sh.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/options/alignment/.svn/prop-base/minuit_alignment.sh.svn-base b/Kepler/options/alignment/.svn/prop-base/minuit_alignment.sh.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/options/alignment/.svn/prop-base/minuit_alignment.sh.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/options/alignment/.svn/text-base/alignment.sh.svn-base b/Kepler/options/alignment/.svn/text-base/alignment.sh.svn-base
new file mode 100644
index 0000000..00e5c6b
--- /dev/null
+++ b/Kepler/options/alignment/.svn/text-base/alignment.sh.svn-base
@@ -0,0 +1,9 @@
+#!/bin/bash 
+
+gaudirun.py example.py survey.py --option="from Configurables import Kepler" --option="Kepler().AlignmentFile=\"Alignment_old.dat\""
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py millepede.py --option="from Configurables import TbAlignment" --option="TbAlignment().DoFs = [1,1,0,0,0,1]"
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py millepede.py
+cp Alignment_out.dat Alignment.dat 
+gaudirun.py example.py alignment.py --option="from Configurables import Kepler" --option="Kepler().Alignment = False"
diff --git a/Kepler/options/alignment/.svn/text-base/dut.py.svn-base b/Kepler/options/alignment/.svn/text-base/dut.py.svn-base
new file mode 100644
index 0000000..713a52b
--- /dev/null
+++ b/Kepler/options/alignment/.svn/text-base/dut.py.svn-base
@@ -0,0 +1,10 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+Kepler().Alignment = True
+
+from Configurables import TbAlignment
+TbAlignment().AlignmentTechnique = "3"
+TbAlignment().DeviceToAlign = 4
+# TbAlignment().DoFs = [True, True, True, True, True, True]
+ 
diff --git a/Kepler/options/alignment/.svn/text-base/millepede.py.svn-base b/Kepler/options/alignment/.svn/text-base/millepede.py.svn-base
new file mode 100644
index 0000000..43a08e7
--- /dev/null
+++ b/Kepler/options/alignment/.svn/text-base/millepede.py.svn-base
@@ -0,0 +1,38 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+# Add TbAlignment to the Telescope sequence.
+Kepler().Alignment = True
+
+#chombach modifications
+
+
+
+from Configurables import TbEventBuilder
+# Skip noise events.
+TbEventBuilder().MinPlanesWithHits = 5
+
+
+# List of devices under test
+duts = [4] 
+
+from Configurables import TbTracking
+# Exclude DUTs from the pattern recognition.
+TbTracking().MaskedPlanes = duts
+# Require clusters on all telescope planes.
+TbTracking().MinNClusters = 8 
+
+from Configurables import TbAlignment
+TbAlignment().AlignmentTechnique = "Millepede"
+# Set the number of tracks to process.
+TbAlignment().NTracks = 10000
+# Set the reference plane (fixed position).
+TbAlignment().ReferencePlane = 3
+# Set the degrees of freedom (x, y, z, rx, ry, rz).
+TbAlignment().DoFs = [0, 0, 1, 0, 0, 0]
+TbAlignment().ParametersResidualsXY = ("", -0.2, 0.2, 100)
+TbAlignment().MaskedPlanes = duts 
+TbAlignment().PrintConfiguration = True
+TbAlignment().ResCutInit = 1.3
+TbAlignment().ResCut = 0.06
+TbAlignment().NIterations = 6
diff --git a/Kepler/options/alignment/.svn/text-base/minuit_alignment.py.svn-base b/Kepler/options/alignment/.svn/text-base/minuit_alignment.py.svn-base
new file mode 100644
index 0000000..824f1d8
--- /dev/null
+++ b/Kepler/options/alignment/.svn/text-base/minuit_alignment.py.svn-base
@@ -0,0 +1,20 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+Kepler().InputFiles      = ["eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run1062/"]
+Kepler().PixelConfigFile = "eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1062/Conditions/PixelMask.dat"
+Kepler().EvtMax          = 100
+Kepler().WriteTuples     = False
+Kepler().Monitoring      = False
+Kepler().Alignment       = True
+Kepler().AlignmentFile   = "Alignment.dat"
+
+from Configurables import TbTrackPlots
+TbTrackPlots().ParametersResidualsXY = ("",-0.1,0.1,2000)
+
+from Configurables import TbAlignment, TbTracking
+TbAlignment().PrintConfiguration = True
+TbAlignment().FitStrategy        = 1
+TbAlignment().ReferencePlane     = 3 
+TbAlignment().MaskedPlanes       = TbTracking().MaskedPlanes
+TbAlignment().OutputLevel        = INFO
diff --git a/Kepler/options/alignment/.svn/text-base/minuit_alignment.sh.svn-base b/Kepler/options/alignment/.svn/text-base/minuit_alignment.sh.svn-base
new file mode 100644
index 0000000..88e4043
--- /dev/null
+++ b/Kepler/options/alignment/.svn/text-base/minuit_alignment.sh.svn-base
@@ -0,0 +1,34 @@
+#!/bin/bash 
+
+RUNNUMBER=$1
+
+cp Alignment.dat Alignment_old.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler, TbAlignment" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="TbAlignment().AlignmentTechnique = \"Method1\"" 
+
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler, TbAlignment" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="TbAlignment().AlignmentTechnique = \"Method0\"" 
+
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler, TbAlignment" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="TbAlignment().AlignmentTechnique = \"Method0\"" --option="TbAlignment().FitStrategy = 2"
+
+cp Alignment_out.dat Alignment_$RUNNUMBER.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="Kepler().Alignment = False" \
+   --option="Kepler().Monitoring = True"
+mv Kepler-histos.root Kepler-histos_$RUNNUMBER.root
+
diff --git a/Kepler/options/alignment/.svn/text-base/survey.py.svn-base b/Kepler/options/alignment/.svn/text-base/survey.py.svn-base
new file mode 100644
index 0000000..d0367df
--- /dev/null
+++ b/Kepler/options/alignment/.svn/text-base/survey.py.svn-base
@@ -0,0 +1,21 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+# Add TbAlignment to the Telescope sequence.
+Kepler().Alignment = True
+# Set the number of events to process.
+Kepler().EvtMax = 100 
+
+from Configurables import TbEventBuilder
+# Skip noise events.
+TbEventBuilder().MinPlanesWithHits = 5
+
+from Configurables import TbClusterPlots
+# Set the reference plane.
+TbClusterPlots().ReferencePlane = 3 
+# Widen the range of the difference histograms if needed.
+TbClusterPlots().ParametersDifferenceXY = ('', -10., 10., 200)
+
+from Configurables import TbAlignment
+TbAlignment().AlignmentTechnique = "survey"
+
diff --git a/Kepler/options/alignment/alignment.sh b/Kepler/options/alignment/alignment.sh
new file mode 100755
index 0000000..00e5c6b
--- /dev/null
+++ b/Kepler/options/alignment/alignment.sh
@@ -0,0 +1,9 @@
+#!/bin/bash 
+
+gaudirun.py example.py survey.py --option="from Configurables import Kepler" --option="Kepler().AlignmentFile=\"Alignment_old.dat\""
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py millepede.py --option="from Configurables import TbAlignment" --option="TbAlignment().DoFs = [1,1,0,0,0,1]"
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py millepede.py
+cp Alignment_out.dat Alignment.dat 
+gaudirun.py example.py alignment.py --option="from Configurables import Kepler" --option="Kepler().Alignment = False"
diff --git a/Kepler/options/alignment/dut.py b/Kepler/options/alignment/dut.py
new file mode 100644
index 0000000..713a52b
--- /dev/null
+++ b/Kepler/options/alignment/dut.py
@@ -0,0 +1,10 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+Kepler().Alignment = True
+
+from Configurables import TbAlignment
+TbAlignment().AlignmentTechnique = "3"
+TbAlignment().DeviceToAlign = 4
+# TbAlignment().DoFs = [True, True, True, True, True, True]
+ 
diff --git a/Kepler/options/alignment/millepede.py b/Kepler/options/alignment/millepede.py
new file mode 100644
index 0000000..43a08e7
--- /dev/null
+++ b/Kepler/options/alignment/millepede.py
@@ -0,0 +1,38 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+# Add TbAlignment to the Telescope sequence.
+Kepler().Alignment = True
+
+#chombach modifications
+
+
+
+from Configurables import TbEventBuilder
+# Skip noise events.
+TbEventBuilder().MinPlanesWithHits = 5
+
+
+# List of devices under test
+duts = [4] 
+
+from Configurables import TbTracking
+# Exclude DUTs from the pattern recognition.
+TbTracking().MaskedPlanes = duts
+# Require clusters on all telescope planes.
+TbTracking().MinNClusters = 8 
+
+from Configurables import TbAlignment
+TbAlignment().AlignmentTechnique = "Millepede"
+# Set the number of tracks to process.
+TbAlignment().NTracks = 10000
+# Set the reference plane (fixed position).
+TbAlignment().ReferencePlane = 3
+# Set the degrees of freedom (x, y, z, rx, ry, rz).
+TbAlignment().DoFs = [0, 0, 1, 0, 0, 0]
+TbAlignment().ParametersResidualsXY = ("", -0.2, 0.2, 100)
+TbAlignment().MaskedPlanes = duts 
+TbAlignment().PrintConfiguration = True
+TbAlignment().ResCutInit = 1.3
+TbAlignment().ResCut = 0.06
+TbAlignment().NIterations = 6
diff --git a/Kepler/options/alignment/minuit_alignment.py b/Kepler/options/alignment/minuit_alignment.py
new file mode 100644
index 0000000..824f1d8
--- /dev/null
+++ b/Kepler/options/alignment/minuit_alignment.py
@@ -0,0 +1,20 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+Kepler().InputFiles      = ["eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run1062/"]
+Kepler().PixelConfigFile = "eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1062/Conditions/PixelMask.dat"
+Kepler().EvtMax          = 100
+Kepler().WriteTuples     = False
+Kepler().Monitoring      = False
+Kepler().Alignment       = True
+Kepler().AlignmentFile   = "Alignment.dat"
+
+from Configurables import TbTrackPlots
+TbTrackPlots().ParametersResidualsXY = ("",-0.1,0.1,2000)
+
+from Configurables import TbAlignment, TbTracking
+TbAlignment().PrintConfiguration = True
+TbAlignment().FitStrategy        = 1
+TbAlignment().ReferencePlane     = 3 
+TbAlignment().MaskedPlanes       = TbTracking().MaskedPlanes
+TbAlignment().OutputLevel        = INFO
diff --git a/Kepler/options/alignment/minuit_alignment.sh b/Kepler/options/alignment/minuit_alignment.sh
new file mode 100755
index 0000000..88e4043
--- /dev/null
+++ b/Kepler/options/alignment/minuit_alignment.sh
@@ -0,0 +1,34 @@
+#!/bin/bash 
+
+RUNNUMBER=$1
+
+cp Alignment.dat Alignment_old.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler, TbAlignment" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="TbAlignment().AlignmentTechnique = \"Method1\"" 
+
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler, TbAlignment" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="TbAlignment().AlignmentTechnique = \"Method0\"" 
+
+cp Alignment_out.dat Alignment.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler, TbAlignment" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="TbAlignment().AlignmentTechnique = \"Method0\"" --option="TbAlignment().FitStrategy = 2"
+
+cp Alignment_out.dat Alignment_$RUNNUMBER.dat
+gaudirun.py example.py minuit_alignment.py \
+   --option="from Configurables import Kepler" \
+   --option="Kepler().InputFiles	= [\"eos/lhcb/testbeam/velo/timepix3/July2014/RawData/Run$RUNNUMBER/\"]" \
+   --option="Kepler().PixelConfigFile = \"eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run$RUNNUMBER/Conditions/PixelMask.dat\"" \
+   --option="Kepler().Alignment = False" \
+   --option="Kepler().Monitoring = True"
+mv Kepler-histos.root Kepler-histos_$RUNNUMBER.root
+
diff --git a/Kepler/options/alignment/survey.py b/Kepler/options/alignment/survey.py
new file mode 100644
index 0000000..d0367df
--- /dev/null
+++ b/Kepler/options/alignment/survey.py
@@ -0,0 +1,21 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+# Add TbAlignment to the Telescope sequence.
+Kepler().Alignment = True
+# Set the number of events to process.
+Kepler().EvtMax = 100 
+
+from Configurables import TbEventBuilder
+# Skip noise events.
+TbEventBuilder().MinPlanesWithHits = 5
+
+from Configurables import TbClusterPlots
+# Set the reference plane.
+TbClusterPlots().ReferencePlane = 3 
+# Widen the range of the difference histograms if needed.
+TbClusterPlots().ParametersDifferenceXY = ('', -10., 10., 200)
+
+from Configurables import TbAlignment
+TbAlignment().AlignmentTechnique = "survey"
+
diff --git a/Kepler/options/batch.py b/Kepler/options/batch.py
new file mode 100644
index 0000000..e0f0760
--- /dev/null
+++ b/Kepler/options/batch.py
@@ -0,0 +1,23 @@
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+from Configurables import TbEventBuilder
+TbEventBuilder().MinPlanesWithHits = 2
+TbEventBuilder().PrintFreq = 100
+TbEventBuilder().Monitoring = True
+Kepler().EvtMax=5000
+
+Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Dec2014/RootFiles/Run4012/Conditions/Alignment4012.dat"
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+TbTracking().MinNClusters = 3
+
+TbTracking().SearchRadius = 0.5
+TbTracking().VolumeAngle = 0.2
+TbTracking().TimeWindow = 75
+TbTracking().Monitoring = False
+TbTracking().SearchPlanes = [2,3]
+TbTracking().MaskedPlanes = []
+
+from Configurables import TbTrackPlots
diff --git a/Kepler/options/combat/.svn/all-wcprops b/Kepler/options/combat/.svn/all-wcprops
new file mode 100644
index 0000000..b3b8bf9
--- /dev/null
+++ b/Kepler/options/combat/.svn/all-wcprops
@@ -0,0 +1,29 @@
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/combat
+END
+combatExample.py
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/Kepler/options/combat/combatExample.py
+END
+singleChipExample.py
+K 25
+svn:wc:ra_dav:version-url
+V 86
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/combat/singleChipExample.py
+END
+CombatAlignment.dat
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/Kepler/options/combat/CombatAlignment.dat
+END
+CombatAlignment.py
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/Kepler/options/combat/CombatAlignment.py
+END
diff --git a/Kepler/options/combat/.svn/entries b/Kepler/options/combat/.svn/entries
new file mode 100644
index 0000000..bc3a9bd
--- /dev/null
+++ b/Kepler/options/combat/.svn/entries
@@ -0,0 +1,164 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/combat
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+combatExample.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+b2ca0a57964d5a0bce8526c33848a2fb
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2387
+
+singleChipExample.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+3852d5610e7b0528ae1074fd16219511
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+983
+
+CombatAlignment.dat
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+8d8d31d71795971b9305d3859b510f8e
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+390
+
+CombatAlignment.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+06485f69479e75ae66a88321661f042a
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1272
+
diff --git a/Kepler/options/combat/.svn/text-base/CombatAlignment.dat.svn-base b/Kepler/options/combat/.svn/text-base/CombatAlignment.dat.svn-base
new file mode 100644
index 0000000..02b3011
--- /dev/null
+++ b/Kepler/options/combat/.svn/text-base/CombatAlignment.dat.svn-base
@@ -0,0 +1,8 @@
+Plane0     0    0     0       0     0     0
+Plane1     -0.2    -0.27     48.5      0     0     0
+Plane2     0.37    0.48     82    0     0     0
+Plane3     -0.26    0.11     117     0     0     0
+Plane4     0.0027    0     330       0     0     0
+Plane5     0.41    0     395      0     0     0
+Plane6     0.41    0     405     0     0     0
+Plane7     -0.25    0     462     0     0     0
diff --git a/Kepler/options/combat/.svn/text-base/CombatAlignment.py.svn-base b/Kepler/options/combat/.svn/text-base/CombatAlignment.py.svn-base
new file mode 100644
index 0000000..2453add
--- /dev/null
+++ b/Kepler/options/combat/.svn/text-base/CombatAlignment.py.svn-base
@@ -0,0 +1,35 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+Kepler().Alignment = True
+Kepler().EvtMax    = 30000
+
+from Configurables import TbAlignment
+TbAlignment().ReferencsvePlane = "Chip1"
+TbAlignment().DuT            = ""
+TbAlignment().AlignmentTechnique = "Millepede"
+TbAlignment().DoFs = [1,1,0,1,1,1]
+TbAlignment().ParametersResidualsXY= ("", -0.8, 0.8, 200)
+TbAlignment().MaskedPlanes = []
+TbAlignment().PrintConfiguration = True
+
+from Configurables import TbClusterPlots
+TbClusterPlots().ParametersDifferenceRot = ("",-.5,0.5,200)
+TbClusterPlots().ParametersDifferenceXY = ("",-7,7,200)
+TbClusterPlots().ParametersXY = ("",-1.,15,280)
+TbClusterPlots().ReferencePlane = 2
+TbClusterPlots().FillComparisonPlots = True
+
+from Configurables import TbTrackPlots, TbCombatBuilder, TbClustering, TbTracking
+TbTrackPlots().ParametersResidualsXY= ("", -0.8, 0.8, 200)
+seq = GaudiSequencer("Telescope")
+seq.Members = [TbCombatBuilder(), TbClustering(), TbTracking(), TbAlignment()]
+
+from Configurables import TbTracking
+TbTracking().MaskedPlanes = []
+
+def patch():
+     from Configurables import TbTrackPlots, TbCombatBuilder, TbClustering, TbTracking
+     seq.Members = [TbCombatBuilder(), TbClustering(), TbTracking(), TbAlignment()]
+
+appendPostConfigAction(patch)
\ No newline at end of file
diff --git a/Kepler/options/combat/.svn/text-base/combatExample.py.svn-base b/Kepler/options/combat/.svn/text-base/combatExample.py.svn-base
new file mode 100644
index 0000000..511055f
--- /dev/null
+++ b/Kepler/options/combat/.svn/text-base/combatExample.py.svn-base
@@ -0,0 +1,63 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py $KEPLERROOT/options/combatExample.py
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+
+# Set the path to the directory/files to be processed
+#Kepler().InputFiles = ["/afs/cern.ch/user/v/vifranco/cmtuser/KEPLER/KEPLER_HEAD/"]
+
+# Set the alignment file
+Kepler().AlignmentFile = "/afs/cern.ch/user/v/vifranco/public/CombatAlignment_2arms.dat"
+
+# Set the masked pixels file
+Kepler().PixelConfigFile = "Tb/Kepler/options/EmptyPixelMask.dat"
+
+# Set the number of events to run over 
+Kepler().EvtMax = 10000
+
+
+# Set the configuration of the individual algorithms
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+
+
+# Combat specific.
+
+#CombatInputFile 0 is for the lower arm and File1 for the higher File2 (if using one arm, use comat File0)
+#Keep the alignment file consistent, use the same number of planes everywhere, also change the number of arms.
+def combatRun():
+     from Configurables import TbCombatBuilder
+     TbCombatBuilder().CombatInputFile0 = "/afs/cern.ch/user/v/vifranco/public/Run31100003_SAMPLE.txt"
+     TbCombatBuilder().ReadoutFormat = "RelaxD"
+#     TbCombatBuilder().CombatInputFile1 = "/afs/cern.ch/user/v/vifranco/cmtuser/KEPLER/KEPLER_HEAD/240614_30V_TH500_100ms_merge.dat"
+
+     seq = GaudiSequencer("Telescope")
+     seq.Members = [TbCombatBuilder(), TbClustering(), TbTracking()]
+
+     TbCombatBuilder().PrintFreq = 5000
+     TbCombatBuilder().NumberArms = 2
+     
+     TbTracking().MinNClusters = 6
+     TbTracking().SearchRadius = 2
+     TbTracking().VolumeAngle = 0.0015
+     TbTracking().SearchPlanes = [3,5]
+     TbTracking().SearchVolume = "diabolo"
+     TbTracking().MaxChi2 = 2000000.
+     TbTracking().ViewerEventNum = 100
+     TbTracking().ViewerTimeLow = 0
+     TbTracking().ViewerTimeUp = 2000000
+     #TbTracking().ViewerOutput = True
+     TbTracking().CombatRun = True
+     
+     seq = GaudiSequencer("Monitoring")
+     from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+     seq.Members = [TbHitMonitor(), TbClusterPlots(),TbTrackPlots()]
+     TbTrackPlots().ParametersResidualsXY = ("", -1.0, 1.0, 200)
+     TbTrackPlots().ParametersXY = ("", -2, 16, 200)
+     TbClusterPlots().ParametersXY = ("", -2, 16, 200)
+
+appendPostConfigAction(combatRun)
diff --git a/Kepler/options/combat/.svn/text-base/singleChipExample.py.svn-base b/Kepler/options/combat/.svn/text-base/singleChipExample.py.svn-base
new file mode 100644
index 0000000..e167d83
--- /dev/null
+++ b/Kepler/options/combat/.svn/text-base/singleChipExample.py.svn-base
@@ -0,0 +1,31 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py singleChipExample.py
+
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+
+# Set the path to the directory/files to be processed
+Kepler().InputFiles = ["singleChipRun/"]
+# Set the alignment file
+Kepler().AlignmentFile = "singleAlignment.dat"
+# Set the masked pixels file
+Kepler().PixelConfigFile = "PixelMask.dat"
+# Set the number of events to run over 
+Kepler().EvtMax = 4300
+
+# Set the configuration of the individual algorithms
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+# Combat specific.
+def combatRun():
+     from Configurables import TbEventBuilder, TbClustering
+     seq = GaudiSequencer("Telescope")
+     seq.Members = [TbEventBuilder(), TbClustering()]
+     
+     seq = GaudiSequencer("Monitoring")
+     from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+     seq.Members = [TbHitMonitor(), TbClusterPlots()]
+
+appendPostConfigAction(combatRun)
diff --git a/Kepler/options/combat/CombatAlignment.dat b/Kepler/options/combat/CombatAlignment.dat
new file mode 100644
index 0000000..02b3011
--- /dev/null
+++ b/Kepler/options/combat/CombatAlignment.dat
@@ -0,0 +1,8 @@
+Plane0     0    0     0       0     0     0
+Plane1     -0.2    -0.27     48.5      0     0     0
+Plane2     0.37    0.48     82    0     0     0
+Plane3     -0.26    0.11     117     0     0     0
+Plane4     0.0027    0     330       0     0     0
+Plane5     0.41    0     395      0     0     0
+Plane6     0.41    0     405     0     0     0
+Plane7     -0.25    0     462     0     0     0
diff --git a/Kepler/options/combat/CombatAlignment.py b/Kepler/options/combat/CombatAlignment.py
new file mode 100644
index 0000000..2453add
--- /dev/null
+++ b/Kepler/options/combat/CombatAlignment.py
@@ -0,0 +1,35 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+Kepler().Alignment = True
+Kepler().EvtMax    = 30000
+
+from Configurables import TbAlignment
+TbAlignment().ReferencsvePlane = "Chip1"
+TbAlignment().DuT            = ""
+TbAlignment().AlignmentTechnique = "Millepede"
+TbAlignment().DoFs = [1,1,0,1,1,1]
+TbAlignment().ParametersResidualsXY= ("", -0.8, 0.8, 200)
+TbAlignment().MaskedPlanes = []
+TbAlignment().PrintConfiguration = True
+
+from Configurables import TbClusterPlots
+TbClusterPlots().ParametersDifferenceRot = ("",-.5,0.5,200)
+TbClusterPlots().ParametersDifferenceXY = ("",-7,7,200)
+TbClusterPlots().ParametersXY = ("",-1.,15,280)
+TbClusterPlots().ReferencePlane = 2
+TbClusterPlots().FillComparisonPlots = True
+
+from Configurables import TbTrackPlots, TbCombatBuilder, TbClustering, TbTracking
+TbTrackPlots().ParametersResidualsXY= ("", -0.8, 0.8, 200)
+seq = GaudiSequencer("Telescope")
+seq.Members = [TbCombatBuilder(), TbClustering(), TbTracking(), TbAlignment()]
+
+from Configurables import TbTracking
+TbTracking().MaskedPlanes = []
+
+def patch():
+     from Configurables import TbTrackPlots, TbCombatBuilder, TbClustering, TbTracking
+     seq.Members = [TbCombatBuilder(), TbClustering(), TbTracking(), TbAlignment()]
+
+appendPostConfigAction(patch)
\ No newline at end of file
diff --git a/Kepler/options/combat/combatExample.py b/Kepler/options/combat/combatExample.py
new file mode 100644
index 0000000..511055f
--- /dev/null
+++ b/Kepler/options/combat/combatExample.py
@@ -0,0 +1,63 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py $KEPLERROOT/options/combatExample.py
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+
+# Set the path to the directory/files to be processed
+#Kepler().InputFiles = ["/afs/cern.ch/user/v/vifranco/cmtuser/KEPLER/KEPLER_HEAD/"]
+
+# Set the alignment file
+Kepler().AlignmentFile = "/afs/cern.ch/user/v/vifranco/public/CombatAlignment_2arms.dat"
+
+# Set the masked pixels file
+Kepler().PixelConfigFile = "Tb/Kepler/options/EmptyPixelMask.dat"
+
+# Set the number of events to run over 
+Kepler().EvtMax = 10000
+
+
+# Set the configuration of the individual algorithms
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+
+
+# Combat specific.
+
+#CombatInputFile 0 is for the lower arm and File1 for the higher File2 (if using one arm, use comat File0)
+#Keep the alignment file consistent, use the same number of planes everywhere, also change the number of arms.
+def combatRun():
+     from Configurables import TbCombatBuilder
+     TbCombatBuilder().CombatInputFile0 = "/afs/cern.ch/user/v/vifranco/public/Run31100003_SAMPLE.txt"
+     TbCombatBuilder().ReadoutFormat = "RelaxD"
+#     TbCombatBuilder().CombatInputFile1 = "/afs/cern.ch/user/v/vifranco/cmtuser/KEPLER/KEPLER_HEAD/240614_30V_TH500_100ms_merge.dat"
+
+     seq = GaudiSequencer("Telescope")
+     seq.Members = [TbCombatBuilder(), TbClustering(), TbTracking()]
+
+     TbCombatBuilder().PrintFreq = 5000
+     TbCombatBuilder().NumberArms = 2
+     
+     TbTracking().MinNClusters = 6
+     TbTracking().SearchRadius = 2
+     TbTracking().VolumeAngle = 0.0015
+     TbTracking().SearchPlanes = [3,5]
+     TbTracking().SearchVolume = "diabolo"
+     TbTracking().MaxChi2 = 2000000.
+     TbTracking().ViewerEventNum = 100
+     TbTracking().ViewerTimeLow = 0
+     TbTracking().ViewerTimeUp = 2000000
+     #TbTracking().ViewerOutput = True
+     TbTracking().CombatRun = True
+     
+     seq = GaudiSequencer("Monitoring")
+     from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+     seq.Members = [TbHitMonitor(), TbClusterPlots(),TbTrackPlots()]
+     TbTrackPlots().ParametersResidualsXY = ("", -1.0, 1.0, 200)
+     TbTrackPlots().ParametersXY = ("", -2, 16, 200)
+     TbClusterPlots().ParametersXY = ("", -2, 16, 200)
+
+appendPostConfigAction(combatRun)
diff --git a/Kepler/options/combat/singleChipExample.py b/Kepler/options/combat/singleChipExample.py
new file mode 100644
index 0000000..e167d83
--- /dev/null
+++ b/Kepler/options/combat/singleChipExample.py
@@ -0,0 +1,31 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py singleChipExample.py
+
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+
+# Set the path to the directory/files to be processed
+Kepler().InputFiles = ["singleChipRun/"]
+# Set the alignment file
+Kepler().AlignmentFile = "singleAlignment.dat"
+# Set the masked pixels file
+Kepler().PixelConfigFile = "PixelMask.dat"
+# Set the number of events to run over 
+Kepler().EvtMax = 4300
+
+# Set the configuration of the individual algorithms
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+# Combat specific.
+def combatRun():
+     from Configurables import TbEventBuilder, TbClustering
+     seq = GaudiSequencer("Telescope")
+     seq.Members = [TbEventBuilder(), TbClustering()]
+     
+     seq = GaudiSequencer("Monitoring")
+     from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+     seq.Members = [TbHitMonitor(), TbClusterPlots()]
+
+appendPostConfigAction(combatRun)
diff --git a/Kepler/options/debug.py b/Kepler/options/debug.py
new file mode 100644
index 0000000..dc070c6
--- /dev/null
+++ b/Kepler/options/debug.py
@@ -0,0 +1,10 @@
+# This file provides examples how to increase or decrease the 
+# verbosity of the output. 
+
+# Set the output level of an individual algorithms
+from Configurables import TbEventBuilder
+TbEventBuilder().OutputLevel = DEBUG
+# Options are VERBOSE, DEBUG, INFO, WARNING, ERROR
+
+# Set the  global output level (all algorithms) 
+MessageSvc().OutputLevel = DEBUG
diff --git a/Kepler/options/efficiency.py b/Kepler/options/efficiency.py
new file mode 100644
index 0000000..f88660c
--- /dev/null
+++ b/Kepler/options/efficiency.py
@@ -0,0 +1,101 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py $KEPLERROOT/options/example.py
+from Gaudi.Configuration import *
+from Configurables import Kepler
+import pickle
+import ROOT
+
+# Set the path to the directory/files to be processed
+path = 'eos/lhcb/testbeam/velo/timepix3/'
+RUN = '9110'
+# if int(RUN) < 2000:
+#   path += 'July'
+# elif int(RUN) < 2815:
+#   path += 'Oct'
+# elif int(RUN) < 4000:
+#   path += 'Nov'
+# else: 
+#   path += 'Dec'
+# path += '2014'
+
+path += 'July2015'
+
+Kepler().InputFiles =  [path + '/RawData/Run' + RUN + '/']
+Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+Kepler().AlignmentFile = path + '/RootFiles/Run' + RUN + '/Conditions/Alignment' + RUN + 'mille.dat'
+#Kepler().AlignmentFile = 'ResStudies/Alignments/dut/Alignment2509.dat'
+Kepler().HistogramFile= 'Kepler_histos_' + RUN + '.root'
+# Set the number of events to run over 
+Kepler().EvtMax = 11000000
+#Kepler().TimingConfigFile = "myTimingConfig.dat"
+
+# Set the configuration of the individual algorithms, e. g.
+from Configurables import TbEventBuilder 
+#TbEventBuilder().MinPlanesWithHits = 5
+
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbSimpleTracking
+TbSimpleTracking().PrintConfiguration = True
+
+from Configurables import TbVisualiserOutput
+TbVisualiserOutput().PrintConfiguration = True
+TbVisualiserOutput().ViewerEvent = 1049
+Kepler().UserAlgorithms = [TbVisualiserOutput()]
+
+DUT_id = pickle.load( open( "DUTnum.p", "rb" ) )
+#DUT_id = 3
+
+
+fResiduals = ROOT.TFile("UnbiasedLocalResolutionsPerPlane.root")
+gx = fResiduals.Get("xPerPlane")
+gy = fResiduals.Get("yPerPlane")
+scaling = 15
+print ((gx.GetBinContent(DUT_id+1)**2 + gy.GetBinContent(DUT_id+1)**2)**0.5)
+allowance = scaling * ((gx.GetBinContent(DUT_id+1)**2 + gy.GetBinContent(DUT_id+1)**2)**0.5)
+print 'DUT_id', DUT_id
+print 'allowance:', allowance
+
+def egRun():
+    from Configurables import TbEventBuilder, TbTrackPlots, TbCalibration, TbVisualiserOutput
+    from Configurables import TbClustering, TbClusterPlots, TbSimpleTracking, TbHitMonitor
+    from Configurables import TbClusterAssociator, TbEfficiency, TbDUTMonitor
+    
+    TbEventBuilder().PrintFreq = 10
+    
+    TbSimpleTracking().TimeWindow = 6
+    TbSimpleTracking().MaxDistance = 0
+    TbSimpleTracking().MinPlanes = 7
+    TbSimpleTracking().MaskedPlanes = [DUT_id, 4]
+    TbSimpleTracking().MaxOpeningAngle = 0.005
+    TbSimpleTracking().RecheckTrack = True
+    TbSimpleTracking().ChargeCutLow = 0
+    TbSimpleTracking().DoOccupancyCut = True
+    TbSimpleTracking().MaxClusterSize = 20
+    TbSimpleTracking().MaxOccupancy = 7 # not inclusive
+    TbTrackPlots().MaskedPlanes = [DUT_id, 4]
+        
+    TbClusterAssociator().DUTs = [DUT_id]
+    TbDUTMonitor().DUTs = [DUT_id]
+    TbClusterAssociator().TimeWindow = 10
+    TbClusterAssociator().XWindow = allowance
+    
+    TbEfficiency().CheckHitDUT = True
+    TbEfficiency().CheckHitAlivePixel = True
+    TbEfficiency().DUT = DUT_id
+    TbEfficiency().TakeDeadPixelsFromFile = True
+    TbEfficiency().nTotalTracks =500000
+    TbEfficiency().MaxChi = 2
+    
+    
+    seq = GaudiSequencer("Telescope")
+    seq.Members = [TbEventBuilder(), TbClustering(), TbSimpleTracking(), TbClusterAssociator(), TbEfficiency()]    
+    #seq.Members = [TbEventBuilder()]  
+    
+    seq = GaudiSequencer("Monitoring")
+    from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots 
+    #seq.Members = [TbHitMonitor(), TbClusterPlots(), TbTrackPlots(), TbDUTMonitor(), TbVisualiserOutput()]
+    seq.Members = [TbDUTMonitor()]
+    
+appendPostConfigAction(egRun)
\ No newline at end of file
diff --git a/Kepler/options/example.py b/Kepler/options/example.py
new file mode 100644
index 0000000..0ae4d92
--- /dev/null
+++ b/Kepler/options/example.py
@@ -0,0 +1,37 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py $KEPLERROOT/options/example.py
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+# Set the path to the directory/files to be processed
+path = 'eos/lhcb/testbeam/velo/timepix3/'
+RUN = '9187'
+if int(RUN) < 2000:
+  path += 'July'
+elif int(RUN) < 2815:
+  path += 'Oct'
+elif int(RUN) < 4000:
+  path += 'Nov'
+else: 
+  path += 'Dec'
+path += '2014'
+
+Kepler().InputFiles =  [path + '/RawData/Run' + RUN + '/']
+Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+Kepler().AlignmentFile = path + '/RootFiles/Run' + RUN + '/Conditions/Alignment' + RUN + 'mille.dat'
+#Kepler().AlignmentFile = 'ResStudies/Alignments/dut/Alignment2509.dat'
+Kepler().HistogramFile= 'Kepler_histos_' + RUN + '.root'
+
+# Set the number of events to run over 
+Kepler().EvtMax = 1000
+
+# Set the configuration of the individual algorithms, e. g.
+from Configurables import TbEventBuilder
+#TbEventBuilder().MinPlanesWithHits = 5
+
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+from Configurables import TbTracking
+TbTracking().PrintConfiguration = True
+
diff --git a/Kepler/options/online/.svn/all-wcprops b/Kepler/options/online/.svn/all-wcprops
new file mode 100644
index 0000000..2477111
--- /dev/null
+++ b/Kepler/options/online/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/176267/Kepler/trunk/Tb/Kepler/options/online
+END
+OnlineMonitor.py
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/176267/Kepler/trunk/Tb/Kepler/options/online/OnlineMonitor.py
+END
+presenter.cfg
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/176267/Kepler/trunk/Tb/Kepler/options/online/presenter.cfg
+END
+runOnlineMonitor.py
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/176267/Kepler/trunk/Tb/Kepler/options/online/runOnlineMonitor.py
+END
diff --git a/Kepler/options/online/.svn/entries b/Kepler/options/online/.svn/entries
new file mode 100644
index 0000000..bc5c95a
--- /dev/null
+++ b/Kepler/options/online/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/online
+http://svn.cern.ch/guest/lhcb
+
+
+
+2014-08-12T12:51:03.631406Z
+176267
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+OnlineMonitor.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+a7c961b9962079afaafd217d9803e207
+2014-08-12T12:51:03.631406Z
+176267
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+618
+
+presenter.cfg
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+49ed6693969c8940bd6386d870c91066
+2014-08-12T12:51:03.631406Z
+176267
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+498
+
+runOnlineMonitor.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+9eebb5ee94cb15820c833f1b0b3b7ef4
+2014-08-12T12:51:03.631406Z
+176267
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+452
+
diff --git a/Kepler/options/online/.svn/prop-base/runOnlineMonitor.py.svn-base b/Kepler/options/online/.svn/prop-base/runOnlineMonitor.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/options/online/.svn/prop-base/runOnlineMonitor.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/options/online/.svn/text-base/OnlineMonitor.py.svn-base b/Kepler/options/online/.svn/text-base/OnlineMonitor.py.svn-base
new file mode 100644
index 0000000..033d539
--- /dev/null
+++ b/Kepler/options/online/.svn/text-base/OnlineMonitor.py.svn-base
@@ -0,0 +1,22 @@
+
+#-------------- EXTRA LINES TO RUN MONITOR SERVICE ONLINE --------------#
+import os
+from Gaudi.Configuration import ApplicationMgr
+
+from Configurables import LHCb__EventRunable
+ApplicationMgr().Runable= LHCb__EventRunable("Runable",NumErrorToStop=1)
+
+from Configurables import MonitorSvc
+ApplicationMgr().ExtSvc += ["MonitorSvc"]
+MonitorSvc().ExpandNameInfix=os.environ["UTGID"]+"/"
+MonitorSvc().ExpandCounterServices = 1
+MonitorSvc().DimUpdateInterval = 1
+
+def run():
+  import OnlineEnv as Online
+  Online.end_config(False)
+
+
+
+#----------------------- USER JOB CONFIGURATION ------------------------#
+import example
diff --git a/Kepler/options/online/.svn/text-base/presenter.cfg.svn-base b/Kepler/options/online/.svn/text-base/presenter.cfg.svn-base
new file mode 100644
index 0000000..c6bfe31
--- /dev/null
+++ b/Kepler/options/online/.svn/text-base/presenter.cfg.svn-base
@@ -0,0 +1,16 @@
+# Basic option to run a minimal version of the official presenter
+#
+mode                 = editor-online
+database-credentials = HIST_READER:r3aDerDB;HIST_WRITER:histeggia194;
+hide-alarm-list      = true
+enable-alarm-display = false
+dim-dns-node         = pplxint6.physics.ox.ac.uk
+window-width         = 1270
+window-height        = 980
+editing-allowed      = true
+saveset-path         = .
+reference-path       = .
+login                = no
+partition            = LHCb
+verbosity            = debug
+
diff --git a/Kepler/options/online/.svn/text-base/runOnlineMonitor.py.svn-base b/Kepler/options/online/.svn/text-base/runOnlineMonitor.py.svn-base
new file mode 100644
index 0000000..e4c83a8
--- /dev/null
+++ b/Kepler/options/online/.svn/text-base/runOnlineMonitor.py.svn-base
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+
+os.environ["DIM_DNS_NODE"]="pplxint6.physics.ox.ac.uk"
+
+os.environ["UTGID"]="LHCb_MONA_TbMonApp_00"
+
+os.environ["PYTHONPATH"]=os.environ["KEPLERROOT"]+'/options:'+os.environ["PYTHONPATH"]
+
+os.system('$GAUDIONLINEROOT/$CMTCONFIG/Gaudi.exe libGaudiOnline.so OnlineTask -msgsvc=MessageSvc -tasktype=LHCb::Class1Task -opt=command="import OnlineMonitor; OnlineMonitor.run()" -main=$GAUDIONLINEROOT/options/Main.opts -auto')
diff --git a/Kepler/options/online/OnlineMonitor.py b/Kepler/options/online/OnlineMonitor.py
new file mode 100644
index 0000000..033d539
--- /dev/null
+++ b/Kepler/options/online/OnlineMonitor.py
@@ -0,0 +1,22 @@
+
+#-------------- EXTRA LINES TO RUN MONITOR SERVICE ONLINE --------------#
+import os
+from Gaudi.Configuration import ApplicationMgr
+
+from Configurables import LHCb__EventRunable
+ApplicationMgr().Runable= LHCb__EventRunable("Runable",NumErrorToStop=1)
+
+from Configurables import MonitorSvc
+ApplicationMgr().ExtSvc += ["MonitorSvc"]
+MonitorSvc().ExpandNameInfix=os.environ["UTGID"]+"/"
+MonitorSvc().ExpandCounterServices = 1
+MonitorSvc().DimUpdateInterval = 1
+
+def run():
+  import OnlineEnv as Online
+  Online.end_config(False)
+
+
+
+#----------------------- USER JOB CONFIGURATION ------------------------#
+import example
diff --git a/Kepler/options/online/presenter.cfg b/Kepler/options/online/presenter.cfg
new file mode 100644
index 0000000..c6bfe31
--- /dev/null
+++ b/Kepler/options/online/presenter.cfg
@@ -0,0 +1,16 @@
+# Basic option to run a minimal version of the official presenter
+#
+mode                 = editor-online
+database-credentials = HIST_READER:r3aDerDB;HIST_WRITER:histeggia194;
+hide-alarm-list      = true
+enable-alarm-display = false
+dim-dns-node         = pplxint6.physics.ox.ac.uk
+window-width         = 1270
+window-height        = 980
+editing-allowed      = true
+saveset-path         = .
+reference-path       = .
+login                = no
+partition            = LHCb
+verbosity            = debug
+
diff --git a/Kepler/options/online/runOnlineMonitor.py b/Kepler/options/online/runOnlineMonitor.py
new file mode 100755
index 0000000..e4c83a8
--- /dev/null
+++ b/Kepler/options/online/runOnlineMonitor.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import os
+
+os.environ["DIM_DNS_NODE"]="pplxint6.physics.ox.ac.uk"
+
+os.environ["UTGID"]="LHCb_MONA_TbMonApp_00"
+
+os.environ["PYTHONPATH"]=os.environ["KEPLERROOT"]+'/options:'+os.environ["PYTHONPATH"]
+
+os.system('$GAUDIONLINEROOT/$CMTCONFIG/Gaudi.exe libGaudiOnline.so OnlineTask -msgsvc=MessageSvc -tasktype=LHCb::Class1Task -opt=command="import OnlineMonitor; OnlineMonitor.run()" -main=$GAUDIONLINEROOT/options/Main.opts -auto')
diff --git a/Kepler/options/singleChipExample.py b/Kepler/options/singleChipExample.py
new file mode 100644
index 0000000..e167d83
--- /dev/null
+++ b/Kepler/options/singleChipExample.py
@@ -0,0 +1,31 @@
+# Basic configuration file. 
+# Execute with: gaudirun.py singleChipExample.py
+
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+
+# Set the path to the directory/files to be processed
+Kepler().InputFiles = ["singleChipRun/"]
+# Set the alignment file
+Kepler().AlignmentFile = "singleAlignment.dat"
+# Set the masked pixels file
+Kepler().PixelConfigFile = "PixelMask.dat"
+# Set the number of events to run over 
+Kepler().EvtMax = 4300
+
+# Set the configuration of the individual algorithms
+from Configurables import TbClustering
+TbClustering().PrintConfiguration = True
+
+# Combat specific.
+def combatRun():
+     from Configurables import TbEventBuilder, TbClustering
+     seq = GaudiSequencer("Telescope")
+     seq.Members = [TbEventBuilder(), TbClustering()]
+     
+     seq = GaudiSequencer("Monitoring")
+     from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+     seq.Members = [TbHitMonitor(), TbClusterPlots()]
+
+appendPostConfigAction(combatRun)
diff --git a/Kepler/options/trackfit/.svn/all-wcprops b/Kepler/options/trackfit/.svn/all-wcprops
new file mode 100644
index 0000000..ba1ebea
--- /dev/null
+++ b/Kepler/options/trackfit/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/185851/Kepler/trunk/Tb/Kepler/options/trackfit
+END
+kfit.py
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/185851/Kepler/trunk/Tb/Kepler/options/trackfit/kfit.py
+END
diff --git a/Kepler/options/trackfit/.svn/entries b/Kepler/options/trackfit/.svn/entries
new file mode 100644
index 0000000..db58c00
--- /dev/null
+++ b/Kepler/options/trackfit/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/trackfit
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-03-24T16:06:33.359389Z
+185851
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+kfit.py
+file
+
+
+
+
+2016-05-09T14:27:48.000000Z
+0ac8746d02ca843087abd1dc71308fe5
+2015-03-24T16:06:33.359389Z
+185851
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+519
+
diff --git a/Kepler/options/trackfit/.svn/text-base/kfit.py.svn-base b/Kepler/options/trackfit/.svn/text-base/kfit.py.svn-base
new file mode 100644
index 0000000..08e3ffd
--- /dev/null
+++ b/Kepler/options/trackfit/.svn/text-base/kfit.py.svn-base
@@ -0,0 +1,15 @@
+from Gaudi.Configuration import *
+
+trackFitToolName = "TbKalmanTrackFit"
+from Configurables import TbTracking
+TbTracking().TrackFitTool = trackFitToolName
+from Configurables import TbTrackPlots
+TbTrackPlots().TrackFitTool = trackFitToolName
+
+from Configurables import TbSimpleTracking
+#TbSimpleTracking().TrackFitTool = trackFitToolName
+from Configurables import TbVertexTracking
+#TbVertexTracking().TrackFitTool = trackFitToolName
+
+from Configurables import TbAlignment
+# TbAlignment().TrackFitTool = trackFitToolName
diff --git a/Kepler/options/trackfit/kfit.py b/Kepler/options/trackfit/kfit.py
new file mode 100644
index 0000000..08e3ffd
--- /dev/null
+++ b/Kepler/options/trackfit/kfit.py
@@ -0,0 +1,15 @@
+from Gaudi.Configuration import *
+
+trackFitToolName = "TbKalmanTrackFit"
+from Configurables import TbTracking
+TbTracking().TrackFitTool = trackFitToolName
+from Configurables import TbTrackPlots
+TbTrackPlots().TrackFitTool = trackFitToolName
+
+from Configurables import TbSimpleTracking
+#TbSimpleTracking().TrackFitTool = trackFitToolName
+from Configurables import TbVertexTracking
+#TbVertexTracking().TrackFitTool = trackFitToolName
+
+from Configurables import TbAlignment
+# TbAlignment().TrackFitTool = trackFitToolName
diff --git a/Kepler/options/tracking/.svn/all-wcprops b/Kepler/options/tracking/.svn/all-wcprops
new file mode 100644
index 0000000..4b8ed4c
--- /dev/null
+++ b/Kepler/options/tracking/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/tracking
+END
+simpleTracking.py
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/tracking/simpleTracking.py
+END
+tracking.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/185430/Kepler/trunk/Tb/Kepler/options/tracking/tracking.py
+END
diff --git a/Kepler/options/tracking/.svn/entries b/Kepler/options/tracking/.svn/entries
new file mode 100644
index 0000000..7dc0656
--- /dev/null
+++ b/Kepler/options/tracking/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/options/tracking
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+simpleTracking.py
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+b135df7141dac4fb507a4768c54d4b28
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+190
+
+tracking.py
+file
+
+
+
+
+2016-05-09T14:27:47.000000Z
+5cb4fa7146e21d54b7decffa7b403612
+2015-03-15T14:01:57.475945Z
+185430
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+507
+
diff --git a/Kepler/options/tracking/.svn/text-base/simpleTracking.py.svn-base b/Kepler/options/tracking/.svn/text-base/simpleTracking.py.svn-base
new file mode 100644
index 0000000..392120a
--- /dev/null
+++ b/Kepler/options/tracking/.svn/text-base/simpleTracking.py.svn-base
@@ -0,0 +1,6 @@
+# Use TbSimpleTracking
+def simpleTracking():
+  from Configurables import TbSimpleTracking
+  GaudiSequencer("Tracking").Members = [TbSimpleTracking()]
+appendPostConfigAction(simpleTracking)
+
diff --git a/Kepler/options/tracking/.svn/text-base/tracking.py.svn-base b/Kepler/options/tracking/.svn/text-base/tracking.py.svn-base
new file mode 100644
index 0000000..a98965e
--- /dev/null
+++ b/Kepler/options/tracking/.svn/text-base/tracking.py.svn-base
@@ -0,0 +1,14 @@
+# This file provides an example how to configure the algorithm TbTracking
+
+from Configurables import TbTracking
+TbTracking().MinNClusters = 7
+TbTracking().SearchRadius = 1
+TbTracking().VolumeAngle = 0.015
+TbTracking().SearchVolume = "diabolo"
+TbTracking().TimeWindow = 150
+TbTracking().nComboCut = 300 # O(100) for speed.
+TbTracking().SearchVolumeFillAlgorithm = "adap_seq" # {seq, adap_seq}. Adap faster.
+TbTracking().Monitoring = True
+TbTracking().SearchPlanes = [4,3,5]
+# TbTracking().MaskedPlanes = []
+
diff --git a/Kepler/options/tracking/simpleTracking.py b/Kepler/options/tracking/simpleTracking.py
new file mode 100644
index 0000000..392120a
--- /dev/null
+++ b/Kepler/options/tracking/simpleTracking.py
@@ -0,0 +1,6 @@
+# Use TbSimpleTracking
+def simpleTracking():
+  from Configurables import TbSimpleTracking
+  GaudiSequencer("Tracking").Members = [TbSimpleTracking()]
+appendPostConfigAction(simpleTracking)
+
diff --git a/Kepler/options/tracking/tracking.py b/Kepler/options/tracking/tracking.py
new file mode 100644
index 0000000..a98965e
--- /dev/null
+++ b/Kepler/options/tracking/tracking.py
@@ -0,0 +1,14 @@
+# This file provides an example how to configure the algorithm TbTracking
+
+from Configurables import TbTracking
+TbTracking().MinNClusters = 7
+TbTracking().SearchRadius = 1
+TbTracking().VolumeAngle = 0.015
+TbTracking().SearchVolume = "diabolo"
+TbTracking().TimeWindow = 150
+TbTracking().nComboCut = 300 # O(100) for speed.
+TbTracking().SearchVolumeFillAlgorithm = "adap_seq" # {seq, adap_seq}. Adap faster.
+TbTracking().Monitoring = True
+TbTracking().SearchPlanes = [4,3,5]
+# TbTracking().MaskedPlanes = []
+
diff --git a/Kepler/python/.svn/all-wcprops b/Kepler/python/.svn/all-wcprops
new file mode 100644
index 0000000..367d97e
--- /dev/null
+++ b/Kepler/python/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/guest/lhcb/!svn/ver/201951/Kepler/trunk/Tb/Kepler/python
+END
diff --git a/Kepler/python/.svn/entries b/Kepler/python/.svn/entries
new file mode 100644
index 0000000..3b40233
--- /dev/null
+++ b/Kepler/python/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/python
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:54:37.186085Z
+201951
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+Kepler
+dir
+
diff --git a/Kepler/python/Kepler/.svn/all-wcprops b/Kepler/python/Kepler/.svn/all-wcprops
new file mode 100644
index 0000000..80324a8
--- /dev/null
+++ b/Kepler/python/Kepler/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/guest/lhcb/!svn/ver/201951/Kepler/trunk/Tb/Kepler/python/Kepler
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/173882/Kepler/trunk/Tb/Kepler/python/Kepler/__init__.py
+END
+Configuration.py
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/201951/Kepler/trunk/Tb/Kepler/python/Kepler/Configuration.py
+END
diff --git a/Kepler/python/Kepler/.svn/entries b/Kepler/python/Kepler/.svn/entries
new file mode 100644
index 0000000..c8ee3b5
--- /dev/null
+++ b/Kepler/python/Kepler/.svn/entries
@@ -0,0 +1,99 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/python/Kepler
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:54:37.186085Z
+201951
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+__init__.py
+file
+
+
+
+
+2016-05-09T14:27:45.000000Z
+d41d8cd98f00b204e9800998ecf8427e
+2014-06-15T18:07:47.065480Z
+173882
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+0
+
+QMTest
+dir
+
+Configuration.py
+file
+
+
+
+
+2016-05-09T14:27:45.000000Z
+c93c29d746f33c83c886dc5b70ccb2ed
+2016-02-24T06:54:37.186085Z
+201951
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8575
+
diff --git a/Kepler/python/Kepler/.svn/prop-base/Configuration.py.svn-base b/Kepler/python/Kepler/.svn/prop-base/Configuration.py.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/Kepler/python/Kepler/.svn/prop-base/Configuration.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/Kepler/python/Kepler/.svn/text-base/Configuration.py.svn-base b/Kepler/python/Kepler/.svn/text-base/Configuration.py.svn-base
new file mode 100644
index 0000000..a548c2d
--- /dev/null
+++ b/Kepler/python/Kepler/.svn/text-base/Configuration.py.svn-base
@@ -0,0 +1,202 @@
+
+"""
+High level configuration tools for Kepler 
+"""
+__version__ = ""
+__author__  = ""
+
+from Gaudi.Configuration import *
+import GaudiKernel.ProcessJobOptions
+from Configurables import LHCbConfigurableUser, LHCbApp
+
+class Kepler(LHCbConfigurableUser):
+
+  __slots__ = {
+    # Input 
+    "AlignmentFile"      :   "",            # Name of input alignment file
+    "PixelConfigFile"    :   [],            # Names of pixel configuration files
+    "TimingConfigFile"   :   "",            # Name of file that configures time offsets
+    "EtaConfigFiles"      :   [],            # Names of files with eta correction parameters
+    "InputFiles"         :   [],            # Names of input files or directories
+    "EvtMax"             :   -1,            # Max. number of events to process
+    # Output
+    "HistogramFile"      :   "",            # Name of output histogram file
+    "TupleFile"          :   "",            # Name of output tuple file
+    "WriteTuples"        :   False,         # Flag to write out tuple file or not
+    # Options
+    "Tracking"           :   True,          # Flag to run tracking or not
+    "UseSimpleTracking"  :   True,          # Flag to use Heinrich's Track finding method
+    "Alignment"          :   False,         # Flag to run alignment or not
+    "Monitoring"         :   True,          # Flag to run the monitoring sequence
+    "Sim"                :   False, 
+    "UT"                 :   False,         # Flag to run the UT reconstruction sequence
+    "UserAlgorithms"     :   []             # List of user algorithms not typically run
+  }
+
+  _propertyDocDct = {
+    'AlignmentFile'   : """ Name of input alignment file """,
+    'PixelConfigFile' : """ Names of input pixel configuration files """,
+    'TimingConfigFile': """ Name of input timing configuration file """,
+    'EtaConfigFiles'   : """ Names of files with eta correction parameters """,
+    'InputFiles'      : """ Names of input raw data files or directories """,
+    'EvtMax'          : """ Maximum number of events to process """,
+    'HistogramFile'   : """ Name of output histogram file """,
+    'TupleFile'       : """ Name of output tuple file """,
+    'WriteTuples'     : """ Flag to write out tuple files or not """,
+    'Tracking'        : """ Flag to run tracking or not """,
+    'Alignment'       : """ Flag to activate alignment or not """,
+    'Monitoring'      : """ Flag to run the monitoring sequence or not """,
+    'Sim'             : """ Flag to simulate tracks rather than read in """,
+    'UT'              : """ Flag to run the UT sequence or not """,
+    'UserAlgorithms'  : """ List of user algorithms """
+  }
+
+  __used_configurables__ = [LHCbApp,LHCbConfigurableUser]
+
+  def configureServices(self):
+    # Pass the input file names to the data service.
+    from Configurables import TbDataSvc
+    TbDataSvc().Input = self.getProp("InputFiles")
+    TbDataSvc().AlignmentFile = self.getProp("AlignmentFile")
+    TbDataSvc().PixelConfigFile = self.getProp("PixelConfigFile")
+    TbDataSvc().TimingConfigFile = self.getProp("TimingConfigFile")
+    TbDataSvc().EtaConfigFiles = self.getProp("EtaConfigFiles")
+    ApplicationMgr().ExtSvc += [TbDataSvc()]
+
+    # Add the geometry service which keeps track of alignment,
+    # the timing service, which tracks event boundaries, 
+    # and the pixel service, which stores masked pixels, 
+    # clock phases and per column timing offsets.
+    from Configurables import TbGeometrySvc, TbTimingSvc, TbPixelSvc
+    ApplicationMgr().ExtSvc += [TbGeometrySvc(), TbTimingSvc(), TbPixelSvc()]
+    
+    # Use TimingAuditor for timing, suppress printout from SequencerTimerTool
+    from Configurables import AuditorSvc, SequencerTimerTool
+    ApplicationMgr().ExtSvc += ['ToolSvc', 'AuditorSvc']
+    ApplicationMgr().AuditAlgorithms = True
+    AuditorSvc().Auditors += ['TimingAuditor']
+    if not SequencerTimerTool().isPropertySet("OutputLevel"):
+      SequencerTimerTool().OutputLevel = 4
+
+  def configureSequence(self):
+    """
+    Set up the top level sequence and its phases
+    """
+    keplerSeq = GaudiSequencer("KeplerSequencer")
+    ApplicationMgr().TopAlg = [keplerSeq]
+    telescopeSeq = GaudiSequencer("Telescope")
+    self.configureTelescope(telescopeSeq)
+    keplerSeq.Members = [telescopeSeq]
+    if self.getProp("UT") == True:
+      utSeq = GaudiSequencer("UT")
+      self.configureUT(utSeq)
+      keplerSeq.Members += [utSeq]
+    if self.getProp("Monitoring") == True:
+      monitoringSeq = GaudiSequencer("Monitoring")
+      self.configureMonitoring(monitoringSeq)
+      keplerSeq.Members += [monitoringSeq]
+    outputSeq = GaudiSequencer("Output")
+    self.configureOutput(outputSeq)
+    keplerSeq.Members += [outputSeq]
+    UserAlgorithms = self.getProp("UserAlgorithms")
+    if (len(UserAlgorithms) != 0):
+      userSeq = GaudiSequencer("UserSequence")
+      userSeq.Members = UserAlgorithms
+      keplerSeq.Members += [userSeq]   
+  def configureTelescope(self, seq):
+    if self.getProp("Sim") == False:
+      from Configurables import TbEventBuilder
+      seq.Members += [TbEventBuilder()]
+    else :
+      from Configurables import TbTestMC
+      seq.Members += [TbTestMC()]
+    from Configurables import TbClustering
+    seq.Members += [TbClustering()]
+    if self.getProp("Tracking") == True:
+      from Configurables import TbSimpleTracking, TbTracking
+      trackingSeq = GaudiSequencer("Tracking")
+      if self.getProp("UseSimpleTracking") == True :
+        trackingSeq.Members = [TbSimpleTracking()]
+      else :
+        trackingSeq.Members = [TbTracking()]
+      seq.Members += [trackingSeq]
+      from Configurables import TbTriggerAssociator
+      seq.Members += [TbTriggerAssociator()]
+      from Configurables import TbClusterAssociator
+      seq.Members += [TbClusterAssociator()]
+      if self.getProp("Alignment") == True:
+        from Configurables import TbAlignment
+        seq.Members += [TbAlignment()]
+
+  def configureMonitoring(self, seq):
+    from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+    if self.getProp("Tracking") == True :
+      seq.Members += [TbHitMonitor(), TbClusterPlots(), TbTrackPlots()]
+      from Configurables import TbTriggerMonitor
+      seq.Members += [TbTriggerMonitor()]
+      from Configurables import TbDUTMonitor
+      seq.Members += [TbDUTMonitor()]
+    else :
+      seq.Members += [TbHitMonitor(), TbClusterPlots()]
+
+  def configureUT(self, seq):
+    # UT algorithms
+    seq.Members = []
+
+  def configureInput(self):
+    # No events are read as input
+    ApplicationMgr().EvtSel = 'NONE'
+    # Delegate handling of max. number of events to ApplicationMgr
+    self.setOtherProps(ApplicationMgr(), ["EvtMax"])
+    # Transient store setup
+    EventDataSvc().ForceLeaves = True
+    EventDataSvc().RootCLID    =    1
+    # Suppress warning message from EventLoopMgr
+    from Configurables import MessageSvc
+    MessageSvc().setError += ['EventLoopMgr']
+
+  def configureOutput(self, seq):
+    # ROOT persistency for histograms
+    ApplicationMgr().HistogramPersistency = "ROOT"
+    # Set histogram file name.
+    histoFile = "Kepler-histos.root"
+    if (self.isPropertySet("HistogramFile") and self.getProp("HistogramFile") != ""):
+      histoFile = self.getProp("HistogramFile")
+    HistogramPersistencySvc().OutputFile = histoFile
+    # Set tuple file name.
+    tupleFile = "Kepler-tuple.root"
+    if (self.isPropertySet('TupleFile') and self.getProp("TupleFile") != ""):
+      tupleFile = self.getProp("TupleFile")
+    ApplicationMgr().ExtSvc += [NTupleSvc()]
+    tupleStr = "FILE1 DATAFILE='%s' TYP='ROOT' OPT='NEW'" % tupleFile
+    NTupleSvc().Output += [tupleStr]
+    from Configurables import MessageSvc
+    MessageSvc().setWarning += ['RFileCnv', 'RCWNTupleCnv']
+    # If requested add TbTupleWriter to the output sequence 
+    if self.getProp("WriteTuples") == True:
+      from Configurables import TbTupleWriter
+      seq.Members += [TbTupleWriter()]
+
+  def evtMax(self):
+    return LHCbApp().evtMax()
+
+  def __apply_configuration__(self):
+    GaudiKernel.ProcessJobOptions.PrintOn()
+    self.configureServices()
+    self.configureSequence()
+    self.configureInput()
+    GaudiKernel.ProcessJobOptions.PrintOn()
+    log.info(self)
+    GaudiKernel.ProcessJobOptions.PrintOff()
+
+  def addAlignment(self, a): 
+    from Configurables import TbAlignment
+    counter = len(TbAlignment().AlignmentTechniques)
+    name = "s%d" % (counter)
+    algname = type(a).__name__
+    print "Added tool: %s (%d)" % (algname, counter)
+    TbAlignment().addTool(a, name = name)
+    TbAlignment().AlignmentTechniques.append(algname)
+
+
+
diff --git a/Kepler/python/Kepler/.svn/text-base/__init__.py.svn-base b/Kepler/python/Kepler/.svn/text-base/__init__.py.svn-base
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Kepler/python/Kepler/.svn/text-base/__init__.py.svn-base
diff --git a/Kepler/python/Kepler/Configuration.py b/Kepler/python/Kepler/Configuration.py
new file mode 100755
index 0000000..a548c2d
--- /dev/null
+++ b/Kepler/python/Kepler/Configuration.py
@@ -0,0 +1,202 @@
+
+"""
+High level configuration tools for Kepler 
+"""
+__version__ = ""
+__author__  = ""
+
+from Gaudi.Configuration import *
+import GaudiKernel.ProcessJobOptions
+from Configurables import LHCbConfigurableUser, LHCbApp
+
+class Kepler(LHCbConfigurableUser):
+
+  __slots__ = {
+    # Input 
+    "AlignmentFile"      :   "",            # Name of input alignment file
+    "PixelConfigFile"    :   [],            # Names of pixel configuration files
+    "TimingConfigFile"   :   "",            # Name of file that configures time offsets
+    "EtaConfigFiles"      :   [],            # Names of files with eta correction parameters
+    "InputFiles"         :   [],            # Names of input files or directories
+    "EvtMax"             :   -1,            # Max. number of events to process
+    # Output
+    "HistogramFile"      :   "",            # Name of output histogram file
+    "TupleFile"          :   "",            # Name of output tuple file
+    "WriteTuples"        :   False,         # Flag to write out tuple file or not
+    # Options
+    "Tracking"           :   True,          # Flag to run tracking or not
+    "UseSimpleTracking"  :   True,          # Flag to use Heinrich's Track finding method
+    "Alignment"          :   False,         # Flag to run alignment or not
+    "Monitoring"         :   True,          # Flag to run the monitoring sequence
+    "Sim"                :   False, 
+    "UT"                 :   False,         # Flag to run the UT reconstruction sequence
+    "UserAlgorithms"     :   []             # List of user algorithms not typically run
+  }
+
+  _propertyDocDct = {
+    'AlignmentFile'   : """ Name of input alignment file """,
+    'PixelConfigFile' : """ Names of input pixel configuration files """,
+    'TimingConfigFile': """ Name of input timing configuration file """,
+    'EtaConfigFiles'   : """ Names of files with eta correction parameters """,
+    'InputFiles'      : """ Names of input raw data files or directories """,
+    'EvtMax'          : """ Maximum number of events to process """,
+    'HistogramFile'   : """ Name of output histogram file """,
+    'TupleFile'       : """ Name of output tuple file """,
+    'WriteTuples'     : """ Flag to write out tuple files or not """,
+    'Tracking'        : """ Flag to run tracking or not """,
+    'Alignment'       : """ Flag to activate alignment or not """,
+    'Monitoring'      : """ Flag to run the monitoring sequence or not """,
+    'Sim'             : """ Flag to simulate tracks rather than read in """,
+    'UT'              : """ Flag to run the UT sequence or not """,
+    'UserAlgorithms'  : """ List of user algorithms """
+  }
+
+  __used_configurables__ = [LHCbApp,LHCbConfigurableUser]
+
+  def configureServices(self):
+    # Pass the input file names to the data service.
+    from Configurables import TbDataSvc
+    TbDataSvc().Input = self.getProp("InputFiles")
+    TbDataSvc().AlignmentFile = self.getProp("AlignmentFile")
+    TbDataSvc().PixelConfigFile = self.getProp("PixelConfigFile")
+    TbDataSvc().TimingConfigFile = self.getProp("TimingConfigFile")
+    TbDataSvc().EtaConfigFiles = self.getProp("EtaConfigFiles")
+    ApplicationMgr().ExtSvc += [TbDataSvc()]
+
+    # Add the geometry service which keeps track of alignment,
+    # the timing service, which tracks event boundaries, 
+    # and the pixel service, which stores masked pixels, 
+    # clock phases and per column timing offsets.
+    from Configurables import TbGeometrySvc, TbTimingSvc, TbPixelSvc
+    ApplicationMgr().ExtSvc += [TbGeometrySvc(), TbTimingSvc(), TbPixelSvc()]
+    
+    # Use TimingAuditor for timing, suppress printout from SequencerTimerTool
+    from Configurables import AuditorSvc, SequencerTimerTool
+    ApplicationMgr().ExtSvc += ['ToolSvc', 'AuditorSvc']
+    ApplicationMgr().AuditAlgorithms = True
+    AuditorSvc().Auditors += ['TimingAuditor']
+    if not SequencerTimerTool().isPropertySet("OutputLevel"):
+      SequencerTimerTool().OutputLevel = 4
+
+  def configureSequence(self):
+    """
+    Set up the top level sequence and its phases
+    """
+    keplerSeq = GaudiSequencer("KeplerSequencer")
+    ApplicationMgr().TopAlg = [keplerSeq]
+    telescopeSeq = GaudiSequencer("Telescope")
+    self.configureTelescope(telescopeSeq)
+    keplerSeq.Members = [telescopeSeq]
+    if self.getProp("UT") == True:
+      utSeq = GaudiSequencer("UT")
+      self.configureUT(utSeq)
+      keplerSeq.Members += [utSeq]
+    if self.getProp("Monitoring") == True:
+      monitoringSeq = GaudiSequencer("Monitoring")
+      self.configureMonitoring(monitoringSeq)
+      keplerSeq.Members += [monitoringSeq]
+    outputSeq = GaudiSequencer("Output")
+    self.configureOutput(outputSeq)
+    keplerSeq.Members += [outputSeq]
+    UserAlgorithms = self.getProp("UserAlgorithms")
+    if (len(UserAlgorithms) != 0):
+      userSeq = GaudiSequencer("UserSequence")
+      userSeq.Members = UserAlgorithms
+      keplerSeq.Members += [userSeq]   
+  def configureTelescope(self, seq):
+    if self.getProp("Sim") == False:
+      from Configurables import TbEventBuilder
+      seq.Members += [TbEventBuilder()]
+    else :
+      from Configurables import TbTestMC
+      seq.Members += [TbTestMC()]
+    from Configurables import TbClustering
+    seq.Members += [TbClustering()]
+    if self.getProp("Tracking") == True:
+      from Configurables import TbSimpleTracking, TbTracking
+      trackingSeq = GaudiSequencer("Tracking")
+      if self.getProp("UseSimpleTracking") == True :
+        trackingSeq.Members = [TbSimpleTracking()]
+      else :
+        trackingSeq.Members = [TbTracking()]
+      seq.Members += [trackingSeq]
+      from Configurables import TbTriggerAssociator
+      seq.Members += [TbTriggerAssociator()]
+      from Configurables import TbClusterAssociator
+      seq.Members += [TbClusterAssociator()]
+      if self.getProp("Alignment") == True:
+        from Configurables import TbAlignment
+        seq.Members += [TbAlignment()]
+
+  def configureMonitoring(self, seq):
+    from Configurables import TbHitMonitor, TbClusterPlots, TbTrackPlots
+    if self.getProp("Tracking") == True :
+      seq.Members += [TbHitMonitor(), TbClusterPlots(), TbTrackPlots()]
+      from Configurables import TbTriggerMonitor
+      seq.Members += [TbTriggerMonitor()]
+      from Configurables import TbDUTMonitor
+      seq.Members += [TbDUTMonitor()]
+    else :
+      seq.Members += [TbHitMonitor(), TbClusterPlots()]
+
+  def configureUT(self, seq):
+    # UT algorithms
+    seq.Members = []
+
+  def configureInput(self):
+    # No events are read as input
+    ApplicationMgr().EvtSel = 'NONE'
+    # Delegate handling of max. number of events to ApplicationMgr
+    self.setOtherProps(ApplicationMgr(), ["EvtMax"])
+    # Transient store setup
+    EventDataSvc().ForceLeaves = True
+    EventDataSvc().RootCLID    =    1
+    # Suppress warning message from EventLoopMgr
+    from Configurables import MessageSvc
+    MessageSvc().setError += ['EventLoopMgr']
+
+  def configureOutput(self, seq):
+    # ROOT persistency for histograms
+    ApplicationMgr().HistogramPersistency = "ROOT"
+    # Set histogram file name.
+    histoFile = "Kepler-histos.root"
+    if (self.isPropertySet("HistogramFile") and self.getProp("HistogramFile") != ""):
+      histoFile = self.getProp("HistogramFile")
+    HistogramPersistencySvc().OutputFile = histoFile
+    # Set tuple file name.
+    tupleFile = "Kepler-tuple.root"
+    if (self.isPropertySet('TupleFile') and self.getProp("TupleFile") != ""):
+      tupleFile = self.getProp("TupleFile")
+    ApplicationMgr().ExtSvc += [NTupleSvc()]
+    tupleStr = "FILE1 DATAFILE='%s' TYP='ROOT' OPT='NEW'" % tupleFile
+    NTupleSvc().Output += [tupleStr]
+    from Configurables import MessageSvc
+    MessageSvc().setWarning += ['RFileCnv', 'RCWNTupleCnv']
+    # If requested add TbTupleWriter to the output sequence 
+    if self.getProp("WriteTuples") == True:
+      from Configurables import TbTupleWriter
+      seq.Members += [TbTupleWriter()]
+
+  def evtMax(self):
+    return LHCbApp().evtMax()
+
+  def __apply_configuration__(self):
+    GaudiKernel.ProcessJobOptions.PrintOn()
+    self.configureServices()
+    self.configureSequence()
+    self.configureInput()
+    GaudiKernel.ProcessJobOptions.PrintOn()
+    log.info(self)
+    GaudiKernel.ProcessJobOptions.PrintOff()
+
+  def addAlignment(self, a): 
+    from Configurables import TbAlignment
+    counter = len(TbAlignment().AlignmentTechniques)
+    name = "s%d" % (counter)
+    algname = type(a).__name__
+    print "Added tool: %s (%d)" % (algname, counter)
+    TbAlignment().addTool(a, name = name)
+    TbAlignment().AlignmentTechniques.append(algname)
+
+
+
diff --git a/Kepler/python/Kepler/Configuration.pyc b/Kepler/python/Kepler/Configuration.pyc
new file mode 100644
index 0000000..10cd371
--- /dev/null
+++ b/Kepler/python/Kepler/Configuration.pyc
Binary files differ
diff --git a/Kepler/python/Kepler/QMTest/.svn/all-wcprops b/Kepler/python/Kepler/QMTest/.svn/all-wcprops
new file mode 100644
index 0000000..6d9ecae
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/174354/Kepler/trunk/Tb/Kepler/python/Kepler/QMTest
+END
+KeplerExclusions.py
+K 25
+svn:wc:ra_dav:version-url
+V 91
+/guest/lhcb/!svn/ver/174354/Kepler/trunk/Tb/Kepler/python/Kepler/QMTest/KeplerExclusions.py
+END
+__init__.py
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/174354/Kepler/trunk/Tb/Kepler/python/Kepler/QMTest/__init__.py
+END
diff --git a/Kepler/python/Kepler/QMTest/.svn/entries b/Kepler/python/Kepler/QMTest/.svn/entries
new file mode 100644
index 0000000..c17b850
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/python/Kepler/QMTest
+http://svn.cern.ch/guest/lhcb
+
+
+
+2014-06-28T14:51:04.243151Z
+174354
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+KeplerExclusions.py
+file
+
+
+
+
+2016-05-09T14:27:45.000000Z
+4f56c805ef0451aa3d150a2e64a6cc4b
+2014-06-28T14:51:04.243151Z
+174354
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+237
+
+__init__.py
+file
+
+
+
+
+2016-05-09T14:27:45.000000Z
+823e664eeab3fee404b3cbd1782dd1d2
+2014-06-28T14:51:04.243151Z
+174354
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+48
+
diff --git a/Kepler/python/Kepler/QMTest/.svn/prop-base/KeplerExclusions.py.svn-base b/Kepler/python/Kepler/QMTest/.svn/prop-base/KeplerExclusions.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/.svn/prop-base/KeplerExclusions.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/python/Kepler/QMTest/.svn/prop-base/__init__.py.svn-base b/Kepler/python/Kepler/QMTest/.svn/prop-base/__init__.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/.svn/prop-base/__init__.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/Kepler/python/Kepler/QMTest/.svn/text-base/KeplerExclusions.py.svn-base b/Kepler/python/Kepler/QMTest/.svn/text-base/KeplerExclusions.py.svn-base
new file mode 100644
index 0000000..f112ce2
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/.svn/text-base/KeplerExclusions.py.svn-base
@@ -0,0 +1,6 @@
+from GaudiTest import LineSkipper, RegexpReplacer
+from GaudiConf.QMTest.LHCbExclusions import preprocessor as LHCbPreprocessor
+
+preprocessor = LHCbPreprocessor + \
+  LineSkipper(["TbEventBuilder...."]) + \
+  LineSkipper(["VolFillTime"])
diff --git a/Kepler/python/Kepler/QMTest/.svn/text-base/__init__.py.svn-base b/Kepler/python/Kepler/QMTest/.svn/text-base/__init__.py.svn-base
new file mode 100644
index 0000000..292306f
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/.svn/text-base/__init__.py.svn-base
@@ -0,0 +1,2 @@
+# tells python that this directory is a module
+
diff --git a/Kepler/python/Kepler/QMTest/KeplerExclusions.py b/Kepler/python/Kepler/QMTest/KeplerExclusions.py
new file mode 100755
index 0000000..f112ce2
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/KeplerExclusions.py
@@ -0,0 +1,6 @@
+from GaudiTest import LineSkipper, RegexpReplacer
+from GaudiConf.QMTest.LHCbExclusions import preprocessor as LHCbPreprocessor
+
+preprocessor = LHCbPreprocessor + \
+  LineSkipper(["TbEventBuilder...."]) + \
+  LineSkipper(["VolFillTime"])
diff --git a/Kepler/python/Kepler/QMTest/__init__.py b/Kepler/python/Kepler/QMTest/__init__.py
new file mode 100755
index 0000000..292306f
--- /dev/null
+++ b/Kepler/python/Kepler/QMTest/__init__.py
@@ -0,0 +1,2 @@
+# tells python that this directory is a module
+
diff --git a/Kepler/python/Kepler/__init__.py b/Kepler/python/Kepler/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Kepler/python/Kepler/__init__.py
diff --git a/Kepler/tests/.svn/all-wcprops b/Kepler/tests/.svn/all-wcprops
new file mode 100644
index 0000000..7b95a8e
--- /dev/null
+++ b/Kepler/tests/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/196708/Kepler/trunk/Tb/Kepler/tests
+END
diff --git a/Kepler/tests/.svn/entries b/Kepler/tests/.svn/entries
new file mode 100644
index 0000000..622b3da
--- /dev/null
+++ b/Kepler/tests/.svn/entries
@@ -0,0 +1,34 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/tests
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-23T15:17:24.703715Z
+196708
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+refs
+dir
+
+qmtest
+dir
+
diff --git a/Kepler/tests/qmtest/.svn/all-wcprops b/Kepler/tests/qmtest/.svn/all-wcprops
new file mode 100644
index 0000000..362d5fc
--- /dev/null
+++ b/Kepler/tests/qmtest/.svn/all-wcprops
@@ -0,0 +1,5 @@
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/196708/Kepler/trunk/Tb/Kepler/tests/qmtest
+END
diff --git a/Kepler/tests/qmtest/.svn/entries b/Kepler/tests/qmtest/.svn/entries
new file mode 100644
index 0000000..b613abf
--- /dev/null
+++ b/Kepler/tests/qmtest/.svn/entries
@@ -0,0 +1,31 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/tests/qmtest
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-23T15:17:24.703715Z
+196708
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+kepler.qms
+dir
+
diff --git a/Kepler/tests/qmtest/kepler.qms/.svn/all-wcprops b/Kepler/tests/qmtest/kepler.qms/.svn/all-wcprops
new file mode 100644
index 0000000..e6e854a
--- /dev/null
+++ b/Kepler/tests/qmtest/kepler.qms/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/196708/Kepler/trunk/Tb/Kepler/tests/qmtest/kepler.qms
+END
+millepede.qmt
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/guest/lhcb/!svn/ver/196708/Kepler/trunk/Tb/Kepler/tests/qmtest/kepler.qms/millepede.qmt
+END
+july2014.qmt
+K 25
+svn:wc:ra_dav:version-url
+V 87
+/guest/lhcb/!svn/ver/184690/Kepler/trunk/Tb/Kepler/tests/qmtest/kepler.qms/july2014.qmt
+END
diff --git a/Kepler/tests/qmtest/kepler.qms/.svn/entries b/Kepler/tests/qmtest/kepler.qms/.svn/entries
new file mode 100644
index 0000000..b4d1fa6
--- /dev/null
+++ b/Kepler/tests/qmtest/kepler.qms/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/tests/qmtest/kepler.qms
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-23T15:17:24.703715Z
+196708
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+millepede.qmt
+file
+
+
+
+
+2016-05-09T14:27:46.000000Z
+736d5e4781276d707cdc6faf86679682
+2015-10-23T15:17:24.703715Z
+196708
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1334
+
+july2014.qmt
+file
+
+
+
+
+2016-05-09T14:27:46.000000Z
+fff6031d635236f1393527b2ab585e32
+2015-03-03T06:13:36.181264Z
+184690
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1137
+
diff --git a/Kepler/tests/qmtest/kepler.qms/.svn/text-base/july2014.qmt.svn-base b/Kepler/tests/qmtest/kepler.qms/.svn/text-base/july2014.qmt.svn-base
new file mode 100644
index 0000000..2446061
--- /dev/null
+++ b/Kepler/tests/qmtest/kepler.qms/.svn/text-base/july2014.qmt.svn-base
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?><!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+  <argument name="program"><text>gaudirun.py</text></argument>
+  <argument name="options"><text>
+from Gaudi.Configuration import *
+from Configurables import Kepler
+Kepler().InputFiles = ["/afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/"]
+Kepler().AlignmentFile = "/afs/cern.ch/work/h/hschindl/public/Kepler/Alignment1024.dat"
+Kepler().PixelConfigFile = ["/afs/cern.ch/work/h/hschindl/public/Kepler/PixelConfig.dat"]
+Kepler().TimingConfigFile = "/afs/cern.ch/work/h/hschindl/public/Kepler/TimingConfig.dat"
+Kepler().EvtMax = 100
+from Configurables import TbEventBuilder
+TbEventBuilder().MinPlanesWithHits = 3
+TbEventBuilder().PrintHeader = True
+  </text></argument>
+  <argument name="reference"><text>$KEPLERROOT/tests/refs/testJuly2014.ref</text></argument>
+  <argument name="validator"><text>
+from Kepler.QMTest.KeplerExclusions import preprocessor
+validateWithReference(preproc = preprocessor)
+  </text></argument>
+</extension>
diff --git a/Kepler/tests/qmtest/kepler.qms/.svn/text-base/millepede.qmt.svn-base b/Kepler/tests/qmtest/kepler.qms/.svn/text-base/millepede.qmt.svn-base
new file mode 100644
index 0000000..e45ea31
--- /dev/null
+++ b/Kepler/tests/qmtest/kepler.qms/.svn/text-base/millepede.qmt.svn-base
@@ -0,0 +1,27 @@
+<?xml version="1.0" ?><!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+  <argument name="program"><text>gaudirun.py</text></argument>
+  <argument name="options"><text>
+from Gaudi.Configuration import *
+from Configurables import Kepler
+run = "7615"
+path = "eos/lhcb/testbeam/velo/timepix3/July2015/"
+Kepler().InputFiles = [path + "RawData/Run" + run + "/"]
+Kepler().AlignmentFile = path + "RootFiles/Run" + run + "/Conditions/Alignment" + run + "mille.dat"
+Kepler().Alignment = True
+from Configurables import TbMillepede 
+Kepler().addAlignment(TbMillepede(MaxChi2 = 1000, ResCutInit = 0.5, ResCut = 0.03, MaskedPlanes = [4]))
+from Configurables import TbAlignment
+TbAlignment().NTracks = 10000
+from Configurables import TbEventBuilder
+TbEventBuilder().MinPlanesWithHits = 5
+from Configurables import TbSimpleTracking
+TbSimpleTracking().MaskedPlanes = [4]
+  </text></argument>
+  <argument name="exit_code"><integer>4</integer></argument>
+  <argument name="reference"><text>$KEPLERROOT/tests/refs/testMillepede.ref</text></argument>
+  <argument name="validator"><text>
+from Kepler.QMTest.KeplerExclusions import preprocessor
+validateWithReference(preproc = preprocessor)
+  </text></argument>
+</extension>
diff --git a/Kepler/tests/qmtest/kepler.qms/july2014.qmt b/Kepler/tests/qmtest/kepler.qms/july2014.qmt
new file mode 100644
index 0000000..2446061
--- /dev/null
+++ b/Kepler/tests/qmtest/kepler.qms/july2014.qmt
@@ -0,0 +1,21 @@
+<?xml version="1.0" ?><!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+  <argument name="program"><text>gaudirun.py</text></argument>
+  <argument name="options"><text>
+from Gaudi.Configuration import *
+from Configurables import Kepler
+Kepler().InputFiles = ["/afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/"]
+Kepler().AlignmentFile = "/afs/cern.ch/work/h/hschindl/public/Kepler/Alignment1024.dat"
+Kepler().PixelConfigFile = ["/afs/cern.ch/work/h/hschindl/public/Kepler/PixelConfig.dat"]
+Kepler().TimingConfigFile = "/afs/cern.ch/work/h/hschindl/public/Kepler/TimingConfig.dat"
+Kepler().EvtMax = 100
+from Configurables import TbEventBuilder
+TbEventBuilder().MinPlanesWithHits = 3
+TbEventBuilder().PrintHeader = True
+  </text></argument>
+  <argument name="reference"><text>$KEPLERROOT/tests/refs/testJuly2014.ref</text></argument>
+  <argument name="validator"><text>
+from Kepler.QMTest.KeplerExclusions import preprocessor
+validateWithReference(preproc = preprocessor)
+  </text></argument>
+</extension>
diff --git a/Kepler/tests/qmtest/kepler.qms/millepede.qmt b/Kepler/tests/qmtest/kepler.qms/millepede.qmt
new file mode 100644
index 0000000..e45ea31
--- /dev/null
+++ b/Kepler/tests/qmtest/kepler.qms/millepede.qmt
@@ -0,0 +1,27 @@
+<?xml version="1.0" ?><!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+  <argument name="program"><text>gaudirun.py</text></argument>
+  <argument name="options"><text>
+from Gaudi.Configuration import *
+from Configurables import Kepler
+run = "7615"
+path = "eos/lhcb/testbeam/velo/timepix3/July2015/"
+Kepler().InputFiles = [path + "RawData/Run" + run + "/"]
+Kepler().AlignmentFile = path + "RootFiles/Run" + run + "/Conditions/Alignment" + run + "mille.dat"
+Kepler().Alignment = True
+from Configurables import TbMillepede 
+Kepler().addAlignment(TbMillepede(MaxChi2 = 1000, ResCutInit = 0.5, ResCut = 0.03, MaskedPlanes = [4]))
+from Configurables import TbAlignment
+TbAlignment().NTracks = 10000
+from Configurables import TbEventBuilder
+TbEventBuilder().MinPlanesWithHits = 5
+from Configurables import TbSimpleTracking
+TbSimpleTracking().MaskedPlanes = [4]
+  </text></argument>
+  <argument name="exit_code"><integer>4</integer></argument>
+  <argument name="reference"><text>$KEPLERROOT/tests/refs/testMillepede.ref</text></argument>
+  <argument name="validator"><text>
+from Kepler.QMTest.KeplerExclusions import preprocessor
+validateWithReference(preproc = preprocessor)
+  </text></argument>
+</extension>
diff --git a/Kepler/tests/refs/.svn/all-wcprops b/Kepler/tests/refs/.svn/all-wcprops
new file mode 100644
index 0000000..aeab218
--- /dev/null
+++ b/Kepler/tests/refs/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/guest/lhcb/!svn/ver/196708/Kepler/trunk/Tb/Kepler/tests/refs
+END
+testJuly2014.ref
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/196509/Kepler/trunk/Tb/Kepler/tests/refs/testJuly2014.ref
+END
+testMillepede.ref
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/196708/Kepler/trunk/Tb/Kepler/tests/refs/testMillepede.ref
+END
diff --git a/Kepler/tests/refs/.svn/entries b/Kepler/tests/refs/.svn/entries
new file mode 100644
index 0000000..92c66e3
--- /dev/null
+++ b/Kepler/tests/refs/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/Kepler/tests/refs
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-23T15:17:24.703715Z
+196708
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+testJuly2014.ref
+file
+
+
+
+
+2016-05-09T14:27:46.000000Z
+1e7518821596cad40a5aaa96d8601cbe
+2015-10-20T16:53:50.358128Z
+196509
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+46345
+
+testMillepede.ref
+file
+
+
+
+
+2016-05-09T14:27:46.000000Z
+f6a22374d8879fb63fa33725ed38c087
+2015-10-23T15:17:24.703715Z
+196708
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+55683
+
diff --git a/Kepler/tests/refs/.svn/text-base/testJuly2014.ref.svn-base b/Kepler/tests/refs/.svn/text-base/testJuly2014.ref.svn-base
new file mode 100644
index 0000000..4c72e2e
--- /dev/null
+++ b/Kepler/tests/refs/.svn/text-base/testJuly2014.ref.svn-base
@@ -0,0 +1,555 @@
+# setting LC_ALL to "C"
+# --> Including file '/afs/cern.ch/user/h/hschindl/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/testJuly.py'
+# <-- End of file '/afs/cern.ch/user/h/hschindl/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/testJuly.py'
+# applying configuration of Kepler
+# /***** User Kepler/Kepler **************************************************************************
+# |-Tracking         = True
+# |-Monitoring       = True
+# |-TimingConfigFile = '/afs/cern.ch/work/h/hschindl/public/Kepler/TimingConfig.dat'  (default: '')
+# |-TupleFile        = ''
+# |-AlignmentFile    = '/afs/cern.ch/work/h/hschindl/public/Kepler/Alignment1024.dat'  (default: '')
+# |-EvtMax           = 100  (default: -1)
+# |-WriteTuples      = False
+# |-HistogramFile    = ''
+# |-PixelConfigFile  = ['/afs/cern.ch/work/h/hschindl/public/Kepler/PixelConfig.dat']  (default: [])
+# |-UserAlgorithms   = []  (default: [])
+# |-InputFiles       = ['/afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/']  (default: [])
+# |-Alignment        = False
+# \----- (End of User Kepler/Kepler) -----------------------------------------------------------------
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to Kepler version v2r1
+                                          running on lxplus0206.cern.ch on Sun Dec 14 10:03:26 2014
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_B05-140727-160847-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_C05-140727-160821-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_D05-140727-160821-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_E05-140727-160822-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_F05-140727-160823-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_G05-140727-160823-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_H07-140727-160822-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_J06-140727-160846-1024-1.dat
+TbGeometrySvc        INFO Importing alignment conditions from /afs/cern.ch/work/h/hschindl/public/Kepler/Alignment1024.dat
+TbGeometrySvc        INFO  0 W0002_J06           16.644     14.226      0.000      2.936      3.288      0.025
+TbGeometrySvc        INFO  1 W0002_B05           16.142     13.893     31.000      2.938      3.293      0.017
+TbGeometrySvc        INFO  2 W0002_C05           16.381     13.986     60.000      2.942      3.292      0.011
+TbGeometrySvc        INFO  3 W0002_D05           16.444     13.767     89.000      2.947      3.308      0.009
+TbGeometrySvc        INFO  4 W0002_G05            0.000     14.080    300.000      3.297      0.157      0.000
+TbGeometrySvc        INFO  5 W0002_F05            0.353     14.052    330.000      3.295      0.159      0.013
+TbGeometrySvc        INFO  6 W0002_H07            0.372     14.144    360.000      3.294      0.167      0.019
+TbGeometrySvc        INFO  7 W0002_E05            0.647     14.410    391.000      3.290      0.152      0.028
+TbPixelSvc           INFO Importing pixel configuration from /afs/cern.ch/work/h/hschindl/public/Kepler/PixelConfig.dat
+TbPixelSvc           INFO Masking pixel 0x8b46 (column 139, row 162) on device W0002_J06
+TbPixelSvc           INFO Masking pixel 0x4cbc (column  77, row  92) on device W0002_C05
+TbPixelSvc           INFO Masking pixel 0x05b5 (column   5, row 217) on device W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 87 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 91 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_E05
+TbPixelSvc           INFO Importing pixel configuration from /afs/cern.ch/work/h/hschindl/public/Kepler/TimingConfig.dat
+TbPixelSvc           INFO Adding time offset 0 ns (0 time units) to chip W0002_J06
+TbPixelSvc           INFO Adding time offset -12.1264 ns (-1987 time units) to chip W0002_B05
+TbPixelSvc           INFO Adding time offset 1.60015 ns (262 time units) to chip W0002_C05
+TbPixelSvc           INFO Adding time offset -8.18727 ns (-1341 time units) to chip W0002_D05
+TbPixelSvc           INFO Adding time offset -16.4738 ns (-2699 time units) to chip W0002_G05
+TbPixelSvc           INFO Adding time offset 2.35494 ns (386 time units) to chip W0002_F05
+TbPixelSvc           INFO Adding time offset -5.43922 ns (-891 time units) to chip W0002_H07
+TbPixelSvc           INFO Adding time offset -15.053 ns (-2466 time units) to chip W0002_E05
+RndmGenSvc.Engine    INFO Generator engine type:CLHEP::RanluxEngine
+RndmGenSvc.Engine    INFO Current Seed:1234567 Luxury:3
+RndmGenSvc           INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine>
+TimingAuditor.T...   INFO This machine has a speed about   3.33 times the speed of a 2.8 GHz Xeon.
+NTupleSvc            INFO Added stream file:Kepler-tuple.root as FILE1
+KeplerSequencer      INFO Member list: GaudiSequencer/Telescope, GaudiSequencer/Monitoring, GaudiSequencer/Output
+Telescope            INFO Member list: TbEventBuilder, TbClustering, GaudiSequencer/Tracking, TbTriggerAssociator, TbClusterAssociator
+RootHistSvc          INFO Writing ROOT histograms to: Kepler-histos.root
+HistogramPersis...   INFO Added successfully Conversion service:RootHistSvc
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000017 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:47.26
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x252 
+ToolSvc.TbHeade...   INFO                                  W0002_B05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 244 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_B05 (device 1) is mapped to plane 1
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000028 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:21.67
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x253 
+ToolSvc.TbHeade...   INFO                                  W0002_C05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 229 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_C05 (device 2) is mapped to plane 2
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000028 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:21.97
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x254 
+ToolSvc.TbHeade...   INFO                                  W0002_D05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 198 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_D05 (device 3) is mapped to plane 3
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000029 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:22.53
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x255 
+ToolSvc.TbHeade...   INFO                                  W0002_E05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 192 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_E05 (device 7) is mapped to plane 7
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000004 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:23.99
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x256 
+ToolSvc.TbHeade...   INFO                                  W0002_F05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 224 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_F05 (device 5) is mapped to plane 5
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000004 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:23.68
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x257 
+ToolSvc.TbHeade...   INFO                                  W0002_G05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 199 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_G05 (device 4) is mapped to plane 4
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000029 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:22.23
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x278 
+ToolSvc.TbHeade...   INFO                                  W0002_H07 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 210 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_H07 (device 6) is mapped to plane 6
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000017 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:46.96
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x26a 
+ToolSvc.TbHeade...   INFO                                  W0002_J06 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 117 008
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_J06 (device 0) is mapped to plane 0
+TbEventBuilder       INFO Initialization successful - reading 146291680 packets
+Tracking             INFO Member list: TbSimpleTracking
+Monitoring           INFO Member list: TbHitMonitor, TbClusterPlots, TbTrackPlots, TbTriggerMonitor, TbDUTMonitor
+Output               INFO Member list: 
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr       INFO Application Manager Started successfully
+TbEventBuilder       INFO       100 events read,       330732 hits,            0 triggers
+ApplicationMgr       INFO Application Manager Stopped successfully
+TbEventBuilder       INFO Plane  0:     18818688 packets in file,           14 hits in cache
+TbEventBuilder       INFO Plane  1:     16116982 packets in file,           20 hits in cache
+TbEventBuilder       INFO Plane  2:     17541221 packets in file,           23 hits in cache
+TbEventBuilder       INFO Plane  3:     17829521 packets in file,           20 hits in cache
+TbEventBuilder       INFO Plane  4:     15980851 packets in file,           10 hits in cache
+TbEventBuilder       INFO Plane  5:     17316763 packets in file,           19 hits in cache
+TbEventBuilder       INFO Plane  6:     18382762 packets in file,           16 hits in cache
+TbEventBuilder       INFO Plane  7:     24304892 packets in file,           13 hits in cache
+TbEventBuilder       INFO Fraction of data read: 0.00226231
+TbEventBuilder       INFO Number of packets lost: 0
+TbEventBuilder       INFO Unknown packets: 169
+TbEventBuilder       INFO Skipped 794 noise events.
+TbClustering      SUCCESS Number of counters : 8
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfClusters0"                             |       100 |       5311 |     53.110 |     34.041 |      0.0000 |      142.00 |
+ | "NumberOfClusters1"                             |       100 |       5357 |     53.570 |     34.254 |      0.0000 |      141.00 |
+ | "NumberOfClusters2"                             |       100 |       5504 |     55.040 |     35.396 |      0.0000 |      149.00 |
+ | "NumberOfClusters3"                             |       100 |       5608 |     56.080 |     35.729 |      0.0000 |      142.00 |
+ | "NumberOfClusters4"                             |       100 |       5819 |     58.190 |     37.743 |      0.0000 |      154.00 |
+ | "NumberOfClusters5"                             |       100 |       6113 |     61.130 |     39.774 |      0.0000 |      162.00 |
+ | "NumberOfClusters6"                             |       100 |       6295 |     62.950 |     41.199 |      0.0000 |      165.00 |
+ | "NumberOfClusters7"                             |       100 |       6566 |     65.660 |     42.701 |      0.0000 |      177.00 |
+TbSimpleTracking  SUCCESS Number of counters : 1
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfChiRejectedVols"                       |         8 |          8 |     1.0000 |     0.0000 |      1.0000 |      1.0000 |
+ | "NumberOfTracks"                                |       100 |       4534 |     45.340 |     30.149 |      0.0000 |      124.00 |
+TbHitMonitor      SUCCESS Booked 40 Histogram(s) : 1D=32 2D=8 
+TbClusterPlots    SUCCESS Booked 220 Histogram(s) : 1D=162 2D=58 
+TbClusterPlots    SUCCESS Number of counters : 8
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ |*"effFractionAssociated0"                        |      5311 |       4391 |(  82.6775 +- 0.519291 )%|   -------   |   -------   |
+ |*"effFractionAssociated1"                        |      5357 |       4527 |(  84.5063 +- 0.494381 )%|   -------   |   -------   |
+ |*"effFractionAssociated2"                        |      5504 |       4534 |(  82.3765 +- 0.513581 )%|   -------   |   -------   |
+ |*"effFractionAssociated3"                        |      5608 |       4518 |(  80.5635 +- 0.528414 )%|   -------   |   -------   |
+ |*"effFractionAssociated4"                        |      5819 |       4368 |(  75.0644 +- 0.567156 )%|   -------   |   -------   |
+ |*"effFractionAssociated5"                        |      6113 |       4534 |(  74.1698 +- 0.559822 )%|   -------   |   -------   |
+ |*"effFractionAssociated6"                        |      6295 |       4534 |(  72.0254 +- 0.565753 )%|   -------   |   -------   |
+ |*"effFractionAssociated7"                        |      6566 |       4495 |(  68.4587 +- 0.573461 )%|   -------   |   -------   |
+TbTrackPlots      SUCCESS Booked 192 Histogram(s) : 1D=96 2D=88 1DProf=8 
+TbTriggerMonitor  SUCCESS Booked 17 Histogram(s) : 1D=17 
+ToolSvc              INFO Removing all tools created by ToolSvc
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO This machine has a speed about   3.33 times the speed of a 2.8 GHz Xeon.
+TimingAuditor.T...   INFO Algorithm          (millisec) |    <user> |   <clock> |      min       max | entries | total (s) |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO EVENT LOOP                    |     4.909 |     5.316 |    0.244      49.7 |     100 |     0.532 |
+TimingAuditor.T...   INFO  KeplerSequencer              |     4.809 |     5.225 |    0.231      49.5 |     100 |     0.523 |
+TimingAuditor.T...   INFO   Telescope                   |     1.300 |     1.683 |    0.146      49.1 |     100 |     0.168 |
+TimingAuditor.T...   INFO    TbEventBuilder             |     0.660 |     0.709 |    0.060      14.5 |     100 |     0.071 |
+TimingAuditor.T...   INFO    TbClustering               |     0.360 |     0.494 |    0.045      13.9 |     100 |     0.049 |
+TimingAuditor.T...   INFO    Tracking                   |     0.250 |     0.454 |    0.019      20.5 |     100 |     0.045 |
+TimingAuditor.T...   INFO     TbTracking                |     0.240 |     0.451 |    0.015      20.5 |     100 |     0.045 |
+TimingAuditor.T...   INFO    TbTriggerAssociator        |     0.010 |     0.018 |    0.012       0.1 |     100 |     0.002 |
+TimingAuditor.T...   INFO   Monitoring                  |     3.510 |     3.537 |    0.066       9.5 |     100 |     0.354 |
+TimingAuditor.T...   INFO    TbHitMonitor               |     0.350 |     0.337 |    0.014       0.9 |     100 |     0.034 |
+TimingAuditor.T...   INFO    TbClusterPlots             |     1.080 |     1.090 |    0.023       2.9 |     100 |     0.109 |
+TimingAuditor.T...   INFO    TbTrackPlots               |     2.040 |     2.082 |    0.011       5.7 |     100 |     0.208 |
+TimingAuditor.T...   INFO    TbTriggerMonitor           |     0.020 |     0.019 |    0.013       0.0 |     100 |     0.002 |
+TimingAuditor.T...   INFO   Output                      |     0.000 |     0.001 |    0.000       0.0 |     100 |     0.000 |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+ApplicationMgr       INFO Application Manager Finalized successfully
+ApplicationMgr       INFO Application Manager Terminated successfully
diff --git a/Kepler/tests/refs/.svn/text-base/testMillepede.ref.svn-base b/Kepler/tests/refs/.svn/text-base/testMillepede.ref.svn-base
new file mode 100644
index 0000000..e9c074a
--- /dev/null
+++ b/Kepler/tests/refs/.svn/text-base/testMillepede.ref.svn-base
@@ -0,0 +1,650 @@
+# setting LC_ALL to "C"
+# --> Including file '/afs/cern.ch/user/h/hschindl/cmtuserkepler/KEPLER/KEPLER_HEAD/millepede.py'
+Added tool: TbMillepede (0)
+# <-- End of file '/afs/cern.ch/user/h/hschindl/cmtuserkepler/KEPLER/KEPLER_HEAD/millepede.py'
+# applying configuration of Kepler
+# /***** User Kepler/Kepler **************************************************************************
+# |-UseSimpleTracking = True
+# |-Tracking          = True
+# |-Monitoring        = True
+# |-TimingConfigFile  = ''
+# |-TupleFile         = ''
+# |-AlignmentFile     = 'eos/lhcb/testbeam/velo/timepix3/July2015/RootFiles/Run7615/Conditions/Alignment7615mille.dat'
+# |                   (default: '')
+# |-EvtMax            = -1
+# |-WriteTuples       = False
+# |-HistogramFile     = 'Kepler-histos.root'  (default: '')
+# |-Alignment         = True  (default: False)
+# |-PixelConfigFile   = []  (default: [])
+# |-UT                = False
+# |-UserAlgorithms    = []  (default: [])
+# |-InputFiles        = ['eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/']  (default: [])
+# |-Sim               = False
+# \----- (End of User Kepler/Kepler) -----------------------------------------------------------------
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to Kepler version v3r0
+                                          running on lxplus0029.cern.ch on Fri Oct 23 16:15:34 2015
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_B05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_C05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_D05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_E05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_F05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_G05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_H07-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_J06-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0009_G08-150714-180051-7615-1.dat
+TbGeometrySvc        INFO Importing alignment conditions from root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RootFiles/Run7615/Conditions/Alignment7615mille.dat
+TbGeometrySvc        INFO  0 W0002_J06           13.907     13.494      3.778      2.984      3.272      0.008
+TbGeometrySvc        INFO  1 W0002_B05           14.293     13.781     52.475      2.985      3.267      0.002
+TbGeometrySvc        INFO  2 W0002_C05           14.214     13.838     93.675      2.988      3.287     -0.001
+TbGeometrySvc        INFO  3 W0002_D05           14.067     14.101    128.900      2.991      3.295      0.006
+TbGeometrySvc        INFO  4 W0009_G08           -0.129     15.709    252.014      3.125     -0.449     -0.053
+TbGeometrySvc        INFO  5 W0002_G05           -1.083     13.560    410.853      3.266      0.166     -0.049
+TbGeometrySvc        INFO  6 W0002_F05           -0.568     13.841    443.837      3.250      0.180     -0.044
+TbGeometrySvc        INFO  7 W0002_H07            0.301     14.130    494.828      3.247      0.175     -0.045
+TbGeometrySvc        INFO  8 W0002_E05            0.289     14.324    538.655      3.233      0.180     -0.048
+RndmGenSvc.Engine    INFO Generator engine type:CLHEP::RanluxEngine
+RndmGenSvc.Engine    INFO Current Seed:1234567 Luxury:3
+RndmGenSvc           INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine>
+TimingAuditor.T...   INFO This machine has a speed about   2.71 times the speed of a 2.8 GHz Xeon.
+NTupleSvc            INFO Added stream file:Kepler-tuple.root as FILE1
+KeplerSequencer      INFO Member list: GaudiSequencer/Telescope, GaudiSequencer/Monitoring, GaudiSequencer/Output
+Telescope            INFO Member list: TbEventBuilder, TbClustering, GaudiSequencer/Tracking, TbTriggerAssociator, TbClusterAssociator, TbAlignment
+RootHistSvc          INFO Writing ROOT histograms to: Kepler-histos.root
+HistogramPersis...   INFO Added successfully Conversion service:RootHistSvc
+TbEventBuilder       INFO W0002_B05 (device 1) is mapped to plane 1
+TbEventBuilder       INFO W0002_C05 (device 2) is mapped to plane 2
+TbEventBuilder       INFO W0002_D05 (device 3) is mapped to plane 3
+TbEventBuilder       INFO W0002_E05 (device 8) is mapped to plane 8
+TbEventBuilder       INFO W0002_F05 (device 6) is mapped to plane 6
+TbEventBuilder       INFO W0002_G05 (device 5) is mapped to plane 5
+TbEventBuilder       INFO W0002_H07 (device 7) is mapped to plane 7
+TbEventBuilder       INFO W0002_J06 (device 0) is mapped to plane 0
+TbEventBuilder       INFO W0009_G08 (device 4) is mapped to plane 4
+TbEventBuilder       INFO Initialization successful - reading 73582112 packets
+Tracking             INFO Member list: TbSimpleTracking
+TbAlignment          INFO Adding tool TbMillepede
+TbAlignment.s0       INFO Using default degrees of freedom.
+Monitoring           INFO Member list: TbHitMonitor, TbClusterPlots, TbTrackPlots, TbTriggerMonitor, TbDUTMonitor
+Output               INFO Member list: 
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr       INFO Application Manager Started successfully
+TbAlignment          INFO Collected 1000 alignment tracks
+TbAlignment          INFO Collected 2000 alignment tracks
+TbAlignment          INFO Collected 3000 alignment tracks
+TbAlignment          INFO Collected 4000 alignment tracks
+TbAlignment          INFO Collected 5000 alignment tracks
+TbAlignment          INFO Collected 6000 alignment tracks
+TbAlignment          INFO Collected 7000 alignment tracks
+TbAlignment          INFO Collected 8000 alignment tracks
+TbAlignment          INFO Collected 9000 alignment tracks
+TbAlignment          INFO Collected 10000 alignment tracks
+TbAlignment.s0       INFO Millepede alignment
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78948
+TbAlignment.s0       INFO Iteration 2 (using 8825 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77975
+TbAlignment.s0       INFO Iteration 3 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 4 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 5 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 6 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 7 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 8 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 9 (using 8820 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0    -0.001165     0.000000      0.00031     -0.01165      0.98592
+TbAlignment.s0       INFO    1    -0.000497     0.000000      0.00014     -0.00497      0.93812
+TbAlignment.s0       INFO    2     0.000902    -0.000000      0.00017      0.00902      0.96087
+TbAlignment.s0       INFO    3     0.001652    -0.000000      0.00033      0.01652      0.98997
+TbAlignment.s0       INFO    4    -0.001484     0.000000      0.00026     -0.01484      0.98375
+TbAlignment.s0       INFO    5    -0.000578     0.000000      0.00021     -0.00578      0.97451
+TbAlignment.s0       INFO    6     0.000692    -0.000000      0.00018      0.00692      0.96187
+TbAlignment.s0       INFO    7     0.000477     0.000000      0.00027      0.00477      0.98050
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8     0.005849    -0.000000      0.00121      0.05849      0.99907
+TbAlignment.s0       INFO    9     0.001895    -0.000000      0.00046      0.01895      0.99415
+TbAlignment.s0       INFO   10    -0.002670     0.000000      0.00051     -0.02670      0.99557
+TbAlignment.s0       INFO   11    -0.006050     0.000000      0.00130     -0.06051      0.99934
+TbAlignment.s0       INFO   12    -0.002986    -0.000000      0.00075     -0.02986      0.99805
+TbAlignment.s0       INFO   13    -0.000231    -0.000000      0.00032     -0.00231      0.98888
+TbAlignment.s0       INFO   14     0.000478     0.000000      0.00023      0.00478      0.97670
+TbAlignment.s0       INFO   15     0.003715    -0.000000      0.00096      0.03716      0.99852
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24     0.004836    -0.000000      0.00072      0.48490      0.98199
+TbAlignment.s0       INFO   25     0.004713    -0.000000      0.00069      0.47246      0.98153
+TbAlignment.s0       INFO   26     0.004560    -0.000000      0.00067      0.45699      0.98662
+TbAlignment.s0       INFO   27     0.005067    -0.000000      0.00066      0.50782      0.98705
+TbAlignment.s0       INFO   28    -0.004147     0.000000      0.00058     -0.41540      0.99657
+TbAlignment.s0       INFO   29    -0.004262     0.000000      0.00062     -0.42707      0.99729
+TbAlignment.s0       INFO   30    -0.005032     0.000000      0.00073     -0.50454      0.99671
+TbAlignment.s0       INFO   31    -0.005735     0.000000      0.00082     -0.57544      0.99768
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32    -0.005983     0.000000      0.00096     -0.60110      0.98987
+TbAlignment.s0       INFO   33    -0.005047     0.000000      0.00080     -0.50631      0.98619
+TbAlignment.s0       INFO   34    -0.003172     0.000000      0.00058     -0.31774      0.98151
+TbAlignment.s0       INFO   35    -0.002304     0.000000      0.00044     -0.23064      0.97018
+TbAlignment.s0       INFO   36     0.003912    -0.000000      0.00057      0.39183      0.99646
+TbAlignment.s0       INFO   37     0.003743    -0.000000      0.00061      0.37501      0.99720
+TbAlignment.s0       INFO   38     0.004089    -0.000000      0.00074      0.41001      0.99681
+TbAlignment.s0       INFO   39     0.004762    -0.000000      0.00083      0.47788      0.99772
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40     0.002804    -0.000000      0.00075      0.28119      0.99996
+TbAlignment.s0       INFO   41     0.002159    -0.000000      0.00061      0.21633      0.99995
+TbAlignment.s0       INFO   42     0.001495     0.000000      0.00049      0.14966      0.99993
+TbAlignment.s0       INFO   43     0.001045     0.000000      0.00039      0.10456      0.99990
+TbAlignment.s0       INFO   44    -0.001248     0.000000      0.00039     -0.12492      0.99993
+TbAlignment.s0       INFO   45    -0.001671     0.000000      0.00048     -0.16733      0.99995
+TbAlignment.s0       INFO   46    -0.002101     0.000000      0.00062     -0.21048      0.99996
+TbAlignment.s0       INFO   47    -0.002482     0.000000      0.00073     -0.24891      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00245
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79204
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0     0.000165     0.000000      0.00029      0.00165      0.98354
+TbAlignment.s0       INFO    1     0.000074     0.000000      0.00014      0.00074      0.93508
+TbAlignment.s0       INFO    2    -0.000083    -0.000000      0.00017     -0.00083      0.95728
+TbAlignment.s0       INFO    3    -0.000231    -0.000000      0.00030     -0.00231      0.98790
+TbAlignment.s0       INFO    4     0.000018     0.000000      0.00026      0.00018      0.98303
+TbAlignment.s0       INFO    5     0.000084     0.000000      0.00021      0.00084      0.97359
+TbAlignment.s0       INFO    6    -0.000064    -0.000000      0.00018     -0.00064      0.96029
+TbAlignment.s0       INFO    7     0.000038     0.000000      0.00026      0.00038      0.97920
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8    -0.000643    -0.000000      0.00120     -0.00643      0.99906
+TbAlignment.s0       INFO    9    -0.000204    -0.000000      0.00046     -0.00204      0.99415
+TbAlignment.s0       INFO   10     0.000277     0.000000      0.00051      0.00277      0.99551
+TbAlignment.s0       INFO   11     0.000696     0.000000      0.00129      0.00696      0.99933
+TbAlignment.s0       INFO   12     0.000236     0.000000      0.00075      0.00236      0.99803
+TbAlignment.s0       INFO   13     0.000060    -0.000000      0.00032      0.00060      0.98879
+TbAlignment.s0       INFO   14    -0.000031     0.000000      0.00023     -0.00031      0.97642
+TbAlignment.s0       INFO   15    -0.000392    -0.000000      0.00096     -0.00392      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24    -0.001461    -0.000000      0.00066     -0.14646      0.98034
+TbAlignment.s0       INFO   25    -0.001289    -0.000000      0.00064     -0.12915      0.97960
+TbAlignment.s0       INFO   26    -0.001111    -0.000000      0.00062     -0.11132      0.98457
+TbAlignment.s0       INFO   27    -0.001009    -0.000000      0.00060     -0.10113      0.98461
+TbAlignment.s0       INFO   28     0.001023     0.000000      0.00054      0.10249      0.99553
+TbAlignment.s0       INFO   29     0.001130     0.000000      0.00058      0.11320      0.99649
+TbAlignment.s0       INFO   30     0.001235     0.000000      0.00066      0.12375      0.99548
+TbAlignment.s0       INFO   31     0.001483     0.000000      0.00075      0.14868      0.99675
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32     0.000883     0.000000      0.00086      0.08866      0.98852
+TbAlignment.s0       INFO   33     0.000712     0.000000      0.00073      0.07138      0.98461
+TbAlignment.s0       INFO   34     0.000446     0.000000      0.00054      0.04468      0.97995
+TbAlignment.s0       INFO   35     0.000298     0.000000      0.00043      0.02985      0.96879
+TbAlignment.s0       INFO   36    -0.000446    -0.000000      0.00053     -0.04469      0.99540
+TbAlignment.s0       INFO   37    -0.000539    -0.000000      0.00057     -0.05397      0.99638
+TbAlignment.s0       INFO   38    -0.000626    -0.000000      0.00068     -0.06273      0.99574
+TbAlignment.s0       INFO   39    -0.000729    -0.000000      0.00077     -0.07309      0.99693
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40    -0.000300    -0.000000      0.00075     -0.03010      0.99996
+TbAlignment.s0       INFO   41    -0.000230    -0.000000      0.00061     -0.02306      0.99995
+TbAlignment.s0       INFO   42    -0.000150    -0.000000      0.00049     -0.01498      0.99993
+TbAlignment.s0       INFO   43    -0.000092     0.000000      0.00039     -0.00925      0.99990
+TbAlignment.s0       INFO   44     0.000144     0.000000      0.00040      0.01440      0.99993
+TbAlignment.s0       INFO   45     0.000169     0.000000      0.00049      0.01694      0.99995
+TbAlignment.s0       INFO   46     0.000213     0.000000      0.00062      0.02137      0.99996
+TbAlignment.s0       INFO   47     0.000246     0.000000      0.00074      0.02467      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00040
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79207
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78090
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0    -0.000033     0.000000      0.00029     -0.00033      0.98414
+TbAlignment.s0       INFO    1    -0.000011     0.000000      0.00014     -0.00011      0.93599
+TbAlignment.s0       INFO    2     0.000014    -0.000000      0.00017      0.00014      0.95818
+TbAlignment.s0       INFO    3     0.000040    -0.000000      0.00031      0.00040      0.98840
+TbAlignment.s0       INFO    4     0.000006     0.000000      0.00026      0.00006      0.98317
+TbAlignment.s0       INFO    5    -0.000012     0.000000      0.00021     -0.00012      0.97377
+TbAlignment.s0       INFO    6     0.000009    -0.000000      0.00018      0.00009      0.96062
+TbAlignment.s0       INFO    7    -0.000014     0.000000      0.00026     -0.00014      0.97953
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8     0.000067    -0.000000      0.00120      0.00067      0.99906
+TbAlignment.s0       INFO    9     0.000021    -0.000000      0.00046      0.00021      0.99415
+TbAlignment.s0       INFO   10    -0.000029     0.000000      0.00051     -0.00029      0.99551
+TbAlignment.s0       INFO   11    -0.000076     0.000000      0.00129     -0.00076      0.99933
+TbAlignment.s0       INFO   12    -0.000018    -0.000000      0.00075     -0.00018      0.99804
+TbAlignment.s0       INFO   13     0.000001    -0.000000      0.00032      0.00001      0.98882
+TbAlignment.s0       INFO   14     0.000001     0.000000      0.00023      0.00001      0.97649
+TbAlignment.s0       INFO   15     0.000033    -0.000000      0.00096      0.00033      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24     0.000226    -0.000000      0.00067      0.02267      0.98090
+TbAlignment.s0       INFO   25     0.000199    -0.000000      0.00065      0.01997      0.98017
+TbAlignment.s0       INFO   26     0.000175    -0.000000      0.00063      0.01749      0.98511
+TbAlignment.s0       INFO   27     0.000156    -0.000000      0.00061      0.01563      0.98518
+TbAlignment.s0       INFO   28    -0.000137     0.000000      0.00055     -0.01368      0.99575
+TbAlignment.s0       INFO   29    -0.000176     0.000000      0.00059     -0.01764      0.99667
+TbAlignment.s0       INFO   30    -0.000199     0.000000      0.00067     -0.01992      0.99577
+TbAlignment.s0       INFO   31    -0.000245     0.000000      0.00077     -0.02452      0.99698
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32    -0.000145     0.000000      0.00089     -0.01460      0.98894
+TbAlignment.s0       INFO   33    -0.000123     0.000000      0.00075     -0.01233      0.98511
+TbAlignment.s0       INFO   34    -0.000088     0.000000      0.00055     -0.00881      0.98054
+TbAlignment.s0       INFO   35    -0.000065     0.000000      0.00043     -0.00651      0.96949
+TbAlignment.s0       INFO   36     0.000079    -0.000000      0.00054      0.00795      0.99565
+TbAlignment.s0       INFO   37     0.000096    -0.000000      0.00058      0.00965      0.99658
+TbAlignment.s0       INFO   38     0.000111    -0.000000      0.00069      0.01113      0.99601
+TbAlignment.s0       INFO   39     0.000135    -0.000000      0.00079      0.01350      0.99714
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40     0.000027    -0.000000      0.00075      0.00274      0.99996
+TbAlignment.s0       INFO   41     0.000020    -0.000000      0.00061      0.00203      0.99995
+TbAlignment.s0       INFO   42     0.000012     0.000000      0.00049      0.00117      0.99993
+TbAlignment.s0       INFO   43     0.000005     0.000000      0.00039      0.00054      0.99990
+TbAlignment.s0       INFO   44    -0.000013    -0.000000      0.00040     -0.00126      0.99993
+TbAlignment.s0       INFO   45    -0.000014    -0.000000      0.00049     -0.00142      0.99995
+TbAlignment.s0       INFO   46    -0.000018    -0.000000      0.00062     -0.00179      0.99996
+TbAlignment.s0       INFO   47    -0.000020    -0.000000      0.00074     -0.00200      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00006
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79206
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78090
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0     0.000009     0.000000      0.00029      0.00009      0.98403
+TbAlignment.s0       INFO    1     0.000003     0.000000      0.00014      0.00003      0.93583
+TbAlignment.s0       INFO    2    -0.000004    -0.000000      0.00017     -0.00004      0.95802
+TbAlignment.s0       INFO    3    -0.000011    -0.000000      0.00031     -0.00011      0.98831
+TbAlignment.s0       INFO    4    -0.000002     0.000000      0.00026     -0.00002      0.98315
+TbAlignment.s0       INFO    5     0.000002     0.000000      0.00021      0.00002      0.97374
+TbAlignment.s0       INFO    6    -0.000002    -0.000000      0.00018     -0.00002      0.96057
+TbAlignment.s0       INFO    7     0.000004     0.000000      0.00026      0.00004      0.97947
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8    -0.000010    -0.000000      0.00120     -0.00010      0.99906
+TbAlignment.s0       INFO    9    -0.000003    -0.000000      0.00046     -0.00003      0.99415
+TbAlignment.s0       INFO   10     0.000005     0.000000      0.00051      0.00005      0.99551
+TbAlignment.s0       INFO   11     0.000011     0.000000      0.00129      0.00011      0.99933
+TbAlignment.s0       INFO   12    -0.000001    -0.000000      0.00075     -0.00001      0.99803
+TbAlignment.s0       INFO   13    -0.000003    -0.000000      0.00032     -0.00003      0.98881
+TbAlignment.s0       INFO   14     0.000001     0.000000      0.00023      0.00001      0.97647
+TbAlignment.s0       INFO   15    -0.000002    -0.000000      0.00096     -0.00002      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24    -0.000048    -0.000000      0.00067     -0.00482      0.98079
+TbAlignment.s0       INFO   25    -0.000044    -0.000000      0.00065     -0.00437      0.98006
+TbAlignment.s0       INFO   26    -0.000040    -0.000000      0.00063     -0.00404      0.98501
+TbAlignment.s0       INFO   27    -0.000037    -0.000000      0.00061     -0.00372      0.98507
+TbAlignment.s0       INFO   28     0.000031     0.000000      0.00055      0.00315      0.99571
+TbAlignment.s0       INFO   29     0.000039     0.000000      0.00058      0.00389      0.99664
+TbAlignment.s0       INFO   30     0.000044     0.000000      0.00067      0.00443      0.99571
+TbAlignment.s0       INFO   31     0.000055     0.000000      0.00076      0.00549      0.99694
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32     0.000036     0.000000      0.00088      0.00357      0.98887
+TbAlignment.s0       INFO   33     0.000030     0.000000      0.00075      0.00299      0.98502
+TbAlignment.s0       INFO   34     0.000021     0.000000      0.00055      0.00208      0.98044
+TbAlignment.s0       INFO   35     0.000015     0.000000      0.00043      0.00150      0.96936
+TbAlignment.s0       INFO   36    -0.000020    -0.000000      0.00054     -0.00199      0.99561
+TbAlignment.s0       INFO   37    -0.000023    -0.000000      0.00058     -0.00230      0.99655
+TbAlignment.s0       INFO   38    -0.000027    -0.000000      0.00069     -0.00267      0.99597
+TbAlignment.s0       INFO   39    -0.000032    -0.000000      0.00078     -0.00318      0.99710
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40    -0.000002    -0.000000      0.00075     -0.00017      0.99996
+TbAlignment.s0       INFO   41    -0.000001    -0.000000      0.00061     -0.00009      0.99995
+TbAlignment.s0       INFO   42     0.000001     0.000000      0.00049      0.00005      0.99993
+TbAlignment.s0       INFO   43     0.000001     0.000000      0.00039      0.00014      0.99990
+TbAlignment.s0       INFO   44     0.000000     0.000000      0.00040      0.00003      0.99993
+TbAlignment.s0       INFO   45     0.000000     0.000000      0.00049      0.00002      0.99995
+TbAlignment.s0       INFO   46     0.000000     0.000000      0.00062      0.00002      0.99996
+TbAlignment.s0       INFO   47    -0.000000    -0.000000      0.00074     -0.00001      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00001
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79206
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78090
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0    -0.000002     0.000000      0.00029     -0.00002      0.98405
+TbAlignment.s0       INFO    1    -0.000001     0.000000      0.00014     -0.00001      0.93587
+TbAlignment.s0       INFO    2     0.000001    -0.000000      0.00017      0.00001      0.95806
+TbAlignment.s0       INFO    3     0.000002    -0.000000      0.00031      0.00002      0.98833
+TbAlignment.s0       INFO    4     0.000001     0.000000      0.00026      0.00001      0.98315
+TbAlignment.s0       INFO    5    -0.000000     0.000000      0.00021     -0.00000      0.97375
+TbAlignment.s0       INFO    6     0.000000    -0.000000      0.00018      0.00000      0.96058
+TbAlignment.s0       INFO    7    -0.000001     0.000000      0.00026     -0.00001      0.97949
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8     0.000001    -0.000000      0.00120      0.00001      0.99906
+TbAlignment.s0       INFO    9     0.000000    -0.000000      0.00046      0.00000      0.99415
+TbAlignment.s0       INFO   10    -0.000001     0.000000      0.00051     -0.00001      0.99551
+TbAlignment.s0       INFO   11    -0.000001     0.000000      0.00129     -0.00001      0.99933
+TbAlignment.s0       INFO   12     0.000001    -0.000000      0.00075      0.00001      0.99803
+TbAlignment.s0       INFO   13     0.000001    -0.000000      0.00032      0.00001      0.98881
+TbAlignment.s0       INFO   14    -0.000000     0.000000      0.00023     -0.00000      0.97648
+TbAlignment.s0       INFO   15    -0.000000    -0.000000      0.00096     -0.00000      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24     0.000011    -0.000000      0.00067      0.00107      0.98081
+TbAlignment.s0       INFO   25     0.000010    -0.000000      0.00065      0.00097      0.98008
+TbAlignment.s0       INFO   26     0.000009    -0.000000      0.00063      0.00088      0.98503
+TbAlignment.s0       INFO   27     0.000008    -0.000000      0.00061      0.00080      0.98510
+TbAlignment.s0       INFO   28    -0.000007     0.000000      0.00055     -0.00070      0.99572
+TbAlignment.s0       INFO   29    -0.000008     0.000000      0.00058     -0.00085      0.99665
+TbAlignment.s0       INFO   30    -0.000010     0.000000      0.00067     -0.00097      0.99573
+TbAlignment.s0       INFO   31    -0.000012     0.000000      0.00076     -0.00120      0.99695
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32    -0.000007     0.000000      0.00088     -0.00073      0.98888
+TbAlignment.s0       INFO   33    -0.000006     0.000000      0.00075     -0.00061      0.98504
+TbAlignment.s0       INFO   34    -0.000004     0.000000      0.00055     -0.00043      0.98046
+TbAlignment.s0       INFO   35    -0.000003     0.000000      0.00043     -0.00031      0.96939
+TbAlignment.s0       INFO   36     0.000004    -0.000000      0.00054      0.00041      0.99562
+TbAlignment.s0       INFO   37     0.000005    -0.000000      0.00058      0.00047      0.99656
+TbAlignment.s0       INFO   38     0.000005    -0.000000      0.00069      0.00055      0.99598
+TbAlignment.s0       INFO   39     0.000007    -0.000000      0.00078      0.00066      0.99711
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40    -0.000000    -0.000000      0.00075     -0.00002      0.99996
+TbAlignment.s0       INFO   41    -0.000000    -0.000000      0.00061     -0.00003      0.99995
+TbAlignment.s0       INFO   42    -0.000000    -0.000000      0.00049     -0.00005      0.99993
+TbAlignment.s0       INFO   43    -0.000001     0.000000      0.00039     -0.00006      0.99990
+TbAlignment.s0       INFO   44     0.000000     0.000000      0.00040      0.00002      0.99993
+TbAlignment.s0       INFO   45     0.000000     0.000000      0.00049      0.00003      0.99995
+TbAlignment.s0       INFO   46     0.000000     0.000000      0.00062      0.00004      0.99996
+TbAlignment.s0       INFO   47     0.000001     0.000000      0.00074      0.00006      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00000
+TbAlignment.s0       INFO Updating geometry...
+EventLoopMgr      SUCCESS Terminating event processing loop due to scheduled stop
+ApplicationMgr       INFO Application Manager Stopped successfully
+TbEventBuilder       INFO Plane  0:      7103600 packets in file,         4466 hits in cache
+TbEventBuilder       INFO Plane  1:      6064648 packets in file,         3775 hits in cache
+TbEventBuilder       INFO Plane  2:      6492004 packets in file,         4013 hits in cache
+TbEventBuilder       INFO Plane  3:      6557011 packets in file,         4740 hits in cache
+TbEventBuilder       INFO Plane  4:     22003178 packets in file,        12613 hits in cache
+TbEventBuilder       INFO Plane  5:      6616512 packets in file,         4227 hits in cache
+TbEventBuilder       INFO Plane  6:      6256693 packets in file,         4015 hits in cache
+TbEventBuilder       INFO Plane  7:      6298052 packets in file,         4097 hits in cache
+TbEventBuilder       INFO Plane  8:      6190414 packets in file,         3891 hits in cache
+TbEventBuilder       INFO Fraction of data read: 0.00876674
+TbEventBuilder       INFO Number of packets lost: 0
+TbEventBuilder       INFO Unknown packets: 373
+TbEventBuilder       INFO Skipped 1961 noise events.
+TbClustering      SUCCESS Number of counters : 9
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfClusters0"                             |        36 |      14064 |     390.67 |     247.79 |      1.0000 |      778.00 |
+ | "NumberOfClusters1"                             |        36 |      14127 |     392.42 |     251.75 |      1.0000 |      795.00 |
+ | "NumberOfClusters2"                             |        36 |      14275 |     396.53 |     253.90 |      1.0000 |      802.00 |
+ | "NumberOfClusters3"                             |        36 |      14413 |     400.36 |     257.82 |      1.0000 |      810.00 |
+ | "NumberOfClusters4"                             |        36 |       4080 |     113.33 |     72.239 |      0.0000 |      244.00 |
+ | "NumberOfClusters5"                             |        36 |      16099 |     447.19 |     287.03 |      1.0000 |      903.00 |
+ | "NumberOfClusters6"                             |        36 |      15491 |     430.31 |     275.64 |      1.0000 |      862.00 |
+ | "NumberOfClusters7"                             |        36 |      15212 |     422.56 |     269.76 |      1.0000 |      842.00 |
+ | "NumberOfClusters8"                             |        36 |      15040 |     417.78 |     268.17 |      1.0000 |      843.00 |
+TbSimpleTracking  SUCCESS Number of counters : 1
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfTracks"                                |        36 |      13965 |     387.92 |     248.52 |      1.0000 |      791.00 |
+TbAlignment          INFO Writing alignment output file to Alignment_out.dat
+TbHitMonitor      SUCCESS Booked 45 Histogram(s) : 1D=36 2D=9 
+TbClusterPlots    SUCCESS Booked 247 Histogram(s) : 1D=182 2D=65 
+TbClusterPlots    SUCCESS Number of counters : 9
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ |*"effFractionAssociated0"                        |     14064 |      12194 |(  86.7036 +- 0.286306 )%|   -------   |   -------   |
+ |*"effFractionAssociated1"                        |     14127 |      13965 |(  98.8533 +- 0.0895784)%|   -------   |   -------   |
+ |*"effFractionAssociated2"                        |     14275 |      13375 |(  93.6953 +- 0.203425 )%|   -------   |   -------   |
+ |*"effFractionAssociated3"                        |     14413 |      13355 |(  92.6594 +- 0.217237 )%|   -------   |   -------   |
+ |*"effFractionAssociated4"                        |      4080 |          0 |(  0.00000 +- 0.0245098)%|   -------   |   -------   |
+ |*"effFractionAssociated5"                        |     16099 |      13320 |(  82.7381 +- 0.297850 )%|   -------   |   -------   |
+ |*"effFractionAssociated6"                        |     15491 |      13309 |(  85.9144 +- 0.279499 )%|   -------   |   -------   |
+ |*"effFractionAssociated7"                        |     15212 |      13291 |(  87.3718 +- 0.269317 )%|   -------   |   -------   |
+ |*"effFractionAssociated8"                        |     15040 |      13284 |(  88.3245 +- 0.261851 )%|   -------   |   -------   |
+TbTrackPlots      SUCCESS Booked 214 Histogram(s) : 1D=106 2D=99 1DProf=9 
+TbTriggerMonitor  SUCCESS Booked 19 Histogram(s) : 1D=19 
+ToolSvc              INFO Removing all tools created by ToolSvc
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO This machine has a speed about   2.71 times the speed of a 2.8 GHz Xeon.
+TimingAuditor.T...   INFO Algorithm          (millisec) |    <user> |   <clock> |      min       max | entries | total (s) |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO EVENT LOOP                    |   954.938 |   974.860 |    0.821   32348.9 |      36 |    35.095 |
+TimingAuditor.T...   INFO  KeplerSequencer              |   954.633 |   974.483 |    0.790   32337.6 |      36 |    35.081 |
+TimingAuditor.T...   INFO   Telescope                   |   914.916 |   932.157 |    0.409   32279.9 |      36 |    33.558 |
+TimingAuditor.T...   INFO    TbEventBuilder             |     7.999 |     8.227 |    0.139      37.8 |      36 |     0.296 |
+TimingAuditor.T...   INFO    TbClustering               |    14.637 |    15.324 |    0.094     110.2 |      36 |     0.552 |
+TimingAuditor.T...   INFO    Tracking                   |     2.333 |     2.317 |    0.035       6.8 |      36 |     0.083 |
+TimingAuditor.T...   INFO     TbSimpleTracking          |     2.333 |     2.308 |    0.030       6.8 |      36 |     0.083 |
+TimingAuditor.T...   INFO    TbTriggerAssociator        |     0.028 |     0.040 |    0.018       0.1 |      36 |     0.001 |
+TimingAuditor.T...   INFO    TbClusterAssociator        |     0.000 |     0.006 |    0.002       0.0 |      36 |     0.000 |
+TimingAuditor.T...   INFO    TbAlignment                |   889.893 |   906.207 |    0.009   32256.8 |      36 |    32.623 |
+TimingAuditor.T...   INFO   Monitoring                  |    39.688 |    42.302 |    0.372      85.9 |      36 |     1.523 |
+TimingAuditor.T...   INFO    TbHitMonitor               |     3.111 |     3.488 |    0.043       8.0 |      36 |     0.126 |
+TimingAuditor.T...   INFO    TbClusterPlots             |     9.693 |     9.909 |    0.126      21.1 |      36 |     0.357 |
+TimingAuditor.T...   INFO    TbTrackPlots               |    26.718 |    28.796 |    0.162      61.9 |      36 |     1.037 |
+TimingAuditor.T...   INFO    TbTriggerMonitor           |     0.028 |     0.035 |    0.020       0.1 |      36 |     0.001 |
+TimingAuditor.T...   INFO    TbDUTMonitor               |     0.083 |     0.035 |    0.004       0.1 |      36 |     0.001 |
+TimingAuditor.T...   INFO   Output                      |     0.000 |     0.012 |    0.001       0.3 |      36 |     0.000 |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+ApplicationMgr       INFO Application Manager Finalized successfully
+ApplicationMgr       INFO Application Manager Terminated successfully with a user requested ScheduledStop
diff --git a/Kepler/tests/refs/testJuly2014.ref b/Kepler/tests/refs/testJuly2014.ref
new file mode 100644
index 0000000..4c72e2e
--- /dev/null
+++ b/Kepler/tests/refs/testJuly2014.ref
@@ -0,0 +1,555 @@
+# setting LC_ALL to "C"
+# --> Including file '/afs/cern.ch/user/h/hschindl/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/testJuly.py'
+# <-- End of file '/afs/cern.ch/user/h/hschindl/cmtuser/KEPLER/KEPLER_HEAD/Tb/Kepler/testJuly.py'
+# applying configuration of Kepler
+# /***** User Kepler/Kepler **************************************************************************
+# |-Tracking         = True
+# |-Monitoring       = True
+# |-TimingConfigFile = '/afs/cern.ch/work/h/hschindl/public/Kepler/TimingConfig.dat'  (default: '')
+# |-TupleFile        = ''
+# |-AlignmentFile    = '/afs/cern.ch/work/h/hschindl/public/Kepler/Alignment1024.dat'  (default: '')
+# |-EvtMax           = 100  (default: -1)
+# |-WriteTuples      = False
+# |-HistogramFile    = ''
+# |-PixelConfigFile  = ['/afs/cern.ch/work/h/hschindl/public/Kepler/PixelConfig.dat']  (default: [])
+# |-UserAlgorithms   = []  (default: [])
+# |-InputFiles       = ['/afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/']  (default: [])
+# |-Alignment        = False
+# \----- (End of User Kepler/Kepler) -----------------------------------------------------------------
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to Kepler version v2r1
+                                          running on lxplus0206.cern.ch on Sun Dec 14 10:03:26 2014
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_B05-140727-160847-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_C05-140727-160821-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_D05-140727-160821-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_E05-140727-160822-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_F05-140727-160823-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_G05-140727-160823-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_H07-140727-160822-1024-1.dat
+TbDataSvc            INFO Reading File: /afs/cern.ch/work/h/hschindl/public/Kepler/Run1024/W0002_J06-140727-160846-1024-1.dat
+TbGeometrySvc        INFO Importing alignment conditions from /afs/cern.ch/work/h/hschindl/public/Kepler/Alignment1024.dat
+TbGeometrySvc        INFO  0 W0002_J06           16.644     14.226      0.000      2.936      3.288      0.025
+TbGeometrySvc        INFO  1 W0002_B05           16.142     13.893     31.000      2.938      3.293      0.017
+TbGeometrySvc        INFO  2 W0002_C05           16.381     13.986     60.000      2.942      3.292      0.011
+TbGeometrySvc        INFO  3 W0002_D05           16.444     13.767     89.000      2.947      3.308      0.009
+TbGeometrySvc        INFO  4 W0002_G05            0.000     14.080    300.000      3.297      0.157      0.000
+TbGeometrySvc        INFO  5 W0002_F05            0.353     14.052    330.000      3.295      0.159      0.013
+TbGeometrySvc        INFO  6 W0002_H07            0.372     14.144    360.000      3.294      0.167      0.019
+TbGeometrySvc        INFO  7 W0002_E05            0.647     14.410    391.000      3.290      0.152      0.028
+TbPixelSvc           INFO Importing pixel configuration from /afs/cern.ch/work/h/hschindl/public/Kepler/PixelConfig.dat
+TbPixelSvc           INFO Masking pixel 0x8b46 (column 139, row 162) on device W0002_J06
+TbPixelSvc           INFO Masking pixel 0x4cbc (column  77, row  92) on device W0002_C05
+TbPixelSvc           INFO Masking pixel 0x05b5 (column   5, row 217) on device W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_J06
+TbPixelSvc           INFO Adding time offset -25 ns to double column 87 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_B05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 91 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_C05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_D05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_G05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_F05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_H07
+TbPixelSvc           INFO Adding time offset -25 ns to double column 97 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 98 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 99 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 100 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 101 on chip W0002_E05
+TbPixelSvc           INFO Adding time offset -25 ns to double column 102 on chip W0002_E05
+TbPixelSvc           INFO Importing pixel configuration from /afs/cern.ch/work/h/hschindl/public/Kepler/TimingConfig.dat
+TbPixelSvc           INFO Adding time offset 0 ns (0 time units) to chip W0002_J06
+TbPixelSvc           INFO Adding time offset -12.1264 ns (-1987 time units) to chip W0002_B05
+TbPixelSvc           INFO Adding time offset 1.60015 ns (262 time units) to chip W0002_C05
+TbPixelSvc           INFO Adding time offset -8.18727 ns (-1341 time units) to chip W0002_D05
+TbPixelSvc           INFO Adding time offset -16.4738 ns (-2699 time units) to chip W0002_G05
+TbPixelSvc           INFO Adding time offset 2.35494 ns (386 time units) to chip W0002_F05
+TbPixelSvc           INFO Adding time offset -5.43922 ns (-891 time units) to chip W0002_H07
+TbPixelSvc           INFO Adding time offset -15.053 ns (-2466 time units) to chip W0002_E05
+RndmGenSvc.Engine    INFO Generator engine type:CLHEP::RanluxEngine
+RndmGenSvc.Engine    INFO Current Seed:1234567 Luxury:3
+RndmGenSvc           INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine>
+TimingAuditor.T...   INFO This machine has a speed about   3.33 times the speed of a 2.8 GHz Xeon.
+NTupleSvc            INFO Added stream file:Kepler-tuple.root as FILE1
+KeplerSequencer      INFO Member list: GaudiSequencer/Telescope, GaudiSequencer/Monitoring, GaudiSequencer/Output
+Telescope            INFO Member list: TbEventBuilder, TbClustering, GaudiSequencer/Tracking, TbTriggerAssociator, TbClusterAssociator
+RootHistSvc          INFO Writing ROOT histograms to: Kepler-histos.root
+HistogramPersis...   INFO Added successfully Conversion service:RootHistSvc
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000017 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:47.26
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x252 
+ToolSvc.TbHeade...   INFO                                  W0002_B05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 244 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_B05 (device 1) is mapped to plane 1
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000028 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:21.67
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x253 
+ToolSvc.TbHeade...   INFO                                  W0002_C05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 229 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_C05 (device 2) is mapped to plane 2
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000028 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:21.97
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x254 
+ToolSvc.TbHeade...   INFO                                  W0002_D05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 198 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_D05 (device 3) is mapped to plane 3
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000029 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:22.53
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x255 
+ToolSvc.TbHeade...   INFO                                  W0002_E05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 192 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_E05 (device 7) is mapped to plane 7
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000004 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8193 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:23.99
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x256 
+ToolSvc.TbHeade...   INFO                                  W0002_F05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 224 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_F05 (device 5) is mapped to plane 5
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000004 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:23.68
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x257 
+ToolSvc.TbHeade...   INFO                                  W0002_G05 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 199 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_G05 (device 4) is mapped to plane 4
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000029 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:22.23
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x278 
+ToolSvc.TbHeade...   INFO                                  W0002_H07 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 210 006
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_H07 (device 6) is mapped to plane 6
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                         File header 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  ID                              0x52445053 
+ToolSvc.TbHeade...   INFO  Total size                      768 
+ToolSvc.TbHeade...   INFO  Size                            512 
+ToolSvc.TbHeade...   INFO  Format                          0x00000001 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  SPIDR ID                        0x2000017 
+ToolSvc.TbHeade...   INFO  Library version                 0x14072400 
+ToolSvc.TbHeade...   INFO  Software version                0x14071501 
+ToolSvc.TbHeade...   INFO  Firmware version                0x14072101 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  IP address                      192.168.100.1 
+ToolSvc.TbHeade...   INFO  IP port                         8192 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Date                            2014-07-27
+ToolSvc.TbHeade...   INFO  Time                            16:08:46.96
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Run number                      1024 
+ToolSvc.TbHeade...   INFO  Sequence number                 1 
+ToolSvc.TbHeade...   INFO  Run info                        10 GeV no protection covers 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Spidr configuration             0x000a0800 
+ToolSvc.TbHeade...   INFO  Data filter                     0xf3ffffff 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO                        Device header
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Type ID                         0x33585054 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  Device ID                       0x26a 
+ToolSvc.TbHeade...   INFO                                  W0002_J06 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  General config                  0x00000668 
+ToolSvc.TbHeade...   INFO  Output block config             0x000009ff 
+ToolSvc.TbHeade...   INFO  PLL config                      0x0000001e 
+ToolSvc.TbHeade...   INFO  Testpulse config                0x000a0001 
+ToolSvc.TbHeade...   INFO  SLVS config                     0x00000008 
+ToolSvc.TbHeade...   INFO  Power pulsing config            0x00000008 
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+ToolSvc.TbHeade...   INFO  DAC values                      000 128 008 128
+ToolSvc.TbHeade...   INFO                                  010 128 117 008
+ToolSvc.TbHeade...   INFO                                  128 008 128 008
+ToolSvc.TbHeade...   INFO                                  128 128 128 128
+ToolSvc.TbHeade...   INFO                                  256 128 128 000
+ToolSvc.TbHeade...   INFO ----------------------------------------------------------------------
+TbEventBuilder       INFO W0002_J06 (device 0) is mapped to plane 0
+TbEventBuilder       INFO Initialization successful - reading 146291680 packets
+Tracking             INFO Member list: TbSimpleTracking
+Monitoring           INFO Member list: TbHitMonitor, TbClusterPlots, TbTrackPlots, TbTriggerMonitor, TbDUTMonitor
+Output               INFO Member list: 
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr       INFO Application Manager Started successfully
+TbEventBuilder       INFO       100 events read,       330732 hits,            0 triggers
+ApplicationMgr       INFO Application Manager Stopped successfully
+TbEventBuilder       INFO Plane  0:     18818688 packets in file,           14 hits in cache
+TbEventBuilder       INFO Plane  1:     16116982 packets in file,           20 hits in cache
+TbEventBuilder       INFO Plane  2:     17541221 packets in file,           23 hits in cache
+TbEventBuilder       INFO Plane  3:     17829521 packets in file,           20 hits in cache
+TbEventBuilder       INFO Plane  4:     15980851 packets in file,           10 hits in cache
+TbEventBuilder       INFO Plane  5:     17316763 packets in file,           19 hits in cache
+TbEventBuilder       INFO Plane  6:     18382762 packets in file,           16 hits in cache
+TbEventBuilder       INFO Plane  7:     24304892 packets in file,           13 hits in cache
+TbEventBuilder       INFO Fraction of data read: 0.00226231
+TbEventBuilder       INFO Number of packets lost: 0
+TbEventBuilder       INFO Unknown packets: 169
+TbEventBuilder       INFO Skipped 794 noise events.
+TbClustering      SUCCESS Number of counters : 8
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfClusters0"                             |       100 |       5311 |     53.110 |     34.041 |      0.0000 |      142.00 |
+ | "NumberOfClusters1"                             |       100 |       5357 |     53.570 |     34.254 |      0.0000 |      141.00 |
+ | "NumberOfClusters2"                             |       100 |       5504 |     55.040 |     35.396 |      0.0000 |      149.00 |
+ | "NumberOfClusters3"                             |       100 |       5608 |     56.080 |     35.729 |      0.0000 |      142.00 |
+ | "NumberOfClusters4"                             |       100 |       5819 |     58.190 |     37.743 |      0.0000 |      154.00 |
+ | "NumberOfClusters5"                             |       100 |       6113 |     61.130 |     39.774 |      0.0000 |      162.00 |
+ | "NumberOfClusters6"                             |       100 |       6295 |     62.950 |     41.199 |      0.0000 |      165.00 |
+ | "NumberOfClusters7"                             |       100 |       6566 |     65.660 |     42.701 |      0.0000 |      177.00 |
+TbSimpleTracking  SUCCESS Number of counters : 1
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfChiRejectedVols"                       |         8 |          8 |     1.0000 |     0.0000 |      1.0000 |      1.0000 |
+ | "NumberOfTracks"                                |       100 |       4534 |     45.340 |     30.149 |      0.0000 |      124.00 |
+TbHitMonitor      SUCCESS Booked 40 Histogram(s) : 1D=32 2D=8 
+TbClusterPlots    SUCCESS Booked 220 Histogram(s) : 1D=162 2D=58 
+TbClusterPlots    SUCCESS Number of counters : 8
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ |*"effFractionAssociated0"                        |      5311 |       4391 |(  82.6775 +- 0.519291 )%|   -------   |   -------   |
+ |*"effFractionAssociated1"                        |      5357 |       4527 |(  84.5063 +- 0.494381 )%|   -------   |   -------   |
+ |*"effFractionAssociated2"                        |      5504 |       4534 |(  82.3765 +- 0.513581 )%|   -------   |   -------   |
+ |*"effFractionAssociated3"                        |      5608 |       4518 |(  80.5635 +- 0.528414 )%|   -------   |   -------   |
+ |*"effFractionAssociated4"                        |      5819 |       4368 |(  75.0644 +- 0.567156 )%|   -------   |   -------   |
+ |*"effFractionAssociated5"                        |      6113 |       4534 |(  74.1698 +- 0.559822 )%|   -------   |   -------   |
+ |*"effFractionAssociated6"                        |      6295 |       4534 |(  72.0254 +- 0.565753 )%|   -------   |   -------   |
+ |*"effFractionAssociated7"                        |      6566 |       4495 |(  68.4587 +- 0.573461 )%|   -------   |   -------   |
+TbTrackPlots      SUCCESS Booked 192 Histogram(s) : 1D=96 2D=88 1DProf=8 
+TbTriggerMonitor  SUCCESS Booked 17 Histogram(s) : 1D=17 
+ToolSvc              INFO Removing all tools created by ToolSvc
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO This machine has a speed about   3.33 times the speed of a 2.8 GHz Xeon.
+TimingAuditor.T...   INFO Algorithm          (millisec) |    <user> |   <clock> |      min       max | entries | total (s) |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO EVENT LOOP                    |     4.909 |     5.316 |    0.244      49.7 |     100 |     0.532 |
+TimingAuditor.T...   INFO  KeplerSequencer              |     4.809 |     5.225 |    0.231      49.5 |     100 |     0.523 |
+TimingAuditor.T...   INFO   Telescope                   |     1.300 |     1.683 |    0.146      49.1 |     100 |     0.168 |
+TimingAuditor.T...   INFO    TbEventBuilder             |     0.660 |     0.709 |    0.060      14.5 |     100 |     0.071 |
+TimingAuditor.T...   INFO    TbClustering               |     0.360 |     0.494 |    0.045      13.9 |     100 |     0.049 |
+TimingAuditor.T...   INFO    Tracking                   |     0.250 |     0.454 |    0.019      20.5 |     100 |     0.045 |
+TimingAuditor.T...   INFO     TbTracking                |     0.240 |     0.451 |    0.015      20.5 |     100 |     0.045 |
+TimingAuditor.T...   INFO    TbTriggerAssociator        |     0.010 |     0.018 |    0.012       0.1 |     100 |     0.002 |
+TimingAuditor.T...   INFO   Monitoring                  |     3.510 |     3.537 |    0.066       9.5 |     100 |     0.354 |
+TimingAuditor.T...   INFO    TbHitMonitor               |     0.350 |     0.337 |    0.014       0.9 |     100 |     0.034 |
+TimingAuditor.T...   INFO    TbClusterPlots             |     1.080 |     1.090 |    0.023       2.9 |     100 |     0.109 |
+TimingAuditor.T...   INFO    TbTrackPlots               |     2.040 |     2.082 |    0.011       5.7 |     100 |     0.208 |
+TimingAuditor.T...   INFO    TbTriggerMonitor           |     0.020 |     0.019 |    0.013       0.0 |     100 |     0.002 |
+TimingAuditor.T...   INFO   Output                      |     0.000 |     0.001 |    0.000       0.0 |     100 |     0.000 |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+ApplicationMgr       INFO Application Manager Finalized successfully
+ApplicationMgr       INFO Application Manager Terminated successfully
diff --git a/Kepler/tests/refs/testMillepede.ref b/Kepler/tests/refs/testMillepede.ref
new file mode 100644
index 0000000..e9c074a
--- /dev/null
+++ b/Kepler/tests/refs/testMillepede.ref
@@ -0,0 +1,650 @@
+# setting LC_ALL to "C"
+# --> Including file '/afs/cern.ch/user/h/hschindl/cmtuserkepler/KEPLER/KEPLER_HEAD/millepede.py'
+Added tool: TbMillepede (0)
+# <-- End of file '/afs/cern.ch/user/h/hschindl/cmtuserkepler/KEPLER/KEPLER_HEAD/millepede.py'
+# applying configuration of Kepler
+# /***** User Kepler/Kepler **************************************************************************
+# |-UseSimpleTracking = True
+# |-Tracking          = True
+# |-Monitoring        = True
+# |-TimingConfigFile  = ''
+# |-TupleFile         = ''
+# |-AlignmentFile     = 'eos/lhcb/testbeam/velo/timepix3/July2015/RootFiles/Run7615/Conditions/Alignment7615mille.dat'
+# |                   (default: '')
+# |-EvtMax            = -1
+# |-WriteTuples       = False
+# |-HistogramFile     = 'Kepler-histos.root'  (default: '')
+# |-Alignment         = True  (default: False)
+# |-PixelConfigFile   = []  (default: [])
+# |-UT                = False
+# |-UserAlgorithms    = []  (default: [])
+# |-InputFiles        = ['eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/']  (default: [])
+# |-Sim               = False
+# \----- (End of User Kepler/Kepler) -----------------------------------------------------------------
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to Kepler version v3r0
+                                          running on lxplus0029.cern.ch on Fri Oct 23 16:15:34 2015
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_B05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_C05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_D05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_E05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_F05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_G05-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_H07-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0002_J06-150714-180051-7615-1.dat
+TbDataSvc            INFO Reading File: root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RawData/Run7615/W0009_G08-150714-180051-7615-1.dat
+TbGeometrySvc        INFO Importing alignment conditions from root://eoslhcb.cern.ch//eos/lhcb/testbeam/velo/timepix3/July2015/RootFiles/Run7615/Conditions/Alignment7615mille.dat
+TbGeometrySvc        INFO  0 W0002_J06           13.907     13.494      3.778      2.984      3.272      0.008
+TbGeometrySvc        INFO  1 W0002_B05           14.293     13.781     52.475      2.985      3.267      0.002
+TbGeometrySvc        INFO  2 W0002_C05           14.214     13.838     93.675      2.988      3.287     -0.001
+TbGeometrySvc        INFO  3 W0002_D05           14.067     14.101    128.900      2.991      3.295      0.006
+TbGeometrySvc        INFO  4 W0009_G08           -0.129     15.709    252.014      3.125     -0.449     -0.053
+TbGeometrySvc        INFO  5 W0002_G05           -1.083     13.560    410.853      3.266      0.166     -0.049
+TbGeometrySvc        INFO  6 W0002_F05           -0.568     13.841    443.837      3.250      0.180     -0.044
+TbGeometrySvc        INFO  7 W0002_H07            0.301     14.130    494.828      3.247      0.175     -0.045
+TbGeometrySvc        INFO  8 W0002_E05            0.289     14.324    538.655      3.233      0.180     -0.048
+RndmGenSvc.Engine    INFO Generator engine type:CLHEP::RanluxEngine
+RndmGenSvc.Engine    INFO Current Seed:1234567 Luxury:3
+RndmGenSvc           INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine>
+TimingAuditor.T...   INFO This machine has a speed about   2.71 times the speed of a 2.8 GHz Xeon.
+NTupleSvc            INFO Added stream file:Kepler-tuple.root as FILE1
+KeplerSequencer      INFO Member list: GaudiSequencer/Telescope, GaudiSequencer/Monitoring, GaudiSequencer/Output
+Telescope            INFO Member list: TbEventBuilder, TbClustering, GaudiSequencer/Tracking, TbTriggerAssociator, TbClusterAssociator, TbAlignment
+RootHistSvc          INFO Writing ROOT histograms to: Kepler-histos.root
+HistogramPersis...   INFO Added successfully Conversion service:RootHistSvc
+TbEventBuilder       INFO W0002_B05 (device 1) is mapped to plane 1
+TbEventBuilder       INFO W0002_C05 (device 2) is mapped to plane 2
+TbEventBuilder       INFO W0002_D05 (device 3) is mapped to plane 3
+TbEventBuilder       INFO W0002_E05 (device 8) is mapped to plane 8
+TbEventBuilder       INFO W0002_F05 (device 6) is mapped to plane 6
+TbEventBuilder       INFO W0002_G05 (device 5) is mapped to plane 5
+TbEventBuilder       INFO W0002_H07 (device 7) is mapped to plane 7
+TbEventBuilder       INFO W0002_J06 (device 0) is mapped to plane 0
+TbEventBuilder       INFO W0009_G08 (device 4) is mapped to plane 4
+TbEventBuilder       INFO Initialization successful - reading 73582112 packets
+Tracking             INFO Member list: TbSimpleTracking
+TbAlignment          INFO Adding tool TbMillepede
+TbAlignment.s0       INFO Using default degrees of freedom.
+Monitoring           INFO Member list: TbHitMonitor, TbClusterPlots, TbTrackPlots, TbTriggerMonitor, TbDUTMonitor
+Output               INFO Member list: 
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr       INFO Application Manager Started successfully
+TbAlignment          INFO Collected 1000 alignment tracks
+TbAlignment          INFO Collected 2000 alignment tracks
+TbAlignment          INFO Collected 3000 alignment tracks
+TbAlignment          INFO Collected 4000 alignment tracks
+TbAlignment          INFO Collected 5000 alignment tracks
+TbAlignment          INFO Collected 6000 alignment tracks
+TbAlignment          INFO Collected 7000 alignment tracks
+TbAlignment          INFO Collected 8000 alignment tracks
+TbAlignment          INFO Collected 9000 alignment tracks
+TbAlignment          INFO Collected 10000 alignment tracks
+TbAlignment.s0       INFO Millepede alignment
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78948
+TbAlignment.s0       INFO Iteration 2 (using 8825 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77975
+TbAlignment.s0       INFO Iteration 3 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 4 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 5 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 6 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 7 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 8 (using 8820 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.77973
+TbAlignment.s0       INFO Iteration 9 (using 8820 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0    -0.001165     0.000000      0.00031     -0.01165      0.98592
+TbAlignment.s0       INFO    1    -0.000497     0.000000      0.00014     -0.00497      0.93812
+TbAlignment.s0       INFO    2     0.000902    -0.000000      0.00017      0.00902      0.96087
+TbAlignment.s0       INFO    3     0.001652    -0.000000      0.00033      0.01652      0.98997
+TbAlignment.s0       INFO    4    -0.001484     0.000000      0.00026     -0.01484      0.98375
+TbAlignment.s0       INFO    5    -0.000578     0.000000      0.00021     -0.00578      0.97451
+TbAlignment.s0       INFO    6     0.000692    -0.000000      0.00018      0.00692      0.96187
+TbAlignment.s0       INFO    7     0.000477     0.000000      0.00027      0.00477      0.98050
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8     0.005849    -0.000000      0.00121      0.05849      0.99907
+TbAlignment.s0       INFO    9     0.001895    -0.000000      0.00046      0.01895      0.99415
+TbAlignment.s0       INFO   10    -0.002670     0.000000      0.00051     -0.02670      0.99557
+TbAlignment.s0       INFO   11    -0.006050     0.000000      0.00130     -0.06051      0.99934
+TbAlignment.s0       INFO   12    -0.002986    -0.000000      0.00075     -0.02986      0.99805
+TbAlignment.s0       INFO   13    -0.000231    -0.000000      0.00032     -0.00231      0.98888
+TbAlignment.s0       INFO   14     0.000478     0.000000      0.00023      0.00478      0.97670
+TbAlignment.s0       INFO   15     0.003715    -0.000000      0.00096      0.03716      0.99852
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24     0.004836    -0.000000      0.00072      0.48490      0.98199
+TbAlignment.s0       INFO   25     0.004713    -0.000000      0.00069      0.47246      0.98153
+TbAlignment.s0       INFO   26     0.004560    -0.000000      0.00067      0.45699      0.98662
+TbAlignment.s0       INFO   27     0.005067    -0.000000      0.00066      0.50782      0.98705
+TbAlignment.s0       INFO   28    -0.004147     0.000000      0.00058     -0.41540      0.99657
+TbAlignment.s0       INFO   29    -0.004262     0.000000      0.00062     -0.42707      0.99729
+TbAlignment.s0       INFO   30    -0.005032     0.000000      0.00073     -0.50454      0.99671
+TbAlignment.s0       INFO   31    -0.005735     0.000000      0.00082     -0.57544      0.99768
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32    -0.005983     0.000000      0.00096     -0.60110      0.98987
+TbAlignment.s0       INFO   33    -0.005047     0.000000      0.00080     -0.50631      0.98619
+TbAlignment.s0       INFO   34    -0.003172     0.000000      0.00058     -0.31774      0.98151
+TbAlignment.s0       INFO   35    -0.002304     0.000000      0.00044     -0.23064      0.97018
+TbAlignment.s0       INFO   36     0.003912    -0.000000      0.00057      0.39183      0.99646
+TbAlignment.s0       INFO   37     0.003743    -0.000000      0.00061      0.37501      0.99720
+TbAlignment.s0       INFO   38     0.004089    -0.000000      0.00074      0.41001      0.99681
+TbAlignment.s0       INFO   39     0.004762    -0.000000      0.00083      0.47788      0.99772
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40     0.002804    -0.000000      0.00075      0.28119      0.99996
+TbAlignment.s0       INFO   41     0.002159    -0.000000      0.00061      0.21633      0.99995
+TbAlignment.s0       INFO   42     0.001495     0.000000      0.00049      0.14966      0.99993
+TbAlignment.s0       INFO   43     0.001045     0.000000      0.00039      0.10456      0.99990
+TbAlignment.s0       INFO   44    -0.001248     0.000000      0.00039     -0.12492      0.99993
+TbAlignment.s0       INFO   45    -0.001671     0.000000      0.00048     -0.16733      0.99995
+TbAlignment.s0       INFO   46    -0.002101     0.000000      0.00062     -0.21048      0.99996
+TbAlignment.s0       INFO   47    -0.002482     0.000000      0.00073     -0.24891      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00245
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79204
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78087
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0     0.000165     0.000000      0.00029      0.00165      0.98354
+TbAlignment.s0       INFO    1     0.000074     0.000000      0.00014      0.00074      0.93508
+TbAlignment.s0       INFO    2    -0.000083    -0.000000      0.00017     -0.00083      0.95728
+TbAlignment.s0       INFO    3    -0.000231    -0.000000      0.00030     -0.00231      0.98790
+TbAlignment.s0       INFO    4     0.000018     0.000000      0.00026      0.00018      0.98303
+TbAlignment.s0       INFO    5     0.000084     0.000000      0.00021      0.00084      0.97359
+TbAlignment.s0       INFO    6    -0.000064    -0.000000      0.00018     -0.00064      0.96029
+TbAlignment.s0       INFO    7     0.000038     0.000000      0.00026      0.00038      0.97920
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8    -0.000643    -0.000000      0.00120     -0.00643      0.99906
+TbAlignment.s0       INFO    9    -0.000204    -0.000000      0.00046     -0.00204      0.99415
+TbAlignment.s0       INFO   10     0.000277     0.000000      0.00051      0.00277      0.99551
+TbAlignment.s0       INFO   11     0.000696     0.000000      0.00129      0.00696      0.99933
+TbAlignment.s0       INFO   12     0.000236     0.000000      0.00075      0.00236      0.99803
+TbAlignment.s0       INFO   13     0.000060    -0.000000      0.00032      0.00060      0.98879
+TbAlignment.s0       INFO   14    -0.000031     0.000000      0.00023     -0.00031      0.97642
+TbAlignment.s0       INFO   15    -0.000392    -0.000000      0.00096     -0.00392      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24    -0.001461    -0.000000      0.00066     -0.14646      0.98034
+TbAlignment.s0       INFO   25    -0.001289    -0.000000      0.00064     -0.12915      0.97960
+TbAlignment.s0       INFO   26    -0.001111    -0.000000      0.00062     -0.11132      0.98457
+TbAlignment.s0       INFO   27    -0.001009    -0.000000      0.00060     -0.10113      0.98461
+TbAlignment.s0       INFO   28     0.001023     0.000000      0.00054      0.10249      0.99553
+TbAlignment.s0       INFO   29     0.001130     0.000000      0.00058      0.11320      0.99649
+TbAlignment.s0       INFO   30     0.001235     0.000000      0.00066      0.12375      0.99548
+TbAlignment.s0       INFO   31     0.001483     0.000000      0.00075      0.14868      0.99675
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32     0.000883     0.000000      0.00086      0.08866      0.98852
+TbAlignment.s0       INFO   33     0.000712     0.000000      0.00073      0.07138      0.98461
+TbAlignment.s0       INFO   34     0.000446     0.000000      0.00054      0.04468      0.97995
+TbAlignment.s0       INFO   35     0.000298     0.000000      0.00043      0.02985      0.96879
+TbAlignment.s0       INFO   36    -0.000446    -0.000000      0.00053     -0.04469      0.99540
+TbAlignment.s0       INFO   37    -0.000539    -0.000000      0.00057     -0.05397      0.99638
+TbAlignment.s0       INFO   38    -0.000626    -0.000000      0.00068     -0.06273      0.99574
+TbAlignment.s0       INFO   39    -0.000729    -0.000000      0.00077     -0.07309      0.99693
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40    -0.000300    -0.000000      0.00075     -0.03010      0.99996
+TbAlignment.s0       INFO   41    -0.000230    -0.000000      0.00061     -0.02306      0.99995
+TbAlignment.s0       INFO   42    -0.000150    -0.000000      0.00049     -0.01498      0.99993
+TbAlignment.s0       INFO   43    -0.000092     0.000000      0.00039     -0.00925      0.99990
+TbAlignment.s0       INFO   44     0.000144     0.000000      0.00040      0.01440      0.99993
+TbAlignment.s0       INFO   45     0.000169     0.000000      0.00049      0.01694      0.99995
+TbAlignment.s0       INFO   46     0.000213     0.000000      0.00062      0.02137      0.99996
+TbAlignment.s0       INFO   47     0.000246     0.000000      0.00074      0.02467      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00040
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79207
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78090
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0    -0.000033     0.000000      0.00029     -0.00033      0.98414
+TbAlignment.s0       INFO    1    -0.000011     0.000000      0.00014     -0.00011      0.93599
+TbAlignment.s0       INFO    2     0.000014    -0.000000      0.00017      0.00014      0.95818
+TbAlignment.s0       INFO    3     0.000040    -0.000000      0.00031      0.00040      0.98840
+TbAlignment.s0       INFO    4     0.000006     0.000000      0.00026      0.00006      0.98317
+TbAlignment.s0       INFO    5    -0.000012     0.000000      0.00021     -0.00012      0.97377
+TbAlignment.s0       INFO    6     0.000009    -0.000000      0.00018      0.00009      0.96062
+TbAlignment.s0       INFO    7    -0.000014     0.000000      0.00026     -0.00014      0.97953
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8     0.000067    -0.000000      0.00120      0.00067      0.99906
+TbAlignment.s0       INFO    9     0.000021    -0.000000      0.00046      0.00021      0.99415
+TbAlignment.s0       INFO   10    -0.000029     0.000000      0.00051     -0.00029      0.99551
+TbAlignment.s0       INFO   11    -0.000076     0.000000      0.00129     -0.00076      0.99933
+TbAlignment.s0       INFO   12    -0.000018    -0.000000      0.00075     -0.00018      0.99804
+TbAlignment.s0       INFO   13     0.000001    -0.000000      0.00032      0.00001      0.98882
+TbAlignment.s0       INFO   14     0.000001     0.000000      0.00023      0.00001      0.97649
+TbAlignment.s0       INFO   15     0.000033    -0.000000      0.00096      0.00033      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24     0.000226    -0.000000      0.00067      0.02267      0.98090
+TbAlignment.s0       INFO   25     0.000199    -0.000000      0.00065      0.01997      0.98017
+TbAlignment.s0       INFO   26     0.000175    -0.000000      0.00063      0.01749      0.98511
+TbAlignment.s0       INFO   27     0.000156    -0.000000      0.00061      0.01563      0.98518
+TbAlignment.s0       INFO   28    -0.000137     0.000000      0.00055     -0.01368      0.99575
+TbAlignment.s0       INFO   29    -0.000176     0.000000      0.00059     -0.01764      0.99667
+TbAlignment.s0       INFO   30    -0.000199     0.000000      0.00067     -0.01992      0.99577
+TbAlignment.s0       INFO   31    -0.000245     0.000000      0.00077     -0.02452      0.99698
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32    -0.000145     0.000000      0.00089     -0.01460      0.98894
+TbAlignment.s0       INFO   33    -0.000123     0.000000      0.00075     -0.01233      0.98511
+TbAlignment.s0       INFO   34    -0.000088     0.000000      0.00055     -0.00881      0.98054
+TbAlignment.s0       INFO   35    -0.000065     0.000000      0.00043     -0.00651      0.96949
+TbAlignment.s0       INFO   36     0.000079    -0.000000      0.00054      0.00795      0.99565
+TbAlignment.s0       INFO   37     0.000096    -0.000000      0.00058      0.00965      0.99658
+TbAlignment.s0       INFO   38     0.000111    -0.000000      0.00069      0.01113      0.99601
+TbAlignment.s0       INFO   39     0.000135    -0.000000      0.00079      0.01350      0.99714
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40     0.000027    -0.000000      0.00075      0.00274      0.99996
+TbAlignment.s0       INFO   41     0.000020    -0.000000      0.00061      0.00203      0.99995
+TbAlignment.s0       INFO   42     0.000012     0.000000      0.00049      0.00117      0.99993
+TbAlignment.s0       INFO   43     0.000005     0.000000      0.00039      0.00054      0.99990
+TbAlignment.s0       INFO   44    -0.000013    -0.000000      0.00040     -0.00126      0.99993
+TbAlignment.s0       INFO   45    -0.000014    -0.000000      0.00049     -0.00142      0.99995
+TbAlignment.s0       INFO   46    -0.000018    -0.000000      0.00062     -0.00179      0.99996
+TbAlignment.s0       INFO   47    -0.000020    -0.000000      0.00074     -0.00200      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00006
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79206
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78090
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0     0.000009     0.000000      0.00029      0.00009      0.98403
+TbAlignment.s0       INFO    1     0.000003     0.000000      0.00014      0.00003      0.93583
+TbAlignment.s0       INFO    2    -0.000004    -0.000000      0.00017     -0.00004      0.95802
+TbAlignment.s0       INFO    3    -0.000011    -0.000000      0.00031     -0.00011      0.98831
+TbAlignment.s0       INFO    4    -0.000002     0.000000      0.00026     -0.00002      0.98315
+TbAlignment.s0       INFO    5     0.000002     0.000000      0.00021      0.00002      0.97374
+TbAlignment.s0       INFO    6    -0.000002    -0.000000      0.00018     -0.00002      0.96057
+TbAlignment.s0       INFO    7     0.000004     0.000000      0.00026      0.00004      0.97947
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8    -0.000010    -0.000000      0.00120     -0.00010      0.99906
+TbAlignment.s0       INFO    9    -0.000003    -0.000000      0.00046     -0.00003      0.99415
+TbAlignment.s0       INFO   10     0.000005     0.000000      0.00051      0.00005      0.99551
+TbAlignment.s0       INFO   11     0.000011     0.000000      0.00129      0.00011      0.99933
+TbAlignment.s0       INFO   12    -0.000001    -0.000000      0.00075     -0.00001      0.99803
+TbAlignment.s0       INFO   13    -0.000003    -0.000000      0.00032     -0.00003      0.98881
+TbAlignment.s0       INFO   14     0.000001     0.000000      0.00023      0.00001      0.97647
+TbAlignment.s0       INFO   15    -0.000002    -0.000000      0.00096     -0.00002      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24    -0.000048    -0.000000      0.00067     -0.00482      0.98079
+TbAlignment.s0       INFO   25    -0.000044    -0.000000      0.00065     -0.00437      0.98006
+TbAlignment.s0       INFO   26    -0.000040    -0.000000      0.00063     -0.00404      0.98501
+TbAlignment.s0       INFO   27    -0.000037    -0.000000      0.00061     -0.00372      0.98507
+TbAlignment.s0       INFO   28     0.000031     0.000000      0.00055      0.00315      0.99571
+TbAlignment.s0       INFO   29     0.000039     0.000000      0.00058      0.00389      0.99664
+TbAlignment.s0       INFO   30     0.000044     0.000000      0.00067      0.00443      0.99571
+TbAlignment.s0       INFO   31     0.000055     0.000000      0.00076      0.00549      0.99694
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32     0.000036     0.000000      0.00088      0.00357      0.98887
+TbAlignment.s0       INFO   33     0.000030     0.000000      0.00075      0.00299      0.98502
+TbAlignment.s0       INFO   34     0.000021     0.000000      0.00055      0.00208      0.98044
+TbAlignment.s0       INFO   35     0.000015     0.000000      0.00043      0.00150      0.96936
+TbAlignment.s0       INFO   36    -0.000020    -0.000000      0.00054     -0.00199      0.99561
+TbAlignment.s0       INFO   37    -0.000023    -0.000000      0.00058     -0.00230      0.99655
+TbAlignment.s0       INFO   38    -0.000027    -0.000000      0.00069     -0.00267      0.99597
+TbAlignment.s0       INFO   39    -0.000032    -0.000000      0.00078     -0.00318      0.99710
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40    -0.000002    -0.000000      0.00075     -0.00017      0.99996
+TbAlignment.s0       INFO   41    -0.000001    -0.000000      0.00061     -0.00009      0.99995
+TbAlignment.s0       INFO   42     0.000001     0.000000      0.00049      0.00005      0.99993
+TbAlignment.s0       INFO   43     0.000001     0.000000      0.00039      0.00014      0.99990
+TbAlignment.s0       INFO   44     0.000000     0.000000      0.00040      0.00003      0.99993
+TbAlignment.s0       INFO   45     0.000000     0.000000      0.00049      0.00002      0.99995
+TbAlignment.s0       INFO   46     0.000000     0.000000      0.00062      0.00002      0.99996
+TbAlignment.s0       INFO   47    -0.000000    -0.000000      0.00074     -0.00001      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00001
+TbAlignment.s0       INFO Updating geometry...
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo  ++ starts
+TbAlignment.s0       INFO                                            
+TbAlignment.s0       INFO Feeding Millepede with 10334 tracks...
+TbAlignment.s0       INFO Determining global parameters...
+TbAlignment.s0       INFO Iteration 1 (using 10334 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.79206
+TbAlignment.s0       INFO Iteration 2 (using 8828 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78090
+TbAlignment.s0       INFO Iteration 3 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 4 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 5 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 6 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 7 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 8 (using 8821 tracks)
+TbAlignment.s0       INFO Chi2 / DOF after re-fit: 1.78088
+TbAlignment.s0       INFO Iteration 9 (using 8821 tracks)
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO  Result of fit for global parameters
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    I    Difference    Last step      Error        Pull     Global corr.
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    0    -0.000002     0.000000      0.00029     -0.00002      0.98405
+TbAlignment.s0       INFO    1    -0.000001     0.000000      0.00014     -0.00001      0.93587
+TbAlignment.s0       INFO    2     0.000001    -0.000000      0.00017      0.00001      0.95806
+TbAlignment.s0       INFO    3     0.000002    -0.000000      0.00031      0.00002      0.98833
+TbAlignment.s0       INFO    4     0.000001     0.000000      0.00026      0.00001      0.98315
+TbAlignment.s0       INFO    5    -0.000000     0.000000      0.00021     -0.00000      0.97375
+TbAlignment.s0       INFO    6     0.000000    -0.000000      0.00018      0.00000      0.96058
+TbAlignment.s0       INFO    7    -0.000001     0.000000      0.00026     -0.00001      0.97949
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO    8     0.000001    -0.000000      0.00120      0.00001      0.99906
+TbAlignment.s0       INFO    9     0.000000    -0.000000      0.00046      0.00000      0.99415
+TbAlignment.s0       INFO   10    -0.000001     0.000000      0.00051     -0.00001      0.99551
+TbAlignment.s0       INFO   11    -0.000001     0.000000      0.00129     -0.00001      0.99933
+TbAlignment.s0       INFO   12     0.000001    -0.000000      0.00075      0.00001      0.99803
+TbAlignment.s0       INFO   13     0.000001    -0.000000      0.00032      0.00001      0.98881
+TbAlignment.s0       INFO   14    -0.000000     0.000000      0.00023     -0.00000      0.97648
+TbAlignment.s0       INFO   15    -0.000000    -0.000000      0.00096     -0.00000      0.99851
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   16          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   17          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   18          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   19          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   20          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   21          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   22          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO   23          OFF          OFF          OFF          OFF          OFF
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   24     0.000011    -0.000000      0.00067      0.00107      0.98081
+TbAlignment.s0       INFO   25     0.000010    -0.000000      0.00065      0.00097      0.98008
+TbAlignment.s0       INFO   26     0.000009    -0.000000      0.00063      0.00088      0.98503
+TbAlignment.s0       INFO   27     0.000008    -0.000000      0.00061      0.00080      0.98510
+TbAlignment.s0       INFO   28    -0.000007     0.000000      0.00055     -0.00070      0.99572
+TbAlignment.s0       INFO   29    -0.000008     0.000000      0.00058     -0.00085      0.99665
+TbAlignment.s0       INFO   30    -0.000010     0.000000      0.00067     -0.00097      0.99573
+TbAlignment.s0       INFO   31    -0.000012     0.000000      0.00076     -0.00120      0.99695
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   32    -0.000007     0.000000      0.00088     -0.00073      0.98888
+TbAlignment.s0       INFO   33    -0.000006     0.000000      0.00075     -0.00061      0.98504
+TbAlignment.s0       INFO   34    -0.000004     0.000000      0.00055     -0.00043      0.98046
+TbAlignment.s0       INFO   35    -0.000003     0.000000      0.00043     -0.00031      0.96939
+TbAlignment.s0       INFO   36     0.000004    -0.000000      0.00054      0.00041      0.99562
+TbAlignment.s0       INFO   37     0.000005    -0.000000      0.00058      0.00047      0.99656
+TbAlignment.s0       INFO   38     0.000005    -0.000000      0.00069      0.00055      0.99598
+TbAlignment.s0       INFO   39     0.000007    -0.000000      0.00078      0.00066      0.99711
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO   40    -0.000000    -0.000000      0.00075     -0.00002      0.99996
+TbAlignment.s0       INFO   41    -0.000000    -0.000000      0.00061     -0.00003      0.99995
+TbAlignment.s0       INFO   42    -0.000000    -0.000000      0.00049     -0.00005      0.99993
+TbAlignment.s0       INFO   43    -0.000001     0.000000      0.00039     -0.00006      0.99990
+TbAlignment.s0       INFO   44     0.000000     0.000000      0.00040      0.00002      0.99993
+TbAlignment.s0       INFO   45     0.000000     0.000000      0.00049      0.00003      0.99995
+TbAlignment.s0       INFO   46     0.000000     0.000000      0.00062      0.00004      0.99996
+TbAlignment.s0       INFO   47     0.000001     0.000000      0.00074      0.00006      0.99997
+TbAlignment.s0       INFO -------------------------------------------------------------------------------------
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO             * o o                   o      
+TbAlignment.s0       INFO               o o                   o      
+TbAlignment.s0       INFO    o ooooo  o o o  oo  ooo   oo   ooo  oo  
+TbAlignment.s0       INFO     o  o  o o o o o  o o  o o  o o  o o  o 
+TbAlignment.s0       INFO     o  o  o o o o oooo o  o oooo o  o oooo 
+TbAlignment.s0       INFO     o  o  o o o o o    ooo  o    o  o o    
+TbAlignment.s0       INFO     o  o  o o o o  oo  o     oo   ooo  oo ++ ends.
+TbAlignment.s0       INFO                        o                   
+TbAlignment.s0       INFO 
+TbAlignment.s0       INFO Convergence: 0.00000
+TbAlignment.s0       INFO Updating geometry...
+EventLoopMgr      SUCCESS Terminating event processing loop due to scheduled stop
+ApplicationMgr       INFO Application Manager Stopped successfully
+TbEventBuilder       INFO Plane  0:      7103600 packets in file,         4466 hits in cache
+TbEventBuilder       INFO Plane  1:      6064648 packets in file,         3775 hits in cache
+TbEventBuilder       INFO Plane  2:      6492004 packets in file,         4013 hits in cache
+TbEventBuilder       INFO Plane  3:      6557011 packets in file,         4740 hits in cache
+TbEventBuilder       INFO Plane  4:     22003178 packets in file,        12613 hits in cache
+TbEventBuilder       INFO Plane  5:      6616512 packets in file,         4227 hits in cache
+TbEventBuilder       INFO Plane  6:      6256693 packets in file,         4015 hits in cache
+TbEventBuilder       INFO Plane  7:      6298052 packets in file,         4097 hits in cache
+TbEventBuilder       INFO Plane  8:      6190414 packets in file,         3891 hits in cache
+TbEventBuilder       INFO Fraction of data read: 0.00876674
+TbEventBuilder       INFO Number of packets lost: 0
+TbEventBuilder       INFO Unknown packets: 373
+TbEventBuilder       INFO Skipped 1961 noise events.
+TbClustering      SUCCESS Number of counters : 9
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfClusters0"                             |        36 |      14064 |     390.67 |     247.79 |      1.0000 |      778.00 |
+ | "NumberOfClusters1"                             |        36 |      14127 |     392.42 |     251.75 |      1.0000 |      795.00 |
+ | "NumberOfClusters2"                             |        36 |      14275 |     396.53 |     253.90 |      1.0000 |      802.00 |
+ | "NumberOfClusters3"                             |        36 |      14413 |     400.36 |     257.82 |      1.0000 |      810.00 |
+ | "NumberOfClusters4"                             |        36 |       4080 |     113.33 |     72.239 |      0.0000 |      244.00 |
+ | "NumberOfClusters5"                             |        36 |      16099 |     447.19 |     287.03 |      1.0000 |      903.00 |
+ | "NumberOfClusters6"                             |        36 |      15491 |     430.31 |     275.64 |      1.0000 |      862.00 |
+ | "NumberOfClusters7"                             |        36 |      15212 |     422.56 |     269.76 |      1.0000 |      842.00 |
+ | "NumberOfClusters8"                             |        36 |      15040 |     417.78 |     268.17 |      1.0000 |      843.00 |
+TbSimpleTracking  SUCCESS Number of counters : 1
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "NumberOfTracks"                                |        36 |      13965 |     387.92 |     248.52 |      1.0000 |      791.00 |
+TbAlignment          INFO Writing alignment output file to Alignment_out.dat
+TbHitMonitor      SUCCESS Booked 45 Histogram(s) : 1D=36 2D=9 
+TbClusterPlots    SUCCESS Booked 247 Histogram(s) : 1D=182 2D=65 
+TbClusterPlots    SUCCESS Number of counters : 9
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ |*"effFractionAssociated0"                        |     14064 |      12194 |(  86.7036 +- 0.286306 )%|   -------   |   -------   |
+ |*"effFractionAssociated1"                        |     14127 |      13965 |(  98.8533 +- 0.0895784)%|   -------   |   -------   |
+ |*"effFractionAssociated2"                        |     14275 |      13375 |(  93.6953 +- 0.203425 )%|   -------   |   -------   |
+ |*"effFractionAssociated3"                        |     14413 |      13355 |(  92.6594 +- 0.217237 )%|   -------   |   -------   |
+ |*"effFractionAssociated4"                        |      4080 |          0 |(  0.00000 +- 0.0245098)%|   -------   |   -------   |
+ |*"effFractionAssociated5"                        |     16099 |      13320 |(  82.7381 +- 0.297850 )%|   -------   |   -------   |
+ |*"effFractionAssociated6"                        |     15491 |      13309 |(  85.9144 +- 0.279499 )%|   -------   |   -------   |
+ |*"effFractionAssociated7"                        |     15212 |      13291 |(  87.3718 +- 0.269317 )%|   -------   |   -------   |
+ |*"effFractionAssociated8"                        |     15040 |      13284 |(  88.3245 +- 0.261851 )%|   -------   |   -------   |
+TbTrackPlots      SUCCESS Booked 214 Histogram(s) : 1D=106 2D=99 1DProf=9 
+TbTriggerMonitor  SUCCESS Booked 19 Histogram(s) : 1D=19 
+ToolSvc              INFO Removing all tools created by ToolSvc
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO This machine has a speed about   2.71 times the speed of a 2.8 GHz Xeon.
+TimingAuditor.T...   INFO Algorithm          (millisec) |    <user> |   <clock> |      min       max | entries | total (s) |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+TimingAuditor.T...   INFO EVENT LOOP                    |   954.938 |   974.860 |    0.821   32348.9 |      36 |    35.095 |
+TimingAuditor.T...   INFO  KeplerSequencer              |   954.633 |   974.483 |    0.790   32337.6 |      36 |    35.081 |
+TimingAuditor.T...   INFO   Telescope                   |   914.916 |   932.157 |    0.409   32279.9 |      36 |    33.558 |
+TimingAuditor.T...   INFO    TbEventBuilder             |     7.999 |     8.227 |    0.139      37.8 |      36 |     0.296 |
+TimingAuditor.T...   INFO    TbClustering               |    14.637 |    15.324 |    0.094     110.2 |      36 |     0.552 |
+TimingAuditor.T...   INFO    Tracking                   |     2.333 |     2.317 |    0.035       6.8 |      36 |     0.083 |
+TimingAuditor.T...   INFO     TbSimpleTracking          |     2.333 |     2.308 |    0.030       6.8 |      36 |     0.083 |
+TimingAuditor.T...   INFO    TbTriggerAssociator        |     0.028 |     0.040 |    0.018       0.1 |      36 |     0.001 |
+TimingAuditor.T...   INFO    TbClusterAssociator        |     0.000 |     0.006 |    0.002       0.0 |      36 |     0.000 |
+TimingAuditor.T...   INFO    TbAlignment                |   889.893 |   906.207 |    0.009   32256.8 |      36 |    32.623 |
+TimingAuditor.T...   INFO   Monitoring                  |    39.688 |    42.302 |    0.372      85.9 |      36 |     1.523 |
+TimingAuditor.T...   INFO    TbHitMonitor               |     3.111 |     3.488 |    0.043       8.0 |      36 |     0.126 |
+TimingAuditor.T...   INFO    TbClusterPlots             |     9.693 |     9.909 |    0.126      21.1 |      36 |     0.357 |
+TimingAuditor.T...   INFO    TbTrackPlots               |    26.718 |    28.796 |    0.162      61.9 |      36 |     1.037 |
+TimingAuditor.T...   INFO    TbTriggerMonitor           |     0.028 |     0.035 |    0.020       0.1 |      36 |     0.001 |
+TimingAuditor.T...   INFO    TbDUTMonitor               |     0.083 |     0.035 |    0.004       0.1 |      36 |     0.001 |
+TimingAuditor.T...   INFO   Output                      |     0.000 |     0.012 |    0.001       0.3 |      36 |     0.000 |
+TimingAuditor.T...   INFO --------------------------------------------------------------------------------------------------
+ApplicationMgr       INFO Application Manager Finalized successfully
+ApplicationMgr       INFO Application Manager Terminated successfully with a user requested ScheduledStop
diff --git a/TbAlgorithms/.svn/all-wcprops b/TbAlgorithms/.svn/all-wcprops
new file mode 100644
index 0000000..6f3af73
--- /dev/null
+++ b/TbAlgorithms/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/188478/Kepler/trunk/Tb/TbAlgorithms/CMakeLists.txt
+END
diff --git a/TbAlgorithms/.svn/entries b/TbAlgorithms/.svn/entries
new file mode 100644
index 0000000..60ff9c6
--- /dev/null
+++ b/TbAlgorithms/.svn/entries
@@ -0,0 +1,71 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlgorithms
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+src
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:45.000000Z
+f5218081c2c825641907cec36b05731d
+2015-05-19T09:45:57.825354Z
+188478
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+563
+
diff --git a/TbAlgorithms/.svn/text-base/CMakeLists.txt.svn-base b/TbAlgorithms/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..5a872d9
--- /dev/null
+++ b/TbAlgorithms/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,16 @@
+################################################################################
+# Package: TbAlgorithms
+################################################################################
+gaudi_subdir(TbAlgorithms v2r2)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS Minuit MathCore GenVector)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbAlgorithms
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbAlgorithms/CMakeLists.txt b/TbAlgorithms/CMakeLists.txt
new file mode 100644
index 0000000..5a872d9
--- /dev/null
+++ b/TbAlgorithms/CMakeLists.txt
@@ -0,0 +1,16 @@
+################################################################################
+# Package: TbAlgorithms
+################################################################################
+gaudi_subdir(TbAlgorithms v2r2)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS Minuit MathCore GenVector)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbAlgorithms
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbAlgorithms/cmt/.svn/all-wcprops b/TbAlgorithms/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..a2c55b1
--- /dev/null
+++ b/TbAlgorithms/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/188478/Kepler/trunk/Tb/TbAlgorithms/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/188478/Kepler/trunk/Tb/TbAlgorithms/cmt/requirements
+END
diff --git a/TbAlgorithms/cmt/.svn/entries b/TbAlgorithms/cmt/.svn/entries
new file mode 100644
index 0000000..ef2f036
--- /dev/null
+++ b/TbAlgorithms/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlgorithms/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T09:45:57.825354Z
+188478
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+1da44bf6930357f55d3f611477b8cb49
+2015-05-19T09:45:57.825354Z
+188478
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+728
+
diff --git a/TbAlgorithms/cmt/.svn/text-base/requirements.svn-base b/TbAlgorithms/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..bfdb0a8
--- /dev/null
+++ b/TbAlgorithms/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,20 @@
+package TbAlgorithms 
+version v2r2
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+use  Boost        v*  LCG_Interfaces
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbAlgorithms    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbAlgorithms
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append Boost_linkopts $(Boost_linkopts_iostreams)
+macro_append ROOT_linkopts " -lMinuit -lHist -lPhysics"
diff --git a/TbAlgorithms/cmt/requirements b/TbAlgorithms/cmt/requirements
new file mode 100644
index 0000000..bfdb0a8
--- /dev/null
+++ b/TbAlgorithms/cmt/requirements
@@ -0,0 +1,20 @@
+package TbAlgorithms 
+version v2r2
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+use  Boost        v*  LCG_Interfaces
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbAlgorithms    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbAlgorithms
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append Boost_linkopts $(Boost_linkopts_iostreams)
+macro_append ROOT_linkopts " -lMinuit -lHist -lPhysics"
diff --git a/TbAlgorithms/doc/.svn/all-wcprops b/TbAlgorithms/doc/.svn/all-wcprops
new file mode 100644
index 0000000..731f0a7
--- /dev/null
+++ b/TbAlgorithms/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/doc/release.notes
+END
diff --git a/TbAlgorithms/doc/.svn/entries b/TbAlgorithms/doc/.svn/entries
new file mode 100644
index 0000000..6dfc4fc
--- /dev/null
+++ b/TbAlgorithms/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlgorithms/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+f64b43966706f96af1373505fb37fe87
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13725
+
diff --git a/TbAlgorithms/doc/.svn/text-base/release.notes.svn-base b/TbAlgorithms/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..65853a4
--- /dev/null
+++ b/TbAlgorithms/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,381 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbAlgorithms
+! Responsible :
+! Purpose     : Algorithms for Timepix3 testbeam analysis
+!-----------------------------------------------------------------------------
+
+! 2016-02-23 - Heinrich Schindler
+ - TbClustering: apply eta corrections if available.
+ - TbSimpleTracking: add option to remove outliers from a candidate track.
+
+! 2016-02-04 - Heinrich Schindler
+ - TbClustering: assign different cluster errors depending on the 
+   number of rows/columns covered by the cluster.
+ - TbSimpleTracking: add cut on max. cluster width,
+   deactivate monitoring by default.
+
+! 2016-01-31 - Heinrich Schindler
+ - TbClustering: move timing histograms to TbClusterPlots. 
+ - TbClusterAssociator: add track chi2 cut.
+
+! 2016-01-28 - Heinrich Schindler
+ - TbHitMonitor: add profile histograms of ToT/charge as function of column.
+ - TbClusterPlots: add ToT histograms.
+
+! 2016-01-26 - Heinrich Schindler
+ - TbSimpleTracking: apply charge and cluster size cuts also at seeding stage.
+
+! 2015-12-14 - Heinrich Schindler
+ - Add options to TbClusterAssociator to use hit or cluster coordinates and
+   to skip used clusters.
+ 
+! 2015-12-02 - Tim Evans
+ - Add new synchronisation method to TbCalibration.
+
+! 2015-11-12 - Dan Saunders
+ - Update default settings for clustering and tracking. 
+ - Add new cuts and function to recover missed hits to TbSimpleTracking.
+
+! 2015-10-29 - Heinrich Schindler
+ - Speed up TbClustering.
+
+! 2015-10-23 - Heinrich Schindler
+ - Fix compiler warnings uncovered by clang (signed vs unsigned int).
+
+!========================= TbAlgorithms v2r2 2015-05-19 =======================
+
+! 2015-05-19 - Heinrich Schindler
+ - Undo latest changes to TbAlignment. To be put back after the release.
+
+! 2015-05-18 - Tim Evans
+ - Added new features to the alignment, can run multiple alignment 
+   algorithms from the same job
+ - Added DeviceSurvey alignment algorithm, that uses time alignment 
+   to survey align a single device (i.e. the DuT)
+ - Options to only use a single trigger channel in the trigger 
+   associator
+
+! 2015-03-24 - Heinrich Schindler
+ - Add property TrackFitTool to TbTrackPlots, TbAlignment, TbTracking, 
+   TbSimpleTracking, TbVertexTracking.
+ - Small speed ups in TbTrackVolume and TbTracking.
+
+! 2015-03-09 - Heinrich Schindler
+ - Add TbDUTMonitor.
+ - TbTracking: avoid new/delete of TbTrackVolume for each seed cluster.
+
+! 2015-03-05 - Heinrich Schindler
+ - TbClusterPlots: bugfix in cluster width plot.
+ - TbTrackPlots: fix tracking efficiency plot titles.
+
+! 2015-03-03 - Heinrich Schindler
+ - Fix typo in previous commit.
+ - Allow tracking algorithms to pick up existing track containers 
+   (in case of multiple pattern recognition instances).
+
+! 2015-03-02 - Heinrich Schindler
+ - Tidy up TbAlignment (bug fix in technique 3, specify device to align and 
+   reference plane by plane index instead of device ID).
+
+! 2015-01-26 - Heinrich Schindler
+ - TbAlignment: remove unused class members.
+ - TbClustering: use scol instead of col in hitTouchesCluster. 
+
+! 2015-01-24 - Heinrich Schindler
+ - TbAlignment: pick up clusters in TbTrack::associatedClusters for technique 3.
+ - TbHitMonitor: plot scol instead of col in hit map.
+
+! 2015-01-21 - Heinrich Schindler
+ - TbClustering: use pixelToPosition function of TbGeometrySvc to 
+   compute the local cluster position.
+ - Fix bug in TbClusterPlots pointed out by Panos.
+ - Use TbHit::charge instead of ToT to compute the cluster charge.
+
+! 2015-01-20 - Heinrich Schindler
+ - Add algorithm TbClusterAssociator.
+
+! 2014-12-30 - Heinrich Schindler
+ - TbTrackVolume: remove unused functions and variables, 
+   separate public and private members, tag associated clusters in TbTracking.
+
+! 2014-12-28 - Heinrich Schindler
+ - Follow removal of TbCluster::endCluster, vertexed, volumed.
+
+! 2014-12-13 - Heinrich Schindler
+ - TbAlignment: add alignment technique 3 (similar to technique 2 but without 
+   requiring the device to align to be in the tracking. 
+
+! 2014-12-13 - Heinrich Schindler
+ - TbMillepede: use values instead of pointers for class members, 
+   remove unused variables.
+
+! 2014-12-12 - Heinrich Schindler
+ - Follow renaming of TbHit::plane to TbHit::device.
+
+! 2014-12-07 - Heinrich Schindler
+ - TbClustering: add member m_used to keep track of which hits are clustered.
+
+!========================= TbAlgorithms v2r1 2014-11-30 =======================
+
+! 2014-11-30 - Heinrich Schindler
+ - Convert TbMillepede to a Gaudi tool.
+
+! 2014-11-20 - Heinrich Schindler
+ - Convert TbClusterFinder to a Gaudi tool and move it to TbKernel.
+
+! 2014-11-11 - Dan Saunders
+ - Add TbVertexTracking.
+
+! 2014-10-26 - Dan Saunders
+ - Add efficiency calculation algorithm.
+
+! 2014-10-08 - Tim Evans
+ - Added simple algorithm TbCalibration which takes histograms from the 
+   tracking and the hitmonitor and produces pixel masks and per plane
+   time calibration constants
+
+! 2014-09-26 - Dan Saunders
+ - Added simple estimates of cluster position errors, and incorporated into 
+   TbTrackFit.
+ - Added optional new pattern recognition shape "sqDiabolo" (not yet default). 
+
+! 2014-09-19 - Heinrich Schindler
+ - Fix in TbAlignment technique 2 (use only clusters on device to align for
+   chi2 calculation).
+
+! 2014-08-26 - Christoph Hombach
+ - Improvements to MILLEPEDE
+
+!========================= TbAlgorithms v2r0 2014-08-18 =======================
+
+! 2014-08-15 - Heinrich Schindler
+ - Move spatial efficiency calculation in TbClusterPlots to external script. 
+ - Remove unused class TbAlignmentPlots.
+ - Fix compiler warning in TbAlignment (replace array by vector).
+
+! 2014-08-04 - Heinrich Schindler
+ - Sort clusters on track by z-position.
+
+! 2014-08-03 - Angelo Di Canto
+ - Minor update to TbAlignment (more configurable properties)
+
+! 2014-08-02 - Dan Saunders
+ - Fixed TbClustering inefficiency (now as good as previous slower version).
+
+! 2014-08-02 - Heinrich Schindler
+ - More residual plots for Paula.
+
+! 2014-08-01 - Dan Saunders  
+  - Updated TbClustering for speed/
+  - Extra plots (pull distributions) to TbTrackPlots.
+
+! 2014-08-01 - Christoph Hombach        
+  - Added alignment monitoring plots to TbTrackPlots
+  
+! 2014-07-30 - Christoph Hombach
+  - Update Millepede
+  
+! 2014-07-31 - Dan Saunders
+  - Changed default ordering of cluster hits to increasing in TOA.
+  - Added a few extra plots to TbTrackPlots.
+  - Updated example.py to use run1024 (assuming eos is mounted). 
+
+! 2014-07-29 - Heinrich Schindler
+ - Add TbTriggerAssociator.
+
+! 2014-07-21 - Christop Hombach
+ - Added residual plots, which can be called after alignment procedure in TbAlignment
+
+! 2014-07-21 - Tim Evans
+ - Added trigger data packets
+
+! 2014-07-21 - Angelo Di Canto
+ - Added checks for masked planes in TbAlignment
+ - Millepede renamed into TbMillepede
+ 
+! 2014-07-19 - Heinrich Schindler
+ - Add TbHeaderDecoder tool which reads and optionally dumps the Spidr header.
+ - TbEventBuilder: retrieve device ID from header and check if it matches 
+   with the alignment file.  
+ - Move TbAlgorithm to TbKernel.
+ - Millepede: clang-format and other cosmetic changes.
+
+! 2014-07-18 Christoph Hombach
+ - Removed DUT from Millepede fit -> Next step DUT separate 
+ - Added shell script to run alignment loop
+
+! 2014-07-18 - Heinrich Schindler
+ - Use htime instead of global time for time windows.
+
+! 2014-07-17 - Christoph Hombach
+ - Working implementation of Millepede
+ - Need to clean up code....
+
+! 2014-07-17 - Tim Evans
+ - Added extended timestamp functionality
+ - Added option to manually set the header size
+
+! 2014-07-14 - Dan Saunders
+ - Added hit maps to TbTrackPlots. 
+ - Few temporary additions to TbEventBuilder (all commented out), present for
+   DQM testing.
+ 
+! 2014-07-14 - Heinrich Schindler
+ - Add new class TbAlgorithm (base class for other testbeam algorithms).
+ 
+ ! 2014-07-14 - Dan Saunders
+ - New plots to TbTrackPlots, and separated filling into separate functions
+   for different categories of plot.
+ - New option in TbTracking to ignore listed planes during tracking.
+
+! 2014-07-09 - Heinrich Schindler
+ - Speed improvements in TbClusterFinder.
+ - TbClusterPlots: add configurable histogram parameters, 
+   histogram labels.
+ - TbTrackPlots: configurable histograms, add local residual plots. 
+
+! 2014-07-08 - Hella Snoek
+ - Added option to search for hits further away in TbClustering.
+ - Added some printout statements to info printing the configurables.
+
+! 2014-07-08 - Dan Saunders
+ - Added safety checks for using TbClusterFinder with empty planes.
+
+! 2014-07-08 - Heinrich Schindler
+ - Adapt TbTupleWriter to new TES locations.
+ - TbTracking: use Gaudi counter for nbr. of tracks; inline geomSvc; 
+   initialize planeSearchOrder directly.
+ - Follow renaming from "chip" to "plane" in TbHit and TbCluster.
+ - Run clang-format.
+ - Member functions to start consistently with lower case letter.
+ - Separate hit monitor histograms for each plane.
+ - Add one/two/three/four-pixel cluster ToT distributions to TbClusterPlots.
+
+! 2014-07-07 - Tim Evans
+ - Updated TbEventBuilder to use different TES locations for the different 
+   chips.
+
+! 2014-07-07 - Heinrich Schindler
+ - Fix compiler warnings in TbAlignmentPlots and TbAlignment.
+ - Update TbAlignment survey method to work with separate TES cluster locations.
+ 
+! 2014-07-07 - Dan Saunders
+ - Updated tracking and clustering to use different TES locations for hits and
+   clusters on different chips. 
+
+! 2014-07-04 - Dan Saunders
+ - Tidied up TbTrackPlots and TbClusterPlots
+ - Allowed for varying track sizes - minimum number of clusters set by 
+   TbTracking().MinNClusters = 5. Priority is given to more complete tracks.
+
+! 2014-07-03 - Angelo Di Canto 
+ - Speed improvements in TbAlignment
+ - Fixed bug in definition of alignment constants in TbAlignment
+
+! 2014-07-01 - Angelo Di Canto 
+ - Fixed few typos/bugs in TbAlignment
+
+! 2014-07-01 - Dan Saunders
+ - Tidied up TbTracking.
+
+! 2014-07-01 - Heinrich Schindler
+ - Add samples plot to TbClusterPlots.
+
+! 2014-06-30 - Heinrich Schindler
+ - TbClustering: remove monitoring plots (to be added to TbClusterPlots);
+   merge some short functions; use STL sort.
+
+! 2014-06-27 - Tim Evans
+ - Added reading of the header classes to TbEventBuilder
+ - Added TbRawFile class as a wrapper for input files to cleanup eventbuilder
+ - Moved raw bank decoding into event definitions
+ - Fixed read order dependence
+
+! 2014-06-25 - Heinrich Schindler
+ - Reduce finalise output of TbTupleWriter.
+ - Delete alignment tracks in destructor of TbAlignment.
+ - TbClustering: consistent definition of local and global coordinates.
+ - Fix compiler warnings.
+
+! 2014-06-19 - Heinrich Schindler
+ - Add TbTupleWriter.
+
+! 2014-06-16 - Dan Saunders
+ - Speed improvements in TbTracking.
+
+! 2014-06-06 - Heinrich Schindler
+ - TbHitMonitor: fix binning in 2D hitmap.
+
+!========================= TbAlgorithms v1r0 2014-05-30 =======================
+
+! 2014-05-29 - Heinrich Schindler
+ - Initialise geometry service pointers to NULL in constructor.
+ - TbEventBuilder::finalize: empty cache, close files.
+ - TbTracking: Get the number of planes from the geometry service.
+ - TbAlignment: change return value of techniqueX from StatusCode to bool.
+ - Follow renaming of chip_num to chip in TbCluster.
+ - Mask (for now) unused variable warnings in TbTrackVolume.
+ - Move TbTestMC and TbTrackFitter to Tb/TbSimulation.
+ 
+! 2014-05-28 - Heinrich Schindler
+ - TbTestMC: use Gaudi random number generators instead of TRandom3.
+ - Call finalize functions of actual base classes.
+ - Trivial formatting changes.
+
+! 2014-05-26 - Heinrich Schindler
+ - TbClustering: add new clusters directly to TbClusters container.
+ - TbTracking: idem; also use on-demand booking of histograms.
+
+! 2014-05-24 - Heinrich Schindler
+ - Follow changes in event classes; cosmetic modifications.
+ - Fix compiler warning in TbTrackFitter.
+ - TbEventBuilder: allow processing of all files in a given directory.
+
+! 2014-05-23 - Panagiotis Tsopelas
+ - In TbAlignment.cpp, TbTrackFitter, TbTrackPlots : 
+   Renamed "chi2" -> "chi2PerNdof" after change in TbTrack
+   Changed  every call to a first state parameter (x0, y0, tx, ty)
+   to a call through the "firstState" 
+
+! 2014-05-21 - Heinrich Schindler
+ - Fix signed/unsigned comparison compiler warnings.
+ - Transfer ownership to TES ("put") directly after newing.
+ - Remove unnecessary include statements.
+ - Remove setters/getters from algorithms (use declareProperty instead). 
+ - TbEventBuilder: change return type of retrieve function to bool 
+   and make it private.
+ - Run clang-format.
+ - TbEventBuilder, TbHitMonitor: add header guards
+ - Remove do-nothing finalize methods.
+
+! 2014-05-15 - Dan Saunders
+ - Added MC genorator and first version of tracking. This including a plot object
+   and prototype track object (TbTrackVolume) used during the track finding.
+   
+ - Clustering also updated to consider hits separated diagonally.
+
+! 2014-05-15 - Marco Clemencic
+ - Fixed CMake configuration.
+
+! 2014-05-06 - Panagiotis Tsopelas
+
+ - Added TbTrackFitter. In this class random cluster positions are assigned to the planes
+   and pseudoTbTracks are formed. Then the TbTrackFit::fit() method is called to fit the 
+   TbTracks. Residuals are also calculated.
+
+! 2014-04-29 - Dan Saunders
+ - Updated TbClustering
+ - Added a TbClusterPlots object - note: need to change local positions to global
+
+! 2014-04-11 - Heinrich Schindler
+ - TbEventBuilder: call stopRun after reaching end of file
+ - Run clang-format to get consistent formatting
+ - Change get to getIfExists
+ - Remove do-nothing finalize method
+
+! 2014-04-02 - Tim Evans
+ - Added TbEventBuilder and TbHitMonitor classes
+
+! 2014-03-31 - Heinrich Schindler
+ - Initial import
+
diff --git a/TbAlgorithms/doc/release.notes b/TbAlgorithms/doc/release.notes
new file mode 100644
index 0000000..65853a4
--- /dev/null
+++ b/TbAlgorithms/doc/release.notes
@@ -0,0 +1,381 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbAlgorithms
+! Responsible :
+! Purpose     : Algorithms for Timepix3 testbeam analysis
+!-----------------------------------------------------------------------------
+
+! 2016-02-23 - Heinrich Schindler
+ - TbClustering: apply eta corrections if available.
+ - TbSimpleTracking: add option to remove outliers from a candidate track.
+
+! 2016-02-04 - Heinrich Schindler
+ - TbClustering: assign different cluster errors depending on the 
+   number of rows/columns covered by the cluster.
+ - TbSimpleTracking: add cut on max. cluster width,
+   deactivate monitoring by default.
+
+! 2016-01-31 - Heinrich Schindler
+ - TbClustering: move timing histograms to TbClusterPlots. 
+ - TbClusterAssociator: add track chi2 cut.
+
+! 2016-01-28 - Heinrich Schindler
+ - TbHitMonitor: add profile histograms of ToT/charge as function of column.
+ - TbClusterPlots: add ToT histograms.
+
+! 2016-01-26 - Heinrich Schindler
+ - TbSimpleTracking: apply charge and cluster size cuts also at seeding stage.
+
+! 2015-12-14 - Heinrich Schindler
+ - Add options to TbClusterAssociator to use hit or cluster coordinates and
+   to skip used clusters.
+ 
+! 2015-12-02 - Tim Evans
+ - Add new synchronisation method to TbCalibration.
+
+! 2015-11-12 - Dan Saunders
+ - Update default settings for clustering and tracking. 
+ - Add new cuts and function to recover missed hits to TbSimpleTracking.
+
+! 2015-10-29 - Heinrich Schindler
+ - Speed up TbClustering.
+
+! 2015-10-23 - Heinrich Schindler
+ - Fix compiler warnings uncovered by clang (signed vs unsigned int).
+
+!========================= TbAlgorithms v2r2 2015-05-19 =======================
+
+! 2015-05-19 - Heinrich Schindler
+ - Undo latest changes to TbAlignment. To be put back after the release.
+
+! 2015-05-18 - Tim Evans
+ - Added new features to the alignment, can run multiple alignment 
+   algorithms from the same job
+ - Added DeviceSurvey alignment algorithm, that uses time alignment 
+   to survey align a single device (i.e. the DuT)
+ - Options to only use a single trigger channel in the trigger 
+   associator
+
+! 2015-03-24 - Heinrich Schindler
+ - Add property TrackFitTool to TbTrackPlots, TbAlignment, TbTracking, 
+   TbSimpleTracking, TbVertexTracking.
+ - Small speed ups in TbTrackVolume and TbTracking.
+
+! 2015-03-09 - Heinrich Schindler
+ - Add TbDUTMonitor.
+ - TbTracking: avoid new/delete of TbTrackVolume for each seed cluster.
+
+! 2015-03-05 - Heinrich Schindler
+ - TbClusterPlots: bugfix in cluster width plot.
+ - TbTrackPlots: fix tracking efficiency plot titles.
+
+! 2015-03-03 - Heinrich Schindler
+ - Fix typo in previous commit.
+ - Allow tracking algorithms to pick up existing track containers 
+   (in case of multiple pattern recognition instances).
+
+! 2015-03-02 - Heinrich Schindler
+ - Tidy up TbAlignment (bug fix in technique 3, specify device to align and 
+   reference plane by plane index instead of device ID).
+
+! 2015-01-26 - Heinrich Schindler
+ - TbAlignment: remove unused class members.
+ - TbClustering: use scol instead of col in hitTouchesCluster. 
+
+! 2015-01-24 - Heinrich Schindler
+ - TbAlignment: pick up clusters in TbTrack::associatedClusters for technique 3.
+ - TbHitMonitor: plot scol instead of col in hit map.
+
+! 2015-01-21 - Heinrich Schindler
+ - TbClustering: use pixelToPosition function of TbGeometrySvc to 
+   compute the local cluster position.
+ - Fix bug in TbClusterPlots pointed out by Panos.
+ - Use TbHit::charge instead of ToT to compute the cluster charge.
+
+! 2015-01-20 - Heinrich Schindler
+ - Add algorithm TbClusterAssociator.
+
+! 2014-12-30 - Heinrich Schindler
+ - TbTrackVolume: remove unused functions and variables, 
+   separate public and private members, tag associated clusters in TbTracking.
+
+! 2014-12-28 - Heinrich Schindler
+ - Follow removal of TbCluster::endCluster, vertexed, volumed.
+
+! 2014-12-13 - Heinrich Schindler
+ - TbAlignment: add alignment technique 3 (similar to technique 2 but without 
+   requiring the device to align to be in the tracking. 
+
+! 2014-12-13 - Heinrich Schindler
+ - TbMillepede: use values instead of pointers for class members, 
+   remove unused variables.
+
+! 2014-12-12 - Heinrich Schindler
+ - Follow renaming of TbHit::plane to TbHit::device.
+
+! 2014-12-07 - Heinrich Schindler
+ - TbClustering: add member m_used to keep track of which hits are clustered.
+
+!========================= TbAlgorithms v2r1 2014-11-30 =======================
+
+! 2014-11-30 - Heinrich Schindler
+ - Convert TbMillepede to a Gaudi tool.
+
+! 2014-11-20 - Heinrich Schindler
+ - Convert TbClusterFinder to a Gaudi tool and move it to TbKernel.
+
+! 2014-11-11 - Dan Saunders
+ - Add TbVertexTracking.
+
+! 2014-10-26 - Dan Saunders
+ - Add efficiency calculation algorithm.
+
+! 2014-10-08 - Tim Evans
+ - Added simple algorithm TbCalibration which takes histograms from the 
+   tracking and the hitmonitor and produces pixel masks and per plane
+   time calibration constants
+
+! 2014-09-26 - Dan Saunders
+ - Added simple estimates of cluster position errors, and incorporated into 
+   TbTrackFit.
+ - Added optional new pattern recognition shape "sqDiabolo" (not yet default). 
+
+! 2014-09-19 - Heinrich Schindler
+ - Fix in TbAlignment technique 2 (use only clusters on device to align for
+   chi2 calculation).
+
+! 2014-08-26 - Christoph Hombach
+ - Improvements to MILLEPEDE
+
+!========================= TbAlgorithms v2r0 2014-08-18 =======================
+
+! 2014-08-15 - Heinrich Schindler
+ - Move spatial efficiency calculation in TbClusterPlots to external script. 
+ - Remove unused class TbAlignmentPlots.
+ - Fix compiler warning in TbAlignment (replace array by vector).
+
+! 2014-08-04 - Heinrich Schindler
+ - Sort clusters on track by z-position.
+
+! 2014-08-03 - Angelo Di Canto
+ - Minor update to TbAlignment (more configurable properties)
+
+! 2014-08-02 - Dan Saunders
+ - Fixed TbClustering inefficiency (now as good as previous slower version).
+
+! 2014-08-02 - Heinrich Schindler
+ - More residual plots for Paula.
+
+! 2014-08-01 - Dan Saunders  
+  - Updated TbClustering for speed/
+  - Extra plots (pull distributions) to TbTrackPlots.
+
+! 2014-08-01 - Christoph Hombach        
+  - Added alignment monitoring plots to TbTrackPlots
+  
+! 2014-07-30 - Christoph Hombach
+  - Update Millepede
+  
+! 2014-07-31 - Dan Saunders
+  - Changed default ordering of cluster hits to increasing in TOA.
+  - Added a few extra plots to TbTrackPlots.
+  - Updated example.py to use run1024 (assuming eos is mounted). 
+
+! 2014-07-29 - Heinrich Schindler
+ - Add TbTriggerAssociator.
+
+! 2014-07-21 - Christop Hombach
+ - Added residual plots, which can be called after alignment procedure in TbAlignment
+
+! 2014-07-21 - Tim Evans
+ - Added trigger data packets
+
+! 2014-07-21 - Angelo Di Canto
+ - Added checks for masked planes in TbAlignment
+ - Millepede renamed into TbMillepede
+ 
+! 2014-07-19 - Heinrich Schindler
+ - Add TbHeaderDecoder tool which reads and optionally dumps the Spidr header.
+ - TbEventBuilder: retrieve device ID from header and check if it matches 
+   with the alignment file.  
+ - Move TbAlgorithm to TbKernel.
+ - Millepede: clang-format and other cosmetic changes.
+
+! 2014-07-18 Christoph Hombach
+ - Removed DUT from Millepede fit -> Next step DUT separate 
+ - Added shell script to run alignment loop
+
+! 2014-07-18 - Heinrich Schindler
+ - Use htime instead of global time for time windows.
+
+! 2014-07-17 - Christoph Hombach
+ - Working implementation of Millepede
+ - Need to clean up code....
+
+! 2014-07-17 - Tim Evans
+ - Added extended timestamp functionality
+ - Added option to manually set the header size
+
+! 2014-07-14 - Dan Saunders
+ - Added hit maps to TbTrackPlots. 
+ - Few temporary additions to TbEventBuilder (all commented out), present for
+   DQM testing.
+ 
+! 2014-07-14 - Heinrich Schindler
+ - Add new class TbAlgorithm (base class for other testbeam algorithms).
+ 
+ ! 2014-07-14 - Dan Saunders
+ - New plots to TbTrackPlots, and separated filling into separate functions
+   for different categories of plot.
+ - New option in TbTracking to ignore listed planes during tracking.
+
+! 2014-07-09 - Heinrich Schindler
+ - Speed improvements in TbClusterFinder.
+ - TbClusterPlots: add configurable histogram parameters, 
+   histogram labels.
+ - TbTrackPlots: configurable histograms, add local residual plots. 
+
+! 2014-07-08 - Hella Snoek
+ - Added option to search for hits further away in TbClustering.
+ - Added some printout statements to info printing the configurables.
+
+! 2014-07-08 - Dan Saunders
+ - Added safety checks for using TbClusterFinder with empty planes.
+
+! 2014-07-08 - Heinrich Schindler
+ - Adapt TbTupleWriter to new TES locations.
+ - TbTracking: use Gaudi counter for nbr. of tracks; inline geomSvc; 
+   initialize planeSearchOrder directly.
+ - Follow renaming from "chip" to "plane" in TbHit and TbCluster.
+ - Run clang-format.
+ - Member functions to start consistently with lower case letter.
+ - Separate hit monitor histograms for each plane.
+ - Add one/two/three/four-pixel cluster ToT distributions to TbClusterPlots.
+
+! 2014-07-07 - Tim Evans
+ - Updated TbEventBuilder to use different TES locations for the different 
+   chips.
+
+! 2014-07-07 - Heinrich Schindler
+ - Fix compiler warnings in TbAlignmentPlots and TbAlignment.
+ - Update TbAlignment survey method to work with separate TES cluster locations.
+ 
+! 2014-07-07 - Dan Saunders
+ - Updated tracking and clustering to use different TES locations for hits and
+   clusters on different chips. 
+
+! 2014-07-04 - Dan Saunders
+ - Tidied up TbTrackPlots and TbClusterPlots
+ - Allowed for varying track sizes - minimum number of clusters set by 
+   TbTracking().MinNClusters = 5. Priority is given to more complete tracks.
+
+! 2014-07-03 - Angelo Di Canto 
+ - Speed improvements in TbAlignment
+ - Fixed bug in definition of alignment constants in TbAlignment
+
+! 2014-07-01 - Angelo Di Canto 
+ - Fixed few typos/bugs in TbAlignment
+
+! 2014-07-01 - Dan Saunders
+ - Tidied up TbTracking.
+
+! 2014-07-01 - Heinrich Schindler
+ - Add samples plot to TbClusterPlots.
+
+! 2014-06-30 - Heinrich Schindler
+ - TbClustering: remove monitoring plots (to be added to TbClusterPlots);
+   merge some short functions; use STL sort.
+
+! 2014-06-27 - Tim Evans
+ - Added reading of the header classes to TbEventBuilder
+ - Added TbRawFile class as a wrapper for input files to cleanup eventbuilder
+ - Moved raw bank decoding into event definitions
+ - Fixed read order dependence
+
+! 2014-06-25 - Heinrich Schindler
+ - Reduce finalise output of TbTupleWriter.
+ - Delete alignment tracks in destructor of TbAlignment.
+ - TbClustering: consistent definition of local and global coordinates.
+ - Fix compiler warnings.
+
+! 2014-06-19 - Heinrich Schindler
+ - Add TbTupleWriter.
+
+! 2014-06-16 - Dan Saunders
+ - Speed improvements in TbTracking.
+
+! 2014-06-06 - Heinrich Schindler
+ - TbHitMonitor: fix binning in 2D hitmap.
+
+!========================= TbAlgorithms v1r0 2014-05-30 =======================
+
+! 2014-05-29 - Heinrich Schindler
+ - Initialise geometry service pointers to NULL in constructor.
+ - TbEventBuilder::finalize: empty cache, close files.
+ - TbTracking: Get the number of planes from the geometry service.
+ - TbAlignment: change return value of techniqueX from StatusCode to bool.
+ - Follow renaming of chip_num to chip in TbCluster.
+ - Mask (for now) unused variable warnings in TbTrackVolume.
+ - Move TbTestMC and TbTrackFitter to Tb/TbSimulation.
+ 
+! 2014-05-28 - Heinrich Schindler
+ - TbTestMC: use Gaudi random number generators instead of TRandom3.
+ - Call finalize functions of actual base classes.
+ - Trivial formatting changes.
+
+! 2014-05-26 - Heinrich Schindler
+ - TbClustering: add new clusters directly to TbClusters container.
+ - TbTracking: idem; also use on-demand booking of histograms.
+
+! 2014-05-24 - Heinrich Schindler
+ - Follow changes in event classes; cosmetic modifications.
+ - Fix compiler warning in TbTrackFitter.
+ - TbEventBuilder: allow processing of all files in a given directory.
+
+! 2014-05-23 - Panagiotis Tsopelas
+ - In TbAlignment.cpp, TbTrackFitter, TbTrackPlots : 
+   Renamed "chi2" -> "chi2PerNdof" after change in TbTrack
+   Changed  every call to a first state parameter (x0, y0, tx, ty)
+   to a call through the "firstState" 
+
+! 2014-05-21 - Heinrich Schindler
+ - Fix signed/unsigned comparison compiler warnings.
+ - Transfer ownership to TES ("put") directly after newing.
+ - Remove unnecessary include statements.
+ - Remove setters/getters from algorithms (use declareProperty instead). 
+ - TbEventBuilder: change return type of retrieve function to bool 
+   and make it private.
+ - Run clang-format.
+ - TbEventBuilder, TbHitMonitor: add header guards
+ - Remove do-nothing finalize methods.
+
+! 2014-05-15 - Dan Saunders
+ - Added MC genorator and first version of tracking. This including a plot object
+   and prototype track object (TbTrackVolume) used during the track finding.
+   
+ - Clustering also updated to consider hits separated diagonally.
+
+! 2014-05-15 - Marco Clemencic
+ - Fixed CMake configuration.
+
+! 2014-05-06 - Panagiotis Tsopelas
+
+ - Added TbTrackFitter. In this class random cluster positions are assigned to the planes
+   and pseudoTbTracks are formed. Then the TbTrackFit::fit() method is called to fit the 
+   TbTracks. Residuals are also calculated.
+
+! 2014-04-29 - Dan Saunders
+ - Updated TbClustering
+ - Added a TbClusterPlots object - note: need to change local positions to global
+
+! 2014-04-11 - Heinrich Schindler
+ - TbEventBuilder: call stopRun after reaching end of file
+ - Run clang-format to get consistent formatting
+ - Change get to getIfExists
+ - Remove do-nothing finalize method
+
+! 2014-04-02 - Tim Evans
+ - Added TbEventBuilder and TbHitMonitor classes
+
+! 2014-03-31 - Heinrich Schindler
+ - Initial import
+
diff --git a/TbAlgorithms/src/.svn/all-wcprops b/TbAlgorithms/src/.svn/all-wcprops
new file mode 100644
index 0000000..95b0411
--- /dev/null
+++ b/TbAlgorithms/src/.svn/all-wcprops
@@ -0,0 +1,173 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/src
+END
+TbClusterPlots.h
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/200685/Kepler/trunk/Tb/TbAlgorithms/src/TbClusterPlots.h
+END
+TbDUTMonitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbDUTMonitor.h
+END
+TbClusterAssociator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/200706/Kepler/trunk/Tb/TbAlgorithms/src/TbClusterAssociator.cpp
+END
+TbTriggerMonitor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTriggerMonitor.cpp
+END
+TbSimpleTracking.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/src/TbSimpleTracking.cpp
+END
+TbVisualiserOutput.h
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/197618/Kepler/trunk/Tb/TbAlgorithms/src/TbVisualiserOutput.h
+END
+TbClusterAssociator.h
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/200706/Kepler/trunk/Tb/TbAlgorithms/src/TbClusterAssociator.h
+END
+TbClustering.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/src/TbClustering.cpp
+END
+TbTriggerMonitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTriggerMonitor.h
+END
+TbSimpleTracking.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/src/TbSimpleTracking.h
+END
+TbClustering.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/201952/Kepler/trunk/Tb/TbAlgorithms/src/TbClustering.h
+END
+TbTrackPlots.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/200904/Kepler/trunk/Tb/TbAlgorithms/src/TbTrackPlots.cpp
+END
+TbCalibration.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbCalibration.cpp
+END
+TbTrackPlots.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/200706/Kepler/trunk/Tb/TbAlgorithms/src/TbTrackPlots.h
+END
+TbTriggerAssociator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTriggerAssociator.cpp
+END
+TbHitMonitor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/200592/Kepler/trunk/Tb/TbAlgorithms/src/TbHitMonitor.cpp
+END
+TbCalibration.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbCalibration.h
+END
+TbTrackVolume.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTrackVolume.cpp
+END
+TbTriggerAssociator.h
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTriggerAssociator.h
+END
+TbVertexTracking.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbVertexTracking.cpp
+END
+TbHitMonitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/200592/Kepler/trunk/Tb/TbAlgorithms/src/TbHitMonitor.h
+END
+TbTrackVolume.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTrackVolume.h
+END
+TbTracking.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTracking.cpp
+END
+TbClusterPlots.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/200904/Kepler/trunk/Tb/TbAlgorithms/src/TbClusterPlots.cpp
+END
+TbDUTMonitor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbDUTMonitor.cpp
+END
+TbVertexTracking.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/186577/Kepler/trunk/Tb/TbAlgorithms/src/TbVertexTracking.h
+END
+TbTracking.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbTracking.h
+END
+TbVisualiserOutput.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/200231/Kepler/trunk/Tb/TbAlgorithms/src/TbVisualiserOutput.cpp
+END
diff --git a/TbAlgorithms/src/.svn/entries b/TbAlgorithms/src/.svn/entries
new file mode 100644
index 0000000..e0d9b7c
--- /dev/null
+++ b/TbAlgorithms/src/.svn/entries
@@ -0,0 +1,980 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlgorithms/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbClusterPlots.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+ec3ed33a14b35cca78bb29eeb0f73ed5
+2016-01-31T12:06:55.490490Z
+200685
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4961
+
+TbDUTMonitor.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+d0e188dfd7afb59fdf500b94717a5378
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2285
+
+TbClusterAssociator.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+2fe987d4736270234c15979ce25308a9
+2016-02-01T08:44:59.600258Z
+200706
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4338
+
+TbTriggerMonitor.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+5024fdef2729187437e2f13d1327a9fd
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4365
+
+TbSimpleTracking.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+0153c1f1de549a5d3336d4d1a6a6bcbb
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+15068
+
+TbVisualiserOutput.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+a3c28cc9ac69b9356617137e8226b433
+2015-11-14T14:26:10.932331Z
+197618
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+833
+
+TbClusterAssociator.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+0bc3bc1c3f8adf768350dbbe469fa219
+2016-02-01T08:44:59.600258Z
+200706
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1031
+
+TbClustering.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+60932036800a3e8e0fe281a98a5098e8
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+13698
+
+TbTriggerMonitor.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+6814dafb0fea9572b850af3aa30d032b
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1225
+
+TbSimpleTracking.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+db11bd565a8697106ff7871b88fc766e
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2349
+
+TbClustering.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+c7439204e4bd661a30c02d78ed796398
+2016-02-24T06:59:33.333028Z
+201952
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2660
+
+TbTrackPlots.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+45dcb54b9e28fbfb905bbe60618f3247
+2016-02-04T17:42:06.201374Z
+200904
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+20629
+
+TbCalibration.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+abd525a6e54f84f32be52814bf6ac0d3
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10378
+
+TbTrackPlots.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+c04c163a2e1375adb356988e30f9edc7
+2016-02-01T08:44:59.600258Z
+200706
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4015
+
+TbTriggerAssociator.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+975770c64fe4d8ac034bad6a8b66d6a6
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3159
+
+TbHitMonitor.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+3ad54d0e6ed8bd92f65ba8dbc4a661df
+2016-01-28T21:57:07.788859Z
+200592
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5120
+
+TbCalibration.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+b2f759a3979e3904ff26ad1bf89198ea
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3788
+
+TbTrackVolume.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+ea2c94ea42472605a4b3926c10657ee1
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5434
+
+TbTriggerAssociator.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+c8ad35bd45153447de3f60b84d08f55c
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1241
+
+TbVertexTracking.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+5a12e849b2a69a72f5c279250533fe3e
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+23934
+
+TbHitMonitor.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+53b2664f5f7af79959e1bb91121faabc
+2016-01-28T21:57:07.788859Z
+200592
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1577
+
+TbTrackVolume.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+abef658e16281f0f3f9a80c5900c3c05
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1997
+
+TbTracking.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+3869d2d1345bc03ecace305861b6acde
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+16280
+
+TbClusterPlots.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+57920adef9bc788e26b675385c3b3666
+2016-02-04T17:42:06.201374Z
+200904
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+25474
+
+TbDUTMonitor.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+23c7d087b2ed413b31c5cfa8d1e941f5
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+11958
+
+TbVertexTracking.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+0a69626152898e69cbe1d12f6b0fc8e6
+2015-04-13T14:01:42.074593Z
+186577
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2326
+
+TbTracking.h
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+14cabe8e5ba81e925be836549847f914
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2732
+
+TbVisualiserOutput.cpp
+file
+
+
+
+
+2016-05-09T14:27:44.000000Z
+00d02be2c0810399c8dfdc5f27ac51b9
+2016-01-26T09:15:46.130838Z
+200231
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5360
+
diff --git a/TbAlgorithms/src/.svn/prop-base/TbClustering.cpp.svn-base b/TbAlgorithms/src/.svn/prop-base/TbClustering.cpp.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbAlgorithms/src/.svn/prop-base/TbClustering.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbAlgorithms/src/.svn/prop-base/TbClustering.h.svn-base b/TbAlgorithms/src/.svn/prop-base/TbClustering.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbAlgorithms/src/.svn/prop-base/TbClustering.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbAlgorithms/src/.svn/prop-base/TbTriggerAssociator.cpp.svn-base b/TbAlgorithms/src/.svn/prop-base/TbTriggerAssociator.cpp.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbAlgorithms/src/.svn/prop-base/TbTriggerAssociator.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbAlgorithms/src/.svn/prop-base/TbTriggerAssociator.h.svn-base b/TbAlgorithms/src/.svn/prop-base/TbTriggerAssociator.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbAlgorithms/src/.svn/prop-base/TbTriggerAssociator.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbAlgorithms/src/.svn/text-base/TbCalibration.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbCalibration.cpp.svn-base
new file mode 100644
index 0000000..7bb42e6
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbCalibration.cpp.svn-base
@@ -0,0 +1,280 @@
+#include <fstream>
+
+// Tb/TbKernel
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbCalibration.h"
+
+// ROOT
+#include "TFitResult.h"
+#include "TFitResultPtr.h"
+#include "TH1D.h"
+
+/// GAUDI
+#include "GaudiUtils/Aida2ROOT.h"
+
+DECLARE_ALGORITHM_FACTORY(TbCalibration)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbCalibration::TbCalibration(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+  declareProperty("PixelConfigFile", m_pixelSvcConfig = "PixelConfig.dat");
+  declareProperty("TimingConfigFile", m_timingSvcConfig = "TimingConfig.dat");
+  declareProperty("CheckHotPixels", m_checkHotPixels = false);
+  declareProperty("CheckSynchronisation", m_checkSyncronisation = false);
+  declareProperty("SyncMethod", m_syncMethod = 1);
+  declareProperty("CheckColumnOffsets", m_checkColumnOffsets = false);
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("DuT", m_dut = 9999);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbCalibration::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  if (m_checkColumnOffsets) m_offsets.resize(m_nPlanes, PROFILE1D(128));
+  if (m_checkHotPixels) m_hitMaps.resize(m_nDevices, PROFILE2D(256, 256));
+  if (m_checkSyncronisation) m_sync.resize(m_nPlanes);
+  return sc;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbCalibration::execute() {
+
+  if (m_checkColumnOffsets) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      LHCb::TbClusters* clusters =
+          getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(i));
+      if (!clusters) continue;
+      columnOffset_execute(clusters);
+    }
+  }
+  if (m_checkHotPixels) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      LHCb::TbHits* hits =
+          getIfExists<LHCb::TbHits>(m_hitLocation + std::to_string(i));
+      if (!hits) continue;
+      hotPixel_execute(hits);
+    }
+  }
+  if (m_checkSyncronisation) {
+    if (m_syncMethod == 0) {
+      std::vector<LHCb::TbClusters*> clusters;
+      for (unsigned int i = 0; i < m_nPlanes; ++i)
+        clusters.push_back(getIfExists<LHCb::TbClusters>(m_clusterLocation +
+                                                         std::to_string(i)));
+      sync_execute(clusters);
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+StatusCode TbCalibration::finalize() {
+
+  std::ofstream pixelFile(m_pixelSvcConfig.c_str());
+  std::ofstream timingFile(m_timingSvcConfig.c_str());
+
+  if (m_checkHotPixels) {
+    pixelFile << "Mask" << std::endl;
+    for (unsigned int i = 0; i < m_nDevices; ++i)
+      hotPixelAnalysis(m_hitMaps[i], geomSvc()->module(i)->id(), pixelFile);
+  }
+  if (m_checkSyncronisation) {
+    if (m_syncMethod == 0)
+      for (unsigned int i = 0; i < m_nPlanes; ++i)
+        syncAnalysis(m_sync[i].avg(), geomSvc()->module(i)->id(), timingFile);
+    else if (m_syncMethod == 1)
+      syncOffset2(timingFile);
+  }
+  if (m_checkColumnOffsets) {
+    pixelFile << "Offset" << std::endl;
+    for (unsigned int i = 0; i < m_nPlanes; ++i)
+      columnOffsetAnalysis(m_offsets[i], geomSvc()->module(i)->id(), pixelFile);
+  }
+  pixelFile.close();
+  timingFile.close();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Identify hot pixels
+//=============================================================================
+void TbCalibration::hotPixelAnalysis(const PROFILE2D& hitMap,
+                                     const std::string& plane,
+                                     std::ostream& os) {
+
+  // Based on Hella's script for identifying hot pixels.
+  // Reject pixels which are more than 40x average
+  for (int col = 0; col < 256; col++) {
+    for (int row = 0; row < 256; row++) {
+      double count = (hitMap[col][row]).n();
+      std::vector<double> nn = hitMap.neighbours(col, row);
+
+      // Cull outliers if not at edge
+      if (nn.size() == 8) {
+        std::sort(nn.begin(), nn.end());
+        nn.erase(nn.begin(), nn.begin() + 2);
+        nn.erase(nn.end() - 2, nn.end());
+      }
+
+      double total = std::accumulate(nn.begin(), nn.end(), 0);
+
+      if (count > 10 * total) {
+        os << plane << " " << std::setw(3) << col << " " << row << std::endl;
+      }
+    }
+  }
+}
+
+void TbCalibration::syncOffset2(std::ostream& os) {
+
+  os << "Timing" << std::endl;
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    std::string title =
+        "Tb/TbTrackPlots/BiasedResiduals/Time/Plane" + std::to_string(i);
+    if (i == m_dut)
+      title = "Tb/TbDUTMonitor/ResidualsTime/Plane" + std::to_string(i);
+    AIDA::IHistogram1D* hAida = NULL;
+    StatusCode sc = GaudiAlgorithm::histoSvc()->retrieveObject(title, hAida);
+    auto hRoot = Gaudi::Utils::Aida2ROOT::aida2root(hAida);
+    os << geomSvc()->module(i)->id() << std::setw(3) << "  "
+       << -hRoot->GetMean() << std::endl;
+  }
+}
+
+//=============================================================================
+// Calculate time offsets for each column
+//=============================================================================
+void TbCalibration::columnOffsetAnalysis(const PROFILE1D& avg_difference,
+                                         const std::string& plane,
+                                         std::ostream& os) {
+  const unsigned int nDcols = 128;
+  std::vector<int> offsets(nDcols, 0);
+  double sum(0.), total(0.);
+  for (auto& d : avg_difference) {
+    sum += d.val();
+    total += d.n();
+  }
+  double avg = sum / total;
+
+  for (unsigned int dcol = 1; dcol < nDcols; ++dcol) {
+    const double difference =
+        avg_difference[dcol].avg() - avg - 25 * offsets[dcol - 1];
+    if (difference > 10.)
+      offsets[dcol] = -1;
+    else if (difference < -10.)
+      offsets[dcol] = +1;
+  }
+  // calculate the average offset
+
+  // deal with the special case where the first super column is desynchronised,
+  // in which case, everything will be shifted by 25 ns in this definition.
+  double avg_offset(0.);
+  for (const auto& d : offsets) avg_offset += d;
+  avg_offset /= 128.;
+
+  if (avg_offset > 0.5)
+    for (auto& d : offsets) d--;
+
+  else if (avg_offset < -0.5)
+    for (auto& d : offsets) d++;
+
+  for (unsigned int dcol = 0; dcol < nDcols; ++dcol) {
+    if (offsets[dcol] != 0)
+      os << plane << " " << std::setw(3) << dcol << " " << offsets[dcol]
+         << std::endl;
+  }
+}
+
+//=============================================================================
+// Fill the data for calculating the column time offsets
+//=============================================================================
+void TbCalibration::columnOffset_execute(const LHCb::TbClusters* clusters) {
+  if (!clusters || clusters->empty()) return;
+  LHCb::TbClusters::const_iterator itc;
+  for (itc = clusters->begin(); itc != clusters->end(); ++itc) {
+    const unsigned int plane = (*itc)->plane();
+    if ((*itc)->size() == 1) continue;
+    auto hits = (*itc)->hits();
+    for (auto& ih0 : hits) {
+      for (auto& ih1 : hits) {
+        const LHCb::TbHit* h0 = ih0;
+        const LHCb::TbHit* h1 = ih1;
+        const int col0 = h0->col();
+        const int col1 = h1->col();
+        if (abs(col0 - col1) != 1) continue;
+        if (h0->row() == h1->row() && h0->col() / 2 != h1->col() / 2) {
+          if (h0->col() > h1->col()) std::swap(h0, h1);
+          m_offsets[plane][(int)(h1->col() / 2)].add(h1->htime() - h0->htime());
+        }
+      }
+    }
+  }
+}
+
+//=============================================================================
+// Fill the data for checking the synchronisation.
+//=============================================================================
+void TbCalibration::sync_execute(
+    const std::vector<LHCb::TbClusters*>& clusters) {
+
+  LHCb::TbClusters* plane0_clusters = clusters[0];
+  for (auto& c : *plane0_clusters) {
+    for (unsigned int i = 1; i < m_nPlanes; ++i) {
+      double nearest = nearestHit(c, clusters[i]);
+      if (nearest != 9999) m_sync[i].add(nearest);
+    }
+  }
+}
+
+//=============================================================================
+// Get the smallest time difference of a list of clusters.
+//=============================================================================
+double TbCalibration::nearestHit(const LHCb::TbCluster* cluster,
+                                 const LHCb::TbClusters* clusters) {
+  if (!clusters || !cluster || clusters->empty()) return 9999;
+  double minTime = cluster->htime() - 50.;
+  double maxTime = cluster->htime() + 50.;
+  LHCb::TbClusters::const_iterator c = std::lower_bound(
+      clusters->begin(), clusters->end(), minTime, lowerBound());
+  double nn = 9999;
+  for (; c != clusters->end() && (*c)->htime() < maxTime; ++c) {
+    if (std::abs((*c)->htime() - cluster->htime()) < std::abs(nn))
+      nn = (*c)->htime() - cluster->htime();
+  }
+  return nn;
+}
+
+//=============================================================================
+// Fill the hit map for identifying hot pixels
+//=============================================================================
+void TbCalibration::hotPixel_execute(const LHCb::TbHits* hits) {
+  if (!hits || hits->empty()) return;
+  const unsigned int device = (*hits->begin())->device();
+  for (auto& h : *hits) m_hitMaps[device][h->col()][h->row()].add(1);
+}
+
+//=============================================================================
+// Save synchronisation info to file.
+//=============================================================================
+void TbCalibration::syncAnalysis(const double& sync, const std::string& plane,
+                                 std::ostream& os) {
+
+  os << plane << std::setw(3) << " " << sync << std::endl;
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbCalibration.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbCalibration.h.svn-base
new file mode 100644
index 0000000..5934024
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbCalibration.h.svn-base
@@ -0,0 +1,117 @@
+#pragma once
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbCalibration TbCalibration.h
+ *
+ *  Algorithm to produce timing and pixel configurations
+ *  Try to make as independent as possible from the rest of Kepler
+ *  (Relies on clustering and EventBuilder only)
+ *
+ *  @author T. Evans
+ *
+ */
+
+class TbCalibration : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbCalibration(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbCalibration() {};
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();
+
+ private:
+  // profile structure
+  struct POINT {
+    POINT() : total(0), nData(0) {};
+    double total;
+    double nData;
+    double avg() const { return nData == 0 ? 0 : total / nData; }
+    double val() const { return total; }
+    double n() const { return nData; }
+    void add(double data) {
+      total += data;
+      nData++;
+    }
+  };
+
+  struct PROFILE1D : public std::vector<POINT> {
+    PROFILE1D(unsigned int size = 0) : std::vector<POINT>(size, POINT()) {}
+  };
+
+  struct PROFILE2D : public std::vector<std::vector<POINT>> {
+    PROFILE2D(unsigned int size_x = 0, unsigned int size_y = 0)
+        : std::vector<std::vector<POINT>>(
+              size_x, std::vector<POINT>(size_y, POINT())) {};
+
+    inline POINT element(const unsigned int x, const unsigned int y) const {
+      std::vector<POINT> tmp = *(begin() + x);
+      return tmp[y];
+    }
+
+    std::vector<double> neighbours(const unsigned int x,
+                                   const unsigned int y) const {
+      std::vector<double> return_value;
+      return_value.clear();
+      unsigned int ix_begin = x > 0 ? x - 1 : 0;
+      unsigned int ix_end = x < size() - 1 ? x + 1 : size() - 1;
+      unsigned int iy_begin = y > 0 ? y - 1 : 0;
+      unsigned int iy_end = y < size() - 1 ? y + 1 : size() - 1;
+      for (unsigned int ix = ix_begin; ix <= ix_end; ++ix) {
+        for (unsigned int iy = iy_begin; iy <= iy_end; ++iy)
+          if (!(ix == x && iy == y))
+            return_value.push_back(element(ix, iy).n());
+      }
+      return return_value;
+    }
+  };
+
+  /// TES location of tracks
+  std::string m_trackLocation;
+  /// TES location of clusters
+  std::string m_clusterLocation;
+  std::string m_hitLocation;
+  std::string m_pixelSvcConfig;
+  std::string m_timingSvcConfig;
+
+  bool m_checkHotPixels;
+  bool m_checkSyncronisation;
+  bool m_checkColumnOffsets;
+  unsigned int m_syncMethod;
+  unsigned int m_dut;  /// synchronisation of the DUT is kept separate and
+                       /// doesn't affect the telescope timing
+  std::vector<PROFILE1D> m_offsets;
+  std::vector<PROFILE2D> m_hitMaps;
+  PROFILE1D m_sync;
+  // hot pixel identification, analyses the work done by execute
+  void hotPixelAnalysis(const PROFILE2D& hitMap, const std::string& plane,
+                        std::ostream& os = std::cout);
+  void hotPixel_execute(const LHCb::TbHits* hits);
+
+  void syncAnalysis(const double& sync, const std::string& plane,
+                    std::ostream& os = std::cout);
+  void sync_execute(const std::vector<LHCb::TbClusters*>& clusters);
+
+  double nearestHit(const LHCb::TbCluster* cluster,
+                    const LHCb::TbClusters* clusters);
+
+  void columnOffsetAnalysis(const PROFILE1D& avg_difference,
+                            const std::string& plane,
+                            std::ostream& os = std::cout);
+  void columnOffset_execute(const LHCb::TbClusters* clusters);
+
+  void syncOffset2(std::ostream& os = std::cout);
+  class lowerBound {
+   public:
+    bool operator()(const LHCb::TbCluster* lhs, const double t) const {
+      return lhs->htime() < t;
+    }
+  };
+};
diff --git a/TbAlgorithms/src/.svn/text-base/TbClusterAssociator.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbClusterAssociator.cpp.svn-base
new file mode 100644
index 0000000..70c5be1
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbClusterAssociator.cpp.svn-base
@@ -0,0 +1,114 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbClusterAssociator.h"
+
+DECLARE_ALGORITHM_FACTORY(TbClusterAssociator)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbClusterAssociator::TbClusterAssociator(const std::string& name,
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+  declareProperty("DUTs", m_duts);
+
+  declareProperty("UseHits", m_useHits = true);
+  declareProperty("ReuseClusters", m_reuseClusters = true);
+  declareProperty("TimeWindow", m_twindow = 200. * Gaudi::Units::ns);
+  declareProperty("XWindow", m_xwindow = 1. * Gaudi::Units::mm);
+  declareProperty("MaxChi2", m_maxChi2 = 100.);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbClusterAssociator::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbClusterAssociator::execute() {
+
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+  for (const auto dut : m_duts) {
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(dut);
+    const LHCb::TbClusters* clusters =
+        getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) continue;
+    // Loop over the tracks.
+    for (LHCb::TbTrack* track : *tracks) {
+      // Skip low quality tracks.
+      if (track->chi2PerNdof() > m_maxChi2) continue;
+      const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, dut);
+      const auto pLocal = geomSvc()->globalToLocal(pGlobal, dut);
+      const double tMin = track->htime() - m_twindow;
+      const double tMax = track->htime() + m_twindow;
+      for (LHCb::TbCluster* cluster : *clusters) {
+        // Assume that the clusters are sorted by time.
+        if (cluster->htime() < tMin) continue;
+        if (cluster->htime() > tMax) break;
+        // Skip used clusters (if requested).
+        if (!m_reuseClusters && cluster->associated()) continue;
+        if (m_useHits) {
+          // Compare the coordinates of the pixels to the track intercept.
+          if (!match(cluster, pLocal.x(), pLocal.y())) continue;
+        } else {
+          // Compare the cluster coordinates to the track intercept.
+          const double dx = cluster->xloc() - pLocal.x();
+          const double dy = cluster->yloc() - pLocal.y();
+          if (fabs(dx) > m_xwindow || fabs(dy) > m_xwindow) continue;
+        }
+        // Associate the cluster to the track and tag it as used.
+        track->addToAssociatedClusters(cluster);
+        cluster->setAssociated(true);
+      }
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Check if the cluster has hits within the search window.
+//=============================================================================
+bool TbClusterAssociator::match(const LHCb::TbCluster* cluster, const double x,
+                                const double y) const {
+
+  const unsigned int plane = cluster->plane();
+  // Loop over hits in the cluster.
+  for (auto hit : cluster->hits()) {
+    double xLocal = 0.;
+    double yLocal = 0.;
+    geomSvc()->pixelToPoint(hit->scol(), hit->row(), plane, xLocal, yLocal);
+    const double dx = xLocal - x;
+    const double dy = yLocal - y;
+    if (fabs(dx) < m_xwindow && fabs(dy) < m_xwindow) return true;
+  }
+  return false;
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbClusterAssociator.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbClusterAssociator.h.svn-base
new file mode 100644
index 0000000..6068c8e
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbClusterAssociator.h.svn-base
@@ -0,0 +1,39 @@
+#pragma once
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbClusterAssociator TbClusterAssociator.h
+ *
+ */
+
+class TbClusterAssociator : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbClusterAssociator(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbClusterAssociator() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<unsigned int> m_duts;
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+
+  /// Flag to use individual pixel hits or cluster coordinate for association.
+  bool m_useHits;
+  /// Flag to associate clusters to more than one track or not.
+  bool m_reuseClusters;
+  /// Time window
+  double m_twindow;
+  /// Spatial window
+  double m_xwindow;
+  /// Chi2 cut
+  double m_maxChi2;
+
+  /// Check if a cluster has hits within the tolerance window.
+  bool match(const LHCb::TbCluster* cluster, const double x,
+             const double y) const;
+};
diff --git a/TbAlgorithms/src/.svn/text-base/TbClusterPlots.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbClusterPlots.cpp.svn-base
new file mode 100644
index 0000000..0854b46
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbClusterPlots.cpp.svn-base
@@ -0,0 +1,601 @@
+#include <cmath>
+
+// AIDA
+// #include "AIDA/IAxis.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbClusterPlots.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbClusterPlots)
+
+//=============================================================================
+// Standard constructor.
+//=============================================================================
+TbClusterPlots::TbClusterPlots(const std::string& name,
+                               ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parToT("", 0.5, 1024.5, 1024),
+      m_parCharge("", 0., 60000., 200),
+      m_parXY("", -25., 25., 200),
+      m_parTime("", 0., 300000., 1000),
+      m_parDifferenceXY("", -2., 2., 200),
+      m_parDifferenceRot("", -0.1, 0.1, 200),
+      m_parDifferenceT("", -1000., 1000., 1000),
+      m_parSamples(0, 100000, 1),
+      m_clusterFinder(nullptr),
+      m_event(0) {
+
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("ReferencePlane", m_referencePlane = 0);
+  declareProperty("TimeWindow", m_twindow = 250. * Gaudi::Units::ns);
+
+  declareProperty("ParametersToT", m_parToT);
+  declareProperty("ParametersCharge", m_parCharge);
+  declareProperty("ParametersXY", m_parXY);
+  declareProperty("ParametersTime", m_parTime);
+  declareProperty("ParametersDifferenceXY", m_parDifferenceXY);
+  declareProperty("ParametersDifferenceRot", m_parDifferenceRot);
+  declareProperty("ParametersDifferenceT", m_parDifferenceT);
+
+  declareProperty("FillSamples", m_fillSamples = false);
+  declareProperty("FillComparisonPlots", m_fillComparisonPlots = false);
+  declareProperty("FillTrackingEfficiency", m_fillTrackingEfficiency = false);
+  declareProperty("ParametersSamples", m_parSamples);
+  declareProperty("ChargeCutLow", m_chargeCutLow = 0);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbClusterPlots::~TbClusterPlots() {}
+
+//=============================================================================
+// Initialization.
+//=============================================================================
+StatusCode TbClusterPlots::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Initialise the plots.
+  setupPlots();
+  // Setup the cluster finder.
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+  if (!m_clusterFinder) {
+    return Error("Cannot retrieve cluster finder tool.");
+  }
+  m_clusterFinder->setSearchAlgorithm("adap_seq");
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalization.
+//=============================================================================
+StatusCode TbClusterPlots::finalize() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    double num = m_nTrackedClusters_vs_telHitOccupancy->binHeight(
+        m_nTrackedClusters_vs_telHitOccupancy->coordToIndex(i));
+    double denom = m_nClusters_vs_telHitOccupancy->binHeight(
+        m_nClusters_vs_telHitOccupancy->coordToIndex(i));
+    double frac = num / denom;
+    if (denom > 0) m_fractionTrackedClusters_vs_telHitOccupancy->fill(i, frac);
+
+    num = m_nTrackedClusters_vs_telCharge->binHeight(
+        m_nTrackedClusters_vs_telCharge->coordToIndex(i));
+    denom = m_nClusters_vs_telCharge->binHeight(
+        m_nClusters_vs_telCharge->coordToIndex(i));
+    frac = num / denom;
+    if (denom > 0) m_fractionTrackedClusters_vs_telCharge->fill(i, frac);
+  }
+
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Main execution.
+//=============================================================================
+StatusCode TbClusterPlots::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Skip masked planes.
+    if (masked(i)) continue;
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) return Error("No clusters in " + clusterLocation);
+    // Fill the plots depending on just these clusters.
+    fillPerChipPlots(clusters);
+    fillClusterVisuals(clusters);
+    // Store the iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+  }
+
+  if (m_fillTrackingEfficiency) fillTrackingEfficiency();
+
+  if (m_fillComparisonPlots) fillComparisonPlots();
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Fill "event displays".
+//=============================================================================
+void TbClusterPlots::fillClusterVisuals(const LHCb::TbClusters* clusters) {
+
+  for (const LHCb::TbCluster* cluster : *clusters) {
+    if (cluster->htime() > m_parSamples.highEdge()) break;
+    if (cluster->htime() < m_parSamples.lowEdge()) continue;
+    if (cluster->associated()) continue;
+    const unsigned int plane = cluster->plane();
+    for (auto hit : cluster->hits()) {
+      double xLocal = 0.;
+      double yLocal = 0.;
+      geomSvc()->pixelToPoint(hit->scol(), hit->row(), plane, xLocal, yLocal);
+      Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      m_clusterVisuals[plane]->fill(pGlobal.x(), pGlobal.y());
+    }
+  }
+}
+
+//=============================================================================
+// Fill plots.
+//=============================================================================
+void TbClusterPlots::fillPerChipPlots(const LHCb::TbClusters* clusters) {
+
+  double tprev = 0.;
+  bool first = true;
+  for (const LHCb::TbCluster* cluster : *clusters) {
+    const unsigned int plane = cluster->plane();
+    const unsigned int tot = cluster->ToT();
+    const double charge = cluster->charge();
+    m_hToT[plane]->fill(tot);
+    m_hCharge[plane]->fill(charge);
+    const unsigned int size = cluster->size();
+    if (size == 1) {
+      m_hToTOnePixel[plane]->fill(tot);
+      m_hChargeOnePixel[plane]->fill(charge);
+    } else if (size == 2) {
+      m_hToTTwoPixel[plane]->fill(tot);
+      m_hChargeTwoPixel[plane]->fill(charge);
+    } else if (size == 3) {
+      m_hToTThreePixel[plane]->fill(tot);
+      m_hChargeThreePixel[plane]->fill(charge);
+    } else if (size == 4) {
+      m_hToTFourPixel[plane]->fill(tot);
+      m_hChargeFourPixel[plane]->fill(charge);
+    }
+    m_hSize[plane]->fill(size);
+
+    // Hitmap.
+    m_hHitMap[plane]->fill(cluster->x(), cluster->y());
+
+    counter("effFractionAssociated" + std::to_string(plane)) +=
+        cluster->associated();
+    if (cluster->charge() > 50) {
+      counter("effFractionAssociatedAbove50TOT" + std::to_string(plane)) +=
+          cluster->associated();
+    }
+    const double t = cluster->htime();
+    m_hTime[plane]->fill(t);
+    if (!first) m_hTimeBetweenClusters[plane]->fill(t - tprev);
+    first = false;
+    tprev = t;
+
+    if (cluster->associated()) {
+      m_hHitMapAssociated[plane]->fill(cluster->x(), cluster->y());
+      m_hSizeAssociated[plane]->fill(size);
+      m_hToTAssociated[plane]->fill(tot);
+      m_hChargeAssociated[plane]->fill(charge);
+      m_hTimeAssociated[plane]->fill(t);
+    } else {
+      m_hHitMapNonAssociated[plane]->fill(cluster->x(), cluster->y());
+      m_hSizeNonAssociated[plane]->fill(size);
+      m_hToTNonAssociated[plane]->fill(tot);
+      m_hChargeNonAssociated[plane]->fill(charge);
+      m_hTimeNonAssociated[plane]->fill(t);
+    }
+    m_hWidthCol[plane]->fill(cluster->cols());
+    m_hWidthRow[plane]->fill(cluster->rows());
+    m_hGlobalXvsZ->fill(cluster->z(), cluster->x());
+    m_hGlobalYvsZ->fill(cluster->z(), cluster->y());
+
+    // Loop over the hits in the cluster.
+    auto hits = cluster->hits();
+    bool firstHit = true;
+    double tSeed = 0.;
+    for (const LHCb::TbHit* hit : hits) {
+      if (firstHit) {
+        tSeed = hit->htime();
+        firstHit = false;
+      } else {
+        m_hTimeSeedMinusHit[plane]->fill(hit->htime() - tSeed);
+      }
+    }
+  }
+
+  if (m_fillSamples) fillSamples(clusters);
+}
+
+//=============================================================================
+// Comparison windows (via scrolling window).
+//=============================================================================
+void TbClusterPlots::fillComparisonPlots() {
+
+  // Make sure there are clusters on the reference plane.
+  if (m_clusterFinder->empty(m_referencePlane)) return;
+  // Scroll over clusters on the reference plane, then draw comparisons
+  // between this cluster and those inside a time window on the other planes.
+  const auto refBegin = m_clusterFinder->first(m_referencePlane);
+  const auto refEnd = m_clusterFinder->end(m_referencePlane);
+  for (auto itRef = refBegin; itRef != refEnd; ++itRef) {
+    // Calculate the time window for this cluster.
+    const auto tRef = (*itRef)->htime();
+    const auto tMin = tRef - m_twindow;
+    const auto tMax = tRef + m_twindow;
+
+    const double xRef = (*itRef)->x();
+    const double yRef = (*itRef)->y();
+
+    // Loop over other the other planes.
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      // Skip empty planes.
+      if (m_clusterFinder->empty(i)) continue;
+      // Get the first cluster within the time range.
+      const auto begin = m_clusterFinder->getIterator(tMin, i);
+      const auto end = m_clusterFinder->end(i);
+      // Loop over the clusters within the range.
+      for (auto ic = begin; ic != end; ++ic) {
+        // Stop when too far ahead.
+        if ((*ic)->htime() >= tMax) break;
+        // (Re)-check if inside the window.
+        if ((*ic)->htime() >= tMin) {
+          // Fill correlation plots.
+          m_gx_correls[i]->fill((*ic)->x(), xRef);
+          m_gy_correls[i]->fill((*ic)->y(), yRef);
+          m_gt_correls[i]->fill((*ic)->htime(), tRef);
+          // Fill difference plots.
+          m_gx_diffs[i]->fill((*ic)->x() - xRef);
+          m_gy_diffs[i]->fill((*ic)->y() - yRef);
+          m_gt_diffs[i]->fill((*ic)->htime() - tRef);
+        }
+      }
+    }
+  }
+}
+
+//=============================================================================
+// Plot a set of clusters.
+//=============================================================================
+void TbClusterPlots::fillSamples(const LHCb::TbClusters* clusters) {
+
+  // Takes a set number of clusters and plots their hits on a TH2, with
+  // the bins weighted by ToT values. Clusters are spaced equally. A dot at
+  // their reconstructed positions would be cool.
+
+  const unsigned int nSamplesRoot = 6;
+  const unsigned int nSamples = nSamplesRoot * nSamplesRoot;
+  const unsigned int sampleSpacing = 6;
+  const unsigned int n = nSamplesRoot * sampleSpacing;
+  LHCb::TbClusters::const_iterator ic = clusters->begin();
+  for (unsigned int i = 0; i < nSamples && i < clusters->size(); ++i) {
+    // Modify later to not always visualize first few clusters.
+    // Position of cluster seed on TH2.
+    // Sequentially left to right, then down to up.
+    const int c_col = (i % nSamplesRoot) * sampleSpacing;
+    const int c_row = (i / nSamplesRoot) * sampleSpacing;
+    const auto& hits = (*ic)->hits();
+    const int seed_col = hits.front()->col();
+    const int seed_row = hits.front()->row();
+    for (auto it = hits.cbegin(), end = hits.cend(); it != end; ++it) {
+      // Center the cluster on the seed hit, then shift to posn on TH2.
+      const int col = ((*it)->col() - seed_col) + c_col;
+      const int row = ((*it)->row() - seed_row) + c_row;
+      plot2D(col, row, "ClusterSamples", "Cluster samples", 0, n, 0, n, n, n,
+             (*it)->ToT());
+    }
+    ++ic;
+  }
+
+  // Switch off filling the samples plot after the first call.
+  m_fillSamples = false;
+}
+
+//=============================================================================
+
+void TbClusterPlots::fillTrackingEfficiency() {
+  std::string clusterLocation = m_clusterLocation + "0";
+  LHCb::TbClusters* clusters_zero =
+      getIfExists<LHCb::TbClusters>(clusterLocation);
+
+  // Loop over clusters on plane 0.
+  LHCb::TbClusters::const_iterator begin = clusters_zero->begin();
+  LHCb::TbClusters::const_iterator end = clusters_zero->end();
+  for (LHCb::TbClusters::const_iterator iSeed = begin; iSeed != end; ++iSeed) {
+    double timeSeed = (*iSeed)->htime();
+    double tWindow = 10;
+
+    unsigned int nClusters = 0;
+    unsigned int nTrackedClusters = 0;
+    unsigned int nTelHits = 0;
+    unsigned int nTelHits_tracked = 0;
+    double telCharge = 0;
+
+    for (unsigned int i = 1; i < m_nPlanes; ++i) {
+      if (i == 4) continue;
+      // Get the clusters for this plane.
+      clusterLocation = m_clusterLocation + std::to_string(i);
+      LHCb::TbClusters* clusters =
+          getIfExists<LHCb::TbClusters>(clusterLocation);
+
+      LHCb::TbClusters::const_iterator begin = clusters->begin();
+      LHCb::TbClusters::const_iterator end = clusters->end();
+      for (LHCb::TbClusters::const_iterator it = begin; it != end; ++it) {
+        double delT = timeSeed - (*it)->htime();
+        if (fabs(delT) < tWindow) {
+          nTelHits += (*it)->size();
+          telCharge += (*it)->charge();
+          if ((*it)->charge() > m_chargeCutLow) {
+            nClusters++;
+            if ((*it)->associated()) {
+              nTrackedClusters++;
+              nTelHits_tracked += (*it)->size();
+            }
+          }
+        }
+      }
+    }
+    //		if (nClustersPerPlane > 4 && m_event == 1050)
+    //std::cout<<nClustersPerPlane<<"\t"<<m_event<<"\t"<<(*iSeed)->htime()<<std::endl;
+    m_telHitOccupancy->fill(nTelHits);
+    m_telHitOccupancy_tracked->fill(nTelHits_tracked);
+    m_nClusters_vs_telHitOccupancy->fill(nTelHits, nClusters);
+    m_nTrackedClusters_vs_telHitOccupancy->fill(nTelHits, nTrackedClusters);
+
+    m_telCharge->fill(telCharge);
+    m_nClusters_vs_telCharge->fill(telCharge, nClusters);
+    m_nTrackedClusters_vs_telCharge->fill(telCharge, nTrackedClusters);
+
+    m_telClusterOccupancy->fill(nClusters);
+    m_telClusterOccupancy_tracked->fill(nTrackedClusters);
+    m_nClusters_vs_telClusterOccupancy->fill(nClusters, nClusters);
+    m_nTrackedClusters_vs_telClusterOccupancy->fill(nClusters,
+                                                    nTrackedClusters);
+
+    //		if (nClusters == 15 && m_event == 1050)
+    //			std::cout<<(*iSeed)->htime()<<"\t"<<nTelHits<<std::endl;
+  }
+}
+
+//=============================================================================
+// Initialization of plot objects
+//=============================================================================
+void TbClusterPlots::setupPlots() {
+  unsigned int nBins = 60;
+  m_nTrackedClusters_vs_telHitOccupancy =
+      book1D("TrackingEfficiency/nTrackedClusters_vs_telHitOccupancy",
+             "nTrackedClusters_vs_telHitOccupancy", 0, 250, nBins);
+  m_fractionTrackedClusters_vs_telHitOccupancy =
+      book1D("TrackingEfficiency/fractionTrackedClusters_telHitOccupancy",
+             "ffractionTrackedClusters_telHitOccupancy", 0, 250, nBins);
+  m_nClusters_vs_telHitOccupancy =
+      book1D("TrackingEfficiency/nClusters_vs_telHitOccupancy",
+             "nClusters_vs_telHitOccupancy", 0, 250, nBins);
+  m_telHitOccupancy = book1D("TrackingEfficiency/telHitOccupancy",
+                             "telHitOccupancy", 0, 250, nBins);
+  m_telHitOccupancy_tracked =
+      book1D("TrackingEfficiency/telHitOccupancy_tracked",
+             "telHitOccupancy_tracked", 0, 250, nBins);
+
+  m_nTrackedClusters_vs_telCharge =
+      book1D("TrackingEfficiency/nTrackedClusters_vs_telCharge",
+             "nTrackedClusters_vs_telCharge", 0, 8000, nBins);
+  m_fractionTrackedClusters_vs_telCharge =
+      book1D("TrackingEfficiency/fractionTrackedClusters_telCharge",
+             "ffractionTrackedClusters_telCharge", 0, 8000, nBins);
+  m_nClusters_vs_telCharge = book1D("TrackingEfficiency/nClusters_vs_telCharge",
+                                    "nClusters_vs_telCharge", 0, 8000, nBins);
+  m_telCharge =
+      book1D("TrackingEfficiency/telCharge", "telCharge", 0, 8000, nBins);
+
+  m_nTrackedClusters_vs_telClusterOccupancy =
+      book1D("TrackingEfficiency/nTrackedClusters_vs_telClusterOccupancy",
+             "nTrackedClusters_vs_telClusterOccupancy", 0, 60, nBins);
+  m_fractionTrackedClusters_vs_telClusterOccupancy =
+      book1D("TrackingEfficiency/fractionTrackedClusters_telClusterOccupancy",
+             "ffractionTrackedClusters_telClusterOccupancy", 0, 60, nBins);
+  m_nClusters_vs_telClusterOccupancy =
+      book1D("TrackingEfficiency/nClusters_vs_telClusterOccupancy",
+             "nClusters_vs_telClusterOccupancy", 0, 60, nBins);
+  m_telClusterOccupancy = book1D("TrackingEfficiency/telClusterOccupancy",
+                                 "telClusterOccupancy", 0, 60, nBins);
+  m_telClusterOccupancy_tracked =
+      book1D("TrackingEfficiency/telClusterOccupancy_tracked",
+             "telClusterOccupancy_tracked", 0, 60, nBins);
+
+  const double zMin = geomSvc()->modules().front()->z() - 50.;
+  const double zMax = geomSvc()->modules().back()->z() + 50.;
+  unsigned int bins = m_parXY.bins();
+  double low = m_parXY.lowEdge();
+  double high = m_parXY.highEdge();
+  m_hGlobalXvsZ =
+      book2D("GlobalXvsZ", "GlobalXvsZ", zMin, zMax, 5000, low, high, bins);
+  m_hGlobalYvsZ =
+      book2D("GlobalYvsZ", "GlobalYvsZ", zMin, zMax, 5000, low, high, bins);
+  setAxisLabels(m_hGlobalXvsZ, "global #it{z} [mm]", "global #it{x} [mm]");
+  setAxisLabels(m_hGlobalYvsZ, "global #it{z} [mm]", "global #it{y} [mm]");
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+
+    // ToT distributions
+    bins = m_parToT.bins();
+    low = m_parToT.lowEdge();
+    high = m_parToT.highEdge();
+    std::string name = "ToT/All/Plane" + plane;
+    m_hToT.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/OnePixel/Plane" + plane;
+    m_hToTOnePixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/TwoPixel/Plane" + plane;
+    m_hToTTwoPixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/ThreePixel/Plane" + plane;
+    m_hToTThreePixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/FourPixel/Plane" + plane;
+    m_hToTFourPixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/Associated/Plane" + plane;
+    m_hToTAssociated.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/NonAssociated/Plane" + plane;
+    m_hToTNonAssociated.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hToT[i], "ToT", "entries");
+    setAxisLabels(m_hToTOnePixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTTwoPixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTThreePixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTFourPixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTAssociated[i], "ToT", "entries");
+    setAxisLabels(m_hToTNonAssociated[i], "ToT", "entries");
+
+    // Charge distributions
+    bins = m_parCharge.bins();
+    low = m_parCharge.lowEdge();
+    high = m_parCharge.highEdge();
+    name = "Charge/All/Plane" + plane;
+    m_hCharge.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/OnePixel/Plane" + plane;
+    m_hChargeOnePixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/TwoPixel/Plane" + plane;
+    m_hChargeTwoPixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/ThreePixel/Plane" + plane;
+    m_hChargeThreePixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/FourPixel/Plane" + plane;
+    m_hChargeFourPixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/Associated/Plane" + plane;
+    m_hChargeAssociated.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/NonAssociated/Plane" + plane;
+    m_hChargeNonAssociated.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hCharge[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeOnePixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeTwoPixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeThreePixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeFourPixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeAssociated[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeNonAssociated[i], "charge [electrons]", "entries");
+
+    // Cluster size distributions
+    name = "Size/Plane" + plane;
+    m_hSize.push_back(book1D(name, title, 0.5, 10.5, 10));
+    name = "SizeAssociated/Plane" + plane;
+    m_hSizeAssociated.push_back(book1D(name, title, 0.5, 10.5, 10));
+    name = "SizeNonAssociated/Plane" + plane;
+    m_hSizeNonAssociated.push_back(book1D(name, title, 0.5, 10.5, 10));
+    setAxisLabels(m_hSize[i], "cluster size", "entries");
+    setAxisLabels(m_hSizeAssociated[i], "cluster size", "entries");
+    setAxisLabels(m_hSizeNonAssociated[i], "cluster size", "entries");
+
+    // Cluster width along column and row directions
+    name = "Width/col/Plane" + plane;
+    m_hWidthCol.push_back(book1D(name, title, 0.5, 10.5, 10));
+    name = "Width/row/Plane" + plane;
+    m_hWidthRow.push_back(book1D(name, title, 0.5, 10.5, 10));
+    setAxisLabels(m_hWidthCol[i], "columns", "entries");
+    setAxisLabels(m_hWidthRow[i], "rows", "entries");
+
+    // Cluster position hit maps
+    bins = m_parXY.bins();
+    low = m_parXY.lowEdge();
+    high = m_parXY.highEdge();
+    name = "Positions/Plane" + plane;
+    m_hHitMap.push_back(book2D(name, title, low, high, bins, low, high, bins));
+    name = "PositionsAssociated/Plane" + plane;
+    m_hHitMapAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "PositionsNonAssociated/Plane" + plane;
+    m_hHitMapNonAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_hHitMap[i], "global #it{x} [mm]", "global #it{y} [mm]");
+    setAxisLabels(m_hHitMapAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+    setAxisLabels(m_hHitMapNonAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+
+    // Global x/y correlations
+    name = "Correlations/x/Plane" + plane;
+    m_gx_correls.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "Correlations/y/Plane" + plane;
+    m_gy_correls.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_gx_correls[i], "#it{x} [mm]", "#it{x}_{ref} [mm]");
+    setAxisLabels(m_gy_correls[i], "#it{y} [mm]", "#it{y}_{ref} [mm]");
+
+    // Time distributions
+    bins = m_parTime.bins();
+    low = m_parTime.lowEdge();
+    high = m_parTime.highEdge();
+    name = "Time/Plane" + plane;
+    m_hTime.push_back(book1D(name, title, low, high, bins));
+    name = "TimeAssociated/Plane" + plane;
+    m_hTimeAssociated.push_back(book1D(name, title, low, high, bins));
+    name = "TimeNonAssociated/Plane" + plane;
+    m_hTimeNonAssociated.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hTime[i], "time [ns]", "entries");
+    setAxisLabels(m_hTimeAssociated[i], "time [ns]", "entries");
+    setAxisLabels(m_hTimeNonAssociated[i], "time [ns]", "entries");
+    // Time spread of hits within a cluster.
+    name = "TimeHitMinusSeed/Plane" + plane;
+    m_hTimeSeedMinusHit.push_back(book1D(name, title, 0., 500., 200));
+    setAxisLabels(m_hTimeSeedMinusHit[i], "#it{t}_{hit} - #it{t}_{seed} [ns]",
+                  "entries");
+    // Time correlations
+    name = "Correlations/t/Plane" + plane;
+    m_gt_correls.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_gt_correls[i], "#it{t}", "#it{t}_{ref}");
+
+    // Global x/y differences
+    bins = m_parDifferenceXY.bins();
+    low = m_parDifferenceXY.lowEdge();
+    high = m_parDifferenceXY.highEdge();
+    name = "Differences/x/Plane" + plane;
+    m_gx_diffs.push_back(book1D(name, title, low, high, bins));
+    name = "Differences/y/Plane" + plane;
+    m_gy_diffs.push_back(book1D(name, title, low, high, bins));
+    bins = m_parDifferenceRot.bins();
+    low = m_parDifferenceRot.lowEdge();
+    high = m_parDifferenceRot.highEdge();
+    setAxisLabels(m_gx_diffs[i], "#it{x} - #it{x}_{ref} [mm]", "entries");
+    setAxisLabels(m_gy_diffs[i], "#it{y} - #it{y}_{ref} [mm]", "entries");
+    // Time differences
+    bins = m_parDifferenceT.bins();
+    low = m_parDifferenceT.lowEdge();
+    high = m_parDifferenceT.highEdge();
+    name = "Differences/t/Plane" + plane;
+    m_gt_diffs.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_gt_diffs[i], "#it{t} - #it{t}_{ref}", "entries");
+
+    // Time between clusters
+    name = "TimeBetweenClusters/Plane" + plane,
+    m_hTimeBetweenClusters.push_back(book1D(name, title, 0., 1000., 50));
+    setAxisLabels(m_hTimeBetweenClusters[i], "#Deltat [ns]", "entries");
+  }
+
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    std::string name = "ClusterVisuals/Sample" + std::to_string(i);
+    m_clusterVisuals.push_back(
+        book2D(name, name, 0, 14.08, 256, 0, 14.08, 256));
+  }
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbClusterPlots.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbClusterPlots.h.svn-base
new file mode 100644
index 0000000..a1ec63d
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbClusterPlots.h.svn-base
@@ -0,0 +1,140 @@
+#ifndef TB_CLUSTERPLOTS_H
+#define TB_CLUSTERPLOTS_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbClusterPlots TbClusterPlots.h
+ *
+ *  Algorithm to produce monitoring histograms for Timepix3 clusters.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbClusterPlots : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbClusterPlots(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbClusterPlots();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();
+
+ private:
+  /// TES location of clusters
+  std::string m_clusterLocation;
+  /// Index of reference plane
+  unsigned int m_referencePlane;
+  /// Time window (in ns) for correlation/difference plots
+  double m_twindow;
+
+  /// Parameters for ToT distribution histograms
+  Gaudi::Histo1DDef m_parToT;
+  /// Parameters for charge distribution histograms
+  Gaudi::Histo1DDef m_parCharge;
+  /// Parameters for x/y histograms (hitmaps and correlations)
+  Gaudi::Histo1DDef m_parXY;
+  /// Parameters for time histograms
+  Gaudi::Histo1DDef m_parTime;
+  /// Parameters for x/y difference histograms
+  Gaudi::Histo1DDef m_parDifferenceXY;
+  /// Parameters for phi difference histograms
+  Gaudi::Histo1DDef m_parDifferenceRot;
+  /// Parameters for time difference histograms
+  Gaudi::Histo1DDef m_parDifferenceT;
+  Gaudi::Histo1DDef m_parSamples;
+
+  AIDA::IHistogram1D* m_telHitOccupancy;
+  AIDA::IHistogram1D* m_telHitOccupancy_tracked;
+  AIDA::IHistogram1D* m_nClusters_vs_telHitOccupancy;
+  AIDA::IHistogram1D* m_nTrackedClusters_vs_telHitOccupancy;
+  AIDA::IHistogram1D* m_fractionTrackedClusters_vs_telHitOccupancy;
+
+  AIDA::IHistogram1D* m_telCharge;
+  AIDA::IHistogram1D* m_nClusters_vs_telCharge;
+  AIDA::IHistogram1D* m_nTrackedClusters_vs_telCharge;
+  AIDA::IHistogram1D* m_fractionTrackedClusters_vs_telCharge;
+
+  AIDA::IHistogram1D* m_telClusterOccupancy;
+  AIDA::IHistogram1D* m_telClusterOccupancy_tracked;
+  AIDA::IHistogram1D* m_nClusters_vs_telClusterOccupancy;
+  AIDA::IHistogram1D* m_nTrackedClusters_vs_telClusterOccupancy;
+  AIDA::IHistogram1D* m_fractionTrackedClusters_vs_telClusterOccupancy;
+
+  bool m_fillSamples;
+  bool m_fillComparisonPlots;     // Much faster to turn off.
+  bool m_fillTrackingEfficiency;  /// slow and pattern recognition-y
+  /// Cluster finder helper class
+  ITbClusterFinder* m_clusterFinder;
+  unsigned int m_event;
+  double m_chargeCutLow;
+
+  // Histograms
+  // ToT distribution
+  std::vector<AIDA::IHistogram1D*> m_hToT;
+  std::vector<AIDA::IHistogram1D*> m_hToTOnePixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTTwoPixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTThreePixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTFourPixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hToTNonAssociated;
+  // Charge distribution
+  std::vector<AIDA::IHistogram1D*> m_hCharge;
+  std::vector<AIDA::IHistogram1D*> m_hChargeOnePixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeTwoPixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeThreePixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeFourPixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hChargeNonAssociated;
+  // Cluster size
+  std::vector<AIDA::IHistogram1D*> m_hSize;
+  std::vector<AIDA::IHistogram1D*> m_hSizeAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hSizeNonAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hWidthCol;
+  std::vector<AIDA::IHistogram1D*> m_hWidthRow;
+  // Cluster time
+  std::vector<AIDA::IHistogram1D*> m_hTime;
+  std::vector<AIDA::IHistogram1D*> m_hTimeAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hTimeNonAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hTimeBetweenClusters;
+  // Time spread of pixel hits in a cluster
+  std::vector<AIDA::IHistogram1D*> m_hTimeSeedMinusHit;
+
+  // Hitmaps
+  std::vector<AIDA::IHistogram2D*> m_hHitMap;
+  std::vector<AIDA::IHistogram2D*> m_hHitMapAssociated;
+  std::vector<AIDA::IHistogram2D*> m_hHitMapNonAssociated;
+
+  AIDA::IHistogram2D* m_hGlobalXvsZ;
+  AIDA::IHistogram2D* m_hGlobalYvsZ;
+
+  // Global correlations.
+  std::vector<AIDA::IHistogram2D*> m_gx_correls;
+  std::vector<AIDA::IHistogram2D*> m_gy_correls;
+  std::vector<AIDA::IHistogram2D*> m_gt_correls;
+
+  // Global differences.
+  std::vector<AIDA::IHistogram1D*> m_gx_diffs;
+  std::vector<AIDA::IHistogram1D*> m_gy_diffs;
+  std::vector<AIDA::IHistogram1D*> m_gt_diffs;
+
+  std::vector<AIDA::IHistogram2D*> m_clusterVisuals;
+
+  void setupPlots();
+  void fillPerChipPlots(const LHCb::TbClusters* clusters);
+  void fillComparisonPlots();
+  void fillSamples(const LHCb::TbClusters* clusters);
+  void fillClusterVisuals(const LHCb::TbClusters* clusters);
+  void fillTrackingEfficiency();
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbClustering.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbClustering.cpp.svn-base
new file mode 100644
index 0000000..5b235a1
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbClustering.cpp.svn-base
@@ -0,0 +1,373 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+#include "TbKernel/TbCondFile.h"
+
+// Local
+#include "TbClustering.h"
+
+DECLARE_ALGORITHM_FACTORY(TbClustering)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbClustering::TbClustering(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TimeWindow", m_twindow = 100. * Gaudi::Units::ns);
+  declareProperty("SearchDist", m_searchDist = 1);
+  declareProperty("ClusterErrorMethod", m_clusterErrorMethod = 0);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbClustering::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  m_eta.resize(m_nPlanes);
+  for (const auto& filename : dataSvc()->getEtaConfig()) {
+    info() << "Importing eta corrections from " << filename << endmsg; 
+    readEta(filename);
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbClustering::execute() {
+
+  // Get the hits to be clustered - loop over planes.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string ext = std::to_string(i);
+    const std::string hitLocation = m_hitLocation + ext;
+    const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(hitLocation);
+    if (!hits) return Error("No hits in " + hitLocation);
+    // Create a cluster container and transfer its ownership to the TES.
+    LHCb::TbClusters* clusters = new LHCb::TbClusters();
+    put(clusters, m_clusterLocation + ext);
+    // Skip masked planes.
+    if (masked(i)) continue;
+    // Keep track of which hits have been clustered.
+    std::vector<bool> used(hits->size(), false);
+    std::vector<const LHCb::TbHit*> pixels;
+    pixels.reserve(100);
+    // Cycle over the (time ordered) hits.
+    for (LHCb::TbHits::const_iterator it = hits->begin(); it != hits->end();
+         ++it) {
+      // Skip hits which are already part of a cluster.
+      if (used[(*it)->key()]) continue;
+      // Start a cluster from this seed pixel and tag the seed as used.
+      used[(*it)->key()] = true;
+      pixels.clear();
+      pixels.push_back(*it);
+      // Get the search range.
+      const double tMax = (*it)->htime() + m_twindow;
+      LHCb::TbHits::const_iterator end = std::upper_bound(
+          it, hits->end(), tMax, lowerBound<const LHCb::TbHit*>());
+      // Add neighbouring hits in the cluster time window.
+      addNeighbouringHits(pixels, it, end, used);
+      // Sort the hits by time.
+      std::sort(pixels.begin(), pixels.end(),
+                TbFunctors::LessByTime<const LHCb::TbHit*>());
+      // Finally, set the remaining cluster attributes according to its hits.
+      completeCluster(i, pixels, clusters);
+    }
+    // Sort the clusters by time.
+    std::sort(clusters->begin(), clusters->end(),
+              TbFunctors::LessByTime<LHCb::TbCluster*>());
+    // Fill the counter.
+    counter("NumberOfClusters" + ext) += clusters->size();
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finding touching hits
+//=============================================================================
+void TbClustering::addNeighbouringHits(std::vector<const LHCb::TbHit*>& pixels,
+                                       LHCb::TbHits::const_iterator begin,
+                                       LHCb::TbHits::const_iterator end,
+                                       std::vector<bool>& used) {
+
+  // Keep track of the cluster's bounding box.
+  int scolmin = pixels.front()->scol();
+  int scolmax = scolmin;
+  int rowmin = pixels.front()->row();
+  int rowmax = rowmin;
+  // Try adding hits to the cluster.
+  bool hitAdded = true;
+  while (hitAdded) {
+    hitAdded = false;
+    unsigned int nUnused = 0;
+    for (LHCb::TbHits::const_iterator it = begin; it != end; ++it) {
+      // Skip hits which are already part of a cluster.
+      if (used[(*it)->key()]) continue;
+      ++nUnused;
+      const int scol = (*it)->scol();
+      const int row = (*it)->row();
+      if (scol < scolmin - m_searchDist) continue;
+      if (scol > scolmax + m_searchDist) continue;
+      if (row < rowmin - m_searchDist) continue;
+      if (row > rowmax + m_searchDist) continue;
+      // Ask if the hit is touching the cluster (with its current set of hits).
+      if (hitTouchesCluster((*it)->scol(), (*it)->row(), pixels)) {
+        // Add the hit to the cluster.
+        pixels.push_back(*it);
+        used[(*it)->key()] = true;
+        --nUnused;
+        hitAdded = true;
+        // Update the bounding box.
+        if (scol < scolmin)
+          scolmin = scol;
+        else if (scol > scolmax)
+          scolmax = scol;
+        if (row < rowmin)
+          rowmin = row;
+        else if (row > rowmax)
+          rowmax = row;
+      }
+    }
+    if (nUnused == 0) break;
+  }
+}
+
+//=============================================================================
+// Complete remaining cluster attributes
+//=============================================================================
+void TbClustering::completeCluster(
+    const unsigned int plane, const std::vector<const LHCb::TbHit*>& pixels,
+    LHCb::TbClusters* clusters) {
+
+  // Create a new cluster object.
+  LHCb::TbCluster* cluster = new LHCb::TbCluster();
+  cluster->setPlane(plane);
+  // Set cluster width along the column and row direction.
+  auto cols = std::minmax_element(pixels.cbegin(), pixels.cend(),
+                        [](const LHCb::TbHit* h1, const LHCb::TbHit* h2) {
+    return h1->scol() < h2->scol();
+  });
+  auto rows = std::minmax_element(pixels.cbegin(), pixels.cend(),
+                        [](const LHCb::TbHit* h1, const LHCb::TbHit* h2) {
+    return h1->row() < h2->row(); 
+  });
+  const unsigned int nCols =
+    1 + (*cols.second)->scol() - (*cols.first)->scol();
+  const unsigned int nRows = 1 + (*rows.second)->row() - (*rows.first)->row();
+  cluster->setCols(nCols);
+  cluster->setRows(nRows);
+  // Add the pixel hits to the cluster, sum up the charge and
+  // calculate the centre of gravity.
+  unsigned int tot = 0;
+  double charge = 0.;
+  double xLocal = 0.;
+  double yLocal = 0.;
+  for (auto it = pixels.cbegin(), end = pixels.cend(); it != end; ++it) {
+    cluster->addToHits(*it);
+    tot += (*it)->ToT();
+    const double q = (*it)->charge();
+    charge += q;
+    double x = 0.;
+    double y = 0.;
+    geomSvc()->pixelToPoint((*it)->scol(), (*it)->row(), plane, x, y);
+    xLocal += x * q;
+    yLocal += y * q;
+  }
+  cluster->setToT(tot);
+  cluster->setCharge(charge);
+  // Assume that the cluster time is the time of the earliest hit.
+  cluster->setTime(pixels.front()->time());
+  cluster->setHtime(pixels.front()->htime());
+  // Calculate the local and global coordinates.
+  xLocal /= charge;
+  yLocal /= charge;
+  // Apply eta-corrections.
+  etaCorrection(xLocal, yLocal, nCols, nRows, plane);
+  
+  cluster->setXloc(xLocal);
+  cluster->setYloc(yLocal);
+  const Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+  const auto pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+  cluster->setX(pGlobal.x());
+  cluster->setY(pGlobal.y());
+  cluster->setZ(pGlobal.z());
+  // Assign error estimates.
+  setClusterError(cluster);
+  // Add the cluster to the container.
+  clusters->insert(cluster);
+}
+
+//=============================================================================
+// Calculate the cluster error estimate.
+//=============================================================================
+void TbClustering::setClusterError(LHCb::TbCluster* cluster) const {
+
+  // Initialise the errors to some default value (for large cluster widths).
+  double dx = 0.1;
+  double dy = 0.1;
+  switch (m_clusterErrorMethod) {
+    case 0: {
+      constexpr std::array<double, 5> sigmas = {0.0027, 0.0035, 0.016, 0.045, 0.065};
+      if (cluster->cols() < 6) dx = sigmas[cluster->cols() - 1];
+      if (cluster->rows() < 6) dy = sigmas[cluster->rows() - 1];
+      break;
+    } 
+    case 2:
+      if (cluster->size() <= 6) {
+        dx = dy = 0.004;
+      } else {
+        // HS: not sure this makes sense
+        const double sigmaHit = (1. / sqrt(12.)) * Tb::PixelPitch;
+        dx = sigmaHit * cluster->cols();
+        dy = sigmaHit * cluster->rows();
+      }
+      break;
+    default:
+      dx = dy = 0.004;
+      break;
+  }
+  cluster->setXErr(dx);
+  cluster->setYErr(dy);
+  cluster->setWx(1. / (dx * dx));
+  cluster->setWy(1. / (dy * dy));
+}
+
+
+//=============================================================================
+// Read the eta correction parameters from file.
+//=============================================================================
+void TbClustering::readEta(const std::string& filename) {
+
+  TbCondFile f(filename);
+  if (!f.is_open()) {
+    warning() << "Cannot open " << filename << endmsg;
+    return;
+  }
+  unsigned int indexPlane = 999;
+  unsigned int indexXy = 0;
+  unsigned int indexCol = 0;
+  unsigned int nLines = 0;
+  while (!f.eof()) {
+    std::string line = "";
+    ++nLines;
+    if (!f.getLine(line)) continue;
+    if (line.find("Plane") != std::string::npos) {
+      indexPlane = 999;
+      std::string key = "";
+      std::string id = "";
+      std::string xy = "";
+      int cols = 0;
+      if (!f.split(line, ' ', key, id, xy, cols)) {
+        warning() << "Error reading line " << nLines << endmsg;
+        continue;
+      }
+      // Find the index corresponding to the given plane name. 
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        if (id == geomSvc()->modules()[i]->id()) {
+          indexPlane = i;
+          break;
+        }
+      } 
+      if (indexPlane == 999) {
+        warning() << "Module " << id 
+                  << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      // Check whether this set of parameters is for the x or the y direction.
+      if (xy == "x" || xy == "X") {
+        indexXy = 0;
+      } else if (xy == "y" || xy == "Y") {
+        indexXy = 1;
+      } else {
+        warning() << "Unexpected direction specifier " << xy 
+                  << " (expected x or y). Skip this parameter set." << endmsg;
+        indexPlane = 999;
+        continue;
+      }
+      // Check the cluster width.
+      if (cols < 2) {
+        warning() << "Unexpected cluster width (" << cols
+                  << "). Skip this parameter set." << endmsg;
+        indexPlane = 999;
+        continue; 
+      }
+      indexCol = cols - 2;
+      if (m_eta[indexPlane][indexXy].size() < indexCol + 1) {
+        m_eta[indexPlane][indexXy].resize(indexCol + 1);
+      }
+      const std::string rowcol = indexXy == 0 ? " columns." : " rows.";
+      info() << "Reading eta-correction parameters for plane " << indexPlane
+             << " for clusters covering " << cols << rowcol << endmsg;
+      m_eta[indexPlane][indexXy][indexCol].clear();
+    } else {
+      if (indexPlane == 999) continue;
+      // Read the intra-pixel interval and the coefficients of the polynomial.
+      double xmin = 0., xmax = 0.;
+      double a = 0., b = 0., c = 0.;
+      if (!f.split(line, ' ', xmin, xmax, a, b, c)) {
+        warning() << "Error reading line " << nLines << endmsg;
+        continue;
+      }
+      EtaCorrection corr;
+      corr.xmin = xmin;
+      corr.xmax = xmax;
+      corr.coefficients = {a, b, c};
+      m_eta[indexPlane][indexXy][indexCol].push_back(corr);
+    }
+  }
+
+}
+
+//=============================================================================
+// Calculate the eta correction terms.
+//=============================================================================
+void TbClustering::etaCorrection(double& xLocal, double& yLocal,
+                                 const unsigned int nCols, 
+                                 const unsigned int nRows, 
+                                 const unsigned int plane) const { 
+
+  // No point to continue in case of single-pixel clusters.
+  if (nCols * nRows == 1) return;
+  // Calculate the intra-pixel coordinates of the cluster.
+  unsigned int scol = 0, row = 0;
+  geomSvc()->pointToPixel(xLocal, yLocal, plane, scol, row);
+  double x0 = 0., y0 = 0.;
+  geomSvc()->pixelToPoint(scol, row, plane, x0, y0);
+  // TODO: this only works for single-chip assemblies.
+  const double x = xLocal - x0 + 0.5 * Tb::PixelPitch;
+  const double y = yLocal - y0 + 0.5 * Tb::PixelPitch;
+  // Calculate the correction terms.
+  if (nCols > 1 && m_eta[plane][0].size() > nCols - 2) {
+    const auto& corrections = m_eta[plane][0][nCols - 2];
+    for (const auto& corr : corrections) {
+      if (x >= corr.xmin && x < corr.xmax) {
+        xLocal += corr.coefficients[0] + corr.coefficients[1] * x + 
+                  corr.coefficients[2] * x * x;
+        break;
+      }
+    }
+  } 
+  if (nRows > 1 && m_eta[plane][1].size() > nRows - 2) {
+    const auto& corrections = m_eta[plane][1][nRows - 2];
+    for (const auto& corr : corrections) {
+      if (y >= corr.xmin && y < corr.xmax) {
+        yLocal += corr.coefficients[0] + corr.coefficients[1] * y + 
+                  corr.coefficients[2] * y * y;
+        break;
+      }
+    }
+  } 
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbClustering.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbClustering.h.svn-base
new file mode 100644
index 0000000..583de7f
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbClustering.h.svn-base
@@ -0,0 +1,80 @@
+#ifndef TB_CLUSTERING_H
+#define TB_CLUSTERING_H 1
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbClustering TbClustering.h
+ *
+ *  Algorithm to group together touching Timepix3 pixel hits.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbClustering : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbClustering(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbClustering() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location prefix of hits
+  std::string m_hitLocation;
+  /// TES location prefix of clusters
+  std::string m_clusterLocation;
+  /// Time window (in ns)
+  double m_twindow;
+  /// Max. distance between two pixels to be grouped together
+  int m_searchDist;
+  /// Cluster error calculation (0 for constant, 1 for COG error propagation
+  int m_clusterErrorMethod;
+  /// Eta-correction parameterisation.
+  struct EtaCorrection {
+    double xmin, xmax;
+    std::vector<double> coefficients;
+  };
+  /// Set of eta-correction parameters per plane, direction, and cluster width.
+  std::vector<std::array<std::vector<std::vector<EtaCorrection> >, 2> > m_eta;
+
+  /// Add pixels to a given seed pixel.
+  void addNeighbouringHits(std::vector<const LHCb::TbHit*>& pixels,
+                           LHCb::TbHits::const_iterator begin,
+                           LHCb::TbHits::const_iterator end,
+                           std::vector<bool>& used);
+  /// Check if a hit touches any of the pixels in a given cluster.
+  bool hitTouchesCluster(const int scol, const int row,
+                         const std::vector<const LHCb::TbHit*>& pixels) const {
+
+    bool result = false;
+    for (auto it = pixels.cbegin(), end = pixels.cend(); it != end; ++it) {
+      if ((abs(int((*it)->scol()) - scol) <= m_searchDist) &&
+          (abs(int((*it)->row()) - row) <= m_searchDist)) {
+        result = true;
+        break;
+      }
+    }
+    return result;
+  }
+
+  /// Set cluster attributes (position, time, ADC).
+  void completeCluster(const unsigned int plane,
+                       const std::vector<const LHCb::TbHit*>& pixels,
+                       LHCb::TbClusters* clusters);
+  /// Calculate the cluster errors.
+  void setClusterError(LHCb::TbCluster* cluster) const;
+  /// Calculate the eta-correction.
+  void etaCorrection(double& xLocal, double& yLocal,
+                     const unsigned int nCols, const unsigned int nRows,
+                     const unsigned int plane) const;
+  void readEta(const std::string& filename);
+
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbDUTMonitor.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbDUTMonitor.cpp.svn-base
new file mode 100644
index 0000000..6d4efe5
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbDUTMonitor.cpp.svn-base
@@ -0,0 +1,292 @@
+// AIDA
+#include "AIDA/IAxis.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbDUTMonitor.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbDUTMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbDUTMonitor::TbDUTMonitor(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parResXY("", -0.2, 0.2, 200),
+      m_parXY("", -20, 20, 500),
+      m_parScanX("", 0, 0, 1),
+      m_parScanY("", 0, 0, 1),
+      m_parResTime("", -100., 100., 2000) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("DUTs", m_duts);
+
+  declareProperty("ScanX", m_parScanX);
+  declareProperty("ScanY", m_parScanY);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbDUTMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Setup the histograms.
+  const unsigned int nDuts = m_duts.size();
+  for (unsigned int i = 0; i < nDuts; ++i) {
+    m_index[m_duts[i]] = i;
+    const std::string plane = std::to_string(m_duts[i]);
+    const std::string title = geomSvc()->modules().at(m_duts[i])->id();
+
+    unsigned int bins = m_parResXY.bins();
+    double low = m_parResXY.lowEdge();
+    double high = m_parResXY.highEdge();
+    std::string name = "ResidualsLocalX/Plane" + plane;
+    m_hResLocalX.push_back(book1D(name, title, low, high, bins));
+    name = "ResidualsLocalY/Plane" + plane;
+    m_hResLocalY.push_back(book1D(name, title, low, high, bins));
+    name = "ResidualsGlobalX/Plane" + plane;
+    m_hResGlobalX.push_back(book1D(name, title, low, high, bins));
+    name = "ResidualsGlobalY/Plane" + plane;
+    m_hResGlobalY.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hResLocalX[i], "#it{x} - #it{x}_{track} [mm]", "entries");
+    setAxisLabels(m_hResLocalY[i], "#it{y} - #it{y}_{track} [mm]", "entries");
+
+    unsigned int binsXY = m_parXY.bins();
+    double lowXY = m_parXY.lowEdge();
+    double highXY = m_parXY.highEdge();
+
+    m_hUnbiasedResGlobalXvsGlobalX.push_back(
+        book2D("GlobalResXvsGlobalX/Plane" + plane, title, lowXY, highXY,
+               binsXY, low, high, bins));
+
+    m_hUnbiasedResGlobalYvsGlobalY.push_back(
+        book2D("GlobalResYvsGlobalY/Plane" + plane, title, lowXY, highXY,
+               binsXY, low, high, bins));
+
+    m_hUnbiasedResGlobalXvsTrackChi2.push_back(
+        book2D("GlobalResXvsTrackChi2/Plane" + plane, title, 0, 100, 1000, low,
+               high, bins));
+    m_hUnbiasedResGlobalYvsTrackChi2.push_back(
+        book2D("GlobalResYvsTrackChi2/Plane" + plane, title, 0, 100, 1000, low,
+               high, bins));
+
+    m_hUnbiasedResGlobalXvsTrackTx.push_back(
+        book2D("GlobalResXvsTrackTx/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+    m_hUnbiasedResGlobalXvsTrackTy.push_back(
+        book2D("GlobalResXvsTrackTy/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+    m_hUnbiasedResGlobalYvsTrackTx.push_back(
+        book2D("GlobalResYvsTrackTx/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+    m_hUnbiasedResGlobalYvsTrackTy.push_back(
+        book2D("GlobalResYvsTrackTy/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+
+    m_hUnbiasedResGlobalXvsPixelX.push_back(
+        book2D("UnbiasedResGlobalXvsPixelX/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalXvsPixelY.push_back(
+        book2D("UnbiasedResGlobalXvsPixelY/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalYvsPixelX.push_back(
+        book2D("UnbiasedResGlobalYvsPixelX/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalYvsPixelY.push_back(
+        book2D("UnbiasedResGlobalYvsPixelY/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalXvsClusterSize.push_back(
+        book2D("GlobalResXvsClusterSize/Plane" + plane, title, 0.5, 10.5, 10,
+               low, high, bins));
+    m_hUnbiasedResGlobalYvsClusterSize.push_back(
+        book2D("GlobalResYvsClusterSize/Plane" + plane, title, 0.5, 10.5, 10,
+               low, high, bins));
+
+    //   m_UnbiasedResGlobalXvshUnbiasedResGlobalY
+    m_UnbiasedResGlobalXvshUnbiasedResGlobalY.push_back(
+        book2D("UnbiasedResGlobalXvshUnbiasedResGlobalY/Plane" + plane, title,
+               low, high, bins, low, high, bins));
+
+    bins = m_parResTime.bins();
+    low = m_parResTime.lowEdge();
+    high = m_parResTime.highEdge();
+    name = "ResidualsTime/Plane" + plane;
+    m_hResTime.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hResTime[i], "#it{t} - #it{t}_{track} [ns]", "entries");
+  }
+  std::vector<std::string> labels = {"X", "Y", "Z", "rotX", "rotY", "rotZ"};
+  unsigned int binsXY = m_parXY.bins();
+  double lowXY = m_parXY.lowEdge();
+  double highXY = m_parXY.highEdge();
+  unsigned int bins = m_parResXY.bins();
+  double low = m_parResXY.lowEdge();
+  double high = m_parResXY.highEdge();
+
+  if (nDuts == 0) return sc;
+  TbModule* mod = geomSvc()->module(m_duts[0]);
+  std::vector<bool> xaxis(6, 0);
+  std::vector<bool> yaxis(6, 0);
+  std::vector<std::string>::iterator xL =
+      std::find(labels.begin(), labels.end(), m_parScanX.title());
+  std::vector<std::string>::iterator yL =
+      std::find(labels.begin(), labels.end(), m_parScanY.title());
+  if (xL != labels.end()) xaxis[xL - labels.begin()] = 1;
+  if (yL != labels.end()) yaxis[yL - labels.begin()] = 1;
+
+  if (xL != labels.end()) {
+    for (int i = 0; i < m_parScanX.bins(); ++i) {
+      const double px = m_parScanX.lowEdge() +
+                        i * (m_parScanX.highEdge() - m_parScanX.lowEdge()) /
+                            m_parScanX.bins();
+      std::string label =
+          "Scan #Delta" + m_parScanX.title() + " = " + std::to_string(px);
+      if (yL == labels.end()) {
+        info() << "Booking scan " << *xL << " = " << px << endmsg;
+        m_hScanXvsX.push_back(book2D("XvsX/Scan" + std::to_string(i), label,
+                                     lowXY, highXY, binsXY, low, high, bins));
+        m_hScanYvsY.push_back(book2D("YvsY/Scan" + std::to_string(i), label,
+                                     lowXY, highXY, binsXY, low, high, bins));
+        m_testModules.push_back(new TbModule());
+        (*m_testModules.rbegin())->setAlignment(
+            mod->x() + px * xaxis[0], mod->y() + px * xaxis[1],
+            mod->z() + px * xaxis[2], mod->rotX() + px * xaxis[3],
+            mod->rotY() + px * xaxis[4], mod->rotZ() + px * xaxis[5], 0, 0, 0,
+            0, 0, 0);
+      } else {
+        for (int j = 0; j < m_parScanY.bins(); ++j) {
+
+          const double py = m_parScanY.lowEdge() +
+                            j * (m_parScanY.highEdge() - m_parScanY.lowEdge()) /
+                                m_parScanY.bins();
+
+          info() << "Booking scan " << *xL << " = " << px << ", " << *yL
+                 << " = " << py << endmsg;
+
+          std::string l =
+              label + ", " + m_parScanY.title() + " = " + std::to_string(py);
+          m_hScanXvsX.push_back(
+              book2D("XvsX/Scan" + std::to_string(i * m_parScanY.bins() + j), l,
+                     lowXY, highXY, binsXY, low, high, bins));
+          m_hScanYvsY.push_back(
+              book2D("YvsY/Scan" + std::to_string(i * m_parScanY.bins() + j), l,
+                     lowXY, highXY, binsXY, low, high, bins));
+          m_testModules.push_back(new TbModule());
+
+          (*m_testModules.rbegin())->setAlignment(
+              mod->x() + px * xaxis[0] + py * yaxis[0],
+              mod->y() + px * xaxis[1] + py * yaxis[1],
+              mod->z() + px * xaxis[2] + py * yaxis[2],
+              mod->rotX() + px * xaxis[3] + py * yaxis[3],
+              mod->rotY() + px * xaxis[4] + py * yaxis[4],
+              mod->rotZ() + px * xaxis[5] + py * yaxis[5], 0, 0, 0, 0, 0, 0);
+        }
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbDUTMonitor::execute() {
+
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+  // Loop over the tracks.
+  for (const LHCb::TbTrack* track : *tracks) {
+    auto clusters = track->associatedClusters();
+    for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+      const unsigned int plane = (*it)->plane();
+      if (m_index.count(plane) < 1) continue;
+      const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, plane);
+      const auto pLocal = geomSvc()->globalToLocal(pGlobal, plane);
+      const unsigned int i = m_index[plane];
+      const double dt = (*it)->htime() - track->htime();
+      const double dx = (*it)->xloc() - pLocal.x();
+      const double dy = (*it)->yloc() - pLocal.y();
+      m_hResLocalX[i]->fill(dx);
+      m_hResLocalY[i]->fill(dy);
+
+      const double dxug = (*it)->x() - pGlobal.x();
+      const double dyug = (*it)->y() - pGlobal.y();
+      m_hResGlobalX[i]->fill(dxug);
+      m_hResGlobalY[i]->fill(dyug);
+      m_hUnbiasedResGlobalXvsGlobalX[i]->fill((*it)->x(), dxug);
+      m_hUnbiasedResGlobalYvsGlobalY[i]->fill((*it)->y(), dyug);
+      m_hResTime[i]->fill(dt);
+
+      m_hUnbiasedResGlobalXvsTrackChi2[i]->fill(track->chi2PerNdof(), dxug);
+      m_hUnbiasedResGlobalYvsTrackChi2[i]->fill(track->chi2PerNdof(), dyug);
+
+      m_UnbiasedResGlobalXvshUnbiasedResGlobalY[i]->fill(dxug, dyug);
+
+      m_hUnbiasedResGlobalXvsTrackTx[i]->fill(track->firstState().tx(), dxug);
+      m_hUnbiasedResGlobalXvsTrackTy[i]->fill(track->firstState().ty(), dxug);
+
+      m_hUnbiasedResGlobalYvsTrackTx[i]->fill(track->firstState().tx(), dyug);
+      m_hUnbiasedResGlobalYvsTrackTy[i]->fill(track->firstState().ty(), dyug);
+
+      m_hUnbiasedResGlobalXvsClusterSize[i]->fill((*it)->hits().size(), dxug);
+      m_hUnbiasedResGlobalYvsClusterSize[i]->fill((*it)->hits().size(), dyug);
+
+      unsigned int row, col;
+
+      geomSvc()->pointToPixel(pLocal.x(), pLocal.y(), 4, col, row);
+      double x0, y0;
+      geomSvc()->pixelToPoint(col, row, 4, x0, y0);
+
+      const double pixelX = (pLocal.x() - x0) / 0.055;
+      const double pixelY = (pLocal.y() - y0) / 0.055;
+
+      m_hUnbiasedResGlobalXvsPixelX[i]->fill(pixelX, dxug);
+      m_hUnbiasedResGlobalXvsPixelY[i]->fill(pixelY, dxug);
+      m_hUnbiasedResGlobalYvsPixelX[i]->fill(pixelX, dyug);
+      m_hUnbiasedResGlobalYvsPixelY[i]->fill(pixelY, dyug);
+
+      for (int j = 0; j < m_testModules.size(); ++j) {
+
+        const auto& p = track->firstState().position();
+        const auto& t = track->firstState().slopes();
+        const Gaudi::XYZVector n = m_testModules[j]->normal();
+        const double s = n.Dot(m_testModules[j]->centre() - p) / n.Dot(t);
+        const auto intercept = p + s * t;
+        const auto cl = m_testModules[j]->transform() *
+                        Gaudi::XYZPoint((*it)->xloc(), (*it)->yloc(), 0);
+        const double dxug = cl.x() - intercept.x();
+        const double dyug = cl.y() - intercept.y();
+        m_hScanXvsX[j]->fill(cl.x(), dxug);
+        m_hScanYvsY[j]->fill(cl.y(), dyug);
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbDUTMonitor.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbDUTMonitor.h.svn-base
new file mode 100644
index 0000000..7b2e7d7
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbDUTMonitor.h.svn-base
@@ -0,0 +1,67 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbDUTMonitor TbDUTMonitor.h
+ *
+ */
+
+class TbDUTMonitor : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbDUTMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbDUTMonitor() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<unsigned int> m_duts;
+  std::map<unsigned int, unsigned int> m_index;
+
+  std::string m_trackLocation;
+
+  /// Parameters for x/y residual histograms
+  Gaudi::Histo1DDef m_parResXY;
+  Gaudi::Histo1DDef m_parXY;
+  Gaudi::Histo1DDef m_parScanX;
+  Gaudi::Histo1DDef m_parScanY;
+
+  /// Parameters for time residual histograms
+  Gaudi::Histo1DDef m_parResTime;
+
+  std::vector<AIDA::IHistogram1D*> m_hResLocalX;
+  std::vector<AIDA::IHistogram1D*> m_hResLocalY;
+  std::vector<AIDA::IHistogram1D*> m_hResGlobalX;
+  std::vector<AIDA::IHistogram1D*> m_hResGlobalY;
+  std::vector<AIDA::IHistogram1D*> m_hResTime;
+
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsGlobalX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsGlobalY;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsTrackChi2;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsTrackChi2;
+
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsPixelX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsPixelY;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsPixelX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsPixelY;
+
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsTrackTx;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsTrackTy;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsTrackTx;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsTrackTy;
+  std::vector<AIDA::IHistogram2D*> m_UnbiasedResGlobalXvshUnbiasedResGlobalY;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsClusterSize;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsClusterSize;
+
+  std::vector<AIDA::IHistogram2D*> m_hScanXvsX;
+  std::vector<AIDA::IHistogram2D*> m_hScanYvsY;
+
+  std::vector<TbModule*> m_testModules;
+};
diff --git a/TbAlgorithms/src/.svn/text-base/TbHitMonitor.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbHitMonitor.cpp.svn-base
new file mode 100644
index 0000000..a27bfa5
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbHitMonitor.cpp.svn-base
@@ -0,0 +1,137 @@
+// Gaudi
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbHitMonitor.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbHitMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbHitMonitor::TbHitMonitor(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parToT("", 0.5, 1024.5, 1024),
+      m_parCharge("", 0., 20000., 200),
+      m_parHitsInEvent("", 0., 10000., 100),
+      m_parDeltaT("", 0., 100., 200),
+      m_nEvents(0) {
+
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+
+  declareProperty("ParametersToT", m_parToT);
+  declareProperty("ParametersCharge", m_parCharge);
+  declareProperty("ParametersHitsInEvent", m_parHitsInEvent);
+  declareProperty("ParametersDeltaT", m_parDeltaT);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbHitMonitor::~TbHitMonitor() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbHitMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Setup the histograms.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+    const unsigned int nRows = Tb::NRows;
+    const unsigned int nCols = geomSvc()->modules().at(i)->cols();
+    std::string name = "HitMap/Plane" + plane;
+
+    m_hHitMap.push_back(book2D(name, title, -0.5, nCols - 0.5, nCols, -0.5,
+                               nRows - 0.5, nRows));
+    setAxisLabels(m_hHitMap[i], "column", "row");
+
+    int bins = m_parToT.bins();
+    double low = m_parToT.lowEdge();
+    double high = m_parToT.highEdge();
+    name = "ToT/Plane" + plane;
+    m_hToT.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hToT[i], "ToT", "entries");
+
+    bins = m_parCharge.bins();
+    low = m_parCharge.lowEdge();
+    high = m_parCharge.highEdge();
+    name = "Charge/Plane" + plane;
+    m_hCharge.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hCharge[i], "charge [electrons]", "entries");
+
+    name = "ToTvsCol/Plane" + plane;
+    m_hToTvsCol.push_back(bookProfile1D(name, title, 
+                                        -0.5, nCols - 0.5, nCols));
+    setAxisLabels(m_hToTvsCol[i], "column", "ToT");
+
+    name = "ChargevsCol/Plane" + plane;
+    m_hChargevsCol.push_back(bookProfile1D(name, title, 
+                             -0.5, nCols - 0.5, nCols));
+    setAxisLabels(m_hChargevsCol[i], "column", "charge [electrons]");
+
+    bins = m_parHitsInEvent.bins();
+    low = m_parHitsInEvent.lowEdge();
+    high = m_parHitsInEvent.highEdge();
+    name = "HitsInEvent/Plane" + plane;
+    m_hHitsInEvent.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hHitsInEvent[i], "number of hits", "events");
+    name = "HitsInEventTrend/Plane" + plane;
+    m_hHitsInEventTrend.push_back(book1D(name, title, -0.5, 999.5, 1000));
+    setAxisLabels(m_hHitsInEventTrend[i], "event", "number of hits");
+
+    bins = m_parDeltaT.bins();
+    low = m_parDeltaT.lowEdge();
+    high = m_parDeltaT.highEdge();
+    name = "TimeBetweenHits/Plane" + plane;
+    m_hTimeBetweenHits.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hTimeBetweenHits[i], "#Deltat [ns]", "entries");
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbHitMonitor::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Grab the hits.
+    const std::string hitLocation = m_hitLocation + std::to_string(i);
+    const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(hitLocation);
+    if (!hits) continue;
+    m_hHitsInEvent[i]->fill(hits->size());
+    m_hHitsInEventTrend[i]->fill(m_nEvents, hits->size());
+    if (hits->empty()) continue;
+    double tprev = 0.;
+    LHCb::TbHits::const_iterator begin = hits->begin();
+    LHCb::TbHits::const_iterator end = hits->end();
+    for (LHCb::TbHits::const_iterator ith = begin; ith != end; ++ith) {
+      const LHCb::TbHit* hit = *ith;
+      m_hToT[i]->fill(hit->ToT());
+      m_hCharge[i]->fill(hit->charge());
+      m_hToTvsCol[i]->fill(hit->scol(), hit->ToT());
+      m_hChargevsCol[i]->fill(hit->scol(), hit->charge());
+      m_hHitMap[i]->fill(hit->scol(), hit->row());
+      const double t = hit->htime();
+      if (ith != begin) m_hTimeBetweenHits[i]->fill(t - tprev);
+      tprev = t;
+    }
+  }
+  ++m_nEvents;
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbHitMonitor.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbHitMonitor.h.svn-base
new file mode 100644
index 0000000..fef9763
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbHitMonitor.h.svn-base
@@ -0,0 +1,55 @@
+#ifndef TB_HIT_MONITOR_H
+#define TB_HIT_MONITOR_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+#include "AIDA/IProfile1D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbHitMonitor TbHitMonitor.h
+ *
+ *  Algorithm to produce monitoring histograms for Timepix3 pixel hits.
+ *
+ *  @author Tim Evans (timothy.david.evans@cern.ch)
+ *  @date   2014-04-01
+ */
+
+class TbHitMonitor : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbHitMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbHitMonitor();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location of hits.
+  std::string m_hitLocation;
+  /// Parameters for ToT distribution histograms
+  Gaudi::Histo1DDef m_parToT;
+  /// Parameters for charge distribution histograms
+  Gaudi::Histo1DDef m_parCharge;
+  /// Parameters for hits / event distribution histograms
+  Gaudi::Histo1DDef m_parHitsInEvent;
+  /// Parameters for time difference histograms
+  Gaudi::Histo1DDef m_parDeltaT;
+
+  /// Event counter
+  unsigned int m_nEvents;
+
+  std::vector<AIDA::IHistogram2D*> m_hHitMap;
+  std::vector<AIDA::IHistogram1D*> m_hToT;
+  std::vector<AIDA::IHistogram1D*> m_hCharge;
+  std::vector<AIDA::IProfile1D*> m_hToTvsCol;
+  std::vector<AIDA::IProfile1D*> m_hChargevsCol;
+  std::vector<AIDA::IHistogram1D*> m_hHitsInEvent;
+  std::vector<AIDA::IHistogram1D*> m_hHitsInEventTrend;
+  std::vector<AIDA::IHistogram1D*> m_hTimeBetweenHits;
+};
+
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbSimpleTracking.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbSimpleTracking.cpp.svn-base
new file mode 100644
index 0000000..bf35330
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbSimpleTracking.cpp.svn-base
@@ -0,0 +1,393 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbSimpleTracking.h"
+
+DECLARE_ALGORITHM_FACTORY(TbSimpleTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbSimpleTracking::TbSimpleTracking(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_trackFit(nullptr) {
+
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+  declareProperty("TimeWindow", m_timeWindow = 10. * Gaudi::Units::ns);
+  declareProperty("MinPlanes", m_nMinPlanes = 8);
+  declareProperty("MaxDistance", m_maxDist = 0. * Gaudi::Units::mm);
+  declareProperty("MaxOpeningAngle", m_maxAngle = 0.01);
+  declareProperty("RecheckTrack", m_recheckTrack = true);
+  declareProperty("RemoveOutliers", m_removeOutliers = true);
+  declareProperty("ChargeCutLow", m_chargeCutLow = 0);
+  declareProperty("MaxClusterSize", m_maxClusterSize = 10);
+  declareProperty("MaxClusterWidth", m_maxClusterWidth = 3);
+  declareProperty("MaxOccupancy", m_maxOccupancy = 8);
+  declareProperty("DoOccupancyCut", m_doOccupancyCut = false);
+  declareProperty("Monitoring", m_monitoring = false);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbSimpleTracking::initialize() {
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  m_clusters.resize(m_nPlanes, nullptr);
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+
+  m_nMaxPlanes = 0;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (!masked(i)) ++m_nMaxPlanes;
+  }
+  if (m_nMaxPlanes == 0) return Error("All planes are masked.");
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbSimpleTracking::execute() {
+
+  // Get the clusters on each plane.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      return Error("No clusters in " + LHCb::TbClusterLocation::Default);
+    }
+    m_clusters[i] = clusters;
+  }
+
+  if (m_doOccupancyCut) findHighOccupancies();
+  unsigned int nKilledOccupancyCut = 0;
+  // Check if there is already a track container.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    // Create a track container and transfer its ownership to the TES.
+    tracks = new LHCb::TbTracks();
+    put(tracks, m_trackLocation);
+  }
+  LHCb::TbTrack* track = nullptr;
+  const unsigned int lastPlane = m_nPlanes - 2;
+  for (unsigned int i = 0; i < lastPlane; ++i) {
+    if (masked(i)) continue;
+    // Get the next valid plane.
+    unsigned int j = i + 1;
+    while (masked(j) && j <= lastPlane) ++j;
+    if (j > lastPlane) break;
+    LHCb::TbClusters::iterator first0 = m_clusters[i]->begin();
+    LHCb::TbClusters::iterator first1 = m_clusters[j]->begin();
+    LHCb::TbClusters::iterator end0 = m_clusters[i]->end();
+    LHCb::TbClusters::iterator end1 = m_clusters[j]->end();
+    for (LHCb::TbClusters::iterator it0 = first0; it0 != end0; ++it0) {
+      // Skip clusters already assigned to tracks.
+      if ((*it0)->associated()) continue;
+      // Skip clusters with too low ToT.
+      if ((*it0)->ToT() < m_chargeCutLow) continue;
+      // Skip large clusters.
+      if ((*it0)->size() > m_maxClusterSize) continue;
+      if (((*it0)->cols() > m_maxClusterWidth) || 
+          ((*it0)->rows() > m_maxClusterWidth)) continue;
+      const double t0 = (*it0)->htime();
+      const double tMin = t0 - m_timeWindow;
+      const double tMax = t0 + m_timeWindow;
+      // Loop over the hits in the second plane.
+      for (LHCb::TbClusters::iterator it1 = first1; it1 != end1; ++it1) {
+        const double t1 = (*it1)->htime();
+        // Skip hits below the time limit.
+        if (t1 < tMin) {
+          // Update the search range.
+          first1 = it1 + 1;
+          continue;
+        }
+        // Stop search when above the time limit.
+        if (t1 > tMax) break;
+        // Skip clusters already assigned to tracks.
+        if ((*it1)->associated()) continue;
+        // Skip clusters with too low charge.
+        if ((*it1)->ToT() < m_chargeCutLow) continue;
+        // Skip large clusters.
+        if ((*it1)->size() > m_maxClusterSize) continue;
+        if (((*it1)->cols() > m_maxClusterWidth) || 
+            ((*it1)->rows() > m_maxClusterWidth)) continue;
+        if (!track)
+          track = new LHCb::TbTrack();
+        else
+          track->clearClusters();
+
+        track->addToClusters(*it0);
+        track->addToClusters(*it1);
+        if (!extendTrack(track, true)) continue;
+        // Fit the track.
+        m_trackFit->fit(track);
+        if (m_recheckTrack) recheckTrack(track);
+        // Check if there are enough measurements on the track.
+        if (track->clusters().size() < m_nMinPlanes) continue;
+        // Check if there are enough unused clusters on the track.
+        /*
+        unsigned int nUnused = 0;
+        for (const LHCb::TbCluster* cluster : track->clusters()) {
+          if (!cluster->associated()) ++nUnused;
+        }
+        if (nUnused < 5) continue;
+        */
+        if (!lowClusterOccupancy(track->htime())) {
+          ++nKilledOccupancyCut;
+          continue;
+        }
+        auto clusters = const_cast<SmartRefVector<LHCb::TbCluster>&>(track->clusters());
+        // Sort the clusters by plane.
+        std::sort(clusters.begin(), clusters.end(),
+                  TbFunctors::LessByZ<const LHCb::TbCluster*>());
+        // Tag the clusters as used.
+        for (auto itc = clusters.begin(), end = clusters.end(); itc != end;
+             ++itc) {
+          (*itc)->setAssociated(true);
+        }
+        // Calculate the global timestamp and add the track to the container.
+        track->setTime(timingSvc()->localToGlobal(track->htime()));
+        tracks->insert(track);
+        track = nullptr;
+      }
+    }
+  }
+  if (track) delete track;
+
+  // Sort the tracks by time.
+  std::sort(tracks->begin(), tracks->end(),
+            TbFunctors::LessByTime<const LHCb::TbTrack*>());
+  // Fill the counters.
+  counter("Number of tracks") += tracks->size();
+  counter("Number of tracks removed by occupancy cut") += nKilledOccupancyCut;
+  appendTrackingEfficiencies();
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Extrapolate and try to add clusters to a given seed track
+//=============================================================================
+bool TbSimpleTracking::extendTrack(LHCb::TbTrack* track, const bool fwd) {
+
+  unsigned int nAdded = 0;
+  // Count planes without matching clusters.
+  unsigned int nMissed = 0;
+  const LHCb::TbCluster* c1 = track->clusters().front();
+  const LHCb::TbCluster* c2 = track->clusters().back();
+  if (!fwd) {
+    c2 = c1;
+    c1 = track->clusters().at(1);
+  }
+  double t = c2->htime();
+  // Calculate the track slopes based on the first two clusters on the track.
+  double td = 1. / (c2->z() - c1->z());
+  double tx = (c2->x() - c1->x()) * td;
+  double ty = (c2->y() - c1->y()) * td;
+  unsigned int plane = c2->plane();
+  if (fwd) {
+    plane += 1;
+  } else {
+    plane -= 1;
+  }
+  while (plane < m_nPlanes) {
+    // Calculate the extrapolated position on this plane. 
+    const double dz = geomSvc()->modules().at(plane)->z() - c1->z();
+    const double xPred = c1->x() + tx * dz;
+    const double yPred = c1->y() + ty * dz;
+    // Calculate the tolerance window.
+    const double tol = fabs(dz * m_maxAngle) + m_maxDist;
+    // Try adding clusters on this plane.
+    const LHCb::TbCluster* c3 = bestCluster(plane, xPred, yPred, t, tol);
+    if (c3) {
+      // Add the cluster.
+      track->addToClusters(c3);
+      ++nAdded;
+      // Reset the missed plane counter.
+      nMissed = 0;
+      // Update the pair of clusters to be used for extrapolating.
+      if ((c3->cols() <= m_maxClusterWidth) && 
+          (c3->rows() <= m_maxClusterWidth)) {
+        c1 = c2;
+        c2 = c3;
+        // Update the track slopes.
+        td = 1. / (c2->z() - c1->z());
+        tx = (c2->x() - c1->x()) * td;
+        ty = (c2->y() - c1->y()) * td;
+      }
+      // Update the predicted timestamp.
+      t = c3->htime();
+    } else {
+      // No matching cluster.
+      ++nMissed;
+      if (nMissed > 1) break;
+    }
+    if (fwd) {
+      ++plane;
+    } else {
+      if (plane == 0) break;
+      --plane;
+    }
+  }
+  return nAdded > 0;
+}
+
+//=============================================================================
+// Get the closest cluster to a given point on the plane
+//=============================================================================
+const LHCb::TbCluster* TbSimpleTracking::bestCluster(const unsigned int plane, 
+    const double xPred, const double yPred,
+    const double tPred, const double tol) {
+  if (masked(plane) || m_clusters[plane]->empty()) return nullptr;
+  // Get the first cluster within the time window.
+  const double tMin = tPred - m_timeWindow;
+  LHCb::TbClusters::iterator end = m_clusters[plane]->end();
+  LHCb::TbClusters::iterator it =
+      std::lower_bound(m_clusters[plane]->begin(), end, tMin, lowerBound());
+  if (it == end) return nullptr;
+  const double tMax = tPred + m_timeWindow;
+  LHCb::TbCluster* best = nullptr;
+  double dtBest = m_timeWindow;
+  for (; it != end; ++it) {
+    const double t = (*it)->htime();
+    if ((*it)->ToT() < m_chargeCutLow) continue;
+    if ((*it)->size() > m_maxClusterSize) continue;
+    // Stop searching when outside the time window.
+    if (t > tMax) break;
+    const double dt = fabs(t - tPred);
+    if (m_monitoring) {
+      const std::string title = "Plane" + std::to_string(plane);
+      plot(t - tPred, "delT" + title, title, -100, 100, 200);
+    }
+    if (dt < dtBest) {
+      // Check if the cluster is within the spatial tolerance window.
+      const double dx = xPred - (*it)->x();
+      const double dy = yPred - (*it)->y();
+      if (m_monitoring) {
+        const std::string title = "Plane " + std::to_string(plane); 
+        plot(dx, "delXY/" + title, title, -3, 3, 200);
+        plot(dy, "delXY/" + title, title, -3, 3, 200);
+      }
+      if (fabs(dx) > tol || fabs(dy) > tol) continue;
+      // Update the best cluster.
+      dtBest = dt;
+      best = *it;
+    }
+  }
+  return best;
+}
+
+//=============================================================================
+// Remove outliers and try to find additional clusters on a track candidate.
+//=============================================================================
+void TbSimpleTracking::recheckTrack(LHCb::TbTrack* track) {
+
+  const unsigned int nClusters = track->clusters().size();
+  if (nClusters < 3 || nClusters >= m_nMaxPlanes) return;
+  // Spatial window for adding clusters to the track.
+  const double tol = 0.1;
+  // Keep track of the planes which already have a cluster on the track.
+  std::vector<bool> planeAssociated(m_nPlanes, false);
+  // Get the straight-line fit parameters.
+  const double x0 = track->firstState().x();
+  const double y0 = track->firstState().y();
+  const double tx = track->firstState().tx();
+  const double ty = track->firstState().ty();
+  auto clusters = track->clusters();
+  const unsigned int nSizeBefore = track->size();
+  for (auto it = clusters.begin(); it != clusters.end(); ) {
+    auto cluster = *it;
+    const unsigned int plane = cluster->plane();
+    ++it;
+    // Remove outliers if requested.
+    const double dx = x0 + tx * cluster->z() - cluster->x();
+    const double dy = y0 + ty * cluster->z() - cluster->y();
+    if (m_removeOutliers && (fabs(dx) > tol || fabs(dy) > tol)) {
+      track->removeFromClusters(cluster);
+    } else {
+      planeAssociated[plane] = true;
+    }
+  }
+  const unsigned int nSizeAfter = track->size();
+  plot(nSizeBefore - nSizeAfter, "NOutliersRemoved", "NOutliersRemoved", -0.5, 10.5, 11);
+  for (unsigned int i = m_nPlanes; i-- > 0;) {
+    if (masked(i) || planeAssociated[i]) continue;
+    // Calculate the track intercept on the plane.
+    const Gaudi::XYZPoint interceptG = geomSvc()->intercept(track, i);
+    const LHCb::TbCluster* cluster = bestCluster(
+        i, interceptG.x(), interceptG.y(), track->htime(), tol);
+    if (cluster) {
+      track->addToClusters(cluster);
+      m_trackFit->fit(track);
+    }
+  }
+}
+
+//=============================================================================
+
+void TbSimpleTracking::findHighOccupancies() {
+
+  m_htimesHighOccupancy.clear();
+  // Find the first non-masked plane.
+  unsigned int seedPlane = 0;
+  while (masked(seedPlane)) ++seedPlane;
+  for (LHCb::TbClusters::const_iterator iSeed = m_clusters[seedPlane]->begin();
+       iSeed != m_clusters[seedPlane]->end(); ++iSeed) {
+    uint nClustersPerSeed = 0;
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (masked(i)) continue;
+      for (LHCb::TbClusters::const_iterator it = m_clusters[i]->begin();
+           it != m_clusters[i]->end(); ++it) {
+        if (fabs((*iSeed)->htime() - (*it)->htime()) < m_timeWindow)
+          nClustersPerSeed++;
+      }
+    }
+    if (nClustersPerSeed > m_maxOccupancy)
+      m_htimesHighOccupancy.push_back((*iSeed)->htime());
+  }
+}
+
+//=============================================================================
+
+bool TbSimpleTracking::lowClusterOccupancy(const double t) const {
+  if (!m_doOccupancyCut) return true;
+  for (unsigned int i = 0; i < m_htimesHighOccupancy.size(); ++i) {
+    if (fabs(t - m_htimesHighOccupancy[i]) < m_timeWindow) return false;
+  }
+  return true;
+}
+
+//=============================================================================
+
+void TbSimpleTracking::appendTrackingEfficiencies() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    for (LHCb::TbClusters::const_iterator it = m_clusters[i]->begin();
+         it != m_clusters[i]->end(); ++it) {
+      counter("nClusters")++;
+      if ((*it)->size() <= m_maxClusterSize &&
+          (*it)->ToT() >= m_chargeCutLow &&
+          lowClusterOccupancy((*it)->htime())) {
+        counter("nClusters selected for tracking")++;
+        if ((*it)->associated()) counter("nClusters associated")++;
+      }
+    }
+  }
+}
+
+//=============================================================================
diff --git a/TbAlgorithms/src/.svn/text-base/TbSimpleTracking.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbSimpleTracking.h.svn-base
new file mode 100644
index 0000000..7c8b249
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbSimpleTracking.h.svn-base
@@ -0,0 +1,80 @@
+#ifndef TB_SIMPLETRACKING_H
+#define TB_SIMPLETRACKING_H 1
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbSimpleTracking TbSimpleTracking.h
+ *
+ */
+
+class TbSimpleTracking : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbSimpleTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbSimpleTracking() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location prefix of clusters
+  std::string m_clusterLocation;
+  /// TES location of tracks
+  std::string m_trackLocation;
+
+  /// Tolerance window in time for adding clusters to a track and for occupancy
+  /// cut
+  double m_timeWindow;
+  /// Minimum number of clusters required to form a track
+  unsigned int m_nMinPlanes;
+  /// Number of non-masked planes
+  unsigned int m_nMaxPlanes;
+  /// Tolerance window in x and y for adding clusters to a track
+  double m_maxDist;
+  /// Angular cut (in radians) for adding clusters to a track
+  double m_maxAngle;
+
+  /// List of clusters
+  std::vector<LHCb::TbClusters *> m_clusters;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+
+  bool m_recheckTrack;
+  bool m_removeOutliers;
+  double m_chargeCutLow;
+  unsigned int m_maxClusterSize;
+  unsigned int m_maxClusterWidth;
+  unsigned int m_maxOccupancy;
+  std::vector<double> m_htimesHighOccupancy;
+  bool m_doOccupancyCut;
+  bool m_monitoring;
+
+  void findHighOccupancies();
+  bool lowClusterOccupancy(const double t) const;
+  void appendTrackingEfficiencies();
+  void recheckTrack(LHCb::TbTrack *track);
+  /// Extrapolate and add clusters to a given seed track.
+  bool extendTrack(LHCb::TbTrack *track, const bool fwd);
+  /// Look for a matching cluster on a given plane.
+  const LHCb::TbCluster *bestCluster(const unsigned int plane,
+                                     const double xPred, const double yPred,
+                                     const double tPred, const double tol);
+  /// Functor for lower bound search.
+  class lowerBound {
+   public:
+    bool operator()(const LHCb::TbCluster *lhs, const double t) const {
+      return lhs->htime() < t;
+    }
+  };
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbTrackPlots.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbTrackPlots.cpp.svn-base
new file mode 100644
index 0000000..afa1680
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTrackPlots.cpp.svn-base
@@ -0,0 +1,494 @@
+// ROOT
+#include "TMath.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+#include "GaudiUtils/Aida2ROOT.h"
+#include "TH1D.h"
+#include "TF1.h"
+#include "TFile.h"
+// Local
+#include "TbTrackPlots.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbTrackPlots)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTrackPlots::TbTrackPlots(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parChi2("", 0., 30., 300),
+      m_parResidualsXY("", -0.2, 0.2, 500),
+      m_parResidualsT("", -50., 50., 2000),
+      m_parXY("", -20, 20, 500),
+      m_parSlope("", -0.0001, 0.0001, 500),
+      m_parCentral("", 4, 10, 1),
+      m_trackFit(nullptr) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+
+  declareProperty("ParametersChi2", m_parChi2);
+  declareProperty("ParametersResidualsXY", m_parResidualsXY);
+  declareProperty("ParametersResidualsT", m_parResidualsT);
+  declareProperty("ParametersXY", m_parXY);
+  declareProperty("ParametersSlope", m_parSlope);
+  declareProperty("ParametersCentral", m_parCentral);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTrackPlots::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+  setupPlots();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalizer
+//=============================================================================
+StatusCode TbTrackPlots::finalize() {
+
+  // Fill plots used after all events have been evaluated.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    double num =
+        m_hnTrackedClusters->binHeight(m_hnTrackedClusters->coordToIndex(i));
+    double denom =
+        m_hnClustersPerPlane->binHeight(m_hnClustersPerPlane->coordToIndex(i));
+    double frac = num / denom;
+    m_hFractionTrackedClusters->fill(i, frac);
+
+    num = m_hnTracksInterceptCentral->binHeight(
+        m_hnTracksInterceptCentral->coordToIndex(i));
+    denom = m_hnClustersPerPlaneCentral->binHeight(
+        m_hnClustersPerPlaneCentral->coordToIndex(i));
+    frac = num / denom;
+    m_hRatioTracksClustersCentral->fill(i, frac);
+  }
+
+  // Code for saving some residuals in a more useful format.
+  //  TFile * fOut = new TFile("UnbiasedLocalResolutionsPerPlane.root",
+  // "RECREATE");
+  //  TH1F * xPerPlane = new TH1F("xPerPlane", "xPerPlane", m_nPlanes, 0,
+  // m_nPlanes);
+  //  TH1F * yPerPlane = new TH1F("yPerPlane", "yPerPlane", m_nPlanes, 0,
+  // m_nPlanes);
+  //
+  //  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+  //  	if (masked(i)) continue;
+  //  	TH1D * proper_UnbiasedResLocalX =
+  // Gaudi::Utils::Aida2ROOT::aida2root(m_hUnbiasedResLX[i]);
+  //  	TH1D * proper_UnbiasedResLocalY =
+  // Gaudi::Utils::Aida2ROOT::aida2root(m_hUnbiasedResLY[i]);
+  //
+  //  	proper_UnbiasedResLocalX->Fit("gaus");
+  //  	proper_UnbiasedResLocalY->Fit("gaus");
+  //
+  //  	xPerPlane->SetBinContent(i+1,
+  // proper_UnbiasedResLocalX->GetFunction("gaus")->GetParameter(2));
+  //  	yPerPlane->SetBinContent(i+1,
+  // proper_UnbiasedResLocalY->GetFunction("gaus")->GetParameter(2));
+  //  }
+  //
+  //  xPerPlane->Write();
+  //  yPerPlane->Write();
+
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTrackPlots::execute() {
+
+  // Grab the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+  // Fill plots that loop over tracks.
+  fillTrackLoopPlots(tracks);
+
+  // Fill plots that loop over clusters (that have tracking information).
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) continue;
+    fillClusterLoopPlots(clusters, i);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Fill track loop plots.
+//=============================================================================
+void TbTrackPlots::fillTrackLoopPlots(LHCb::TbTracks* tracks) {
+
+  for (LHCb::TbTrack* track : *tracks) {
+    m_hChi2->fill(track->chi2PerNdof());
+    m_hTrackSize->fill(track->size());
+    m_hProb->fill(TMath::Prob(track->chi2(), track->ndof()));
+    m_hSlopeXZ->fill(track->firstState().tx());
+    m_hSlopeYZ->fill(track->firstState().ty());
+    m_hFirstStateX->fill(track->firstState().x());
+    m_hFirstStateY->fill(track->firstState().y());
+    m_hSlopeXvsX->fill(track->firstState().tx(), track->firstState().x());
+    m_hSlopeYvsY->fill(track->firstState().ty(), track->firstState().y());
+    // Calculate the intercept of the track with the detector planes.
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, i);
+      m_hIntercepts[i]->fill(intercept.x(), intercept.y());
+      // Plot the intercepts of tracks with/without an associated trigger. 
+      if (track->triggers().empty()) {
+        m_hInterceptsNonAssociated[i]->fill(intercept.x(), intercept.y());
+      } else {
+        m_hInterceptsAssociated[i]->fill(intercept.x(), intercept.y());
+      }
+      if (intercept.x() > m_parCentral.lowEdge() &&
+          intercept.x() < m_parCentral.highEdge() &&
+          intercept.y() > m_parCentral.lowEdge() &&
+          intercept.y() < m_parCentral.highEdge())
+        m_hnTracksInterceptCentral->fill(i);
+    }
+    const auto triggers = track->triggers();
+    for (auto trigger : triggers) {
+      m_hTimeDifferenceTrackTrigger->fill(trigger->htime() - track->htime());
+    }
+    fillResiduals(track);
+
+    // Delta angle.
+    LHCb::TbTrack track1, track2;
+    for (unsigned int i = 0; i < track->clusters().size(); i++) {
+      if (track->clusters()[i]->plane() < 4)
+        track1.addToClusters(track->clusters()[i]);
+      else
+        track2.addToClusters(track->clusters()[i]);
+    }
+    if (track2.clusters().size() > 2 && track1.clusters().size() > 2) {
+      m_trackFit->fit(&track1);
+      m_trackFit->fit(&track2);
+      const double dtx = track2.firstState().tx() - track1.firstState().tx();
+      const double dty = track2.firstState().ty() - track1.firstState().ty();
+      plot(dtx, "delAngleArmsX", "delAngleArmsX", -0.001, 0.001, 300);
+      plot(dty, "delAngleArmsY", "delAngleArmsY", -0.001, 0.001, 300);
+    }
+  }
+}
+
+//=============================================================================
+// Fill residual distributions.
+//=============================================================================
+void TbTrackPlots::fillResiduals(LHCb::TbTrack* track) {
+
+  const auto clusters = track->clusters();
+  for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+    const unsigned int plane = (*it)->plane();
+
+    // Mask the plane under consideration to calculate the unbiased residuals.
+    m_trackFit->maskPlane(plane);
+    m_trackFit->fit(track);
+
+    // Calculate the global unbiased residuals.
+    const auto interceptUG = geomSvc()->intercept(track, plane);
+    const double dxug = (*it)->x() - interceptUG.x();
+    const double dyug = (*it)->y() - interceptUG.y();
+    m_hUnbiasedResGX[plane]->fill(dxug);
+    m_hUnbiasedResGY[plane]->fill(dyug);
+
+    // Calculate the local unbiased residuals.
+    const auto interceptUL = geomSvc()->globalToLocal(interceptUG, plane);
+    const double dxul = (*it)->xloc() - interceptUL.x();
+    const double dyul = (*it)->yloc() - interceptUL.y();
+    m_hUnbiasedResLX[plane]->fill(dxul);
+    m_hUnbiasedResLY[plane]->fill(dyul);
+
+    // Re-include the plane under consideration in the fit and refit.
+    m_trackFit->unmaskPlane(plane);
+    m_trackFit->fit(track);
+
+    // Calculate the global biased residuals in x and y.
+    const Gaudi::XYZPoint interceptG = geomSvc()->intercept(track, plane);
+    const double dxg = (*it)->x() - interceptG.x();
+    const double dyg = (*it)->y() - interceptG.y();
+    m_hBiasedResGX[plane]->fill(dxg);
+    m_hBiasedResGY[plane]->fill(dyg);
+
+    // Calculate the local biased residuals.
+    const auto interceptL = geomSvc()->globalToLocal(interceptG, plane);
+    const double dxl = (*it)->xloc() - interceptL.x();
+    const double dyl = (*it)->yloc() - interceptL.y();
+    m_hBiasedResLX[plane]->fill(dxl);
+    m_hBiasedResLY[plane]->fill(dyl);
+
+    // Biased global residuals as function of local x/y.
+    m_hBiasedResGXvsLX[plane]->fill((*it)->xloc(), dxg);
+    m_hBiasedResGYvsLY[plane]->fill((*it)->yloc(), dyg);
+    // Unbiased global residuals as function of global x/y.
+    m_hUnbiasedResGXvsGX[plane]->fill((*it)->x(), dxug);
+    m_hUnbiasedResGYvsGY[plane]->fill((*it)->y(), dyug);
+
+    const double trprob = TMath::Prob(track->chi2(), track->ndof());
+    m_hBiasedResGXvsTrackProb[plane]->fill(trprob, dxg);
+    m_hBiasedResGYvsTrackProb[plane]->fill(trprob, dyg);
+
+    // Time residuals.
+    const double dt = (*it)->htime() - track->htime();
+    m_hBiasedResT[plane]->fill(dt);
+    m_hBiasedResTvsGX[plane]->fill((*it)->x(), dt);
+
+    auto hits = (*it)->hits();
+    for (auto ith = hits.cbegin(), hend = hits.cend(); ith != hend; ++ith) {
+      const double delt = (*ith)->htime() - track->htime();
+      m_hBiasedResPixelTvsColumn[plane]->fill((*ith)->col(), delt);
+    }
+
+    /// Fill time synchronisation histograms, with respect to chip zero,
+    /// and also the synchronisation stability
+    if (plane != 0) continue;
+    for (auto jt = clusters.cbegin(); jt != end; ++jt) {
+      const double dt0 = (*it)->htime() - (*jt)->htime();
+      m_hSyncDifferences[(*jt)->plane()]->fill(dt0);
+      m_syncInRun[(*jt)->plane()]->fill((*it)->time() / Tb::minute, dt0);
+    }
+  }
+}
+
+//=============================================================================
+// Fill cluster loop plots.
+//=============================================================================
+void TbTrackPlots::fillClusterLoopPlots(const LHCb::TbClusters* clusters,
+                                        const unsigned int plane) {
+  unsigned int nTrackedClusters = 0;
+  unsigned int nClustersCentral = 0;
+  for (const LHCb::TbCluster* cluster : *clusters) {
+    if (cluster->associated()) ++nTrackedClusters;
+    if (cluster->x() > m_parCentral.lowEdge() &&
+        cluster->x() < m_parCentral.highEdge() &&
+        cluster->y() > m_parCentral.lowEdge() &&
+        cluster->y() < m_parCentral.highEdge())
+      nClustersCentral++;
+  }
+
+  m_hnTrackedClusters->fill(plane, nTrackedClusters);
+  m_hnClustersPerPlane->fill(plane, clusters->size());
+  m_hnClustersPerPlaneCentral->fill(plane, nClustersCentral);
+}
+
+//=============================================================================
+// Setup plots
+//=============================================================================
+void TbTrackPlots::setupPlots() {
+
+  unsigned int bins = m_parChi2.bins();
+  double low = m_parChi2.lowEdge();
+  double high = m_parChi2.highEdge();
+  m_hChi2 = book1D("Chi2PerDof", low, high, bins);
+  setAxisLabels(m_hChi2, "#chi^{2} / n_{dof}", "entries");
+
+  m_hProb = book1D("Probability", 0., 1., 1000);
+  setAxisLabels(m_hProb, "probability", "entries");
+
+  m_hTrackSize = book1D("TrackSize", 0.5, 12.5, 12);
+  setAxisLabels(m_hTrackSize, "number of clusters", "entries");
+
+  m_hnClustersPerPlane = book1D("TrackingEfficiency/nClustersPerPlane",
+                                "nClustersPerPlane", -0.5, 12.5, 13);
+  setAxisLabels(m_hnClustersPerPlane, "plane", "clusters");
+
+  m_hnTrackedClusters = book1D("TrackingEfficiency/nTrackedClusters",
+                               "nTrackedClusters", -0.5, 12.5, 13);
+  setAxisLabels(m_hnTrackedClusters, "plane", "clusters");
+
+  m_hFractionTrackedClusters =
+      book1D("TrackingEfficiency/FractionTrackedClusters",
+             "FractionTrackedClusters", -0.5, 12.5, 13);
+  setAxisLabels(m_hFractionTrackedClusters, "plane", "Fraction");
+
+  m_hnClustersPerPlaneCentral =
+      book1D("TrackingEfficiency/nClustersPerPlaneCentral",
+             "nClustersPerPlaneCentral", -0.5, 12.5, 13);
+  setAxisLabels(m_hnClustersPerPlaneCentral, "plane", "clusters");
+
+  m_hnTracksInterceptCentral =
+      book1D("TrackingEfficiency/nTracksInterceptCentral",
+             "nTracksInterceptCentral", -0.5, 12.5, 13);
+  setAxisLabels(m_hnTracksInterceptCentral, "plane", "tracks");
+
+  m_hRatioTracksClustersCentral =
+      book1D("TrackingEfficiency/RatioTracksClustersCentral",
+             "RatioTracksClustersCentral", -0.5, 12.5, 13);
+  setAxisLabels(m_hRatioTracksClustersCentral, "plane", "Fraction");
+
+  bins = m_parSlope.bins();
+  low = m_parSlope.lowEdge();
+  high = m_parSlope.highEdge();
+  m_hSlopeXZ = book1D("SlopeXZ", low, high, bins);
+  m_hSlopeYZ = book1D("SlopeYZ", low, high, bins);
+  setAxisLabels(m_hSlopeXZ, "#it{t}_{x}", "entries");
+  setAxisLabels(m_hSlopeYZ, "#it{t}_{y}", "entries");
+
+  bins = m_parXY.bins();
+  low = m_parXY.lowEdge();
+  high = m_parXY.highEdge();
+  m_hFirstStateX = book1D("FirstStateX", low, high, bins);
+  m_hFirstStateY = book1D("FirstStateY", low, high, bins);
+
+  m_hSlopeXvsX =
+      book2D("SlopeXZvsFirstStateX", "t_{x} vs x", m_parSlope.lowEdge(),
+             m_parSlope.highEdge(), m_parSlope.bins(), low, high, bins);
+  m_hSlopeYvsY =
+      book2D("SlopeYZvsFirstStateY", "t_{y} vs y", m_parSlope.lowEdge(),
+             m_parSlope.highEdge(), m_parSlope.bins(), low, high, bins);
+
+  setAxisLabels(m_hSlopeXvsX, "#it{t}_{x}", "#it{x}_{0} [mm]");
+  setAxisLabels(m_hSlopeYvsY, "#it{t}_{y}", "#it{y}_{0} [mm]");
+
+  setAxisLabels(m_hFirstStateX, "#it{x}_{0} [mm]", "entries");
+  setAxisLabels(m_hFirstStateY, "#it{y}_{0} [mm]", "entries");
+
+  const std::string labelx = "#it{x} - #it{x}_{track} [mm]";
+  const std::string labely = "#it{y} - #it{y}_{track} [mm]";
+  const std::string labelt = "#it{t} - #it{t}_{track} [ns]";
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+    // Track intercepts
+    bins = m_parXY.bins();
+    low = m_parXY.lowEdge();
+    high = m_parXY.highEdge();
+    std::string name = "Intercepts/Plane" + plane;
+    m_hIntercepts.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "InterceptsAssociated/Plane" + plane;
+    m_hInterceptsAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "InterceptsNonAssociated/Plane" + plane;
+    m_hInterceptsNonAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_hIntercepts[i], "global #it{x} [mm]", "global #it{y} [mm]");
+    setAxisLabels(m_hInterceptsAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+    setAxisLabels(m_hInterceptsNonAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+
+    // Biased x/y residuals
+    bins = m_parResidualsXY.bins();
+    low = m_parResidualsXY.lowEdge();
+    high = m_parResidualsXY.highEdge();
+    name = "BiasedResiduals/GlobalX/Plane" + plane;
+    m_hBiasedResGX.push_back(book1D(name, title, low, high, bins));
+    name = "BiasedResiduals/GlobalY/Plane" + plane;
+    m_hBiasedResGY.push_back(book1D(name, title, low, high, bins));
+    name = "BiasedResiduals/LocalX/Plane" + plane;
+    m_hBiasedResLX.push_back(book1D(name, title, low, high, bins));
+    name = "BiasedResiduals/LocalY/Plane" + plane;
+    m_hBiasedResLY.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hBiasedResGX[i], labelx, "entries");
+    setAxisLabels(m_hBiasedResGY[i], labely, "entries");
+    setAxisLabels(m_hBiasedResLX[i], labelx, "entries");
+    setAxisLabels(m_hBiasedResLY[i], labely, "entries");
+
+    // Biased residuals vs. x/y
+    const unsigned int binsXY = m_parXY.bins();
+    const double lowXY = m_parXY.lowEdge();
+    const double highXY = m_parXY.highEdge();
+    name = "BiasedResiduals/GlobalResXvsLocalX/Plane" + plane;
+    m_hBiasedResGXvsLX.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    name = "BiasedResiduals/GlobalResYvsLocalY/Plane" + plane;
+    m_hBiasedResGYvsLY.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    setAxisLabels(m_hBiasedResGXvsLX[i], "local #it{x} [mm]", labelx);
+    setAxisLabels(m_hBiasedResGYvsLY[i], "local #it{y} [mm]", labely);
+
+    // Unbiased x/y residuals
+    name = "UnbiasedResiduals/GlobalX/Plane" + plane;
+    m_hUnbiasedResGX.push_back(book1D(name, title, low, high, bins));
+    name = "UnbiasedResiduals/GlobalY/Plane" + plane;
+    m_hUnbiasedResGY.push_back(book1D(name, title, low, high, bins));
+    name = "UnbiasedResiduals/LocalX/Plane" + plane;
+    m_hUnbiasedResLX.push_back(book1D(name, title, low, high, bins));
+    name = "UnbiasedResiduals/LocalY/Plane" + plane;
+    m_hUnbiasedResLY.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hUnbiasedResGX[i], labelx, "entries");
+    setAxisLabels(m_hUnbiasedResGY[i], labely, "entries");
+    setAxisLabels(m_hUnbiasedResLX[i], labelx, "entries");
+    setAxisLabels(m_hUnbiasedResLY[i], labely, "entries");
+
+    // Unbiased residuals vs. x/y
+    name = "UnbiasedResiduals/GlobalResXvsGlobalX/Plane" + plane;
+    m_hUnbiasedResGXvsGX.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    name = "UnbiasedResiduals/GlobalResYvsGlobalY/Plane" + plane;
+    m_hUnbiasedResGYvsGY.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    setAxisLabels(m_hUnbiasedResGXvsGX[i], "global #it{x} [mm]", labelx);
+    setAxisLabels(m_hUnbiasedResGYvsGY[i], "global #it{y} [mm]", labely);
+
+    // Biased residuals vs. track probability
+    name = "BiasedResiduals/GlobalXvsTrackProb/Plane" + plane;
+    m_hBiasedResGXvsTrackProb.push_back(
+        book2D(name, title, 0.0, 1.0, 1000, low, high, bins));
+    name = "BiasedResiduals/GlobalYvsTrackProb/Plane" + plane;
+    m_hBiasedResGYvsTrackProb.push_back(
+        book2D(name, title, 0.0, 1.0, 1000, low, high, bins));
+
+    // Time residuals
+    bins = m_parResidualsT.bins();
+    low = m_parResidualsT.lowEdge();
+    high = m_parResidualsT.highEdge();
+    name = "BiasedResiduals/Time/Plane" + plane;
+    m_hBiasedResT.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hBiasedResT[i], labelt, "entries");
+
+    // Residuals with respect to plane zero
+    name = "MisalignmentFrom0/Plane" + plane;
+    m_hSyncDifferences.push_back(book1D(name, title, -35.0, 35.0, 2000));
+    setAxisLabels(m_hSyncDifferences[i], labelt, "entries");
+
+    name = "MisalignmentFrom0Profile/Plane" + plane;
+    m_syncInRun.push_back(bookProfile1D(name, title, 0, 120.0, 120));
+    setAxisLabels(m_syncInRun[i], "#it{t}_{track} [minutes]",
+                  "#LT #it{t} - #it{t}_{track} #GT [ns]");
+
+    name = "BiasedResiduals/ResTimeVsGlobalX/Plane" + plane;
+    m_hBiasedResTvsGX.push_back(
+        book2D(name, title, -12, 3, 256, low, high, bins));
+    setAxisLabels(m_hBiasedResTvsGX[i], "#it{x} [mm]", labelt);
+    name = "BiasedResiduals/ResHitTimeVsColumn/Plane" + plane;
+    m_hBiasedResPixelTvsColumn.push_back(
+        book2D(name, title, -0.5, 255.5, 256, low, high, bins));
+    setAxisLabels(m_hBiasedResPixelTvsColumn[i], "column",
+                  "#it{t}_{hit} - #it{t}_{track} [ns]");
+
+    // Time difference between tracks and triggers
+    name = "TimeDifferenceTrackTriggers";
+    m_hTimeDifferenceTrackTrigger = book1D(name, "#Deltat", -1000., 1000., 500);
+    setAxisLabels(m_hTimeDifferenceTrackTrigger,
+                  "#it{t}_{trigger} - #it{t}_track [ns]", "entries");
+  }
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbTrackPlots.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbTrackPlots.h.svn-base
new file mode 100644
index 0000000..e1b95df
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTrackPlots.h.svn-base
@@ -0,0 +1,120 @@
+#ifndef TB_TRACKPLOTS_H
+#define TB_TRACKPLOTS_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+
+#include "AIDA/IProfile2D.h"
+#include "AIDA/IProfile1D.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTrackPlots TbTrackPlots.h
+ *
+ *  Algorithm to produce monitoring histograms for telescope tracks.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbTrackPlots : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTrackPlots(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTrackPlots() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+
+ private:
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+
+  /// Track intercepts.
+  std::vector<AIDA::IHistogram2D*> m_hIntercepts;
+  std::vector<AIDA::IHistogram2D*> m_hInterceptsAssociated;
+  std::vector<AIDA::IHistogram2D*> m_hInterceptsNonAssociated;
+  /// Biased residuals.
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResGX;
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResGY;
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResLX;
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResLY;
+  /// Unbiased residuals.
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResGX;
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResGY;
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResLX;
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResLY;
+
+  /// Biased residuals as functions of x/y.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGXvsLX;
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGYvsLY;
+  /// Unbiased residuals as functions of x/y.
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGXvsGX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGYvsGY;
+  /// Biased residuals as functions of track probability.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGXvsTrackProb;
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGYvsTrackProb;
+
+  /// Cluster time residuals.
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResT;
+  /// Cluster time residuals as function of global x.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResTvsGX;
+  /// Pixel time residuals as function of column number.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResPixelTvsColumn;
+
+  /// Tracking efficiency plots.
+  AIDA::IHistogram1D* m_hRatioTracksClustersCentral;
+  AIDA::IHistogram1D* m_hnClustersPerPlaneCentral;
+  AIDA::IHistogram1D* m_hnTracksInterceptCentral;
+  AIDA::IHistogram1D* m_hFractionTrackedClusters;
+  AIDA::IHistogram1D* m_hnClustersPerPlane;
+  AIDA::IHistogram1D* m_hnTrackedClusters;
+
+  /// Other.
+  AIDA::IHistogram1D* m_hTimeDifferenceTrackTrigger;
+
+  std::vector<AIDA::IHistogram1D*> m_hSyncDifferences;
+  std::vector<AIDA::IProfile1D*> m_syncInRun;
+
+  AIDA::IHistogram1D* m_hChi2;
+  AIDA::IHistogram1D* m_hProb;
+  AIDA::IHistogram1D* m_hTrackSize;
+  AIDA::IHistogram1D* m_hSlopeXZ;
+  AIDA::IHistogram1D* m_hSlopeYZ;
+  AIDA::IHistogram1D* m_hFirstStateX;
+  AIDA::IHistogram1D* m_hFirstStateY;
+  AIDA::IHistogram2D* m_hSlopeXvsX;
+  AIDA::IHistogram2D* m_hSlopeYvsY;
+
+  /// Parameters for chi-squared distribution
+  Gaudi::Histo1DDef m_parChi2;
+  /// Parameters for x/y residual distributions
+  Gaudi::Histo1DDef m_parResidualsXY;
+  /// Parameters for time residual distributions
+  Gaudi::Histo1DDef m_parResidualsT;
+  /// Parameters for x/y histograms (hitmaps)
+  Gaudi::Histo1DDef m_parXY;
+  /// Parameters for track slope distributions
+  Gaudi::Histo1DDef m_parSlope;
+  /// Parameters for central region cuts.
+  Gaudi::Histo1DDef m_parCentral;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit* m_trackFit;
+
+  void setupPlots();
+  void fillClusterLoopPlots(const LHCb::TbClusters* clusters,
+                            const unsigned int plane);
+  void fillTrackLoopPlots(LHCb::TbTracks* tracks);
+  void fillResiduals(LHCb::TbTrack* track);
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbTrackVolume.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbTrackVolume.cpp.svn-base
new file mode 100644
index 0000000..28791b1
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTrackVolume.cpp.svn-base
@@ -0,0 +1,163 @@
+#include "Event/TbTrack.h"
+
+#include "TbTrackVolume.h"
+
+//=============================================================================
+// Constructor
+//=============================================================================
+TbTrackVolume::TbTrackVolume(const std::string& vol_shape,
+                             const unsigned int& nPlanes, const double& r,
+                             const double& rY, const double& theta,
+                             const double& thetaY,
+                             const unsigned int& minNClusters)
+    : m_r(r),
+      m_rY(rY),
+      m_r2(r * r),
+      m_theta(theta),
+      m_thetaY(thetaY),
+      m_seed_cluster(NULL),
+      m_nPlanes(nPlanes),
+      m_MinNClusters(minNClusters) {
+
+  if (vol_shape == "cylinder") {
+    m_3vol_shape = VolShape::Cylinder;
+  } else if (vol_shape == "diabolo") {
+    m_3vol_shape = VolShape::Diabolo;
+  } else if (vol_shape == "sqDiabolo") {
+    m_3vol_shape = VolShape::SqDiabolo;
+  } else {
+    // Use default shape.
+    m_3vol_shape = VolShape::Cylinder;
+  }
+}
+
+//=============================================================================
+// Initialise with a given seed cluster.
+//=============================================================================
+void TbTrackVolume::reset(LHCb::TbCluster* c) {
+
+  m_clusters.clear();
+  m_clusters.resize(m_nPlanes, std::vector<LHCb::TbCluster*>());
+  m_clusters[c->plane()].push_back(c);
+  m_seed_cluster = c;
+  m_done = false;
+}
+
+//=============================================================================
+// Check if a given cluster is within the volume.
+//=============================================================================
+void TbTrackVolume::consider_cluster(LHCb::TbCluster* c) {
+
+  bool inside = false;
+  switch (m_3vol_shape) {
+    case VolShape::Cylinder:
+      inside = consider_cluster_cylinder(c);
+      break;
+    case VolShape::Diabolo:
+      inside = consider_cluster_diabolo(c);
+      break;
+    case VolShape::SqDiabolo:
+      inside = consider_cluster_sqDiabolo(c);
+      break;
+    default:
+      break;
+  }
+  if (inside) {
+    m_clusters[c->plane()].push_back(c);
+  }
+}
+
+//=============================================================================
+bool TbTrackVolume::consider_cluster_sqDiabolo(const LHCb::TbCluster* c_out)
+    const {
+
+  const double delx = c_out->x() - seed()->x();
+  const double dely = c_out->y() - seed()->y();
+  const double dz = fabs(c_out->z() - seed()->z());
+  const double r_x = dz * m_theta + m_r;
+  const double r_y = dz * m_thetaY + m_rY;
+  if (delx < r_x && dely < r_y) return true;
+  return false;
+}
+
+//=============================================================================
+bool TbTrackVolume::consider_cluster_diabolo(const LHCb::TbCluster* c) const {
+
+  const double delx = c->x() - seed()->x();
+  const double dely = c->y() - seed()->y();
+  const double r_z = m_r + fabs(c->z() - m_seed_cluster->z()) * m_theta;
+  return (delx * delx + dely * dely < r_z * r_z);
+}
+
+//=============================================================================
+bool TbTrackVolume::notAlreadyConsidered(const LHCb::TbCluster* c) const {
+  bool result = true;
+  for (unsigned int i = 0; i < m_clusters[c->plane()].size(); i++) {
+    if (m_clusters[c->plane()][i]->key() == c->key()) result = false;
+  }
+  return result;
+}
+
+//=============================================================================
+bool TbTrackVolume::consider_cluster_cylinder(const LHCb::TbCluster* c) const {
+  const double delx = c->x() - seed()->x();
+  const double dely = c->y() - seed()->y();
+  if ((delx * delx + dely * dely) < m_r2 && notAlreadyConsidered(c)) {
+    return true;
+  }
+  return false;
+}
+
+//=============================================================================
+// Return the number of track combinations that can be made from this volume
+//=============================================================================
+unsigned int TbTrackVolume::nCombos() {
+
+  if (m_done) return m_nCombos;
+  // Remove empty planes.
+  for (unsigned int i = 0; i < m_clusters.size(); i++) {
+    if (m_clusters[i].size() == 0) {
+      m_clusters.erase(m_clusters.begin() + i);
+      i--;
+    }
+  }
+  m_combo_counters.assign(m_clusters.size(), 0);
+
+  if (m_clusters.size() < m_MinNClusters) {
+    m_nCombos = 0;
+  } else {
+    m_nCombos = 1;
+    for (unsigned int i = 0; i < m_clusters.size(); i++) {
+      m_nCombos *= m_clusters[i].size();
+    }
+  }
+  m_done = true;
+  return m_nCombos;
+}
+
+//=============================================================================
+// Make a track from the current combination of clusters
+//=============================================================================
+void TbTrackVolume::get_track_combo(LHCb::TbTrack* track) {
+
+  for (unsigned int iplane = 0; iplane < m_clusters.size(); iplane++) {
+    const int ic = m_combo_counters[iplane];
+    track->addToClusters(m_clusters[iplane][ic]);
+  }
+}
+
+//=============================================================================
+// Get the next combination of clusters
+//=============================================================================
+void TbTrackVolume::increment_combo_counters() {
+  const int n = m_combo_counters.size() - 1;
+  m_combo_counters[n] += 1;
+
+  // Adaptive clock.
+  for (int i = n; i >= 1; i--) {
+    if (m_combo_counters[i] >= m_clusters[i].size()) {
+      m_combo_counters[i] = 0;
+      m_combo_counters[i - 1] += 1;
+    }
+  }
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbTrackVolume.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbTrackVolume.h.svn-base
new file mode 100644
index 0000000..755913d
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTrackVolume.h.svn-base
@@ -0,0 +1,72 @@
+#ifndef TB_TRACKVOLUME_H
+#define TB_TRACKVOLUME_H 1
+
+#include <iostream>
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+/** @class TbTrackVolume TbTrackVolume.h
+ *
+ *  Container for clusters given a set of spatial and time cuts. Used for
+ *  tracking. Offers easy access to particular formations of tracks.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbTrackVolume {
+ public:
+  enum VolShape {
+    Cylinder = 1,
+    Diabolo = 2,
+    SqDiabolo = 3
+  };
+  /// Constructor
+  TbTrackVolume(const std::string& volshape, const unsigned int& nPlanes,
+                const double& r, const double& ry, const double& theta,
+                const double& thetay, const unsigned int& minNClusters);
+  /// Destructor
+  ~TbTrackVolume() {}
+
+  void reset(LHCb::TbCluster* c);
+  void consider_cluster(LHCb::TbCluster* c);
+
+  unsigned int nCombos();
+  void get_track_combo(LHCb::TbTrack* t);
+  void increment_combo_counters();
+
+  // Setters and getters ______________________________________________________
+  LHCb::TbCluster* seed() const { return m_seed_cluster; }
+
+  /// Overload ostream operator <<
+  friend std::ostream& operator<<(std::ostream& s, const TbTrackVolume& v) {
+    s << v.m_theta << " " << v.m_r << " " << v.m_thetaY << " " << v.m_rY << " "
+      << v.seed()->x() << " " << v.seed()->y() << " " << v.seed()->z() << " ";
+    return s;
+  }
+
+  std::vector<std::vector<LHCb::TbCluster*> > m_clusters;
+
+ private:
+  double m_r;
+  double m_rY;
+  double m_r2;
+  double m_theta;
+  double m_thetaY;
+
+  LHCb::TbCluster* m_seed_cluster;
+  unsigned int m_3vol_shape;
+
+  unsigned int m_nPlanes;
+  unsigned int m_MinNClusters;
+  std::vector<unsigned int> m_combo_counters;
+  unsigned int m_nCombos;
+  bool m_done;
+
+  bool consider_cluster_cylinder(const LHCb::TbCluster* cl) const;
+  bool consider_cluster_diabolo(const LHCb::TbCluster* cl) const;
+  bool consider_cluster_sqDiabolo(const LHCb::TbCluster* cl) const;
+  bool notAlreadyConsidered(const LHCb::TbCluster* cl) const;
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbTracking.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbTracking.cpp.svn-base
new file mode 100644
index 0000000..5732aca
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTracking.cpp.svn-base
@@ -0,0 +1,421 @@
+#include <fstream>
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbTracking.h"
+
+DECLARE_ALGORITHM_FACTORY(TbTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTracking::TbTracking(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_tracks(nullptr),
+      m_trackFit(nullptr),
+      m_clusterFinder(nullptr),
+      m_trackVolume(nullptr),
+      m_event(0) {
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+  declareProperty("Monitoring", m_monitoring = false);
+  declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
+  declareProperty("MinNClusters", m_MinNClusters = 7);
+  declareProperty("SearchRadius", m_vol_radius = 1 * Gaudi::Units::mm);
+  declareProperty("MaxChi2", m_ChiSqRedCut = 20000.);
+  declareProperty("VolumeAngle", m_vol_theta = 0.015);
+  declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
+  declareProperty("ClusterSizeCut", m_clusterSizeCut = 1000);
+  declareProperty("CombatRun", m_combatRun = false);
+
+  // Options for the event viewer.
+  declareProperty("ViewerOutput", m_viewerOutput = false);
+  declareProperty("ViewerEventNum", m_viewerEvent = 100);
+
+  // Default values.
+  m_search_3vol = "diabolo";
+  m_ClusterFinderSearchAlgorithm = "adap_seq";
+  m_nComboCut = 300;
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTracking::~TbTracking() {
+
+  if (m_trackVolume) {
+    delete m_trackVolume;
+  }
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTracking::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+  // Set up the cluster finder.
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+  if (!m_clusterFinder) return Error("Cannot retrieve cluster finder tool.");
+  m_clusterFinder->setSearchAlgorithm(m_ClusterFinderSearchAlgorithm);
+  m_volumed.resize(m_nPlanes);
+  // Set up the track volume.
+  m_trackVolume =
+      new TbTrackVolume(m_search_3vol, m_nPlanes, m_vol_radius, m_vol_radius,
+                        m_vol_theta, m_vol_theta, m_MinNClusters);
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTracking::execute() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (m_event == m_viewerEvent && m_viewerOutput) {
+      std::ofstream myfile;
+      myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat");
+      myfile << "# Output\n";
+      myfile.close();
+    }
+
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      return Error("No clusters in " + clusterLocation);
+    }
+    // Store the cluster iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+    m_volumed[i].clear();
+    m_volumed[i].resize(clusters->size(), false);
+  }
+
+  // Check if there is already a track container.
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!m_tracks) {
+    // Create a track container and transfer its ownership to the TES.
+    m_tracks = new LHCb::TbTracks();
+    put(m_tracks, m_trackLocation);
+  }
+  // Do the tracking and time order.
+  performTracking();
+  timeOrderTracks();
+
+  counter("NumberOfTracks") += m_tracks->size();
+  if (m_event == m_viewerEvent && m_viewerOutput) outputViewerData();
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Tracking
+//=============================================================================
+void TbTracking::performTracking() {
+  // The working of this algorithm is similar to the cluster maker, such that:
+  // - Loop over some set of seed clusters (those on the m_SeedPlanes).
+  // - Create a container (TbTrackVolume) centered on each seed cluster
+  //   (in space and time).
+  // - Impose the condition that any formed track must contain this seed.
+  // - Evaluate that 4-volume, to see if it contained a track.
+  // - If a choice (e.g. more than one possible combination of clusters),
+  //   take the best fitting. Priority is given to more complete tracks.
+  // - If another track happened to be in the 4volume, but not
+  //   containing this seed, then it will be found later.
+
+  // Iterate over planes in the specified order.
+  for (const auto& plane : m_PlaneSearchOrder) {
+    // Skip masked and empty planes.
+    if (masked(plane) || m_clusterFinder->empty(plane)) continue;
+    // Iterate over the clusters on this plane.
+    const auto end = m_clusterFinder->end(plane);
+    for (auto ic = m_clusterFinder->first(plane); ic != end; ++ic) {
+      // Check if the seed has already been used.
+      if ((*ic)->associated() || (*ic)->size() > m_clusterSizeCut) continue;
+      // Initialise the track volume container and find clusters
+      // that fall in its space-time volume.
+      fillTrackVolume(*ic, 0, m_nPlanes);
+      // Tag the clusters as "volumed".
+      for (unsigned int i = 0; i < m_trackVolume->m_clusters.size(); ++i) {
+        for (const auto cl : m_trackVolume->m_clusters[i]) {
+          m_volumed[cl->plane()][cl->key()] = true;
+        }
+      }
+      // Look for a track - automatically keeps if suitable.
+      evaluateTrackVolume(m_trackVolume);
+    }
+  }
+}
+
+//=============================================================================
+// Fill the given track volume with clusters in its space-time volume.
+//=============================================================================
+void TbTracking::fillTrackVolume(LHCb::TbCluster* seed,
+                                 const unsigned int& planeLow,
+                                 const unsigned int& planeUp) {
+
+  m_trackVolume->reset(seed);
+  const double tMin = seed->htime() - 0.5 * m_twindow;
+  const double tMax = seed->htime() + 0.5 * m_twindow;
+  for (unsigned int i = planeLow; i < planeUp; ++i) {
+    // Skip empty planes, masked planes and the seed plane.
+    if (m_clusterFinder->empty(i) || i == seed->plane() || masked(i)) {
+      continue;
+    }
+    // Start with the first cluster in the time window
+    // and loop until the end of the time window.
+    const auto end = m_clusterFinder->end(i);
+    for (auto ic = m_clusterFinder->getIterator(tMin, i); ic != end; ++ic) {
+      if ((*ic)->htime() < tMin) continue;
+      if ((*ic)->htime() > tMax) break;
+      // Skip clusters which are already used or exceed the cluster size cut.
+      if (!(*ic)->associated() && (*ic)->size() <= m_clusterSizeCut) {
+        m_trackVolume->consider_cluster(*ic);
+      }
+    }
+  }
+  if (m_event == m_viewerEvent && m_viewerOutput) {
+    std::ofstream file;
+    file.open("KeplerViewerData.dat", std::ofstream::app);
+    file << "SqTrackArea " << m_trackVolume << tMin << " " << tMax << "\n";
+  }
+}
+
+//=============================================================================
+// Finding the best tracks
+//=============================================================================
+void TbTracking::evaluateTrackVolume(TbTrackVolume* track_volume) {
+
+  LHCb::TbTrack* trialTrack = NULL;
+  LHCb::TbTrack* best_track = NULL;
+  double best_chi_dof = -1.;
+  // Get the number of combinations to check (depends on the size of the track
+  // to be formed).
+  const unsigned int ncombos = std::min(track_volume->nCombos(), m_nComboCut);
+  // Do the search over this number of combinations - the TbTrackVolume has
+  // method to retrieve a particular combination of clusters forming a track.
+  for (unsigned int i = 0; i < ncombos; ++i) {
+    // Create or reset the trial track.
+    if (!trialTrack) {
+      trialTrack = new LHCb::TbTrack();
+    } else {
+      trialTrack->clearClusters();
+    }
+    // Get the ith track combination.
+    track_volume->get_track_combo(trialTrack);
+    // Sort the clusters by z-position.
+    SmartRefVector<LHCb::TbCluster>& clusters =
+        const_cast<SmartRefVector<LHCb::TbCluster>&>(trialTrack->clusters());
+    std::sort(clusters.begin(), clusters.end(),
+              TbFunctors::LessByZ<const LHCb::TbCluster*>());
+    // Evaluate this track.
+    m_trackFit->fit(trialTrack);
+    const double chi2_per_dof = trialTrack->chi2PerNdof();
+    if (i == 0) {
+      // First combination tried case.
+      best_chi_dof = chi2_per_dof;
+      best_track = trialTrack;
+      trialTrack = NULL;
+    } else if (chi2_per_dof < best_chi_dof) {
+      // Case of better combination.
+      delete best_track;
+      best_chi_dof = chi2_per_dof;
+      best_track = trialTrack;
+      trialTrack = NULL;
+    }
+    // Prepare for next combination.
+    track_volume->increment_combo_counters();
+  }
+
+  if (m_monitoring) fillTrackVolPlots(track_volume);
+  if (!best_track) return;
+
+  // If the best chi2 is too high, consider popping one cluster.
+  if (best_track->clusters().size() > m_MinNClusters + 1 &&
+      best_chi_dof > m_ChiSqRedCut) {
+    int popID = -1;
+    for (unsigned int i = 0; i < m_nPlanes; i++) {
+      m_trackFit->maskPlane(i);
+      m_trackFit->fit(best_track);
+      if (best_track->chi2PerNdof() < best_chi_dof) {
+        best_chi_dof = best_track->chi2PerNdof();
+        popID = i;
+      }
+      m_trackFit->unmaskPlane(i);
+    }
+    if (popID != -1) {
+      for (auto cluster : best_track->clusters()) {
+        if (int(cluster->plane()) == popID) {
+          best_track->removeFromClusters(cluster);
+        }
+      }
+    }
+    m_trackFit->fit(best_track);
+    counter("NumberOfPopRecoveredTracks") += 1;
+  }
+
+  // At this point, found the best fitting track in the volume.
+  // Apply chi2 cut, and save.
+  if (best_chi_dof > m_ChiSqRedCut) {
+    counter("NumberOfChiRejectedVols") += 1;
+    delete best_track;
+    return;
+  }
+
+  SmartRefVector<LHCb::TbCluster>& clusters =
+      const_cast<SmartRefVector<LHCb::TbCluster>&>(best_track->clusters());
+  auto earliest_hit =
+      std::min_element(clusters.begin(), clusters.end(),
+                       TbFunctors::LessByTime<const LHCb::TbCluster*>());
+
+  if (timingSvc()->beforeOverlap((*earliest_hit)->time()) || m_combatRun) {
+    for (auto itc = clusters.begin(), end = clusters.end(); itc != end; ++itc) {
+      (*itc)->setAssociated(true);
+    }
+    m_tracks->insert(best_track);
+    best_track->setTime(timingSvc()->localToGlobal(best_track->htime()));
+    if (m_monitoring) fillTrackVolPlots(track_volume);
+  } else {
+    info() << "Overlapping track" << endmsg;
+    delete best_track;
+  }
+}
+
+//=============================================================================
+// Monitoring plots
+//=============================================================================
+void TbTracking::fillTrackVolPlots(TbTrackVolume* vol) {
+  plot(vol->nCombos(), "nComboDist_of_TrackVolumes",
+       "nComboDist_of_TrackVolumes", -0.5, 1099.5, 1100);
+  unsigned int nclusters = 0;
+  for (unsigned int i = 0; i < vol->m_clusters.size(); i++) {
+    nclusters += vol->m_clusters[i].size();
+    if (vol->m_clusters[i].size() > 0) {
+      const std::string plane = std::to_string(vol->m_clusters[i][0]->plane());
+      plot(vol->m_clusters[i].size(),
+           "nVolClusters/nClusterPerVolPlane" + plane,
+           "nClusterPerVolPlane" + plane, 0.5, 10.5, 10);
+    }
+  }
+  plot(nclusters, "nVolClusters/nCluster_in_TrackVolumes",
+       "nCluster_in_TrackVolumes", -0.5, 99.5, 100);
+}
+
+//=============================================================================
+// Track time ordering - honeycomb
+//=============================================================================
+void TbTracking::timeOrderTracks() {
+
+  const double s_factor = 1.3;
+  LHCb::TbTrack* track1;
+  LHCb::TbTrack* track2;
+  unsigned int gap = m_tracks->size() / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    LHCb::TbTracks::iterator itt;
+    for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
+      track1 = *itt;
+      track2 = *(itt + gap);
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        std::iter_swap(itt, itt + gap);
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbTracking::outputViewerData() {
+  std::ofstream myfile;
+  myfile.open("KeplerViewerData.dat", std::ofstream::app);
+
+  // First output the chips.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    myfile << "Chip ";
+    Gaudi::XYZPoint posn1(0., 14.08, 0.);
+    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+    posn = geomSvc()->localToGlobal(posn2, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+    posn = geomSvc()->localToGlobal(posn3, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn4(0., 0., 0.);
+    posn = geomSvc()->localToGlobal(posn4, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    myfile << "\n";
+  }
+
+  // Tracks.
+  for (const LHCb::TbTrack* track : *m_tracks) {
+    myfile << "Track ";
+    myfile << track->firstState().tx() << " " << track->firstState().x() << " "
+           << track->firstState().ty() << " " << track->firstState().y() << " "
+           << track->htime() << "\n";
+  }
+
+  // Clusters.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    auto ic = m_clusterFinder->first(i);
+    const auto end = m_clusterFinder->end(i);
+    for (; ic != end; ++ic) {
+      const int tag = m_volumed[i][(*ic)->key()] + (*ic)->associated();
+      myfile << "Cluster ";
+      myfile << (*ic)->x() << " " << (*ic)->y() << " " << (*ic)->z() << " "
+             << (*ic)->htime() << " " << tag << " \n";
+      // Its hits.
+      for (const auto hit : (*ic)->hits()) {
+        myfile << "Pixel ";
+        double xLocal = 0.;
+        double yLocal = 0.;
+        geomSvc()->pixelToPoint(hit->scol(), hit->row(), i, xLocal, yLocal);
+        Gaudi::XYZPoint pLocal(xLocal - 0.5 * Tb::PixelPitch,
+                               yLocal - 0.5 * Tb::PixelPitch, 0.);
+        Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn2(pLocal.x() + Tb::PixelPitch, pLocal.y(), 0.);
+        posn = geomSvc()->localToGlobal(posn2, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn3(pLocal.x() + Tb::PixelPitch,
+                              pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn3, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn4, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        myfile << hit->htime() << " " << hit->ToT() << "\n";
+      }
+    }
+  }
+  myfile.close();
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbTracking.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbTracking.h.svn-base
new file mode 100644
index 0000000..de0123a
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTracking.h.svn-base
@@ -0,0 +1,93 @@
+#ifndef TB_TRACKING_H
+#define TB_TRACKING_H 1
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTrackVolume.h"
+
+/** @class TbTracking TbTracking.h
+ *
+ *  Algorithm for track reconstruction in Timepix3 telescope
+ *
+ * @author Dan Saunders
+ */
+
+class TbTracking : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbTracking();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// Track container (to be filled).
+  LHCb::TbTracks *m_tracks;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+  /// Tool to find particular clusters.
+  ITbClusterFinder *m_clusterFinder;
+  /// Tool for evaluating seed tracks.
+  TbTrackVolume *m_trackVolume;
+
+  /// TES location prefix of cluster containers.
+  std::string m_clusterLocation;
+  /// TES location prefix of track containers.
+  std::string m_trackLocation;
+
+  /// Flag to fill (or not) monitoring histograms.
+  bool m_monitoring;
+  /// Time width (in ns) of search window around seed cluster.
+  double m_twindow;
+  /// Minimum number of clusters to form a track.
+  unsigned int m_MinNClusters;
+  /// Spatial shapes of TbTrackVolumes {cylinder, diabolo}.
+  std::string m_search_3vol;
+  /// Spatial shape parameter.
+  double m_vol_radius;
+  /// Spatial shape parameter.
+  double m_vol_theta;
+  /// Chi2 cut.
+  double m_ChiSqRedCut;
+  /// Upper cut on the number of combinations to try in a TbTrackVolume.
+  /// Useful for speed, and rarely used; set O(100).
+  unsigned int m_nComboCut;
+  /// Search algorithm used to fill TbTrackVolumes - {"seq", "adap_seq"}.
+  /// "adap_seq" recommended.
+  std::string m_ClusterFinderSearchAlgorithm;
+
+  /// For certain volumes, it's advantageous to use seeds from the center of
+  /// the telescope, so the order of the search can be specified here.
+  std::vector<unsigned int> m_PlaneSearchOrder;
+  /// Max. size of clusters on a track
+  unsigned int m_clusterSizeCut;
+
+  std::vector<std::vector<bool> > m_volumed;
+  // Viewer options.
+  bool m_viewerOutput;
+  unsigned int m_viewerEvent;
+  unsigned int m_event;
+  bool m_combatRun;
+
+  void outputViewerData();
+  void performTracking();
+  void fillTrackVolume(LHCb::TbCluster *seed, const unsigned int &planeLow,
+                       const unsigned int &planeUp);
+  void evaluateTrackVolume(TbTrackVolume *vol);
+  void timeOrderTracks();
+  void fillTrackVolPlots(TbTrackVolume *vol);
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbTriggerAssociator.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbTriggerAssociator.cpp.svn-base
new file mode 100644
index 0000000..c55347c
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTriggerAssociator.cpp.svn-base
@@ -0,0 +1,88 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTriggerAssociator.h"
+
+DECLARE_ALGORITHM_FACTORY(TbTriggerAssociator)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTriggerAssociator::TbTriggerAssociator(const std::string& name,
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TriggerLocation",
+                  m_triggerLocation = LHCb::TbTriggerLocation::Default);
+
+  declareProperty("TimeWindow", m_twindow = 1000. * Gaudi::Units::ns);
+  declareProperty("TimeOffset", m_toffset = 0.);
+  declareProperty("Plane", m_plane = 999);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTriggerAssociator::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTriggerAssociator::execute() {
+
+  // Grab the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  // Grab the triggers.
+  std::vector<LHCb::TbTriggers*> triggers(m_nPlanes, nullptr);
+  std::vector<LHCb::TbTriggers::iterator> begin(m_nPlanes);
+  std::vector<LHCb::TbTriggers::iterator> end(m_nPlanes);
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (m_plane != 999 && i != m_plane) continue;
+    const std::string location = m_triggerLocation + std::to_string(i);
+    triggers[i] = getIfExists<LHCb::TbTriggers>(location);
+    if (!triggers[i]) {
+      return Error("No triggers in " + location);
+    }
+    begin[i] = triggers[i]->begin();
+    end[i] = triggers[i]->end();
+  }
+
+  // Loop over the tracks.
+  for (LHCb::TbTrack* track : *tracks) {
+    const double t = track->htime() + m_toffset;
+    // Calculate the time window.
+    const double tMin = t - m_twindow;
+    const double tMax = t + m_twindow;
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (m_plane != 999 && i != m_plane) continue;
+      if (triggers[i]->empty()) continue;
+      // Get the first trigger within the time window (if any).
+      LHCb::TbTriggers::iterator it =
+          std::lower_bound(begin[i], end[i], tMin, lowerBound());
+      if (it == end[i]) continue;
+      // Associate all triggers within the window to the track.
+      for (; it != end[i]; ++it) {
+        // Stop when outside the time window.
+        if ((*it)->htime() > tMax) break;
+        track->addToTriggers(*it);
+        (*it)->setAssociated(true);
+      }
+    }
+  }
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbTriggerAssociator.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbTriggerAssociator.h.svn-base
new file mode 100644
index 0000000..82c9a75
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTriggerAssociator.h.svn-base
@@ -0,0 +1,47 @@
+#ifndef TB_TRIGGER_ASSOCIATOR_H
+#define TB_TRIGGER_ASSOCIATOR_H 1
+
+// Tb/TbEvent
+#include "Event/TbTrigger.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTriggerAssociator TbTriggerAssociator.h
+ *
+ *  Algorithm to link reconstructed tracks with matching trigger timestamps.
+ *
+ */
+
+class TbTriggerAssociator : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTriggerAssociator(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbTriggerAssociator() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location of tracks
+  std::string m_trackLocation;
+  /// TES location of triggers
+  std::string m_triggerLocation;
+
+  /// Time window (in ns)
+  double m_twindow;
+  /// Time offset (in ns) of trigger packets with respect to tracks
+  double m_toffset;
+  /// Specify only a single plane to take triggers from , i.e. for multiple
+  /// external users using different SPIDRS
+  unsigned int m_plane;
+  /// Functor for lower bound search.
+  class lowerBound {
+   public:
+    bool operator()(const LHCb::TbTrigger *lhs, const double t) const {
+      return lhs->htime() < t;
+    }
+  };
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbTriggerMonitor.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbTriggerMonitor.cpp.svn-base
new file mode 100644
index 0000000..7c5cb7c
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTriggerMonitor.cpp.svn-base
@@ -0,0 +1,116 @@
+// Gaudi
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbTrigger.h"
+
+// Local
+#include "TbTriggerMonitor.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbTriggerMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTriggerMonitor::TbTriggerMonitor(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parTriggersInEvent("", 0., 1000., 200),
+      m_nEvents(0) {
+
+  declareProperty("TriggerLocation",
+                  m_triggerLocation = LHCb::TbTriggerLocation::Default);
+  declareProperty("ParametersTriggersInEvent", m_parTriggersInEvent);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTriggerMonitor::~TbTriggerMonitor() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbTriggerMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  m_missedTriggers.resize(m_nPlanes);
+  m_counter.resize(m_nPlanes);
+  m_counter.resize(m_nPlanes, 0);
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    std::string name = "TimeBetweenTriggers";
+    std::string title = "Plane " + plane;
+    m_hTimeBetweenTriggers.push_back(book1D(name, title, 0., 500., 200));
+    setAxisLabels(m_hTimeBetweenTriggers[i], "#Deltat [ns]", "entries");
+    unsigned int bins = m_parTriggersInEvent.bins();
+    double low = m_parTriggersInEvent.lowEdge();
+    double high = m_parTriggersInEvent.highEdge();
+    name = "TriggersInEvent/Plane" + plane;
+    m_hTriggersInEvent.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hTriggersInEvent[i], "number of triggers", "events");
+    name = "TriggersInEventTrend/Plane" + plane;
+    m_hTriggersInEventTrend.push_back(book1D(name, title, -0.5, 999.5, 1000));
+    setAxisLabels(m_hTriggersInEventTrend[i], "event", "number of hits");
+  }
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TbTriggerMonitor::finalize() {
+  /*
+    for( unsigned int i = 0 ; i < m_nPlanes; ++i){
+
+     std::vector<std::pair<uint64_t, uint64_t>> summary = m_missedTriggers[i];
+      if( summary.size() != 0 ){
+        info() << "Trigger jumps on plane " << i << endmsg;;
+        for( std::vector<std::pair<uint64_t, uint64_t >>::iterator jump =
+    summary.begin(); jump != summary.end(); ++jump ){
+
+          info() << "Trigger jumps from " << jump->second << " to " <<
+    jump->first << endmsg;
+        }
+      }
+    }
+  */
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTriggerMonitor::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Grab the triggers.
+    const std::string ext = std::to_string(i);
+    const std::string location = m_triggerLocation + ext;
+    const LHCb::TbTriggers* triggers = getIfExists<LHCb::TbTriggers>(location);
+    if (!triggers) return StatusCode::SUCCESS;
+    m_hTriggersInEvent[i]->fill(triggers->size());
+    m_hTriggersInEventTrend[i]->fill(m_nEvents, triggers->size());
+    double tprev = 0.;
+    LHCb::TbTriggers::const_iterator begin = triggers->begin();
+    LHCb::TbTriggers::const_iterator end = triggers->end();
+    for (LHCb::TbTriggers::const_iterator it = begin; it != end; ++it) {
+      // Check for missed triggers.
+      if ((*it)->counter() - m_counter[i] != 1 && m_counter[i] != 4095) {
+        info() << "Counter on plane " << i << " jumps from " << m_counter[i]
+               << " to " << (*it)->counter() << endmsg;
+      }
+      m_counter[i] = (*it)->counter();
+      const double t = (*it)->htime();
+
+      if (it != begin) {
+        m_hTimeBetweenTriggers[i]->fill(t - tprev);
+      }
+      tprev = t;
+      counter("effFractionAssociated" + ext) += (*it)->associated();
+    }
+  }
+  ++m_nEvents;
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbTriggerMonitor.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbTriggerMonitor.h.svn-base
new file mode 100644
index 0000000..816ff2b
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbTriggerMonitor.h.svn-base
@@ -0,0 +1,45 @@
+#ifndef TB_TRIGGER_MONITOR_H
+#define TB_TRIGGER_MONITOR_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTriggerMonitor TbTriggerMonitor.h
+ *
+ *  Algorithm to produce monitoring histograms for scintillator triggers.
+ *
+ */
+
+class TbTriggerMonitor : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbTriggerMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTriggerMonitor();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm Finalize
+ private:
+  /// TES location of triggers.
+  std::string m_triggerLocation;
+
+  /// Parameters for hits / event distribution histograms
+  Gaudi::Histo1DDef m_parTriggersInEvent;
+
+  /// Event counter
+  unsigned int m_nEvents;
+
+  /// Last trigger counters
+  std::vector<unsigned int> m_counter;
+
+  std::vector<AIDA::IHistogram1D*> m_hTimeBetweenTriggers;
+  std::vector<AIDA::IHistogram1D*> m_hTriggersInEvent;
+  std::vector<AIDA::IHistogram1D*> m_hTriggersInEventTrend;
+  std::vector<std::vector<std::pair<uint64_t, uint64_t>>> m_missedTriggers;
+};
+
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbVertexTracking.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbVertexTracking.cpp.svn-base
new file mode 100644
index 0000000..79b0208
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbVertexTracking.cpp.svn-base
@@ -0,0 +1,607 @@
+#include <algorithm>
+#include <fstream>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbVertexTracking.h"
+
+DECLARE_ALGORITHM_FACTORY(TbVertexTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbVertexTracking::TbVertexTracking(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_tracks(nullptr),
+      m_trackFit(nullptr),
+      m_clusterFinder(nullptr),
+      m_event(0) {
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+
+  declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
+  declareProperty("MinNClusters", m_MinNClusters = 7);
+  declareProperty("SearchVolumeFillAlgorithm",
+                  m_ClusterFinderSearchAlgorithm = "adap_seq");
+  declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
+  declareProperty("ClusterSizeCut", m_clusterSizeCut = 1000);
+  declareProperty("MinNClustersRepeat", m_MinNClustersRepeat = 3);
+  declareProperty("RadialCut", m_radialCut = 0.2);
+
+  declareProperty("ViewerOutput", m_viewerOutput = false);
+  declareProperty("ViewerEventNum", m_viewerEvent = 100);
+  declareProperty("CombatRun", m_combatRun = false);
+  declareProperty("MaxChi2", m_ChiSqRedCut = 200.);
+  declareProperty("DoVertexting", m_doVertexting = false);
+  declareProperty("DoRepeat", m_doRepeat = true);
+  declareProperty("AngleCut", m_angleCut = 0.2);
+
+  declareProperty("VertexDelR", m_vertexDelR = 0.1);
+  declareProperty("VertexDelT", m_vertexDelT = 10);
+  m_currentAngleCut = m_angleCut;
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbVertexTracking::~TbVertexTracking() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbVertexTracking::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+  // Set up the cluster finder.
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+  if (!m_clusterFinder) return Error("Cannot retrieve cluster finder tool.");
+  m_endCluster.resize(m_nPlanes);
+  m_vertexedCluster.resize(m_nPlanes);
+  m_volumed.resize(m_nPlanes);
+  initialStateVsFitStateTx =
+      book2D("initialStateVsFitStateTx", "initialStateVsFitStateTx", -0.001,
+             0.001, 200, -0.001, 0.001, 200);
+  initialStateVsFitStateTy =
+      book2D("initialStateVsFitStateTy", "initialStateVsFitStateTy", -0.001,
+             0.001, 200, -0.001, 0.001, 200);
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbVertexTracking::execute() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (m_event == m_viewerEvent && m_viewerOutput) {
+      std::ofstream myfile;
+      myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat");
+      myfile << "# Output\n";
+      myfile.close();
+    }
+
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      error() << "No clusters in " << clusterLocation << endmsg;
+      return StatusCode::FAILURE;
+    }
+    m_endCluster[i].clear();
+    m_endCluster[i].resize(clusters->size(), false);
+    m_vertexedCluster[i].clear();
+    m_vertexedCluster[i].resize(clusters->size(), false);
+    m_volumed[i].clear();
+    m_volumed[i].resize(clusters->size(), false);
+    // Store the cluster iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+  }
+
+  // Check if there is already a track container.
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!m_tracks) {
+    // Create a track container and transfer its ownership to the TES.
+    m_tracks = new LHCb::TbTracks();
+    put(m_tracks, m_trackLocation);
+  }
+  m_vertices = new LHCb::TbVertices();
+  put(m_vertices, LHCb::TbVertexLocation::Default);
+
+  // Advantagous to filter out the thin tracks.
+  m_currentAngleCut = 0.01;
+  performVertexTracking();
+  m_currentAngleCut = m_angleCut;
+  performVertexTracking();
+
+  if (m_doRepeat) {
+    // Allow lower demands on track size.
+    unsigned int tempSizeHolder = m_MinNClusters;
+    m_MinNClusters = m_MinNClustersRepeat;
+    performVertexTracking();
+    m_MinNClusters = tempSizeHolder;
+  }
+
+  timeOrderTracks();
+
+  if (m_doVertexting) collectIntoVertices();
+  /*
+  LHCb::TbTracks::iterator itrack;
+  for (itrack = m_tracks->begin(); itrack < m_tracks->end() - 1; itrack++) {
+    plot((*(itrack + 1))->htime() - (*itrack)->htime(), "TimeBetweenTracks",
+         "TimeBetweenTracks", 0.0, 5000, 500);
+  }
+  */
+  counter("NumberOfTracks") += m_tracks->size();
+  counter("NumberOfVertices") += m_vertices->size();
+  if (m_event == m_viewerEvent && m_viewerOutput) outputViewerData();
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+void TbVertexTracking::collectIntoVertices() {
+  // Iterate over tracks.
+  LHCb::TbVertex* tempVertex = nullptr;
+  LHCb::TbTracks::iterator itrack;
+  for (itrack = m_tracks->begin(); itrack < m_tracks->end(); itrack++) {
+    tempVertex = nullptr;
+    if ((*itrack)->vertexed()) continue;
+    LHCb::TbTracks::iterator jtrack;
+    for (jtrack = itrack; jtrack < m_tracks->end(); jtrack++) {
+      if ((*jtrack)->vertexed() || itrack == jtrack) continue;
+
+      // Check time difference.
+      if (fabs((*itrack)->htime() - (*jtrack)->htime()) < m_vertexDelT) {
+        // Assume decay happened near a detector.
+        for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+          // Work out the spatial separation.
+          Gaudi::XYZPoint intercept1 = geomSvc()->intercept((*itrack), iplane);
+          Gaudi::XYZPoint intercept2 = geomSvc()->intercept((*jtrack), iplane);
+          double delr2 = pow(intercept1.x() - intercept2.x(), 2);
+          delr2 += pow(intercept1.y() - intercept2.y(), 2);
+          if (pow(delr2, 0.5) < m_vertexDelR) {
+
+            // We have a vertex, although should also add some cluster counting.
+            if (tempVertex == nullptr) {
+              tempVertex = new LHCb::TbVertex();
+              tempVertex->addToTracks(*itrack);
+              (*itrack)->setVertexed(true);
+              tempVertex->setX(intercept1.x());
+              tempVertex->setY(intercept1.y());
+              tempVertex->setZ(intercept1.z());
+              tempVertex->setHtime((*itrack)->htime());
+              tempVertex->setInteractionPlane(iplane);
+
+              SmartRefVector<LHCb::TbCluster>& clusters =
+                  const_cast<SmartRefVector<LHCb::TbCluster>&>(
+                      (*itrack)->clusters());
+              for (unsigned int i = 0; i < clusters.size(); i++) {
+                m_vertexedCluster[clusters[i]->plane()][clusters[i]->key()] =
+                    true;
+                unsigned int plane = clusters[i]->plane();
+                if (plane == 0 || plane == 1 || plane == 2)
+                  (*itrack)->setParentVertex(true);
+              }
+            }
+
+            tempVertex->addToTracks(*jtrack);
+            (*jtrack)->setVertexed(true);
+            SmartRefVector<LHCb::TbCluster>& clusters =
+                const_cast<SmartRefVector<LHCb::TbCluster>&>(
+                    (*jtrack)->clusters());
+            for (unsigned int i = 0; i < clusters.size(); i++) {
+              m_vertexedCluster[clusters[i]->plane()][clusters[i]->key()] =
+                  true;
+              unsigned int plane = clusters[i]->plane();
+              if (plane == 0 || plane == 1 || plane == 2)
+                (*jtrack)->setParentVertex(true);
+            }
+            break;
+          }
+        }
+      }
+      if ((*jtrack)->htime() - (*itrack)->htime() > m_vertexDelT) break;
+    }
+    if (tempVertex != nullptr) m_vertices->insert(tempVertex);
+  }
+
+  // Remove tracks forming vertices from m_tracks.
+  LHCb::TbVertices::iterator ivertex;
+  for (ivertex = m_vertices->begin(); ivertex != m_vertices->end(); ivertex++) {
+    SmartRefVector<LHCb::TbTrack>& tracks =
+        const_cast<SmartRefVector<LHCb::TbTrack>&>((*ivertex)->tracks());
+    for (unsigned int i = 0; i < tracks.size(); i++)
+      m_tracks->remove(tracks[i]);
+  }
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+void TbVertexTracking::performVertexTracking() {
+  // Iterate over search planes.
+  for (const auto& plane : m_PlaneSearchOrder) {
+
+    if (masked(plane) || m_clusterFinder->empty(plane)) continue;
+    auto ic = m_clusterFinder->first(plane);
+    const auto end = m_clusterFinder->end(plane);
+    for (; ic != end; ++ic) {
+      // Check if too big, and if already tracked.
+      if ((*ic)->size() > m_clusterSizeCut) continue;
+      if ((*ic)->associated() && !m_endCluster[plane][(*ic)->key()]) continue;
+      formTrack(*ic);
+    }
+  }
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+void TbVertexTracking::evalHoughState(LHCb::TbCluster* seed,
+                                      LHCb::TbCluster* cluster2,
+                                      LHCb::TbState* tempInitialState) {
+  if (m_event == m_viewerEvent && m_viewerOutput)
+    outputHoughState(seed, cluster2);
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+  track->addToClusters(seed);
+  track->addToClusters(cluster2);
+  track->setFirstState(*tempInitialState);
+  bool sizeSuitable = fillTrack(track, seed, cluster2);
+  if (!sizeSuitable) {
+    counter("NumberOfSizeRejectedTracks") += 1;
+    delete track;
+  } else {
+    m_trackFit->fit(track);
+    initialStateVsFitStateTx->fill(track->firstState().tx(),
+                                   tempInitialState->tx());
+    initialStateVsFitStateTy->fill(track->firstState().ty(),
+                                   tempInitialState->ty());
+    plot(track->firstState().tx() - tempInitialState->tx(),
+         "initialStateMinusFittedStateX", "initialStateMinusFittedStateX",
+         -0.005, 0.005, 200);
+
+    // Consider popping one clusters if its going to fail.
+    int popID = -1;
+    double chi = track->chi2PerNdof();
+    if (track->clusters().size() > m_MinNClusters + 1 &&
+        track->chi2PerNdof() > m_ChiSqRedCut) {
+      for (unsigned int i = 0; i < m_nPlanes; i++) {
+        m_trackFit->maskPlane(i);
+        m_trackFit->fit(track);
+        if (track->chi2PerNdof() < chi) {
+          chi = track->chi2PerNdof();
+          popID = i;
+        }
+        m_trackFit->unmaskPlane(i);
+      }
+      if (popID != -1) {
+        for (auto cluster : track->clusters()) {
+          if (int(cluster->plane()) == popID) {
+            track->removeFromClusters(cluster);
+          }
+        }
+      }
+      m_trackFit->fit(track);
+      if (track->chi2PerNdof() < m_ChiSqRedCut)
+        counter("NumberOfPopRecoveredTracks") += 1;
+    }
+
+    if (track->chi2PerNdof() < m_ChiSqRedCut) {
+      SmartRefVector<LHCb::TbCluster>& clusters =
+          const_cast<SmartRefVector<LHCb::TbCluster>&>(track->clusters());
+      auto earliest_hit =
+          std::min_element(clusters.begin(), clusters.end(),
+                           TbFunctors::LessByTime<const LHCb::TbCluster*>());
+
+      if (timingSvc()->beforeOverlap((*earliest_hit)->time()) || m_combatRun) {
+        auto farthest_hit =
+            std::max_element(clusters.begin(), clusters.end(),
+                             TbFunctors::LessByZ<const LHCb::TbCluster*>());
+        if ((*farthest_hit)->plane() != m_nPlanes - 1) {
+          m_endCluster[(*farthest_hit)->plane()][(*farthest_hit)->key()] = true;
+        }
+        auto nearest_hit =
+            std::min_element(clusters.begin(), clusters.end(),
+                             TbFunctors::LessByZ<const LHCb::TbCluster*>());
+        if ((*nearest_hit)->plane() != 0) {
+          m_endCluster[(*nearest_hit)->plane()][(*nearest_hit)->key()] = true;
+        }
+
+        m_tracks->insert(track);
+        track->setTime(timingSvc()->localToGlobal(track->htime()));
+        track->setAssociated(true);
+      }
+    } else {
+      delete track;
+      counter("NumberOfChiRejectedTracks") += 1;
+    }
+  }
+}
+
+//=============================================================================
+//
+//=============================================================================
+bool TbVertexTracking::fillTrack(LHCb::TbTrack* track,
+                                 LHCb::TbCluster* seedCluster,
+                                 LHCb::TbCluster* cluster2) {
+  unsigned int nAllowedGaps = m_nPlanes - m_MinNClusters;
+  unsigned int nGaps = 0;
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    bool foundCluster = false;
+    if (m_clusterFinder->empty(iplane) || masked(iplane) ||
+        iplane == seedCluster->plane() || iplane == cluster2->plane()) {
+      // nGaps++;
+      continue;
+    }
+    auto ic =
+        m_clusterFinder->getIterator(seedCluster->htime() - m_twindow, iplane);
+    const auto end = m_clusterFinder->end(iplane);
+    for (; ic != end; ++ic) {
+      if ((*ic)->size() > m_clusterSizeCut) continue;
+      Gaudi::XYZPoint intercept = geomSvc()->intercept(track, iplane);
+      double delr2 = pow(intercept.y() - (*ic)->y(), 2);
+      delr2 += pow(intercept.x() - (*ic)->x(), 2);
+
+      plot(intercept.x() - (*ic)->x(), "initialResidualX", "initialResidualX",
+           -0.05, 0.05, 200);
+      plot(intercept.y() - (*ic)->y(), "initialResidualY", "initialResidualY",
+           -0.05, 0.05, 200);
+
+      if (m_event == m_viewerEvent && m_viewerOutput)
+        outputPatternRecog(intercept.x(), intercept.y(), intercept.z(),
+                           seedCluster->htime());
+
+      if (pow(delr2, 0.5) < m_radialCut) {
+        if (!(*ic)->associated() ||
+            m_endCluster[(*ic)->plane()][(*ic)->key()]) {
+          m_volumed[(*ic)->plane()][(*ic)->key()] = true;
+          track->addToClusters(*ic);
+          m_trackFit->fit(track);
+          foundCluster = true;
+          break;
+        }
+      }
+      if ((*ic)->htime() > seedCluster->htime() + m_twindow) break;
+    }
+    if (!foundCluster) nGaps++;
+    if (nGaps == nAllowedGaps) return false;
+  }
+  if (track->clusters().size() < m_MinNClusters) return false;
+  return true;
+}
+
+//=============================================================================
+//
+//=============================================================================
+void TbVertexTracking::formTrack(LHCb::TbCluster* seedCluster) {
+  bool madeTrack = false;
+  // Form pairs of clusters from either side of seed plane.
+  // Eval each pair as its formed.
+  for (unsigned int iplane = seedCluster->plane() - 1;
+       iplane != seedCluster->plane() + 2; iplane++) {
+    if (m_clusterFinder->empty(iplane) || iplane == seedCluster->plane() ||
+        masked(iplane))
+      continue;
+    auto ic =
+        m_clusterFinder->getIterator(seedCluster->htime() - m_twindow, iplane);
+    const auto end = m_clusterFinder->end(iplane);
+    for (; ic != end; ++ic) {
+
+      // Find the gradients between the pair.
+      if ((*ic)->size() > m_clusterSizeCut || (*ic)->associated()) continue;
+      double tx =
+          (seedCluster->x() - (*ic)->x()) / (seedCluster->z() - (*ic)->z());
+      double ty =
+          (seedCluster->y() - (*ic)->y()) / (seedCluster->z() - (*ic)->z());
+      double x0 = seedCluster->x() - tx * seedCluster->z();
+      double y0 = seedCluster->y() - ty * seedCluster->z();
+      Gaudi::SymMatrix4x4 cov;
+      LHCb::TbState fstate(Gaudi::Vector4(x0, y0, tx, ty), cov, 0., 0);
+      plot(tx, "initialTx", "initialTx", -0.1, 0.1, 200);
+      plot(ty, "initialTy", "initialTy", -0.1, 0.1, 200);
+
+      counter("NumberOfFormedHoughStates") += 1;
+      if (fabs(tx) < 0.01 && fabs(ty) < 0.01) counter("nThinStates") += 1;
+      if (fabs(tx) < m_currentAngleCut && fabs(ty) < m_currentAngleCut) {
+        evalHoughState(seedCluster, (*ic), &fstate);
+        if (seedCluster->associated() &&
+            !m_endCluster[seedCluster->plane()][seedCluster->key()]) {
+          madeTrack = true;
+          break;
+        }
+      } else
+        counter("nAngleCutStates") += 1;
+      if ((*ic)->htime() > seedCluster->htime() + m_twindow) break;
+    }
+    if (madeTrack) break;
+  }
+}
+
+//=============================================================================
+// Viewer outputs
+//=============================================================================
+void TbVertexTracking::outputVertices() {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  for (LHCb::TbVertex* vertex : *m_vertices) {
+    myfile << "Vertex " << vertex->x() << " " << vertex->y() << " "
+           << vertex->z() << " " << vertex->htime() << " "
+           << vertex->tracks().size() << " ";
+    for (unsigned int i = 0; i < vertex->tracks().size(); i++) {
+      myfile << vertex->tracks()[i]->firstState().tx() << " "
+             << vertex->tracks()[i]->firstState().x() << " "
+             << vertex->tracks()[i]->firstState().ty() << " "
+             << vertex->tracks()[i]->firstState().y() << " ";
+      if (vertex->tracks()[i]->parentVertex())
+        myfile << "1 ";
+      else
+        myfile << "0 ";
+    }
+    myfile << "\n";
+  }
+  myfile.close();
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVertexTracking::outputPatternRecog(double x, double y, double z,
+                                          double ht) {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  myfile << "PatternRecogCircle " << x << " " << y << " " << z << " " << ht
+         << " " << m_radialCut << "\n";
+  myfile.close();
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVertexTracking::outputHoughState(LHCb::TbCluster* c1,
+                                        LHCb::TbCluster* c2) {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  myfile << "HoughState " << c1->x() << " " << c1->y() << " " << c1->z() << " "
+         << c2->x() << " " << c2->y() << " " << c2->z() << " " << c1->htime()
+         << " " << c2->htime() << " \n";
+  myfile.close();
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVertexTracking::outputViewerData() {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  // First output the chips.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    myfile << "Chip ";
+    Gaudi::XYZPoint posn1(0., 14.08, 0.);
+    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+    posn = geomSvc()->localToGlobal(posn2, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+    posn = geomSvc()->localToGlobal(posn3, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn4(0., 0., 0.);
+    posn = geomSvc()->localToGlobal(posn4, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+    myfile << "\n";
+  }
+
+  // Tracks.
+  for (LHCb::TbTrack* track : *m_tracks) {
+    myfile << "Track " << track->firstState().tx() << " "
+           << track->firstState().x() << " " << track->firstState().ty() << " "
+           << track->firstState().y() << " " << track->htime() << "\n";
+  }
+
+  // Clusters.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const auto end = m_clusterFinder->end(i);
+    for (auto it = m_clusterFinder->first(i); it != end; ++it) {
+      myfile << "Cluster " << (*it)->x() << " " << (*it)->y() << " "
+             << (*it)->z() << " " << (*it)->htime() << " ";
+      const bool endCluster = m_endCluster[(*it)->plane()][(*it)->key()];
+      const bool vertexed = m_vertexedCluster[(*it)->plane()][(*it)->key()];
+      if (endCluster && vertexed) {
+        myfile << "5 \n";
+      } else if (vertexed) {
+        myfile << "4 \n";
+      } else if (endCluster) {
+        myfile << "3 \n";
+      } else if ((*it)->associated()) {
+        myfile << "2 \n";
+      } else if (m_volumed[(*it)->plane()][(*it)->key()]) {
+        myfile << "1 \n";
+      } else {
+        myfile << "0 \n";
+      }
+
+      // Its hits.
+      for (auto hit : (*it)->hits()) {
+        myfile << "Pixel ";
+        double xLocal = 0.;
+        double yLocal = 0.;
+        geomSvc()->pixelToPoint(hit->scol(), hit->row(), i, xLocal, yLocal);
+        Gaudi::XYZPoint pLocal(xLocal - 0.5 * Tb::PixelPitch,
+                               yLocal - 0.5 * Tb::PixelPitch, 0.);
+        Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        Gaudi::XYZPoint posn2(pLocal.x() + 0.055, pLocal.y(), 0.);
+        posn = geomSvc()->localToGlobal(posn2, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        Gaudi::XYZPoint posn3(pLocal.x() + 0.055, pLocal.y() + 0.055, 0.);
+        posn = geomSvc()->localToGlobal(posn3, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y() + 0.055, 0.);
+        posn = geomSvc()->localToGlobal(posn4, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        myfile << hit->htime() << " " << hit->ToT() << "\n";
+      }
+    }
+  }
+  myfile.close();
+  outputVertices();
+}
+
+//=============================================================================
+// Track time ordering - honeycomb
+//=============================================================================
+void TbVertexTracking::timeOrderTracks() {
+
+  const double s_factor = 1.3;
+  LHCb::TbTrack* track1;
+  LHCb::TbTrack* track2;
+  unsigned int gap = m_tracks->size() / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    LHCb::TbTracks::iterator itt;
+    for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
+      track1 = *itt;
+      track2 = *(itt + gap);
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        std::iter_swap(itt, itt + gap);
+        swapped = true;
+      }
+    }
+  }
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbVertexTracking.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbVertexTracking.h.svn-base
new file mode 100644
index 0000000..bb317e6
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbVertexTracking.h.svn-base
@@ -0,0 +1,82 @@
+#ifndef TB_VERTEXTRACKING_H
+#define TB_VERTEXTRACKING_H 1
+
+// AIDA
+#include "AIDA/IHistogram2D.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+#include "Event/TbVertex.h"
+
+/** @class TbVertexTracking TbVertexTracking.h
+ *
+ *  Algorithm for tracks with vertices reconstruction
+ *
+ * @author Dan Saunders
+ */
+
+class TbVertexTracking : public TbAlgorithm {
+ public:
+  TbVertexTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  virtual ~TbVertexTracking();
+  virtual StatusCode initialize();
+  virtual StatusCode execute();
+
+ private:
+  LHCb::TbTracks *m_tracks;
+  LHCb::TbVertices *m_vertices;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+  ITbClusterFinder *m_clusterFinder;
+  std::string m_clusterLocation;
+  std::string m_trackLocation;
+  std::vector<std::vector<bool> > m_endCluster;
+  std::vector<std::vector<bool> > m_vertexedCluster;
+  std::vector<std::vector<bool> > m_volumed;
+
+  double m_twindow;
+  unsigned int m_MinNClusters;
+  unsigned int m_MinNClustersRepeat;
+  double m_ChiSqRedCut;
+  std::string m_ClusterFinderSearchAlgorithm;
+  std::vector<unsigned int> m_PlaneSearchOrder;
+  unsigned int m_clusterSizeCut;
+
+  bool m_viewerOutput;
+  unsigned int m_viewerEvent;
+  unsigned int m_event;
+  bool m_combatRun;
+  double m_radialCut;
+  bool m_doVertexting;
+  bool m_doRepeat;
+  double m_angleCut;
+  double m_currentAngleCut;
+  double m_vertexDelR;
+  double m_vertexDelT;
+
+  // Historgrams ______________________________________________________________
+  AIDA::IHistogram2D *initialStateVsFitStateTx;
+  AIDA::IHistogram2D *initialStateVsFitStateTy;
+
+  // Methods __________________________________________________________________
+  bool fillTrack(LHCb::TbTrack *, LHCb::TbCluster *, LHCb::TbCluster *);
+  void evalHoughState(LHCb::TbCluster *, LHCb::TbCluster *, LHCb::TbState *);
+  void outputViewerData();
+  void performVertexTracking();
+  void timeOrderTracks();
+  void formTrack(LHCb::TbCluster *);
+  void outputPatternRecog(double, double, double, double);
+  void outputHoughState(LHCb::TbCluster *, LHCb::TbCluster *);
+  void collectIntoVertices();
+  void outputVertices();
+};
+#endif
diff --git a/TbAlgorithms/src/.svn/text-base/TbVisualiserOutput.cpp.svn-base b/TbAlgorithms/src/.svn/text-base/TbVisualiserOutput.cpp.svn-base
new file mode 100644
index 0000000..0fae00e
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbVisualiserOutput.cpp.svn-base
@@ -0,0 +1,142 @@
+#include <fstream>
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbVisualiserOutput.h"
+
+DECLARE_ALGORITHM_FACTORY(TbVisualiserOutput)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbVisualiserOutput::TbVisualiserOutput(const std::string& name,
+                                       ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator), m_event(0) {
+  declareProperty("ViewerEvent", m_viewerEvent = 7);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbVisualiserOutput::~TbVisualiserOutput() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbVisualiserOutput::initialize() {
+
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbVisualiserOutput::execute() {
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!m_tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  if (m_event == m_viewerEvent) {
+
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+      LHCb::TbClusters* clusters =
+          getIfExists<LHCb::TbClusters>(clusterLocation);
+      m_clusterFinder->setClusters(clusters, i);
+    }
+    outputViewerData();
+  }
+
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVisualiserOutput::outputViewerData() {
+  std::ofstream myfile;
+  myfile.open("KeplerViewerData.dat", std::ofstream::app);
+  myfile << "# Output\n";
+  // First output the chips.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    myfile << "Chip ";
+    Gaudi::XYZPoint posn1(0., 14.08, 0.);
+    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+    posn = geomSvc()->localToGlobal(posn2, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+    posn = geomSvc()->localToGlobal(posn3, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn4(0., 0., 0.);
+    posn = geomSvc()->localToGlobal(posn4, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    myfile << "\n";
+  }
+  // Tracks.
+  for (const LHCb::TbTrack* track : *m_tracks) {
+    myfile << "Track ";
+    myfile << track->firstState().tx() << " " << track->firstState().x() << " "
+           << track->firstState().ty() << " " << track->firstState().y() << " "
+           << track->htime() << "\n";
+  }
+  // Clusters.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    auto ic = m_clusterFinder->first(i);
+    const auto end = m_clusterFinder->end(i);
+    for (; ic != end; ++ic) {
+      const int tag = (*ic)->associated();
+      myfile << "Cluster ";
+      myfile << (*ic)->x() << " " << (*ic)->y() << " " << (*ic)->z() << " "
+             << (*ic)->htime() << " " << tag << " \n";
+      // Its hits.
+      for (const auto hit : (*ic)->hits()) {
+        myfile << "Pixel ";
+        double xLocal = 0.;
+        double yLocal = 0.;
+        geomSvc()->pixelToPoint(hit->scol(), hit->row(), i, xLocal, yLocal);
+        Gaudi::XYZPoint pLocal(xLocal - 0.5 * Tb::PixelPitch,
+                               yLocal - 0.5 * Tb::PixelPitch, 0.);
+        Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn2(pLocal.x() + Tb::PixelPitch, pLocal.y(), 0.);
+        posn = geomSvc()->localToGlobal(posn2, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn3(pLocal.x() + Tb::PixelPitch,
+                              pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn3, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn4, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        myfile << hit->htime() << " " << hit->ToT() << "\n";
+      }
+    }
+  }
+  myfile.close();
+}
diff --git a/TbAlgorithms/src/.svn/text-base/TbVisualiserOutput.h.svn-base b/TbAlgorithms/src/.svn/text-base/TbVisualiserOutput.h.svn-base
new file mode 100644
index 0000000..059240a
--- /dev/null
+++ b/TbAlgorithms/src/.svn/text-base/TbVisualiserOutput.h.svn-base
@@ -0,0 +1,36 @@
+#ifndef TB_VISUALISEROUTPUT_H
+#define TB_VISUALISEROUTPUT_H 1
+
+// Tb/TbKernel
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+/** @class TbVisualiserOutput TbVisualiserOutput.h
+ * @author Dan Saunders
+ */
+
+class TbVisualiserOutput : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbVisualiserOutput(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbVisualiserOutput();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  LHCb::TbTracks *m_tracks;
+  ITbClusterFinder *m_clusterFinder;
+  std::string m_clusterLocation;
+  std::string m_trackLocation;
+
+  unsigned int m_viewerEvent;
+  unsigned int m_event;
+
+  void outputViewerData();
+};
+#endif
diff --git a/TbAlgorithms/src/TbCalibration.cpp b/TbAlgorithms/src/TbCalibration.cpp
new file mode 100644
index 0000000..7bb42e6
--- /dev/null
+++ b/TbAlgorithms/src/TbCalibration.cpp
@@ -0,0 +1,280 @@
+#include <fstream>
+
+// Tb/TbKernel
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbCalibration.h"
+
+// ROOT
+#include "TFitResult.h"
+#include "TFitResultPtr.h"
+#include "TH1D.h"
+
+/// GAUDI
+#include "GaudiUtils/Aida2ROOT.h"
+
+DECLARE_ALGORITHM_FACTORY(TbCalibration)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbCalibration::TbCalibration(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+  declareProperty("PixelConfigFile", m_pixelSvcConfig = "PixelConfig.dat");
+  declareProperty("TimingConfigFile", m_timingSvcConfig = "TimingConfig.dat");
+  declareProperty("CheckHotPixels", m_checkHotPixels = false);
+  declareProperty("CheckSynchronisation", m_checkSyncronisation = false);
+  declareProperty("SyncMethod", m_syncMethod = 1);
+  declareProperty("CheckColumnOffsets", m_checkColumnOffsets = false);
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("DuT", m_dut = 9999);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbCalibration::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  if (m_checkColumnOffsets) m_offsets.resize(m_nPlanes, PROFILE1D(128));
+  if (m_checkHotPixels) m_hitMaps.resize(m_nDevices, PROFILE2D(256, 256));
+  if (m_checkSyncronisation) m_sync.resize(m_nPlanes);
+  return sc;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbCalibration::execute() {
+
+  if (m_checkColumnOffsets) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      LHCb::TbClusters* clusters =
+          getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(i));
+      if (!clusters) continue;
+      columnOffset_execute(clusters);
+    }
+  }
+  if (m_checkHotPixels) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      LHCb::TbHits* hits =
+          getIfExists<LHCb::TbHits>(m_hitLocation + std::to_string(i));
+      if (!hits) continue;
+      hotPixel_execute(hits);
+    }
+  }
+  if (m_checkSyncronisation) {
+    if (m_syncMethod == 0) {
+      std::vector<LHCb::TbClusters*> clusters;
+      for (unsigned int i = 0; i < m_nPlanes; ++i)
+        clusters.push_back(getIfExists<LHCb::TbClusters>(m_clusterLocation +
+                                                         std::to_string(i)));
+      sync_execute(clusters);
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+StatusCode TbCalibration::finalize() {
+
+  std::ofstream pixelFile(m_pixelSvcConfig.c_str());
+  std::ofstream timingFile(m_timingSvcConfig.c_str());
+
+  if (m_checkHotPixels) {
+    pixelFile << "Mask" << std::endl;
+    for (unsigned int i = 0; i < m_nDevices; ++i)
+      hotPixelAnalysis(m_hitMaps[i], geomSvc()->module(i)->id(), pixelFile);
+  }
+  if (m_checkSyncronisation) {
+    if (m_syncMethod == 0)
+      for (unsigned int i = 0; i < m_nPlanes; ++i)
+        syncAnalysis(m_sync[i].avg(), geomSvc()->module(i)->id(), timingFile);
+    else if (m_syncMethod == 1)
+      syncOffset2(timingFile);
+  }
+  if (m_checkColumnOffsets) {
+    pixelFile << "Offset" << std::endl;
+    for (unsigned int i = 0; i < m_nPlanes; ++i)
+      columnOffsetAnalysis(m_offsets[i], geomSvc()->module(i)->id(), pixelFile);
+  }
+  pixelFile.close();
+  timingFile.close();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Identify hot pixels
+//=============================================================================
+void TbCalibration::hotPixelAnalysis(const PROFILE2D& hitMap,
+                                     const std::string& plane,
+                                     std::ostream& os) {
+
+  // Based on Hella's script for identifying hot pixels.
+  // Reject pixels which are more than 40x average
+  for (int col = 0; col < 256; col++) {
+    for (int row = 0; row < 256; row++) {
+      double count = (hitMap[col][row]).n();
+      std::vector<double> nn = hitMap.neighbours(col, row);
+
+      // Cull outliers if not at edge
+      if (nn.size() == 8) {
+        std::sort(nn.begin(), nn.end());
+        nn.erase(nn.begin(), nn.begin() + 2);
+        nn.erase(nn.end() - 2, nn.end());
+      }
+
+      double total = std::accumulate(nn.begin(), nn.end(), 0);
+
+      if (count > 10 * total) {
+        os << plane << " " << std::setw(3) << col << " " << row << std::endl;
+      }
+    }
+  }
+}
+
+void TbCalibration::syncOffset2(std::ostream& os) {
+
+  os << "Timing" << std::endl;
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    std::string title =
+        "Tb/TbTrackPlots/BiasedResiduals/Time/Plane" + std::to_string(i);
+    if (i == m_dut)
+      title = "Tb/TbDUTMonitor/ResidualsTime/Plane" + std::to_string(i);
+    AIDA::IHistogram1D* hAida = NULL;
+    StatusCode sc = GaudiAlgorithm::histoSvc()->retrieveObject(title, hAida);
+    auto hRoot = Gaudi::Utils::Aida2ROOT::aida2root(hAida);
+    os << geomSvc()->module(i)->id() << std::setw(3) << "  "
+       << -hRoot->GetMean() << std::endl;
+  }
+}
+
+//=============================================================================
+// Calculate time offsets for each column
+//=============================================================================
+void TbCalibration::columnOffsetAnalysis(const PROFILE1D& avg_difference,
+                                         const std::string& plane,
+                                         std::ostream& os) {
+  const unsigned int nDcols = 128;
+  std::vector<int> offsets(nDcols, 0);
+  double sum(0.), total(0.);
+  for (auto& d : avg_difference) {
+    sum += d.val();
+    total += d.n();
+  }
+  double avg = sum / total;
+
+  for (unsigned int dcol = 1; dcol < nDcols; ++dcol) {
+    const double difference =
+        avg_difference[dcol].avg() - avg - 25 * offsets[dcol - 1];
+    if (difference > 10.)
+      offsets[dcol] = -1;
+    else if (difference < -10.)
+      offsets[dcol] = +1;
+  }
+  // calculate the average offset
+
+  // deal with the special case where the first super column is desynchronised,
+  // in which case, everything will be shifted by 25 ns in this definition.
+  double avg_offset(0.);
+  for (const auto& d : offsets) avg_offset += d;
+  avg_offset /= 128.;
+
+  if (avg_offset > 0.5)
+    for (auto& d : offsets) d--;
+
+  else if (avg_offset < -0.5)
+    for (auto& d : offsets) d++;
+
+  for (unsigned int dcol = 0; dcol < nDcols; ++dcol) {
+    if (offsets[dcol] != 0)
+      os << plane << " " << std::setw(3) << dcol << " " << offsets[dcol]
+         << std::endl;
+  }
+}
+
+//=============================================================================
+// Fill the data for calculating the column time offsets
+//=============================================================================
+void TbCalibration::columnOffset_execute(const LHCb::TbClusters* clusters) {
+  if (!clusters || clusters->empty()) return;
+  LHCb::TbClusters::const_iterator itc;
+  for (itc = clusters->begin(); itc != clusters->end(); ++itc) {
+    const unsigned int plane = (*itc)->plane();
+    if ((*itc)->size() == 1) continue;
+    auto hits = (*itc)->hits();
+    for (auto& ih0 : hits) {
+      for (auto& ih1 : hits) {
+        const LHCb::TbHit* h0 = ih0;
+        const LHCb::TbHit* h1 = ih1;
+        const int col0 = h0->col();
+        const int col1 = h1->col();
+        if (abs(col0 - col1) != 1) continue;
+        if (h0->row() == h1->row() && h0->col() / 2 != h1->col() / 2) {
+          if (h0->col() > h1->col()) std::swap(h0, h1);
+          m_offsets[plane][(int)(h1->col() / 2)].add(h1->htime() - h0->htime());
+        }
+      }
+    }
+  }
+}
+
+//=============================================================================
+// Fill the data for checking the synchronisation.
+//=============================================================================
+void TbCalibration::sync_execute(
+    const std::vector<LHCb::TbClusters*>& clusters) {
+
+  LHCb::TbClusters* plane0_clusters = clusters[0];
+  for (auto& c : *plane0_clusters) {
+    for (unsigned int i = 1; i < m_nPlanes; ++i) {
+      double nearest = nearestHit(c, clusters[i]);
+      if (nearest != 9999) m_sync[i].add(nearest);
+    }
+  }
+}
+
+//=============================================================================
+// Get the smallest time difference of a list of clusters.
+//=============================================================================
+double TbCalibration::nearestHit(const LHCb::TbCluster* cluster,
+                                 const LHCb::TbClusters* clusters) {
+  if (!clusters || !cluster || clusters->empty()) return 9999;
+  double minTime = cluster->htime() - 50.;
+  double maxTime = cluster->htime() + 50.;
+  LHCb::TbClusters::const_iterator c = std::lower_bound(
+      clusters->begin(), clusters->end(), minTime, lowerBound());
+  double nn = 9999;
+  for (; c != clusters->end() && (*c)->htime() < maxTime; ++c) {
+    if (std::abs((*c)->htime() - cluster->htime()) < std::abs(nn))
+      nn = (*c)->htime() - cluster->htime();
+  }
+  return nn;
+}
+
+//=============================================================================
+// Fill the hit map for identifying hot pixels
+//=============================================================================
+void TbCalibration::hotPixel_execute(const LHCb::TbHits* hits) {
+  if (!hits || hits->empty()) return;
+  const unsigned int device = (*hits->begin())->device();
+  for (auto& h : *hits) m_hitMaps[device][h->col()][h->row()].add(1);
+}
+
+//=============================================================================
+// Save synchronisation info to file.
+//=============================================================================
+void TbCalibration::syncAnalysis(const double& sync, const std::string& plane,
+                                 std::ostream& os) {
+
+  os << plane << std::setw(3) << " " << sync << std::endl;
+}
diff --git a/TbAlgorithms/src/TbCalibration.h b/TbAlgorithms/src/TbCalibration.h
new file mode 100644
index 0000000..5934024
--- /dev/null
+++ b/TbAlgorithms/src/TbCalibration.h
@@ -0,0 +1,117 @@
+#pragma once
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbCalibration TbCalibration.h
+ *
+ *  Algorithm to produce timing and pixel configurations
+ *  Try to make as independent as possible from the rest of Kepler
+ *  (Relies on clustering and EventBuilder only)
+ *
+ *  @author T. Evans
+ *
+ */
+
+class TbCalibration : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbCalibration(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbCalibration() {};
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();
+
+ private:
+  // profile structure
+  struct POINT {
+    POINT() : total(0), nData(0) {};
+    double total;
+    double nData;
+    double avg() const { return nData == 0 ? 0 : total / nData; }
+    double val() const { return total; }
+    double n() const { return nData; }
+    void add(double data) {
+      total += data;
+      nData++;
+    }
+  };
+
+  struct PROFILE1D : public std::vector<POINT> {
+    PROFILE1D(unsigned int size = 0) : std::vector<POINT>(size, POINT()) {}
+  };
+
+  struct PROFILE2D : public std::vector<std::vector<POINT>> {
+    PROFILE2D(unsigned int size_x = 0, unsigned int size_y = 0)
+        : std::vector<std::vector<POINT>>(
+              size_x, std::vector<POINT>(size_y, POINT())) {};
+
+    inline POINT element(const unsigned int x, const unsigned int y) const {
+      std::vector<POINT> tmp = *(begin() + x);
+      return tmp[y];
+    }
+
+    std::vector<double> neighbours(const unsigned int x,
+                                   const unsigned int y) const {
+      std::vector<double> return_value;
+      return_value.clear();
+      unsigned int ix_begin = x > 0 ? x - 1 : 0;
+      unsigned int ix_end = x < size() - 1 ? x + 1 : size() - 1;
+      unsigned int iy_begin = y > 0 ? y - 1 : 0;
+      unsigned int iy_end = y < size() - 1 ? y + 1 : size() - 1;
+      for (unsigned int ix = ix_begin; ix <= ix_end; ++ix) {
+        for (unsigned int iy = iy_begin; iy <= iy_end; ++iy)
+          if (!(ix == x && iy == y))
+            return_value.push_back(element(ix, iy).n());
+      }
+      return return_value;
+    }
+  };
+
+  /// TES location of tracks
+  std::string m_trackLocation;
+  /// TES location of clusters
+  std::string m_clusterLocation;
+  std::string m_hitLocation;
+  std::string m_pixelSvcConfig;
+  std::string m_timingSvcConfig;
+
+  bool m_checkHotPixels;
+  bool m_checkSyncronisation;
+  bool m_checkColumnOffsets;
+  unsigned int m_syncMethod;
+  unsigned int m_dut;  /// synchronisation of the DUT is kept separate and
+                       /// doesn't affect the telescope timing
+  std::vector<PROFILE1D> m_offsets;
+  std::vector<PROFILE2D> m_hitMaps;
+  PROFILE1D m_sync;
+  // hot pixel identification, analyses the work done by execute
+  void hotPixelAnalysis(const PROFILE2D& hitMap, const std::string& plane,
+                        std::ostream& os = std::cout);
+  void hotPixel_execute(const LHCb::TbHits* hits);
+
+  void syncAnalysis(const double& sync, const std::string& plane,
+                    std::ostream& os = std::cout);
+  void sync_execute(const std::vector<LHCb::TbClusters*>& clusters);
+
+  double nearestHit(const LHCb::TbCluster* cluster,
+                    const LHCb::TbClusters* clusters);
+
+  void columnOffsetAnalysis(const PROFILE1D& avg_difference,
+                            const std::string& plane,
+                            std::ostream& os = std::cout);
+  void columnOffset_execute(const LHCb::TbClusters* clusters);
+
+  void syncOffset2(std::ostream& os = std::cout);
+  class lowerBound {
+   public:
+    bool operator()(const LHCb::TbCluster* lhs, const double t) const {
+      return lhs->htime() < t;
+    }
+  };
+};
diff --git a/TbAlgorithms/src/TbClusterAssociator.cpp b/TbAlgorithms/src/TbClusterAssociator.cpp
new file mode 100644
index 0000000..70c5be1
--- /dev/null
+++ b/TbAlgorithms/src/TbClusterAssociator.cpp
@@ -0,0 +1,114 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbClusterAssociator.h"
+
+DECLARE_ALGORITHM_FACTORY(TbClusterAssociator)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbClusterAssociator::TbClusterAssociator(const std::string& name,
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+  declareProperty("DUTs", m_duts);
+
+  declareProperty("UseHits", m_useHits = true);
+  declareProperty("ReuseClusters", m_reuseClusters = true);
+  declareProperty("TimeWindow", m_twindow = 200. * Gaudi::Units::ns);
+  declareProperty("XWindow", m_xwindow = 1. * Gaudi::Units::mm);
+  declareProperty("MaxChi2", m_maxChi2 = 100.);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbClusterAssociator::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbClusterAssociator::execute() {
+
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+  for (const auto dut : m_duts) {
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(dut);
+    const LHCb::TbClusters* clusters =
+        getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) continue;
+    // Loop over the tracks.
+    for (LHCb::TbTrack* track : *tracks) {
+      // Skip low quality tracks.
+      if (track->chi2PerNdof() > m_maxChi2) continue;
+      const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, dut);
+      const auto pLocal = geomSvc()->globalToLocal(pGlobal, dut);
+      const double tMin = track->htime() - m_twindow;
+      const double tMax = track->htime() + m_twindow;
+      for (LHCb::TbCluster* cluster : *clusters) {
+        // Assume that the clusters are sorted by time.
+        if (cluster->htime() < tMin) continue;
+        if (cluster->htime() > tMax) break;
+        // Skip used clusters (if requested).
+        if (!m_reuseClusters && cluster->associated()) continue;
+        if (m_useHits) {
+          // Compare the coordinates of the pixels to the track intercept.
+          if (!match(cluster, pLocal.x(), pLocal.y())) continue;
+        } else {
+          // Compare the cluster coordinates to the track intercept.
+          const double dx = cluster->xloc() - pLocal.x();
+          const double dy = cluster->yloc() - pLocal.y();
+          if (fabs(dx) > m_xwindow || fabs(dy) > m_xwindow) continue;
+        }
+        // Associate the cluster to the track and tag it as used.
+        track->addToAssociatedClusters(cluster);
+        cluster->setAssociated(true);
+      }
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Check if the cluster has hits within the search window.
+//=============================================================================
+bool TbClusterAssociator::match(const LHCb::TbCluster* cluster, const double x,
+                                const double y) const {
+
+  const unsigned int plane = cluster->plane();
+  // Loop over hits in the cluster.
+  for (auto hit : cluster->hits()) {
+    double xLocal = 0.;
+    double yLocal = 0.;
+    geomSvc()->pixelToPoint(hit->scol(), hit->row(), plane, xLocal, yLocal);
+    const double dx = xLocal - x;
+    const double dy = yLocal - y;
+    if (fabs(dx) < m_xwindow && fabs(dy) < m_xwindow) return true;
+  }
+  return false;
+}
diff --git a/TbAlgorithms/src/TbClusterAssociator.h b/TbAlgorithms/src/TbClusterAssociator.h
new file mode 100644
index 0000000..6068c8e
--- /dev/null
+++ b/TbAlgorithms/src/TbClusterAssociator.h
@@ -0,0 +1,39 @@
+#pragma once
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbClusterAssociator TbClusterAssociator.h
+ *
+ */
+
+class TbClusterAssociator : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbClusterAssociator(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbClusterAssociator() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<unsigned int> m_duts;
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+
+  /// Flag to use individual pixel hits or cluster coordinate for association.
+  bool m_useHits;
+  /// Flag to associate clusters to more than one track or not.
+  bool m_reuseClusters;
+  /// Time window
+  double m_twindow;
+  /// Spatial window
+  double m_xwindow;
+  /// Chi2 cut
+  double m_maxChi2;
+
+  /// Check if a cluster has hits within the tolerance window.
+  bool match(const LHCb::TbCluster* cluster, const double x,
+             const double y) const;
+};
diff --git a/TbAlgorithms/src/TbClusterPlots.cpp b/TbAlgorithms/src/TbClusterPlots.cpp
new file mode 100644
index 0000000..0854b46
--- /dev/null
+++ b/TbAlgorithms/src/TbClusterPlots.cpp
@@ -0,0 +1,601 @@
+#include <cmath>
+
+// AIDA
+// #include "AIDA/IAxis.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbClusterPlots.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbClusterPlots)
+
+//=============================================================================
+// Standard constructor.
+//=============================================================================
+TbClusterPlots::TbClusterPlots(const std::string& name,
+                               ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parToT("", 0.5, 1024.5, 1024),
+      m_parCharge("", 0., 60000., 200),
+      m_parXY("", -25., 25., 200),
+      m_parTime("", 0., 300000., 1000),
+      m_parDifferenceXY("", -2., 2., 200),
+      m_parDifferenceRot("", -0.1, 0.1, 200),
+      m_parDifferenceT("", -1000., 1000., 1000),
+      m_parSamples(0, 100000, 1),
+      m_clusterFinder(nullptr),
+      m_event(0) {
+
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("ReferencePlane", m_referencePlane = 0);
+  declareProperty("TimeWindow", m_twindow = 250. * Gaudi::Units::ns);
+
+  declareProperty("ParametersToT", m_parToT);
+  declareProperty("ParametersCharge", m_parCharge);
+  declareProperty("ParametersXY", m_parXY);
+  declareProperty("ParametersTime", m_parTime);
+  declareProperty("ParametersDifferenceXY", m_parDifferenceXY);
+  declareProperty("ParametersDifferenceRot", m_parDifferenceRot);
+  declareProperty("ParametersDifferenceT", m_parDifferenceT);
+
+  declareProperty("FillSamples", m_fillSamples = false);
+  declareProperty("FillComparisonPlots", m_fillComparisonPlots = false);
+  declareProperty("FillTrackingEfficiency", m_fillTrackingEfficiency = false);
+  declareProperty("ParametersSamples", m_parSamples);
+  declareProperty("ChargeCutLow", m_chargeCutLow = 0);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbClusterPlots::~TbClusterPlots() {}
+
+//=============================================================================
+// Initialization.
+//=============================================================================
+StatusCode TbClusterPlots::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Initialise the plots.
+  setupPlots();
+  // Setup the cluster finder.
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+  if (!m_clusterFinder) {
+    return Error("Cannot retrieve cluster finder tool.");
+  }
+  m_clusterFinder->setSearchAlgorithm("adap_seq");
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalization.
+//=============================================================================
+StatusCode TbClusterPlots::finalize() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    double num = m_nTrackedClusters_vs_telHitOccupancy->binHeight(
+        m_nTrackedClusters_vs_telHitOccupancy->coordToIndex(i));
+    double denom = m_nClusters_vs_telHitOccupancy->binHeight(
+        m_nClusters_vs_telHitOccupancy->coordToIndex(i));
+    double frac = num / denom;
+    if (denom > 0) m_fractionTrackedClusters_vs_telHitOccupancy->fill(i, frac);
+
+    num = m_nTrackedClusters_vs_telCharge->binHeight(
+        m_nTrackedClusters_vs_telCharge->coordToIndex(i));
+    denom = m_nClusters_vs_telCharge->binHeight(
+        m_nClusters_vs_telCharge->coordToIndex(i));
+    frac = num / denom;
+    if (denom > 0) m_fractionTrackedClusters_vs_telCharge->fill(i, frac);
+  }
+
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Main execution.
+//=============================================================================
+StatusCode TbClusterPlots::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Skip masked planes.
+    if (masked(i)) continue;
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) return Error("No clusters in " + clusterLocation);
+    // Fill the plots depending on just these clusters.
+    fillPerChipPlots(clusters);
+    fillClusterVisuals(clusters);
+    // Store the iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+  }
+
+  if (m_fillTrackingEfficiency) fillTrackingEfficiency();
+
+  if (m_fillComparisonPlots) fillComparisonPlots();
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Fill "event displays".
+//=============================================================================
+void TbClusterPlots::fillClusterVisuals(const LHCb::TbClusters* clusters) {
+
+  for (const LHCb::TbCluster* cluster : *clusters) {
+    if (cluster->htime() > m_parSamples.highEdge()) break;
+    if (cluster->htime() < m_parSamples.lowEdge()) continue;
+    if (cluster->associated()) continue;
+    const unsigned int plane = cluster->plane();
+    for (auto hit : cluster->hits()) {
+      double xLocal = 0.;
+      double yLocal = 0.;
+      geomSvc()->pixelToPoint(hit->scol(), hit->row(), plane, xLocal, yLocal);
+      Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      m_clusterVisuals[plane]->fill(pGlobal.x(), pGlobal.y());
+    }
+  }
+}
+
+//=============================================================================
+// Fill plots.
+//=============================================================================
+void TbClusterPlots::fillPerChipPlots(const LHCb::TbClusters* clusters) {
+
+  double tprev = 0.;
+  bool first = true;
+  for (const LHCb::TbCluster* cluster : *clusters) {
+    const unsigned int plane = cluster->plane();
+    const unsigned int tot = cluster->ToT();
+    const double charge = cluster->charge();
+    m_hToT[plane]->fill(tot);
+    m_hCharge[plane]->fill(charge);
+    const unsigned int size = cluster->size();
+    if (size == 1) {
+      m_hToTOnePixel[plane]->fill(tot);
+      m_hChargeOnePixel[plane]->fill(charge);
+    } else if (size == 2) {
+      m_hToTTwoPixel[plane]->fill(tot);
+      m_hChargeTwoPixel[plane]->fill(charge);
+    } else if (size == 3) {
+      m_hToTThreePixel[plane]->fill(tot);
+      m_hChargeThreePixel[plane]->fill(charge);
+    } else if (size == 4) {
+      m_hToTFourPixel[plane]->fill(tot);
+      m_hChargeFourPixel[plane]->fill(charge);
+    }
+    m_hSize[plane]->fill(size);
+
+    // Hitmap.
+    m_hHitMap[plane]->fill(cluster->x(), cluster->y());
+
+    counter("effFractionAssociated" + std::to_string(plane)) +=
+        cluster->associated();
+    if (cluster->charge() > 50) {
+      counter("effFractionAssociatedAbove50TOT" + std::to_string(plane)) +=
+          cluster->associated();
+    }
+    const double t = cluster->htime();
+    m_hTime[plane]->fill(t);
+    if (!first) m_hTimeBetweenClusters[plane]->fill(t - tprev);
+    first = false;
+    tprev = t;
+
+    if (cluster->associated()) {
+      m_hHitMapAssociated[plane]->fill(cluster->x(), cluster->y());
+      m_hSizeAssociated[plane]->fill(size);
+      m_hToTAssociated[plane]->fill(tot);
+      m_hChargeAssociated[plane]->fill(charge);
+      m_hTimeAssociated[plane]->fill(t);
+    } else {
+      m_hHitMapNonAssociated[plane]->fill(cluster->x(), cluster->y());
+      m_hSizeNonAssociated[plane]->fill(size);
+      m_hToTNonAssociated[plane]->fill(tot);
+      m_hChargeNonAssociated[plane]->fill(charge);
+      m_hTimeNonAssociated[plane]->fill(t);
+    }
+    m_hWidthCol[plane]->fill(cluster->cols());
+    m_hWidthRow[plane]->fill(cluster->rows());
+    m_hGlobalXvsZ->fill(cluster->z(), cluster->x());
+    m_hGlobalYvsZ->fill(cluster->z(), cluster->y());
+
+    // Loop over the hits in the cluster.
+    auto hits = cluster->hits();
+    bool firstHit = true;
+    double tSeed = 0.;
+    for (const LHCb::TbHit* hit : hits) {
+      if (firstHit) {
+        tSeed = hit->htime();
+        firstHit = false;
+      } else {
+        m_hTimeSeedMinusHit[plane]->fill(hit->htime() - tSeed);
+      }
+    }
+  }
+
+  if (m_fillSamples) fillSamples(clusters);
+}
+
+//=============================================================================
+// Comparison windows (via scrolling window).
+//=============================================================================
+void TbClusterPlots::fillComparisonPlots() {
+
+  // Make sure there are clusters on the reference plane.
+  if (m_clusterFinder->empty(m_referencePlane)) return;
+  // Scroll over clusters on the reference plane, then draw comparisons
+  // between this cluster and those inside a time window on the other planes.
+  const auto refBegin = m_clusterFinder->first(m_referencePlane);
+  const auto refEnd = m_clusterFinder->end(m_referencePlane);
+  for (auto itRef = refBegin; itRef != refEnd; ++itRef) {
+    // Calculate the time window for this cluster.
+    const auto tRef = (*itRef)->htime();
+    const auto tMin = tRef - m_twindow;
+    const auto tMax = tRef + m_twindow;
+
+    const double xRef = (*itRef)->x();
+    const double yRef = (*itRef)->y();
+
+    // Loop over other the other planes.
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      // Skip empty planes.
+      if (m_clusterFinder->empty(i)) continue;
+      // Get the first cluster within the time range.
+      const auto begin = m_clusterFinder->getIterator(tMin, i);
+      const auto end = m_clusterFinder->end(i);
+      // Loop over the clusters within the range.
+      for (auto ic = begin; ic != end; ++ic) {
+        // Stop when too far ahead.
+        if ((*ic)->htime() >= tMax) break;
+        // (Re)-check if inside the window.
+        if ((*ic)->htime() >= tMin) {
+          // Fill correlation plots.
+          m_gx_correls[i]->fill((*ic)->x(), xRef);
+          m_gy_correls[i]->fill((*ic)->y(), yRef);
+          m_gt_correls[i]->fill((*ic)->htime(), tRef);
+          // Fill difference plots.
+          m_gx_diffs[i]->fill((*ic)->x() - xRef);
+          m_gy_diffs[i]->fill((*ic)->y() - yRef);
+          m_gt_diffs[i]->fill((*ic)->htime() - tRef);
+        }
+      }
+    }
+  }
+}
+
+//=============================================================================
+// Plot a set of clusters.
+//=============================================================================
+void TbClusterPlots::fillSamples(const LHCb::TbClusters* clusters) {
+
+  // Takes a set number of clusters and plots their hits on a TH2, with
+  // the bins weighted by ToT values. Clusters are spaced equally. A dot at
+  // their reconstructed positions would be cool.
+
+  const unsigned int nSamplesRoot = 6;
+  const unsigned int nSamples = nSamplesRoot * nSamplesRoot;
+  const unsigned int sampleSpacing = 6;
+  const unsigned int n = nSamplesRoot * sampleSpacing;
+  LHCb::TbClusters::const_iterator ic = clusters->begin();
+  for (unsigned int i = 0; i < nSamples && i < clusters->size(); ++i) {
+    // Modify later to not always visualize first few clusters.
+    // Position of cluster seed on TH2.
+    // Sequentially left to right, then down to up.
+    const int c_col = (i % nSamplesRoot) * sampleSpacing;
+    const int c_row = (i / nSamplesRoot) * sampleSpacing;
+    const auto& hits = (*ic)->hits();
+    const int seed_col = hits.front()->col();
+    const int seed_row = hits.front()->row();
+    for (auto it = hits.cbegin(), end = hits.cend(); it != end; ++it) {
+      // Center the cluster on the seed hit, then shift to posn on TH2.
+      const int col = ((*it)->col() - seed_col) + c_col;
+      const int row = ((*it)->row() - seed_row) + c_row;
+      plot2D(col, row, "ClusterSamples", "Cluster samples", 0, n, 0, n, n, n,
+             (*it)->ToT());
+    }
+    ++ic;
+  }
+
+  // Switch off filling the samples plot after the first call.
+  m_fillSamples = false;
+}
+
+//=============================================================================
+
+void TbClusterPlots::fillTrackingEfficiency() {
+  std::string clusterLocation = m_clusterLocation + "0";
+  LHCb::TbClusters* clusters_zero =
+      getIfExists<LHCb::TbClusters>(clusterLocation);
+
+  // Loop over clusters on plane 0.
+  LHCb::TbClusters::const_iterator begin = clusters_zero->begin();
+  LHCb::TbClusters::const_iterator end = clusters_zero->end();
+  for (LHCb::TbClusters::const_iterator iSeed = begin; iSeed != end; ++iSeed) {
+    double timeSeed = (*iSeed)->htime();
+    double tWindow = 10;
+
+    unsigned int nClusters = 0;
+    unsigned int nTrackedClusters = 0;
+    unsigned int nTelHits = 0;
+    unsigned int nTelHits_tracked = 0;
+    double telCharge = 0;
+
+    for (unsigned int i = 1; i < m_nPlanes; ++i) {
+      if (i == 4) continue;
+      // Get the clusters for this plane.
+      clusterLocation = m_clusterLocation + std::to_string(i);
+      LHCb::TbClusters* clusters =
+          getIfExists<LHCb::TbClusters>(clusterLocation);
+
+      LHCb::TbClusters::const_iterator begin = clusters->begin();
+      LHCb::TbClusters::const_iterator end = clusters->end();
+      for (LHCb::TbClusters::const_iterator it = begin; it != end; ++it) {
+        double delT = timeSeed - (*it)->htime();
+        if (fabs(delT) < tWindow) {
+          nTelHits += (*it)->size();
+          telCharge += (*it)->charge();
+          if ((*it)->charge() > m_chargeCutLow) {
+            nClusters++;
+            if ((*it)->associated()) {
+              nTrackedClusters++;
+              nTelHits_tracked += (*it)->size();
+            }
+          }
+        }
+      }
+    }
+    //		if (nClustersPerPlane > 4 && m_event == 1050)
+    //std::cout<<nClustersPerPlane<<"\t"<<m_event<<"\t"<<(*iSeed)->htime()<<std::endl;
+    m_telHitOccupancy->fill(nTelHits);
+    m_telHitOccupancy_tracked->fill(nTelHits_tracked);
+    m_nClusters_vs_telHitOccupancy->fill(nTelHits, nClusters);
+    m_nTrackedClusters_vs_telHitOccupancy->fill(nTelHits, nTrackedClusters);
+
+    m_telCharge->fill(telCharge);
+    m_nClusters_vs_telCharge->fill(telCharge, nClusters);
+    m_nTrackedClusters_vs_telCharge->fill(telCharge, nTrackedClusters);
+
+    m_telClusterOccupancy->fill(nClusters);
+    m_telClusterOccupancy_tracked->fill(nTrackedClusters);
+    m_nClusters_vs_telClusterOccupancy->fill(nClusters, nClusters);
+    m_nTrackedClusters_vs_telClusterOccupancy->fill(nClusters,
+                                                    nTrackedClusters);
+
+    //		if (nClusters == 15 && m_event == 1050)
+    //			std::cout<<(*iSeed)->htime()<<"\t"<<nTelHits<<std::endl;
+  }
+}
+
+//=============================================================================
+// Initialization of plot objects
+//=============================================================================
+void TbClusterPlots::setupPlots() {
+  unsigned int nBins = 60;
+  m_nTrackedClusters_vs_telHitOccupancy =
+      book1D("TrackingEfficiency/nTrackedClusters_vs_telHitOccupancy",
+             "nTrackedClusters_vs_telHitOccupancy", 0, 250, nBins);
+  m_fractionTrackedClusters_vs_telHitOccupancy =
+      book1D("TrackingEfficiency/fractionTrackedClusters_telHitOccupancy",
+             "ffractionTrackedClusters_telHitOccupancy", 0, 250, nBins);
+  m_nClusters_vs_telHitOccupancy =
+      book1D("TrackingEfficiency/nClusters_vs_telHitOccupancy",
+             "nClusters_vs_telHitOccupancy", 0, 250, nBins);
+  m_telHitOccupancy = book1D("TrackingEfficiency/telHitOccupancy",
+                             "telHitOccupancy", 0, 250, nBins);
+  m_telHitOccupancy_tracked =
+      book1D("TrackingEfficiency/telHitOccupancy_tracked",
+             "telHitOccupancy_tracked", 0, 250, nBins);
+
+  m_nTrackedClusters_vs_telCharge =
+      book1D("TrackingEfficiency/nTrackedClusters_vs_telCharge",
+             "nTrackedClusters_vs_telCharge", 0, 8000, nBins);
+  m_fractionTrackedClusters_vs_telCharge =
+      book1D("TrackingEfficiency/fractionTrackedClusters_telCharge",
+             "ffractionTrackedClusters_telCharge", 0, 8000, nBins);
+  m_nClusters_vs_telCharge = book1D("TrackingEfficiency/nClusters_vs_telCharge",
+                                    "nClusters_vs_telCharge", 0, 8000, nBins);
+  m_telCharge =
+      book1D("TrackingEfficiency/telCharge", "telCharge", 0, 8000, nBins);
+
+  m_nTrackedClusters_vs_telClusterOccupancy =
+      book1D("TrackingEfficiency/nTrackedClusters_vs_telClusterOccupancy",
+             "nTrackedClusters_vs_telClusterOccupancy", 0, 60, nBins);
+  m_fractionTrackedClusters_vs_telClusterOccupancy =
+      book1D("TrackingEfficiency/fractionTrackedClusters_telClusterOccupancy",
+             "ffractionTrackedClusters_telClusterOccupancy", 0, 60, nBins);
+  m_nClusters_vs_telClusterOccupancy =
+      book1D("TrackingEfficiency/nClusters_vs_telClusterOccupancy",
+             "nClusters_vs_telClusterOccupancy", 0, 60, nBins);
+  m_telClusterOccupancy = book1D("TrackingEfficiency/telClusterOccupancy",
+                                 "telClusterOccupancy", 0, 60, nBins);
+  m_telClusterOccupancy_tracked =
+      book1D("TrackingEfficiency/telClusterOccupancy_tracked",
+             "telClusterOccupancy_tracked", 0, 60, nBins);
+
+  const double zMin = geomSvc()->modules().front()->z() - 50.;
+  const double zMax = geomSvc()->modules().back()->z() + 50.;
+  unsigned int bins = m_parXY.bins();
+  double low = m_parXY.lowEdge();
+  double high = m_parXY.highEdge();
+  m_hGlobalXvsZ =
+      book2D("GlobalXvsZ", "GlobalXvsZ", zMin, zMax, 5000, low, high, bins);
+  m_hGlobalYvsZ =
+      book2D("GlobalYvsZ", "GlobalYvsZ", zMin, zMax, 5000, low, high, bins);
+  setAxisLabels(m_hGlobalXvsZ, "global #it{z} [mm]", "global #it{x} [mm]");
+  setAxisLabels(m_hGlobalYvsZ, "global #it{z} [mm]", "global #it{y} [mm]");
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+
+    // ToT distributions
+    bins = m_parToT.bins();
+    low = m_parToT.lowEdge();
+    high = m_parToT.highEdge();
+    std::string name = "ToT/All/Plane" + plane;
+    m_hToT.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/OnePixel/Plane" + plane;
+    m_hToTOnePixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/TwoPixel/Plane" + plane;
+    m_hToTTwoPixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/ThreePixel/Plane" + plane;
+    m_hToTThreePixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/FourPixel/Plane" + plane;
+    m_hToTFourPixel.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/Associated/Plane" + plane;
+    m_hToTAssociated.push_back(book1D(name, title, low, high, bins));
+    name = "ToT/NonAssociated/Plane" + plane;
+    m_hToTNonAssociated.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hToT[i], "ToT", "entries");
+    setAxisLabels(m_hToTOnePixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTTwoPixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTThreePixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTFourPixel[i], "ToT", "entries");
+    setAxisLabels(m_hToTAssociated[i], "ToT", "entries");
+    setAxisLabels(m_hToTNonAssociated[i], "ToT", "entries");
+
+    // Charge distributions
+    bins = m_parCharge.bins();
+    low = m_parCharge.lowEdge();
+    high = m_parCharge.highEdge();
+    name = "Charge/All/Plane" + plane;
+    m_hCharge.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/OnePixel/Plane" + plane;
+    m_hChargeOnePixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/TwoPixel/Plane" + plane;
+    m_hChargeTwoPixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/ThreePixel/Plane" + plane;
+    m_hChargeThreePixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/FourPixel/Plane" + plane;
+    m_hChargeFourPixel.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/Associated/Plane" + plane;
+    m_hChargeAssociated.push_back(book1D(name, title, low, high, bins));
+    name = "Charge/NonAssociated/Plane" + plane;
+    m_hChargeNonAssociated.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hCharge[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeOnePixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeTwoPixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeThreePixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeFourPixel[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeAssociated[i], "charge [electrons]", "entries");
+    setAxisLabels(m_hChargeNonAssociated[i], "charge [electrons]", "entries");
+
+    // Cluster size distributions
+    name = "Size/Plane" + plane;
+    m_hSize.push_back(book1D(name, title, 0.5, 10.5, 10));
+    name = "SizeAssociated/Plane" + plane;
+    m_hSizeAssociated.push_back(book1D(name, title, 0.5, 10.5, 10));
+    name = "SizeNonAssociated/Plane" + plane;
+    m_hSizeNonAssociated.push_back(book1D(name, title, 0.5, 10.5, 10));
+    setAxisLabels(m_hSize[i], "cluster size", "entries");
+    setAxisLabels(m_hSizeAssociated[i], "cluster size", "entries");
+    setAxisLabels(m_hSizeNonAssociated[i], "cluster size", "entries");
+
+    // Cluster width along column and row directions
+    name = "Width/col/Plane" + plane;
+    m_hWidthCol.push_back(book1D(name, title, 0.5, 10.5, 10));
+    name = "Width/row/Plane" + plane;
+    m_hWidthRow.push_back(book1D(name, title, 0.5, 10.5, 10));
+    setAxisLabels(m_hWidthCol[i], "columns", "entries");
+    setAxisLabels(m_hWidthRow[i], "rows", "entries");
+
+    // Cluster position hit maps
+    bins = m_parXY.bins();
+    low = m_parXY.lowEdge();
+    high = m_parXY.highEdge();
+    name = "Positions/Plane" + plane;
+    m_hHitMap.push_back(book2D(name, title, low, high, bins, low, high, bins));
+    name = "PositionsAssociated/Plane" + plane;
+    m_hHitMapAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "PositionsNonAssociated/Plane" + plane;
+    m_hHitMapNonAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_hHitMap[i], "global #it{x} [mm]", "global #it{y} [mm]");
+    setAxisLabels(m_hHitMapAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+    setAxisLabels(m_hHitMapNonAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+
+    // Global x/y correlations
+    name = "Correlations/x/Plane" + plane;
+    m_gx_correls.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "Correlations/y/Plane" + plane;
+    m_gy_correls.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_gx_correls[i], "#it{x} [mm]", "#it{x}_{ref} [mm]");
+    setAxisLabels(m_gy_correls[i], "#it{y} [mm]", "#it{y}_{ref} [mm]");
+
+    // Time distributions
+    bins = m_parTime.bins();
+    low = m_parTime.lowEdge();
+    high = m_parTime.highEdge();
+    name = "Time/Plane" + plane;
+    m_hTime.push_back(book1D(name, title, low, high, bins));
+    name = "TimeAssociated/Plane" + plane;
+    m_hTimeAssociated.push_back(book1D(name, title, low, high, bins));
+    name = "TimeNonAssociated/Plane" + plane;
+    m_hTimeNonAssociated.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hTime[i], "time [ns]", "entries");
+    setAxisLabels(m_hTimeAssociated[i], "time [ns]", "entries");
+    setAxisLabels(m_hTimeNonAssociated[i], "time [ns]", "entries");
+    // Time spread of hits within a cluster.
+    name = "TimeHitMinusSeed/Plane" + plane;
+    m_hTimeSeedMinusHit.push_back(book1D(name, title, 0., 500., 200));
+    setAxisLabels(m_hTimeSeedMinusHit[i], "#it{t}_{hit} - #it{t}_{seed} [ns]",
+                  "entries");
+    // Time correlations
+    name = "Correlations/t/Plane" + plane;
+    m_gt_correls.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_gt_correls[i], "#it{t}", "#it{t}_{ref}");
+
+    // Global x/y differences
+    bins = m_parDifferenceXY.bins();
+    low = m_parDifferenceXY.lowEdge();
+    high = m_parDifferenceXY.highEdge();
+    name = "Differences/x/Plane" + plane;
+    m_gx_diffs.push_back(book1D(name, title, low, high, bins));
+    name = "Differences/y/Plane" + plane;
+    m_gy_diffs.push_back(book1D(name, title, low, high, bins));
+    bins = m_parDifferenceRot.bins();
+    low = m_parDifferenceRot.lowEdge();
+    high = m_parDifferenceRot.highEdge();
+    setAxisLabels(m_gx_diffs[i], "#it{x} - #it{x}_{ref} [mm]", "entries");
+    setAxisLabels(m_gy_diffs[i], "#it{y} - #it{y}_{ref} [mm]", "entries");
+    // Time differences
+    bins = m_parDifferenceT.bins();
+    low = m_parDifferenceT.lowEdge();
+    high = m_parDifferenceT.highEdge();
+    name = "Differences/t/Plane" + plane;
+    m_gt_diffs.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_gt_diffs[i], "#it{t} - #it{t}_{ref}", "entries");
+
+    // Time between clusters
+    name = "TimeBetweenClusters/Plane" + plane,
+    m_hTimeBetweenClusters.push_back(book1D(name, title, 0., 1000., 50));
+    setAxisLabels(m_hTimeBetweenClusters[i], "#Deltat [ns]", "entries");
+  }
+
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    std::string name = "ClusterVisuals/Sample" + std::to_string(i);
+    m_clusterVisuals.push_back(
+        book2D(name, name, 0, 14.08, 256, 0, 14.08, 256));
+  }
+}
diff --git a/TbAlgorithms/src/TbClusterPlots.h b/TbAlgorithms/src/TbClusterPlots.h
new file mode 100644
index 0000000..a1ec63d
--- /dev/null
+++ b/TbAlgorithms/src/TbClusterPlots.h
@@ -0,0 +1,140 @@
+#ifndef TB_CLUSTERPLOTS_H
+#define TB_CLUSTERPLOTS_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbClusterPlots TbClusterPlots.h
+ *
+ *  Algorithm to produce monitoring histograms for Timepix3 clusters.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbClusterPlots : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbClusterPlots(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbClusterPlots();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();
+
+ private:
+  /// TES location of clusters
+  std::string m_clusterLocation;
+  /// Index of reference plane
+  unsigned int m_referencePlane;
+  /// Time window (in ns) for correlation/difference plots
+  double m_twindow;
+
+  /// Parameters for ToT distribution histograms
+  Gaudi::Histo1DDef m_parToT;
+  /// Parameters for charge distribution histograms
+  Gaudi::Histo1DDef m_parCharge;
+  /// Parameters for x/y histograms (hitmaps and correlations)
+  Gaudi::Histo1DDef m_parXY;
+  /// Parameters for time histograms
+  Gaudi::Histo1DDef m_parTime;
+  /// Parameters for x/y difference histograms
+  Gaudi::Histo1DDef m_parDifferenceXY;
+  /// Parameters for phi difference histograms
+  Gaudi::Histo1DDef m_parDifferenceRot;
+  /// Parameters for time difference histograms
+  Gaudi::Histo1DDef m_parDifferenceT;
+  Gaudi::Histo1DDef m_parSamples;
+
+  AIDA::IHistogram1D* m_telHitOccupancy;
+  AIDA::IHistogram1D* m_telHitOccupancy_tracked;
+  AIDA::IHistogram1D* m_nClusters_vs_telHitOccupancy;
+  AIDA::IHistogram1D* m_nTrackedClusters_vs_telHitOccupancy;
+  AIDA::IHistogram1D* m_fractionTrackedClusters_vs_telHitOccupancy;
+
+  AIDA::IHistogram1D* m_telCharge;
+  AIDA::IHistogram1D* m_nClusters_vs_telCharge;
+  AIDA::IHistogram1D* m_nTrackedClusters_vs_telCharge;
+  AIDA::IHistogram1D* m_fractionTrackedClusters_vs_telCharge;
+
+  AIDA::IHistogram1D* m_telClusterOccupancy;
+  AIDA::IHistogram1D* m_telClusterOccupancy_tracked;
+  AIDA::IHistogram1D* m_nClusters_vs_telClusterOccupancy;
+  AIDA::IHistogram1D* m_nTrackedClusters_vs_telClusterOccupancy;
+  AIDA::IHistogram1D* m_fractionTrackedClusters_vs_telClusterOccupancy;
+
+  bool m_fillSamples;
+  bool m_fillComparisonPlots;     // Much faster to turn off.
+  bool m_fillTrackingEfficiency;  /// slow and pattern recognition-y
+  /// Cluster finder helper class
+  ITbClusterFinder* m_clusterFinder;
+  unsigned int m_event;
+  double m_chargeCutLow;
+
+  // Histograms
+  // ToT distribution
+  std::vector<AIDA::IHistogram1D*> m_hToT;
+  std::vector<AIDA::IHistogram1D*> m_hToTOnePixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTTwoPixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTThreePixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTFourPixel;
+  std::vector<AIDA::IHistogram1D*> m_hToTAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hToTNonAssociated;
+  // Charge distribution
+  std::vector<AIDA::IHistogram1D*> m_hCharge;
+  std::vector<AIDA::IHistogram1D*> m_hChargeOnePixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeTwoPixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeThreePixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeFourPixel;
+  std::vector<AIDA::IHistogram1D*> m_hChargeAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hChargeNonAssociated;
+  // Cluster size
+  std::vector<AIDA::IHistogram1D*> m_hSize;
+  std::vector<AIDA::IHistogram1D*> m_hSizeAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hSizeNonAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hWidthCol;
+  std::vector<AIDA::IHistogram1D*> m_hWidthRow;
+  // Cluster time
+  std::vector<AIDA::IHistogram1D*> m_hTime;
+  std::vector<AIDA::IHistogram1D*> m_hTimeAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hTimeNonAssociated;
+  std::vector<AIDA::IHistogram1D*> m_hTimeBetweenClusters;
+  // Time spread of pixel hits in a cluster
+  std::vector<AIDA::IHistogram1D*> m_hTimeSeedMinusHit;
+
+  // Hitmaps
+  std::vector<AIDA::IHistogram2D*> m_hHitMap;
+  std::vector<AIDA::IHistogram2D*> m_hHitMapAssociated;
+  std::vector<AIDA::IHistogram2D*> m_hHitMapNonAssociated;
+
+  AIDA::IHistogram2D* m_hGlobalXvsZ;
+  AIDA::IHistogram2D* m_hGlobalYvsZ;
+
+  // Global correlations.
+  std::vector<AIDA::IHistogram2D*> m_gx_correls;
+  std::vector<AIDA::IHistogram2D*> m_gy_correls;
+  std::vector<AIDA::IHistogram2D*> m_gt_correls;
+
+  // Global differences.
+  std::vector<AIDA::IHistogram1D*> m_gx_diffs;
+  std::vector<AIDA::IHistogram1D*> m_gy_diffs;
+  std::vector<AIDA::IHistogram1D*> m_gt_diffs;
+
+  std::vector<AIDA::IHistogram2D*> m_clusterVisuals;
+
+  void setupPlots();
+  void fillPerChipPlots(const LHCb::TbClusters* clusters);
+  void fillComparisonPlots();
+  void fillSamples(const LHCb::TbClusters* clusters);
+  void fillClusterVisuals(const LHCb::TbClusters* clusters);
+  void fillTrackingEfficiency();
+};
+#endif
diff --git a/TbAlgorithms/src/TbClustering.cpp b/TbAlgorithms/src/TbClustering.cpp
new file mode 100755
index 0000000..5b235a1
--- /dev/null
+++ b/TbAlgorithms/src/TbClustering.cpp
@@ -0,0 +1,373 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+#include "TbKernel/TbCondFile.h"
+
+// Local
+#include "TbClustering.h"
+
+DECLARE_ALGORITHM_FACTORY(TbClustering)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbClustering::TbClustering(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TimeWindow", m_twindow = 100. * Gaudi::Units::ns);
+  declareProperty("SearchDist", m_searchDist = 1);
+  declareProperty("ClusterErrorMethod", m_clusterErrorMethod = 0);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbClustering::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  m_eta.resize(m_nPlanes);
+  for (const auto& filename : dataSvc()->getEtaConfig()) {
+    info() << "Importing eta corrections from " << filename << endmsg; 
+    readEta(filename);
+  }
+  
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbClustering::execute() {
+
+  // Get the hits to be clustered - loop over planes.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string ext = std::to_string(i);
+    const std::string hitLocation = m_hitLocation + ext;
+    const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(hitLocation);
+    if (!hits) return Error("No hits in " + hitLocation);
+    // Create a cluster container and transfer its ownership to the TES.
+    LHCb::TbClusters* clusters = new LHCb::TbClusters();
+    put(clusters, m_clusterLocation + ext);
+    // Skip masked planes.
+    if (masked(i)) continue;
+    // Keep track of which hits have been clustered.
+    std::vector<bool> used(hits->size(), false);
+    std::vector<const LHCb::TbHit*> pixels;
+    pixels.reserve(100);
+    // Cycle over the (time ordered) hits.
+    for (LHCb::TbHits::const_iterator it = hits->begin(); it != hits->end();
+         ++it) {
+      // Skip hits which are already part of a cluster.
+      if (used[(*it)->key()]) continue;
+      // Start a cluster from this seed pixel and tag the seed as used.
+      used[(*it)->key()] = true;
+      pixels.clear();
+      pixels.push_back(*it);
+      // Get the search range.
+      const double tMax = (*it)->htime() + m_twindow;
+      LHCb::TbHits::const_iterator end = std::upper_bound(
+          it, hits->end(), tMax, lowerBound<const LHCb::TbHit*>());
+      // Add neighbouring hits in the cluster time window.
+      addNeighbouringHits(pixels, it, end, used);
+      // Sort the hits by time.
+      std::sort(pixels.begin(), pixels.end(),
+                TbFunctors::LessByTime<const LHCb::TbHit*>());
+      // Finally, set the remaining cluster attributes according to its hits.
+      completeCluster(i, pixels, clusters);
+    }
+    // Sort the clusters by time.
+    std::sort(clusters->begin(), clusters->end(),
+              TbFunctors::LessByTime<LHCb::TbCluster*>());
+    // Fill the counter.
+    counter("NumberOfClusters" + ext) += clusters->size();
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finding touching hits
+//=============================================================================
+void TbClustering::addNeighbouringHits(std::vector<const LHCb::TbHit*>& pixels,
+                                       LHCb::TbHits::const_iterator begin,
+                                       LHCb::TbHits::const_iterator end,
+                                       std::vector<bool>& used) {
+
+  // Keep track of the cluster's bounding box.
+  int scolmin = pixels.front()->scol();
+  int scolmax = scolmin;
+  int rowmin = pixels.front()->row();
+  int rowmax = rowmin;
+  // Try adding hits to the cluster.
+  bool hitAdded = true;
+  while (hitAdded) {
+    hitAdded = false;
+    unsigned int nUnused = 0;
+    for (LHCb::TbHits::const_iterator it = begin; it != end; ++it) {
+      // Skip hits which are already part of a cluster.
+      if (used[(*it)->key()]) continue;
+      ++nUnused;
+      const int scol = (*it)->scol();
+      const int row = (*it)->row();
+      if (scol < scolmin - m_searchDist) continue;
+      if (scol > scolmax + m_searchDist) continue;
+      if (row < rowmin - m_searchDist) continue;
+      if (row > rowmax + m_searchDist) continue;
+      // Ask if the hit is touching the cluster (with its current set of hits).
+      if (hitTouchesCluster((*it)->scol(), (*it)->row(), pixels)) {
+        // Add the hit to the cluster.
+        pixels.push_back(*it);
+        used[(*it)->key()] = true;
+        --nUnused;
+        hitAdded = true;
+        // Update the bounding box.
+        if (scol < scolmin)
+          scolmin = scol;
+        else if (scol > scolmax)
+          scolmax = scol;
+        if (row < rowmin)
+          rowmin = row;
+        else if (row > rowmax)
+          rowmax = row;
+      }
+    }
+    if (nUnused == 0) break;
+  }
+}
+
+//=============================================================================
+// Complete remaining cluster attributes
+//=============================================================================
+void TbClustering::completeCluster(
+    const unsigned int plane, const std::vector<const LHCb::TbHit*>& pixels,
+    LHCb::TbClusters* clusters) {
+
+  // Create a new cluster object.
+  LHCb::TbCluster* cluster = new LHCb::TbCluster();
+  cluster->setPlane(plane);
+  // Set cluster width along the column and row direction.
+  auto cols = std::minmax_element(pixels.cbegin(), pixels.cend(),
+                        [](const LHCb::TbHit* h1, const LHCb::TbHit* h2) {
+    return h1->scol() < h2->scol();
+  });
+  auto rows = std::minmax_element(pixels.cbegin(), pixels.cend(),
+                        [](const LHCb::TbHit* h1, const LHCb::TbHit* h2) {
+    return h1->row() < h2->row(); 
+  });
+  const unsigned int nCols =
+    1 + (*cols.second)->scol() - (*cols.first)->scol();
+  const unsigned int nRows = 1 + (*rows.second)->row() - (*rows.first)->row();
+  cluster->setCols(nCols);
+  cluster->setRows(nRows);
+  // Add the pixel hits to the cluster, sum up the charge and
+  // calculate the centre of gravity.
+  unsigned int tot = 0;
+  double charge = 0.;
+  double xLocal = 0.;
+  double yLocal = 0.;
+  for (auto it = pixels.cbegin(), end = pixels.cend(); it != end; ++it) {
+    cluster->addToHits(*it);
+    tot += (*it)->ToT();
+    const double q = (*it)->charge();
+    charge += q;
+    double x = 0.;
+    double y = 0.;
+    geomSvc()->pixelToPoint((*it)->scol(), (*it)->row(), plane, x, y);
+    xLocal += x * q;
+    yLocal += y * q;
+  }
+  cluster->setToT(tot);
+  cluster->setCharge(charge);
+  // Assume that the cluster time is the time of the earliest hit.
+  cluster->setTime(pixels.front()->time());
+  cluster->setHtime(pixels.front()->htime());
+  // Calculate the local and global coordinates.
+  xLocal /= charge;
+  yLocal /= charge;
+  // Apply eta-corrections.
+  etaCorrection(xLocal, yLocal, nCols, nRows, plane);
+  
+  cluster->setXloc(xLocal);
+  cluster->setYloc(yLocal);
+  const Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+  const auto pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+  cluster->setX(pGlobal.x());
+  cluster->setY(pGlobal.y());
+  cluster->setZ(pGlobal.z());
+  // Assign error estimates.
+  setClusterError(cluster);
+  // Add the cluster to the container.
+  clusters->insert(cluster);
+}
+
+//=============================================================================
+// Calculate the cluster error estimate.
+//=============================================================================
+void TbClustering::setClusterError(LHCb::TbCluster* cluster) const {
+
+  // Initialise the errors to some default value (for large cluster widths).
+  double dx = 0.1;
+  double dy = 0.1;
+  switch (m_clusterErrorMethod) {
+    case 0: {
+      constexpr std::array<double, 5> sigmas = {0.0027, 0.0035, 0.016, 0.045, 0.065};
+      if (cluster->cols() < 6) dx = sigmas[cluster->cols() - 1];
+      if (cluster->rows() < 6) dy = sigmas[cluster->rows() - 1];
+      break;
+    } 
+    case 2:
+      if (cluster->size() <= 6) {
+        dx = dy = 0.004;
+      } else {
+        // HS: not sure this makes sense
+        const double sigmaHit = (1. / sqrt(12.)) * Tb::PixelPitch;
+        dx = sigmaHit * cluster->cols();
+        dy = sigmaHit * cluster->rows();
+      }
+      break;
+    default:
+      dx = dy = 0.004;
+      break;
+  }
+  cluster->setXErr(dx);
+  cluster->setYErr(dy);
+  cluster->setWx(1. / (dx * dx));
+  cluster->setWy(1. / (dy * dy));
+}
+
+
+//=============================================================================
+// Read the eta correction parameters from file.
+//=============================================================================
+void TbClustering::readEta(const std::string& filename) {
+
+  TbCondFile f(filename);
+  if (!f.is_open()) {
+    warning() << "Cannot open " << filename << endmsg;
+    return;
+  }
+  unsigned int indexPlane = 999;
+  unsigned int indexXy = 0;
+  unsigned int indexCol = 0;
+  unsigned int nLines = 0;
+  while (!f.eof()) {
+    std::string line = "";
+    ++nLines;
+    if (!f.getLine(line)) continue;
+    if (line.find("Plane") != std::string::npos) {
+      indexPlane = 999;
+      std::string key = "";
+      std::string id = "";
+      std::string xy = "";
+      int cols = 0;
+      if (!f.split(line, ' ', key, id, xy, cols)) {
+        warning() << "Error reading line " << nLines << endmsg;
+        continue;
+      }
+      // Find the index corresponding to the given plane name. 
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        if (id == geomSvc()->modules()[i]->id()) {
+          indexPlane = i;
+          break;
+        }
+      } 
+      if (indexPlane == 999) {
+        warning() << "Module " << id 
+                  << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      // Check whether this set of parameters is for the x or the y direction.
+      if (xy == "x" || xy == "X") {
+        indexXy = 0;
+      } else if (xy == "y" || xy == "Y") {
+        indexXy = 1;
+      } else {
+        warning() << "Unexpected direction specifier " << xy 
+                  << " (expected x or y). Skip this parameter set." << endmsg;
+        indexPlane = 999;
+        continue;
+      }
+      // Check the cluster width.
+      if (cols < 2) {
+        warning() << "Unexpected cluster width (" << cols
+                  << "). Skip this parameter set." << endmsg;
+        indexPlane = 999;
+        continue; 
+      }
+      indexCol = cols - 2;
+      if (m_eta[indexPlane][indexXy].size() < indexCol + 1) {
+        m_eta[indexPlane][indexXy].resize(indexCol + 1);
+      }
+      const std::string rowcol = indexXy == 0 ? " columns." : " rows.";
+      info() << "Reading eta-correction parameters for plane " << indexPlane
+             << " for clusters covering " << cols << rowcol << endmsg;
+      m_eta[indexPlane][indexXy][indexCol].clear();
+    } else {
+      if (indexPlane == 999) continue;
+      // Read the intra-pixel interval and the coefficients of the polynomial.
+      double xmin = 0., xmax = 0.;
+      double a = 0., b = 0., c = 0.;
+      if (!f.split(line, ' ', xmin, xmax, a, b, c)) {
+        warning() << "Error reading line " << nLines << endmsg;
+        continue;
+      }
+      EtaCorrection corr;
+      corr.xmin = xmin;
+      corr.xmax = xmax;
+      corr.coefficients = {a, b, c};
+      m_eta[indexPlane][indexXy][indexCol].push_back(corr);
+    }
+  }
+
+}
+
+//=============================================================================
+// Calculate the eta correction terms.
+//=============================================================================
+void TbClustering::etaCorrection(double& xLocal, double& yLocal,
+                                 const unsigned int nCols, 
+                                 const unsigned int nRows, 
+                                 const unsigned int plane) const { 
+
+  // No point to continue in case of single-pixel clusters.
+  if (nCols * nRows == 1) return;
+  // Calculate the intra-pixel coordinates of the cluster.
+  unsigned int scol = 0, row = 0;
+  geomSvc()->pointToPixel(xLocal, yLocal, plane, scol, row);
+  double x0 = 0., y0 = 0.;
+  geomSvc()->pixelToPoint(scol, row, plane, x0, y0);
+  // TODO: this only works for single-chip assemblies.
+  const double x = xLocal - x0 + 0.5 * Tb::PixelPitch;
+  const double y = yLocal - y0 + 0.5 * Tb::PixelPitch;
+  // Calculate the correction terms.
+  if (nCols > 1 && m_eta[plane][0].size() > nCols - 2) {
+    const auto& corrections = m_eta[plane][0][nCols - 2];
+    for (const auto& corr : corrections) {
+      if (x >= corr.xmin && x < corr.xmax) {
+        xLocal += corr.coefficients[0] + corr.coefficients[1] * x + 
+                  corr.coefficients[2] * x * x;
+        break;
+      }
+    }
+  } 
+  if (nRows > 1 && m_eta[plane][1].size() > nRows - 2) {
+    const auto& corrections = m_eta[plane][1][nRows - 2];
+    for (const auto& corr : corrections) {
+      if (y >= corr.xmin && y < corr.xmax) {
+        yLocal += corr.coefficients[0] + corr.coefficients[1] * y + 
+                  corr.coefficients[2] * y * y;
+        break;
+      }
+    }
+  } 
+}
diff --git a/TbAlgorithms/src/TbClustering.h b/TbAlgorithms/src/TbClustering.h
new file mode 100755
index 0000000..583de7f
--- /dev/null
+++ b/TbAlgorithms/src/TbClustering.h
@@ -0,0 +1,80 @@
+#ifndef TB_CLUSTERING_H
+#define TB_CLUSTERING_H 1
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbClustering TbClustering.h
+ *
+ *  Algorithm to group together touching Timepix3 pixel hits.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbClustering : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbClustering(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbClustering() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location prefix of hits
+  std::string m_hitLocation;
+  /// TES location prefix of clusters
+  std::string m_clusterLocation;
+  /// Time window (in ns)
+  double m_twindow;
+  /// Max. distance between two pixels to be grouped together
+  int m_searchDist;
+  /// Cluster error calculation (0 for constant, 1 for COG error propagation
+  int m_clusterErrorMethod;
+  /// Eta-correction parameterisation.
+  struct EtaCorrection {
+    double xmin, xmax;
+    std::vector<double> coefficients;
+  };
+  /// Set of eta-correction parameters per plane, direction, and cluster width.
+  std::vector<std::array<std::vector<std::vector<EtaCorrection> >, 2> > m_eta;
+
+  /// Add pixels to a given seed pixel.
+  void addNeighbouringHits(std::vector<const LHCb::TbHit*>& pixels,
+                           LHCb::TbHits::const_iterator begin,
+                           LHCb::TbHits::const_iterator end,
+                           std::vector<bool>& used);
+  /// Check if a hit touches any of the pixels in a given cluster.
+  bool hitTouchesCluster(const int scol, const int row,
+                         const std::vector<const LHCb::TbHit*>& pixels) const {
+
+    bool result = false;
+    for (auto it = pixels.cbegin(), end = pixels.cend(); it != end; ++it) {
+      if ((abs(int((*it)->scol()) - scol) <= m_searchDist) &&
+          (abs(int((*it)->row()) - row) <= m_searchDist)) {
+        result = true;
+        break;
+      }
+    }
+    return result;
+  }
+
+  /// Set cluster attributes (position, time, ADC).
+  void completeCluster(const unsigned int plane,
+                       const std::vector<const LHCb::TbHit*>& pixels,
+                       LHCb::TbClusters* clusters);
+  /// Calculate the cluster errors.
+  void setClusterError(LHCb::TbCluster* cluster) const;
+  /// Calculate the eta-correction.
+  void etaCorrection(double& xLocal, double& yLocal,
+                     const unsigned int nCols, const unsigned int nRows,
+                     const unsigned int plane) const;
+  void readEta(const std::string& filename);
+
+};
+#endif
diff --git a/TbAlgorithms/src/TbDUTMonitor.cpp b/TbAlgorithms/src/TbDUTMonitor.cpp
new file mode 100644
index 0000000..6d4efe5
--- /dev/null
+++ b/TbAlgorithms/src/TbDUTMonitor.cpp
@@ -0,0 +1,292 @@
+// AIDA
+#include "AIDA/IAxis.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbDUTMonitor.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbDUTMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbDUTMonitor::TbDUTMonitor(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parResXY("", -0.2, 0.2, 200),
+      m_parXY("", -20, 20, 500),
+      m_parScanX("", 0, 0, 1),
+      m_parScanY("", 0, 0, 1),
+      m_parResTime("", -100., 100., 2000) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("DUTs", m_duts);
+
+  declareProperty("ScanX", m_parScanX);
+  declareProperty("ScanY", m_parScanY);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbDUTMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Setup the histograms.
+  const unsigned int nDuts = m_duts.size();
+  for (unsigned int i = 0; i < nDuts; ++i) {
+    m_index[m_duts[i]] = i;
+    const std::string plane = std::to_string(m_duts[i]);
+    const std::string title = geomSvc()->modules().at(m_duts[i])->id();
+
+    unsigned int bins = m_parResXY.bins();
+    double low = m_parResXY.lowEdge();
+    double high = m_parResXY.highEdge();
+    std::string name = "ResidualsLocalX/Plane" + plane;
+    m_hResLocalX.push_back(book1D(name, title, low, high, bins));
+    name = "ResidualsLocalY/Plane" + plane;
+    m_hResLocalY.push_back(book1D(name, title, low, high, bins));
+    name = "ResidualsGlobalX/Plane" + plane;
+    m_hResGlobalX.push_back(book1D(name, title, low, high, bins));
+    name = "ResidualsGlobalY/Plane" + plane;
+    m_hResGlobalY.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hResLocalX[i], "#it{x} - #it{x}_{track} [mm]", "entries");
+    setAxisLabels(m_hResLocalY[i], "#it{y} - #it{y}_{track} [mm]", "entries");
+
+    unsigned int binsXY = m_parXY.bins();
+    double lowXY = m_parXY.lowEdge();
+    double highXY = m_parXY.highEdge();
+
+    m_hUnbiasedResGlobalXvsGlobalX.push_back(
+        book2D("GlobalResXvsGlobalX/Plane" + plane, title, lowXY, highXY,
+               binsXY, low, high, bins));
+
+    m_hUnbiasedResGlobalYvsGlobalY.push_back(
+        book2D("GlobalResYvsGlobalY/Plane" + plane, title, lowXY, highXY,
+               binsXY, low, high, bins));
+
+    m_hUnbiasedResGlobalXvsTrackChi2.push_back(
+        book2D("GlobalResXvsTrackChi2/Plane" + plane, title, 0, 100, 1000, low,
+               high, bins));
+    m_hUnbiasedResGlobalYvsTrackChi2.push_back(
+        book2D("GlobalResYvsTrackChi2/Plane" + plane, title, 0, 100, 1000, low,
+               high, bins));
+
+    m_hUnbiasedResGlobalXvsTrackTx.push_back(
+        book2D("GlobalResXvsTrackTx/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+    m_hUnbiasedResGlobalXvsTrackTy.push_back(
+        book2D("GlobalResXvsTrackTy/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+    m_hUnbiasedResGlobalYvsTrackTx.push_back(
+        book2D("GlobalResYvsTrackTx/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+    m_hUnbiasedResGlobalYvsTrackTy.push_back(
+        book2D("GlobalResYvsTrackTy/Plane" + plane, title, -0.002, 0.002, 100,
+               low, high, bins));
+
+    m_hUnbiasedResGlobalXvsPixelX.push_back(
+        book2D("UnbiasedResGlobalXvsPixelX/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalXvsPixelY.push_back(
+        book2D("UnbiasedResGlobalXvsPixelY/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalYvsPixelX.push_back(
+        book2D("UnbiasedResGlobalYvsPixelX/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalYvsPixelY.push_back(
+        book2D("UnbiasedResGlobalYvsPixelY/Plane" + plane, title, -1.0, 1.0,
+               200, low, high, bins));
+
+    m_hUnbiasedResGlobalXvsClusterSize.push_back(
+        book2D("GlobalResXvsClusterSize/Plane" + plane, title, 0.5, 10.5, 10,
+               low, high, bins));
+    m_hUnbiasedResGlobalYvsClusterSize.push_back(
+        book2D("GlobalResYvsClusterSize/Plane" + plane, title, 0.5, 10.5, 10,
+               low, high, bins));
+
+    //   m_UnbiasedResGlobalXvshUnbiasedResGlobalY
+    m_UnbiasedResGlobalXvshUnbiasedResGlobalY.push_back(
+        book2D("UnbiasedResGlobalXvshUnbiasedResGlobalY/Plane" + plane, title,
+               low, high, bins, low, high, bins));
+
+    bins = m_parResTime.bins();
+    low = m_parResTime.lowEdge();
+    high = m_parResTime.highEdge();
+    name = "ResidualsTime/Plane" + plane;
+    m_hResTime.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hResTime[i], "#it{t} - #it{t}_{track} [ns]", "entries");
+  }
+  std::vector<std::string> labels = {"X", "Y", "Z", "rotX", "rotY", "rotZ"};
+  unsigned int binsXY = m_parXY.bins();
+  double lowXY = m_parXY.lowEdge();
+  double highXY = m_parXY.highEdge();
+  unsigned int bins = m_parResXY.bins();
+  double low = m_parResXY.lowEdge();
+  double high = m_parResXY.highEdge();
+
+  if (nDuts == 0) return sc;
+  TbModule* mod = geomSvc()->module(m_duts[0]);
+  std::vector<bool> xaxis(6, 0);
+  std::vector<bool> yaxis(6, 0);
+  std::vector<std::string>::iterator xL =
+      std::find(labels.begin(), labels.end(), m_parScanX.title());
+  std::vector<std::string>::iterator yL =
+      std::find(labels.begin(), labels.end(), m_parScanY.title());
+  if (xL != labels.end()) xaxis[xL - labels.begin()] = 1;
+  if (yL != labels.end()) yaxis[yL - labels.begin()] = 1;
+
+  if (xL != labels.end()) {
+    for (int i = 0; i < m_parScanX.bins(); ++i) {
+      const double px = m_parScanX.lowEdge() +
+                        i * (m_parScanX.highEdge() - m_parScanX.lowEdge()) /
+                            m_parScanX.bins();
+      std::string label =
+          "Scan #Delta" + m_parScanX.title() + " = " + std::to_string(px);
+      if (yL == labels.end()) {
+        info() << "Booking scan " << *xL << " = " << px << endmsg;
+        m_hScanXvsX.push_back(book2D("XvsX/Scan" + std::to_string(i), label,
+                                     lowXY, highXY, binsXY, low, high, bins));
+        m_hScanYvsY.push_back(book2D("YvsY/Scan" + std::to_string(i), label,
+                                     lowXY, highXY, binsXY, low, high, bins));
+        m_testModules.push_back(new TbModule());
+        (*m_testModules.rbegin())->setAlignment(
+            mod->x() + px * xaxis[0], mod->y() + px * xaxis[1],
+            mod->z() + px * xaxis[2], mod->rotX() + px * xaxis[3],
+            mod->rotY() + px * xaxis[4], mod->rotZ() + px * xaxis[5], 0, 0, 0,
+            0, 0, 0);
+      } else {
+        for (int j = 0; j < m_parScanY.bins(); ++j) {
+
+          const double py = m_parScanY.lowEdge() +
+                            j * (m_parScanY.highEdge() - m_parScanY.lowEdge()) /
+                                m_parScanY.bins();
+
+          info() << "Booking scan " << *xL << " = " << px << ", " << *yL
+                 << " = " << py << endmsg;
+
+          std::string l =
+              label + ", " + m_parScanY.title() + " = " + std::to_string(py);
+          m_hScanXvsX.push_back(
+              book2D("XvsX/Scan" + std::to_string(i * m_parScanY.bins() + j), l,
+                     lowXY, highXY, binsXY, low, high, bins));
+          m_hScanYvsY.push_back(
+              book2D("YvsY/Scan" + std::to_string(i * m_parScanY.bins() + j), l,
+                     lowXY, highXY, binsXY, low, high, bins));
+          m_testModules.push_back(new TbModule());
+
+          (*m_testModules.rbegin())->setAlignment(
+              mod->x() + px * xaxis[0] + py * yaxis[0],
+              mod->y() + px * xaxis[1] + py * yaxis[1],
+              mod->z() + px * xaxis[2] + py * yaxis[2],
+              mod->rotX() + px * xaxis[3] + py * yaxis[3],
+              mod->rotY() + px * xaxis[4] + py * yaxis[4],
+              mod->rotZ() + px * xaxis[5] + py * yaxis[5], 0, 0, 0, 0, 0, 0);
+        }
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbDUTMonitor::execute() {
+
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+  // Loop over the tracks.
+  for (const LHCb::TbTrack* track : *tracks) {
+    auto clusters = track->associatedClusters();
+    for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+      const unsigned int plane = (*it)->plane();
+      if (m_index.count(plane) < 1) continue;
+      const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, plane);
+      const auto pLocal = geomSvc()->globalToLocal(pGlobal, plane);
+      const unsigned int i = m_index[plane];
+      const double dt = (*it)->htime() - track->htime();
+      const double dx = (*it)->xloc() - pLocal.x();
+      const double dy = (*it)->yloc() - pLocal.y();
+      m_hResLocalX[i]->fill(dx);
+      m_hResLocalY[i]->fill(dy);
+
+      const double dxug = (*it)->x() - pGlobal.x();
+      const double dyug = (*it)->y() - pGlobal.y();
+      m_hResGlobalX[i]->fill(dxug);
+      m_hResGlobalY[i]->fill(dyug);
+      m_hUnbiasedResGlobalXvsGlobalX[i]->fill((*it)->x(), dxug);
+      m_hUnbiasedResGlobalYvsGlobalY[i]->fill((*it)->y(), dyug);
+      m_hResTime[i]->fill(dt);
+
+      m_hUnbiasedResGlobalXvsTrackChi2[i]->fill(track->chi2PerNdof(), dxug);
+      m_hUnbiasedResGlobalYvsTrackChi2[i]->fill(track->chi2PerNdof(), dyug);
+
+      m_UnbiasedResGlobalXvshUnbiasedResGlobalY[i]->fill(dxug, dyug);
+
+      m_hUnbiasedResGlobalXvsTrackTx[i]->fill(track->firstState().tx(), dxug);
+      m_hUnbiasedResGlobalXvsTrackTy[i]->fill(track->firstState().ty(), dxug);
+
+      m_hUnbiasedResGlobalYvsTrackTx[i]->fill(track->firstState().tx(), dyug);
+      m_hUnbiasedResGlobalYvsTrackTy[i]->fill(track->firstState().ty(), dyug);
+
+      m_hUnbiasedResGlobalXvsClusterSize[i]->fill((*it)->hits().size(), dxug);
+      m_hUnbiasedResGlobalYvsClusterSize[i]->fill((*it)->hits().size(), dyug);
+
+      unsigned int row, col;
+
+      geomSvc()->pointToPixel(pLocal.x(), pLocal.y(), 4, col, row);
+      double x0, y0;
+      geomSvc()->pixelToPoint(col, row, 4, x0, y0);
+
+      const double pixelX = (pLocal.x() - x0) / 0.055;
+      const double pixelY = (pLocal.y() - y0) / 0.055;
+
+      m_hUnbiasedResGlobalXvsPixelX[i]->fill(pixelX, dxug);
+      m_hUnbiasedResGlobalXvsPixelY[i]->fill(pixelY, dxug);
+      m_hUnbiasedResGlobalYvsPixelX[i]->fill(pixelX, dyug);
+      m_hUnbiasedResGlobalYvsPixelY[i]->fill(pixelY, dyug);
+
+      for (int j = 0; j < m_testModules.size(); ++j) {
+
+        const auto& p = track->firstState().position();
+        const auto& t = track->firstState().slopes();
+        const Gaudi::XYZVector n = m_testModules[j]->normal();
+        const double s = n.Dot(m_testModules[j]->centre() - p) / n.Dot(t);
+        const auto intercept = p + s * t;
+        const auto cl = m_testModules[j]->transform() *
+                        Gaudi::XYZPoint((*it)->xloc(), (*it)->yloc(), 0);
+        const double dxug = cl.x() - intercept.x();
+        const double dyug = cl.y() - intercept.y();
+        m_hScanXvsX[j]->fill(cl.x(), dxug);
+        m_hScanYvsY[j]->fill(cl.y(), dyug);
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/TbDUTMonitor.h b/TbAlgorithms/src/TbDUTMonitor.h
new file mode 100644
index 0000000..7b2e7d7
--- /dev/null
+++ b/TbAlgorithms/src/TbDUTMonitor.h
@@ -0,0 +1,67 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbDUTMonitor TbDUTMonitor.h
+ *
+ */
+
+class TbDUTMonitor : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbDUTMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbDUTMonitor() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<unsigned int> m_duts;
+  std::map<unsigned int, unsigned int> m_index;
+
+  std::string m_trackLocation;
+
+  /// Parameters for x/y residual histograms
+  Gaudi::Histo1DDef m_parResXY;
+  Gaudi::Histo1DDef m_parXY;
+  Gaudi::Histo1DDef m_parScanX;
+  Gaudi::Histo1DDef m_parScanY;
+
+  /// Parameters for time residual histograms
+  Gaudi::Histo1DDef m_parResTime;
+
+  std::vector<AIDA::IHistogram1D*> m_hResLocalX;
+  std::vector<AIDA::IHistogram1D*> m_hResLocalY;
+  std::vector<AIDA::IHistogram1D*> m_hResGlobalX;
+  std::vector<AIDA::IHistogram1D*> m_hResGlobalY;
+  std::vector<AIDA::IHistogram1D*> m_hResTime;
+
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsGlobalX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsGlobalY;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsTrackChi2;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsTrackChi2;
+
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsPixelX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsPixelY;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsPixelX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsPixelY;
+
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsTrackTx;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsTrackTy;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsTrackTx;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsTrackTy;
+  std::vector<AIDA::IHistogram2D*> m_UnbiasedResGlobalXvshUnbiasedResGlobalY;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalXvsClusterSize;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGlobalYvsClusterSize;
+
+  std::vector<AIDA::IHistogram2D*> m_hScanXvsX;
+  std::vector<AIDA::IHistogram2D*> m_hScanYvsY;
+
+  std::vector<TbModule*> m_testModules;
+};
diff --git a/TbAlgorithms/src/TbHitMonitor.cpp b/TbAlgorithms/src/TbHitMonitor.cpp
new file mode 100644
index 0000000..a27bfa5
--- /dev/null
+++ b/TbAlgorithms/src/TbHitMonitor.cpp
@@ -0,0 +1,137 @@
+// Gaudi
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbHitMonitor.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbHitMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbHitMonitor::TbHitMonitor(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parToT("", 0.5, 1024.5, 1024),
+      m_parCharge("", 0., 20000., 200),
+      m_parHitsInEvent("", 0., 10000., 100),
+      m_parDeltaT("", 0., 100., 200),
+      m_nEvents(0) {
+
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+
+  declareProperty("ParametersToT", m_parToT);
+  declareProperty("ParametersCharge", m_parCharge);
+  declareProperty("ParametersHitsInEvent", m_parHitsInEvent);
+  declareProperty("ParametersDeltaT", m_parDeltaT);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbHitMonitor::~TbHitMonitor() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbHitMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Setup the histograms.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+    const unsigned int nRows = Tb::NRows;
+    const unsigned int nCols = geomSvc()->modules().at(i)->cols();
+    std::string name = "HitMap/Plane" + plane;
+
+    m_hHitMap.push_back(book2D(name, title, -0.5, nCols - 0.5, nCols, -0.5,
+                               nRows - 0.5, nRows));
+    setAxisLabels(m_hHitMap[i], "column", "row");
+
+    int bins = m_parToT.bins();
+    double low = m_parToT.lowEdge();
+    double high = m_parToT.highEdge();
+    name = "ToT/Plane" + plane;
+    m_hToT.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hToT[i], "ToT", "entries");
+
+    bins = m_parCharge.bins();
+    low = m_parCharge.lowEdge();
+    high = m_parCharge.highEdge();
+    name = "Charge/Plane" + plane;
+    m_hCharge.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hCharge[i], "charge [electrons]", "entries");
+
+    name = "ToTvsCol/Plane" + plane;
+    m_hToTvsCol.push_back(bookProfile1D(name, title, 
+                                        -0.5, nCols - 0.5, nCols));
+    setAxisLabels(m_hToTvsCol[i], "column", "ToT");
+
+    name = "ChargevsCol/Plane" + plane;
+    m_hChargevsCol.push_back(bookProfile1D(name, title, 
+                             -0.5, nCols - 0.5, nCols));
+    setAxisLabels(m_hChargevsCol[i], "column", "charge [electrons]");
+
+    bins = m_parHitsInEvent.bins();
+    low = m_parHitsInEvent.lowEdge();
+    high = m_parHitsInEvent.highEdge();
+    name = "HitsInEvent/Plane" + plane;
+    m_hHitsInEvent.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hHitsInEvent[i], "number of hits", "events");
+    name = "HitsInEventTrend/Plane" + plane;
+    m_hHitsInEventTrend.push_back(book1D(name, title, -0.5, 999.5, 1000));
+    setAxisLabels(m_hHitsInEventTrend[i], "event", "number of hits");
+
+    bins = m_parDeltaT.bins();
+    low = m_parDeltaT.lowEdge();
+    high = m_parDeltaT.highEdge();
+    name = "TimeBetweenHits/Plane" + plane;
+    m_hTimeBetweenHits.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hTimeBetweenHits[i], "#Deltat [ns]", "entries");
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbHitMonitor::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Grab the hits.
+    const std::string hitLocation = m_hitLocation + std::to_string(i);
+    const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(hitLocation);
+    if (!hits) continue;
+    m_hHitsInEvent[i]->fill(hits->size());
+    m_hHitsInEventTrend[i]->fill(m_nEvents, hits->size());
+    if (hits->empty()) continue;
+    double tprev = 0.;
+    LHCb::TbHits::const_iterator begin = hits->begin();
+    LHCb::TbHits::const_iterator end = hits->end();
+    for (LHCb::TbHits::const_iterator ith = begin; ith != end; ++ith) {
+      const LHCb::TbHit* hit = *ith;
+      m_hToT[i]->fill(hit->ToT());
+      m_hCharge[i]->fill(hit->charge());
+      m_hToTvsCol[i]->fill(hit->scol(), hit->ToT());
+      m_hChargevsCol[i]->fill(hit->scol(), hit->charge());
+      m_hHitMap[i]->fill(hit->scol(), hit->row());
+      const double t = hit->htime();
+      if (ith != begin) m_hTimeBetweenHits[i]->fill(t - tprev);
+      tprev = t;
+    }
+  }
+  ++m_nEvents;
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/TbHitMonitor.h b/TbAlgorithms/src/TbHitMonitor.h
new file mode 100644
index 0000000..fef9763
--- /dev/null
+++ b/TbAlgorithms/src/TbHitMonitor.h
@@ -0,0 +1,55 @@
+#ifndef TB_HIT_MONITOR_H
+#define TB_HIT_MONITOR_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+#include "AIDA/IProfile1D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbHitMonitor TbHitMonitor.h
+ *
+ *  Algorithm to produce monitoring histograms for Timepix3 pixel hits.
+ *
+ *  @author Tim Evans (timothy.david.evans@cern.ch)
+ *  @date   2014-04-01
+ */
+
+class TbHitMonitor : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbHitMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbHitMonitor();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location of hits.
+  std::string m_hitLocation;
+  /// Parameters for ToT distribution histograms
+  Gaudi::Histo1DDef m_parToT;
+  /// Parameters for charge distribution histograms
+  Gaudi::Histo1DDef m_parCharge;
+  /// Parameters for hits / event distribution histograms
+  Gaudi::Histo1DDef m_parHitsInEvent;
+  /// Parameters for time difference histograms
+  Gaudi::Histo1DDef m_parDeltaT;
+
+  /// Event counter
+  unsigned int m_nEvents;
+
+  std::vector<AIDA::IHistogram2D*> m_hHitMap;
+  std::vector<AIDA::IHistogram1D*> m_hToT;
+  std::vector<AIDA::IHistogram1D*> m_hCharge;
+  std::vector<AIDA::IProfile1D*> m_hToTvsCol;
+  std::vector<AIDA::IProfile1D*> m_hChargevsCol;
+  std::vector<AIDA::IHistogram1D*> m_hHitsInEvent;
+  std::vector<AIDA::IHistogram1D*> m_hHitsInEventTrend;
+  std::vector<AIDA::IHistogram1D*> m_hTimeBetweenHits;
+};
+
+#endif
diff --git a/TbAlgorithms/src/TbSimpleTracking.cpp b/TbAlgorithms/src/TbSimpleTracking.cpp
new file mode 100644
index 0000000..bf35330
--- /dev/null
+++ b/TbAlgorithms/src/TbSimpleTracking.cpp
@@ -0,0 +1,393 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbSimpleTracking.h"
+
+DECLARE_ALGORITHM_FACTORY(TbSimpleTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbSimpleTracking::TbSimpleTracking(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_trackFit(nullptr) {
+
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+  declareProperty("TimeWindow", m_timeWindow = 10. * Gaudi::Units::ns);
+  declareProperty("MinPlanes", m_nMinPlanes = 8);
+  declareProperty("MaxDistance", m_maxDist = 0. * Gaudi::Units::mm);
+  declareProperty("MaxOpeningAngle", m_maxAngle = 0.01);
+  declareProperty("RecheckTrack", m_recheckTrack = true);
+  declareProperty("RemoveOutliers", m_removeOutliers = true);
+  declareProperty("ChargeCutLow", m_chargeCutLow = 0);
+  declareProperty("MaxClusterSize", m_maxClusterSize = 10);
+  declareProperty("MaxClusterWidth", m_maxClusterWidth = 3);
+  declareProperty("MaxOccupancy", m_maxOccupancy = 8);
+  declareProperty("DoOccupancyCut", m_doOccupancyCut = false);
+  declareProperty("Monitoring", m_monitoring = false);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbSimpleTracking::initialize() {
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  m_clusters.resize(m_nPlanes, nullptr);
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+
+  m_nMaxPlanes = 0;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (!masked(i)) ++m_nMaxPlanes;
+  }
+  if (m_nMaxPlanes == 0) return Error("All planes are masked.");
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbSimpleTracking::execute() {
+
+  // Get the clusters on each plane.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      return Error("No clusters in " + LHCb::TbClusterLocation::Default);
+    }
+    m_clusters[i] = clusters;
+  }
+
+  if (m_doOccupancyCut) findHighOccupancies();
+  unsigned int nKilledOccupancyCut = 0;
+  // Check if there is already a track container.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    // Create a track container and transfer its ownership to the TES.
+    tracks = new LHCb::TbTracks();
+    put(tracks, m_trackLocation);
+  }
+  LHCb::TbTrack* track = nullptr;
+  const unsigned int lastPlane = m_nPlanes - 2;
+  for (unsigned int i = 0; i < lastPlane; ++i) {
+    if (masked(i)) continue;
+    // Get the next valid plane.
+    unsigned int j = i + 1;
+    while (masked(j) && j <= lastPlane) ++j;
+    if (j > lastPlane) break;
+    LHCb::TbClusters::iterator first0 = m_clusters[i]->begin();
+    LHCb::TbClusters::iterator first1 = m_clusters[j]->begin();
+    LHCb::TbClusters::iterator end0 = m_clusters[i]->end();
+    LHCb::TbClusters::iterator end1 = m_clusters[j]->end();
+    for (LHCb::TbClusters::iterator it0 = first0; it0 != end0; ++it0) {
+      // Skip clusters already assigned to tracks.
+      if ((*it0)->associated()) continue;
+      // Skip clusters with too low ToT.
+      if ((*it0)->ToT() < m_chargeCutLow) continue;
+      // Skip large clusters.
+      if ((*it0)->size() > m_maxClusterSize) continue;
+      if (((*it0)->cols() > m_maxClusterWidth) || 
+          ((*it0)->rows() > m_maxClusterWidth)) continue;
+      const double t0 = (*it0)->htime();
+      const double tMin = t0 - m_timeWindow;
+      const double tMax = t0 + m_timeWindow;
+      // Loop over the hits in the second plane.
+      for (LHCb::TbClusters::iterator it1 = first1; it1 != end1; ++it1) {
+        const double t1 = (*it1)->htime();
+        // Skip hits below the time limit.
+        if (t1 < tMin) {
+          // Update the search range.
+          first1 = it1 + 1;
+          continue;
+        }
+        // Stop search when above the time limit.
+        if (t1 > tMax) break;
+        // Skip clusters already assigned to tracks.
+        if ((*it1)->associated()) continue;
+        // Skip clusters with too low charge.
+        if ((*it1)->ToT() < m_chargeCutLow) continue;
+        // Skip large clusters.
+        if ((*it1)->size() > m_maxClusterSize) continue;
+        if (((*it1)->cols() > m_maxClusterWidth) || 
+            ((*it1)->rows() > m_maxClusterWidth)) continue;
+        if (!track)
+          track = new LHCb::TbTrack();
+        else
+          track->clearClusters();
+
+        track->addToClusters(*it0);
+        track->addToClusters(*it1);
+        if (!extendTrack(track, true)) continue;
+        // Fit the track.
+        m_trackFit->fit(track);
+        if (m_recheckTrack) recheckTrack(track);
+        // Check if there are enough measurements on the track.
+        if (track->clusters().size() < m_nMinPlanes) continue;
+        // Check if there are enough unused clusters on the track.
+        /*
+        unsigned int nUnused = 0;
+        for (const LHCb::TbCluster* cluster : track->clusters()) {
+          if (!cluster->associated()) ++nUnused;
+        }
+        if (nUnused < 5) continue;
+        */
+        if (!lowClusterOccupancy(track->htime())) {
+          ++nKilledOccupancyCut;
+          continue;
+        }
+        auto clusters = const_cast<SmartRefVector<LHCb::TbCluster>&>(track->clusters());
+        // Sort the clusters by plane.
+        std::sort(clusters.begin(), clusters.end(),
+                  TbFunctors::LessByZ<const LHCb::TbCluster*>());
+        // Tag the clusters as used.
+        for (auto itc = clusters.begin(), end = clusters.end(); itc != end;
+             ++itc) {
+          (*itc)->setAssociated(true);
+        }
+        // Calculate the global timestamp and add the track to the container.
+        track->setTime(timingSvc()->localToGlobal(track->htime()));
+        tracks->insert(track);
+        track = nullptr;
+      }
+    }
+  }
+  if (track) delete track;
+
+  // Sort the tracks by time.
+  std::sort(tracks->begin(), tracks->end(),
+            TbFunctors::LessByTime<const LHCb::TbTrack*>());
+  // Fill the counters.
+  counter("Number of tracks") += tracks->size();
+  counter("Number of tracks removed by occupancy cut") += nKilledOccupancyCut;
+  appendTrackingEfficiencies();
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Extrapolate and try to add clusters to a given seed track
+//=============================================================================
+bool TbSimpleTracking::extendTrack(LHCb::TbTrack* track, const bool fwd) {
+
+  unsigned int nAdded = 0;
+  // Count planes without matching clusters.
+  unsigned int nMissed = 0;
+  const LHCb::TbCluster* c1 = track->clusters().front();
+  const LHCb::TbCluster* c2 = track->clusters().back();
+  if (!fwd) {
+    c2 = c1;
+    c1 = track->clusters().at(1);
+  }
+  double t = c2->htime();
+  // Calculate the track slopes based on the first two clusters on the track.
+  double td = 1. / (c2->z() - c1->z());
+  double tx = (c2->x() - c1->x()) * td;
+  double ty = (c2->y() - c1->y()) * td;
+  unsigned int plane = c2->plane();
+  if (fwd) {
+    plane += 1;
+  } else {
+    plane -= 1;
+  }
+  while (plane < m_nPlanes) {
+    // Calculate the extrapolated position on this plane. 
+    const double dz = geomSvc()->modules().at(plane)->z() - c1->z();
+    const double xPred = c1->x() + tx * dz;
+    const double yPred = c1->y() + ty * dz;
+    // Calculate the tolerance window.
+    const double tol = fabs(dz * m_maxAngle) + m_maxDist;
+    // Try adding clusters on this plane.
+    const LHCb::TbCluster* c3 = bestCluster(plane, xPred, yPred, t, tol);
+    if (c3) {
+      // Add the cluster.
+      track->addToClusters(c3);
+      ++nAdded;
+      // Reset the missed plane counter.
+      nMissed = 0;
+      // Update the pair of clusters to be used for extrapolating.
+      if ((c3->cols() <= m_maxClusterWidth) && 
+          (c3->rows() <= m_maxClusterWidth)) {
+        c1 = c2;
+        c2 = c3;
+        // Update the track slopes.
+        td = 1. / (c2->z() - c1->z());
+        tx = (c2->x() - c1->x()) * td;
+        ty = (c2->y() - c1->y()) * td;
+      }
+      // Update the predicted timestamp.
+      t = c3->htime();
+    } else {
+      // No matching cluster.
+      ++nMissed;
+      if (nMissed > 1) break;
+    }
+    if (fwd) {
+      ++plane;
+    } else {
+      if (plane == 0) break;
+      --plane;
+    }
+  }
+  return nAdded > 0;
+}
+
+//=============================================================================
+// Get the closest cluster to a given point on the plane
+//=============================================================================
+const LHCb::TbCluster* TbSimpleTracking::bestCluster(const unsigned int plane, 
+    const double xPred, const double yPred,
+    const double tPred, const double tol) {
+  if (masked(plane) || m_clusters[plane]->empty()) return nullptr;
+  // Get the first cluster within the time window.
+  const double tMin = tPred - m_timeWindow;
+  LHCb::TbClusters::iterator end = m_clusters[plane]->end();
+  LHCb::TbClusters::iterator it =
+      std::lower_bound(m_clusters[plane]->begin(), end, tMin, lowerBound());
+  if (it == end) return nullptr;
+  const double tMax = tPred + m_timeWindow;
+  LHCb::TbCluster* best = nullptr;
+  double dtBest = m_timeWindow;
+  for (; it != end; ++it) {
+    const double t = (*it)->htime();
+    if ((*it)->ToT() < m_chargeCutLow) continue;
+    if ((*it)->size() > m_maxClusterSize) continue;
+    // Stop searching when outside the time window.
+    if (t > tMax) break;
+    const double dt = fabs(t - tPred);
+    if (m_monitoring) {
+      const std::string title = "Plane" + std::to_string(plane);
+      plot(t - tPred, "delT" + title, title, -100, 100, 200);
+    }
+    if (dt < dtBest) {
+      // Check if the cluster is within the spatial tolerance window.
+      const double dx = xPred - (*it)->x();
+      const double dy = yPred - (*it)->y();
+      if (m_monitoring) {
+        const std::string title = "Plane " + std::to_string(plane); 
+        plot(dx, "delXY/" + title, title, -3, 3, 200);
+        plot(dy, "delXY/" + title, title, -3, 3, 200);
+      }
+      if (fabs(dx) > tol || fabs(dy) > tol) continue;
+      // Update the best cluster.
+      dtBest = dt;
+      best = *it;
+    }
+  }
+  return best;
+}
+
+//=============================================================================
+// Remove outliers and try to find additional clusters on a track candidate.
+//=============================================================================
+void TbSimpleTracking::recheckTrack(LHCb::TbTrack* track) {
+
+  const unsigned int nClusters = track->clusters().size();
+  if (nClusters < 3 || nClusters >= m_nMaxPlanes) return;
+  // Spatial window for adding clusters to the track.
+  const double tol = 0.1;
+  // Keep track of the planes which already have a cluster on the track.
+  std::vector<bool> planeAssociated(m_nPlanes, false);
+  // Get the straight-line fit parameters.
+  const double x0 = track->firstState().x();
+  const double y0 = track->firstState().y();
+  const double tx = track->firstState().tx();
+  const double ty = track->firstState().ty();
+  auto clusters = track->clusters();
+  const unsigned int nSizeBefore = track->size();
+  for (auto it = clusters.begin(); it != clusters.end(); ) {
+    auto cluster = *it;
+    const unsigned int plane = cluster->plane();
+    ++it;
+    // Remove outliers if requested.
+    const double dx = x0 + tx * cluster->z() - cluster->x();
+    const double dy = y0 + ty * cluster->z() - cluster->y();
+    if (m_removeOutliers && (fabs(dx) > tol || fabs(dy) > tol)) {
+      track->removeFromClusters(cluster);
+    } else {
+      planeAssociated[plane] = true;
+    }
+  }
+  const unsigned int nSizeAfter = track->size();
+  plot(nSizeBefore - nSizeAfter, "NOutliersRemoved", "NOutliersRemoved", -0.5, 10.5, 11);
+  for (unsigned int i = m_nPlanes; i-- > 0;) {
+    if (masked(i) || planeAssociated[i]) continue;
+    // Calculate the track intercept on the plane.
+    const Gaudi::XYZPoint interceptG = geomSvc()->intercept(track, i);
+    const LHCb::TbCluster* cluster = bestCluster(
+        i, interceptG.x(), interceptG.y(), track->htime(), tol);
+    if (cluster) {
+      track->addToClusters(cluster);
+      m_trackFit->fit(track);
+    }
+  }
+}
+
+//=============================================================================
+
+void TbSimpleTracking::findHighOccupancies() {
+
+  m_htimesHighOccupancy.clear();
+  // Find the first non-masked plane.
+  unsigned int seedPlane = 0;
+  while (masked(seedPlane)) ++seedPlane;
+  for (LHCb::TbClusters::const_iterator iSeed = m_clusters[seedPlane]->begin();
+       iSeed != m_clusters[seedPlane]->end(); ++iSeed) {
+    uint nClustersPerSeed = 0;
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (masked(i)) continue;
+      for (LHCb::TbClusters::const_iterator it = m_clusters[i]->begin();
+           it != m_clusters[i]->end(); ++it) {
+        if (fabs((*iSeed)->htime() - (*it)->htime()) < m_timeWindow)
+          nClustersPerSeed++;
+      }
+    }
+    if (nClustersPerSeed > m_maxOccupancy)
+      m_htimesHighOccupancy.push_back((*iSeed)->htime());
+  }
+}
+
+//=============================================================================
+
+bool TbSimpleTracking::lowClusterOccupancy(const double t) const {
+  if (!m_doOccupancyCut) return true;
+  for (unsigned int i = 0; i < m_htimesHighOccupancy.size(); ++i) {
+    if (fabs(t - m_htimesHighOccupancy[i]) < m_timeWindow) return false;
+  }
+  return true;
+}
+
+//=============================================================================
+
+void TbSimpleTracking::appendTrackingEfficiencies() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    for (LHCb::TbClusters::const_iterator it = m_clusters[i]->begin();
+         it != m_clusters[i]->end(); ++it) {
+      counter("nClusters")++;
+      if ((*it)->size() <= m_maxClusterSize &&
+          (*it)->ToT() >= m_chargeCutLow &&
+          lowClusterOccupancy((*it)->htime())) {
+        counter("nClusters selected for tracking")++;
+        if ((*it)->associated()) counter("nClusters associated")++;
+      }
+    }
+  }
+}
+
+//=============================================================================
diff --git a/TbAlgorithms/src/TbSimpleTracking.h b/TbAlgorithms/src/TbSimpleTracking.h
new file mode 100644
index 0000000..7c8b249
--- /dev/null
+++ b/TbAlgorithms/src/TbSimpleTracking.h
@@ -0,0 +1,80 @@
+#ifndef TB_SIMPLETRACKING_H
+#define TB_SIMPLETRACKING_H 1
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbSimpleTracking TbSimpleTracking.h
+ *
+ */
+
+class TbSimpleTracking : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbSimpleTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbSimpleTracking() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location prefix of clusters
+  std::string m_clusterLocation;
+  /// TES location of tracks
+  std::string m_trackLocation;
+
+  /// Tolerance window in time for adding clusters to a track and for occupancy
+  /// cut
+  double m_timeWindow;
+  /// Minimum number of clusters required to form a track
+  unsigned int m_nMinPlanes;
+  /// Number of non-masked planes
+  unsigned int m_nMaxPlanes;
+  /// Tolerance window in x and y for adding clusters to a track
+  double m_maxDist;
+  /// Angular cut (in radians) for adding clusters to a track
+  double m_maxAngle;
+
+  /// List of clusters
+  std::vector<LHCb::TbClusters *> m_clusters;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+
+  bool m_recheckTrack;
+  bool m_removeOutliers;
+  double m_chargeCutLow;
+  unsigned int m_maxClusterSize;
+  unsigned int m_maxClusterWidth;
+  unsigned int m_maxOccupancy;
+  std::vector<double> m_htimesHighOccupancy;
+  bool m_doOccupancyCut;
+  bool m_monitoring;
+
+  void findHighOccupancies();
+  bool lowClusterOccupancy(const double t) const;
+  void appendTrackingEfficiencies();
+  void recheckTrack(LHCb::TbTrack *track);
+  /// Extrapolate and add clusters to a given seed track.
+  bool extendTrack(LHCb::TbTrack *track, const bool fwd);
+  /// Look for a matching cluster on a given plane.
+  const LHCb::TbCluster *bestCluster(const unsigned int plane,
+                                     const double xPred, const double yPred,
+                                     const double tPred, const double tol);
+  /// Functor for lower bound search.
+  class lowerBound {
+   public:
+    bool operator()(const LHCb::TbCluster *lhs, const double t) const {
+      return lhs->htime() < t;
+    }
+  };
+};
+#endif
diff --git a/TbAlgorithms/src/TbTrackPlots.cpp b/TbAlgorithms/src/TbTrackPlots.cpp
new file mode 100644
index 0000000..afa1680
--- /dev/null
+++ b/TbAlgorithms/src/TbTrackPlots.cpp
@@ -0,0 +1,494 @@
+// ROOT
+#include "TMath.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+#include "GaudiUtils/Aida2ROOT.h"
+#include "TH1D.h"
+#include "TF1.h"
+#include "TFile.h"
+// Local
+#include "TbTrackPlots.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbTrackPlots)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTrackPlots::TbTrackPlots(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parChi2("", 0., 30., 300),
+      m_parResidualsXY("", -0.2, 0.2, 500),
+      m_parResidualsT("", -50., 50., 2000),
+      m_parXY("", -20, 20, 500),
+      m_parSlope("", -0.0001, 0.0001, 500),
+      m_parCentral("", 4, 10, 1),
+      m_trackFit(nullptr) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+
+  declareProperty("ParametersChi2", m_parChi2);
+  declareProperty("ParametersResidualsXY", m_parResidualsXY);
+  declareProperty("ParametersResidualsT", m_parResidualsT);
+  declareProperty("ParametersXY", m_parXY);
+  declareProperty("ParametersSlope", m_parSlope);
+  declareProperty("ParametersCentral", m_parCentral);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTrackPlots::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+  setupPlots();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalizer
+//=============================================================================
+StatusCode TbTrackPlots::finalize() {
+
+  // Fill plots used after all events have been evaluated.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    double num =
+        m_hnTrackedClusters->binHeight(m_hnTrackedClusters->coordToIndex(i));
+    double denom =
+        m_hnClustersPerPlane->binHeight(m_hnClustersPerPlane->coordToIndex(i));
+    double frac = num / denom;
+    m_hFractionTrackedClusters->fill(i, frac);
+
+    num = m_hnTracksInterceptCentral->binHeight(
+        m_hnTracksInterceptCentral->coordToIndex(i));
+    denom = m_hnClustersPerPlaneCentral->binHeight(
+        m_hnClustersPerPlaneCentral->coordToIndex(i));
+    frac = num / denom;
+    m_hRatioTracksClustersCentral->fill(i, frac);
+  }
+
+  // Code for saving some residuals in a more useful format.
+  //  TFile * fOut = new TFile("UnbiasedLocalResolutionsPerPlane.root",
+  // "RECREATE");
+  //  TH1F * xPerPlane = new TH1F("xPerPlane", "xPerPlane", m_nPlanes, 0,
+  // m_nPlanes);
+  //  TH1F * yPerPlane = new TH1F("yPerPlane", "yPerPlane", m_nPlanes, 0,
+  // m_nPlanes);
+  //
+  //  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+  //  	if (masked(i)) continue;
+  //  	TH1D * proper_UnbiasedResLocalX =
+  // Gaudi::Utils::Aida2ROOT::aida2root(m_hUnbiasedResLX[i]);
+  //  	TH1D * proper_UnbiasedResLocalY =
+  // Gaudi::Utils::Aida2ROOT::aida2root(m_hUnbiasedResLY[i]);
+  //
+  //  	proper_UnbiasedResLocalX->Fit("gaus");
+  //  	proper_UnbiasedResLocalY->Fit("gaus");
+  //
+  //  	xPerPlane->SetBinContent(i+1,
+  // proper_UnbiasedResLocalX->GetFunction("gaus")->GetParameter(2));
+  //  	yPerPlane->SetBinContent(i+1,
+  // proper_UnbiasedResLocalY->GetFunction("gaus")->GetParameter(2));
+  //  }
+  //
+  //  xPerPlane->Write();
+  //  yPerPlane->Write();
+
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTrackPlots::execute() {
+
+  // Grab the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+  // Fill plots that loop over tracks.
+  fillTrackLoopPlots(tracks);
+
+  // Fill plots that loop over clusters (that have tracking information).
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) continue;
+    fillClusterLoopPlots(clusters, i);
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Fill track loop plots.
+//=============================================================================
+void TbTrackPlots::fillTrackLoopPlots(LHCb::TbTracks* tracks) {
+
+  for (LHCb::TbTrack* track : *tracks) {
+    m_hChi2->fill(track->chi2PerNdof());
+    m_hTrackSize->fill(track->size());
+    m_hProb->fill(TMath::Prob(track->chi2(), track->ndof()));
+    m_hSlopeXZ->fill(track->firstState().tx());
+    m_hSlopeYZ->fill(track->firstState().ty());
+    m_hFirstStateX->fill(track->firstState().x());
+    m_hFirstStateY->fill(track->firstState().y());
+    m_hSlopeXvsX->fill(track->firstState().tx(), track->firstState().x());
+    m_hSlopeYvsY->fill(track->firstState().ty(), track->firstState().y());
+    // Calculate the intercept of the track with the detector planes.
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, i);
+      m_hIntercepts[i]->fill(intercept.x(), intercept.y());
+      // Plot the intercepts of tracks with/without an associated trigger. 
+      if (track->triggers().empty()) {
+        m_hInterceptsNonAssociated[i]->fill(intercept.x(), intercept.y());
+      } else {
+        m_hInterceptsAssociated[i]->fill(intercept.x(), intercept.y());
+      }
+      if (intercept.x() > m_parCentral.lowEdge() &&
+          intercept.x() < m_parCentral.highEdge() &&
+          intercept.y() > m_parCentral.lowEdge() &&
+          intercept.y() < m_parCentral.highEdge())
+        m_hnTracksInterceptCentral->fill(i);
+    }
+    const auto triggers = track->triggers();
+    for (auto trigger : triggers) {
+      m_hTimeDifferenceTrackTrigger->fill(trigger->htime() - track->htime());
+    }
+    fillResiduals(track);
+
+    // Delta angle.
+    LHCb::TbTrack track1, track2;
+    for (unsigned int i = 0; i < track->clusters().size(); i++) {
+      if (track->clusters()[i]->plane() < 4)
+        track1.addToClusters(track->clusters()[i]);
+      else
+        track2.addToClusters(track->clusters()[i]);
+    }
+    if (track2.clusters().size() > 2 && track1.clusters().size() > 2) {
+      m_trackFit->fit(&track1);
+      m_trackFit->fit(&track2);
+      const double dtx = track2.firstState().tx() - track1.firstState().tx();
+      const double dty = track2.firstState().ty() - track1.firstState().ty();
+      plot(dtx, "delAngleArmsX", "delAngleArmsX", -0.001, 0.001, 300);
+      plot(dty, "delAngleArmsY", "delAngleArmsY", -0.001, 0.001, 300);
+    }
+  }
+}
+
+//=============================================================================
+// Fill residual distributions.
+//=============================================================================
+void TbTrackPlots::fillResiduals(LHCb::TbTrack* track) {
+
+  const auto clusters = track->clusters();
+  for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+    const unsigned int plane = (*it)->plane();
+
+    // Mask the plane under consideration to calculate the unbiased residuals.
+    m_trackFit->maskPlane(plane);
+    m_trackFit->fit(track);
+
+    // Calculate the global unbiased residuals.
+    const auto interceptUG = geomSvc()->intercept(track, plane);
+    const double dxug = (*it)->x() - interceptUG.x();
+    const double dyug = (*it)->y() - interceptUG.y();
+    m_hUnbiasedResGX[plane]->fill(dxug);
+    m_hUnbiasedResGY[plane]->fill(dyug);
+
+    // Calculate the local unbiased residuals.
+    const auto interceptUL = geomSvc()->globalToLocal(interceptUG, plane);
+    const double dxul = (*it)->xloc() - interceptUL.x();
+    const double dyul = (*it)->yloc() - interceptUL.y();
+    m_hUnbiasedResLX[plane]->fill(dxul);
+    m_hUnbiasedResLY[plane]->fill(dyul);
+
+    // Re-include the plane under consideration in the fit and refit.
+    m_trackFit->unmaskPlane(plane);
+    m_trackFit->fit(track);
+
+    // Calculate the global biased residuals in x and y.
+    const Gaudi::XYZPoint interceptG = geomSvc()->intercept(track, plane);
+    const double dxg = (*it)->x() - interceptG.x();
+    const double dyg = (*it)->y() - interceptG.y();
+    m_hBiasedResGX[plane]->fill(dxg);
+    m_hBiasedResGY[plane]->fill(dyg);
+
+    // Calculate the local biased residuals.
+    const auto interceptL = geomSvc()->globalToLocal(interceptG, plane);
+    const double dxl = (*it)->xloc() - interceptL.x();
+    const double dyl = (*it)->yloc() - interceptL.y();
+    m_hBiasedResLX[plane]->fill(dxl);
+    m_hBiasedResLY[plane]->fill(dyl);
+
+    // Biased global residuals as function of local x/y.
+    m_hBiasedResGXvsLX[plane]->fill((*it)->xloc(), dxg);
+    m_hBiasedResGYvsLY[plane]->fill((*it)->yloc(), dyg);
+    // Unbiased global residuals as function of global x/y.
+    m_hUnbiasedResGXvsGX[plane]->fill((*it)->x(), dxug);
+    m_hUnbiasedResGYvsGY[plane]->fill((*it)->y(), dyug);
+
+    const double trprob = TMath::Prob(track->chi2(), track->ndof());
+    m_hBiasedResGXvsTrackProb[plane]->fill(trprob, dxg);
+    m_hBiasedResGYvsTrackProb[plane]->fill(trprob, dyg);
+
+    // Time residuals.
+    const double dt = (*it)->htime() - track->htime();
+    m_hBiasedResT[plane]->fill(dt);
+    m_hBiasedResTvsGX[plane]->fill((*it)->x(), dt);
+
+    auto hits = (*it)->hits();
+    for (auto ith = hits.cbegin(), hend = hits.cend(); ith != hend; ++ith) {
+      const double delt = (*ith)->htime() - track->htime();
+      m_hBiasedResPixelTvsColumn[plane]->fill((*ith)->col(), delt);
+    }
+
+    /// Fill time synchronisation histograms, with respect to chip zero,
+    /// and also the synchronisation stability
+    if (plane != 0) continue;
+    for (auto jt = clusters.cbegin(); jt != end; ++jt) {
+      const double dt0 = (*it)->htime() - (*jt)->htime();
+      m_hSyncDifferences[(*jt)->plane()]->fill(dt0);
+      m_syncInRun[(*jt)->plane()]->fill((*it)->time() / Tb::minute, dt0);
+    }
+  }
+}
+
+//=============================================================================
+// Fill cluster loop plots.
+//=============================================================================
+void TbTrackPlots::fillClusterLoopPlots(const LHCb::TbClusters* clusters,
+                                        const unsigned int plane) {
+  unsigned int nTrackedClusters = 0;
+  unsigned int nClustersCentral = 0;
+  for (const LHCb::TbCluster* cluster : *clusters) {
+    if (cluster->associated()) ++nTrackedClusters;
+    if (cluster->x() > m_parCentral.lowEdge() &&
+        cluster->x() < m_parCentral.highEdge() &&
+        cluster->y() > m_parCentral.lowEdge() &&
+        cluster->y() < m_parCentral.highEdge())
+      nClustersCentral++;
+  }
+
+  m_hnTrackedClusters->fill(plane, nTrackedClusters);
+  m_hnClustersPerPlane->fill(plane, clusters->size());
+  m_hnClustersPerPlaneCentral->fill(plane, nClustersCentral);
+}
+
+//=============================================================================
+// Setup plots
+//=============================================================================
+void TbTrackPlots::setupPlots() {
+
+  unsigned int bins = m_parChi2.bins();
+  double low = m_parChi2.lowEdge();
+  double high = m_parChi2.highEdge();
+  m_hChi2 = book1D("Chi2PerDof", low, high, bins);
+  setAxisLabels(m_hChi2, "#chi^{2} / n_{dof}", "entries");
+
+  m_hProb = book1D("Probability", 0., 1., 1000);
+  setAxisLabels(m_hProb, "probability", "entries");
+
+  m_hTrackSize = book1D("TrackSize", 0.5, 12.5, 12);
+  setAxisLabels(m_hTrackSize, "number of clusters", "entries");
+
+  m_hnClustersPerPlane = book1D("TrackingEfficiency/nClustersPerPlane",
+                                "nClustersPerPlane", -0.5, 12.5, 13);
+  setAxisLabels(m_hnClustersPerPlane, "plane", "clusters");
+
+  m_hnTrackedClusters = book1D("TrackingEfficiency/nTrackedClusters",
+                               "nTrackedClusters", -0.5, 12.5, 13);
+  setAxisLabels(m_hnTrackedClusters, "plane", "clusters");
+
+  m_hFractionTrackedClusters =
+      book1D("TrackingEfficiency/FractionTrackedClusters",
+             "FractionTrackedClusters", -0.5, 12.5, 13);
+  setAxisLabels(m_hFractionTrackedClusters, "plane", "Fraction");
+
+  m_hnClustersPerPlaneCentral =
+      book1D("TrackingEfficiency/nClustersPerPlaneCentral",
+             "nClustersPerPlaneCentral", -0.5, 12.5, 13);
+  setAxisLabels(m_hnClustersPerPlaneCentral, "plane", "clusters");
+
+  m_hnTracksInterceptCentral =
+      book1D("TrackingEfficiency/nTracksInterceptCentral",
+             "nTracksInterceptCentral", -0.5, 12.5, 13);
+  setAxisLabels(m_hnTracksInterceptCentral, "plane", "tracks");
+
+  m_hRatioTracksClustersCentral =
+      book1D("TrackingEfficiency/RatioTracksClustersCentral",
+             "RatioTracksClustersCentral", -0.5, 12.5, 13);
+  setAxisLabels(m_hRatioTracksClustersCentral, "plane", "Fraction");
+
+  bins = m_parSlope.bins();
+  low = m_parSlope.lowEdge();
+  high = m_parSlope.highEdge();
+  m_hSlopeXZ = book1D("SlopeXZ", low, high, bins);
+  m_hSlopeYZ = book1D("SlopeYZ", low, high, bins);
+  setAxisLabels(m_hSlopeXZ, "#it{t}_{x}", "entries");
+  setAxisLabels(m_hSlopeYZ, "#it{t}_{y}", "entries");
+
+  bins = m_parXY.bins();
+  low = m_parXY.lowEdge();
+  high = m_parXY.highEdge();
+  m_hFirstStateX = book1D("FirstStateX", low, high, bins);
+  m_hFirstStateY = book1D("FirstStateY", low, high, bins);
+
+  m_hSlopeXvsX =
+      book2D("SlopeXZvsFirstStateX", "t_{x} vs x", m_parSlope.lowEdge(),
+             m_parSlope.highEdge(), m_parSlope.bins(), low, high, bins);
+  m_hSlopeYvsY =
+      book2D("SlopeYZvsFirstStateY", "t_{y} vs y", m_parSlope.lowEdge(),
+             m_parSlope.highEdge(), m_parSlope.bins(), low, high, bins);
+
+  setAxisLabels(m_hSlopeXvsX, "#it{t}_{x}", "#it{x}_{0} [mm]");
+  setAxisLabels(m_hSlopeYvsY, "#it{t}_{y}", "#it{y}_{0} [mm]");
+
+  setAxisLabels(m_hFirstStateX, "#it{x}_{0} [mm]", "entries");
+  setAxisLabels(m_hFirstStateY, "#it{y}_{0} [mm]", "entries");
+
+  const std::string labelx = "#it{x} - #it{x}_{track} [mm]";
+  const std::string labely = "#it{y} - #it{y}_{track} [mm]";
+  const std::string labelt = "#it{t} - #it{t}_{track} [ns]";
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+    // Track intercepts
+    bins = m_parXY.bins();
+    low = m_parXY.lowEdge();
+    high = m_parXY.highEdge();
+    std::string name = "Intercepts/Plane" + plane;
+    m_hIntercepts.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "InterceptsAssociated/Plane" + plane;
+    m_hInterceptsAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    name = "InterceptsNonAssociated/Plane" + plane;
+    m_hInterceptsNonAssociated.push_back(
+        book2D(name, title, low, high, bins, low, high, bins));
+    setAxisLabels(m_hIntercepts[i], "global #it{x} [mm]", "global #it{y} [mm]");
+    setAxisLabels(m_hInterceptsAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+    setAxisLabels(m_hInterceptsNonAssociated[i], "global #it{x} [mm]",
+                  "global #it{y} [mm]");
+
+    // Biased x/y residuals
+    bins = m_parResidualsXY.bins();
+    low = m_parResidualsXY.lowEdge();
+    high = m_parResidualsXY.highEdge();
+    name = "BiasedResiduals/GlobalX/Plane" + plane;
+    m_hBiasedResGX.push_back(book1D(name, title, low, high, bins));
+    name = "BiasedResiduals/GlobalY/Plane" + plane;
+    m_hBiasedResGY.push_back(book1D(name, title, low, high, bins));
+    name = "BiasedResiduals/LocalX/Plane" + plane;
+    m_hBiasedResLX.push_back(book1D(name, title, low, high, bins));
+    name = "BiasedResiduals/LocalY/Plane" + plane;
+    m_hBiasedResLY.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hBiasedResGX[i], labelx, "entries");
+    setAxisLabels(m_hBiasedResGY[i], labely, "entries");
+    setAxisLabels(m_hBiasedResLX[i], labelx, "entries");
+    setAxisLabels(m_hBiasedResLY[i], labely, "entries");
+
+    // Biased residuals vs. x/y
+    const unsigned int binsXY = m_parXY.bins();
+    const double lowXY = m_parXY.lowEdge();
+    const double highXY = m_parXY.highEdge();
+    name = "BiasedResiduals/GlobalResXvsLocalX/Plane" + plane;
+    m_hBiasedResGXvsLX.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    name = "BiasedResiduals/GlobalResYvsLocalY/Plane" + plane;
+    m_hBiasedResGYvsLY.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    setAxisLabels(m_hBiasedResGXvsLX[i], "local #it{x} [mm]", labelx);
+    setAxisLabels(m_hBiasedResGYvsLY[i], "local #it{y} [mm]", labely);
+
+    // Unbiased x/y residuals
+    name = "UnbiasedResiduals/GlobalX/Plane" + plane;
+    m_hUnbiasedResGX.push_back(book1D(name, title, low, high, bins));
+    name = "UnbiasedResiduals/GlobalY/Plane" + plane;
+    m_hUnbiasedResGY.push_back(book1D(name, title, low, high, bins));
+    name = "UnbiasedResiduals/LocalX/Plane" + plane;
+    m_hUnbiasedResLX.push_back(book1D(name, title, low, high, bins));
+    name = "UnbiasedResiduals/LocalY/Plane" + plane;
+    m_hUnbiasedResLY.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hUnbiasedResGX[i], labelx, "entries");
+    setAxisLabels(m_hUnbiasedResGY[i], labely, "entries");
+    setAxisLabels(m_hUnbiasedResLX[i], labelx, "entries");
+    setAxisLabels(m_hUnbiasedResLY[i], labely, "entries");
+
+    // Unbiased residuals vs. x/y
+    name = "UnbiasedResiduals/GlobalResXvsGlobalX/Plane" + plane;
+    m_hUnbiasedResGXvsGX.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    name = "UnbiasedResiduals/GlobalResYvsGlobalY/Plane" + plane;
+    m_hUnbiasedResGYvsGY.push_back(
+        book2D(name, title, lowXY, highXY, binsXY, low, high, bins));
+    setAxisLabels(m_hUnbiasedResGXvsGX[i], "global #it{x} [mm]", labelx);
+    setAxisLabels(m_hUnbiasedResGYvsGY[i], "global #it{y} [mm]", labely);
+
+    // Biased residuals vs. track probability
+    name = "BiasedResiduals/GlobalXvsTrackProb/Plane" + plane;
+    m_hBiasedResGXvsTrackProb.push_back(
+        book2D(name, title, 0.0, 1.0, 1000, low, high, bins));
+    name = "BiasedResiduals/GlobalYvsTrackProb/Plane" + plane;
+    m_hBiasedResGYvsTrackProb.push_back(
+        book2D(name, title, 0.0, 1.0, 1000, low, high, bins));
+
+    // Time residuals
+    bins = m_parResidualsT.bins();
+    low = m_parResidualsT.lowEdge();
+    high = m_parResidualsT.highEdge();
+    name = "BiasedResiduals/Time/Plane" + plane;
+    m_hBiasedResT.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hBiasedResT[i], labelt, "entries");
+
+    // Residuals with respect to plane zero
+    name = "MisalignmentFrom0/Plane" + plane;
+    m_hSyncDifferences.push_back(book1D(name, title, -35.0, 35.0, 2000));
+    setAxisLabels(m_hSyncDifferences[i], labelt, "entries");
+
+    name = "MisalignmentFrom0Profile/Plane" + plane;
+    m_syncInRun.push_back(bookProfile1D(name, title, 0, 120.0, 120));
+    setAxisLabels(m_syncInRun[i], "#it{t}_{track} [minutes]",
+                  "#LT #it{t} - #it{t}_{track} #GT [ns]");
+
+    name = "BiasedResiduals/ResTimeVsGlobalX/Plane" + plane;
+    m_hBiasedResTvsGX.push_back(
+        book2D(name, title, -12, 3, 256, low, high, bins));
+    setAxisLabels(m_hBiasedResTvsGX[i], "#it{x} [mm]", labelt);
+    name = "BiasedResiduals/ResHitTimeVsColumn/Plane" + plane;
+    m_hBiasedResPixelTvsColumn.push_back(
+        book2D(name, title, -0.5, 255.5, 256, low, high, bins));
+    setAxisLabels(m_hBiasedResPixelTvsColumn[i], "column",
+                  "#it{t}_{hit} - #it{t}_{track} [ns]");
+
+    // Time difference between tracks and triggers
+    name = "TimeDifferenceTrackTriggers";
+    m_hTimeDifferenceTrackTrigger = book1D(name, "#Deltat", -1000., 1000., 500);
+    setAxisLabels(m_hTimeDifferenceTrackTrigger,
+                  "#it{t}_{trigger} - #it{t}_track [ns]", "entries");
+  }
+}
diff --git a/TbAlgorithms/src/TbTrackPlots.h b/TbAlgorithms/src/TbTrackPlots.h
new file mode 100644
index 0000000..e1b95df
--- /dev/null
+++ b/TbAlgorithms/src/TbTrackPlots.h
@@ -0,0 +1,120 @@
+#ifndef TB_TRACKPLOTS_H
+#define TB_TRACKPLOTS_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+
+#include "AIDA/IProfile2D.h"
+#include "AIDA/IProfile1D.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTrackPlots TbTrackPlots.h
+ *
+ *  Algorithm to produce monitoring histograms for telescope tracks.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbTrackPlots : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTrackPlots(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTrackPlots() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+
+ private:
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+
+  /// Track intercepts.
+  std::vector<AIDA::IHistogram2D*> m_hIntercepts;
+  std::vector<AIDA::IHistogram2D*> m_hInterceptsAssociated;
+  std::vector<AIDA::IHistogram2D*> m_hInterceptsNonAssociated;
+  /// Biased residuals.
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResGX;
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResGY;
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResLX;
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResLY;
+  /// Unbiased residuals.
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResGX;
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResGY;
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResLX;
+  std::vector<AIDA::IHistogram1D*> m_hUnbiasedResLY;
+
+  /// Biased residuals as functions of x/y.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGXvsLX;
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGYvsLY;
+  /// Unbiased residuals as functions of x/y.
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGXvsGX;
+  std::vector<AIDA::IHistogram2D*> m_hUnbiasedResGYvsGY;
+  /// Biased residuals as functions of track probability.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGXvsTrackProb;
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResGYvsTrackProb;
+
+  /// Cluster time residuals.
+  std::vector<AIDA::IHistogram1D*> m_hBiasedResT;
+  /// Cluster time residuals as function of global x.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResTvsGX;
+  /// Pixel time residuals as function of column number.
+  std::vector<AIDA::IHistogram2D*> m_hBiasedResPixelTvsColumn;
+
+  /// Tracking efficiency plots.
+  AIDA::IHistogram1D* m_hRatioTracksClustersCentral;
+  AIDA::IHistogram1D* m_hnClustersPerPlaneCentral;
+  AIDA::IHistogram1D* m_hnTracksInterceptCentral;
+  AIDA::IHistogram1D* m_hFractionTrackedClusters;
+  AIDA::IHistogram1D* m_hnClustersPerPlane;
+  AIDA::IHistogram1D* m_hnTrackedClusters;
+
+  /// Other.
+  AIDA::IHistogram1D* m_hTimeDifferenceTrackTrigger;
+
+  std::vector<AIDA::IHistogram1D*> m_hSyncDifferences;
+  std::vector<AIDA::IProfile1D*> m_syncInRun;
+
+  AIDA::IHistogram1D* m_hChi2;
+  AIDA::IHistogram1D* m_hProb;
+  AIDA::IHistogram1D* m_hTrackSize;
+  AIDA::IHistogram1D* m_hSlopeXZ;
+  AIDA::IHistogram1D* m_hSlopeYZ;
+  AIDA::IHistogram1D* m_hFirstStateX;
+  AIDA::IHistogram1D* m_hFirstStateY;
+  AIDA::IHistogram2D* m_hSlopeXvsX;
+  AIDA::IHistogram2D* m_hSlopeYvsY;
+
+  /// Parameters for chi-squared distribution
+  Gaudi::Histo1DDef m_parChi2;
+  /// Parameters for x/y residual distributions
+  Gaudi::Histo1DDef m_parResidualsXY;
+  /// Parameters for time residual distributions
+  Gaudi::Histo1DDef m_parResidualsT;
+  /// Parameters for x/y histograms (hitmaps)
+  Gaudi::Histo1DDef m_parXY;
+  /// Parameters for track slope distributions
+  Gaudi::Histo1DDef m_parSlope;
+  /// Parameters for central region cuts.
+  Gaudi::Histo1DDef m_parCentral;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit* m_trackFit;
+
+  void setupPlots();
+  void fillClusterLoopPlots(const LHCb::TbClusters* clusters,
+                            const unsigned int plane);
+  void fillTrackLoopPlots(LHCb::TbTracks* tracks);
+  void fillResiduals(LHCb::TbTrack* track);
+};
+#endif
diff --git a/TbAlgorithms/src/TbTrackVolume.cpp b/TbAlgorithms/src/TbTrackVolume.cpp
new file mode 100644
index 0000000..28791b1
--- /dev/null
+++ b/TbAlgorithms/src/TbTrackVolume.cpp
@@ -0,0 +1,163 @@
+#include "Event/TbTrack.h"
+
+#include "TbTrackVolume.h"
+
+//=============================================================================
+// Constructor
+//=============================================================================
+TbTrackVolume::TbTrackVolume(const std::string& vol_shape,
+                             const unsigned int& nPlanes, const double& r,
+                             const double& rY, const double& theta,
+                             const double& thetaY,
+                             const unsigned int& minNClusters)
+    : m_r(r),
+      m_rY(rY),
+      m_r2(r * r),
+      m_theta(theta),
+      m_thetaY(thetaY),
+      m_seed_cluster(NULL),
+      m_nPlanes(nPlanes),
+      m_MinNClusters(minNClusters) {
+
+  if (vol_shape == "cylinder") {
+    m_3vol_shape = VolShape::Cylinder;
+  } else if (vol_shape == "diabolo") {
+    m_3vol_shape = VolShape::Diabolo;
+  } else if (vol_shape == "sqDiabolo") {
+    m_3vol_shape = VolShape::SqDiabolo;
+  } else {
+    // Use default shape.
+    m_3vol_shape = VolShape::Cylinder;
+  }
+}
+
+//=============================================================================
+// Initialise with a given seed cluster.
+//=============================================================================
+void TbTrackVolume::reset(LHCb::TbCluster* c) {
+
+  m_clusters.clear();
+  m_clusters.resize(m_nPlanes, std::vector<LHCb::TbCluster*>());
+  m_clusters[c->plane()].push_back(c);
+  m_seed_cluster = c;
+  m_done = false;
+}
+
+//=============================================================================
+// Check if a given cluster is within the volume.
+//=============================================================================
+void TbTrackVolume::consider_cluster(LHCb::TbCluster* c) {
+
+  bool inside = false;
+  switch (m_3vol_shape) {
+    case VolShape::Cylinder:
+      inside = consider_cluster_cylinder(c);
+      break;
+    case VolShape::Diabolo:
+      inside = consider_cluster_diabolo(c);
+      break;
+    case VolShape::SqDiabolo:
+      inside = consider_cluster_sqDiabolo(c);
+      break;
+    default:
+      break;
+  }
+  if (inside) {
+    m_clusters[c->plane()].push_back(c);
+  }
+}
+
+//=============================================================================
+bool TbTrackVolume::consider_cluster_sqDiabolo(const LHCb::TbCluster* c_out)
+    const {
+
+  const double delx = c_out->x() - seed()->x();
+  const double dely = c_out->y() - seed()->y();
+  const double dz = fabs(c_out->z() - seed()->z());
+  const double r_x = dz * m_theta + m_r;
+  const double r_y = dz * m_thetaY + m_rY;
+  if (delx < r_x && dely < r_y) return true;
+  return false;
+}
+
+//=============================================================================
+bool TbTrackVolume::consider_cluster_diabolo(const LHCb::TbCluster* c) const {
+
+  const double delx = c->x() - seed()->x();
+  const double dely = c->y() - seed()->y();
+  const double r_z = m_r + fabs(c->z() - m_seed_cluster->z()) * m_theta;
+  return (delx * delx + dely * dely < r_z * r_z);
+}
+
+//=============================================================================
+bool TbTrackVolume::notAlreadyConsidered(const LHCb::TbCluster* c) const {
+  bool result = true;
+  for (unsigned int i = 0; i < m_clusters[c->plane()].size(); i++) {
+    if (m_clusters[c->plane()][i]->key() == c->key()) result = false;
+  }
+  return result;
+}
+
+//=============================================================================
+bool TbTrackVolume::consider_cluster_cylinder(const LHCb::TbCluster* c) const {
+  const double delx = c->x() - seed()->x();
+  const double dely = c->y() - seed()->y();
+  if ((delx * delx + dely * dely) < m_r2 && notAlreadyConsidered(c)) {
+    return true;
+  }
+  return false;
+}
+
+//=============================================================================
+// Return the number of track combinations that can be made from this volume
+//=============================================================================
+unsigned int TbTrackVolume::nCombos() {
+
+  if (m_done) return m_nCombos;
+  // Remove empty planes.
+  for (unsigned int i = 0; i < m_clusters.size(); i++) {
+    if (m_clusters[i].size() == 0) {
+      m_clusters.erase(m_clusters.begin() + i);
+      i--;
+    }
+  }
+  m_combo_counters.assign(m_clusters.size(), 0);
+
+  if (m_clusters.size() < m_MinNClusters) {
+    m_nCombos = 0;
+  } else {
+    m_nCombos = 1;
+    for (unsigned int i = 0; i < m_clusters.size(); i++) {
+      m_nCombos *= m_clusters[i].size();
+    }
+  }
+  m_done = true;
+  return m_nCombos;
+}
+
+//=============================================================================
+// Make a track from the current combination of clusters
+//=============================================================================
+void TbTrackVolume::get_track_combo(LHCb::TbTrack* track) {
+
+  for (unsigned int iplane = 0; iplane < m_clusters.size(); iplane++) {
+    const int ic = m_combo_counters[iplane];
+    track->addToClusters(m_clusters[iplane][ic]);
+  }
+}
+
+//=============================================================================
+// Get the next combination of clusters
+//=============================================================================
+void TbTrackVolume::increment_combo_counters() {
+  const int n = m_combo_counters.size() - 1;
+  m_combo_counters[n] += 1;
+
+  // Adaptive clock.
+  for (int i = n; i >= 1; i--) {
+    if (m_combo_counters[i] >= m_clusters[i].size()) {
+      m_combo_counters[i] = 0;
+      m_combo_counters[i - 1] += 1;
+    }
+  }
+}
diff --git a/TbAlgorithms/src/TbTrackVolume.h b/TbAlgorithms/src/TbTrackVolume.h
new file mode 100644
index 0000000..755913d
--- /dev/null
+++ b/TbAlgorithms/src/TbTrackVolume.h
@@ -0,0 +1,72 @@
+#ifndef TB_TRACKVOLUME_H
+#define TB_TRACKVOLUME_H 1
+
+#include <iostream>
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+/** @class TbTrackVolume TbTrackVolume.h
+ *
+ *  Container for clusters given a set of spatial and time cuts. Used for
+ *  tracking. Offers easy access to particular formations of tracks.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbTrackVolume {
+ public:
+  enum VolShape {
+    Cylinder = 1,
+    Diabolo = 2,
+    SqDiabolo = 3
+  };
+  /// Constructor
+  TbTrackVolume(const std::string& volshape, const unsigned int& nPlanes,
+                const double& r, const double& ry, const double& theta,
+                const double& thetay, const unsigned int& minNClusters);
+  /// Destructor
+  ~TbTrackVolume() {}
+
+  void reset(LHCb::TbCluster* c);
+  void consider_cluster(LHCb::TbCluster* c);
+
+  unsigned int nCombos();
+  void get_track_combo(LHCb::TbTrack* t);
+  void increment_combo_counters();
+
+  // Setters and getters ______________________________________________________
+  LHCb::TbCluster* seed() const { return m_seed_cluster; }
+
+  /// Overload ostream operator <<
+  friend std::ostream& operator<<(std::ostream& s, const TbTrackVolume& v) {
+    s << v.m_theta << " " << v.m_r << " " << v.m_thetaY << " " << v.m_rY << " "
+      << v.seed()->x() << " " << v.seed()->y() << " " << v.seed()->z() << " ";
+    return s;
+  }
+
+  std::vector<std::vector<LHCb::TbCluster*> > m_clusters;
+
+ private:
+  double m_r;
+  double m_rY;
+  double m_r2;
+  double m_theta;
+  double m_thetaY;
+
+  LHCb::TbCluster* m_seed_cluster;
+  unsigned int m_3vol_shape;
+
+  unsigned int m_nPlanes;
+  unsigned int m_MinNClusters;
+  std::vector<unsigned int> m_combo_counters;
+  unsigned int m_nCombos;
+  bool m_done;
+
+  bool consider_cluster_cylinder(const LHCb::TbCluster* cl) const;
+  bool consider_cluster_diabolo(const LHCb::TbCluster* cl) const;
+  bool consider_cluster_sqDiabolo(const LHCb::TbCluster* cl) const;
+  bool notAlreadyConsidered(const LHCb::TbCluster* cl) const;
+};
+#endif
diff --git a/TbAlgorithms/src/TbTracking.cpp b/TbAlgorithms/src/TbTracking.cpp
new file mode 100644
index 0000000..5732aca
--- /dev/null
+++ b/TbAlgorithms/src/TbTracking.cpp
@@ -0,0 +1,421 @@
+#include <fstream>
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbTracking.h"
+
+DECLARE_ALGORITHM_FACTORY(TbTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTracking::TbTracking(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_tracks(nullptr),
+      m_trackFit(nullptr),
+      m_clusterFinder(nullptr),
+      m_trackVolume(nullptr),
+      m_event(0) {
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+  declareProperty("Monitoring", m_monitoring = false);
+  declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
+  declareProperty("MinNClusters", m_MinNClusters = 7);
+  declareProperty("SearchRadius", m_vol_radius = 1 * Gaudi::Units::mm);
+  declareProperty("MaxChi2", m_ChiSqRedCut = 20000.);
+  declareProperty("VolumeAngle", m_vol_theta = 0.015);
+  declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
+  declareProperty("ClusterSizeCut", m_clusterSizeCut = 1000);
+  declareProperty("CombatRun", m_combatRun = false);
+
+  // Options for the event viewer.
+  declareProperty("ViewerOutput", m_viewerOutput = false);
+  declareProperty("ViewerEventNum", m_viewerEvent = 100);
+
+  // Default values.
+  m_search_3vol = "diabolo";
+  m_ClusterFinderSearchAlgorithm = "adap_seq";
+  m_nComboCut = 300;
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTracking::~TbTracking() {
+
+  if (m_trackVolume) {
+    delete m_trackVolume;
+  }
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTracking::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+  // Set up the cluster finder.
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+  if (!m_clusterFinder) return Error("Cannot retrieve cluster finder tool.");
+  m_clusterFinder->setSearchAlgorithm(m_ClusterFinderSearchAlgorithm);
+  m_volumed.resize(m_nPlanes);
+  // Set up the track volume.
+  m_trackVolume =
+      new TbTrackVolume(m_search_3vol, m_nPlanes, m_vol_radius, m_vol_radius,
+                        m_vol_theta, m_vol_theta, m_MinNClusters);
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTracking::execute() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (m_event == m_viewerEvent && m_viewerOutput) {
+      std::ofstream myfile;
+      myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat");
+      myfile << "# Output\n";
+      myfile.close();
+    }
+
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      return Error("No clusters in " + clusterLocation);
+    }
+    // Store the cluster iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+    m_volumed[i].clear();
+    m_volumed[i].resize(clusters->size(), false);
+  }
+
+  // Check if there is already a track container.
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!m_tracks) {
+    // Create a track container and transfer its ownership to the TES.
+    m_tracks = new LHCb::TbTracks();
+    put(m_tracks, m_trackLocation);
+  }
+  // Do the tracking and time order.
+  performTracking();
+  timeOrderTracks();
+
+  counter("NumberOfTracks") += m_tracks->size();
+  if (m_event == m_viewerEvent && m_viewerOutput) outputViewerData();
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Tracking
+//=============================================================================
+void TbTracking::performTracking() {
+  // The working of this algorithm is similar to the cluster maker, such that:
+  // - Loop over some set of seed clusters (those on the m_SeedPlanes).
+  // - Create a container (TbTrackVolume) centered on each seed cluster
+  //   (in space and time).
+  // - Impose the condition that any formed track must contain this seed.
+  // - Evaluate that 4-volume, to see if it contained a track.
+  // - If a choice (e.g. more than one possible combination of clusters),
+  //   take the best fitting. Priority is given to more complete tracks.
+  // - If another track happened to be in the 4volume, but not
+  //   containing this seed, then it will be found later.
+
+  // Iterate over planes in the specified order.
+  for (const auto& plane : m_PlaneSearchOrder) {
+    // Skip masked and empty planes.
+    if (masked(plane) || m_clusterFinder->empty(plane)) continue;
+    // Iterate over the clusters on this plane.
+    const auto end = m_clusterFinder->end(plane);
+    for (auto ic = m_clusterFinder->first(plane); ic != end; ++ic) {
+      // Check if the seed has already been used.
+      if ((*ic)->associated() || (*ic)->size() > m_clusterSizeCut) continue;
+      // Initialise the track volume container and find clusters
+      // that fall in its space-time volume.
+      fillTrackVolume(*ic, 0, m_nPlanes);
+      // Tag the clusters as "volumed".
+      for (unsigned int i = 0; i < m_trackVolume->m_clusters.size(); ++i) {
+        for (const auto cl : m_trackVolume->m_clusters[i]) {
+          m_volumed[cl->plane()][cl->key()] = true;
+        }
+      }
+      // Look for a track - automatically keeps if suitable.
+      evaluateTrackVolume(m_trackVolume);
+    }
+  }
+}
+
+//=============================================================================
+// Fill the given track volume with clusters in its space-time volume.
+//=============================================================================
+void TbTracking::fillTrackVolume(LHCb::TbCluster* seed,
+                                 const unsigned int& planeLow,
+                                 const unsigned int& planeUp) {
+
+  m_trackVolume->reset(seed);
+  const double tMin = seed->htime() - 0.5 * m_twindow;
+  const double tMax = seed->htime() + 0.5 * m_twindow;
+  for (unsigned int i = planeLow; i < planeUp; ++i) {
+    // Skip empty planes, masked planes and the seed plane.
+    if (m_clusterFinder->empty(i) || i == seed->plane() || masked(i)) {
+      continue;
+    }
+    // Start with the first cluster in the time window
+    // and loop until the end of the time window.
+    const auto end = m_clusterFinder->end(i);
+    for (auto ic = m_clusterFinder->getIterator(tMin, i); ic != end; ++ic) {
+      if ((*ic)->htime() < tMin) continue;
+      if ((*ic)->htime() > tMax) break;
+      // Skip clusters which are already used or exceed the cluster size cut.
+      if (!(*ic)->associated() && (*ic)->size() <= m_clusterSizeCut) {
+        m_trackVolume->consider_cluster(*ic);
+      }
+    }
+  }
+  if (m_event == m_viewerEvent && m_viewerOutput) {
+    std::ofstream file;
+    file.open("KeplerViewerData.dat", std::ofstream::app);
+    file << "SqTrackArea " << m_trackVolume << tMin << " " << tMax << "\n";
+  }
+}
+
+//=============================================================================
+// Finding the best tracks
+//=============================================================================
+void TbTracking::evaluateTrackVolume(TbTrackVolume* track_volume) {
+
+  LHCb::TbTrack* trialTrack = NULL;
+  LHCb::TbTrack* best_track = NULL;
+  double best_chi_dof = -1.;
+  // Get the number of combinations to check (depends on the size of the track
+  // to be formed).
+  const unsigned int ncombos = std::min(track_volume->nCombos(), m_nComboCut);
+  // Do the search over this number of combinations - the TbTrackVolume has
+  // method to retrieve a particular combination of clusters forming a track.
+  for (unsigned int i = 0; i < ncombos; ++i) {
+    // Create or reset the trial track.
+    if (!trialTrack) {
+      trialTrack = new LHCb::TbTrack();
+    } else {
+      trialTrack->clearClusters();
+    }
+    // Get the ith track combination.
+    track_volume->get_track_combo(trialTrack);
+    // Sort the clusters by z-position.
+    SmartRefVector<LHCb::TbCluster>& clusters =
+        const_cast<SmartRefVector<LHCb::TbCluster>&>(trialTrack->clusters());
+    std::sort(clusters.begin(), clusters.end(),
+              TbFunctors::LessByZ<const LHCb::TbCluster*>());
+    // Evaluate this track.
+    m_trackFit->fit(trialTrack);
+    const double chi2_per_dof = trialTrack->chi2PerNdof();
+    if (i == 0) {
+      // First combination tried case.
+      best_chi_dof = chi2_per_dof;
+      best_track = trialTrack;
+      trialTrack = NULL;
+    } else if (chi2_per_dof < best_chi_dof) {
+      // Case of better combination.
+      delete best_track;
+      best_chi_dof = chi2_per_dof;
+      best_track = trialTrack;
+      trialTrack = NULL;
+    }
+    // Prepare for next combination.
+    track_volume->increment_combo_counters();
+  }
+
+  if (m_monitoring) fillTrackVolPlots(track_volume);
+  if (!best_track) return;
+
+  // If the best chi2 is too high, consider popping one cluster.
+  if (best_track->clusters().size() > m_MinNClusters + 1 &&
+      best_chi_dof > m_ChiSqRedCut) {
+    int popID = -1;
+    for (unsigned int i = 0; i < m_nPlanes; i++) {
+      m_trackFit->maskPlane(i);
+      m_trackFit->fit(best_track);
+      if (best_track->chi2PerNdof() < best_chi_dof) {
+        best_chi_dof = best_track->chi2PerNdof();
+        popID = i;
+      }
+      m_trackFit->unmaskPlane(i);
+    }
+    if (popID != -1) {
+      for (auto cluster : best_track->clusters()) {
+        if (int(cluster->plane()) == popID) {
+          best_track->removeFromClusters(cluster);
+        }
+      }
+    }
+    m_trackFit->fit(best_track);
+    counter("NumberOfPopRecoveredTracks") += 1;
+  }
+
+  // At this point, found the best fitting track in the volume.
+  // Apply chi2 cut, and save.
+  if (best_chi_dof > m_ChiSqRedCut) {
+    counter("NumberOfChiRejectedVols") += 1;
+    delete best_track;
+    return;
+  }
+
+  SmartRefVector<LHCb::TbCluster>& clusters =
+      const_cast<SmartRefVector<LHCb::TbCluster>&>(best_track->clusters());
+  auto earliest_hit =
+      std::min_element(clusters.begin(), clusters.end(),
+                       TbFunctors::LessByTime<const LHCb::TbCluster*>());
+
+  if (timingSvc()->beforeOverlap((*earliest_hit)->time()) || m_combatRun) {
+    for (auto itc = clusters.begin(), end = clusters.end(); itc != end; ++itc) {
+      (*itc)->setAssociated(true);
+    }
+    m_tracks->insert(best_track);
+    best_track->setTime(timingSvc()->localToGlobal(best_track->htime()));
+    if (m_monitoring) fillTrackVolPlots(track_volume);
+  } else {
+    info() << "Overlapping track" << endmsg;
+    delete best_track;
+  }
+}
+
+//=============================================================================
+// Monitoring plots
+//=============================================================================
+void TbTracking::fillTrackVolPlots(TbTrackVolume* vol) {
+  plot(vol->nCombos(), "nComboDist_of_TrackVolumes",
+       "nComboDist_of_TrackVolumes", -0.5, 1099.5, 1100);
+  unsigned int nclusters = 0;
+  for (unsigned int i = 0; i < vol->m_clusters.size(); i++) {
+    nclusters += vol->m_clusters[i].size();
+    if (vol->m_clusters[i].size() > 0) {
+      const std::string plane = std::to_string(vol->m_clusters[i][0]->plane());
+      plot(vol->m_clusters[i].size(),
+           "nVolClusters/nClusterPerVolPlane" + plane,
+           "nClusterPerVolPlane" + plane, 0.5, 10.5, 10);
+    }
+  }
+  plot(nclusters, "nVolClusters/nCluster_in_TrackVolumes",
+       "nCluster_in_TrackVolumes", -0.5, 99.5, 100);
+}
+
+//=============================================================================
+// Track time ordering - honeycomb
+//=============================================================================
+void TbTracking::timeOrderTracks() {
+
+  const double s_factor = 1.3;
+  LHCb::TbTrack* track1;
+  LHCb::TbTrack* track2;
+  unsigned int gap = m_tracks->size() / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    LHCb::TbTracks::iterator itt;
+    for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
+      track1 = *itt;
+      track2 = *(itt + gap);
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        std::iter_swap(itt, itt + gap);
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbTracking::outputViewerData() {
+  std::ofstream myfile;
+  myfile.open("KeplerViewerData.dat", std::ofstream::app);
+
+  // First output the chips.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    myfile << "Chip ";
+    Gaudi::XYZPoint posn1(0., 14.08, 0.);
+    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+    posn = geomSvc()->localToGlobal(posn2, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+    posn = geomSvc()->localToGlobal(posn3, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn4(0., 0., 0.);
+    posn = geomSvc()->localToGlobal(posn4, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    myfile << "\n";
+  }
+
+  // Tracks.
+  for (const LHCb::TbTrack* track : *m_tracks) {
+    myfile << "Track ";
+    myfile << track->firstState().tx() << " " << track->firstState().x() << " "
+           << track->firstState().ty() << " " << track->firstState().y() << " "
+           << track->htime() << "\n";
+  }
+
+  // Clusters.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    auto ic = m_clusterFinder->first(i);
+    const auto end = m_clusterFinder->end(i);
+    for (; ic != end; ++ic) {
+      const int tag = m_volumed[i][(*ic)->key()] + (*ic)->associated();
+      myfile << "Cluster ";
+      myfile << (*ic)->x() << " " << (*ic)->y() << " " << (*ic)->z() << " "
+             << (*ic)->htime() << " " << tag << " \n";
+      // Its hits.
+      for (const auto hit : (*ic)->hits()) {
+        myfile << "Pixel ";
+        double xLocal = 0.;
+        double yLocal = 0.;
+        geomSvc()->pixelToPoint(hit->scol(), hit->row(), i, xLocal, yLocal);
+        Gaudi::XYZPoint pLocal(xLocal - 0.5 * Tb::PixelPitch,
+                               yLocal - 0.5 * Tb::PixelPitch, 0.);
+        Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn2(pLocal.x() + Tb::PixelPitch, pLocal.y(), 0.);
+        posn = geomSvc()->localToGlobal(posn2, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn3(pLocal.x() + Tb::PixelPitch,
+                              pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn3, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn4, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        myfile << hit->htime() << " " << hit->ToT() << "\n";
+      }
+    }
+  }
+  myfile.close();
+}
diff --git a/TbAlgorithms/src/TbTracking.h b/TbAlgorithms/src/TbTracking.h
new file mode 100644
index 0000000..de0123a
--- /dev/null
+++ b/TbAlgorithms/src/TbTracking.h
@@ -0,0 +1,93 @@
+#ifndef TB_TRACKING_H
+#define TB_TRACKING_H 1
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTrackVolume.h"
+
+/** @class TbTracking TbTracking.h
+ *
+ *  Algorithm for track reconstruction in Timepix3 telescope
+ *
+ * @author Dan Saunders
+ */
+
+class TbTracking : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbTracking();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// Track container (to be filled).
+  LHCb::TbTracks *m_tracks;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+  /// Tool to find particular clusters.
+  ITbClusterFinder *m_clusterFinder;
+  /// Tool for evaluating seed tracks.
+  TbTrackVolume *m_trackVolume;
+
+  /// TES location prefix of cluster containers.
+  std::string m_clusterLocation;
+  /// TES location prefix of track containers.
+  std::string m_trackLocation;
+
+  /// Flag to fill (or not) monitoring histograms.
+  bool m_monitoring;
+  /// Time width (in ns) of search window around seed cluster.
+  double m_twindow;
+  /// Minimum number of clusters to form a track.
+  unsigned int m_MinNClusters;
+  /// Spatial shapes of TbTrackVolumes {cylinder, diabolo}.
+  std::string m_search_3vol;
+  /// Spatial shape parameter.
+  double m_vol_radius;
+  /// Spatial shape parameter.
+  double m_vol_theta;
+  /// Chi2 cut.
+  double m_ChiSqRedCut;
+  /// Upper cut on the number of combinations to try in a TbTrackVolume.
+  /// Useful for speed, and rarely used; set O(100).
+  unsigned int m_nComboCut;
+  /// Search algorithm used to fill TbTrackVolumes - {"seq", "adap_seq"}.
+  /// "adap_seq" recommended.
+  std::string m_ClusterFinderSearchAlgorithm;
+
+  /// For certain volumes, it's advantageous to use seeds from the center of
+  /// the telescope, so the order of the search can be specified here.
+  std::vector<unsigned int> m_PlaneSearchOrder;
+  /// Max. size of clusters on a track
+  unsigned int m_clusterSizeCut;
+
+  std::vector<std::vector<bool> > m_volumed;
+  // Viewer options.
+  bool m_viewerOutput;
+  unsigned int m_viewerEvent;
+  unsigned int m_event;
+  bool m_combatRun;
+
+  void outputViewerData();
+  void performTracking();
+  void fillTrackVolume(LHCb::TbCluster *seed, const unsigned int &planeLow,
+                       const unsigned int &planeUp);
+  void evaluateTrackVolume(TbTrackVolume *vol);
+  void timeOrderTracks();
+  void fillTrackVolPlots(TbTrackVolume *vol);
+};
+#endif
diff --git a/TbAlgorithms/src/TbTriggerAssociator.cpp b/TbAlgorithms/src/TbTriggerAssociator.cpp
new file mode 100755
index 0000000..c55347c
--- /dev/null
+++ b/TbAlgorithms/src/TbTriggerAssociator.cpp
@@ -0,0 +1,88 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTriggerAssociator.h"
+
+DECLARE_ALGORITHM_FACTORY(TbTriggerAssociator)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTriggerAssociator::TbTriggerAssociator(const std::string& name,
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TriggerLocation",
+                  m_triggerLocation = LHCb::TbTriggerLocation::Default);
+
+  declareProperty("TimeWindow", m_twindow = 1000. * Gaudi::Units::ns);
+  declareProperty("TimeOffset", m_toffset = 0.);
+  declareProperty("Plane", m_plane = 999);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTriggerAssociator::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTriggerAssociator::execute() {
+
+  // Grab the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  // Grab the triggers.
+  std::vector<LHCb::TbTriggers*> triggers(m_nPlanes, nullptr);
+  std::vector<LHCb::TbTriggers::iterator> begin(m_nPlanes);
+  std::vector<LHCb::TbTriggers::iterator> end(m_nPlanes);
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (m_plane != 999 && i != m_plane) continue;
+    const std::string location = m_triggerLocation + std::to_string(i);
+    triggers[i] = getIfExists<LHCb::TbTriggers>(location);
+    if (!triggers[i]) {
+      return Error("No triggers in " + location);
+    }
+    begin[i] = triggers[i]->begin();
+    end[i] = triggers[i]->end();
+  }
+
+  // Loop over the tracks.
+  for (LHCb::TbTrack* track : *tracks) {
+    const double t = track->htime() + m_toffset;
+    // Calculate the time window.
+    const double tMin = t - m_twindow;
+    const double tMax = t + m_twindow;
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (m_plane != 999 && i != m_plane) continue;
+      if (triggers[i]->empty()) continue;
+      // Get the first trigger within the time window (if any).
+      LHCb::TbTriggers::iterator it =
+          std::lower_bound(begin[i], end[i], tMin, lowerBound());
+      if (it == end[i]) continue;
+      // Associate all triggers within the window to the track.
+      for (; it != end[i]; ++it) {
+        // Stop when outside the time window.
+        if ((*it)->htime() > tMax) break;
+        track->addToTriggers(*it);
+        (*it)->setAssociated(true);
+      }
+    }
+  }
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/TbTriggerAssociator.h b/TbAlgorithms/src/TbTriggerAssociator.h
new file mode 100755
index 0000000..82c9a75
--- /dev/null
+++ b/TbAlgorithms/src/TbTriggerAssociator.h
@@ -0,0 +1,47 @@
+#ifndef TB_TRIGGER_ASSOCIATOR_H
+#define TB_TRIGGER_ASSOCIATOR_H 1
+
+// Tb/TbEvent
+#include "Event/TbTrigger.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTriggerAssociator TbTriggerAssociator.h
+ *
+ *  Algorithm to link reconstructed tracks with matching trigger timestamps.
+ *
+ */
+
+class TbTriggerAssociator : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTriggerAssociator(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbTriggerAssociator() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  /// TES location of tracks
+  std::string m_trackLocation;
+  /// TES location of triggers
+  std::string m_triggerLocation;
+
+  /// Time window (in ns)
+  double m_twindow;
+  /// Time offset (in ns) of trigger packets with respect to tracks
+  double m_toffset;
+  /// Specify only a single plane to take triggers from , i.e. for multiple
+  /// external users using different SPIDRS
+  unsigned int m_plane;
+  /// Functor for lower bound search.
+  class lowerBound {
+   public:
+    bool operator()(const LHCb::TbTrigger *lhs, const double t) const {
+      return lhs->htime() < t;
+    }
+  };
+};
+#endif
diff --git a/TbAlgorithms/src/TbTriggerMonitor.cpp b/TbAlgorithms/src/TbTriggerMonitor.cpp
new file mode 100644
index 0000000..7c5cb7c
--- /dev/null
+++ b/TbAlgorithms/src/TbTriggerMonitor.cpp
@@ -0,0 +1,116 @@
+// Gaudi
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbTrigger.h"
+
+// Local
+#include "TbTriggerMonitor.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbTriggerMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTriggerMonitor::TbTriggerMonitor(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_parTriggersInEvent("", 0., 1000., 200),
+      m_nEvents(0) {
+
+  declareProperty("TriggerLocation",
+                  m_triggerLocation = LHCb::TbTriggerLocation::Default);
+  declareProperty("ParametersTriggersInEvent", m_parTriggersInEvent);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTriggerMonitor::~TbTriggerMonitor() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbTriggerMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  m_missedTriggers.resize(m_nPlanes);
+  m_counter.resize(m_nPlanes);
+  m_counter.resize(m_nPlanes, 0);
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    std::string name = "TimeBetweenTriggers";
+    std::string title = "Plane " + plane;
+    m_hTimeBetweenTriggers.push_back(book1D(name, title, 0., 500., 200));
+    setAxisLabels(m_hTimeBetweenTriggers[i], "#Deltat [ns]", "entries");
+    unsigned int bins = m_parTriggersInEvent.bins();
+    double low = m_parTriggersInEvent.lowEdge();
+    double high = m_parTriggersInEvent.highEdge();
+    name = "TriggersInEvent/Plane" + plane;
+    m_hTriggersInEvent.push_back(book1D(name, title, low, high, bins));
+    setAxisLabels(m_hTriggersInEvent[i], "number of triggers", "events");
+    name = "TriggersInEventTrend/Plane" + plane;
+    m_hTriggersInEventTrend.push_back(book1D(name, title, -0.5, 999.5, 1000));
+    setAxisLabels(m_hTriggersInEventTrend[i], "event", "number of hits");
+  }
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TbTriggerMonitor::finalize() {
+  /*
+    for( unsigned int i = 0 ; i < m_nPlanes; ++i){
+
+     std::vector<std::pair<uint64_t, uint64_t>> summary = m_missedTriggers[i];
+      if( summary.size() != 0 ){
+        info() << "Trigger jumps on plane " << i << endmsg;;
+        for( std::vector<std::pair<uint64_t, uint64_t >>::iterator jump =
+    summary.begin(); jump != summary.end(); ++jump ){
+
+          info() << "Trigger jumps from " << jump->second << " to " <<
+    jump->first << endmsg;
+        }
+      }
+    }
+  */
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTriggerMonitor::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    // Grab the triggers.
+    const std::string ext = std::to_string(i);
+    const std::string location = m_triggerLocation + ext;
+    const LHCb::TbTriggers* triggers = getIfExists<LHCb::TbTriggers>(location);
+    if (!triggers) return StatusCode::SUCCESS;
+    m_hTriggersInEvent[i]->fill(triggers->size());
+    m_hTriggersInEventTrend[i]->fill(m_nEvents, triggers->size());
+    double tprev = 0.;
+    LHCb::TbTriggers::const_iterator begin = triggers->begin();
+    LHCb::TbTriggers::const_iterator end = triggers->end();
+    for (LHCb::TbTriggers::const_iterator it = begin; it != end; ++it) {
+      // Check for missed triggers.
+      if ((*it)->counter() - m_counter[i] != 1 && m_counter[i] != 4095) {
+        info() << "Counter on plane " << i << " jumps from " << m_counter[i]
+               << " to " << (*it)->counter() << endmsg;
+      }
+      m_counter[i] = (*it)->counter();
+      const double t = (*it)->htime();
+
+      if (it != begin) {
+        m_hTimeBetweenTriggers[i]->fill(t - tprev);
+      }
+      tprev = t;
+      counter("effFractionAssociated" + ext) += (*it)->associated();
+    }
+  }
+  ++m_nEvents;
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlgorithms/src/TbTriggerMonitor.h b/TbAlgorithms/src/TbTriggerMonitor.h
new file mode 100644
index 0000000..816ff2b
--- /dev/null
+++ b/TbAlgorithms/src/TbTriggerMonitor.h
@@ -0,0 +1,45 @@
+#ifndef TB_TRIGGER_MONITOR_H
+#define TB_TRIGGER_MONITOR_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTriggerMonitor TbTriggerMonitor.h
+ *
+ *  Algorithm to produce monitoring histograms for scintillator triggers.
+ *
+ */
+
+class TbTriggerMonitor : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbTriggerMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTriggerMonitor();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm Finalize
+ private:
+  /// TES location of triggers.
+  std::string m_triggerLocation;
+
+  /// Parameters for hits / event distribution histograms
+  Gaudi::Histo1DDef m_parTriggersInEvent;
+
+  /// Event counter
+  unsigned int m_nEvents;
+
+  /// Last trigger counters
+  std::vector<unsigned int> m_counter;
+
+  std::vector<AIDA::IHistogram1D*> m_hTimeBetweenTriggers;
+  std::vector<AIDA::IHistogram1D*> m_hTriggersInEvent;
+  std::vector<AIDA::IHistogram1D*> m_hTriggersInEventTrend;
+  std::vector<std::vector<std::pair<uint64_t, uint64_t>>> m_missedTriggers;
+};
+
+#endif
diff --git a/TbAlgorithms/src/TbVertexTracking.cpp b/TbAlgorithms/src/TbVertexTracking.cpp
new file mode 100644
index 0000000..79b0208
--- /dev/null
+++ b/TbAlgorithms/src/TbVertexTracking.cpp
@@ -0,0 +1,607 @@
+#include <algorithm>
+#include <fstream>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbVertexTracking.h"
+
+DECLARE_ALGORITHM_FACTORY(TbVertexTracking)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbVertexTracking::TbVertexTracking(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_tracks(nullptr),
+      m_trackFit(nullptr),
+      m_clusterFinder(nullptr),
+      m_event(0) {
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("TrackFitTool", m_trackFitTool = "TbTrackFit");
+
+  declareProperty("TimeWindow", m_twindow = 150. * Gaudi::Units::ns);
+  declareProperty("MinNClusters", m_MinNClusters = 7);
+  declareProperty("SearchVolumeFillAlgorithm",
+                  m_ClusterFinderSearchAlgorithm = "adap_seq");
+  declareProperty("SearchPlanes", m_PlaneSearchOrder = {4, 3, 5});
+  declareProperty("ClusterSizeCut", m_clusterSizeCut = 1000);
+  declareProperty("MinNClustersRepeat", m_MinNClustersRepeat = 3);
+  declareProperty("RadialCut", m_radialCut = 0.2);
+
+  declareProperty("ViewerOutput", m_viewerOutput = false);
+  declareProperty("ViewerEventNum", m_viewerEvent = 100);
+  declareProperty("CombatRun", m_combatRun = false);
+  declareProperty("MaxChi2", m_ChiSqRedCut = 200.);
+  declareProperty("DoVertexting", m_doVertexting = false);
+  declareProperty("DoRepeat", m_doRepeat = true);
+  declareProperty("AngleCut", m_angleCut = 0.2);
+
+  declareProperty("VertexDelR", m_vertexDelR = 0.1);
+  declareProperty("VertexDelT", m_vertexDelT = 10);
+  m_currentAngleCut = m_angleCut;
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbVertexTracking::~TbVertexTracking() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbVertexTracking::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>(m_trackFitTool, "Fitter", this);
+  if (!m_trackFit) return Error("Cannot retrieve track fit tool.");
+  // Set up the cluster finder.
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+  if (!m_clusterFinder) return Error("Cannot retrieve cluster finder tool.");
+  m_endCluster.resize(m_nPlanes);
+  m_vertexedCluster.resize(m_nPlanes);
+  m_volumed.resize(m_nPlanes);
+  initialStateVsFitStateTx =
+      book2D("initialStateVsFitStateTx", "initialStateVsFitStateTx", -0.001,
+             0.001, 200, -0.001, 0.001, 200);
+  initialStateVsFitStateTy =
+      book2D("initialStateVsFitStateTy", "initialStateVsFitStateTy", -0.001,
+             0.001, 200, -0.001, 0.001, 200);
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbVertexTracking::execute() {
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (m_event == m_viewerEvent && m_viewerOutput) {
+      std::ofstream myfile;
+      myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat");
+      myfile << "# Output\n";
+      myfile.close();
+    }
+
+    const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    if (!clusters) {
+      error() << "No clusters in " << clusterLocation << endmsg;
+      return StatusCode::FAILURE;
+    }
+    m_endCluster[i].clear();
+    m_endCluster[i].resize(clusters->size(), false);
+    m_vertexedCluster[i].clear();
+    m_vertexedCluster[i].resize(clusters->size(), false);
+    m_volumed[i].clear();
+    m_volumed[i].resize(clusters->size(), false);
+    // Store the cluster iterators in the cluster finder.
+    m_clusterFinder->setClusters(clusters, i);
+  }
+
+  // Check if there is already a track container.
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!m_tracks) {
+    // Create a track container and transfer its ownership to the TES.
+    m_tracks = new LHCb::TbTracks();
+    put(m_tracks, m_trackLocation);
+  }
+  m_vertices = new LHCb::TbVertices();
+  put(m_vertices, LHCb::TbVertexLocation::Default);
+
+  // Advantagous to filter out the thin tracks.
+  m_currentAngleCut = 0.01;
+  performVertexTracking();
+  m_currentAngleCut = m_angleCut;
+  performVertexTracking();
+
+  if (m_doRepeat) {
+    // Allow lower demands on track size.
+    unsigned int tempSizeHolder = m_MinNClusters;
+    m_MinNClusters = m_MinNClustersRepeat;
+    performVertexTracking();
+    m_MinNClusters = tempSizeHolder;
+  }
+
+  timeOrderTracks();
+
+  if (m_doVertexting) collectIntoVertices();
+  /*
+  LHCb::TbTracks::iterator itrack;
+  for (itrack = m_tracks->begin(); itrack < m_tracks->end() - 1; itrack++) {
+    plot((*(itrack + 1))->htime() - (*itrack)->htime(), "TimeBetweenTracks",
+         "TimeBetweenTracks", 0.0, 5000, 500);
+  }
+  */
+  counter("NumberOfTracks") += m_tracks->size();
+  counter("NumberOfVertices") += m_vertices->size();
+  if (m_event == m_viewerEvent && m_viewerOutput) outputViewerData();
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+void TbVertexTracking::collectIntoVertices() {
+  // Iterate over tracks.
+  LHCb::TbVertex* tempVertex = nullptr;
+  LHCb::TbTracks::iterator itrack;
+  for (itrack = m_tracks->begin(); itrack < m_tracks->end(); itrack++) {
+    tempVertex = nullptr;
+    if ((*itrack)->vertexed()) continue;
+    LHCb::TbTracks::iterator jtrack;
+    for (jtrack = itrack; jtrack < m_tracks->end(); jtrack++) {
+      if ((*jtrack)->vertexed() || itrack == jtrack) continue;
+
+      // Check time difference.
+      if (fabs((*itrack)->htime() - (*jtrack)->htime()) < m_vertexDelT) {
+        // Assume decay happened near a detector.
+        for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+          // Work out the spatial separation.
+          Gaudi::XYZPoint intercept1 = geomSvc()->intercept((*itrack), iplane);
+          Gaudi::XYZPoint intercept2 = geomSvc()->intercept((*jtrack), iplane);
+          double delr2 = pow(intercept1.x() - intercept2.x(), 2);
+          delr2 += pow(intercept1.y() - intercept2.y(), 2);
+          if (pow(delr2, 0.5) < m_vertexDelR) {
+
+            // We have a vertex, although should also add some cluster counting.
+            if (tempVertex == nullptr) {
+              tempVertex = new LHCb::TbVertex();
+              tempVertex->addToTracks(*itrack);
+              (*itrack)->setVertexed(true);
+              tempVertex->setX(intercept1.x());
+              tempVertex->setY(intercept1.y());
+              tempVertex->setZ(intercept1.z());
+              tempVertex->setHtime((*itrack)->htime());
+              tempVertex->setInteractionPlane(iplane);
+
+              SmartRefVector<LHCb::TbCluster>& clusters =
+                  const_cast<SmartRefVector<LHCb::TbCluster>&>(
+                      (*itrack)->clusters());
+              for (unsigned int i = 0; i < clusters.size(); i++) {
+                m_vertexedCluster[clusters[i]->plane()][clusters[i]->key()] =
+                    true;
+                unsigned int plane = clusters[i]->plane();
+                if (plane == 0 || plane == 1 || plane == 2)
+                  (*itrack)->setParentVertex(true);
+              }
+            }
+
+            tempVertex->addToTracks(*jtrack);
+            (*jtrack)->setVertexed(true);
+            SmartRefVector<LHCb::TbCluster>& clusters =
+                const_cast<SmartRefVector<LHCb::TbCluster>&>(
+                    (*jtrack)->clusters());
+            for (unsigned int i = 0; i < clusters.size(); i++) {
+              m_vertexedCluster[clusters[i]->plane()][clusters[i]->key()] =
+                  true;
+              unsigned int plane = clusters[i]->plane();
+              if (plane == 0 || plane == 1 || plane == 2)
+                (*jtrack)->setParentVertex(true);
+            }
+            break;
+          }
+        }
+      }
+      if ((*jtrack)->htime() - (*itrack)->htime() > m_vertexDelT) break;
+    }
+    if (tempVertex != nullptr) m_vertices->insert(tempVertex);
+  }
+
+  // Remove tracks forming vertices from m_tracks.
+  LHCb::TbVertices::iterator ivertex;
+  for (ivertex = m_vertices->begin(); ivertex != m_vertices->end(); ivertex++) {
+    SmartRefVector<LHCb::TbTrack>& tracks =
+        const_cast<SmartRefVector<LHCb::TbTrack>&>((*ivertex)->tracks());
+    for (unsigned int i = 0; i < tracks.size(); i++)
+      m_tracks->remove(tracks[i]);
+  }
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+void TbVertexTracking::performVertexTracking() {
+  // Iterate over search planes.
+  for (const auto& plane : m_PlaneSearchOrder) {
+
+    if (masked(plane) || m_clusterFinder->empty(plane)) continue;
+    auto ic = m_clusterFinder->first(plane);
+    const auto end = m_clusterFinder->end(plane);
+    for (; ic != end; ++ic) {
+      // Check if too big, and if already tracked.
+      if ((*ic)->size() > m_clusterSizeCut) continue;
+      if ((*ic)->associated() && !m_endCluster[plane][(*ic)->key()]) continue;
+      formTrack(*ic);
+    }
+  }
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+void TbVertexTracking::evalHoughState(LHCb::TbCluster* seed,
+                                      LHCb::TbCluster* cluster2,
+                                      LHCb::TbState* tempInitialState) {
+  if (m_event == m_viewerEvent && m_viewerOutput)
+    outputHoughState(seed, cluster2);
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+  track->addToClusters(seed);
+  track->addToClusters(cluster2);
+  track->setFirstState(*tempInitialState);
+  bool sizeSuitable = fillTrack(track, seed, cluster2);
+  if (!sizeSuitable) {
+    counter("NumberOfSizeRejectedTracks") += 1;
+    delete track;
+  } else {
+    m_trackFit->fit(track);
+    initialStateVsFitStateTx->fill(track->firstState().tx(),
+                                   tempInitialState->tx());
+    initialStateVsFitStateTy->fill(track->firstState().ty(),
+                                   tempInitialState->ty());
+    plot(track->firstState().tx() - tempInitialState->tx(),
+         "initialStateMinusFittedStateX", "initialStateMinusFittedStateX",
+         -0.005, 0.005, 200);
+
+    // Consider popping one clusters if its going to fail.
+    int popID = -1;
+    double chi = track->chi2PerNdof();
+    if (track->clusters().size() > m_MinNClusters + 1 &&
+        track->chi2PerNdof() > m_ChiSqRedCut) {
+      for (unsigned int i = 0; i < m_nPlanes; i++) {
+        m_trackFit->maskPlane(i);
+        m_trackFit->fit(track);
+        if (track->chi2PerNdof() < chi) {
+          chi = track->chi2PerNdof();
+          popID = i;
+        }
+        m_trackFit->unmaskPlane(i);
+      }
+      if (popID != -1) {
+        for (auto cluster : track->clusters()) {
+          if (int(cluster->plane()) == popID) {
+            track->removeFromClusters(cluster);
+          }
+        }
+      }
+      m_trackFit->fit(track);
+      if (track->chi2PerNdof() < m_ChiSqRedCut)
+        counter("NumberOfPopRecoveredTracks") += 1;
+    }
+
+    if (track->chi2PerNdof() < m_ChiSqRedCut) {
+      SmartRefVector<LHCb::TbCluster>& clusters =
+          const_cast<SmartRefVector<LHCb::TbCluster>&>(track->clusters());
+      auto earliest_hit =
+          std::min_element(clusters.begin(), clusters.end(),
+                           TbFunctors::LessByTime<const LHCb::TbCluster*>());
+
+      if (timingSvc()->beforeOverlap((*earliest_hit)->time()) || m_combatRun) {
+        auto farthest_hit =
+            std::max_element(clusters.begin(), clusters.end(),
+                             TbFunctors::LessByZ<const LHCb::TbCluster*>());
+        if ((*farthest_hit)->plane() != m_nPlanes - 1) {
+          m_endCluster[(*farthest_hit)->plane()][(*farthest_hit)->key()] = true;
+        }
+        auto nearest_hit =
+            std::min_element(clusters.begin(), clusters.end(),
+                             TbFunctors::LessByZ<const LHCb::TbCluster*>());
+        if ((*nearest_hit)->plane() != 0) {
+          m_endCluster[(*nearest_hit)->plane()][(*nearest_hit)->key()] = true;
+        }
+
+        m_tracks->insert(track);
+        track->setTime(timingSvc()->localToGlobal(track->htime()));
+        track->setAssociated(true);
+      }
+    } else {
+      delete track;
+      counter("NumberOfChiRejectedTracks") += 1;
+    }
+  }
+}
+
+//=============================================================================
+//
+//=============================================================================
+bool TbVertexTracking::fillTrack(LHCb::TbTrack* track,
+                                 LHCb::TbCluster* seedCluster,
+                                 LHCb::TbCluster* cluster2) {
+  unsigned int nAllowedGaps = m_nPlanes - m_MinNClusters;
+  unsigned int nGaps = 0;
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    bool foundCluster = false;
+    if (m_clusterFinder->empty(iplane) || masked(iplane) ||
+        iplane == seedCluster->plane() || iplane == cluster2->plane()) {
+      // nGaps++;
+      continue;
+    }
+    auto ic =
+        m_clusterFinder->getIterator(seedCluster->htime() - m_twindow, iplane);
+    const auto end = m_clusterFinder->end(iplane);
+    for (; ic != end; ++ic) {
+      if ((*ic)->size() > m_clusterSizeCut) continue;
+      Gaudi::XYZPoint intercept = geomSvc()->intercept(track, iplane);
+      double delr2 = pow(intercept.y() - (*ic)->y(), 2);
+      delr2 += pow(intercept.x() - (*ic)->x(), 2);
+
+      plot(intercept.x() - (*ic)->x(), "initialResidualX", "initialResidualX",
+           -0.05, 0.05, 200);
+      plot(intercept.y() - (*ic)->y(), "initialResidualY", "initialResidualY",
+           -0.05, 0.05, 200);
+
+      if (m_event == m_viewerEvent && m_viewerOutput)
+        outputPatternRecog(intercept.x(), intercept.y(), intercept.z(),
+                           seedCluster->htime());
+
+      if (pow(delr2, 0.5) < m_radialCut) {
+        if (!(*ic)->associated() ||
+            m_endCluster[(*ic)->plane()][(*ic)->key()]) {
+          m_volumed[(*ic)->plane()][(*ic)->key()] = true;
+          track->addToClusters(*ic);
+          m_trackFit->fit(track);
+          foundCluster = true;
+          break;
+        }
+      }
+      if ((*ic)->htime() > seedCluster->htime() + m_twindow) break;
+    }
+    if (!foundCluster) nGaps++;
+    if (nGaps == nAllowedGaps) return false;
+  }
+  if (track->clusters().size() < m_MinNClusters) return false;
+  return true;
+}
+
+//=============================================================================
+//
+//=============================================================================
+void TbVertexTracking::formTrack(LHCb::TbCluster* seedCluster) {
+  bool madeTrack = false;
+  // Form pairs of clusters from either side of seed plane.
+  // Eval each pair as its formed.
+  for (unsigned int iplane = seedCluster->plane() - 1;
+       iplane != seedCluster->plane() + 2; iplane++) {
+    if (m_clusterFinder->empty(iplane) || iplane == seedCluster->plane() ||
+        masked(iplane))
+      continue;
+    auto ic =
+        m_clusterFinder->getIterator(seedCluster->htime() - m_twindow, iplane);
+    const auto end = m_clusterFinder->end(iplane);
+    for (; ic != end; ++ic) {
+
+      // Find the gradients between the pair.
+      if ((*ic)->size() > m_clusterSizeCut || (*ic)->associated()) continue;
+      double tx =
+          (seedCluster->x() - (*ic)->x()) / (seedCluster->z() - (*ic)->z());
+      double ty =
+          (seedCluster->y() - (*ic)->y()) / (seedCluster->z() - (*ic)->z());
+      double x0 = seedCluster->x() - tx * seedCluster->z();
+      double y0 = seedCluster->y() - ty * seedCluster->z();
+      Gaudi::SymMatrix4x4 cov;
+      LHCb::TbState fstate(Gaudi::Vector4(x0, y0, tx, ty), cov, 0., 0);
+      plot(tx, "initialTx", "initialTx", -0.1, 0.1, 200);
+      plot(ty, "initialTy", "initialTy", -0.1, 0.1, 200);
+
+      counter("NumberOfFormedHoughStates") += 1;
+      if (fabs(tx) < 0.01 && fabs(ty) < 0.01) counter("nThinStates") += 1;
+      if (fabs(tx) < m_currentAngleCut && fabs(ty) < m_currentAngleCut) {
+        evalHoughState(seedCluster, (*ic), &fstate);
+        if (seedCluster->associated() &&
+            !m_endCluster[seedCluster->plane()][seedCluster->key()]) {
+          madeTrack = true;
+          break;
+        }
+      } else
+        counter("nAngleCutStates") += 1;
+      if ((*ic)->htime() > seedCluster->htime() + m_twindow) break;
+    }
+    if (madeTrack) break;
+  }
+}
+
+//=============================================================================
+// Viewer outputs
+//=============================================================================
+void TbVertexTracking::outputVertices() {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  for (LHCb::TbVertex* vertex : *m_vertices) {
+    myfile << "Vertex " << vertex->x() << " " << vertex->y() << " "
+           << vertex->z() << " " << vertex->htime() << " "
+           << vertex->tracks().size() << " ";
+    for (unsigned int i = 0; i < vertex->tracks().size(); i++) {
+      myfile << vertex->tracks()[i]->firstState().tx() << " "
+             << vertex->tracks()[i]->firstState().x() << " "
+             << vertex->tracks()[i]->firstState().ty() << " "
+             << vertex->tracks()[i]->firstState().y() << " ";
+      if (vertex->tracks()[i]->parentVertex())
+        myfile << "1 ";
+      else
+        myfile << "0 ";
+    }
+    myfile << "\n";
+  }
+  myfile.close();
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVertexTracking::outputPatternRecog(double x, double y, double z,
+                                          double ht) {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  myfile << "PatternRecogCircle " << x << " " << y << " " << z << " " << ht
+         << " " << m_radialCut << "\n";
+  myfile.close();
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVertexTracking::outputHoughState(LHCb::TbCluster* c1,
+                                        LHCb::TbCluster* c2) {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  myfile << "HoughState " << c1->x() << " " << c1->y() << " " << c1->z() << " "
+         << c2->x() << " " << c2->y() << " " << c2->z() << " " << c1->htime()
+         << " " << c2->htime() << " \n";
+  myfile.close();
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVertexTracking::outputViewerData() {
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat",
+              std::ofstream::app);
+  // First output the chips.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    myfile << "Chip ";
+    Gaudi::XYZPoint posn1(0., 14.08, 0.);
+    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+    posn = geomSvc()->localToGlobal(posn2, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+    posn = geomSvc()->localToGlobal(posn3, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn4(0., 0., 0.);
+    posn = geomSvc()->localToGlobal(posn4, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+    myfile << "\n";
+  }
+
+  // Tracks.
+  for (LHCb::TbTrack* track : *m_tracks) {
+    myfile << "Track " << track->firstState().tx() << " "
+           << track->firstState().x() << " " << track->firstState().ty() << " "
+           << track->firstState().y() << " " << track->htime() << "\n";
+  }
+
+  // Clusters.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const auto end = m_clusterFinder->end(i);
+    for (auto it = m_clusterFinder->first(i); it != end; ++it) {
+      myfile << "Cluster " << (*it)->x() << " " << (*it)->y() << " "
+             << (*it)->z() << " " << (*it)->htime() << " ";
+      const bool endCluster = m_endCluster[(*it)->plane()][(*it)->key()];
+      const bool vertexed = m_vertexedCluster[(*it)->plane()][(*it)->key()];
+      if (endCluster && vertexed) {
+        myfile << "5 \n";
+      } else if (vertexed) {
+        myfile << "4 \n";
+      } else if (endCluster) {
+        myfile << "3 \n";
+      } else if ((*it)->associated()) {
+        myfile << "2 \n";
+      } else if (m_volumed[(*it)->plane()][(*it)->key()]) {
+        myfile << "1 \n";
+      } else {
+        myfile << "0 \n";
+      }
+
+      // Its hits.
+      for (auto hit : (*it)->hits()) {
+        myfile << "Pixel ";
+        double xLocal = 0.;
+        double yLocal = 0.;
+        geomSvc()->pixelToPoint(hit->scol(), hit->row(), i, xLocal, yLocal);
+        Gaudi::XYZPoint pLocal(xLocal - 0.5 * Tb::PixelPitch,
+                               yLocal - 0.5 * Tb::PixelPitch, 0.);
+        Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        Gaudi::XYZPoint posn2(pLocal.x() + 0.055, pLocal.y(), 0.);
+        posn = geomSvc()->localToGlobal(posn2, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        Gaudi::XYZPoint posn3(pLocal.x() + 0.055, pLocal.y() + 0.055, 0.);
+        posn = geomSvc()->localToGlobal(posn3, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y() + 0.055, 0.);
+        posn = geomSvc()->localToGlobal(posn4, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+        myfile << hit->htime() << " " << hit->ToT() << "\n";
+      }
+    }
+  }
+  myfile.close();
+  outputVertices();
+}
+
+//=============================================================================
+// Track time ordering - honeycomb
+//=============================================================================
+void TbVertexTracking::timeOrderTracks() {
+
+  const double s_factor = 1.3;
+  LHCb::TbTrack* track1;
+  LHCb::TbTrack* track2;
+  unsigned int gap = m_tracks->size() / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    LHCb::TbTracks::iterator itt;
+    for (itt = m_tracks->begin(); itt < m_tracks->end() - gap; ++itt) {
+      track1 = *itt;
+      track2 = *(itt + gap);
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        std::iter_swap(itt, itt + gap);
+        swapped = true;
+      }
+    }
+  }
+}
diff --git a/TbAlgorithms/src/TbVertexTracking.h b/TbAlgorithms/src/TbVertexTracking.h
new file mode 100644
index 0000000..bb317e6
--- /dev/null
+++ b/TbAlgorithms/src/TbVertexTracking.h
@@ -0,0 +1,82 @@
+#ifndef TB_VERTEXTRACKING_H
+#define TB_VERTEXTRACKING_H 1
+
+// AIDA
+#include "AIDA/IHistogram2D.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+#include "Event/TbVertex.h"
+
+/** @class TbVertexTracking TbVertexTracking.h
+ *
+ *  Algorithm for tracks with vertices reconstruction
+ *
+ * @author Dan Saunders
+ */
+
+class TbVertexTracking : public TbAlgorithm {
+ public:
+  TbVertexTracking(const std::string &name, ISvcLocator *pSvcLocator);
+  virtual ~TbVertexTracking();
+  virtual StatusCode initialize();
+  virtual StatusCode execute();
+
+ private:
+  LHCb::TbTracks *m_tracks;
+  LHCb::TbVertices *m_vertices;
+
+  /// Name of the track fit tool
+  std::string m_trackFitTool;
+  /// Track fit tool
+  ITbTrackFit *m_trackFit;
+  ITbClusterFinder *m_clusterFinder;
+  std::string m_clusterLocation;
+  std::string m_trackLocation;
+  std::vector<std::vector<bool> > m_endCluster;
+  std::vector<std::vector<bool> > m_vertexedCluster;
+  std::vector<std::vector<bool> > m_volumed;
+
+  double m_twindow;
+  unsigned int m_MinNClusters;
+  unsigned int m_MinNClustersRepeat;
+  double m_ChiSqRedCut;
+  std::string m_ClusterFinderSearchAlgorithm;
+  std::vector<unsigned int> m_PlaneSearchOrder;
+  unsigned int m_clusterSizeCut;
+
+  bool m_viewerOutput;
+  unsigned int m_viewerEvent;
+  unsigned int m_event;
+  bool m_combatRun;
+  double m_radialCut;
+  bool m_doVertexting;
+  bool m_doRepeat;
+  double m_angleCut;
+  double m_currentAngleCut;
+  double m_vertexDelR;
+  double m_vertexDelT;
+
+  // Historgrams ______________________________________________________________
+  AIDA::IHistogram2D *initialStateVsFitStateTx;
+  AIDA::IHistogram2D *initialStateVsFitStateTy;
+
+  // Methods __________________________________________________________________
+  bool fillTrack(LHCb::TbTrack *, LHCb::TbCluster *, LHCb::TbCluster *);
+  void evalHoughState(LHCb::TbCluster *, LHCb::TbCluster *, LHCb::TbState *);
+  void outputViewerData();
+  void performVertexTracking();
+  void timeOrderTracks();
+  void formTrack(LHCb::TbCluster *);
+  void outputPatternRecog(double, double, double, double);
+  void outputHoughState(LHCb::TbCluster *, LHCb::TbCluster *);
+  void collectIntoVertices();
+  void outputVertices();
+};
+#endif
diff --git a/TbAlgorithms/src/TbVisualiserOutput.cpp b/TbAlgorithms/src/TbVisualiserOutput.cpp
new file mode 100644
index 0000000..0fae00e
--- /dev/null
+++ b/TbAlgorithms/src/TbVisualiserOutput.cpp
@@ -0,0 +1,142 @@
+#include <fstream>
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbVisualiserOutput.h"
+
+DECLARE_ALGORITHM_FACTORY(TbVisualiserOutput)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbVisualiserOutput::TbVisualiserOutput(const std::string& name,
+                                       ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator), m_event(0) {
+  declareProperty("ViewerEvent", m_viewerEvent = 7);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbVisualiserOutput::~TbVisualiserOutput() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbVisualiserOutput::initialize() {
+
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  m_clusterFinder =
+      tool<ITbClusterFinder>("TbClusterFinder", "ClusterFinder", this);
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbVisualiserOutput::execute() {
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!m_tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  if (m_event == m_viewerEvent) {
+
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      const std::string clusterLocation = m_clusterLocation + std::to_string(i);
+      LHCb::TbClusters* clusters =
+          getIfExists<LHCb::TbClusters>(clusterLocation);
+      m_clusterFinder->setClusters(clusters, i);
+    }
+    outputViewerData();
+  }
+
+  m_event++;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Viewer output
+//=============================================================================
+void TbVisualiserOutput::outputViewerData() {
+  std::ofstream myfile;
+  myfile.open("KeplerViewerData.dat", std::ofstream::app);
+  myfile << "# Output\n";
+  // First output the chips.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    myfile << "Chip ";
+    Gaudi::XYZPoint posn1(0., 14.08, 0.);
+    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+    posn = geomSvc()->localToGlobal(posn2, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+    posn = geomSvc()->localToGlobal(posn3, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    Gaudi::XYZPoint posn4(0., 0., 0.);
+    posn = geomSvc()->localToGlobal(posn4, i);
+    myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+
+    myfile << "\n";
+  }
+  // Tracks.
+  for (const LHCb::TbTrack* track : *m_tracks) {
+    myfile << "Track ";
+    myfile << track->firstState().tx() << " " << track->firstState().x() << " "
+           << track->firstState().ty() << " " << track->firstState().y() << " "
+           << track->htime() << "\n";
+  }
+  // Clusters.
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    auto ic = m_clusterFinder->first(i);
+    const auto end = m_clusterFinder->end(i);
+    for (; ic != end; ++ic) {
+      const int tag = (*ic)->associated();
+      myfile << "Cluster ";
+      myfile << (*ic)->x() << " " << (*ic)->y() << " " << (*ic)->z() << " "
+             << (*ic)->htime() << " " << tag << " \n";
+      // Its hits.
+      for (const auto hit : (*ic)->hits()) {
+        myfile << "Pixel ";
+        double xLocal = 0.;
+        double yLocal = 0.;
+        geomSvc()->pixelToPoint(hit->scol(), hit->row(), i, xLocal, yLocal);
+        Gaudi::XYZPoint pLocal(xLocal - 0.5 * Tb::PixelPitch,
+                               yLocal - 0.5 * Tb::PixelPitch, 0.);
+        Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn2(pLocal.x() + Tb::PixelPitch, pLocal.y(), 0.);
+        posn = geomSvc()->localToGlobal(posn2, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn3(pLocal.x() + Tb::PixelPitch,
+                              pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn3, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y() + Tb::PixelPitch, 0.);
+        posn = geomSvc()->localToGlobal(posn4, i);
+        myfile << posn.x() << " " << posn.y() << " " << posn.z() << " ";
+        myfile << hit->htime() << " " << hit->ToT() << "\n";
+      }
+    }
+  }
+  myfile.close();
+}
diff --git a/TbAlgorithms/src/TbVisualiserOutput.h b/TbAlgorithms/src/TbVisualiserOutput.h
new file mode 100644
index 0000000..059240a
--- /dev/null
+++ b/TbAlgorithms/src/TbVisualiserOutput.h
@@ -0,0 +1,36 @@
+#ifndef TB_VISUALISEROUTPUT_H
+#define TB_VISUALISEROUTPUT_H 1
+
+// Tb/TbKernel
+#include "TbKernel/ITbClusterFinder.h"
+#include "TbKernel/TbAlgorithm.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+/** @class TbVisualiserOutput TbVisualiserOutput.h
+ * @author Dan Saunders
+ */
+
+class TbVisualiserOutput : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbVisualiserOutput(const std::string &name, ISvcLocator *pSvcLocator);
+  /// Destructor
+  virtual ~TbVisualiserOutput();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  LHCb::TbTracks *m_tracks;
+  ITbClusterFinder *m_clusterFinder;
+  std::string m_clusterLocation;
+  std::string m_trackLocation;
+
+  unsigned int m_viewerEvent;
+  unsigned int m_event;
+
+  void outputViewerData();
+};
+#endif
diff --git a/TbAlignment/.svn/all-wcprops b/TbAlignment/.svn/all-wcprops
new file mode 100644
index 0000000..234308b
--- /dev/null
+++ b/TbAlignment/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/guest/lhcb/!svn/ver/205735/Kepler/trunk/Tb/TbAlignment
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/196752/Kepler/trunk/Tb/TbAlignment/CMakeLists.txt
+END
diff --git a/TbAlignment/.svn/entries b/TbAlignment/.svn/entries
new file mode 100644
index 0000000..04f3aa0
--- /dev/null
+++ b/TbAlignment/.svn/entries
@@ -0,0 +1,71 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlignment
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-05-06T11:53:49.381857Z
+205735
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+src
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+92f80cd741adf3f5e0f552f9ecbdddfe
+2015-10-24T15:51:04.007127Z
+196752
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+560
+
diff --git a/TbAlignment/.svn/text-base/CMakeLists.txt.svn-base b/TbAlignment/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..f714524
--- /dev/null
+++ b/TbAlignment/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,16 @@
+################################################################################
+# Package: TbAlignment
+################################################################################
+gaudi_subdir(TbAlignment v1r0)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS Minuit MathCore GenVector)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbAlignment
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbAlignment/CMakeLists.txt b/TbAlignment/CMakeLists.txt
new file mode 100644
index 0000000..f714524
--- /dev/null
+++ b/TbAlignment/CMakeLists.txt
@@ -0,0 +1,16 @@
+################################################################################
+# Package: TbAlignment
+################################################################################
+gaudi_subdir(TbAlignment v1r0)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS Minuit MathCore GenVector)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbAlignment
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbAlignment/cmt/.svn/all-wcprops b/TbAlignment/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..77be88d
--- /dev/null
+++ b/TbAlignment/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/guest/lhcb/!svn/ver/190737/Kepler/trunk/Tb/TbAlignment/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/190737/Kepler/trunk/Tb/TbAlignment/cmt/requirements
+END
diff --git a/TbAlignment/cmt/.svn/entries b/TbAlignment/cmt/.svn/entries
new file mode 100644
index 0000000..732bf68
--- /dev/null
+++ b/TbAlignment/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlignment/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-06-23T16:42:50.573067Z
+190737
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+a889ac58ba9f99bcb83cc27e50b6a0c7
+2015-06-23T16:42:50.573067Z
+190737
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+723
+
diff --git a/TbAlignment/cmt/.svn/text-base/requirements.svn-base b/TbAlignment/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..dd5bb7e
--- /dev/null
+++ b/TbAlignment/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,21 @@
+package TbAlignment
+version v1r0
+
+branches          cmt doc src
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+use  Boost        v*  LCG_Interfaces
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbAlignment    ../src/*.cpp -import=AIDA
+apply_pattern    component_library library=TbAlignment
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append Boost_linkopts $(Boost_linkopts_iostreams)
+macro_append ROOT_linkopts " -lMinuit -lHist -lPhysics"
+
diff --git a/TbAlignment/cmt/requirements b/TbAlignment/cmt/requirements
new file mode 100644
index 0000000..dd5bb7e
--- /dev/null
+++ b/TbAlignment/cmt/requirements
@@ -0,0 +1,21 @@
+package TbAlignment
+version v1r0
+
+branches          cmt doc src
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+use  Boost        v*  LCG_Interfaces
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbAlignment    ../src/*.cpp -import=AIDA
+apply_pattern    component_library library=TbAlignment
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append Boost_linkopts $(Boost_linkopts_iostreams)
+macro_append ROOT_linkopts " -lMinuit -lHist -lPhysics"
+
diff --git a/TbAlignment/doc/.svn/all-wcprops b/TbAlignment/doc/.svn/all-wcprops
new file mode 100644
index 0000000..a1729b3
--- /dev/null
+++ b/TbAlignment/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/guest/lhcb/!svn/ver/197093/Kepler/trunk/Tb/TbAlignment/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197093/Kepler/trunk/Tb/TbAlignment/doc/release.notes
+END
diff --git a/TbAlignment/doc/.svn/entries b/TbAlignment/doc/.svn/entries
new file mode 100644
index 0000000..9ef7e63
--- /dev/null
+++ b/TbAlignment/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlignment/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-01T22:22:30.088045Z
+197093
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+4118a9d079594da53c4a3589e427b7fb
+2015-11-01T22:22:30.088045Z
+197093
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1446
+
diff --git a/TbAlignment/doc/.svn/text-base/release.notes.svn-base b/TbAlignment/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..5050307
--- /dev/null
+++ b/TbAlignment/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,41 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbAlignment
+! Responsible : 
+! Purpose     : Algorithms for testbeam alignment
+!-----------------------------------------------------------------------------
+
+! 2015-11-02 - Heinrich Schindler
+ - Re-include isEdge function in TbAlignmentBase.
+ - Enclose fcn in namespace. Prettify monitoring output.
+ 
+! 2015-10-28 - Heinrich Schindler
+ - Remove TbAlignmentMinuit3 and TbAlignmentDeviceSurvey (functionality is now
+   included in TbAlignmentMinuit2).
+
+! 2015-10-28 - Tim Evans
+ - Merge TbAlignmentMinuit2, TbAlignmentMinuit3, and TbAlignmentDeviceSurvey.
+
+! 2015-10-21 - Heinrich Schindler
+ - Rewrite parts of TbMillepede to improve readability.
+
+! 2015-10-17 - Heinrich Schindler
+ - Remove duplicated property MaxChi2 from TbMillepede.
+ - Fix compiler warnings.
+
+! 2015-07-21 - Heinrich Schindler
+ - Tidy up. 
+
+! 2015-07-16  - Tim Evans
+ - Fixes in Millepede, fixed linking errors
+
+! 2015-06-28 - Heinrich Schindler
+ - Tidy up. Adapt "survey" technique to work from within a GaudiTool.
+
+! 2015-06-25 - Heinrich Schindler
+ - Rename files according to standard naming scheme.
+
+! 2015-06-23 - Tim Evans 
+ - First import of alignment algorithms from TbAlgorithms
+ - Split the alignment algorithm between a single meta algorithm that arranges 
+   a sequence of tools, and a collection of alignment tools that can be configured
+   and run in a sequence
diff --git a/TbAlignment/doc/release.notes b/TbAlignment/doc/release.notes
new file mode 100644
index 0000000..5050307
--- /dev/null
+++ b/TbAlignment/doc/release.notes
@@ -0,0 +1,41 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbAlignment
+! Responsible : 
+! Purpose     : Algorithms for testbeam alignment
+!-----------------------------------------------------------------------------
+
+! 2015-11-02 - Heinrich Schindler
+ - Re-include isEdge function in TbAlignmentBase.
+ - Enclose fcn in namespace. Prettify monitoring output.
+ 
+! 2015-10-28 - Heinrich Schindler
+ - Remove TbAlignmentMinuit3 and TbAlignmentDeviceSurvey (functionality is now
+   included in TbAlignmentMinuit2).
+
+! 2015-10-28 - Tim Evans
+ - Merge TbAlignmentMinuit2, TbAlignmentMinuit3, and TbAlignmentDeviceSurvey.
+
+! 2015-10-21 - Heinrich Schindler
+ - Rewrite parts of TbMillepede to improve readability.
+
+! 2015-10-17 - Heinrich Schindler
+ - Remove duplicated property MaxChi2 from TbMillepede.
+ - Fix compiler warnings.
+
+! 2015-07-21 - Heinrich Schindler
+ - Tidy up. 
+
+! 2015-07-16  - Tim Evans
+ - Fixes in Millepede, fixed linking errors
+
+! 2015-06-28 - Heinrich Schindler
+ - Tidy up. Adapt "survey" technique to work from within a GaudiTool.
+
+! 2015-06-25 - Heinrich Schindler
+ - Rename files according to standard naming scheme.
+
+! 2015-06-23 - Tim Evans 
+ - First import of alignment algorithms from TbAlgorithms
+ - Split the alignment algorithm between a single meta algorithm that arranges 
+   a sequence of tools, and a collection of alignment tools that can be configured
+   and run in a sequence
diff --git a/TbAlignment/src/.svn/all-wcprops b/TbAlignment/src/.svn/all-wcprops
new file mode 100644
index 0000000..4c6b319
--- /dev/null
+++ b/TbAlignment/src/.svn/all-wcprops
@@ -0,0 +1,101 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/guest/lhcb/!svn/ver/205735/Kepler/trunk/Tb/TbAlignment/src
+END
+TbAlignmentBase.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/205019/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentBase.cpp
+END
+TbAlignmentBase.h
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/197093/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentBase.h
+END
+TbAlignment.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/197093/Kepler/trunk/Tb/TbAlignment/src/TbAlignment.cpp
+END
+TbAlignment.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197093/Kepler/trunk/Tb/TbAlignment/src/TbAlignment.h
+END
+TbAlignmentMinuit0.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/197185/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuit0.cpp
+END
+TbAlignmentMinuit1.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/197055/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuit1.cpp
+END
+TbAlignmentMinuit2.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/205019/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuit2.cpp
+END
+TbAlignmentMinuit0.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/197185/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuit0.h
+END
+TbAlignmentMinuit1.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/196953/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuit1.h
+END
+TbAlignmentMinuit2.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/205019/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuit2.h
+END
+TbAlignmentSurvey.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/197055/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentSurvey.cpp
+END
+TbAlignmentMinuitBase.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/197185/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuitBase.cpp
+END
+TbMillepede.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/205735/Kepler/trunk/Tb/TbAlignment/src/TbMillepede.cpp
+END
+TbAlignmentSurvey.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/196613/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentSurvey.h
+END
+TbAlignmentMinuitBase.h
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/197185/Kepler/trunk/Tb/TbAlignment/src/TbAlignmentMinuitBase.h
+END
+TbMillepede.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197055/Kepler/trunk/Tb/TbAlignment/src/TbMillepede.h
+END
diff --git a/TbAlignment/src/.svn/entries b/TbAlignment/src/.svn/entries
new file mode 100644
index 0000000..58c9926
--- /dev/null
+++ b/TbAlignment/src/.svn/entries
@@ -0,0 +1,572 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlignment/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-05-06T11:53:49.381857Z
+205735
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbAlignmentBase.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+555c7164d0cba131292775f48983a61c
+2016-04-19T19:58:58.694018Z
+205019
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9872
+
+TbAlignmentBase.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+ee56b0abef1ea3a0045737092ac8af18
+2015-11-01T22:22:30.088045Z
+197093
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2728
+
+TbAlignment.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+e937dbfb3b0121a7f6ebf47ef651b5eb
+2015-11-01T22:22:30.088045Z
+197093
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4971
+
+TbAlignment.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+cccb40b370315d048a88bf214eaf6b3c
+2015-11-01T22:22:30.088045Z
+197093
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1223
+
+TbAlignmentMinuit0.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+7a3329de64eaf3785902afdea05ff8ba
+2015-11-04T10:41:09.903529Z
+197185
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4045
+
+TbAlignmentMinuit1.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+504c649d2d4a6698151658aa59d2ec15
+2015-10-31T19:56:10.654704Z
+197055
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4535
+
+TbAlignmentMinuit2.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+719d12f82a68d1cca3c7c6afdac08bb1
+2016-04-19T19:58:58.694018Z
+205019
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9938
+
+TbAlignmentMinuit0.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+0d613c50c3ad3102214305ae9969beba
+2015-11-04T10:41:09.903529Z
+197185
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+510
+
+TbAlignmentMinuit1.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+2992264c22fafc0698438d3c6ba76442
+2015-10-29T08:39:29.812074Z
+196953
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+511
+
+TbAlignmentMinuit2.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+08bd76c8f4b3bbdf30333c1216c88f73
+2016-04-19T19:58:58.694018Z
+205019
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1016
+
+TbAlignmentSurvey.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+9a0a6163b9f8849f4da0446c9f485b85
+2015-10-31T19:56:10.654704Z
+197055
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2770
+
+TbAlignmentMinuitBase.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+d360ba7bcc991f65866a8acca7614523
+2015-11-04T10:41:09.903529Z
+197185
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4774
+
+TbMillepede.cpp
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+d57f8847e8a2792b2a55234916e094d7
+2016-05-06T11:53:49.381857Z
+205735
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+40276
+
+TbAlignmentSurvey.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+bba2d3c41435a6bbf27587bf30e445b3
+2015-10-22T11:28:21.744746Z
+196613
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+400
+
+TbAlignmentMinuitBase.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+24b802ba73464041e74772d6684d2f6c
+2015-11-04T10:41:09.903529Z
+197185
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+750
+
+TbMillepede.h
+file
+
+
+
+
+2016-05-09T14:27:51.000000Z
+03da098b010ac5d71c0f478dcb91f9ea
+2015-10-31T19:56:10.654704Z
+197055
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4860
+
diff --git a/TbAlignment/src/.svn/prop-base/TbAlignment.cpp.svn-base b/TbAlignment/src/.svn/prop-base/TbAlignment.cpp.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/TbAlignment/src/.svn/prop-base/TbAlignment.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/TbAlignment/src/.svn/prop-base/TbMillepede.cpp.svn-base b/TbAlignment/src/.svn/prop-base/TbMillepede.cpp.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/TbAlignment/src/.svn/prop-base/TbMillepede.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/TbAlignment/src/.svn/prop-base/TbMillepede.h.svn-base b/TbAlignment/src/.svn/prop-base/TbMillepede.h.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/TbAlignment/src/.svn/prop-base/TbMillepede.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/TbAlignment/src/.svn/text-base/TbAlignment.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignment.cpp.svn-base
new file mode 100644
index 0000000..6d6bdc9
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignment.cpp.svn-base
@@ -0,0 +1,137 @@
+#include <fstream>
+
+// Gaudi
+#include "GaudiKernel/IEventProcessor.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbModule.h"
+#include "TbKernel/TbAlignmentTrack.h"
+
+// Local
+#include "TbAlignment.h"
+
+DECLARE_ALGORITHM_FACTORY(TbAlignment)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignment::TbAlignment(const std::string &name, ISvcLocator *pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator), m_lastTrackPrint(0), m_tracks() {
+
+  declareProperty("OutputAlignmentFile", m_outputFile = "Alignment_out.dat");
+  declareProperty("AlignmentTechniques", m_alignmentSequence);
+  declareProperty("NTracks", m_nTracks = 0);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignment::~TbAlignment() {
+
+  // Delete the alignment tracks.
+  for (auto track : m_tracks) {
+    if (track) delete track;
+  }
+  m_tracks.clear();
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbAlignment::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  if (m_alignmentSequence.empty()) {
+    return Error("Alignment sequence is empty.");
+  }
+  unsigned int scounter = 0;
+  for (const auto &toolName : m_alignmentSequence) {
+    info() << "Adding tool " << toolName << endmsg;
+    const std::string name = "s" + std::to_string(scounter++);
+    TbAlignmentBase* newTool = tool<TbAlignmentBase>(toolName, name, this);
+    if (!newTool) return Error("Cannot retrieve tool " + toolName);
+    m_toolChain.push_back(newTool);
+  }
+  m_toolIterator = m_toolChain.begin();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbAlignment::execute() {
+
+  auto currentTool = *m_toolIterator;
+  StatusCode sc = currentTool->execute(m_tracks);
+  if (sc.isFailure()) return sc;
+
+  const unsigned int nTracks = m_tracks.size();
+  if (nTracks - (nTracks % 1000) != m_lastTrackPrint) {
+    m_lastTrackPrint = nTracks - (nTracks % 1000);
+    info() << "Collected " << m_lastTrackPrint << " alignment tracks" << endmsg;
+  }
+  // If requested, stop processing events after a given number of tracks.
+  if (m_nTracks > 0 && nTracks > m_nTracks) {
+    currentTool->plotResiduals(m_tracks, "Before");
+    currentTool->align(m_tracks);
+    currentTool->plotResiduals(m_tracks, "After");
+    ++m_toolIterator;
+    if (m_toolIterator == m_toolChain.end()) {
+      SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+      if (app) app->stopRun();
+      return StatusCode::SUCCESS;
+    }
+    currentTool = *m_toolIterator;
+    // Reset track cache
+    if (currentTool->clearTracks()) {
+      for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+        if (*it) delete *it;
+      }
+      m_tracks.clear();
+      m_lastTrackPrint = 0;
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalization
+//=============================================================================
+StatusCode TbAlignment::finalize() {
+
+  if (m_toolIterator != m_toolChain.end()) {
+    info() << "Event loop terminating before chain completion" << endmsg;
+    (*m_toolIterator)->align(m_tracks);
+  }
+  writeAlignmentFile();
+  // Finalise the base class.
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Save the alignment constants to file
+//=============================================================================
+bool TbAlignment::writeAlignmentFile() {
+  // Write results to output file
+  info() << "Writing alignment output file to " << m_outputFile << endmsg;
+  std::ofstream txtfile(m_outputFile.c_str());
+  if (!txtfile) {
+    error() << "Cannot create file " << m_outputFile << endmsg;
+    return false;
+  }
+  auto modules = geomSvc()->modules();
+  for (auto im = modules.begin(), end = modules.end(); im != end; ++im) {
+    txtfile << (*im)->id() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->x() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->y() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->z() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->rotX() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->rotY() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->rotZ() << std::endl;
+  }
+  txtfile.close();
+  return true;
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignment.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignment.h.svn-base
new file mode 100644
index 0000000..4007aeb
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignment.h.svn-base
@@ -0,0 +1,51 @@
+#ifndef TBALIGNMENT_H
+#define TBALIGNMENT_H 1
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+/** @class TbAlignment TbAlignment.h
+ *
+ *  Algorithm for telescope alignment.
+ *
+ *  @author Angelo Di Canto
+ *  @date   2014-04-22
+ */
+
+class TbAlignmentTrack;
+
+class TbAlignment : public TbAlgorithm {
+
+ public:
+  /// Standard constructor
+  TbAlignment(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbAlignment();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+
+ private:
+  /// Output alignment file
+  std::string m_outputFile;
+  /// Alignment methods to be run
+  std::vector<std::string> m_alignmentSequence;
+  /// For the track counter printout
+  unsigned int m_lastTrackPrint;
+
+  /// Tracks for alignment
+  std::vector<TbAlignmentTrack*> m_tracks;
+  /// Number of alignment tracks after which to stop processsing.
+  unsigned int m_nTracks;
+
+  std::vector<TbAlignmentBase*> m_toolChain;
+  std::vector<TbAlignmentBase*>::iterator m_toolIterator;
+
+  bool writeAlignmentFile();
+};
+
+#endif  // TBALIGNMENT_H
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentBase.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentBase.cpp.svn-base
new file mode 100644
index 0000000..af0ea59
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentBase.cpp.svn-base
@@ -0,0 +1,240 @@
+// ROOT
+#include <TH1D.h>
+#include <TProfile.h>
+#include <TFitResult.h>
+#include <TFitResultPtr.h>
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IProfile1D.h"
+
+// Gaudi
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentBase::TbAlignmentBase(const std::string& type,
+                                 const std::string& name,
+                                 const IInterface* parent)
+    : GaudiHistoTool(type, name, parent),
+      m_trackFit(nullptr),
+      m_geomSvc(nullptr) {
+
+  declareInterface<TbAlignmentBase>(this);
+
+  declareProperty("TrackLocation", 
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("DOFs", m_dofs = {});
+  declareProperty("ClearTracks", m_clearTracks = true);
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+  declareProperty("Monitoring", m_monitoring = false);
+  declareProperty("MaxChi2", m_maxChi2 = 100.);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbAlignmentBase::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiHistoTool::initialize();
+  if (sc.isFailure()) return sc;
+  m_modules = geomSvc()->modules();
+  m_nPlanes = m_modules.size();
+  m_masked.resize(m_nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) m_masked[plane] = true;
+
+  // Set the degrees of freedom.
+  if (m_dofs.size() != 6) {
+    info() << "Using the default degrees of freedom:" << endmsg;
+    if (m_dofsDefault.size() != 6) {
+      // Default DoFs are not defined. Set them.
+      m_dofsDefault = {true, true, false, true, true, true};
+    }
+    m_dofs = m_dofsDefault;
+  } else {
+    info() << "Using the following degrees of freedom:" << endmsg;
+  }
+  // Print the degrees of freedom.
+  const std::vector<std::string> labels = {"Translation X", "Translation Y",
+                                           "Translation Z", "Rotation X",
+                                           "Rotation Y",    "Rotation Z"};
+  for (unsigned int i = 0; i < 6; ++i) {
+    const std::string on = m_dofs[i] ? "ON" : "OFF";
+    info() << format("  %-14s  %-3s", labels[i].c_str(), on.c_str()) << endmsg;
+  }
+
+  // Set up the track fit tool.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  if (!m_trackFit) {
+    return Error("Failed to initialise track fit.");
+  }
+  return StatusCode::SUCCESS;
+}
+
+void TbAlignmentBase::plotResiduals(std::vector<TbAlignmentTrack*>& tracks,
+                                    const std::string& tag) {
+
+  if (!m_monitoring) return;
+  // Book histograms.
+  std::vector<AIDA::IHistogram1D*> hResGlobalX;
+  std::vector<AIDA::IHistogram1D*> hResGlobalY;
+  std::vector<AIDA::IProfile1D*> hResGlobalXvsGlobalX;
+  std::vector<AIDA::IProfile1D*> hResGlobalYvsGlobalY;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = "Plane " + plane;
+    // Distribution of unbiased global x-residuals.
+    std::string name = tag + "/UnbiasedResiduals/GlobalX/Plane" + plane;
+    double low(-0.2);
+    double high(0.2);
+    unsigned int bins(200);
+    hResGlobalX.push_back(book1D(name, title, low, high, bins));
+    // Distribution of unbiased global y-residuals.
+    name = tag + "/UnbiasedResiduals/GlobalY/Plane" + plane;
+    hResGlobalY.push_back(book1D(name, title, low, high, bins));
+    // Profile of unbiased global x-residuals as function of global x.
+    low = -20.;
+    high = 20.;
+    bins = 200;
+    name = "UnbiasedResiduals/GlobalResXvsGlobalX/Plane" + plane;
+    hResGlobalXvsGlobalX.push_back(
+        bookProfile1D(name, title, low, high, bins));
+    // Profile of unbiased global y-residuals as function of global y.
+    name = "UnbiasedResiduals/GlobalResYvsGlobalY/Plane" + plane;
+    hResGlobalYvsGlobalY.push_back(
+        bookProfile1D(name, title, low, high, bins));
+  }
+  std::vector<double> ty(m_nPlanes, 0.);
+  std::vector<double> yty(m_nPlanes, 0.);
+  std::vector<double> y(m_nPlanes, 0.);
+  std::vector<double> yy(m_nPlanes, 0.);
+  std::vector<double> tyty(m_nPlanes, 0.);
+
+  for (auto& at : tracks) {
+    // Get the track object.
+    LHCb::TbTrack* track = at->track();
+    // Loop over the clusters on the track.
+    auto clusters = track->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      const unsigned int plane = (*ic)->plane();
+      const LHCb::TbCluster* cluster = *ic;
+      // Refit the track without this cluster.
+      m_trackFit->maskPlane(plane);
+      m_trackFit->fit(track);
+      // Calculate the global x and y residuals.
+      const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, plane);
+      const auto pLocal = Gaudi::XYZPoint(cluster->xloc(), cluster->yloc(), 0);
+      const auto pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      const double dxug = pGlobal.x() - intercept.x();
+      const double dyug = pGlobal.y() - intercept.y();
+
+      ty[plane] += track->firstState().ty();
+      yty[plane] += track->firstState().ty() * pGlobal.y();
+      y[plane] += pGlobal.y();
+      yy[plane] += pGlobal.y() * pGlobal.y();
+      tyty[plane] += track->firstState().ty() * track->firstState().ty();
+
+      hResGlobalX[plane]->fill(dxug);
+      hResGlobalY[plane]->fill(dyug);
+      hResGlobalXvsGlobalX[plane]->fill(pGlobal.x(), dxug);
+      hResGlobalYvsGlobalY[plane]->fill(pGlobal.y(), dyug);
+      m_trackFit->unmaskPlane(plane);
+    }
+    m_trackFit->fit(track);
+    // Loop over the associated clusters.
+    auto aclusters = track->associatedClusters();
+    for (auto it = aclusters.cbegin(), end = aclusters.cend(); it != end; ++it) {
+      const unsigned int plane = (*it)->plane();
+      // Calculate the global x and y residuals.
+      const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, plane);
+      const auto pLocal = Gaudi::XYZPoint((*it)->xloc(), (*it)->yloc(), 0);
+      const auto pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      const double dxug = pGlobal.x() - intercept.x();
+      const double dyug = pGlobal.y() - intercept.y();
+      hResGlobalX[plane]->fill(dxug);
+      hResGlobalY[plane]->fill(dyug);
+      hResGlobalXvsGlobalX[plane]->fill(pGlobal.x(), dxug);
+      hResGlobalYvsGlobalY[plane]->fill(pGlobal.y(), dyug);
+    }
+  }
+
+  if (msgLevel(MSG::DEBUG)) {
+    const unsigned int nTracks = tracks.size();
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      y[i] /= nTracks;
+      ty[i] /= nTracks;
+      yty[i] /= nTracks;
+      yy[i] /= nTracks;
+      tyty[i] /= nTracks;
+      info() << "Plane " << i << ": Pearson-coefficient = "
+             << (yty[i] - y[i] * ty[i]) /
+                    (sqrt(yy[i] - y[i] * y[i]) *
+                     sqrt(tyty[i] - ty[i] * ty[i])) << endmsg;
+    }
+  }
+  // Fit the residual distributions and print the fit results.
+  const std::string line(85, '-');
+  info() << line << endmsg; 
+  info() << "Plane     Mean X [\u03bcm]       Mean Y [\u03bcm]      "
+         << "Sigma X [\u03bcm]     Sigma Y [\u03bcm]" << endmsg; 
+  info() << line << endmsg; 
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    auto hx = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalX[i]);
+    auto hy = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalY[i]);
+    if (hx->GetEntries() == 0 || hy->GetEntries() == 0) continue;
+    TFitResultPtr rx = hx->Fit("gaus", "QS0");
+    TFitResultPtr ry = hy->Fit("gaus", "QS0");
+    if (!rx.Get() || !ry.Get()) continue;
+    info() << std::setprecision(4);
+    info() << format(" %3u   % 5.3f +/- %4.3f  % 5.3f +/- %4.3f ", i,
+                     1.e3 * rx->Parameter(1), 1.e3 * rx->Error(1),
+                     1.e3 * ry->Parameter(1), 1.e3 * ry->Error(1)) 
+           << format(" %4.3f +/- %4.3f  %4.3f +/- %4.3f", 
+                     1.e3 * rx->Parameter(2), 1.e3 * rx->Error(2),
+                     1.e3 * ry->Parameter(2), 1.e3 * ry->Error(2)) << endmsg; 
+  }
+  // Fit the profiles (x/y residuals vs. global x/y) and print the results.
+  info() << line << endmsg; 
+  info() << "Plane     Slope X [\u03bcm]       Slope Y [\u03bcm]" << endmsg;
+  info() << line << endmsg; 
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    auto xgx = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalXvsGlobalX[i]);
+    auto ygy = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalYvsGlobalY[i]);
+    if (xgx->GetEntries() == 0 || ygy->GetEntries() == 0) continue;
+    TFitResultPtr rbx = xgx->Fit("pol1", "QS0");
+    TFitResultPtr rby = ygy->Fit("pol1", "QS0");
+    if (!rbx.Get() || !rby.Get()) continue;
+    info() << std::setprecision(4);
+    info() << format(" %3u   % 5.3f +/- %4.3f   % 5.3f +/- %4.3f ", i,
+                     1.e3 * rbx->Parameter(1), 1.e3 * rbx->Error(1),
+                     1.e3 * rby->Parameter(1), 1.e3 * rby->Error(1))
+           << endmsg;
+  }
+  info() << line << endmsg; 
+
+}
+
+//=============================================================================
+// Collect alignment tracks (called at each event).
+//=============================================================================
+StatusCode TbAlignmentBase::execute(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  // Get the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  // Add them to the alignment track store.
+  for (LHCb::TbTrack* track : *tracks) {
+    if (track->chi2() > m_maxChi2 || isEdge( track ) ) continue ;  
+    TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
+    alignmentTracks.push_back(alignmentTrack);
+  }
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentBase.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentBase.h.svn-base
new file mode 100644
index 0000000..d3f2e3e
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentBase.h.svn-base
@@ -0,0 +1,88 @@
+#pragma once
+
+
+// Gaudi
+#include "GaudiAlg/GaudiHistoTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/TbAlignmentTrack.h"
+#include "TbKernel/TbModule.h"
+#include "TbKernel/ITbTrackFit.h"
+
+static const InterfaceID IID_TbAlignmentBase("TbAlignmentBase", 1, 0);
+
+class TbAlignmentBase : public GaudiHistoTool {
+
+ public:
+  /// Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_TbAlignmentBase; }
+  /// Constructor
+  TbAlignmentBase(const std::string& type, const std::string& name,
+                  const IInterface* parent);
+  /// Destructor
+  ~TbAlignmentBase() {}
+
+  virtual StatusCode initialize();
+
+  /// Store tracks/clusters to be used for the alignment (called each event).
+  virtual StatusCode execute(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  /// Alignment function (called after enough tracks have been collected).
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks) = 0;
+
+  bool clearTracks() const { return m_clearTracks; }
+  /// Fill monitoring histograms.
+  void plotResiduals(std::vector<TbAlignmentTrack*>& tracks,
+                     const std::string& tag);
+
+ protected:
+  /// TES location of tracks.
+  std::string m_trackLocation;
+  /// Chi2 cut on tracks to be used for alignment 
+  double m_maxChi2;
+  /// Degrees of freedom
+  std::vector<bool> m_dofs;
+  /// Default degrees of freedom
+  std::vector<bool> m_dofsDefault;
+  /// List of masked planes
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+  /// Flag to produce monitoring histograms.
+  bool m_monitoring;
+  /// Flag to reset the track store before collecting alignment tracks.
+  bool m_clearTracks;
+
+  std::vector<TbModule*> m_modules;
+  unsigned int m_nPlanes;
+  /// Track fit tool
+  ITbTrackFit* m_trackFit;
+
+  bool masked(const unsigned int plane) const {
+    return plane < m_masked.size() ? m_masked[plane] : false;
+  }
+
+  /// Pointer to the geometry service.
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// On-demand access to the geometry service.
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+  /// Determine whether a track passes the edge region of a plane.
+  bool isEdge(const LHCb::TbTrack* track) {
+    for (auto cluster : track->clusters()) {
+      if (isEdge(cluster)) return true;
+    }
+    return false;
+  }
+  /// Determine whether a cluster is close to the edge region of a plane.
+  bool isEdge(const LHCb::TbCluster* cluster) {
+    return cluster->xloc() <  0.5 ||
+           cluster->xloc() > 13.5 ||
+           cluster->yloc() < 0.5 ||
+           cluster->yloc() > 13.5 ;
+  }
+
+
+};
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuit0.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit0.cpp.svn-base
new file mode 100644
index 0000000..5ed40c4
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit0.cpp.svn-base
@@ -0,0 +1,100 @@
+#include "TbAlignmentMinuit0.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentMinuit0)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuit0::TbAlignmentMinuit0(const std::string& type,
+                                       const std::string& name,
+                                       const IInterface* parent)
+    : TbAlignmentMinuitBase(type, name, parent) {
+
+  declareProperty("ReferencePlane", m_referencePlane = 999);
+
+  m_dofsDefault = {true, true, false, true, true, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuit0::~TbAlignmentMinuit0() {}
+
+//=============================================================================
+// Calculate the chi2.
+//=============================================================================
+void TbAlignmentMinuit0::chi2(double& f, double* par, double* /*g*/) {
+
+  // Assign new aligment constants
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    (*im)->setAlignment(par[6 * i + 0], par[6 * i + 1], par[6 * i + 2],
+                        par[6 * i + 3], par[6 * i + 4], par[6 * i + 5]);
+  }
+
+  // Loop over tracks
+  f = 0.;
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    // Update global coordinates of the clusters
+    SmartRefVector<LHCb::TbCluster> clusters = (*it)->track()->clusters();
+    for (auto ic = clusters.begin(), end = clusters.end(); ic != end; ++ic) {
+      Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+      const unsigned int plane = (*ic)->plane();
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      (*ic)->setX(pGlobal.x());
+      (*ic)->setY(pGlobal.y());
+      (*ic)->setZ(pGlobal.z());
+    }
+    // Refit track with new cluster positions
+    m_trackFit->fit((*it)->track());
+    // Add the new track chi2 to the overall chi2
+    f += (*it)->track()->chi2();
+  }
+}
+//=============================================================================
+// Main alignment function.
+//=============================================================================
+void TbAlignmentMinuit0::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  TbAlignmentMinuitBase::align(alignmentTracks);
+  info() << "Minuit technique 0" << endmsg;
+  double arglist[2];
+  arglist[0] = 10000;
+  arglist[1] = 1.e-2;
+
+  for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
+    info() << "Iteration " << iteration + 1 << "/" << m_nIterations << endmsg;
+    // Align detector modules one at a time
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      // Skip reference plane and masked planes.
+      if (i == m_referencePlane || masked(i)) continue;
+      // Wobble this plane and fix the others.
+      for (unsigned int j = 0; j < m_nPlanes; ++j) {
+        if (i != j) {
+          m_fitter->FixParameter(6 * j + 0);  // x
+          m_fitter->FixParameter(6 * j + 1);  // y
+          m_fitter->FixParameter(6 * j + 2);  // z
+          m_fitter->FixParameter(6 * j + 3);  // Rx
+          m_fitter->FixParameter(6 * j + 4);  // Ry
+          m_fitter->FixParameter(6 * j + 5);  // Rz
+        } else {
+          info() << "*** Wobbling detector " << j << endmsg;
+          for (unsigned int k = 0; k < 6; ++k) {
+            if (m_dofs[k]) {
+              m_fitter->ReleaseParameter(6 * j + k);
+            } else {
+              m_fitter->FixParameter(6 * j + k);
+            }
+          }
+        }
+      }
+      // Execute minimization and calculate proper error matrix
+      m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
+      m_fitter->ExecuteCommand("HESSE", arglist, 1);
+      if (msgLevel(MSG::INFO))
+        m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
+    }
+  }
+  updateGeometry();
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuit0.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit0.h.svn-base
new file mode 100644
index 0000000..716f923
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit0.h.svn-base
@@ -0,0 +1,21 @@
+#pragma once
+
+// Local
+#include "TbAlignmentMinuitBase.h"
+
+class TbAlignmentMinuit0 : public TbAlignmentMinuitBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuit0(const std::string& type, const std::string& name,
+                     const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuit0();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  void chi2(double& f, double* par, double* g);
+
+ private:
+  /// Plane to be kept fixed
+  unsigned int m_referencePlane;
+};
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuit1.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit1.cpp.svn-base
new file mode 100644
index 0000000..08ac8f5
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit1.cpp.svn-base
@@ -0,0 +1,110 @@
+#include "TbAlignmentMinuit1.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentMinuit1)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuit1::TbAlignmentMinuit1(const std::string& type,
+                                       const std::string& name,
+                                       const IInterface* parent)
+    : TbAlignmentMinuitBase(type, name, parent) {
+
+  declareProperty("ReferencePlane", m_referencePlane = 999);
+
+  m_dofsDefault = {true, true, false, false, false, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuit1::~TbAlignmentMinuit1() {}
+
+//=============================================================================
+// Calculate the chi2.
+//=============================================================================
+void TbAlignmentMinuit1::chi2(double& f, double* par, double* /*g*/) {
+
+  // Assign new aligment constants
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    (*im)->setAlignment(par[6 * i + 0], par[6 * i + 1], par[6 * i + 2],
+                        par[6 * i + 3], par[6 * i + 4], par[6 * i + 5]);
+  }
+
+  // Loop over tracks
+  f = 0.;
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    // Get global position of each cluster relative to the reference cluster
+    auto clusters = (*it)->track()->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      // Skip reference plane
+      const unsigned int plane = (*ic)->plane();
+      if (plane == m_referencePlane) continue;
+      // Transform local cluster coordinates to global frame
+      Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      // Calculate residuals wrt reference
+      const double xresidual = pGlobal.x() - (*it)->xOnReferencePlane();
+      const double yresidual = pGlobal.y() - (*it)->yOnReferencePlane();
+      // Add residuals to chi2
+      f += xresidual * xresidual + yresidual * yresidual;
+    }
+  }
+}
+
+//=============================================================================
+// Main alignment function.
+//=============================================================================
+void TbAlignmentMinuit1::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  TbAlignmentMinuitBase::align(alignmentTracks);
+  info() << "Minuit technique 1" << endmsg;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const unsigned int offset = 6 * i;
+    // Fix unwanted detectors
+    if (i == m_referencePlane || masked(i)) {
+      info() << "*** Detector " << i << " will be held fixed" << endmsg;
+      m_fitter->FixParameter(offset + 0);  // x
+      m_fitter->FixParameter(offset + 1);  // y
+      m_fitter->FixParameter(offset + 2);  // z
+      m_fitter->FixParameter(offset + 3);  // Rx
+      m_fitter->FixParameter(offset + 4);  // Ry
+      m_fitter->FixParameter(offset + 5);  // Rz
+    } else {
+      for (unsigned int j = 0; j < 6; ++j) {
+        if (m_dofs[j]) {
+          m_fitter->ReleaseParameter(offset + j);
+        } else {
+          m_fitter->FixParameter(offset + j);
+        }
+      }
+    }
+  }
+
+  // Loop over tracks and get global position of the reference cluster.
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    auto clusters = (*it)->track()->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      // Find reference cluster
+      const unsigned int plane = (*ic)->plane();
+      if (plane != m_referencePlane) continue;
+      // Transform local cluster coordinates to global frame
+      Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      (*it)->setXOnReferencePlane(pGlobal.x());
+      (*it)->setYOnReferencePlane(pGlobal.y());
+      break;
+    }
+  }
+
+  // Execute minimization and calculate proper error matrix
+  double arglist[2];
+  arglist[0] = 10000;
+  arglist[1] = 1.e-2;
+  m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
+  m_fitter->ExecuteCommand("HESSE", arglist, 1);
+  if (msgLevel(MSG::INFO)) m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
+  updateGeometry();
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuit1.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit1.h.svn-base
new file mode 100644
index 0000000..36356a3
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit1.h.svn-base
@@ -0,0 +1,21 @@
+#pragma once
+
+// Local
+#include "TbAlignmentMinuitBase.h"
+
+class TbAlignmentMinuit1 : public TbAlignmentMinuitBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuit1(const std::string& type, const std::string& name,
+                     const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuit1();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  void chi2(double& f, double* par, double* g);
+
+ private:
+  /// Plane to be kept fixed.
+  unsigned int m_referencePlane;
+};
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuit2.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit2.cpp.svn-base
new file mode 100644
index 0000000..028a512
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit2.cpp.svn-base
@@ -0,0 +1,239 @@
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbAlignmentMinuit2.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentMinuit2)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuit2::TbAlignmentMinuit2(const std::string& type,
+                                       const std::string& name,
+                                       const IInterface* parent)
+    : TbAlignmentMinuitBase(type, name, parent) {
+
+  declareProperty("ClusterLocation", 
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("DeviceToAlign", m_deviceToAlign = 999);
+  declareProperty("IsDUT", m_isDUT = true);
+  declareProperty("RefitTracks", m_refitTracks = false);
+  declareProperty("TimeWindow", m_twindow = 200. * Gaudi::Units::ns);
+  declareProperty("XWindow", m_xwindow = 1. * Gaudi::Units::mm);
+  declareProperty("IgnoreEdge",m_ignoreEdge=1);
+  m_dofsDefault = {true, true, true, true, true, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuit2::~TbAlignmentMinuit2() {}
+
+//=============================================================================
+// Collect the tracks and clusters to be used for the alignment.
+//=============================================================================
+StatusCode TbAlignmentMinuit2::execute(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  // Grab the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  if (!m_isDUT) {
+    // We want to align a plane which is included in the pattern recognition.
+    for (LHCb::TbTrack* track : *tracks) {
+      // Skip low-quality tracks.
+      if (track->chi2() > m_maxChi2) continue;
+      // Add a new alignment track (cloning track and clusters) to the store.
+      alignmentTracks.emplace_back(new TbAlignmentTrack(track));
+    }
+    return StatusCode::SUCCESS;
+  }
+  // We want to align a plane which is not included in the pattern recognition.
+  if (m_twindow < 0. && m_xwindow < 0.) {
+    // Use the clusters which have been associated to the track.
+    for (LHCb::TbTrack* track : *tracks) {
+      // Skip low-quality tracks.
+      if (track->chi2() > m_maxChi2) continue;
+      auto clusters = track->associatedClusters();
+      for (auto it = clusters.begin(), end = clusters.end(); it != end; ++it) {
+        if ((*it)->plane() != m_deviceToAlign) continue;
+        // Create a new alignment track (cloning the track).
+        TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
+        // Clone the cluster and add it to the alignment track.
+        LHCb::TbCluster* alignmentCluster = (*it)->clone();
+        alignmentTrack->track()->addToAssociatedClusters(alignmentCluster);
+        alignmentTrack->addToClusters(alignmentCluster);
+        // Add the alignment track to the store.
+        alignmentTracks.push_back(alignmentTrack);
+        // Stop after the first valid cluster.
+        break;
+      }
+    }
+    return StatusCode::SUCCESS;
+  }
+  // We need to associate DUT clusters to the track.
+  // Grab the clusters on the device to align.
+  const std::string clusterLocation = m_clusterLocation + std::to_string(m_deviceToAlign);
+  LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+  if (!clusters) {
+    return Error("No clusters in " + clusterLocation);
+  }
+  unsigned int edgeRejected(0), spaceRejected(0);
+
+  for (LHCb::TbTrack* track : *tracks) {
+    // Skip low-quality tracks.
+    if (track->chi2PerNdof() > m_maxChi2) continue;
+    // Calculate the track intercept on the device to align.
+    const auto pGlobal = geomSvc()->intercept(track, m_deviceToAlign);
+    const auto pLocal = geomSvc()->globalToLocal(pGlobal, m_deviceToAlign);
+    // Calculate the time window.
+    const double tMin = track->htime() - m_twindow;
+    const double tMax = track->htime() + m_twindow;
+    // Get the first cluster within the time window.
+    LHCb::TbClusters::iterator end = clusters->end();
+    LHCb::TbClusters::iterator begin = std::lower_bound(
+        clusters->begin(), end, tMin, lowerBound<const LHCb::TbCluster*>());
+    if (begin == clusters->end()) continue;
+    // Loop over the clusters.
+    for (LHCb::TbClusters::iterator it = begin; it != end; ++it) {
+      // Stop when outside the time window.
+      if ((*it)->htime() > tMax) break;
+      // Skip clusters too far away from the track intercept.
+      const double dx = (*it)->xloc() - pLocal.x();
+      const double dy = (*it)->yloc() - pLocal.y();
+      if (fabs(dx) > m_xwindow || fabs(dy) > m_xwindow){ spaceRejected++; continue; }
+      // Skip clusters close to the edge of the sensor.
+      if (isEdge(*it) && m_ignoreEdge ){edgeRejected++; continue;}
+      // Create a new alignment track (cloning the track).
+      TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
+      // Clone the cluster and add it to the alignment track.
+      LHCb::TbCluster* alignmentCluster = (*it)->clone();
+      alignmentTrack->track()->addToAssociatedClusters(alignmentCluster);
+      alignmentTrack->addToClusters(alignmentCluster);
+      // Add the alignment track to the store.
+      alignmentTracks.push_back(alignmentTrack);
+      // Stop after the first valid cluster.
+      break;
+    }
+  }
+  //info() << edgeRejected << "   " << spaceRejected << "    " << tracks->size() << endmsg;
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Calculate the chi2.
+//=============================================================================
+void TbAlignmentMinuit2::chi2(double& f, double* par, double* /*g*/) {
+
+  const unsigned int offset = m_deviceToAlign * 6;
+  // Check the z-position.
+  const double z = m_modules[m_deviceToAlign]->z() + par[offset + 2];
+  if (m_deviceToAlign > 0) {
+    if (z <= m_modules[m_deviceToAlign - 1]->z()) {
+      info() << "Z is below limit!" << endmsg;
+      f = std::numeric_limits<double>::max();
+      return;
+    }
+  }
+  if (m_deviceToAlign < m_nPlanes - 1) {
+    if (z >= m_modules[m_deviceToAlign + 1]->z()) {
+      info() << "Z is above limit!" << endmsg;
+      f = std::numeric_limits<double>::max();
+      return;
+    }
+  }
+
+  m_modules[m_deviceToAlign]->setAlignment(par[offset + 0], par[offset + 1],
+                                           par[offset + 2], par[offset + 3],
+                                           par[offset + 4], par[offset + 5]);
+  // Loop over the alignment tracks.
+  f = 0.;
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    // Form residuals with all clusters selected for alignment
+    auto clusters = (*it)->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      if ((*ic)->plane() != m_deviceToAlign) continue;
+      Gaudi::XYZPoint point = geomSvc()->localToGlobal(
+          Gaudi::XYZPoint((*ic)->xloc(), (*ic)->yloc(), 0), m_deviceToAlign);
+      Gaudi::XYZPoint intercept =
+          geomSvc()->intercept((*it)->track(), m_deviceToAlign);
+      // TODO: why not the local residual?
+      const double xresidual = point.x() - intercept.x();
+      // const double xresidual = (*ic)->xloc() - intercept.x();
+      const double yresidual = point.y() - intercept.y();
+      // const double yresidual = (*ic)->yloc() - intercept.y();
+      f += xresidual * xresidual + yresidual * yresidual;
+    }
+  }
+}
+
+//=============================================================================
+// Main alignment function.
+//=============================================================================
+void TbAlignmentMinuit2::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  TbAlignmentMinuitBase::align(alignmentTracks);
+  info() << "Minuit technique 2. Aligning plane " << m_deviceToAlign << endmsg;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i) || i == m_deviceToAlign)
+      m_trackFit->maskPlane(i);
+    else
+      m_trackFit->unmaskPlane(i);
+  }
+
+  for (auto alignmentTrack : m_tracks) m_trackFit->fit(alignmentTrack->track());
+
+  for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
+    info() << "Iteration " << iteration + 1 << "/" << m_nIterations << endmsg;
+    // Loop over detector modules
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      const unsigned int offset = 6 * i;
+      if (i == m_deviceToAlign) {
+        info() << "*** Wobbling detector " << i << endmsg;
+        for (unsigned int j = 0; j < 6; ++j) {
+          if (m_dofs[j]) {
+            m_fitter->ReleaseParameter(offset + j);
+          } else {
+            m_fitter->FixParameter(offset + j);
+          }
+        }
+      } else {
+        m_fitter->FixParameter(offset + 0);  // x
+        m_fitter->FixParameter(offset + 1);  // y
+        m_fitter->FixParameter(offset + 2);  // z
+        m_fitter->FixParameter(offset + 3);  // Rx
+        m_fitter->FixParameter(offset + 4);  // Ry
+        m_fitter->FixParameter(offset + 5);  // Rz
+      }
+    }
+    // Execute minimization and calculate proper error matrix
+    double arglist[2];
+    arglist[0] = 10000;
+    arglist[1] = 1.e-2;
+    m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
+    m_fitter->ExecuteCommand("HESSE", arglist, 1);
+    if (msgLevel(MSG::INFO)) m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
+ 
+    updateGeometry();
+  }
+
+  if (m_refitTracks) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (masked(i))
+        m_trackFit->maskPlane(i);
+      else
+        m_trackFit->unmaskPlane(i);
+    }
+    for (auto it : m_tracks) m_trackFit->fit(it->track());
+  }
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuit2.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit2.h.svn-base
new file mode 100644
index 0000000..e1596cd
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuit2.h.svn-base
@@ -0,0 +1,34 @@
+#pragma once
+
+// Local
+#include "TbAlignmentMinuitBase.h"
+
+class TbAlignmentMinuit2 : public TbAlignmentMinuitBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuit2(const std::string& type, const std::string& name,
+                     const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuit2();
+
+  /// Collect tracks and clusters for alignment (called at each event).
+  virtual StatusCode execute(std::vector<TbAlignmentTrack*>& tracks);
+
+  virtual void align(std::vector<TbAlignmentTrack*>& tracks);
+  void chi2(double& f, double* par, double* g);
+
+ private:
+  /// TES location prefix of clusters
+  std::string m_clusterLocation;
+  /// Plane index of the device to align
+  unsigned int m_deviceToAlign;
+  /// Flag whether the device to align is excluded from the pattern recognition
+  bool m_isDUT;
+  bool m_refitTracks;
+  bool m_ignoreEdge;
+  /// Time window for associating clusters to a track
+  double m_twindow;
+  /// Spatial window for associating clusters to a track
+  double m_xwindow;
+};
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuitBase.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuitBase.cpp.svn-base
new file mode 100644
index 0000000..a4369b8
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuitBase.cpp.svn-base
@@ -0,0 +1,106 @@
+#include "TbAlignmentMinuitBase.h"
+
+namespace Tb {
+TbAlignmentMinuitBase* gTbAlignmentMinuitBase(nullptr);
+
+//=============================================================================
+// Function to be minimised
+//=============================================================================
+void fcn(int&, double* g, double& f, double* par, int) {
+  gTbAlignmentMinuitBase->chi2(f, par, g);
+}
+}
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuitBase::TbAlignmentMinuitBase(const std::string& type,
+                                             const std::string& name,
+                                             const IInterface* parent)
+    : TbAlignmentBase(type, name, parent) {
+
+  declareProperty("NIterations", m_nIterations = 3);
+  declareProperty("FitStrategy", m_fitStrategy = 2);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuitBase::~TbAlignmentMinuitBase() {}
+
+//=============================================================================
+// Update the module positions and orientations
+//=============================================================================
+void TbAlignmentMinuitBase::updateGeometry() {
+
+  info() << "Updating alignment constants:" << endmsg;
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    const double x = (*im)->x() + m_fitter->GetParameter(6 * i + 0);
+    const double y = (*im)->y() + m_fitter->GetParameter(6 * i + 1);
+    const double z = (*im)->z() + m_fitter->GetParameter(6 * i + 2);
+    const double rotx = (*im)->rotX() + m_fitter->GetParameter(6 * i + 3);
+    const double roty = (*im)->rotY() + m_fitter->GetParameter(6 * i + 4);
+    const double rotz = (*im)->rotZ() + m_fitter->GetParameter(6 * i + 5);
+    info() << format("%2i", i) << format(" %-15s", (*im)->id().c_str())
+           << format(" %10.3f", (*im)->x()) << format(" %10.3f", (*im)->y())
+           << format(" %10.3f", (*im)->z()) << format(" %10.3f", (*im)->rotX())
+           << format(" %10.3f", (*im)->rotY())
+           << format(" %10.3f", (*im)->rotZ()) << endmsg;
+    (*im)->setAlignment(x, y, z, rotx, roty, rotz, 0., 0., 0., 0., 0., 0.);
+  }
+}
+
+//=============================================================================
+// Main alignment function
+//=============================================================================
+void TbAlignmentMinuitBase::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  m_tracks = alignmentTracks;
+  // Set up the fitter.
+  m_fitter = new TFitter(60);
+  Tb::gTbAlignmentMinuitBase = this;
+  m_fitter->SetFCN(Tb::fcn);
+  // Set the output level (-1: none, 0: minimum: 1: normal).
+  double arglist = -1.;
+  if (msgLevel(MSG::DEBUG)) arglist = 1.;
+  m_fitter->ExecuteCommand("SET PRINTOUT", &arglist, 1);
+  // Set the value defining parameter errors.
+  arglist = 1.;
+  m_fitter->ExecuteCommand("SET ERR", &arglist, 1);
+  // Set the strategy for calculating derivatives. 
+  arglist = m_fitStrategy;
+  m_fitter->ExecuteCommand("SET STRATEGY", &arglist, 1);
+  // Set the floating point accuracy.
+  arglist = 1.e-12;
+  m_fitter->ExecuteCommand("SET EPS", &arglist, 1);
+  setParameters();
+}
+
+//=============================================================================
+// Set the initial values of the fit parameters.
+//=============================================================================
+void TbAlignmentMinuitBase::setParameters() {
+
+  info() << "Setting initial values of alignment parameters" << endmsg;
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    const double dx = (*im)->dX();
+    const double dy = (*im)->dY();
+    const double dz = (*im)->dZ();
+    const double drx = (*im)->dRotX();
+    const double dry = (*im)->dRotY();
+    const double drz = (*im)->dRotZ();
+    const std::string id = (*im)->id();
+    m_fitter->SetParameter(6 * i + 0, (id + " dx ").c_str(), dx, 0.001, 0., 0.);
+    m_fitter->SetParameter(6 * i + 1, (id + " dy ").c_str(), dy, 0.001, 0., 0.);
+    m_fitter->SetParameter(6 * i + 2, (id + " dz ").c_str(), dz, 1., 0., 0.);
+    m_fitter->SetParameter(6 * i + 3, (id + " dRx").c_str(), drx, 0.001, 0.,
+                           0.);
+    m_fitter->SetParameter(6 * i + 4, (id + " dRy").c_str(), dry, 0.001, 0.,
+                           0.);
+    m_fitter->SetParameter(6 * i + 5, (id + " dRz").c_str(), drz, 0.001, 0.,
+                           0.);
+  }
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentMinuitBase.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentMinuitBase.h.svn-base
new file mode 100644
index 0000000..dd73928
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentMinuitBase.h.svn-base
@@ -0,0 +1,33 @@
+#pragma once
+
+// ROOT
+#include "TFitter.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+class TbAlignmentMinuitBase : public TbAlignmentBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuitBase(const std::string& type, const std::string& name,
+                        const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuitBase();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  virtual void chi2(double& f, double* par, double* g) = 0;
+
+  virtual void updateGeometry();
+
+ protected:
+  /// Number of iterations
+  unsigned int m_nIterations;
+  /// Minuit fit strategy (allowed values are 0, 1, 2).
+  int m_fitStrategy;
+
+  std::vector<TbAlignmentTrack*> m_tracks;
+  TFitter* m_fitter;
+
+  void setParameters();
+};
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentSurvey.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentSurvey.cpp.svn-base
new file mode 100644
index 0000000..89cd1a4
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentSurvey.cpp.svn-base
@@ -0,0 +1,76 @@
+// ROOT
+#include "TH1.h"
+
+// Gaudi
+#include "GaudiKernel/IHistogramSvc.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Local
+#include "TbAlignmentSurvey.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentSurvey)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentSurvey::TbAlignmentSurvey(const std::string& type,
+                                     const std::string& name,
+                                     const IInterface* parent)
+    : TbAlignmentBase(type, name, parent) {}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentSurvey::~TbAlignmentSurvey() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbAlignmentSurvey::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlignmentBase::initialize();
+  if (sc.isFailure()) return sc;
+
+  return StatusCode::SUCCESS;
+}
+
+void TbAlignmentSurvey::align(std::vector<TbAlignmentTrack*>& /*tracks*/) {
+
+  info() << "Survey alignment" << endmsg;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    const std::string plane = std::to_string(i);
+    const std::string path = "Tb/TbClusterPlots/Differences/";
+    const std::string titlex = path + "x/Plane" + plane;
+    const std::string titley = path + "y/Plane" + plane;
+    double tx = m_modules[i]->x();
+    double ty = m_modules[i]->y();
+
+    if (m_dofs[0]) {
+      AIDA::IHistogram1D* hAida = NULL;
+      StatusCode sc = GaudiTool::histoSvc()->retrieveObject(titlex, hAida);
+      if (sc.isFailure() || !hAida) {
+        warning() << "Cannot retrieve histogram " << titlex << endmsg;
+      } else {
+        auto hRoot = Gaudi::Utils::Aida2ROOT::aida2root(hAida);
+        tx -= hRoot->GetBinCenter(hRoot->GetMaximumBin());
+      }
+    }
+    if (m_dofs[1]) {
+      AIDA::IHistogram1D* hAida = NULL;
+      StatusCode sc = GaudiTool::histoSvc()->retrieveObject(titley, hAida);
+      if (sc.isFailure() || !hAida) {
+        warning() << "Cannot retrieve histogram " << titley << endmsg;
+      } else {
+        auto hRoot = Gaudi::Utils::Aida2ROOT::aida2root(hAida);
+        ty -= hRoot->GetBinCenter(hRoot->GetMaximumBin());
+      }
+    }
+    const double rx = m_modules[i]->rotX();
+    const double ry = m_modules[i]->rotY();
+    const double rz = m_modules[i]->rotZ();
+    const double tz = m_modules[i]->z();
+    m_modules[i]->setAlignment(tx, ty, tz, rx, ry, rz, 0., 0., 0., 0., 0., 0.);
+  }
+}
diff --git a/TbAlignment/src/.svn/text-base/TbAlignmentSurvey.h.svn-base b/TbAlignment/src/.svn/text-base/TbAlignmentSurvey.h.svn-base
new file mode 100644
index 0000000..7c97ba7
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbAlignmentSurvey.h.svn-base
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "TbAlignmentBase.h"
+
+class TbAlignmentSurvey : public TbAlignmentBase {
+
+ public:
+  /// Constructor
+  TbAlignmentSurvey(const std::string& type, const std::string& name,
+                    const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentSurvey();
+
+  virtual StatusCode initialize();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+};
diff --git a/TbAlignment/src/.svn/text-base/TbMillepede.cpp.svn-base b/TbAlignment/src/.svn/text-base/TbMillepede.cpp.svn-base
new file mode 100644
index 0000000..aafcda3
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbMillepede.cpp.svn-base
@@ -0,0 +1,1093 @@
+#include <iomanip>
+#include <algorithm>
+#include <cmath>
+
+// Local
+#include "TbMillepede.h"
+
+// TbKernel
+#include "TbKernel/TbGeomFunctions.h"
+
+DECLARE_TOOL_FACTORY(TbMillepede)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbMillepede::TbMillepede(const std::string& type, const std::string& name,
+                         const IInterface* parent)
+    : TbAlignmentBase(type, name, parent),
+      m_nalc(4),
+      m_debug(false),
+      m_iterate(true) {
+
+  declareProperty("NIterations", m_nIterations = 5);
+  declareProperty("ResCut", m_rescut = 0.05);
+  declareProperty("ResCutInit", m_rescut_init = 0.6);
+  declareProperty("NStdDev", m_nstdev = 0);
+  declareProperty("Sigmas", m_sigmas = {});
+
+  m_dofsDefault = {true, true, false, true, true, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbMillepede::~TbMillepede() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbMillepede::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlignmentBase::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Get the verbosity level.
+  m_debug = msgLevel(MSG::DEBUG);
+
+  // Renumber the planes in Millepede, ignoring masked planes.
+  m_millePlanes.assign(m_nPlanes, 999);
+  unsigned int index = 0;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    m_millePlanes[i] = index;
+    ++index;
+  }
+  // Use default values for the sigmas, unless specified explicitly.
+  if (m_sigmas.size() != 6) {
+    m_sigmas = {0.05, 0.05, 0.5, 0.005, 0.005, 0.005};
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main alignment function
+//=============================================================================
+void TbMillepede::align(std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  info() << "Millepede alignment" << endmsg;
+  const unsigned int nPlanes = m_nPlanes - m_maskedPlanes.size();
+  const unsigned int nParameters = 6 * nPlanes;
+  for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
+    const unsigned int nTracks = alignmentTracks.size();
+    // Define the constraint equations.
+    setConstraints(nPlanes);
+    const double startfact = 100.;
+    // Initialise all matrices and vectors.
+    reset(nPlanes, startfact);
+    info() << "Feeding Millepede with " << nTracks << " tracks..." << endmsg;
+    // Feed Millepede with tracks.
+    unsigned int nSkipped = 0;
+    unsigned int nOutliers = 0;
+    for (unsigned int i = 0; i < nTracks; ++i) {
+      LHCb::TbTrack* track = alignmentTracks[i]->track();
+      if (track->size() != nPlanes) {
+        ++nSkipped;
+        continue;
+      }
+      if (!putTrack(track, nPlanes)) {
+        ++nOutliers;
+      }
+    }
+    if (nSkipped > 0) {
+      info() << "Skipped " << nSkipped << " tracks with less than " << nPlanes
+             << " clusters." << endmsg;
+    }
+    if (nOutliers > 0) {
+      info() << "Rejected " << nOutliers << " outlier tracks." << endmsg;
+    }
+    // Do the global fit.
+    info() << "Determining global parameters..." << endmsg;
+    fitGlobal();
+    // Calculate the convergence metric (sum of misalignments).
+    double converg = 0.;
+    for (unsigned int i = 0; i < nParameters; ++i) {
+      converg += fabs(m_dparm[i]);
+    }
+    converg /= nParameters;
+    info() << "Convergence: " << converg << endmsg;
+    // Update the module positions and orientations.
+    info() << "Updating geometry..." << endmsg;
+    updateGeometry();
+    // Update the cluster coordinates based on the new geometry.
+    for (unsigned int i = 0; i < nTracks; ++i) {
+      LHCb::TbTrack* track = alignmentTracks[i]->track();
+      SmartRefVector<LHCb::TbCluster> clusters = track->clusters();
+      for (auto ic = clusters.begin(), end = clusters.end(); ic != end; ++ic) {
+        Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+        const auto pGlobal = geomSvc()->localToGlobal(pLocal, (*ic)->plane());
+        (*ic)->setX(pGlobal.x());
+        (*ic)->setY(pGlobal.y());
+        (*ic)->setZ(pGlobal.z());
+      }
+    }
+    if (converg < 0.00001) break;
+  }
+}
+
+//=============================================================================
+// Setup the constraint equations.
+//=============================================================================
+void TbMillepede::setConstraints(const unsigned int nPlanes) {
+
+  // Calculate the mean z-position.
+  double avgz = 0.;
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.cbegin())) continue;
+    avgz += (*im)->z();
+  }
+  avgz /= nPlanes;
+  // Calculate the variance.
+  double varz = 0.0;
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.cbegin())) continue;
+    const double dz = (*im)->z() - avgz;
+    varz += dz * dz;
+  }
+  varz /= nPlanes;
+
+  // Define the 9 constraints equations according to the requested geometry.
+  const unsigned int nParameters = 6 * nPlanes;
+  std::vector<double> ftx(nParameters, 0.);
+  std::vector<double> fty(nParameters, 0.);
+  std::vector<double> ftz(nParameters, 0.);
+  std::vector<double> frx(nParameters, 0.);
+  std::vector<double> fry(nParameters, 0.);
+  std::vector<double> frz(nParameters, 0.);
+  std::vector<double> fscaz(nParameters, 0.);
+  std::vector<double> shearx(nParameters, 0.);
+  std::vector<double> sheary(nParameters, 0.);
+
+  m_constraints.clear();
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.begin())) continue;
+    const unsigned int i = m_millePlanes[im - m_modules.begin()];
+    const double sz = ((*im)->z() - avgz) / varz;
+    ftx[i] = 1.0;
+    fty[i + nPlanes] = 1.0;
+    ftz[i + 2 * nPlanes] = 1.0;
+    frx[i + 3 * nPlanes] = 1.0 ; // i > 4 ? 1.0 : -1.0;
+    fry[i + 4 * nPlanes] = 1.0 ; //  i > 4 ? 1.0 : -1.0;
+    frz[i + 5 * nPlanes] = 1.0;
+    shearx[i] = sz;
+    sheary[i + nPlanes] = sz;
+    fscaz[i + 2 * nPlanes] = sz;
+  }
+
+  const std::vector<bool> constraints = {true,  true, true, true, false,
+                                         false, true, true, true};
+  //  Put the constraints information in the basket.
+  if (constraints[0] && m_dofs[0]) addConstraint(ftx, 0.0);
+  if (constraints[1] && m_dofs[0]) addConstraint(shearx, 0.);
+  if (constraints[2] && m_dofs[1]) addConstraint(fty, 0.0);
+  if (constraints[3] && m_dofs[1]) addConstraint(sheary, 0.);
+  if (constraints[4] && m_dofs[2]) addConstraint(ftz, 0.0);
+  // if (constraints[5] && m_dofs[2]) addConstraint(fscaz, 0.0);
+  if (constraints[6] && m_dofs[3]) addConstraint(frx, 0.0);
+  if (constraints[7] && m_dofs[4]) addConstraint(fry, 0.0);
+  if (constraints[8] && m_dofs[5]) addConstraint(frz, 0.0);
+}
+
+//=============================================================================
+// Define a single constraint equation.
+//=============================================================================
+void TbMillepede::addConstraint(const std::vector<double>& dercs,
+                                const double rhs) {
+
+  Constraint constraint;
+  // Set the right-hand side (Lagrange multiplier value, sum of equation).
+  constraint.rhs = rhs;
+  // Set the constraint equation coefficients.
+  constraint.coefficients = dercs;
+  m_constraints.push_back(constraint);
+}
+
+//=============================================================================
+// Add the equations for one track to the matrix
+//=============================================================================
+bool TbMillepede::putTrack(LHCb::TbTrack* track, const unsigned int nPlanes) {
+
+  std::vector<Equation> equations;
+  const unsigned int nParameters = 6 * nPlanes;
+  // Global derivatives
+  std::vector<double> dergb(nParameters, 0.);
+  // Global derivatives non linearly related to residual
+  std::vector<double> dernl(nParameters, 0.);
+  // Local parameter indices associated with non-linear derivatives
+  std::vector<int> dernli(nParameters, 0);
+  // Track slopes
+  std::vector<double> dernls(nParameters, 0.);
+
+  /// Refit the track for the reference states.
+  m_trackFit->fit(track);
+  auto state = track->firstState();
+  const double tx = state.tx();
+  const double ty = state.ty();
+
+  // Iterate over each cluster on the track.
+  const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters();
+  for (auto itc = clusters.cbegin(), end = clusters.cend(); itc != end; ++itc) {
+    if (masked((*itc)->plane())) continue;
+    const auto normal = geomSvc()->module((*itc)->plane())->normal();
+    double nx = normal.x() / normal.z();
+    double ny = normal.y() / normal.z();
+    const double xg = (*itc)->x();
+    const double yg = (*itc)->y();
+    const double zg = (*itc)->z();
+    // Calculate quasi-local coordinates.
+    const double zl = zg - m_modules[(*itc)->plane()]->z();
+    const double xl = xg - m_modules[(*itc)->plane()]->x();
+    const double yl = yg - m_modules[(*itc)->plane()]->y();
+
+    std::vector<double> nonlinear = {
+        nx, ny, 1., -yl + zl * ny, -xl + zl * nx, xl * ny - yl * nx};
+    const double den = 1. + tx * nx + ty * ny;
+    for (auto& a : nonlinear) a /= den;
+    // Get the errors on the measured x and y coordinates.
+    const double errx = (*itc)->xErr();
+    const double erry = (*itc)->yErr();
+    // Get the internal plane index in Millepede.
+    const unsigned int plane = m_millePlanes[(*itc)->plane()];
+    // Set the local derivatives for the X equation.
+    std::vector<double> derlc = {1., zg, 0., 0.};
+    // Set the global derivatives (see LHCb-2005-101) for the X equation.
+    std::fill(dergb.begin(), dergb.end(), 0.);
+    std::fill(dernl.begin(), dernl.end(), 0.);
+    std::fill(dernli.begin(), dernli.end(), 0);
+    std::fill(dernls.begin(), dernls.end(), 0.);
+    if (m_dofs[0]) dergb[plane] = -1.;
+    if (m_dofs[4]) dergb[4 * nPlanes + plane] = -zl;
+    if (m_dofs[5]) dergb[5 * nPlanes + plane] = yl;
+    for (unsigned int i = 0; i < 6; ++i) {
+      if (!m_dofs[i]) continue;
+      dergb[i * nPlanes + plane] += tx * nonlinear[i];
+      dernl[i * nPlanes + plane] = nonlinear[i];
+      dernli[i * nPlanes + plane] = 1;
+      dernls[i * nPlanes + plane] = tx;
+    }
+    // Store the X equation.
+    addEquation(equations, derlc, dergb, dernl, dernli, dernls, xg, errx);
+    // Set the local derivatives for the Y equation.
+    derlc = {0., 0., 1., zg};
+    // Set the global derivatives (see LHCb-2005-101) for the Y equation.
+    std::fill(dergb.begin(), dergb.end(), 0.);
+    std::fill(dernl.begin(), dernl.end(), 0.);
+    std::fill(dernli.begin(), dernli.end(), 0);
+    std::fill(dernls.begin(), dernls.end(), 0.);
+    if (m_dofs[1]) dergb[nPlanes + plane] = -1.;
+    if (m_dofs[3]) dergb[3 * nPlanes + plane] = -zl;
+    if (m_dofs[5]) dergb[5 * nPlanes + plane] = -xl;
+    for (unsigned int i = 0; i < 6; ++i) {
+      if (!m_dofs[i]) continue;
+      dergb[i * nPlanes + plane] += ty * nonlinear[i];
+      dernl[i * nPlanes + plane] = nonlinear[i];
+      dernli[i * nPlanes + plane] = 3;
+      dernls[i * nPlanes + plane] = ty;
+    }
+    // Store the Y equation.
+    addEquation(equations, derlc, dergb, dernl, dernli, dernls, yg, erry);
+  }
+  // Vector containing the track parameters
+  std::vector<double> trackParams(2 * m_nalc + 2, 0.);
+  // Fit the track.
+  const unsigned int iteration = 1;
+  const bool ok = fitTrack(equations, trackParams, false, iteration);
+  if (ok) m_equations.push_back(equations);
+  return ok;
+}
+
+//=============================================================================
+// Store the parameters for one measurement
+//=============================================================================
+void TbMillepede::addEquation(std::vector<Equation>& equations,
+                              const std::vector<double>& derlc,
+                              const std::vector<double>& dergb,
+                              const std::vector<double>& dernl,
+                              const std::vector<int>& dernli,
+                              const std::vector<double>& slopes,
+                              const double rmeas, const double sigma) {
+
+  if (sigma <= 0.) {
+    error() << "Invalid cluster error (" << sigma << ")" << endmsg;
+    return;
+  }
+  Equation equation;
+  equation.rmeas = rmeas;
+  equation.weight = 1. / (sigma * sigma);
+  // Add non-zero local derivatives and corresponding indices.
+  equation.derL.clear();
+  equation.indL.clear();
+  for (unsigned int i = 0; i < m_nalc; ++i) {
+    if (derlc[i] == 0.) continue;
+    equation.indL.push_back(i);
+    equation.derL.push_back(derlc[i]);
+  }
+  // Add non-zero global derivatives and corresponding indices.
+  equation.derG.clear();
+  equation.indG.clear();
+  equation.derNL.clear();
+  equation.indNL.clear();
+  equation.slopes.clear();
+  const unsigned int nG = dergb.size();
+  for (unsigned int i = 0; i < nG; ++i) {
+    if (dergb[i] == 0.) continue;
+    equation.indG.push_back(i);
+    equation.derG.push_back(dergb[i]);
+    equation.derNL.push_back(dernl[i]);
+    equation.indNL.push_back(dernli[i]);
+    equation.slopes.push_back(slopes[i]);
+  }
+  // Add the equation to the list.
+  equations.push_back(std::move(equation));
+}
+
+//=============================================================================
+// Track fit (local fit)
+//=============================================================================
+bool TbMillepede::fitTrack(const std::vector<Equation>& equations,
+                           std::vector<double>& trackParams,
+                           const bool singlefit, const unsigned int iteration) {
+
+  std::vector<double> blvec(m_nalc, 0.);
+  std::vector<std::vector<double> > clmat(m_nalc,
+                                          std::vector<double>(m_nalc, 0.));
+
+  // First loop: local track fit
+  for (const auto& equation : equations) {
+    double rmeas = equation.rmeas;
+    // Suppress the global part (only relevant with iterations).
+    const unsigned int nG = equation.derG.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      rmeas -= equation.derG[i] * m_dparm[j];
+    }
+    const double w = equation.weight;
+    // Fill local matrix and vector.
+    const unsigned int nL = equation.derL.size();
+    for (unsigned int i = 0; i < nL; ++i) {
+      const unsigned int j = equation.indL[i];
+      blvec[j] += w * rmeas * equation.derL[i];
+      if (m_debug) debug() << "blvec[" << j << "] = " << blvec[j] << endmsg;
+      // Symmetric matrix, don't bother k > j coefficients.
+      for (unsigned int k = 0; k <= i; ++k) {
+        const unsigned int ik = equation.indL[k];
+        clmat[j][ik] += w * equation.derL[i] * equation.derL[k];
+        if (m_debug) {
+          debug() << "clmat[" << j << "][" << ik << "] = " << clmat[j][ik]
+                  << endmsg;
+        }
+      }
+    }
+  }
+
+  // Local parameter matrix is completed, now invert to solve.
+  // Rank: number of non-zero diagonal elements.
+  int rank = invertMatrixLocal(clmat, blvec, m_nalc);
+  // Store the track parameters and errors.
+  for (unsigned int i = 0; i < m_nalc; ++i) {
+    trackParams[2 * i] = blvec[i];
+    trackParams[2 * i + 1] = sqrt(fabs(clmat[i][i]));
+  }
+
+  // Second loop: residual calculation.
+  double chi2 = 0.0;
+  int ndf = 0;
+  for (const auto& equation : equations) {
+    double rmeas = equation.rmeas;
+    // Suppress global and local terms.
+    const unsigned int nL = equation.derL.size();
+    for (unsigned int i = 0; i < nL; ++i) {
+      const unsigned int j = equation.indL[i];
+      rmeas -= equation.derL[i] * blvec[j];
+    }
+    const unsigned int nG = equation.derG.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      rmeas -= equation.derG[i] * m_dparm[j];
+    }
+    // Now rmeas contains the residual value.
+    if (m_debug) debug() << "Residual value: " << rmeas << endmsg;
+    // Reject the track if the residual is too large (outlier).
+    const double rescut = iteration <= 1 ? m_rescut_init : m_rescut;
+    if (fabs(rmeas) >= rescut) {
+      if (m_debug) {
+        debug() << "Reject track due to residual cut in iteration " << iteration
+                << endmsg;
+      }
+      return false;
+    }
+    chi2 += equation.weight * rmeas * rmeas;
+    ++ndf;
+  }
+  ndf -= rank;
+  const bool printDetails = false;
+  if (printDetails) {
+    info() << endmsg;
+    info() << "Local track fit (rank " << rank << ")" << endmsg;
+    info() << " Result of local fit :      (index/parameter/error)" << endmsg;
+    for (unsigned int i = 0; i < m_nalc; ++i) {
+      info() << std::setprecision(6) << std::fixed << std::setw(20) << i
+             << "   /   " << std::setw(10) << blvec[i] << "   /   "
+             << sqrt(clmat[i][i]) << endmsg;
+    }
+    info() << "Final chi square / degrees of freedom: " << chi2 << " / " << ndf
+           << endmsg;
+  }
+
+  // Stop here if just updating the track parameters.
+  if (singlefit) return true;
+
+  if (m_nstdev != 0 && ndf > 0) {
+    const double chi2PerNdf = chi2 / ndf;
+    const double cut = chi2Limit(m_nstdev, ndf) * m_cfactr;
+    if (chi2 > cut) {
+      // Reject the track.
+      if (m_debug) {
+        debug() << "Rejected track because chi2 / ndof (" << chi2PerNdf
+                << ") is larger than " << cut << endmsg;
+      }
+      return false;
+    }
+  }
+  // Store the chi2 and number of degrees of freedom.
+  trackParams[2 * m_nalc] = ndf;
+  trackParams[2 * m_nalc + 1] = chi2;
+
+  // Local operations are finished. Track is accepted.
+  // Third loop: update the global parameters (other matrices).
+  m_clcmat.assign(m_nagb, std::vector<double>(m_nalc, 0.));
+  unsigned int nagbn = 0;
+  std::vector<int> indnz(m_nagb, -1);
+  std::vector<int> indbk(m_nagb, 0);
+  for (const auto& equation : equations) {
+    double rmeas = equation.rmeas;
+    // Suppress the global part.
+    const unsigned int nG = equation.derG.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      rmeas -= equation.derG[i] * m_dparm[j];
+    }
+    const double w = equation.weight;
+    // First of all, the global/global terms.
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      m_bgvec[j] += w * rmeas * equation.derG[i];
+      if (m_debug) debug() << "bgvec[" << j << "] = " << m_bgvec[j] << endmsg;
+      for (unsigned int k = 0; k < nG; ++k) {
+        const unsigned int n = equation.indG[k];
+        m_cgmat[j][n] += w * equation.derG[i] * equation.derG[k];
+        if (m_debug) {
+          debug() << "cgmat[" << j << "][" << n << "] = " << m_cgmat[j][n]
+                  << endmsg;
+        }
+      }
+    }
+    // Now we have also rectangular matrices containing global/local terms.
+    const unsigned int nL = equation.derL.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      // Index of index.
+      int ik = indnz[j];
+      if (ik == -1) {
+        // New global variable.
+        indnz[j] = nagbn;
+        indbk[nagbn] = j;
+        ik = nagbn;
+        ++nagbn;
+      }
+      // Now fill the rectangular matrix.
+      for (unsigned int k = 0; k < nL; ++k) {
+        const unsigned int ij = equation.indL[k];
+        m_clcmat[ik][ij] += w * equation.derG[i] * equation.derL[k];
+        if (m_debug)
+          debug() << "clcmat[" << ik << "][" << ij << "] = " << m_clcmat[ik][ij]
+                  << endmsg;
+      }
+    }
+  }
+
+  // Third loop is finished, now we update the correction matrices.
+  multiplyAVAt(clmat, m_clcmat, m_corrm, m_nalc, nagbn);
+  multiplyAX(m_clcmat, blvec, m_corrv, m_nalc, nagbn);
+  for (unsigned int i = 0; i < nagbn; ++i) {
+    const unsigned int j = indbk[i];
+    m_bgvec[j] -= m_corrv[i];
+    for (unsigned int k = 0; k < nagbn; ++k) {
+      const unsigned int ik = indbk[k];
+      m_cgmat[j][ik] -= m_corrm[i][k];
+    }
+  }
+  return true;
+}
+
+//=============================================================================
+// Update the module positions and orientations.
+//=============================================================================
+void TbMillepede::updateGeometry() {
+
+  const unsigned int nPlanes = m_nPlanes - m_maskedPlanes.size();
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.begin())) continue;
+    const unsigned int plane = m_millePlanes[im - m_modules.begin()];
+    const double tx = (*im)->x() + m_dparm[plane + 0 * nPlanes];
+    const double ty = (*im)->y() + m_dparm[plane + 1 * nPlanes];
+    const double tz = (*im)->z() + m_dparm[plane + 2 * nPlanes];
+    double rx = 0.;
+    double ry = 0.;
+    double rz = 0.;
+    Tb::SmallRotation((*im)->rotX(), m_dparm[plane + 3 * nPlanes],
+                      (*im)->rotY(), m_dparm[plane + 4 * nPlanes],
+                      m_dparm[plane + 5 * nPlanes], rx, ry, rz);
+    (*im)->setAlignment(tx, ty, tz, (*im)->rotX() - rx, (*im)->rotY() + ry,
+                        (*im)->rotZ() - rz, 0., 0., 0., 0., 0., 0.);
+  }
+}
+
+//=============================================================================
+// Initialise the vectors and arrays.
+//=============================================================================
+bool TbMillepede::reset(const unsigned int nPlanes, const double startfact) {
+
+  info() << "                                           " << endmsg;
+  info() << "            * o o                   o      " << endmsg;
+  info() << "              o o                   o      " << endmsg;
+  info() << "   o ooooo  o o o  oo  ooo   oo   ooo  oo  " << endmsg;
+  info() << "    o  o  o o o o o  o o  o o  o o  o o  o " << endmsg;
+  info() << "    o  o  o o o o oooo o  o oooo o  o oooo " << endmsg;
+  info() << "    o  o  o o o o o    ooo  o    o  o o    " << endmsg;
+  info() << "    o  o  o o o o  oo  o     oo   ooo  oo  ++ starts" << endmsg;
+  info() << "                                           " << endmsg;
+
+  // Reset the list of track equations.
+  m_equations.clear();
+  // Set the number of global derivatives.
+  m_nagb = 6 * nPlanes;
+  // Reset matrices and vectors.
+  const unsigned int nRows = m_nagb + m_constraints.size();
+  m_bgvec.resize(nRows, 0.);
+  m_cgmat.assign(nRows, std::vector<double>(nRows, 0.));
+  m_corrv.assign(m_nagb, 0.);
+  m_corrm.assign(m_nagb, std::vector<double>(m_nagb, 0.));
+  m_dparm.assign(m_nagb, 0.);
+
+  // Define the sigmas for each parameter.
+  m_fixed.assign(m_nagb, true);
+  m_psigm.assign(m_nagb, 0.);
+  for (unsigned int i = 0; i < 6; ++i) {
+    if (!m_dofs[i]) continue;
+    for (unsigned int j = i * nPlanes; j < (i + 1) * nPlanes; ++j) {
+      m_fixed[j] = false;
+      m_psigm[j] = m_sigmas[i];
+    }
+  }
+  // Fix modules if requested.
+  for (auto it = m_fixedPlanes.cbegin(); it != m_fixedPlanes.cend(); ++it) {
+    info() << "You are fixing module " << (*it) << endmsg;
+    // TODO: check if this is the "millePlanes" index or the regular one.
+    const unsigned ndofs = m_fix_all ? 6 : 3;
+    for (unsigned int i = 0; i < ndofs; ++i) {
+      m_fixed[(*it) + i * nPlanes] = true;
+      m_psigm[(*it) + i * nPlanes] = 0.;
+    }
+  }
+
+  // Set the chi2 / ndof cut used in the local track fit.
+  // Iterations are stopped when the cut factor reaches the ref. value (1).
+  m_cfactref = 1.;
+  m_cfactr = std::max(1., startfact);
+
+  return true;
+}
+
+//=============================================================================
+//
+//=============================================================================
+bool TbMillepede::fitGlobal() {
+
+  m_diag.assign(m_nagb, 0.);
+  std::vector<double> bgvecPrev(m_nagb, 0.);
+  std::vector<double> trackParams(2 * m_nalc + 2, 0.);
+  const unsigned int nTracks = m_equations.size();
+  std::vector<std::vector<double> > localParams(
+      nTracks, std::vector<double>(m_nalc, 0.));
+
+  const unsigned int nMaxIterations = 10;
+  unsigned int iteration = 1;
+  unsigned int nGoodTracks = nTracks;
+  while (iteration <= nMaxIterations) {
+    info() << "Iteration " << iteration << " (using " << nGoodTracks
+           << " tracks)" << endmsg;
+
+    // Save the diagonal elements.
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      m_diag[i] = m_cgmat[i][i];
+    }
+
+    unsigned int nFixed = 0;
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      if (m_fixed[i]) {
+        // Fixed global parameter.
+        ++nFixed;
+        for (unsigned int j = 0; j < m_nagb; ++j) {
+          // Reset row and column.
+          m_cgmat[i][j] = 0.0;
+          m_cgmat[j][i] = 0.0;
+        }
+      } else {
+        m_cgmat[i][i] += 1. / (m_psigm[i] * m_psigm[i]);
+      }
+    }
+    // Add the constraints equations.
+    unsigned int nRows = m_nagb;
+    for (const auto& constraint : m_constraints) {
+      double sum = constraint.rhs;
+      for (unsigned int j = 0; j < m_nagb; ++j) {
+        if (m_psigm[j] == 0.) {
+          m_cgmat[nRows][j] = 0.0;
+          m_cgmat[j][nRows] = 0.0;
+        } else {
+          m_cgmat[nRows][j] = nGoodTracks * constraint.coefficients[j];
+          m_cgmat[j][nRows] = m_cgmat[nRows][j];
+        }
+        sum -= constraint.coefficients[j] * m_dparm[j];
+      }
+      m_cgmat[nRows][nRows] = 0.0;
+      m_bgvec[nRows] = nGoodTracks * sum;
+      ++nRows;
+    }
+
+    double cor = 0.0;
+    if (iteration > 1) {
+      for (unsigned int j = 0; j < m_nagb; ++j) {
+        for (unsigned int i = 0; i < m_nagb; ++i) {
+          if (m_fixed[i]) continue;
+          cor += bgvecPrev[j] * m_cgmat[j][i] * bgvecPrev[i];
+          if (i == j) {
+            cor -= bgvecPrev[i] * bgvecPrev[i] / (m_psigm[i] * m_psigm[i]);
+          }
+        }
+      }
+    }
+    if (m_debug) debug() << " Final corr. is " << cor << endmsg;
+
+    // Do the matrix inversion.
+    const int rank = invertMatrix(m_cgmat, m_bgvec, nRows);
+    // Update the global parameters values.
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      m_dparm[i] += m_bgvec[i];
+      bgvecPrev[i] = m_bgvec[i];
+      if (m_debug) {
+        debug() << "bgvec[" << i << "] = " << m_bgvec[i] << endmsg;
+        debug() << "dparm[" << i << "] = " << m_dparm[i] << endmsg;
+        debug() << "cgmat[" << i << "][" << i << "] = " << m_cgmat[i][i]
+                << endmsg;
+        debug() << "err = " << sqrt(fabs(m_cgmat[i][i])) << endmsg;
+        debug() << "cgmat * diag = " << std::setprecision(5)
+                << m_cgmat[i][i] * m_diag[i] << endmsg;
+      }
+    }
+    if (nRows - nFixed - rank != 0) {
+      warning() << "The rank defect of the symmetric " << nRows << " by "
+                << nRows << " matrix is " << nRows - nFixed - rank << endmsg;
+    }
+    if (!m_iterate) break;
+    ++iteration;
+    if (iteration == nMaxIterations) break;
+    // Update the factor in the track chi2 cut.
+    const double newcfactr = sqrt(m_cfactr);
+    if (newcfactr > 1.2 * m_cfactref) {
+      m_cfactr = newcfactr;
+    } else {
+      m_cfactr = m_cfactref;
+    }
+    if (m_debug) {
+      debug() << "Refitting tracks with cut factor " << m_cfactr << endmsg;
+    }
+
+    // Reset global variables.
+    for (unsigned int i = 0; i < nRows; ++i) {
+      m_bgvec[i] = 0.0;
+      for (unsigned int j = 0; j < nRows; ++j) m_cgmat[i][j] = 0.0;
+    }
+    // Refit the tracks.
+    double chi2 = 0.;
+    double ndof = 0.;
+    nGoodTracks = 0;
+    for (unsigned int i = 0; i < nTracks; ++i) {
+      // Skip invalidated tracks.
+      if (m_equations[i].empty()) continue;
+      std::vector<Equation> equations(m_equations[i].begin(),
+                                      m_equations[i].end());
+      for (auto equation : equations) {
+        const unsigned int nG = equation.derG.size();
+        for (unsigned int j = 0; j < nG; ++j) {
+          const double t = localParams[i][equation.indNL[j]];
+          if (t == 0) continue;
+          equation.derG[j] += equation.derNL[j] * (t - equation.slopes[j]);
+        }
+      }
+      std::fill(trackParams.begin(), trackParams.end(), 0.);
+      // Refit the track.
+      bool ok = fitTrack(equations, trackParams, false, iteration);
+      // Cache the track state.
+      for (unsigned int j = 0; j < m_nalc; ++j) {
+        localParams[i][j] = trackParams[2 * j];
+      }
+      if (ok) {
+        // Update the total chi2.
+        chi2 += trackParams[2 * m_nalc + 1];
+        ndof += trackParams[2 * m_nalc];
+        ++nGoodTracks;
+      } else {
+        // Disable the track.
+        m_equations[i].clear();
+      }
+    }
+    info() << "Chi2 / DOF after re-fit: " << chi2 / (ndof - nRows) << endmsg;
+  }
+
+  // Print the final results.
+  printResults();
+
+  info() << endmsg;
+  info() << "            * o o                   o      " << endmsg;
+  info() << "              o o                   o      " << endmsg;
+  info() << "   o ooooo  o o o  oo  ooo   oo   ooo  oo  " << endmsg;
+  info() << "    o  o  o o o o o  o o  o o  o o  o o  o " << endmsg;
+  info() << "    o  o  o o o o oooo o  o oooo o  o oooo " << endmsg;
+  info() << "    o  o  o o o o o    ooo  o    o  o o    " << endmsg;
+  info() << "    o  o  o o o o  oo  o     oo   ooo  oo ++ ends." << endmsg;
+  info() << "                       o                   " << endmsg;
+  info() << endmsg;
+  return true;
+}
+
+//=============================================================================
+// Obtain solution of a system of linear equations with symmetric matrix
+// and the inverse (using 'singular-value friendly' GAUSS pivot).
+// Solve the equation V * X = B.
+// V is replaced by its inverse matrix and B by X, the solution vector
+//=============================================================================
+int TbMillepede::invertMatrix(std::vector<std::vector<double> >& v,
+                              std::vector<double>& b, const int n) {
+  int rank = 0;
+  const double eps = 0.0000000000001;
+
+  std::vector<double> diag(n, 0.);
+  std::vector<bool> used_param(n, true);
+  std::vector<bool> flag(n, true);
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j <= i; j++) {
+      v[j][i] = v[i][j];
+    }
+  }
+
+  // Find max. elements of each row and column.
+  std::vector<double> r(n, 0.);
+  std::vector<double> c(n, 0.);
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j < n; j++) {
+      if (fabs(v[i][j]) >= r[i]) r[i] = fabs(v[i][j]);
+      if (fabs(v[j][i]) >= c[i]) c[i] = fabs(v[j][i]);
+    }
+  }
+  for (int i = 0; i < n; i++) {
+    if (0.0 != r[i]) r[i] = 1. / r[i];
+    if (0.0 != c[i]) c[i] = 1. / c[i];
+    // Check if max elements are within requested precision.
+    if (eps >= r[i]) r[i] = 0.0;
+    if (eps >= c[i]) c[i] = 0.0;
+  }
+
+  // Equilibrate the V matrix
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j < n; j++) {
+      v[i][j] = sqrt(r[i]) * v[i][j] * sqrt(c[j]);
+    }
+  }
+
+  for (int i = 0; i < n; i++) {
+    // Save the absolute values of the diagonal elements.
+    diag[i] = fabs(v[i][i]);
+    if (r[i] == 0. && c[i] == 0.) {
+      // This part is empty (non-linear treatment with non constraints)
+      flag[i] = false;
+      used_param[i] = false;
+    }
+  }
+
+  for (int i = 0; i < n; i++) {
+    double vkk = 0.0;
+    int k = -1;
+    // First look for the pivot, i. e. the max unused diagonal element.
+    for (int j = 0; j < n; j++) {
+      if (flag[j] && (fabs(v[j][j]) > std::max(fabs(vkk), eps))) {
+        vkk = v[j][j];
+        k = j;
+      }
+    }
+
+    if (k >= 0) {
+      // Pivot found.
+      rank++;
+      // Use this value.
+      flag[k] = false;
+      // Replace pivot by its inverse.
+      vkk = 1.0 / vkk;
+      v[k][k] = -vkk;
+      for (int j = 0; j < n; j++) {
+        for (int jj = 0; jj < n; jj++) {
+          if (j != k && jj != k && used_param[j] && used_param[jj]) {
+            // Other elements (do them first as you use old v[k][j])
+            v[j][jj] = v[j][jj] - vkk * v[j][k] * v[k][jj];
+          }
+        }
+      }
+      for (int j = 0; j < n; j++) {
+        if (j != k && used_param[j]) {
+          v[j][k] = v[j][k] * vkk;
+          v[k][j] = v[k][j] * vkk;
+        }
+      }
+    } else {
+      // No more pivot value (clear those elements)
+      for (int j = 0; j < n; j++) {
+        if (flag[j]) {
+          b[j] = 0.0;
+          for (int k = 0; k < n; k++) {
+            v[j][k] = 0.0;
+            v[k][j] = 0.0;
+          }
+        }
+      }
+      break;
+    }
+  }
+  // Correct matrix V
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j < n; j++) {
+      v[i][j] = sqrt(c[i]) * v[i][j] * sqrt(r[j]);
+    }
+  }
+
+  std::vector<double> temp(n, 0.);
+  for (int j = 0; j < n; j++) {
+    // Reverse matrix elements
+    for (int jj = 0; jj < n; jj++) {
+      v[j][jj] = -v[j][jj];
+      temp[j] += v[j][jj] * b[jj];
+    }
+  }
+
+  for (int j = 0; j < n; j++) {
+    b[j] = temp[j];
+  }
+  return rank;
+}
+
+//=============================================================================
+// Simplified version.
+//=============================================================================
+int TbMillepede::invertMatrixLocal(std::vector<std::vector<double> >& v,
+                                   std::vector<double>& b, const int n) {
+
+  int rank = 0;
+  const double eps = 0.0000000000001;
+
+  std::vector<bool> flag(n, true);
+  std::vector<double> diag(n, 0.);
+  for (int i = 0; i < n; i++) {
+    // Save the absolute values of the diagonal elements.
+    diag[i] = fabs(v[i][i]);
+    for (int j = 0; j <= i; j++) {
+      v[j][i] = v[i][j];
+    }
+  }
+
+  for (int i = 0; i < n; i++) {
+    double vkk = 0.0;
+    int k = -1;
+    // First look for the pivot, i. e. the max. unused diagonal element.
+    for (int j = 0; j < n; j++) {
+      if (flag[j] && (fabs(v[j][j]) > std::max(fabs(vkk), eps * diag[j]))) {
+        vkk = v[j][j];
+        k = j;
+      }
+    }
+
+    if (k >= 0) {
+      // Pivot found
+      rank++;
+      flag[k] = false;
+      // Replace pivot by its inverse.
+      vkk = 1.0 / vkk;
+      v[k][k] = -vkk;
+      for (int j = 0; j < n; j++) {
+        for (int jj = 0; jj < n; jj++) {
+          if (j != k && jj != k) {
+            // Other elements (do them first as you use old v[k][j])
+            v[j][jj] = v[j][jj] - vkk * v[j][k] * v[k][jj];
+          }
+        }
+      }
+
+      for (int j = 0; j < n; j++) {
+        if (j != k) {
+          v[j][k] = v[j][k] * vkk;
+          v[k][j] = v[k][j] * vkk;
+        }
+      }
+    } else {
+      // No more pivot values (clear those elements).
+      for (int j = 0; j < n; j++) {
+        if (flag[j]) {
+          b[j] = 0.0;
+          for (k = 0; k < n; k++) v[j][k] = 0.0;
+        }
+      }
+      break;
+    }
+  }
+
+  std::vector<double> temp(n, 0.);
+  for (int j = 0; j < n; j++) {
+    // Reverse matrix elements
+    for (int jj = 0; jj < n; jj++) {
+      v[j][jj] = -v[j][jj];
+      temp[j] += v[j][jj] * b[jj];
+    }
+  }
+  for (int j = 0; j < n; j++) {
+    b[j] = temp[j];
+  }
+  return rank;
+}
+
+//=============================================================================
+// Return the limit in chi^2 / nd for n sigmas stdev authorized.
+// Only n=1, 2, and 3 are expected in input.
+//=============================================================================
+double TbMillepede::chi2Limit(const int n, const int nd) const {
+  constexpr double sn[3] = {0.47523, 1.690140, 2.782170};
+  constexpr double table[3][30] = {
+      {1.0000, 1.1479, 1.1753, 1.1798, 1.1775, 1.1730, 1.1680, 1.1630,
+       1.1581, 1.1536, 1.1493, 1.1454, 1.1417, 1.1383, 1.1351, 1.1321,
+       1.1293, 1.1266, 1.1242, 1.1218, 1.1196, 1.1175, 1.1155, 1.1136,
+       1.1119, 1.1101, 1.1085, 1.1070, 1.1055, 1.1040},
+      {4.0000, 3.0900, 2.6750, 2.4290, 2.2628, 2.1415, 2.0481, 1.9736,
+       1.9124, 1.8610, 1.8171, 1.7791, 1.7457, 1.7161, 1.6897, 1.6658,
+       1.6442, 1.6246, 1.6065, 1.5899, 1.5745, 1.5603, 1.5470, 1.5346,
+       1.5230, 1.5120, 1.5017, 1.4920, 1.4829, 1.4742},
+      {9.0000, 5.9146, 4.7184, 4.0628, 3.6410, 3.3436, 3.1209, 2.9468,
+       2.8063, 2.6902, 2.5922, 2.5082, 2.4352, 2.3711, 2.3143, 2.2635,
+       2.2178, 2.1764, 2.1386, 2.1040, 2.0722, 2.0428, 2.0155, 1.9901,
+       1.9665, 1.9443, 1.9235, 1.9040, 1.8855, 1.8681}};
+
+  if (nd < 1) return 0.;
+  const int m = std::max(1, std::min(n, 3));
+  if (nd <= 30) return table[m - 1][nd - 1];
+  return ((sn[m - 1] + sqrt(float(2 * nd - 3))) *
+          (sn[m - 1] + sqrt(float(2 * nd - 3)))) /
+         float(2 * nd - 2);
+}
+
+//=============================================================================
+// Multiply general M-by-N matrix A and N-vector X
+//=============================================================================
+bool TbMillepede::multiplyAX(const std::vector<std::vector<double> >& a,
+                             const std::vector<double>& x,
+                             std::vector<double>& y, const unsigned int n,
+                             const unsigned int m) {
+
+  // Y = A * X, where
+  //   A = general M-by-N matrix
+  //   X = N vector
+  //   Y = M vector
+  for (unsigned int i = 0; i < m; ++i) {
+    y[i] = 0.0;
+    for (unsigned int j = 0; j < n; ++j) {
+      y[i] += a[i][j] * x[j];
+    }
+  }
+  return true;
+}
+
+//=============================================================================
+// Multiply symmetric N-by-N matrix V from the left with general M-by-N
+// matrix A and from the right with the transposed of the same general
+// matrix to form a symmetric M-by-M matrix W.
+//=============================================================================
+bool TbMillepede::multiplyAVAt(const std::vector<std::vector<double> >& v,
+                               const std::vector<std::vector<double> >& a,
+                               std::vector<std::vector<double> >& w,
+                               const unsigned int n, const unsigned int m) {
+
+  // W = A * V * AT, where
+  //   V = symmetric N-by-N matrix
+  //   A = general N-by-M matrix
+  //   W = symmetric M-by-M matrix
+  for (unsigned int i = 0; i < m; ++i) {
+    for (unsigned int j = 0; j <= i; ++j) {
+      // Reset the final matrix.
+      w[i][j] = 0.0;
+      // Fill the upper left triangle.
+      for (unsigned int k = 0; k < n; ++k) {
+        for (unsigned int l = 0; l < n; ++l) {
+          w[i][j] += a[i][k] * v[k][l] * a[j][l];
+        }
+      }
+      // Fill the rest.
+      w[j][i] = w[i][j];
+    }
+  }
+
+  return true;
+}
+
+//=============================================================================
+// Print results
+//=============================================================================
+bool TbMillepede::printResults() {
+  const std::string line(85, '-');
+  info() << line << endmsg;
+  info() << " Result of fit for global parameters" << endmsg;
+  info() << line << endmsg;
+  info() << "   I    Difference    Last step      "
+         << "Error        Pull     Global corr." << endmsg;
+  info() << line << endmsg;
+  for (unsigned int i = 0; i < m_nagb; ++i) {
+    double err = sqrt(fabs(m_cgmat[i][i]));
+    if (m_cgmat[i][i] < 0.0) err = -err;
+    if (fabs(m_cgmat[i][i] * m_diag[i]) > 0) {
+      info() << std::setprecision(6) << std::fixed;
+      // Calculate the pull.
+      const double pull =
+          m_dparm[i] / sqrt(m_psigm[i] * m_psigm[i] - m_cgmat[i][i]);
+      // Calculate the global correlation coefficient
+      // (correlation between the parameter and all the other variables).
+      const double gcor = sqrt(fabs(1.0 - 1.0 / (m_cgmat[i][i] * m_diag[i])));
+      info() << std::setw(4) << i << "   " << std::setw(10) << m_dparm[i]
+             << "   " << std::setw(10) << m_bgvec[i] << "   " << std::setw(10)
+             << std::setprecision(5) << err << "   " << std::setw(10)
+             << std::setprecision(5) << pull << "   " << std::setw(10) << gcor
+             << endmsg;
+    } else {
+      info() << std::setw(4) << i << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF" << endmsg;
+    }
+    if ((i + 1) % (m_nagb / 6) == 0) info() << line << endmsg;
+  }
+  if (m_debug) {
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      debug() << " i=" << i
+              << "  sqrt(fabs(cgmat[i][i]))=" << sqrt(fabs(m_cgmat[i][i]))
+              << " diag = " << m_diag[i] << endmsg;
+    }
+  }
+
+  return true;
+}
diff --git a/TbAlignment/src/.svn/text-base/TbMillepede.h.svn-base b/TbAlignment/src/.svn/text-base/TbMillepede.h.svn-base
new file mode 100644
index 0000000..aebed80
--- /dev/null
+++ b/TbAlignment/src/.svn/text-base/TbMillepede.h.svn-base
@@ -0,0 +1,144 @@
+#pragma once
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+/** @class TbMillepede TbMillepede.h
+ *
+ *  Implementation of the Millepede algorithm.
+ *
+ *  @author Christoph Hombach
+ *  @date   2012-06-19
+ */
+
+class TbMillepede : public TbAlignmentBase {
+ public:
+  /// Constructor
+  TbMillepede(const std::string& type, const std::string& name,
+              const IInterface* parent);
+  /// Destructor
+  virtual ~TbMillepede();
+
+  virtual StatusCode initialize();
+
+  void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+
+  virtual void updateGeometry();
+
+ private:
+  struct Equation {
+    double rmeas;
+    double weight;
+    std::vector<int> indG;
+    std::vector<double> derG;
+    std::vector<int> indL;
+    std::vector<double> derL;
+    std::vector<int> indNL;
+    std::vector<double> derNL;
+    std::vector<double> slopes;
+  };
+  struct Constraint {
+    /// Right-hand side (Lagrange multiplier)
+    double rhs;
+    /// Coefficients
+    std::vector<double> coefficients;
+  };
+
+  /// (Re-)initialise matrices and vectors.
+  bool reset(const unsigned int nPlanes, const double startfact);
+  /// Setup the constraint equations.
+  void setConstraints(const unsigned int nPlanes);
+  /// Define a single constraint equation
+  void addConstraint(const std::vector<double>& dercs, const double rhs);
+  /// Add the equations for one track and do the local fit.
+  bool putTrack(LHCb::TbTrack* track, const unsigned int nPlanes);
+  /// Store the parameters for one measurement.
+  void addEquation(std::vector<Equation>& equations,
+                   const std::vector<double>& derlc,
+                   const std::vector<double>& dergb,
+                   const std::vector<double>& dernl,
+                   const std::vector<int>& dernli,
+                   const std::vector<double>& dernls, const double rmeas,
+                   const double sigma);
+  /// Perform local parameters fit using the equations for one track.
+  bool fitTrack(const std::vector<Equation>& equations,
+                std::vector<double>& trackParams, const bool singlefit,
+                const unsigned int iteration);
+  /// Perform global parameters fit.
+  bool fitGlobal();
+  /// Print the results of the global parameters fit.
+  bool printResults();
+
+  /// Matrix inversion and solution for global fit.
+  int invertMatrix(std::vector<std::vector<double> >& v, std::vector<double>& b,
+                   const int n);
+  /// Matrix inversion and solution for local fit.
+  int invertMatrixLocal(std::vector<std::vector<double> >& v,
+                        std::vector<double>& b, const int n);
+
+  /// Return the limit in chi2 / ndof for n sigmas.
+  double chi2Limit(const int n, const int nd) const;
+  /// Multiply matrix and vector
+  bool multiplyAX(const std::vector<std::vector<double> >& a,
+                  const std::vector<double>& x, std::vector<double>& y,
+                  const unsigned int n, const unsigned int m);
+  /// Multiply matrices
+  bool multiplyAVAt(const std::vector<std::vector<double> >& v,
+                    const std::vector<std::vector<double> >& a,
+                    std::vector<std::vector<double> >& w, const unsigned int n,
+                    const unsigned int m);
+
+  /// Number of global derivatives
+  unsigned int m_nagb;
+  /// Number of local derivatives
+  unsigned int m_nalc;
+
+  /// Equations for each track
+  std::vector<std::vector<Equation> > m_equations;
+  /// Constraint equations
+  std::vector<Constraint> m_constraints;
+
+  ///  Flag for each global parameter whether it is fixed or not.
+  std::vector<bool> m_fixed;
+  /// Sigmas for each global parameter.
+  std::vector<double> m_psigm;
+
+  std::vector<std::vector<double> > m_cgmat;
+  std::vector<std::vector<double> > m_corrm;
+  std::vector<std::vector<double> > m_clcmat;
+
+  std::vector<double> m_bgvec;
+  std::vector<double> m_corrv;
+  std::vector<double> m_diag;
+
+  /// Difference in misalignment parameters with respect to initial values.
+  std::vector<double> m_dparm;
+
+  /// Mapping of internal numbering to geometry service planes.
+  std::vector<unsigned int> m_millePlanes;
+
+  bool m_debug;
+  /// Flag to switch on/off iterations in the global fit.
+  bool m_iterate;
+  /// Residual cut after the first iteration.
+  double m_rescut;
+  /// Residual cut in the first iteration.
+  double m_rescut_init;
+  /// Factor in chisquare / ndof cut.
+  double m_cfactr;
+  /// Reference value for chisquare / ndof cut factor.
+  double m_cfactref;
+  // Number of standard deviations for chisquare / ndof cut.
+  int m_nstdev;
+  /// Number of "full" iterations (with geometry updates).
+  unsigned int m_nIterations;
+  /// Sigmas for each degree of freedom
+  std::vector<double> m_sigmas;
+  /// Planes to be kept fixed
+  std::vector<unsigned int> m_fixedPlanes;
+  /// Flag to fix all degrees of freedom or only the translations.
+  bool m_fix_all;
+};
diff --git a/TbAlignment/src/TbAlignment.cpp b/TbAlignment/src/TbAlignment.cpp
new file mode 100755
index 0000000..6d6bdc9
--- /dev/null
+++ b/TbAlignment/src/TbAlignment.cpp
@@ -0,0 +1,137 @@
+#include <fstream>
+
+// Gaudi
+#include "GaudiKernel/IEventProcessor.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbModule.h"
+#include "TbKernel/TbAlignmentTrack.h"
+
+// Local
+#include "TbAlignment.h"
+
+DECLARE_ALGORITHM_FACTORY(TbAlignment)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignment::TbAlignment(const std::string &name, ISvcLocator *pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator), m_lastTrackPrint(0), m_tracks() {
+
+  declareProperty("OutputAlignmentFile", m_outputFile = "Alignment_out.dat");
+  declareProperty("AlignmentTechniques", m_alignmentSequence);
+  declareProperty("NTracks", m_nTracks = 0);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignment::~TbAlignment() {
+
+  // Delete the alignment tracks.
+  for (auto track : m_tracks) {
+    if (track) delete track;
+  }
+  m_tracks.clear();
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbAlignment::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  if (m_alignmentSequence.empty()) {
+    return Error("Alignment sequence is empty.");
+  }
+  unsigned int scounter = 0;
+  for (const auto &toolName : m_alignmentSequence) {
+    info() << "Adding tool " << toolName << endmsg;
+    const std::string name = "s" + std::to_string(scounter++);
+    TbAlignmentBase* newTool = tool<TbAlignmentBase>(toolName, name, this);
+    if (!newTool) return Error("Cannot retrieve tool " + toolName);
+    m_toolChain.push_back(newTool);
+  }
+  m_toolIterator = m_toolChain.begin();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbAlignment::execute() {
+
+  auto currentTool = *m_toolIterator;
+  StatusCode sc = currentTool->execute(m_tracks);
+  if (sc.isFailure()) return sc;
+
+  const unsigned int nTracks = m_tracks.size();
+  if (nTracks - (nTracks % 1000) != m_lastTrackPrint) {
+    m_lastTrackPrint = nTracks - (nTracks % 1000);
+    info() << "Collected " << m_lastTrackPrint << " alignment tracks" << endmsg;
+  }
+  // If requested, stop processing events after a given number of tracks.
+  if (m_nTracks > 0 && nTracks > m_nTracks) {
+    currentTool->plotResiduals(m_tracks, "Before");
+    currentTool->align(m_tracks);
+    currentTool->plotResiduals(m_tracks, "After");
+    ++m_toolIterator;
+    if (m_toolIterator == m_toolChain.end()) {
+      SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+      if (app) app->stopRun();
+      return StatusCode::SUCCESS;
+    }
+    currentTool = *m_toolIterator;
+    // Reset track cache
+    if (currentTool->clearTracks()) {
+      for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+        if (*it) delete *it;
+      }
+      m_tracks.clear();
+      m_lastTrackPrint = 0;
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalization
+//=============================================================================
+StatusCode TbAlignment::finalize() {
+
+  if (m_toolIterator != m_toolChain.end()) {
+    info() << "Event loop terminating before chain completion" << endmsg;
+    (*m_toolIterator)->align(m_tracks);
+  }
+  writeAlignmentFile();
+  // Finalise the base class.
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Save the alignment constants to file
+//=============================================================================
+bool TbAlignment::writeAlignmentFile() {
+  // Write results to output file
+  info() << "Writing alignment output file to " << m_outputFile << endmsg;
+  std::ofstream txtfile(m_outputFile.c_str());
+  if (!txtfile) {
+    error() << "Cannot create file " << m_outputFile << endmsg;
+    return false;
+  }
+  auto modules = geomSvc()->modules();
+  for (auto im = modules.begin(), end = modules.end(); im != end; ++im) {
+    txtfile << (*im)->id() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->x() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->y() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->z() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->rotX() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->rotY() << "  " << std::setw(12) << std::setprecision(10)
+            << (*im)->rotZ() << std::endl;
+  }
+  txtfile.close();
+  return true;
+}
diff --git a/TbAlignment/src/TbAlignment.h b/TbAlignment/src/TbAlignment.h
new file mode 100644
index 0000000..4007aeb
--- /dev/null
+++ b/TbAlignment/src/TbAlignment.h
@@ -0,0 +1,51 @@
+#ifndef TBALIGNMENT_H
+#define TBALIGNMENT_H 1
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+/** @class TbAlignment TbAlignment.h
+ *
+ *  Algorithm for telescope alignment.
+ *
+ *  @author Angelo Di Canto
+ *  @date   2014-04-22
+ */
+
+class TbAlignmentTrack;
+
+class TbAlignment : public TbAlgorithm {
+
+ public:
+  /// Standard constructor
+  TbAlignment(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbAlignment();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+
+ private:
+  /// Output alignment file
+  std::string m_outputFile;
+  /// Alignment methods to be run
+  std::vector<std::string> m_alignmentSequence;
+  /// For the track counter printout
+  unsigned int m_lastTrackPrint;
+
+  /// Tracks for alignment
+  std::vector<TbAlignmentTrack*> m_tracks;
+  /// Number of alignment tracks after which to stop processsing.
+  unsigned int m_nTracks;
+
+  std::vector<TbAlignmentBase*> m_toolChain;
+  std::vector<TbAlignmentBase*>::iterator m_toolIterator;
+
+  bool writeAlignmentFile();
+};
+
+#endif  // TBALIGNMENT_H
diff --git a/TbAlignment/src/TbAlignmentBase.cpp b/TbAlignment/src/TbAlignmentBase.cpp
new file mode 100644
index 0000000..af0ea59
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentBase.cpp
@@ -0,0 +1,240 @@
+// ROOT
+#include <TH1D.h>
+#include <TProfile.h>
+#include <TFitResult.h>
+#include <TFitResultPtr.h>
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IProfile1D.h"
+
+// Gaudi
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentBase::TbAlignmentBase(const std::string& type,
+                                 const std::string& name,
+                                 const IInterface* parent)
+    : GaudiHistoTool(type, name, parent),
+      m_trackFit(nullptr),
+      m_geomSvc(nullptr) {
+
+  declareInterface<TbAlignmentBase>(this);
+
+  declareProperty("TrackLocation", 
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("DOFs", m_dofs = {});
+  declareProperty("ClearTracks", m_clearTracks = true);
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+  declareProperty("Monitoring", m_monitoring = false);
+  declareProperty("MaxChi2", m_maxChi2 = 100.);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbAlignmentBase::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiHistoTool::initialize();
+  if (sc.isFailure()) return sc;
+  m_modules = geomSvc()->modules();
+  m_nPlanes = m_modules.size();
+  m_masked.resize(m_nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) m_masked[plane] = true;
+
+  // Set the degrees of freedom.
+  if (m_dofs.size() != 6) {
+    info() << "Using the default degrees of freedom:" << endmsg;
+    if (m_dofsDefault.size() != 6) {
+      // Default DoFs are not defined. Set them.
+      m_dofsDefault = {true, true, false, true, true, true};
+    }
+    m_dofs = m_dofsDefault;
+  } else {
+    info() << "Using the following degrees of freedom:" << endmsg;
+  }
+  // Print the degrees of freedom.
+  const std::vector<std::string> labels = {"Translation X", "Translation Y",
+                                           "Translation Z", "Rotation X",
+                                           "Rotation Y",    "Rotation Z"};
+  for (unsigned int i = 0; i < 6; ++i) {
+    const std::string on = m_dofs[i] ? "ON" : "OFF";
+    info() << format("  %-14s  %-3s", labels[i].c_str(), on.c_str()) << endmsg;
+  }
+
+  // Set up the track fit tool.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  if (!m_trackFit) {
+    return Error("Failed to initialise track fit.");
+  }
+  return StatusCode::SUCCESS;
+}
+
+void TbAlignmentBase::plotResiduals(std::vector<TbAlignmentTrack*>& tracks,
+                                    const std::string& tag) {
+
+  if (!m_monitoring) return;
+  // Book histograms.
+  std::vector<AIDA::IHistogram1D*> hResGlobalX;
+  std::vector<AIDA::IHistogram1D*> hResGlobalY;
+  std::vector<AIDA::IProfile1D*> hResGlobalXvsGlobalX;
+  std::vector<AIDA::IProfile1D*> hResGlobalYvsGlobalY;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = "Plane " + plane;
+    // Distribution of unbiased global x-residuals.
+    std::string name = tag + "/UnbiasedResiduals/GlobalX/Plane" + plane;
+    double low(-0.2);
+    double high(0.2);
+    unsigned int bins(200);
+    hResGlobalX.push_back(book1D(name, title, low, high, bins));
+    // Distribution of unbiased global y-residuals.
+    name = tag + "/UnbiasedResiduals/GlobalY/Plane" + plane;
+    hResGlobalY.push_back(book1D(name, title, low, high, bins));
+    // Profile of unbiased global x-residuals as function of global x.
+    low = -20.;
+    high = 20.;
+    bins = 200;
+    name = "UnbiasedResiduals/GlobalResXvsGlobalX/Plane" + plane;
+    hResGlobalXvsGlobalX.push_back(
+        bookProfile1D(name, title, low, high, bins));
+    // Profile of unbiased global y-residuals as function of global y.
+    name = "UnbiasedResiduals/GlobalResYvsGlobalY/Plane" + plane;
+    hResGlobalYvsGlobalY.push_back(
+        bookProfile1D(name, title, low, high, bins));
+  }
+  std::vector<double> ty(m_nPlanes, 0.);
+  std::vector<double> yty(m_nPlanes, 0.);
+  std::vector<double> y(m_nPlanes, 0.);
+  std::vector<double> yy(m_nPlanes, 0.);
+  std::vector<double> tyty(m_nPlanes, 0.);
+
+  for (auto& at : tracks) {
+    // Get the track object.
+    LHCb::TbTrack* track = at->track();
+    // Loop over the clusters on the track.
+    auto clusters = track->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      const unsigned int plane = (*ic)->plane();
+      const LHCb::TbCluster* cluster = *ic;
+      // Refit the track without this cluster.
+      m_trackFit->maskPlane(plane);
+      m_trackFit->fit(track);
+      // Calculate the global x and y residuals.
+      const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, plane);
+      const auto pLocal = Gaudi::XYZPoint(cluster->xloc(), cluster->yloc(), 0);
+      const auto pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      const double dxug = pGlobal.x() - intercept.x();
+      const double dyug = pGlobal.y() - intercept.y();
+
+      ty[plane] += track->firstState().ty();
+      yty[plane] += track->firstState().ty() * pGlobal.y();
+      y[plane] += pGlobal.y();
+      yy[plane] += pGlobal.y() * pGlobal.y();
+      tyty[plane] += track->firstState().ty() * track->firstState().ty();
+
+      hResGlobalX[plane]->fill(dxug);
+      hResGlobalY[plane]->fill(dyug);
+      hResGlobalXvsGlobalX[plane]->fill(pGlobal.x(), dxug);
+      hResGlobalYvsGlobalY[plane]->fill(pGlobal.y(), dyug);
+      m_trackFit->unmaskPlane(plane);
+    }
+    m_trackFit->fit(track);
+    // Loop over the associated clusters.
+    auto aclusters = track->associatedClusters();
+    for (auto it = aclusters.cbegin(), end = aclusters.cend(); it != end; ++it) {
+      const unsigned int plane = (*it)->plane();
+      // Calculate the global x and y residuals.
+      const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, plane);
+      const auto pLocal = Gaudi::XYZPoint((*it)->xloc(), (*it)->yloc(), 0);
+      const auto pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      const double dxug = pGlobal.x() - intercept.x();
+      const double dyug = pGlobal.y() - intercept.y();
+      hResGlobalX[plane]->fill(dxug);
+      hResGlobalY[plane]->fill(dyug);
+      hResGlobalXvsGlobalX[plane]->fill(pGlobal.x(), dxug);
+      hResGlobalYvsGlobalY[plane]->fill(pGlobal.y(), dyug);
+    }
+  }
+
+  if (msgLevel(MSG::DEBUG)) {
+    const unsigned int nTracks = tracks.size();
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      y[i] /= nTracks;
+      ty[i] /= nTracks;
+      yty[i] /= nTracks;
+      yy[i] /= nTracks;
+      tyty[i] /= nTracks;
+      info() << "Plane " << i << ": Pearson-coefficient = "
+             << (yty[i] - y[i] * ty[i]) /
+                    (sqrt(yy[i] - y[i] * y[i]) *
+                     sqrt(tyty[i] - ty[i] * ty[i])) << endmsg;
+    }
+  }
+  // Fit the residual distributions and print the fit results.
+  const std::string line(85, '-');
+  info() << line << endmsg; 
+  info() << "Plane     Mean X [\u03bcm]       Mean Y [\u03bcm]      "
+         << "Sigma X [\u03bcm]     Sigma Y [\u03bcm]" << endmsg; 
+  info() << line << endmsg; 
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    auto hx = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalX[i]);
+    auto hy = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalY[i]);
+    if (hx->GetEntries() == 0 || hy->GetEntries() == 0) continue;
+    TFitResultPtr rx = hx->Fit("gaus", "QS0");
+    TFitResultPtr ry = hy->Fit("gaus", "QS0");
+    if (!rx.Get() || !ry.Get()) continue;
+    info() << std::setprecision(4);
+    info() << format(" %3u   % 5.3f +/- %4.3f  % 5.3f +/- %4.3f ", i,
+                     1.e3 * rx->Parameter(1), 1.e3 * rx->Error(1),
+                     1.e3 * ry->Parameter(1), 1.e3 * ry->Error(1)) 
+           << format(" %4.3f +/- %4.3f  %4.3f +/- %4.3f", 
+                     1.e3 * rx->Parameter(2), 1.e3 * rx->Error(2),
+                     1.e3 * ry->Parameter(2), 1.e3 * ry->Error(2)) << endmsg; 
+  }
+  // Fit the profiles (x/y residuals vs. global x/y) and print the results.
+  info() << line << endmsg; 
+  info() << "Plane     Slope X [\u03bcm]       Slope Y [\u03bcm]" << endmsg;
+  info() << line << endmsg; 
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    auto xgx = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalXvsGlobalX[i]);
+    auto ygy = Gaudi::Utils::Aida2ROOT::aida2root(hResGlobalYvsGlobalY[i]);
+    if (xgx->GetEntries() == 0 || ygy->GetEntries() == 0) continue;
+    TFitResultPtr rbx = xgx->Fit("pol1", "QS0");
+    TFitResultPtr rby = ygy->Fit("pol1", "QS0");
+    if (!rbx.Get() || !rby.Get()) continue;
+    info() << std::setprecision(4);
+    info() << format(" %3u   % 5.3f +/- %4.3f   % 5.3f +/- %4.3f ", i,
+                     1.e3 * rbx->Parameter(1), 1.e3 * rbx->Error(1),
+                     1.e3 * rby->Parameter(1), 1.e3 * rby->Error(1))
+           << endmsg;
+  }
+  info() << line << endmsg; 
+
+}
+
+//=============================================================================
+// Collect alignment tracks (called at each event).
+//=============================================================================
+StatusCode TbAlignmentBase::execute(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  // Get the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  // Add them to the alignment track store.
+  for (LHCb::TbTrack* track : *tracks) {
+    if (track->chi2() > m_maxChi2 || isEdge( track ) ) continue ;  
+    TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
+    alignmentTracks.push_back(alignmentTrack);
+  }
+  return StatusCode::SUCCESS;
+}
diff --git a/TbAlignment/src/TbAlignmentBase.h b/TbAlignment/src/TbAlignmentBase.h
new file mode 100644
index 0000000..d3f2e3e
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentBase.h
@@ -0,0 +1,88 @@
+#pragma once
+
+
+// Gaudi
+#include "GaudiAlg/GaudiHistoTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/TbAlignmentTrack.h"
+#include "TbKernel/TbModule.h"
+#include "TbKernel/ITbTrackFit.h"
+
+static const InterfaceID IID_TbAlignmentBase("TbAlignmentBase", 1, 0);
+
+class TbAlignmentBase : public GaudiHistoTool {
+
+ public:
+  /// Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_TbAlignmentBase; }
+  /// Constructor
+  TbAlignmentBase(const std::string& type, const std::string& name,
+                  const IInterface* parent);
+  /// Destructor
+  ~TbAlignmentBase() {}
+
+  virtual StatusCode initialize();
+
+  /// Store tracks/clusters to be used for the alignment (called each event).
+  virtual StatusCode execute(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  /// Alignment function (called after enough tracks have been collected).
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks) = 0;
+
+  bool clearTracks() const { return m_clearTracks; }
+  /// Fill monitoring histograms.
+  void plotResiduals(std::vector<TbAlignmentTrack*>& tracks,
+                     const std::string& tag);
+
+ protected:
+  /// TES location of tracks.
+  std::string m_trackLocation;
+  /// Chi2 cut on tracks to be used for alignment 
+  double m_maxChi2;
+  /// Degrees of freedom
+  std::vector<bool> m_dofs;
+  /// Default degrees of freedom
+  std::vector<bool> m_dofsDefault;
+  /// List of masked planes
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+  /// Flag to produce monitoring histograms.
+  bool m_monitoring;
+  /// Flag to reset the track store before collecting alignment tracks.
+  bool m_clearTracks;
+
+  std::vector<TbModule*> m_modules;
+  unsigned int m_nPlanes;
+  /// Track fit tool
+  ITbTrackFit* m_trackFit;
+
+  bool masked(const unsigned int plane) const {
+    return plane < m_masked.size() ? m_masked[plane] : false;
+  }
+
+  /// Pointer to the geometry service.
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// On-demand access to the geometry service.
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+  /// Determine whether a track passes the edge region of a plane.
+  bool isEdge(const LHCb::TbTrack* track) {
+    for (auto cluster : track->clusters()) {
+      if (isEdge(cluster)) return true;
+    }
+    return false;
+  }
+  /// Determine whether a cluster is close to the edge region of a plane.
+  bool isEdge(const LHCb::TbCluster* cluster) {
+    return cluster->xloc() <  0.5 ||
+           cluster->xloc() > 13.5 ||
+           cluster->yloc() < 0.5 ||
+           cluster->yloc() > 13.5 ;
+  }
+
+
+};
diff --git a/TbAlignment/src/TbAlignmentMinuit0.cpp b/TbAlignment/src/TbAlignmentMinuit0.cpp
new file mode 100644
index 0000000..5ed40c4
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuit0.cpp
@@ -0,0 +1,100 @@
+#include "TbAlignmentMinuit0.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentMinuit0)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuit0::TbAlignmentMinuit0(const std::string& type,
+                                       const std::string& name,
+                                       const IInterface* parent)
+    : TbAlignmentMinuitBase(type, name, parent) {
+
+  declareProperty("ReferencePlane", m_referencePlane = 999);
+
+  m_dofsDefault = {true, true, false, true, true, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuit0::~TbAlignmentMinuit0() {}
+
+//=============================================================================
+// Calculate the chi2.
+//=============================================================================
+void TbAlignmentMinuit0::chi2(double& f, double* par, double* /*g*/) {
+
+  // Assign new aligment constants
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    (*im)->setAlignment(par[6 * i + 0], par[6 * i + 1], par[6 * i + 2],
+                        par[6 * i + 3], par[6 * i + 4], par[6 * i + 5]);
+  }
+
+  // Loop over tracks
+  f = 0.;
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    // Update global coordinates of the clusters
+    SmartRefVector<LHCb::TbCluster> clusters = (*it)->track()->clusters();
+    for (auto ic = clusters.begin(), end = clusters.end(); ic != end; ++ic) {
+      Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+      const unsigned int plane = (*ic)->plane();
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      (*ic)->setX(pGlobal.x());
+      (*ic)->setY(pGlobal.y());
+      (*ic)->setZ(pGlobal.z());
+    }
+    // Refit track with new cluster positions
+    m_trackFit->fit((*it)->track());
+    // Add the new track chi2 to the overall chi2
+    f += (*it)->track()->chi2();
+  }
+}
+//=============================================================================
+// Main alignment function.
+//=============================================================================
+void TbAlignmentMinuit0::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  TbAlignmentMinuitBase::align(alignmentTracks);
+  info() << "Minuit technique 0" << endmsg;
+  double arglist[2];
+  arglist[0] = 10000;
+  arglist[1] = 1.e-2;
+
+  for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
+    info() << "Iteration " << iteration + 1 << "/" << m_nIterations << endmsg;
+    // Align detector modules one at a time
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      // Skip reference plane and masked planes.
+      if (i == m_referencePlane || masked(i)) continue;
+      // Wobble this plane and fix the others.
+      for (unsigned int j = 0; j < m_nPlanes; ++j) {
+        if (i != j) {
+          m_fitter->FixParameter(6 * j + 0);  // x
+          m_fitter->FixParameter(6 * j + 1);  // y
+          m_fitter->FixParameter(6 * j + 2);  // z
+          m_fitter->FixParameter(6 * j + 3);  // Rx
+          m_fitter->FixParameter(6 * j + 4);  // Ry
+          m_fitter->FixParameter(6 * j + 5);  // Rz
+        } else {
+          info() << "*** Wobbling detector " << j << endmsg;
+          for (unsigned int k = 0; k < 6; ++k) {
+            if (m_dofs[k]) {
+              m_fitter->ReleaseParameter(6 * j + k);
+            } else {
+              m_fitter->FixParameter(6 * j + k);
+            }
+          }
+        }
+      }
+      // Execute minimization and calculate proper error matrix
+      m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
+      m_fitter->ExecuteCommand("HESSE", arglist, 1);
+      if (msgLevel(MSG::INFO))
+        m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
+    }
+  }
+  updateGeometry();
+}
diff --git a/TbAlignment/src/TbAlignmentMinuit0.h b/TbAlignment/src/TbAlignmentMinuit0.h
new file mode 100644
index 0000000..716f923
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuit0.h
@@ -0,0 +1,21 @@
+#pragma once
+
+// Local
+#include "TbAlignmentMinuitBase.h"
+
+class TbAlignmentMinuit0 : public TbAlignmentMinuitBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuit0(const std::string& type, const std::string& name,
+                     const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuit0();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  void chi2(double& f, double* par, double* g);
+
+ private:
+  /// Plane to be kept fixed
+  unsigned int m_referencePlane;
+};
diff --git a/TbAlignment/src/TbAlignmentMinuit1.cpp b/TbAlignment/src/TbAlignmentMinuit1.cpp
new file mode 100644
index 0000000..08ac8f5
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuit1.cpp
@@ -0,0 +1,110 @@
+#include "TbAlignmentMinuit1.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentMinuit1)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuit1::TbAlignmentMinuit1(const std::string& type,
+                                       const std::string& name,
+                                       const IInterface* parent)
+    : TbAlignmentMinuitBase(type, name, parent) {
+
+  declareProperty("ReferencePlane", m_referencePlane = 999);
+
+  m_dofsDefault = {true, true, false, false, false, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuit1::~TbAlignmentMinuit1() {}
+
+//=============================================================================
+// Calculate the chi2.
+//=============================================================================
+void TbAlignmentMinuit1::chi2(double& f, double* par, double* /*g*/) {
+
+  // Assign new aligment constants
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    (*im)->setAlignment(par[6 * i + 0], par[6 * i + 1], par[6 * i + 2],
+                        par[6 * i + 3], par[6 * i + 4], par[6 * i + 5]);
+  }
+
+  // Loop over tracks
+  f = 0.;
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    // Get global position of each cluster relative to the reference cluster
+    auto clusters = (*it)->track()->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      // Skip reference plane
+      const unsigned int plane = (*ic)->plane();
+      if (plane == m_referencePlane) continue;
+      // Transform local cluster coordinates to global frame
+      Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      // Calculate residuals wrt reference
+      const double xresidual = pGlobal.x() - (*it)->xOnReferencePlane();
+      const double yresidual = pGlobal.y() - (*it)->yOnReferencePlane();
+      // Add residuals to chi2
+      f += xresidual * xresidual + yresidual * yresidual;
+    }
+  }
+}
+
+//=============================================================================
+// Main alignment function.
+//=============================================================================
+void TbAlignmentMinuit1::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  TbAlignmentMinuitBase::align(alignmentTracks);
+  info() << "Minuit technique 1" << endmsg;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const unsigned int offset = 6 * i;
+    // Fix unwanted detectors
+    if (i == m_referencePlane || masked(i)) {
+      info() << "*** Detector " << i << " will be held fixed" << endmsg;
+      m_fitter->FixParameter(offset + 0);  // x
+      m_fitter->FixParameter(offset + 1);  // y
+      m_fitter->FixParameter(offset + 2);  // z
+      m_fitter->FixParameter(offset + 3);  // Rx
+      m_fitter->FixParameter(offset + 4);  // Ry
+      m_fitter->FixParameter(offset + 5);  // Rz
+    } else {
+      for (unsigned int j = 0; j < 6; ++j) {
+        if (m_dofs[j]) {
+          m_fitter->ReleaseParameter(offset + j);
+        } else {
+          m_fitter->FixParameter(offset + j);
+        }
+      }
+    }
+  }
+
+  // Loop over tracks and get global position of the reference cluster.
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    auto clusters = (*it)->track()->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      // Find reference cluster
+      const unsigned int plane = (*ic)->plane();
+      if (plane != m_referencePlane) continue;
+      // Transform local cluster coordinates to global frame
+      Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+      Gaudi::XYZPoint pGlobal = geomSvc()->localToGlobal(pLocal, plane);
+      (*it)->setXOnReferencePlane(pGlobal.x());
+      (*it)->setYOnReferencePlane(pGlobal.y());
+      break;
+    }
+  }
+
+  // Execute minimization and calculate proper error matrix
+  double arglist[2];
+  arglist[0] = 10000;
+  arglist[1] = 1.e-2;
+  m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
+  m_fitter->ExecuteCommand("HESSE", arglist, 1);
+  if (msgLevel(MSG::INFO)) m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
+  updateGeometry();
+}
diff --git a/TbAlignment/src/TbAlignmentMinuit1.h b/TbAlignment/src/TbAlignmentMinuit1.h
new file mode 100644
index 0000000..36356a3
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuit1.h
@@ -0,0 +1,21 @@
+#pragma once
+
+// Local
+#include "TbAlignmentMinuitBase.h"
+
+class TbAlignmentMinuit1 : public TbAlignmentMinuitBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuit1(const std::string& type, const std::string& name,
+                     const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuit1();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  void chi2(double& f, double* par, double* g);
+
+ private:
+  /// Plane to be kept fixed.
+  unsigned int m_referencePlane;
+};
diff --git a/TbAlignment/src/TbAlignmentMinuit2.cpp b/TbAlignment/src/TbAlignmentMinuit2.cpp
new file mode 100644
index 0000000..028a512
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuit2.cpp
@@ -0,0 +1,239 @@
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbAlignmentMinuit2.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentMinuit2)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuit2::TbAlignmentMinuit2(const std::string& type,
+                                       const std::string& name,
+                                       const IInterface* parent)
+    : TbAlignmentMinuitBase(type, name, parent) {
+
+  declareProperty("ClusterLocation", 
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("DeviceToAlign", m_deviceToAlign = 999);
+  declareProperty("IsDUT", m_isDUT = true);
+  declareProperty("RefitTracks", m_refitTracks = false);
+  declareProperty("TimeWindow", m_twindow = 200. * Gaudi::Units::ns);
+  declareProperty("XWindow", m_xwindow = 1. * Gaudi::Units::mm);
+  declareProperty("IgnoreEdge",m_ignoreEdge=1);
+  m_dofsDefault = {true, true, true, true, true, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuit2::~TbAlignmentMinuit2() {}
+
+//=============================================================================
+// Collect the tracks and clusters to be used for the alignment.
+//=============================================================================
+StatusCode TbAlignmentMinuit2::execute(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  // Grab the tracks.
+  LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+  if (!m_isDUT) {
+    // We want to align a plane which is included in the pattern recognition.
+    for (LHCb::TbTrack* track : *tracks) {
+      // Skip low-quality tracks.
+      if (track->chi2() > m_maxChi2) continue;
+      // Add a new alignment track (cloning track and clusters) to the store.
+      alignmentTracks.emplace_back(new TbAlignmentTrack(track));
+    }
+    return StatusCode::SUCCESS;
+  }
+  // We want to align a plane which is not included in the pattern recognition.
+  if (m_twindow < 0. && m_xwindow < 0.) {
+    // Use the clusters which have been associated to the track.
+    for (LHCb::TbTrack* track : *tracks) {
+      // Skip low-quality tracks.
+      if (track->chi2() > m_maxChi2) continue;
+      auto clusters = track->associatedClusters();
+      for (auto it = clusters.begin(), end = clusters.end(); it != end; ++it) {
+        if ((*it)->plane() != m_deviceToAlign) continue;
+        // Create a new alignment track (cloning the track).
+        TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
+        // Clone the cluster and add it to the alignment track.
+        LHCb::TbCluster* alignmentCluster = (*it)->clone();
+        alignmentTrack->track()->addToAssociatedClusters(alignmentCluster);
+        alignmentTrack->addToClusters(alignmentCluster);
+        // Add the alignment track to the store.
+        alignmentTracks.push_back(alignmentTrack);
+        // Stop after the first valid cluster.
+        break;
+      }
+    }
+    return StatusCode::SUCCESS;
+  }
+  // We need to associate DUT clusters to the track.
+  // Grab the clusters on the device to align.
+  const std::string clusterLocation = m_clusterLocation + std::to_string(m_deviceToAlign);
+  LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+  if (!clusters) {
+    return Error("No clusters in " + clusterLocation);
+  }
+  unsigned int edgeRejected(0), spaceRejected(0);
+
+  for (LHCb::TbTrack* track : *tracks) {
+    // Skip low-quality tracks.
+    if (track->chi2PerNdof() > m_maxChi2) continue;
+    // Calculate the track intercept on the device to align.
+    const auto pGlobal = geomSvc()->intercept(track, m_deviceToAlign);
+    const auto pLocal = geomSvc()->globalToLocal(pGlobal, m_deviceToAlign);
+    // Calculate the time window.
+    const double tMin = track->htime() - m_twindow;
+    const double tMax = track->htime() + m_twindow;
+    // Get the first cluster within the time window.
+    LHCb::TbClusters::iterator end = clusters->end();
+    LHCb::TbClusters::iterator begin = std::lower_bound(
+        clusters->begin(), end, tMin, lowerBound<const LHCb::TbCluster*>());
+    if (begin == clusters->end()) continue;
+    // Loop over the clusters.
+    for (LHCb::TbClusters::iterator it = begin; it != end; ++it) {
+      // Stop when outside the time window.
+      if ((*it)->htime() > tMax) break;
+      // Skip clusters too far away from the track intercept.
+      const double dx = (*it)->xloc() - pLocal.x();
+      const double dy = (*it)->yloc() - pLocal.y();
+      if (fabs(dx) > m_xwindow || fabs(dy) > m_xwindow){ spaceRejected++; continue; }
+      // Skip clusters close to the edge of the sensor.
+      if (isEdge(*it) && m_ignoreEdge ){edgeRejected++; continue;}
+      // Create a new alignment track (cloning the track).
+      TbAlignmentTrack* alignmentTrack = new TbAlignmentTrack(track);
+      // Clone the cluster and add it to the alignment track.
+      LHCb::TbCluster* alignmentCluster = (*it)->clone();
+      alignmentTrack->track()->addToAssociatedClusters(alignmentCluster);
+      alignmentTrack->addToClusters(alignmentCluster);
+      // Add the alignment track to the store.
+      alignmentTracks.push_back(alignmentTrack);
+      // Stop after the first valid cluster.
+      break;
+    }
+  }
+  //info() << edgeRejected << "   " << spaceRejected << "    " << tracks->size() << endmsg;
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Calculate the chi2.
+//=============================================================================
+void TbAlignmentMinuit2::chi2(double& f, double* par, double* /*g*/) {
+
+  const unsigned int offset = m_deviceToAlign * 6;
+  // Check the z-position.
+  const double z = m_modules[m_deviceToAlign]->z() + par[offset + 2];
+  if (m_deviceToAlign > 0) {
+    if (z <= m_modules[m_deviceToAlign - 1]->z()) {
+      info() << "Z is below limit!" << endmsg;
+      f = std::numeric_limits<double>::max();
+      return;
+    }
+  }
+  if (m_deviceToAlign < m_nPlanes - 1) {
+    if (z >= m_modules[m_deviceToAlign + 1]->z()) {
+      info() << "Z is above limit!" << endmsg;
+      f = std::numeric_limits<double>::max();
+      return;
+    }
+  }
+
+  m_modules[m_deviceToAlign]->setAlignment(par[offset + 0], par[offset + 1],
+                                           par[offset + 2], par[offset + 3],
+                                           par[offset + 4], par[offset + 5]);
+  // Loop over the alignment tracks.
+  f = 0.;
+  for (auto it = m_tracks.begin(), end = m_tracks.end(); it != end; ++it) {
+    // Form residuals with all clusters selected for alignment
+    auto clusters = (*it)->clusters();
+    for (auto ic = clusters.cbegin(), end = clusters.cend(); ic != end; ++ic) {
+      if ((*ic)->plane() != m_deviceToAlign) continue;
+      Gaudi::XYZPoint point = geomSvc()->localToGlobal(
+          Gaudi::XYZPoint((*ic)->xloc(), (*ic)->yloc(), 0), m_deviceToAlign);
+      Gaudi::XYZPoint intercept =
+          geomSvc()->intercept((*it)->track(), m_deviceToAlign);
+      // TODO: why not the local residual?
+      const double xresidual = point.x() - intercept.x();
+      // const double xresidual = (*ic)->xloc() - intercept.x();
+      const double yresidual = point.y() - intercept.y();
+      // const double yresidual = (*ic)->yloc() - intercept.y();
+      f += xresidual * xresidual + yresidual * yresidual;
+    }
+  }
+}
+
+//=============================================================================
+// Main alignment function.
+//=============================================================================
+void TbAlignmentMinuit2::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  TbAlignmentMinuitBase::align(alignmentTracks);
+  info() << "Minuit technique 2. Aligning plane " << m_deviceToAlign << endmsg;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i) || i == m_deviceToAlign)
+      m_trackFit->maskPlane(i);
+    else
+      m_trackFit->unmaskPlane(i);
+  }
+
+  for (auto alignmentTrack : m_tracks) m_trackFit->fit(alignmentTrack->track());
+
+  for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
+    info() << "Iteration " << iteration + 1 << "/" << m_nIterations << endmsg;
+    // Loop over detector modules
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      const unsigned int offset = 6 * i;
+      if (i == m_deviceToAlign) {
+        info() << "*** Wobbling detector " << i << endmsg;
+        for (unsigned int j = 0; j < 6; ++j) {
+          if (m_dofs[j]) {
+            m_fitter->ReleaseParameter(offset + j);
+          } else {
+            m_fitter->FixParameter(offset + j);
+          }
+        }
+      } else {
+        m_fitter->FixParameter(offset + 0);  // x
+        m_fitter->FixParameter(offset + 1);  // y
+        m_fitter->FixParameter(offset + 2);  // z
+        m_fitter->FixParameter(offset + 3);  // Rx
+        m_fitter->FixParameter(offset + 4);  // Ry
+        m_fitter->FixParameter(offset + 5);  // Rz
+      }
+    }
+    // Execute minimization and calculate proper error matrix
+    double arglist[2];
+    arglist[0] = 10000;
+    arglist[1] = 1.e-2;
+    m_fitter->ExecuteCommand("MIGRAD", arglist, 2);
+    m_fitter->ExecuteCommand("HESSE", arglist, 1);
+    if (msgLevel(MSG::INFO)) m_fitter->ExecuteCommand("SHOW PARAMETERS", 0, 0);
+ 
+    updateGeometry();
+  }
+
+  if (m_refitTracks) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (masked(i))
+        m_trackFit->maskPlane(i);
+      else
+        m_trackFit->unmaskPlane(i);
+    }
+    for (auto it : m_tracks) m_trackFit->fit(it->track());
+  }
+}
diff --git a/TbAlignment/src/TbAlignmentMinuit2.h b/TbAlignment/src/TbAlignmentMinuit2.h
new file mode 100644
index 0000000..e1596cd
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuit2.h
@@ -0,0 +1,34 @@
+#pragma once
+
+// Local
+#include "TbAlignmentMinuitBase.h"
+
+class TbAlignmentMinuit2 : public TbAlignmentMinuitBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuit2(const std::string& type, const std::string& name,
+                     const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuit2();
+
+  /// Collect tracks and clusters for alignment (called at each event).
+  virtual StatusCode execute(std::vector<TbAlignmentTrack*>& tracks);
+
+  virtual void align(std::vector<TbAlignmentTrack*>& tracks);
+  void chi2(double& f, double* par, double* g);
+
+ private:
+  /// TES location prefix of clusters
+  std::string m_clusterLocation;
+  /// Plane index of the device to align
+  unsigned int m_deviceToAlign;
+  /// Flag whether the device to align is excluded from the pattern recognition
+  bool m_isDUT;
+  bool m_refitTracks;
+  bool m_ignoreEdge;
+  /// Time window for associating clusters to a track
+  double m_twindow;
+  /// Spatial window for associating clusters to a track
+  double m_xwindow;
+};
diff --git a/TbAlignment/src/TbAlignmentMinuitBase.cpp b/TbAlignment/src/TbAlignmentMinuitBase.cpp
new file mode 100644
index 0000000..a4369b8
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuitBase.cpp
@@ -0,0 +1,106 @@
+#include "TbAlignmentMinuitBase.h"
+
+namespace Tb {
+TbAlignmentMinuitBase* gTbAlignmentMinuitBase(nullptr);
+
+//=============================================================================
+// Function to be minimised
+//=============================================================================
+void fcn(int&, double* g, double& f, double* par, int) {
+  gTbAlignmentMinuitBase->chi2(f, par, g);
+}
+}
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentMinuitBase::TbAlignmentMinuitBase(const std::string& type,
+                                             const std::string& name,
+                                             const IInterface* parent)
+    : TbAlignmentBase(type, name, parent) {
+
+  declareProperty("NIterations", m_nIterations = 3);
+  declareProperty("FitStrategy", m_fitStrategy = 2);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentMinuitBase::~TbAlignmentMinuitBase() {}
+
+//=============================================================================
+// Update the module positions and orientations
+//=============================================================================
+void TbAlignmentMinuitBase::updateGeometry() {
+
+  info() << "Updating alignment constants:" << endmsg;
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    const double x = (*im)->x() + m_fitter->GetParameter(6 * i + 0);
+    const double y = (*im)->y() + m_fitter->GetParameter(6 * i + 1);
+    const double z = (*im)->z() + m_fitter->GetParameter(6 * i + 2);
+    const double rotx = (*im)->rotX() + m_fitter->GetParameter(6 * i + 3);
+    const double roty = (*im)->rotY() + m_fitter->GetParameter(6 * i + 4);
+    const double rotz = (*im)->rotZ() + m_fitter->GetParameter(6 * i + 5);
+    info() << format("%2i", i) << format(" %-15s", (*im)->id().c_str())
+           << format(" %10.3f", (*im)->x()) << format(" %10.3f", (*im)->y())
+           << format(" %10.3f", (*im)->z()) << format(" %10.3f", (*im)->rotX())
+           << format(" %10.3f", (*im)->rotY())
+           << format(" %10.3f", (*im)->rotZ()) << endmsg;
+    (*im)->setAlignment(x, y, z, rotx, roty, rotz, 0., 0., 0., 0., 0., 0.);
+  }
+}
+
+//=============================================================================
+// Main alignment function
+//=============================================================================
+void TbAlignmentMinuitBase::align(
+    std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  m_tracks = alignmentTracks;
+  // Set up the fitter.
+  m_fitter = new TFitter(60);
+  Tb::gTbAlignmentMinuitBase = this;
+  m_fitter->SetFCN(Tb::fcn);
+  // Set the output level (-1: none, 0: minimum: 1: normal).
+  double arglist = -1.;
+  if (msgLevel(MSG::DEBUG)) arglist = 1.;
+  m_fitter->ExecuteCommand("SET PRINTOUT", &arglist, 1);
+  // Set the value defining parameter errors.
+  arglist = 1.;
+  m_fitter->ExecuteCommand("SET ERR", &arglist, 1);
+  // Set the strategy for calculating derivatives. 
+  arglist = m_fitStrategy;
+  m_fitter->ExecuteCommand("SET STRATEGY", &arglist, 1);
+  // Set the floating point accuracy.
+  arglist = 1.e-12;
+  m_fitter->ExecuteCommand("SET EPS", &arglist, 1);
+  setParameters();
+}
+
+//=============================================================================
+// Set the initial values of the fit parameters.
+//=============================================================================
+void TbAlignmentMinuitBase::setParameters() {
+
+  info() << "Setting initial values of alignment parameters" << endmsg;
+  for (auto im = m_modules.begin(), end = m_modules.end(); im != end; ++im) {
+    const unsigned int i = im - m_modules.begin();
+    const double dx = (*im)->dX();
+    const double dy = (*im)->dY();
+    const double dz = (*im)->dZ();
+    const double drx = (*im)->dRotX();
+    const double dry = (*im)->dRotY();
+    const double drz = (*im)->dRotZ();
+    const std::string id = (*im)->id();
+    m_fitter->SetParameter(6 * i + 0, (id + " dx ").c_str(), dx, 0.001, 0., 0.);
+    m_fitter->SetParameter(6 * i + 1, (id + " dy ").c_str(), dy, 0.001, 0., 0.);
+    m_fitter->SetParameter(6 * i + 2, (id + " dz ").c_str(), dz, 1., 0., 0.);
+    m_fitter->SetParameter(6 * i + 3, (id + " dRx").c_str(), drx, 0.001, 0.,
+                           0.);
+    m_fitter->SetParameter(6 * i + 4, (id + " dRy").c_str(), dry, 0.001, 0.,
+                           0.);
+    m_fitter->SetParameter(6 * i + 5, (id + " dRz").c_str(), drz, 0.001, 0.,
+                           0.);
+  }
+}
diff --git a/TbAlignment/src/TbAlignmentMinuitBase.h b/TbAlignment/src/TbAlignmentMinuitBase.h
new file mode 100644
index 0000000..dd73928
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentMinuitBase.h
@@ -0,0 +1,33 @@
+#pragma once
+
+// ROOT
+#include "TFitter.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+class TbAlignmentMinuitBase : public TbAlignmentBase {
+
+ public:
+  /// Constructor
+  TbAlignmentMinuitBase(const std::string& type, const std::string& name,
+                        const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentMinuitBase();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+  virtual void chi2(double& f, double* par, double* g) = 0;
+
+  virtual void updateGeometry();
+
+ protected:
+  /// Number of iterations
+  unsigned int m_nIterations;
+  /// Minuit fit strategy (allowed values are 0, 1, 2).
+  int m_fitStrategy;
+
+  std::vector<TbAlignmentTrack*> m_tracks;
+  TFitter* m_fitter;
+
+  void setParameters();
+};
diff --git a/TbAlignment/src/TbAlignmentSurvey.cpp b/TbAlignment/src/TbAlignmentSurvey.cpp
new file mode 100644
index 0000000..89cd1a4
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentSurvey.cpp
@@ -0,0 +1,76 @@
+// ROOT
+#include "TH1.h"
+
+// Gaudi
+#include "GaudiKernel/IHistogramSvc.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Local
+#include "TbAlignmentSurvey.h"
+
+DECLARE_TOOL_FACTORY(TbAlignmentSurvey)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbAlignmentSurvey::TbAlignmentSurvey(const std::string& type,
+                                     const std::string& name,
+                                     const IInterface* parent)
+    : TbAlignmentBase(type, name, parent) {}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlignmentSurvey::~TbAlignmentSurvey() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbAlignmentSurvey::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlignmentBase::initialize();
+  if (sc.isFailure()) return sc;
+
+  return StatusCode::SUCCESS;
+}
+
+void TbAlignmentSurvey::align(std::vector<TbAlignmentTrack*>& /*tracks*/) {
+
+  info() << "Survey alignment" << endmsg;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    const std::string plane = std::to_string(i);
+    const std::string path = "Tb/TbClusterPlots/Differences/";
+    const std::string titlex = path + "x/Plane" + plane;
+    const std::string titley = path + "y/Plane" + plane;
+    double tx = m_modules[i]->x();
+    double ty = m_modules[i]->y();
+
+    if (m_dofs[0]) {
+      AIDA::IHistogram1D* hAida = NULL;
+      StatusCode sc = GaudiTool::histoSvc()->retrieveObject(titlex, hAida);
+      if (sc.isFailure() || !hAida) {
+        warning() << "Cannot retrieve histogram " << titlex << endmsg;
+      } else {
+        auto hRoot = Gaudi::Utils::Aida2ROOT::aida2root(hAida);
+        tx -= hRoot->GetBinCenter(hRoot->GetMaximumBin());
+      }
+    }
+    if (m_dofs[1]) {
+      AIDA::IHistogram1D* hAida = NULL;
+      StatusCode sc = GaudiTool::histoSvc()->retrieveObject(titley, hAida);
+      if (sc.isFailure() || !hAida) {
+        warning() << "Cannot retrieve histogram " << titley << endmsg;
+      } else {
+        auto hRoot = Gaudi::Utils::Aida2ROOT::aida2root(hAida);
+        ty -= hRoot->GetBinCenter(hRoot->GetMaximumBin());
+      }
+    }
+    const double rx = m_modules[i]->rotX();
+    const double ry = m_modules[i]->rotY();
+    const double rz = m_modules[i]->rotZ();
+    const double tz = m_modules[i]->z();
+    m_modules[i]->setAlignment(tx, ty, tz, rx, ry, rz, 0., 0., 0., 0., 0., 0.);
+  }
+}
diff --git a/TbAlignment/src/TbAlignmentSurvey.h b/TbAlignment/src/TbAlignmentSurvey.h
new file mode 100644
index 0000000..7c97ba7
--- /dev/null
+++ b/TbAlignment/src/TbAlignmentSurvey.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "TbAlignmentBase.h"
+
+class TbAlignmentSurvey : public TbAlignmentBase {
+
+ public:
+  /// Constructor
+  TbAlignmentSurvey(const std::string& type, const std::string& name,
+                    const IInterface* parent);
+  /// Destructor
+  virtual ~TbAlignmentSurvey();
+
+  virtual StatusCode initialize();
+
+  virtual void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+};
diff --git a/TbAlignment/src/TbMillepede.cpp b/TbAlignment/src/TbMillepede.cpp
new file mode 100755
index 0000000..aafcda3
--- /dev/null
+++ b/TbAlignment/src/TbMillepede.cpp
@@ -0,0 +1,1093 @@
+#include <iomanip>
+#include <algorithm>
+#include <cmath>
+
+// Local
+#include "TbMillepede.h"
+
+// TbKernel
+#include "TbKernel/TbGeomFunctions.h"
+
+DECLARE_TOOL_FACTORY(TbMillepede)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbMillepede::TbMillepede(const std::string& type, const std::string& name,
+                         const IInterface* parent)
+    : TbAlignmentBase(type, name, parent),
+      m_nalc(4),
+      m_debug(false),
+      m_iterate(true) {
+
+  declareProperty("NIterations", m_nIterations = 5);
+  declareProperty("ResCut", m_rescut = 0.05);
+  declareProperty("ResCutInit", m_rescut_init = 0.6);
+  declareProperty("NStdDev", m_nstdev = 0);
+  declareProperty("Sigmas", m_sigmas = {});
+
+  m_dofsDefault = {true, true, false, true, true, true};
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbMillepede::~TbMillepede() {}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbMillepede::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlignmentBase::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Get the verbosity level.
+  m_debug = msgLevel(MSG::DEBUG);
+
+  // Renumber the planes in Millepede, ignoring masked planes.
+  m_millePlanes.assign(m_nPlanes, 999);
+  unsigned int index = 0;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    if (masked(i)) continue;
+    m_millePlanes[i] = index;
+    ++index;
+  }
+  // Use default values for the sigmas, unless specified explicitly.
+  if (m_sigmas.size() != 6) {
+    m_sigmas = {0.05, 0.05, 0.5, 0.005, 0.005, 0.005};
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main alignment function
+//=============================================================================
+void TbMillepede::align(std::vector<TbAlignmentTrack*>& alignmentTracks) {
+
+  info() << "Millepede alignment" << endmsg;
+  const unsigned int nPlanes = m_nPlanes - m_maskedPlanes.size();
+  const unsigned int nParameters = 6 * nPlanes;
+  for (unsigned int iteration = 0; iteration < m_nIterations; ++iteration) {
+    const unsigned int nTracks = alignmentTracks.size();
+    // Define the constraint equations.
+    setConstraints(nPlanes);
+    const double startfact = 100.;
+    // Initialise all matrices and vectors.
+    reset(nPlanes, startfact);
+    info() << "Feeding Millepede with " << nTracks << " tracks..." << endmsg;
+    // Feed Millepede with tracks.
+    unsigned int nSkipped = 0;
+    unsigned int nOutliers = 0;
+    for (unsigned int i = 0; i < nTracks; ++i) {
+      LHCb::TbTrack* track = alignmentTracks[i]->track();
+      if (track->size() != nPlanes) {
+        ++nSkipped;
+        continue;
+      }
+      if (!putTrack(track, nPlanes)) {
+        ++nOutliers;
+      }
+    }
+    if (nSkipped > 0) {
+      info() << "Skipped " << nSkipped << " tracks with less than " << nPlanes
+             << " clusters." << endmsg;
+    }
+    if (nOutliers > 0) {
+      info() << "Rejected " << nOutliers << " outlier tracks." << endmsg;
+    }
+    // Do the global fit.
+    info() << "Determining global parameters..." << endmsg;
+    fitGlobal();
+    // Calculate the convergence metric (sum of misalignments).
+    double converg = 0.;
+    for (unsigned int i = 0; i < nParameters; ++i) {
+      converg += fabs(m_dparm[i]);
+    }
+    converg /= nParameters;
+    info() << "Convergence: " << converg << endmsg;
+    // Update the module positions and orientations.
+    info() << "Updating geometry..." << endmsg;
+    updateGeometry();
+    // Update the cluster coordinates based on the new geometry.
+    for (unsigned int i = 0; i < nTracks; ++i) {
+      LHCb::TbTrack* track = alignmentTracks[i]->track();
+      SmartRefVector<LHCb::TbCluster> clusters = track->clusters();
+      for (auto ic = clusters.begin(), end = clusters.end(); ic != end; ++ic) {
+        Gaudi::XYZPoint pLocal((*ic)->xloc(), (*ic)->yloc(), 0.);
+        const auto pGlobal = geomSvc()->localToGlobal(pLocal, (*ic)->plane());
+        (*ic)->setX(pGlobal.x());
+        (*ic)->setY(pGlobal.y());
+        (*ic)->setZ(pGlobal.z());
+      }
+    }
+    if (converg < 0.00001) break;
+  }
+}
+
+//=============================================================================
+// Setup the constraint equations.
+//=============================================================================
+void TbMillepede::setConstraints(const unsigned int nPlanes) {
+
+  // Calculate the mean z-position.
+  double avgz = 0.;
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.cbegin())) continue;
+    avgz += (*im)->z();
+  }
+  avgz /= nPlanes;
+  // Calculate the variance.
+  double varz = 0.0;
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.cbegin())) continue;
+    const double dz = (*im)->z() - avgz;
+    varz += dz * dz;
+  }
+  varz /= nPlanes;
+
+  // Define the 9 constraints equations according to the requested geometry.
+  const unsigned int nParameters = 6 * nPlanes;
+  std::vector<double> ftx(nParameters, 0.);
+  std::vector<double> fty(nParameters, 0.);
+  std::vector<double> ftz(nParameters, 0.);
+  std::vector<double> frx(nParameters, 0.);
+  std::vector<double> fry(nParameters, 0.);
+  std::vector<double> frz(nParameters, 0.);
+  std::vector<double> fscaz(nParameters, 0.);
+  std::vector<double> shearx(nParameters, 0.);
+  std::vector<double> sheary(nParameters, 0.);
+
+  m_constraints.clear();
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.begin())) continue;
+    const unsigned int i = m_millePlanes[im - m_modules.begin()];
+    const double sz = ((*im)->z() - avgz) / varz;
+    ftx[i] = 1.0;
+    fty[i + nPlanes] = 1.0;
+    ftz[i + 2 * nPlanes] = 1.0;
+    frx[i + 3 * nPlanes] = 1.0 ; // i > 4 ? 1.0 : -1.0;
+    fry[i + 4 * nPlanes] = 1.0 ; //  i > 4 ? 1.0 : -1.0;
+    frz[i + 5 * nPlanes] = 1.0;
+    shearx[i] = sz;
+    sheary[i + nPlanes] = sz;
+    fscaz[i + 2 * nPlanes] = sz;
+  }
+
+  const std::vector<bool> constraints = {true,  true, true, true, false,
+                                         false, true, true, true};
+  //  Put the constraints information in the basket.
+  if (constraints[0] && m_dofs[0]) addConstraint(ftx, 0.0);
+  if (constraints[1] && m_dofs[0]) addConstraint(shearx, 0.);
+  if (constraints[2] && m_dofs[1]) addConstraint(fty, 0.0);
+  if (constraints[3] && m_dofs[1]) addConstraint(sheary, 0.);
+  if (constraints[4] && m_dofs[2]) addConstraint(ftz, 0.0);
+  // if (constraints[5] && m_dofs[2]) addConstraint(fscaz, 0.0);
+  if (constraints[6] && m_dofs[3]) addConstraint(frx, 0.0);
+  if (constraints[7] && m_dofs[4]) addConstraint(fry, 0.0);
+  if (constraints[8] && m_dofs[5]) addConstraint(frz, 0.0);
+}
+
+//=============================================================================
+// Define a single constraint equation.
+//=============================================================================
+void TbMillepede::addConstraint(const std::vector<double>& dercs,
+                                const double rhs) {
+
+  Constraint constraint;
+  // Set the right-hand side (Lagrange multiplier value, sum of equation).
+  constraint.rhs = rhs;
+  // Set the constraint equation coefficients.
+  constraint.coefficients = dercs;
+  m_constraints.push_back(constraint);
+}
+
+//=============================================================================
+// Add the equations for one track to the matrix
+//=============================================================================
+bool TbMillepede::putTrack(LHCb::TbTrack* track, const unsigned int nPlanes) {
+
+  std::vector<Equation> equations;
+  const unsigned int nParameters = 6 * nPlanes;
+  // Global derivatives
+  std::vector<double> dergb(nParameters, 0.);
+  // Global derivatives non linearly related to residual
+  std::vector<double> dernl(nParameters, 0.);
+  // Local parameter indices associated with non-linear derivatives
+  std::vector<int> dernli(nParameters, 0);
+  // Track slopes
+  std::vector<double> dernls(nParameters, 0.);
+
+  /// Refit the track for the reference states.
+  m_trackFit->fit(track);
+  auto state = track->firstState();
+  const double tx = state.tx();
+  const double ty = state.ty();
+
+  // Iterate over each cluster on the track.
+  const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters();
+  for (auto itc = clusters.cbegin(), end = clusters.cend(); itc != end; ++itc) {
+    if (masked((*itc)->plane())) continue;
+    const auto normal = geomSvc()->module((*itc)->plane())->normal();
+    double nx = normal.x() / normal.z();
+    double ny = normal.y() / normal.z();
+    const double xg = (*itc)->x();
+    const double yg = (*itc)->y();
+    const double zg = (*itc)->z();
+    // Calculate quasi-local coordinates.
+    const double zl = zg - m_modules[(*itc)->plane()]->z();
+    const double xl = xg - m_modules[(*itc)->plane()]->x();
+    const double yl = yg - m_modules[(*itc)->plane()]->y();
+
+    std::vector<double> nonlinear = {
+        nx, ny, 1., -yl + zl * ny, -xl + zl * nx, xl * ny - yl * nx};
+    const double den = 1. + tx * nx + ty * ny;
+    for (auto& a : nonlinear) a /= den;
+    // Get the errors on the measured x and y coordinates.
+    const double errx = (*itc)->xErr();
+    const double erry = (*itc)->yErr();
+    // Get the internal plane index in Millepede.
+    const unsigned int plane = m_millePlanes[(*itc)->plane()];
+    // Set the local derivatives for the X equation.
+    std::vector<double> derlc = {1., zg, 0., 0.};
+    // Set the global derivatives (see LHCb-2005-101) for the X equation.
+    std::fill(dergb.begin(), dergb.end(), 0.);
+    std::fill(dernl.begin(), dernl.end(), 0.);
+    std::fill(dernli.begin(), dernli.end(), 0);
+    std::fill(dernls.begin(), dernls.end(), 0.);
+    if (m_dofs[0]) dergb[plane] = -1.;
+    if (m_dofs[4]) dergb[4 * nPlanes + plane] = -zl;
+    if (m_dofs[5]) dergb[5 * nPlanes + plane] = yl;
+    for (unsigned int i = 0; i < 6; ++i) {
+      if (!m_dofs[i]) continue;
+      dergb[i * nPlanes + plane] += tx * nonlinear[i];
+      dernl[i * nPlanes + plane] = nonlinear[i];
+      dernli[i * nPlanes + plane] = 1;
+      dernls[i * nPlanes + plane] = tx;
+    }
+    // Store the X equation.
+    addEquation(equations, derlc, dergb, dernl, dernli, dernls, xg, errx);
+    // Set the local derivatives for the Y equation.
+    derlc = {0., 0., 1., zg};
+    // Set the global derivatives (see LHCb-2005-101) for the Y equation.
+    std::fill(dergb.begin(), dergb.end(), 0.);
+    std::fill(dernl.begin(), dernl.end(), 0.);
+    std::fill(dernli.begin(), dernli.end(), 0);
+    std::fill(dernls.begin(), dernls.end(), 0.);
+    if (m_dofs[1]) dergb[nPlanes + plane] = -1.;
+    if (m_dofs[3]) dergb[3 * nPlanes + plane] = -zl;
+    if (m_dofs[5]) dergb[5 * nPlanes + plane] = -xl;
+    for (unsigned int i = 0; i < 6; ++i) {
+      if (!m_dofs[i]) continue;
+      dergb[i * nPlanes + plane] += ty * nonlinear[i];
+      dernl[i * nPlanes + plane] = nonlinear[i];
+      dernli[i * nPlanes + plane] = 3;
+      dernls[i * nPlanes + plane] = ty;
+    }
+    // Store the Y equation.
+    addEquation(equations, derlc, dergb, dernl, dernli, dernls, yg, erry);
+  }
+  // Vector containing the track parameters
+  std::vector<double> trackParams(2 * m_nalc + 2, 0.);
+  // Fit the track.
+  const unsigned int iteration = 1;
+  const bool ok = fitTrack(equations, trackParams, false, iteration);
+  if (ok) m_equations.push_back(equations);
+  return ok;
+}
+
+//=============================================================================
+// Store the parameters for one measurement
+//=============================================================================
+void TbMillepede::addEquation(std::vector<Equation>& equations,
+                              const std::vector<double>& derlc,
+                              const std::vector<double>& dergb,
+                              const std::vector<double>& dernl,
+                              const std::vector<int>& dernli,
+                              const std::vector<double>& slopes,
+                              const double rmeas, const double sigma) {
+
+  if (sigma <= 0.) {
+    error() << "Invalid cluster error (" << sigma << ")" << endmsg;
+    return;
+  }
+  Equation equation;
+  equation.rmeas = rmeas;
+  equation.weight = 1. / (sigma * sigma);
+  // Add non-zero local derivatives and corresponding indices.
+  equation.derL.clear();
+  equation.indL.clear();
+  for (unsigned int i = 0; i < m_nalc; ++i) {
+    if (derlc[i] == 0.) continue;
+    equation.indL.push_back(i);
+    equation.derL.push_back(derlc[i]);
+  }
+  // Add non-zero global derivatives and corresponding indices.
+  equation.derG.clear();
+  equation.indG.clear();
+  equation.derNL.clear();
+  equation.indNL.clear();
+  equation.slopes.clear();
+  const unsigned int nG = dergb.size();
+  for (unsigned int i = 0; i < nG; ++i) {
+    if (dergb[i] == 0.) continue;
+    equation.indG.push_back(i);
+    equation.derG.push_back(dergb[i]);
+    equation.derNL.push_back(dernl[i]);
+    equation.indNL.push_back(dernli[i]);
+    equation.slopes.push_back(slopes[i]);
+  }
+  // Add the equation to the list.
+  equations.push_back(std::move(equation));
+}
+
+//=============================================================================
+// Track fit (local fit)
+//=============================================================================
+bool TbMillepede::fitTrack(const std::vector<Equation>& equations,
+                           std::vector<double>& trackParams,
+                           const bool singlefit, const unsigned int iteration) {
+
+  std::vector<double> blvec(m_nalc, 0.);
+  std::vector<std::vector<double> > clmat(m_nalc,
+                                          std::vector<double>(m_nalc, 0.));
+
+  // First loop: local track fit
+  for (const auto& equation : equations) {
+    double rmeas = equation.rmeas;
+    // Suppress the global part (only relevant with iterations).
+    const unsigned int nG = equation.derG.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      rmeas -= equation.derG[i] * m_dparm[j];
+    }
+    const double w = equation.weight;
+    // Fill local matrix and vector.
+    const unsigned int nL = equation.derL.size();
+    for (unsigned int i = 0; i < nL; ++i) {
+      const unsigned int j = equation.indL[i];
+      blvec[j] += w * rmeas * equation.derL[i];
+      if (m_debug) debug() << "blvec[" << j << "] = " << blvec[j] << endmsg;
+      // Symmetric matrix, don't bother k > j coefficients.
+      for (unsigned int k = 0; k <= i; ++k) {
+        const unsigned int ik = equation.indL[k];
+        clmat[j][ik] += w * equation.derL[i] * equation.derL[k];
+        if (m_debug) {
+          debug() << "clmat[" << j << "][" << ik << "] = " << clmat[j][ik]
+                  << endmsg;
+        }
+      }
+    }
+  }
+
+  // Local parameter matrix is completed, now invert to solve.
+  // Rank: number of non-zero diagonal elements.
+  int rank = invertMatrixLocal(clmat, blvec, m_nalc);
+  // Store the track parameters and errors.
+  for (unsigned int i = 0; i < m_nalc; ++i) {
+    trackParams[2 * i] = blvec[i];
+    trackParams[2 * i + 1] = sqrt(fabs(clmat[i][i]));
+  }
+
+  // Second loop: residual calculation.
+  double chi2 = 0.0;
+  int ndf = 0;
+  for (const auto& equation : equations) {
+    double rmeas = equation.rmeas;
+    // Suppress global and local terms.
+    const unsigned int nL = equation.derL.size();
+    for (unsigned int i = 0; i < nL; ++i) {
+      const unsigned int j = equation.indL[i];
+      rmeas -= equation.derL[i] * blvec[j];
+    }
+    const unsigned int nG = equation.derG.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      rmeas -= equation.derG[i] * m_dparm[j];
+    }
+    // Now rmeas contains the residual value.
+    if (m_debug) debug() << "Residual value: " << rmeas << endmsg;
+    // Reject the track if the residual is too large (outlier).
+    const double rescut = iteration <= 1 ? m_rescut_init : m_rescut;
+    if (fabs(rmeas) >= rescut) {
+      if (m_debug) {
+        debug() << "Reject track due to residual cut in iteration " << iteration
+                << endmsg;
+      }
+      return false;
+    }
+    chi2 += equation.weight * rmeas * rmeas;
+    ++ndf;
+  }
+  ndf -= rank;
+  const bool printDetails = false;
+  if (printDetails) {
+    info() << endmsg;
+    info() << "Local track fit (rank " << rank << ")" << endmsg;
+    info() << " Result of local fit :      (index/parameter/error)" << endmsg;
+    for (unsigned int i = 0; i < m_nalc; ++i) {
+      info() << std::setprecision(6) << std::fixed << std::setw(20) << i
+             << "   /   " << std::setw(10) << blvec[i] << "   /   "
+             << sqrt(clmat[i][i]) << endmsg;
+    }
+    info() << "Final chi square / degrees of freedom: " << chi2 << " / " << ndf
+           << endmsg;
+  }
+
+  // Stop here if just updating the track parameters.
+  if (singlefit) return true;
+
+  if (m_nstdev != 0 && ndf > 0) {
+    const double chi2PerNdf = chi2 / ndf;
+    const double cut = chi2Limit(m_nstdev, ndf) * m_cfactr;
+    if (chi2 > cut) {
+      // Reject the track.
+      if (m_debug) {
+        debug() << "Rejected track because chi2 / ndof (" << chi2PerNdf
+                << ") is larger than " << cut << endmsg;
+      }
+      return false;
+    }
+  }
+  // Store the chi2 and number of degrees of freedom.
+  trackParams[2 * m_nalc] = ndf;
+  trackParams[2 * m_nalc + 1] = chi2;
+
+  // Local operations are finished. Track is accepted.
+  // Third loop: update the global parameters (other matrices).
+  m_clcmat.assign(m_nagb, std::vector<double>(m_nalc, 0.));
+  unsigned int nagbn = 0;
+  std::vector<int> indnz(m_nagb, -1);
+  std::vector<int> indbk(m_nagb, 0);
+  for (const auto& equation : equations) {
+    double rmeas = equation.rmeas;
+    // Suppress the global part.
+    const unsigned int nG = equation.derG.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      rmeas -= equation.derG[i] * m_dparm[j];
+    }
+    const double w = equation.weight;
+    // First of all, the global/global terms.
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      m_bgvec[j] += w * rmeas * equation.derG[i];
+      if (m_debug) debug() << "bgvec[" << j << "] = " << m_bgvec[j] << endmsg;
+      for (unsigned int k = 0; k < nG; ++k) {
+        const unsigned int n = equation.indG[k];
+        m_cgmat[j][n] += w * equation.derG[i] * equation.derG[k];
+        if (m_debug) {
+          debug() << "cgmat[" << j << "][" << n << "] = " << m_cgmat[j][n]
+                  << endmsg;
+        }
+      }
+    }
+    // Now we have also rectangular matrices containing global/local terms.
+    const unsigned int nL = equation.derL.size();
+    for (unsigned int i = 0; i < nG; ++i) {
+      const unsigned int j = equation.indG[i];
+      // Index of index.
+      int ik = indnz[j];
+      if (ik == -1) {
+        // New global variable.
+        indnz[j] = nagbn;
+        indbk[nagbn] = j;
+        ik = nagbn;
+        ++nagbn;
+      }
+      // Now fill the rectangular matrix.
+      for (unsigned int k = 0; k < nL; ++k) {
+        const unsigned int ij = equation.indL[k];
+        m_clcmat[ik][ij] += w * equation.derG[i] * equation.derL[k];
+        if (m_debug)
+          debug() << "clcmat[" << ik << "][" << ij << "] = " << m_clcmat[ik][ij]
+                  << endmsg;
+      }
+    }
+  }
+
+  // Third loop is finished, now we update the correction matrices.
+  multiplyAVAt(clmat, m_clcmat, m_corrm, m_nalc, nagbn);
+  multiplyAX(m_clcmat, blvec, m_corrv, m_nalc, nagbn);
+  for (unsigned int i = 0; i < nagbn; ++i) {
+    const unsigned int j = indbk[i];
+    m_bgvec[j] -= m_corrv[i];
+    for (unsigned int k = 0; k < nagbn; ++k) {
+      const unsigned int ik = indbk[k];
+      m_cgmat[j][ik] -= m_corrm[i][k];
+    }
+  }
+  return true;
+}
+
+//=============================================================================
+// Update the module positions and orientations.
+//=============================================================================
+void TbMillepede::updateGeometry() {
+
+  const unsigned int nPlanes = m_nPlanes - m_maskedPlanes.size();
+  for (auto im = m_modules.cbegin(), end = m_modules.cend(); im != end; ++im) {
+    if (masked(im - m_modules.begin())) continue;
+    const unsigned int plane = m_millePlanes[im - m_modules.begin()];
+    const double tx = (*im)->x() + m_dparm[plane + 0 * nPlanes];
+    const double ty = (*im)->y() + m_dparm[plane + 1 * nPlanes];
+    const double tz = (*im)->z() + m_dparm[plane + 2 * nPlanes];
+    double rx = 0.;
+    double ry = 0.;
+    double rz = 0.;
+    Tb::SmallRotation((*im)->rotX(), m_dparm[plane + 3 * nPlanes],
+                      (*im)->rotY(), m_dparm[plane + 4 * nPlanes],
+                      m_dparm[plane + 5 * nPlanes], rx, ry, rz);
+    (*im)->setAlignment(tx, ty, tz, (*im)->rotX() - rx, (*im)->rotY() + ry,
+                        (*im)->rotZ() - rz, 0., 0., 0., 0., 0., 0.);
+  }
+}
+
+//=============================================================================
+// Initialise the vectors and arrays.
+//=============================================================================
+bool TbMillepede::reset(const unsigned int nPlanes, const double startfact) {
+
+  info() << "                                           " << endmsg;
+  info() << "            * o o                   o      " << endmsg;
+  info() << "              o o                   o      " << endmsg;
+  info() << "   o ooooo  o o o  oo  ooo   oo   ooo  oo  " << endmsg;
+  info() << "    o  o  o o o o o  o o  o o  o o  o o  o " << endmsg;
+  info() << "    o  o  o o o o oooo o  o oooo o  o oooo " << endmsg;
+  info() << "    o  o  o o o o o    ooo  o    o  o o    " << endmsg;
+  info() << "    o  o  o o o o  oo  o     oo   ooo  oo  ++ starts" << endmsg;
+  info() << "                                           " << endmsg;
+
+  // Reset the list of track equations.
+  m_equations.clear();
+  // Set the number of global derivatives.
+  m_nagb = 6 * nPlanes;
+  // Reset matrices and vectors.
+  const unsigned int nRows = m_nagb + m_constraints.size();
+  m_bgvec.resize(nRows, 0.);
+  m_cgmat.assign(nRows, std::vector<double>(nRows, 0.));
+  m_corrv.assign(m_nagb, 0.);
+  m_corrm.assign(m_nagb, std::vector<double>(m_nagb, 0.));
+  m_dparm.assign(m_nagb, 0.);
+
+  // Define the sigmas for each parameter.
+  m_fixed.assign(m_nagb, true);
+  m_psigm.assign(m_nagb, 0.);
+  for (unsigned int i = 0; i < 6; ++i) {
+    if (!m_dofs[i]) continue;
+    for (unsigned int j = i * nPlanes; j < (i + 1) * nPlanes; ++j) {
+      m_fixed[j] = false;
+      m_psigm[j] = m_sigmas[i];
+    }
+  }
+  // Fix modules if requested.
+  for (auto it = m_fixedPlanes.cbegin(); it != m_fixedPlanes.cend(); ++it) {
+    info() << "You are fixing module " << (*it) << endmsg;
+    // TODO: check if this is the "millePlanes" index or the regular one.
+    const unsigned ndofs = m_fix_all ? 6 : 3;
+    for (unsigned int i = 0; i < ndofs; ++i) {
+      m_fixed[(*it) + i * nPlanes] = true;
+      m_psigm[(*it) + i * nPlanes] = 0.;
+    }
+  }
+
+  // Set the chi2 / ndof cut used in the local track fit.
+  // Iterations are stopped when the cut factor reaches the ref. value (1).
+  m_cfactref = 1.;
+  m_cfactr = std::max(1., startfact);
+
+  return true;
+}
+
+//=============================================================================
+//
+//=============================================================================
+bool TbMillepede::fitGlobal() {
+
+  m_diag.assign(m_nagb, 0.);
+  std::vector<double> bgvecPrev(m_nagb, 0.);
+  std::vector<double> trackParams(2 * m_nalc + 2, 0.);
+  const unsigned int nTracks = m_equations.size();
+  std::vector<std::vector<double> > localParams(
+      nTracks, std::vector<double>(m_nalc, 0.));
+
+  const unsigned int nMaxIterations = 10;
+  unsigned int iteration = 1;
+  unsigned int nGoodTracks = nTracks;
+  while (iteration <= nMaxIterations) {
+    info() << "Iteration " << iteration << " (using " << nGoodTracks
+           << " tracks)" << endmsg;
+
+    // Save the diagonal elements.
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      m_diag[i] = m_cgmat[i][i];
+    }
+
+    unsigned int nFixed = 0;
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      if (m_fixed[i]) {
+        // Fixed global parameter.
+        ++nFixed;
+        for (unsigned int j = 0; j < m_nagb; ++j) {
+          // Reset row and column.
+          m_cgmat[i][j] = 0.0;
+          m_cgmat[j][i] = 0.0;
+        }
+      } else {
+        m_cgmat[i][i] += 1. / (m_psigm[i] * m_psigm[i]);
+      }
+    }
+    // Add the constraints equations.
+    unsigned int nRows = m_nagb;
+    for (const auto& constraint : m_constraints) {
+      double sum = constraint.rhs;
+      for (unsigned int j = 0; j < m_nagb; ++j) {
+        if (m_psigm[j] == 0.) {
+          m_cgmat[nRows][j] = 0.0;
+          m_cgmat[j][nRows] = 0.0;
+        } else {
+          m_cgmat[nRows][j] = nGoodTracks * constraint.coefficients[j];
+          m_cgmat[j][nRows] = m_cgmat[nRows][j];
+        }
+        sum -= constraint.coefficients[j] * m_dparm[j];
+      }
+      m_cgmat[nRows][nRows] = 0.0;
+      m_bgvec[nRows] = nGoodTracks * sum;
+      ++nRows;
+    }
+
+    double cor = 0.0;
+    if (iteration > 1) {
+      for (unsigned int j = 0; j < m_nagb; ++j) {
+        for (unsigned int i = 0; i < m_nagb; ++i) {
+          if (m_fixed[i]) continue;
+          cor += bgvecPrev[j] * m_cgmat[j][i] * bgvecPrev[i];
+          if (i == j) {
+            cor -= bgvecPrev[i] * bgvecPrev[i] / (m_psigm[i] * m_psigm[i]);
+          }
+        }
+      }
+    }
+    if (m_debug) debug() << " Final corr. is " << cor << endmsg;
+
+    // Do the matrix inversion.
+    const int rank = invertMatrix(m_cgmat, m_bgvec, nRows);
+    // Update the global parameters values.
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      m_dparm[i] += m_bgvec[i];
+      bgvecPrev[i] = m_bgvec[i];
+      if (m_debug) {
+        debug() << "bgvec[" << i << "] = " << m_bgvec[i] << endmsg;
+        debug() << "dparm[" << i << "] = " << m_dparm[i] << endmsg;
+        debug() << "cgmat[" << i << "][" << i << "] = " << m_cgmat[i][i]
+                << endmsg;
+        debug() << "err = " << sqrt(fabs(m_cgmat[i][i])) << endmsg;
+        debug() << "cgmat * diag = " << std::setprecision(5)
+                << m_cgmat[i][i] * m_diag[i] << endmsg;
+      }
+    }
+    if (nRows - nFixed - rank != 0) {
+      warning() << "The rank defect of the symmetric " << nRows << " by "
+                << nRows << " matrix is " << nRows - nFixed - rank << endmsg;
+    }
+    if (!m_iterate) break;
+    ++iteration;
+    if (iteration == nMaxIterations) break;
+    // Update the factor in the track chi2 cut.
+    const double newcfactr = sqrt(m_cfactr);
+    if (newcfactr > 1.2 * m_cfactref) {
+      m_cfactr = newcfactr;
+    } else {
+      m_cfactr = m_cfactref;
+    }
+    if (m_debug) {
+      debug() << "Refitting tracks with cut factor " << m_cfactr << endmsg;
+    }
+
+    // Reset global variables.
+    for (unsigned int i = 0; i < nRows; ++i) {
+      m_bgvec[i] = 0.0;
+      for (unsigned int j = 0; j < nRows; ++j) m_cgmat[i][j] = 0.0;
+    }
+    // Refit the tracks.
+    double chi2 = 0.;
+    double ndof = 0.;
+    nGoodTracks = 0;
+    for (unsigned int i = 0; i < nTracks; ++i) {
+      // Skip invalidated tracks.
+      if (m_equations[i].empty()) continue;
+      std::vector<Equation> equations(m_equations[i].begin(),
+                                      m_equations[i].end());
+      for (auto equation : equations) {
+        const unsigned int nG = equation.derG.size();
+        for (unsigned int j = 0; j < nG; ++j) {
+          const double t = localParams[i][equation.indNL[j]];
+          if (t == 0) continue;
+          equation.derG[j] += equation.derNL[j] * (t - equation.slopes[j]);
+        }
+      }
+      std::fill(trackParams.begin(), trackParams.end(), 0.);
+      // Refit the track.
+      bool ok = fitTrack(equations, trackParams, false, iteration);
+      // Cache the track state.
+      for (unsigned int j = 0; j < m_nalc; ++j) {
+        localParams[i][j] = trackParams[2 * j];
+      }
+      if (ok) {
+        // Update the total chi2.
+        chi2 += trackParams[2 * m_nalc + 1];
+        ndof += trackParams[2 * m_nalc];
+        ++nGoodTracks;
+      } else {
+        // Disable the track.
+        m_equations[i].clear();
+      }
+    }
+    info() << "Chi2 / DOF after re-fit: " << chi2 / (ndof - nRows) << endmsg;
+  }
+
+  // Print the final results.
+  printResults();
+
+  info() << endmsg;
+  info() << "            * o o                   o      " << endmsg;
+  info() << "              o o                   o      " << endmsg;
+  info() << "   o ooooo  o o o  oo  ooo   oo   ooo  oo  " << endmsg;
+  info() << "    o  o  o o o o o  o o  o o  o o  o o  o " << endmsg;
+  info() << "    o  o  o o o o oooo o  o oooo o  o oooo " << endmsg;
+  info() << "    o  o  o o o o o    ooo  o    o  o o    " << endmsg;
+  info() << "    o  o  o o o o  oo  o     oo   ooo  oo ++ ends." << endmsg;
+  info() << "                       o                   " << endmsg;
+  info() << endmsg;
+  return true;
+}
+
+//=============================================================================
+// Obtain solution of a system of linear equations with symmetric matrix
+// and the inverse (using 'singular-value friendly' GAUSS pivot).
+// Solve the equation V * X = B.
+// V is replaced by its inverse matrix and B by X, the solution vector
+//=============================================================================
+int TbMillepede::invertMatrix(std::vector<std::vector<double> >& v,
+                              std::vector<double>& b, const int n) {
+  int rank = 0;
+  const double eps = 0.0000000000001;
+
+  std::vector<double> diag(n, 0.);
+  std::vector<bool> used_param(n, true);
+  std::vector<bool> flag(n, true);
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j <= i; j++) {
+      v[j][i] = v[i][j];
+    }
+  }
+
+  // Find max. elements of each row and column.
+  std::vector<double> r(n, 0.);
+  std::vector<double> c(n, 0.);
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j < n; j++) {
+      if (fabs(v[i][j]) >= r[i]) r[i] = fabs(v[i][j]);
+      if (fabs(v[j][i]) >= c[i]) c[i] = fabs(v[j][i]);
+    }
+  }
+  for (int i = 0; i < n; i++) {
+    if (0.0 != r[i]) r[i] = 1. / r[i];
+    if (0.0 != c[i]) c[i] = 1. / c[i];
+    // Check if max elements are within requested precision.
+    if (eps >= r[i]) r[i] = 0.0;
+    if (eps >= c[i]) c[i] = 0.0;
+  }
+
+  // Equilibrate the V matrix
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j < n; j++) {
+      v[i][j] = sqrt(r[i]) * v[i][j] * sqrt(c[j]);
+    }
+  }
+
+  for (int i = 0; i < n; i++) {
+    // Save the absolute values of the diagonal elements.
+    diag[i] = fabs(v[i][i]);
+    if (r[i] == 0. && c[i] == 0.) {
+      // This part is empty (non-linear treatment with non constraints)
+      flag[i] = false;
+      used_param[i] = false;
+    }
+  }
+
+  for (int i = 0; i < n; i++) {
+    double vkk = 0.0;
+    int k = -1;
+    // First look for the pivot, i. e. the max unused diagonal element.
+    for (int j = 0; j < n; j++) {
+      if (flag[j] && (fabs(v[j][j]) > std::max(fabs(vkk), eps))) {
+        vkk = v[j][j];
+        k = j;
+      }
+    }
+
+    if (k >= 0) {
+      // Pivot found.
+      rank++;
+      // Use this value.
+      flag[k] = false;
+      // Replace pivot by its inverse.
+      vkk = 1.0 / vkk;
+      v[k][k] = -vkk;
+      for (int j = 0; j < n; j++) {
+        for (int jj = 0; jj < n; jj++) {
+          if (j != k && jj != k && used_param[j] && used_param[jj]) {
+            // Other elements (do them first as you use old v[k][j])
+            v[j][jj] = v[j][jj] - vkk * v[j][k] * v[k][jj];
+          }
+        }
+      }
+      for (int j = 0; j < n; j++) {
+        if (j != k && used_param[j]) {
+          v[j][k] = v[j][k] * vkk;
+          v[k][j] = v[k][j] * vkk;
+        }
+      }
+    } else {
+      // No more pivot value (clear those elements)
+      for (int j = 0; j < n; j++) {
+        if (flag[j]) {
+          b[j] = 0.0;
+          for (int k = 0; k < n; k++) {
+            v[j][k] = 0.0;
+            v[k][j] = 0.0;
+          }
+        }
+      }
+      break;
+    }
+  }
+  // Correct matrix V
+  for (int i = 0; i < n; i++) {
+    for (int j = 0; j < n; j++) {
+      v[i][j] = sqrt(c[i]) * v[i][j] * sqrt(r[j]);
+    }
+  }
+
+  std::vector<double> temp(n, 0.);
+  for (int j = 0; j < n; j++) {
+    // Reverse matrix elements
+    for (int jj = 0; jj < n; jj++) {
+      v[j][jj] = -v[j][jj];
+      temp[j] += v[j][jj] * b[jj];
+    }
+  }
+
+  for (int j = 0; j < n; j++) {
+    b[j] = temp[j];
+  }
+  return rank;
+}
+
+//=============================================================================
+// Simplified version.
+//=============================================================================
+int TbMillepede::invertMatrixLocal(std::vector<std::vector<double> >& v,
+                                   std::vector<double>& b, const int n) {
+
+  int rank = 0;
+  const double eps = 0.0000000000001;
+
+  std::vector<bool> flag(n, true);
+  std::vector<double> diag(n, 0.);
+  for (int i = 0; i < n; i++) {
+    // Save the absolute values of the diagonal elements.
+    diag[i] = fabs(v[i][i]);
+    for (int j = 0; j <= i; j++) {
+      v[j][i] = v[i][j];
+    }
+  }
+
+  for (int i = 0; i < n; i++) {
+    double vkk = 0.0;
+    int k = -1;
+    // First look for the pivot, i. e. the max. unused diagonal element.
+    for (int j = 0; j < n; j++) {
+      if (flag[j] && (fabs(v[j][j]) > std::max(fabs(vkk), eps * diag[j]))) {
+        vkk = v[j][j];
+        k = j;
+      }
+    }
+
+    if (k >= 0) {
+      // Pivot found
+      rank++;
+      flag[k] = false;
+      // Replace pivot by its inverse.
+      vkk = 1.0 / vkk;
+      v[k][k] = -vkk;
+      for (int j = 0; j < n; j++) {
+        for (int jj = 0; jj < n; jj++) {
+          if (j != k && jj != k) {
+            // Other elements (do them first as you use old v[k][j])
+            v[j][jj] = v[j][jj] - vkk * v[j][k] * v[k][jj];
+          }
+        }
+      }
+
+      for (int j = 0; j < n; j++) {
+        if (j != k) {
+          v[j][k] = v[j][k] * vkk;
+          v[k][j] = v[k][j] * vkk;
+        }
+      }
+    } else {
+      // No more pivot values (clear those elements).
+      for (int j = 0; j < n; j++) {
+        if (flag[j]) {
+          b[j] = 0.0;
+          for (k = 0; k < n; k++) v[j][k] = 0.0;
+        }
+      }
+      break;
+    }
+  }
+
+  std::vector<double> temp(n, 0.);
+  for (int j = 0; j < n; j++) {
+    // Reverse matrix elements
+    for (int jj = 0; jj < n; jj++) {
+      v[j][jj] = -v[j][jj];
+      temp[j] += v[j][jj] * b[jj];
+    }
+  }
+  for (int j = 0; j < n; j++) {
+    b[j] = temp[j];
+  }
+  return rank;
+}
+
+//=============================================================================
+// Return the limit in chi^2 / nd for n sigmas stdev authorized.
+// Only n=1, 2, and 3 are expected in input.
+//=============================================================================
+double TbMillepede::chi2Limit(const int n, const int nd) const {
+  constexpr double sn[3] = {0.47523, 1.690140, 2.782170};
+  constexpr double table[3][30] = {
+      {1.0000, 1.1479, 1.1753, 1.1798, 1.1775, 1.1730, 1.1680, 1.1630,
+       1.1581, 1.1536, 1.1493, 1.1454, 1.1417, 1.1383, 1.1351, 1.1321,
+       1.1293, 1.1266, 1.1242, 1.1218, 1.1196, 1.1175, 1.1155, 1.1136,
+       1.1119, 1.1101, 1.1085, 1.1070, 1.1055, 1.1040},
+      {4.0000, 3.0900, 2.6750, 2.4290, 2.2628, 2.1415, 2.0481, 1.9736,
+       1.9124, 1.8610, 1.8171, 1.7791, 1.7457, 1.7161, 1.6897, 1.6658,
+       1.6442, 1.6246, 1.6065, 1.5899, 1.5745, 1.5603, 1.5470, 1.5346,
+       1.5230, 1.5120, 1.5017, 1.4920, 1.4829, 1.4742},
+      {9.0000, 5.9146, 4.7184, 4.0628, 3.6410, 3.3436, 3.1209, 2.9468,
+       2.8063, 2.6902, 2.5922, 2.5082, 2.4352, 2.3711, 2.3143, 2.2635,
+       2.2178, 2.1764, 2.1386, 2.1040, 2.0722, 2.0428, 2.0155, 1.9901,
+       1.9665, 1.9443, 1.9235, 1.9040, 1.8855, 1.8681}};
+
+  if (nd < 1) return 0.;
+  const int m = std::max(1, std::min(n, 3));
+  if (nd <= 30) return table[m - 1][nd - 1];
+  return ((sn[m - 1] + sqrt(float(2 * nd - 3))) *
+          (sn[m - 1] + sqrt(float(2 * nd - 3)))) /
+         float(2 * nd - 2);
+}
+
+//=============================================================================
+// Multiply general M-by-N matrix A and N-vector X
+//=============================================================================
+bool TbMillepede::multiplyAX(const std::vector<std::vector<double> >& a,
+                             const std::vector<double>& x,
+                             std::vector<double>& y, const unsigned int n,
+                             const unsigned int m) {
+
+  // Y = A * X, where
+  //   A = general M-by-N matrix
+  //   X = N vector
+  //   Y = M vector
+  for (unsigned int i = 0; i < m; ++i) {
+    y[i] = 0.0;
+    for (unsigned int j = 0; j < n; ++j) {
+      y[i] += a[i][j] * x[j];
+    }
+  }
+  return true;
+}
+
+//=============================================================================
+// Multiply symmetric N-by-N matrix V from the left with general M-by-N
+// matrix A and from the right with the transposed of the same general
+// matrix to form a symmetric M-by-M matrix W.
+//=============================================================================
+bool TbMillepede::multiplyAVAt(const std::vector<std::vector<double> >& v,
+                               const std::vector<std::vector<double> >& a,
+                               std::vector<std::vector<double> >& w,
+                               const unsigned int n, const unsigned int m) {
+
+  // W = A * V * AT, where
+  //   V = symmetric N-by-N matrix
+  //   A = general N-by-M matrix
+  //   W = symmetric M-by-M matrix
+  for (unsigned int i = 0; i < m; ++i) {
+    for (unsigned int j = 0; j <= i; ++j) {
+      // Reset the final matrix.
+      w[i][j] = 0.0;
+      // Fill the upper left triangle.
+      for (unsigned int k = 0; k < n; ++k) {
+        for (unsigned int l = 0; l < n; ++l) {
+          w[i][j] += a[i][k] * v[k][l] * a[j][l];
+        }
+      }
+      // Fill the rest.
+      w[j][i] = w[i][j];
+    }
+  }
+
+  return true;
+}
+
+//=============================================================================
+// Print results
+//=============================================================================
+bool TbMillepede::printResults() {
+  const std::string line(85, '-');
+  info() << line << endmsg;
+  info() << " Result of fit for global parameters" << endmsg;
+  info() << line << endmsg;
+  info() << "   I    Difference    Last step      "
+         << "Error        Pull     Global corr." << endmsg;
+  info() << line << endmsg;
+  for (unsigned int i = 0; i < m_nagb; ++i) {
+    double err = sqrt(fabs(m_cgmat[i][i]));
+    if (m_cgmat[i][i] < 0.0) err = -err;
+    if (fabs(m_cgmat[i][i] * m_diag[i]) > 0) {
+      info() << std::setprecision(6) << std::fixed;
+      // Calculate the pull.
+      const double pull =
+          m_dparm[i] / sqrt(m_psigm[i] * m_psigm[i] - m_cgmat[i][i]);
+      // Calculate the global correlation coefficient
+      // (correlation between the parameter and all the other variables).
+      const double gcor = sqrt(fabs(1.0 - 1.0 / (m_cgmat[i][i] * m_diag[i])));
+      info() << std::setw(4) << i << "   " << std::setw(10) << m_dparm[i]
+             << "   " << std::setw(10) << m_bgvec[i] << "   " << std::setw(10)
+             << std::setprecision(5) << err << "   " << std::setw(10)
+             << std::setprecision(5) << pull << "   " << std::setw(10) << gcor
+             << endmsg;
+    } else {
+      info() << std::setw(4) << i << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF"
+             << "   " << std::setw(10) << "OFF" << endmsg;
+    }
+    if ((i + 1) % (m_nagb / 6) == 0) info() << line << endmsg;
+  }
+  if (m_debug) {
+    for (unsigned int i = 0; i < m_nagb; ++i) {
+      debug() << " i=" << i
+              << "  sqrt(fabs(cgmat[i][i]))=" << sqrt(fabs(m_cgmat[i][i]))
+              << " diag = " << m_diag[i] << endmsg;
+    }
+  }
+
+  return true;
+}
diff --git a/TbAlignment/src/TbMillepede.h b/TbAlignment/src/TbMillepede.h
new file mode 100755
index 0000000..aebed80
--- /dev/null
+++ b/TbAlignment/src/TbMillepede.h
@@ -0,0 +1,144 @@
+#pragma once
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbAlignmentBase.h"
+
+/** @class TbMillepede TbMillepede.h
+ *
+ *  Implementation of the Millepede algorithm.
+ *
+ *  @author Christoph Hombach
+ *  @date   2012-06-19
+ */
+
+class TbMillepede : public TbAlignmentBase {
+ public:
+  /// Constructor
+  TbMillepede(const std::string& type, const std::string& name,
+              const IInterface* parent);
+  /// Destructor
+  virtual ~TbMillepede();
+
+  virtual StatusCode initialize();
+
+  void align(std::vector<TbAlignmentTrack*>& alignmentTracks);
+
+  virtual void updateGeometry();
+
+ private:
+  struct Equation {
+    double rmeas;
+    double weight;
+    std::vector<int> indG;
+    std::vector<double> derG;
+    std::vector<int> indL;
+    std::vector<double> derL;
+    std::vector<int> indNL;
+    std::vector<double> derNL;
+    std::vector<double> slopes;
+  };
+  struct Constraint {
+    /// Right-hand side (Lagrange multiplier)
+    double rhs;
+    /// Coefficients
+    std::vector<double> coefficients;
+  };
+
+  /// (Re-)initialise matrices and vectors.
+  bool reset(const unsigned int nPlanes, const double startfact);
+  /// Setup the constraint equations.
+  void setConstraints(const unsigned int nPlanes);
+  /// Define a single constraint equation
+  void addConstraint(const std::vector<double>& dercs, const double rhs);
+  /// Add the equations for one track and do the local fit.
+  bool putTrack(LHCb::TbTrack* track, const unsigned int nPlanes);
+  /// Store the parameters for one measurement.
+  void addEquation(std::vector<Equation>& equations,
+                   const std::vector<double>& derlc,
+                   const std::vector<double>& dergb,
+                   const std::vector<double>& dernl,
+                   const std::vector<int>& dernli,
+                   const std::vector<double>& dernls, const double rmeas,
+                   const double sigma);
+  /// Perform local parameters fit using the equations for one track.
+  bool fitTrack(const std::vector<Equation>& equations,
+                std::vector<double>& trackParams, const bool singlefit,
+                const unsigned int iteration);
+  /// Perform global parameters fit.
+  bool fitGlobal();
+  /// Print the results of the global parameters fit.
+  bool printResults();
+
+  /// Matrix inversion and solution for global fit.
+  int invertMatrix(std::vector<std::vector<double> >& v, std::vector<double>& b,
+                   const int n);
+  /// Matrix inversion and solution for local fit.
+  int invertMatrixLocal(std::vector<std::vector<double> >& v,
+                        std::vector<double>& b, const int n);
+
+  /// Return the limit in chi2 / ndof for n sigmas.
+  double chi2Limit(const int n, const int nd) const;
+  /// Multiply matrix and vector
+  bool multiplyAX(const std::vector<std::vector<double> >& a,
+                  const std::vector<double>& x, std::vector<double>& y,
+                  const unsigned int n, const unsigned int m);
+  /// Multiply matrices
+  bool multiplyAVAt(const std::vector<std::vector<double> >& v,
+                    const std::vector<std::vector<double> >& a,
+                    std::vector<std::vector<double> >& w, const unsigned int n,
+                    const unsigned int m);
+
+  /// Number of global derivatives
+  unsigned int m_nagb;
+  /// Number of local derivatives
+  unsigned int m_nalc;
+
+  /// Equations for each track
+  std::vector<std::vector<Equation> > m_equations;
+  /// Constraint equations
+  std::vector<Constraint> m_constraints;
+
+  ///  Flag for each global parameter whether it is fixed or not.
+  std::vector<bool> m_fixed;
+  /// Sigmas for each global parameter.
+  std::vector<double> m_psigm;
+
+  std::vector<std::vector<double> > m_cgmat;
+  std::vector<std::vector<double> > m_corrm;
+  std::vector<std::vector<double> > m_clcmat;
+
+  std::vector<double> m_bgvec;
+  std::vector<double> m_corrv;
+  std::vector<double> m_diag;
+
+  /// Difference in misalignment parameters with respect to initial values.
+  std::vector<double> m_dparm;
+
+  /// Mapping of internal numbering to geometry service planes.
+  std::vector<unsigned int> m_millePlanes;
+
+  bool m_debug;
+  /// Flag to switch on/off iterations in the global fit.
+  bool m_iterate;
+  /// Residual cut after the first iteration.
+  double m_rescut;
+  /// Residual cut in the first iteration.
+  double m_rescut_init;
+  /// Factor in chisquare / ndof cut.
+  double m_cfactr;
+  /// Reference value for chisquare / ndof cut factor.
+  double m_cfactref;
+  // Number of standard deviations for chisquare / ndof cut.
+  int m_nstdev;
+  /// Number of "full" iterations (with geometry updates).
+  unsigned int m_nIterations;
+  /// Sigmas for each degree of freedom
+  std::vector<double> m_sigmas;
+  /// Planes to be kept fixed
+  std::vector<unsigned int> m_fixedPlanes;
+  /// Flag to fix all degrees of freedom or only the translations.
+  bool m_fix_all;
+};
diff --git a/TbAnalysis/.svn/all-wcprops b/TbAnalysis/.svn/all-wcprops
new file mode 100644
index 0000000..2703404
--- /dev/null
+++ b/TbAnalysis/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 54
+/guest/lhcb/!svn/ver/198560/Kepler/trunk/Tb/TbAnalysis
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/197484/Kepler/trunk/Tb/TbAnalysis/CMakeLists.txt
+END
diff --git a/TbAnalysis/.svn/entries b/TbAnalysis/.svn/entries
new file mode 100644
index 0000000..437b18f
--- /dev/null
+++ b/TbAnalysis/.svn/entries
@@ -0,0 +1,71 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAnalysis
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-12-02T13:34:23.155536Z
+198560
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+src
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:56.000000Z
+c41c4c0761ac948f284cefbc7204cf90
+2015-11-12T10:18:32.099510Z
+197484
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+565
+
diff --git a/TbAnalysis/.svn/text-base/CMakeLists.txt.svn-base b/TbAnalysis/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..6f1bab9
--- /dev/null
+++ b/TbAnalysis/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,16 @@
+################################################################################
+# Package: TbAnalysis
+################################################################################
+gaudi_subdir(TbAnalysis v1r1)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS MathCore GenVector Physics Matrix)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbAnalysis
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbAnalysis/CMakeLists.txt b/TbAnalysis/CMakeLists.txt
new file mode 100644
index 0000000..6f1bab9
--- /dev/null
+++ b/TbAnalysis/CMakeLists.txt
@@ -0,0 +1,16 @@
+################################################################################
+# Package: TbAnalysis
+################################################################################
+gaudi_subdir(TbAnalysis v1r1)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS MathCore GenVector Physics Matrix)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbAnalysis
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbAnalysis/cmt/.svn/all-wcprops b/TbAnalysis/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..1db0ab4
--- /dev/null
+++ b/TbAnalysis/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/guest/lhcb/!svn/ver/197783/Kepler/trunk/Tb/TbAnalysis/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/188483/Kepler/trunk/Tb/TbAnalysis/cmt/requirements
+END
diff --git a/TbAnalysis/cmt/.svn/entries b/TbAnalysis/cmt/.svn/entries
new file mode 100644
index 0000000..6ffb923
--- /dev/null
+++ b/TbAnalysis/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAnalysis/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-19T10:45:50.948321Z
+197783
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+c8d9a4321a922a28b558724595940d38
+2015-05-19T09:49:28.904848Z
+188483
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+519
+
diff --git a/TbAnalysis/cmt/.svn/text-base/requirements.svn-base b/TbAnalysis/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..7e5bc65
--- /dev/null
+++ b/TbAnalysis/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,16 @@
+package TbAnalysis 
+version v1r1
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbAnalysis    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbAnalysis
+macro_append ROOT_linkopts " -lMinuit -lHist -lPhysics"
diff --git a/TbAnalysis/cmt/requirements b/TbAnalysis/cmt/requirements
new file mode 100644
index 0000000..7e5bc65
--- /dev/null
+++ b/TbAnalysis/cmt/requirements
@@ -0,0 +1,16 @@
+package TbAnalysis 
+version v1r1
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbAnalysis    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbAnalysis
+macro_append ROOT_linkopts " -lMinuit -lHist -lPhysics"
diff --git a/TbAnalysis/doc/.svn/all-wcprops b/TbAnalysis/doc/.svn/all-wcprops
new file mode 100644
index 0000000..09dda54
--- /dev/null
+++ b/TbAnalysis/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/guest/lhcb/!svn/ver/197611/Kepler/trunk/Tb/TbAnalysis/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197611/Kepler/trunk/Tb/TbAnalysis/doc/release.notes
+END
diff --git a/TbAnalysis/doc/.svn/entries b/TbAnalysis/doc/.svn/entries
new file mode 100644
index 0000000..19c474f
--- /dev/null
+++ b/TbAnalysis/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAnalysis/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-14T11:28:35.425170Z
+197611
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+3b8f531e938c8d9e99fff291195144eb
+2015-11-14T11:28:35.425170Z
+197611
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+737
+
diff --git a/TbAnalysis/doc/.svn/text-base/release.notes.svn-base b/TbAnalysis/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..0c7bcfa
--- /dev/null
+++ b/TbAnalysis/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,25 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbAnalysis
+! Responsible :
+! Purpose     : Collection of algorithms for specific test beam analyses
+!-----------------------------------------------------------------------------
+
+! 2015-11-12 - Dan Saunders
+ - Add TbEfficiency.
+
+! 2015-11-11 - Tim Evans
+ - Add TbVertexing.
+
+! 2015-10-23 - Heinrich Schindler
+ - Fix compiler warnings in TbEffPur uncovered by clang.
+
+!========================= TbAnalysis v1r1 2015-05-19 =======================
+
+! 2015-03-04 - Tim Evans
+ - Add plots to TbTimewalkMonitor
+
+!========================= TbAnalysis v1r0 2014-11-30 =======================
+
+! 2014-11-17 - Heinrich Schindler
+ - Initial import
+
diff --git a/TbAnalysis/doc/release.notes b/TbAnalysis/doc/release.notes
new file mode 100644
index 0000000..0c7bcfa
--- /dev/null
+++ b/TbAnalysis/doc/release.notes
@@ -0,0 +1,25 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbAnalysis
+! Responsible :
+! Purpose     : Collection of algorithms for specific test beam analyses
+!-----------------------------------------------------------------------------
+
+! 2015-11-12 - Dan Saunders
+ - Add TbEfficiency.
+
+! 2015-11-11 - Tim Evans
+ - Add TbVertexing.
+
+! 2015-10-23 - Heinrich Schindler
+ - Fix compiler warnings in TbEffPur uncovered by clang.
+
+!========================= TbAnalysis v1r1 2015-05-19 =======================
+
+! 2015-03-04 - Tim Evans
+ - Add plots to TbTimewalkMonitor
+
+!========================= TbAnalysis v1r0 2014-11-30 =======================
+
+! 2014-11-17 - Heinrich Schindler
+ - Initial import
+
diff --git a/TbAnalysis/src/.svn/all-wcprops b/TbAnalysis/src/.svn/all-wcprops
new file mode 100644
index 0000000..f3d3a00
--- /dev/null
+++ b/TbAnalysis/src/.svn/all-wcprops
@@ -0,0 +1,77 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/guest/lhcb/!svn/ver/198560/Kepler/trunk/Tb/TbAnalysis/src
+END
+TbChargeCalib.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/182246/Kepler/trunk/Tb/TbAnalysis/src/TbChargeCalib.h
+END
+TbEfficiency.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197726/Kepler/trunk/Tb/TbAnalysis/src/TbEfficiency.h
+END
+TbTimewalkMonitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/190289/Kepler/trunk/Tb/TbAnalysis/src/TbTimewalkMonitor.h
+END
+TbResolutionMonitor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/196412/Kepler/trunk/Tb/TbAnalysis/src/TbResolutionMonitor.cpp
+END
+TbVertexing.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197430/Kepler/trunk/Tb/TbAnalysis/src/TbVertexing.cpp
+END
+TbEffPur.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/196683/Kepler/trunk/Tb/TbAnalysis/src/TbEffPur.h
+END
+TbResolutionMonitor.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/180518/Kepler/trunk/Tb/TbAnalysis/src/TbResolutionMonitor.h
+END
+TbVertexing.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197430/Kepler/trunk/Tb/TbAnalysis/src/TbVertexing.h
+END
+TbChargeCalib.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/196412/Kepler/trunk/Tb/TbAnalysis/src/TbChargeCalib.cpp
+END
+TbEfficiency.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/197807/Kepler/trunk/Tb/TbAnalysis/src/TbEfficiency.cpp
+END
+TbTimewalkMonitor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/198560/Kepler/trunk/Tb/TbAnalysis/src/TbTimewalkMonitor.cpp
+END
+TbEffPur.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/196683/Kepler/trunk/Tb/TbAnalysis/src/TbEffPur.cpp
+END
diff --git a/TbAnalysis/src/.svn/entries b/TbAnalysis/src/.svn/entries
new file mode 100644
index 0000000..d09f0b7
--- /dev/null
+++ b/TbAnalysis/src/.svn/entries
@@ -0,0 +1,436 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAnalysis/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-12-02T13:34:23.155536Z
+198560
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbChargeCalib.h
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+0aa8b51d435603d7012317a9411ee48d
+2015-01-10T23:07:56.865725Z
+182246
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+562
+
+TbEfficiency.h
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+d3ec6a1137a160320c9f15a14a32eddb
+2015-11-17T13:18:40.094527Z
+197726
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1376
+
+TbTimewalkMonitor.h
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+52686757b12cbe3dd20728f67a2e2071
+2015-06-15T11:23:40.096784Z
+190289
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1560
+
+TbResolutionMonitor.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+f001371c56c9e600d3ef14e6c5a19c99
+2015-10-17T15:37:57.736429Z
+196412
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4148
+
+TbVertexing.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+5f51593e57cf73e07167538119b29a41
+2015-11-10T17:28:27.488768Z
+197430
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4744
+
+TbEffPur.h
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+512a6da1800e9cd8316e47d5db99d04a
+2015-10-23T11:15:02.549411Z
+196683
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3799
+
+TbResolutionMonitor.h
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+0f96703f005e8931c476e854b4e87088
+2014-11-20T19:24:21.222174Z
+180518
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+571
+
+TbVertexing.h
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+22804f786e162cd44ab4b7eb8984cc6c
+2015-11-10T17:28:27.488768Z
+197430
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2893
+
+TbChargeCalib.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+e8a1fccc22bed61872c10442bcb8ace9
+2015-10-17T15:37:57.736429Z
+196412
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2446
+
+TbEfficiency.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+f3d5b2f047f8e75c4a0261a3f934e287
+2015-11-20T04:35:00.494755Z
+197807
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7419
+
+TbTimewalkMonitor.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+572b3086a01e101920e188654d8b560e
+2015-12-02T13:34:23.155536Z
+198560
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9133
+
+TbEffPur.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+ab7ce752654d8b7586dd2cdc0077fe08
+2015-10-23T11:15:02.549411Z
+196683
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+34737
+
diff --git a/TbAnalysis/src/.svn/text-base/TbChargeCalib.cpp.svn-base b/TbAnalysis/src/.svn/text-base/TbChargeCalib.cpp.svn-base
new file mode 100644
index 0000000..ebd8678
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbChargeCalib.cpp.svn-base
@@ -0,0 +1,74 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbChargeCalib.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbChargeCalib)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbChargeCalib::TbChargeCalib(const std::string& name, 
+                                     ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbChargeCalib::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  info() << "Booking histograms for Chargecalib ... " << endmsg;
+  m_ToTHists.reserve(256*256);
+  for( unsigned int i = 0 ; i < 256*256; ++i){
+    const std::string name = "c=" + std::to_string( i/256 ) + ", r=" + std::to_string(i%256);
+    if( i % 256 == 0 ) info() << "Booked histogram for column " << i << endmsg;
+    m_ToTHists.push_back(book1D(name, name, 0.5, 200.5, 200));
+    setAxisLabels(m_ToTHists[i], "ToT", "Entries");
+  }
+  info() << "Booked 60000 ish hists" << endmsg; 
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbChargeCalib::execute() {
+
+   LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation+std::to_string(0));
+   if (!clusters) {
+     error() << "No clusters in " << m_clusterLocation << endmsg;
+     return StatusCode::FAILURE;
+   }
+  for( const LHCb::TbCluster* c : *clusters  ){
+    if( c->size() != 1 ) continue;
+ 
+    unsigned int col = c->hits()[0]->col();
+    unsigned int row = c->hits()[0]->row();
+    unsigned int tot = c->hits()[0]->ToT();
+    //info() << c->hits()[0] << endmsg;
+    m_ToTHists[ col*256 + row ]->fill( tot );
+
+  } 
+  return StatusCode::SUCCESS;
+}
+
diff --git a/TbAnalysis/src/.svn/text-base/TbChargeCalib.h.svn-base b/TbAnalysis/src/.svn/text-base/TbChargeCalib.h.svn-base
new file mode 100644
index 0000000..8e3860b
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbChargeCalib.h.svn-base
@@ -0,0 +1,28 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbChargeCalib TbChargeCalib.h
+ *
+ */
+
+class TbChargeCalib : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbChargeCalib(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbChargeCalib() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::string m_clusterLocation;
+
+  std::vector<AIDA::IHistogram1D*> m_ToTHists;
+
+};
diff --git a/TbAnalysis/src/.svn/text-base/TbEffPur.cpp.svn-base b/TbAnalysis/src/.svn/text-base/TbEffPur.cpp.svn-base
new file mode 100644
index 0000000..9503401
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbEffPur.cpp.svn-base
@@ -0,0 +1,900 @@
+#include <fstream>
+
+// ROOT
+#include "TMath.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbEffPur.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbEffPur)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbEffPur::TbEffPur(const std::string& name, ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator),
+  m_pitch(0.055),
+  m_nDUTpixels(256),
+  m_nTracks(0),
+  m_nClusters(0),
+  m_nTrackedClusters(0),
+	m_nClustersPassedCentral(0),
+	m_nTracksCentral(0),
+	m_nClustersPassedCorner(0),
+	m_nTracksCorner(0),
+  m_eff(0.),
+  m_pur(0.),
+  m_deadAreaRadius(2.),
+  m_trackAssociated(NULL)
+{
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("VertexLocation",
+                  m_vertexLocation = LHCb::TbVertexLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+  // Parameters.
+  declareProperty("DUTindex", m_DUTindex = 4);
+  declareProperty("GlobalCutXLow", m_xLow = 3);
+  declareProperty("GlobalCutXUp", m_xUp = 9);
+  declareProperty("GlobalCutYLow", m_yLow = 3);
+  declareProperty("GlobalCutYUp", m_yUp = 9);
+  declareProperty("LocalProbabilityCut", m_probCut = 0.5);
+
+  declareProperty("RResidualCut", m_rResidualCut = 0.1);
+  declareProperty("TResidualCut", m_tResidualCut = 100);
+  declareProperty("ChargeCutLow", m_chargeCutLow = 0);
+  // ... note this global cut enforced at different point to above.
+  declareProperty("ChargeCutUp", m_chargeCutUp = 1000000);
+  declareProperty("LitSquareSide", m_litSquareSide = 0);
+
+  declareProperty("ViewerOutput", m_viewerOutput = false);
+  declareProperty("ViewerEventNum", m_viewerEvent = 100);
+  declareProperty("TGap", m_tGap = 200);
+  declareProperty("CorrelationTimeWindow", m_correlationTimeWindow = 100);
+  declareProperty("ApplyVeto", m_applyVeto = true);
+  declareProperty("TelescopeClusterVetoDelT", m_telescopeClusterVetoDelT = 30);
+  declareProperty("EdgeVetoDistance", m_edgeVetoDistance = 0.025);
+  m_nEvent = -1;
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbEffPur::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+	// Efficiency objects.
+	m_effX = new TEfficiency("efficiencyX", "efficiencyX", 40, 0.0, 0.11);
+	m_effY = new TEfficiency("efficiencyY", "efficiencyY", 40, 0.0, 0.11);
+	m_effs = new TEfficiency("efficiency", "efficiency", 1, -0.5, 0.5);
+  m_purs = new TEfficiency("purity", "Tb/TbEffPur/pur", 1, -0.5, 0.5);
+  m_effHitmap = new TEfficiency("efficiencyHitmap", "efficiencyHitmap",
+  		64, 0.0, 14.08, 64, 0.0, 14.08);
+  m_purHitmap = new TEfficiency("puritHitmap", "purityHitmap",
+  		64, 0.0, 14.08, 64, 0.0, 14.08);
+
+  int nBins = 50;
+  m_effHitmapInterPixel = new TEfficiency("efficiencyHitmapInterPixel", "efficiencyHitmapInterPixel",
+  		nBins, 0.0, 0.055, nBins, 0.0, 0.055);
+  m_purHitmapInterPixel = new TEfficiency("puritHitmapInterPixel", "purityHitmapInterPixel",
+  		nBins, 0.0, 0.055, nBins, 0.0, 0.055);
+
+  m_effHitmapInterPixelTriple = new TEfficiency("efficiencyHitmapInterPixelTriple", "efficiencyHitmapInterPixelTriple",
+  		150, 0.0, 10*0.055, 20, 0.0, 2*0.055);
+
+  for (unsigned int i=1; i<5; i++) {
+  	std::string name = "efficiencyHitmapInterClusterSize" + std::to_string(i);
+  	TEfficiency * e = new TEfficiency(name.c_str(), name.c_str(),
+  		nBins, 0.0, 0.055, nBins, 0.0, 0.055);
+  	m_effHitmapInterPixelVsSizes.push_back(e);
+  }
+
+  // Plots for post correlations.
+  m_remainsCorrelationsX = book2D("remainsClusterCorrelationsX", "remainsClusterCorrelationsX", 0, 14, 200, 0, 14, 200);
+  m_remainsCorrelationsY = book2D("remainsClusterCorrelationsY", "remainsClusterCorrelationsY", 0, 14, 200, 0, 14, 200);
+  m_remainsDifferencesXY = book2D("remainsDifferencesXY", "remainsDifferencesXY", -1.5, 1.5, 150, -1.5, 1.5, 150);
+  m_clusterRemainsPositionsLocal = book2D("clusterRemainsPositionsLocal", "clusterRemainsPositionsLocal", -5, 20, 600, -5, 20, 600);
+  m_trackRemainsPositionsLocal = book2D("trackRemainsPositionsLocal", "trackRemainsPositionsLocal", 0, 256, 600, 0, 256, 600);
+  m_clusterRemainsPositionsGlobal = book2D("clusterRemainsPositionsGlobal", "clusterRemainsPositionsGlobal", -5, 20, 600, -5, 20, 600);
+  m_trackRemainsPositionsGlobal = book2D("trackRemainsPositionsGlobal", "trackRemainsPositionsGlobal", -5, 20, 600, -5, 20, 600);
+  m_vetoTracksHitmap = book2D("vetoTrackHitmap", "vetoTrackHitmap", -5, 20, 600, -5, 20, 600);
+  m_vetoClustersHitmap = book2D("vetoClusterHitmap", "vetoClusterHitmap", -5, 20, 600, -5, 20, 600);
+  m_timeResidualVsColumn = book2D("timeResidualVsColumn", "timeResidualVsColumn", 0, 256, 256, -50, 50, 500);
+
+
+  // Setup the tools.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  // h_effVsCharge = new TH2F("effVsCharge", "effVsCharge", 50, 0.5, 1, 20, 0.5, 20.5);
+  // TFile * f = new TFile("/afs/cern.ch/user/d/dsaunder/cmtuser/KEPLER/KEPLER_HEAD/EDR_plots/EfficiencyResults/Eff-S22-Run6309-500V.root", "READ");
+  // h_effInter = (TH2F*)f->Get("eff_histo");
+  return StatusCode::SUCCESS;
+
+}
+
+
+//=============================================================================
+// Finalizer
+//=============================================================================
+StatusCode TbEffPur::finalize() {
+	m_effs->SetTotalEvents(0, m_nTracks);
+	m_effs->SetPassedEvents(0, m_nTrackedClusters);
+
+	m_purs->SetTotalEvents(0, m_nClusters);
+	m_purs->SetPassedEvents(0, m_nTrackedClusters);
+
+	m_eff = m_nTrackedClusters/(1.0*m_nTracks);
+	m_pur = m_nTrackedClusters/(1.0*m_nClusters);
+	std::cout<<"ith ROOT Efficiency: " << m_effs->GetEfficiency(0) << " + " << m_effs->GetEfficiencyErrorUp(0) <<" - "<< m_effs->GetEfficiencyErrorLow(0) <<std::endl;
+	std::cout<<"ith ROOT Purity: " << m_purs->GetEfficiency(0) << " + " << m_purs->GetEfficiencyErrorUp(0) <<" - "<< m_purs->GetEfficiencyErrorLow(0) <<std::endl;
+
+	std::cout<<"Corner efficiency: "<<m_nClustersPassedCorner/(1.*m_nTracksCorner)<<std::endl;
+	std::cout<<"Central efficiency: "<<m_nClustersPassedCentral/(1.*m_nTracksCentral)<<std::endl;
+
+	plot(m_eff, "Efficiency", "Efficiency", 0.0, 1, 1);
+	plot(m_pur, "Purity", "Purity", 0.0, 1, 1);
+	plot(m_effs->GetEfficiencyErrorUp(0), "EfficiencyError", "EfficiencyError", 0.0, 1, 1);
+	plot(m_purs->GetEfficiencyErrorUp(0), "PurityError", "PurityError", 0.0, 1, 1);
+
+	TH2D * h = Gaudi::Utils::Aida2ROOT::aida2root(m_trackRemainsPositionsLocal);
+	double maxBin = h->GetBinContent(h->GetMaximumBin());
+	double minBin = h->GetBinContent(h->GetMinimumBin());
+	for (int i=0; i<m_trackRemainsPositionsLocal->xAxis().bins(); i++) {
+		for (int j=0; j<m_trackRemainsPositionsLocal->yAxis().bins(); j++) {
+			plot(m_trackRemainsPositionsLocal->binHeight(i, j), "trackRemainsBins",
+					"trackRemainsBins", minBin, maxBin, int(maxBin-minBin));
+		}
+	}
+
+	TFile * f = new TFile("EfficiencyResults.root", "RECREATE");
+	//m_effs->Write();
+
+	m_effHitmapInterPixel->Write();
+	m_effHitmapInterPixelTriple->Write();
+	//h_effVsCharge->Write();
+	//m_effs->CreateHistogram()->Write();
+	m_effHitmapInterPixel->CreateHistogram()->Write();
+	m_effHitmapInterPixelTriple->CreateHistogram()->Write();
+
+
+
+//	for (unsigned int i=0; i<m_effHitmapInterPixelVsSizes.size(); i++) {
+//		m_effHitmapInterPixelVsSizes[i]->Write();
+//		//m_effHitmapInterPixelVsSizes[i]->CreateHistogram()->Write();
+//	}
+	f->Close();
+  return TbAlgorithm::finalize();
+}
+
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbEffPur::execute()
+{
+	m_nEvent++;
+
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  //m_vertices = getIfExists<LHCb::TbVertices>(m_vertexLocation);
+  m_clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(m_DUTindex));
+
+  if (m_clusters->size() < 100 || m_tracks->size() < 100) return StatusCode::SUCCESS;
+
+  // Matching.
+  effPur();
+  return StatusCode::SUCCESS;
+}
+
+
+//=============================================================================
+// Efficiency finding
+//=============================================================================
+void TbEffPur::effPur()
+{
+	// Non-veto'd containers.
+  std::vector<LHCb::TbCluster*> * cutClusters = new std::vector<LHCb::TbCluster*>();
+  std::vector<LHCb::TbTrack*> cutTracks;
+  int nClustersPreVeto = m_clusters->size();
+  int nTracksPreVeto  = m_tracks->size();
+
+
+  // Apply veto.
+  if (m_applyVeto) applyVeto(cutClusters, &cutTracks);
+  else fillAllTrackClusters(cutClusters, &cutTracks);
+  m_trackAssociated = new std::vector<bool>(cutTracks.size(), false);
+  //std::cout<<"Fraction tracks not veto'd: "<<cutTracks.size()/(1.0*nTracksPreVeto)<<"\tEvent: "<<m_nEvent<<std::endl;
+  //std::cout<<"Fraction clusters not veto'd: "<<cutClusters->size()/(1.0*nClustersPreVeto)<<"\tEvent: "<<m_nEvent<<std::endl;
+  plot(cutClusters->size()/(1.0*nClustersPreVeto), "clusterFractionVetod", "clusterFractionVetod", 0.0, 1.0, 200);
+  plot(cutTracks.size()/(1.0*nTracksPreVeto), "trackFractionVetod", "trackFractionVetod", 0.0, 1.0, 200);
+
+
+  // Do matching.
+  m_nClusters += cutClusters->size();
+  m_nTracks += cutTracks.size();
+  trackClusters(cutClusters, &cutTracks);
+
+
+  // Viewer options.
+  if (m_nEvent == m_viewerEvent) {
+  	if (m_viewerOutput) outputViewerData();
+		for (LHCb::TbClusters::iterator iclust = cutClusters->begin();
+				iclust != cutClusters->end(); iclust++) {
+//			if (!(*iclust)->associated())
+//				std::cout<<"Note: non-associated clusters at hTime: "<<(*iclust)->htime()<<std::endl;
+		}
+  }
+
+  // Correlate remains.
+  //correlateRemains(&cutTracks, cutClusters);
+  delete cutClusters;
+  delete m_trackAssociated;
+}
+
+
+//=============================================================================
+// Global cuts
+//=============================================================================
+void TbEffPur::applyVeto(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks)
+{
+  // Gather all cluster times (over all planes) and sort it ___________________
+	std::vector<double> allClusterTimes;
+	for (unsigned int i=0; i<m_nPlanes; i++) {
+    LHCb::TbClusters * clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(i));
+		for (LHCb::TbClusters::const_iterator it = clusters->begin(); it != clusters->end(); ++it)
+			allClusterTimes.push_back((*it)->htime());
+	}
+	std::sort(allClusterTimes.begin(), allClusterTimes.end());
+
+
+
+	// Get big enough gaps in pairs _____________________________________________
+	std::vector<double> tGapCenters;
+	tGapCenters.push_back(0);
+	for (std::vector<double>::iterator itime = allClusterTimes.begin()+1;
+			itime != allClusterTimes.end(); itime++) {
+		plot((*itime) - (*(itime-1)), "allGapWidths", "allGapWidths", 0.0, 3000.0, 200);
+		if ((*itime) - (*(itime-1)) > m_tGap) {
+			tGapCenters.push_back(0.5*((*itime) + (*(itime-1))));
+			plot((*itime) - (*(itime-1)), "bigGapWidths", "bigGapWidths", 0.0, 3000.0, 200);
+		}
+	}
+	tGapCenters.push_back(allClusterTimes.back());
+	counter("nGaps") += tGapCenters.size();
+	plot(tGapCenters.size(), "nGaps", "nGaps", 0.0, 1000.0, 200);
+
+
+
+	// Loop over these sub events and veto ______________________________________
+	std::vector<double>::iterator igap;
+	for (igap = tGapCenters.begin(); igap != tGapCenters.end() - 1; igap++) {
+		bool veto = false;
+
+		if (igap == tGapCenters.begin() || igap == tGapCenters.end() -1) veto = true;
+
+		// Loop tracks.
+		if (!veto) {
+			for (LHCb::TbTrack* track : *m_tracks) {
+				if (track->htime() > (*igap) && track->htime() < (*(igap+1))) {
+					// Veto on tracks outside cuts.
+					const Gaudi::XYZPoint trackInterceptGlobal = geomSvc()->intercept(track, m_DUTindex);
+					if (!globalCutPosition(trackInterceptGlobal)) veto = true;
+					else if (outsideDUT(trackInterceptGlobal)) veto = true;
+					else if (interceptDeadPixel(trackInterceptGlobal)) veto = true;
+				}
+			}
+		}
+
+
+		// Loop vertices.
+//		if (!veto) {
+//			for (LHCb::TbVertex* vertex : *m_vertices) {
+//				if (vertex->htime() > (*igap) && vertex->htime() < (*(igap+1))) {
+//					veto = true;
+//				}
+//			}
+//		}
+
+
+		// Loop DUT clusters.
+		if (!veto) {
+			for (const LHCb::TbCluster* cluster : *m_clusters) {
+				if (cluster->htime() > (*igap) && cluster->htime() < (*(igap+1))) {
+					// Veto on clusters outside cuts.
+					Gaudi::XYZPoint clusterInterceptGlobal(cluster->x(), cluster->y(), cluster->z());
+					if (!globalCutPosition(clusterInterceptGlobal)) veto = true;
+					if (cluster->charge() > m_chargeCutUp || cluster->charge() < m_chargeCutLow) veto = true;
+				}
+			}
+		}
+
+
+		// Loop telescope clusters.
+		if (!veto) {
+			for (unsigned int i=0; i<m_nPlanes; i++) {
+				if (i == m_DUTindex) continue;
+				LHCb::TbClusters * clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(i));
+				for (LHCb::TbClusters::const_iterator it = clusters->begin(); it != clusters->end()-1; ++it) {
+					if ((*it)->htime() > (*igap) && (*it)->htime() < (*(igap+1))) {
+						double delt = (*it)->htime() - (*(it+1))->htime();
+						if (fabs(delt) < m_telescopeClusterVetoDelT) {
+							veto = true;
+							break;
+						}
+					}
+				}
+			}
+		}
+
+
+		if (!veto) fillTrackClusters(cutClusters, cutTracks, (*igap), (*(igap+1)));
+		else counter("nGapsFiltered") += 1;
+	}
+}
+
+
+
+//=============================================================================
+// Correlate remains
+//=============================================================================
+void TbEffPur::correlateRemains(std::vector<LHCb::TbTrack*> * cutTracks,
+		std::vector<LHCb::TbCluster*> * cutClusters)
+{
+	for (std::vector<LHCb::TbCluster*>::iterator ic = cutClusters->begin();
+	  		ic != cutClusters->end(); ++ic) {
+		if (!(*ic)->associated()) {
+			m_clusterRemainsPositionsGlobal->fill((*ic)->x(), (*ic)->y());
+			m_clusterRemainsPositionsLocal->fill((*ic)->xloc(), (*ic)->yloc());
+			plot((*ic)->charge(), "chargeClusterRemains", "chargeClusterRemains", 0.0, 1000.0, 125);
+		}
+	}
+
+	unsigned int i = 0;
+	for (std::vector<LHCb::TbTrack*>::iterator itrack = cutTracks->begin();
+			itrack != cutTracks->end(); itrack++) {
+		if (!m_trackAssociated->at(i)) {
+		  Gaudi::XYZPoint trackIntercept = geomSvc()->intercept((*itrack), m_DUTindex);
+		  m_trackRemainsPositionsGlobal->fill(trackIntercept.x(), trackIntercept.y());
+		  auto interceptUL = geomSvc()->globalToLocal(trackIntercept, m_DUTindex);
+		  m_trackRemainsPositionsLocal->fill(interceptUL.x()/m_pitch - 0.5, interceptUL.y()/m_pitch - 0.5);
+		}
+		i++;
+	}
+
+
+  // Draws correlations plots between non-associated clusters and tracks.
+	for (std::vector<LHCb::TbTrack*>::iterator itrack = cutTracks->begin();
+			itrack != cutTracks->end(); itrack++) {
+	  for (std::vector<LHCb::TbCluster*>::iterator ic = cutClusters->begin();
+	  		ic != cutClusters->end(); ++ic) {
+	  	if ((*ic)->htime() < (*itrack)->htime() - m_correlationTimeWindow) continue;
+	  	if (!(*ic)->associated()) {
+	  		//if (m_nEvent == m_viewerEvent) std::cout<<"Impurity at time: "<<(*ic)->htime()<<std::endl;
+	  		Gaudi::XYZPoint trackIntercept = geomSvc()->intercept((*itrack), m_DUTindex);
+	  		m_remainsCorrelationsX->fill(trackIntercept.x(), (*ic)->x());
+	  		m_remainsCorrelationsY->fill(trackIntercept.y(), (*ic)->y());
+
+	  		plot(trackIntercept.x() - (*ic)->x(), "remainClustDifferencesX", "remainsClustDifferencesX", -1.5, 1.5, 150);
+	  		plot(trackIntercept.y() - (*ic)->y(), "remainClustDifferencesY", "remainClustDifferencesY", -1.5, 1.5, 150);
+	  		plot((*itrack)->htime() - (*ic)->htime(), "remainClustDifferencesT", "remainClustDifferencesT", -50, 50, 150);
+
+	  		m_remainsDifferencesXY->fill(trackIntercept.y() - (*ic)->y(), trackIntercept.x() - (*ic)->x());
+	  	}
+	  	if ((*ic)->htime() > (*itrack)->htime() + m_correlationTimeWindow) break;
+	  }
+	}
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void TbEffPur::fillAllTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks)
+{
+  for (LHCb::TbTrack* track : *m_tracks) cutTracks->push_back(track);
+  for (std::vector<LHCb::TbCluster*>::iterator iClust = m_clusters->begin();
+  		iClust != m_clusters->end(); iClust++) cutClusters->push_back(*iClust);
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void TbEffPur::fillTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks, double tlow, double tup)
+{
+	// Push tracks and clusters inside this time window, which passed the veto.
+  for (LHCb::TbTrack* track : *m_tracks) {
+  	if (track->htime() > tlow && track->htime() < tup) {
+  		Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+  		cutTracks->push_back(track);
+  		m_vetoTracksHitmap->fill(trackIntercept.x(), trackIntercept.y());
+
+  		Gaudi::XYZPoint trackInterceptLocal = geomSvc()->globalToLocal(trackIntercept, m_DUTindex);
+			int row = trackInterceptLocal.y()/m_pitch - 0.5;
+			int col = trackInterceptLocal.x()/m_pitch - 0.5;
+
+			if (pixelSvc()->isMasked(pixelSvc()->address(col, row), m_DUTindex)) {
+				std::cout<<"Shouldn't be here!"<<std::endl;
+			}
+  	}
+  }
+
+  for (LHCb::TbCluster* cluster : *m_clusters) {
+		if (cluster->htime() > tlow && cluster->htime() < tup) {
+			cutClusters->push_back(cluster);
+			m_vetoClustersHitmap->fill(cluster->x(), cluster->y());
+		}
+  }
+}
+
+
+//=============================================================================
+// Global cuts
+//=============================================================================
+void TbEffPur::trackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks)
+{
+  for (std::vector<LHCb::TbTrack*>::iterator itrack = cutTracks->begin();
+  		itrack != cutTracks->end(); itrack++) {
+
+  	// Get local position of track.
+  	const auto interceptUG = geomSvc()->intercept((*itrack), m_DUTindex);
+    const auto interceptUL = geomSvc()->globalToLocal(interceptUG, m_DUTindex);
+
+
+  	// Loop over clusters to find the closest.
+  	LHCb::TbCluster * closestCluster = NULL;
+  	double bestRadialDistance;
+  	for (std::vector<LHCb::TbCluster*>::iterator iclust = cutClusters->begin();
+  			iclust != cutClusters->end(); iclust++) {
+  		bool match = matchTrackToCluster((*iclust), (*itrack));
+  		double radialDistance = getRadialSeparation((*iclust), (*itrack));
+  		if (match) {
+  			if (!closestCluster) {
+  				closestCluster = (*iclust);
+  				bestRadialDistance = radialDistance;
+  			}
+  			else if (radialDistance<bestRadialDistance) {
+  				closestCluster = (*iclust);
+  				bestRadialDistance = radialDistance;
+  			}
+  		}
+
+  		if ((*iclust)->htime() - (*itrack)->htime() > m_tResidualCut) break;
+  	}
+
+  	double trackX = interceptUL.x();
+  	double trackY = interceptUL.y();
+
+		if (closestCluster != NULL && closestCluster->charge() > m_chargeCutLow) {
+			closestCluster->setAssociated(true);
+			m_nTrackedClusters++;
+			m_effHitmap->Fill(true, trackX, trackY);
+			m_effX->Fill(true, trackX);
+			m_effY->Fill(true, trackY);
+
+			if (fmod(trackX, m_pitch)<0.0183 && fmod(trackY, m_pitch) < 0.0183) m_nClustersPassedCorner++;
+			if (fmod(trackX, m_pitch) > 0.0183 &&
+					fmod(trackX, m_pitch) < (2*0.0183) &&
+					fmod(trackY, m_pitch) > 0.0183 &&
+					fmod(trackY, m_pitch) < (2*0.0183)) m_nClustersPassedCentral++;
+
+
+			//h_effVsCharge->Fill(h_effInter->Interpolate(fmod(trackX, m_pitch), fmod(trackY, m_pitch)), closestCluster->charge());
+			// if (trackY > 9.25 && trackY < 10.25) m_effHitmapInterPixel->Fill(true, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+			// if (trackX > 28.05 &&
+			// 		trackX < 28.6) m_effHitmapInterPixelTriple->Fill(true, trackX-28.05, fmod(trackY, m_pitch));
+
+
+      m_effHitmapInterPixel->Fill(true, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+      m_effHitmapInterPixelTriple->Fill(true, trackX-28.05, fmod(trackY, m_pitch));
+
+
+			if (closestCluster->size() <= m_effHitmapInterPixelVsSizes.size())
+				m_effHitmapInterPixelVsSizes[closestCluster->size()-1]->Fill(true, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+			m_trackAssociated->at(itrack - cutTracks->begin()) = true;
+			plot(closestCluster->x() - interceptUG.x(), "xResidualsClustMinusTrack", "xResidualsClustMinusTrack", -0.2, 0.2, 400);
+			plot(closestCluster->y() - interceptUG.y(), "yResidualsClustMinusTrack", "yResidualsClustMinusTrack", -0.2, 0.2, 400);
+			plot(closestCluster->htime() - (*itrack)->htime(), "hTimeResidualClustMinusTrack", "hTimeResidualClustMinusTrack", -50, 50, 400);
+			if (closestCluster->size() == 1) {
+				auto hits = closestCluster->hits();
+				int col = (*hits.begin())->col();
+				m_timeResidualVsColumn->fill(col, closestCluster->htime() - (*itrack)->htime());
+			}
+			if ((*itrack)->vertexed()) counter("nVerticesCorrelated") += 1;
+		}
+		else {
+			m_effHitmap->Fill(false, trackX, trackY);
+			// if (trackY > 9.25 && trackY < 10.25) m_effHitmapInterPixel->Fill(false, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+			// if (trackX > 28.05 &&
+			// 		trackX < 28.6) m_effHitmapInterPixelTriple->Fill(false, trackX-28.05, fmod(trackY, m_pitch));
+
+      m_effHitmapInterPixel->Fill(false, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+      m_effHitmapInterPixelTriple->Fill(false, trackX-28.05, fmod(trackY, m_pitch));
+			m_effX->Fill(false, trackX);
+			m_effY->Fill(false, trackY);
+			//std::cout<<"Inefficiency at time: "<<(*itrack)->htime()<<std::endl;
+		}
+		if (fmod(trackX, m_pitch)<0.0183 && fmod(trackY, m_pitch) < 0.0183) m_nTracksCorner++;
+		if (fmod(trackX, m_pitch) > 0.0183 &&
+					fmod(trackX, m_pitch) < (2*0.0183) &&
+					fmod(trackY, m_pitch) > 0.0183 &&
+					fmod(trackY, m_pitch) < (2*0.0183)) m_nTracksCentral++;
+  }
+}
+
+
+
+//=============================================================================
+//
+//=============================================================================
+double TbEffPur::getRadialSeparation(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track)
+{
+  Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+	double xResidual = cluster->x() - trackIntercept.x();
+	double yResidual = cluster->y() - trackIntercept.y();
+
+	double r2 = xResidual*xResidual + yResidual*yResidual;
+	return pow(r2, 0.5);
+}
+
+
+//=============================================================================
+// Local cuts
+//=============================================================================
+bool TbEffPur::matchTrackToCluster(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track)
+{
+  Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+	double xResidual = cluster->x() - trackIntercept.x();
+	double yResidual = cluster->y() - trackIntercept.y();
+	double tResidual = cluster->htime() - track->htime();
+	double delr = pow(pow(xResidual, 2) + pow(yResidual, 2), 0.5);
+
+//	if (track->vertexed()) plot(xResidual, "vertexResiduals/X", "vertexResiduals/X", -0.5, 0.5, 200);
+//	if (track->vertexed()) plot(yResidual, "vertexResiduals/Y", "vertexResiduals/Y", -0.5, 0.5, 200);
+//	if (track->vertexed()) plot(tResidual, "vertexResiduals/T", "vertexResiduals/T", -0.5, 0.5, 200);
+//
+//	if (track->vertexed() && litPixel(cluster, track)) {
+//		plot(xResidual, "vertexResiduals/Xlit", "vertexResiduals/Xlit", -0.5, 0.5, 200);
+//		plot(yResidual, "vertexResiduals/Ylit", "vertexResiduals/Ylit", -0.5, 0.5, 200);
+//	}
+
+
+	if (fabs(tResidual) > m_tResidualCut) {
+  	counter("nTimeRejected") += 1;
+		return false;
+	}
+
+  if (delr > m_rResidualCut) {
+  	counter("nSpatialRejected") += 1;
+  	if (litPixel(cluster, track)) return true;
+  	else {
+  		counter("nSpatialAndLitRejected") += 1;
+  		return false;
+  	}
+  }
+
+//	if (!litPixel(cluster, track)) return false;
+
+  return true;
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+bool TbEffPur::interceptDeadPixel(Gaudi::XYZPoint trackInterceptGlobal)
+{
+	// Find the row and column corresponding to the track intercept.
+	Gaudi::XYZPoint trackInterceptLocal = geomSvc()->globalToLocal(trackInterceptGlobal, m_DUTindex);
+  int row = trackInterceptLocal.y()/m_pitch - 0.5;
+  int col = trackInterceptLocal.x()/m_pitch - 0.5;
+
+  for (int icol = col - 1; icol != col+2; icol++) {
+  	for (int irow = row - 1; irow != row+2; irow++) {
+  		if (icol >= 0 && icol <256 && irow>=0 && irow<256) {
+  			if (pixelSvc()->isMasked(pixelSvc()->address(icol, irow), m_DUTindex)) {
+					return true;
+				}
+
+//  			if (icol == 17 && irow == 36) {
+//  				return true;
+//  			}
+//				if (icol == 18 && irow == 36) {
+//  				return true;
+//  			}
+//				if (icol == 53 && irow == 3) {
+//  				return true;
+//  			}
+//				if (icol == 54 && irow == 3) {
+//  				return true;
+//  			}
+//				if (icol == 73 && irow == 26) {
+//  				return true;
+//  			}
+//				if (icol == 74 && irow == 26) {
+//  				return true;
+//  			}
+//				if (icol == 19 && irow == 103) {
+//  				return true;
+//  			}
+//				if (icol == 31 && irow == 106) {
+//  				return true;
+//  			}
+//				if (icol == 32 && irow == 106) {
+//  				return true;
+//  			}
+//				if (icol == 38 && irow == 108) {
+//  				return true;
+//  			}
+//				if (icol == 63 && irow == 95) {
+//  				return true;
+//  			}
+//				if (icol == 64 && irow == 95) {
+//  				return true;
+//  			}
+//				if (icol == 103 && irow == 23) {
+//  				return true;
+//  			}
+//				if (icol == 104 && irow == 23) {
+//  				return true;
+//  			}
+//				if (icol == 115 && irow == 20) {
+//  				return true;
+//  			}
+//				if (icol == 116 && irow == 94) {
+//  				return true;
+//  			}
+  		}
+  	}
+  }
+
+
+
+  return false;
+}
+
+//=============================================================================
+//
+//=============================================================================
+bool TbEffPur::litPixel(LHCb::TbCluster * cluster, LHCb::TbTrack * track)
+{
+	// Find the row and column corresponding to the track intercept.
+	Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+	Gaudi::XYZPoint pLocal = geomSvc()->globalToLocal(trackIntercept, m_DUTindex);
+  int row = pLocal.y()/m_pitch - 0.5;
+  int col = pLocal.x()/m_pitch - 0.5;
+
+  // See if within a pre-defined square of pixels.
+  for (unsigned int i=0; i<cluster->size(); i++) {
+  	unsigned int delRow = abs(row - int(cluster->hits()[i]->row()));
+  	unsigned int delCol = abs(col - int(cluster->hits()[i]->col()));
+
+  	if (delRow <= m_litSquareSide && delCol <= m_litSquareSide) {
+		  counter("nLitPixels") += 1;
+  		return true;
+  	}
+  }
+
+  return false;
+}
+
+
+//=============================================================================
+// Excluding dead regions.
+//=============================================================================
+bool TbEffPur::globalCutPosition(Gaudi::XYZPoint pGlobal)
+{
+	if (pGlobal.x() < m_xLow + m_edgeVetoDistance) return false;
+	else if (pGlobal.x() > m_xUp - m_edgeVetoDistance) return false;
+	else if (pGlobal.y() < m_yLow + m_edgeVetoDistance) return false;
+	else if	(pGlobal.y() > m_yUp - m_edgeVetoDistance) return false;
+  return true; // Inside.
+}
+
+
+//=============================================================================
+// Excluding dead regions.
+//=============================================================================
+bool TbEffPur::outsideDUT(Gaudi::XYZPoint interceptUG)
+{
+	const auto interceptUL = geomSvc()->globalToLocal(interceptUG, m_DUTindex);
+	if (interceptUL.x() < 0 + m_edgeVetoDistance ||
+			interceptUL.x() > 14.08 - m_edgeVetoDistance ||
+			interceptUL.y() < 0 + m_edgeVetoDistance||
+			interceptUL.y() > 14.08 - m_edgeVetoDistance) return true;
+	return false;
+}
+
+
+
+//=============================================================================
+// Viewer output.
+//=============================================================================
+//=============================================================================
+// Viewer output.
+//=============================================================================
+//=============================================================================
+// Viewer output.
+//=============================================================================
+
+void TbEffPur::outputDeadRegion(unsigned int col, unsigned int row) {
+	std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat", std::ofstream::app);
+	std::string outputLine;
+	for (int irow = std::max(int(row-m_deadAreaRadius), 0);
+  		irow < std::min(int(row+m_deadAreaRadius+1), m_nDUTpixels); irow++) {
+  	for (int icol = std::max(int(col-m_deadAreaRadius), 0);
+  		icol < std::min(int(col+m_deadAreaRadius+1), m_nDUTpixels); icol++) {
+
+
+			outputLine = "DeadPixel ";
+			const double xLocal = (col-icol) * m_pitch; // Dont want the middle!
+			const double yLocal = (row-irow) * m_pitch; // Dont want the middle!
+			Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+
+			Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			Gaudi::XYZPoint posn2(pLocal.x() + 0.055, pLocal.y(), 0.);
+			posn = geomSvc()->localToGlobal(posn2, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			Gaudi::XYZPoint posn3(pLocal.x() + 0.055, pLocal.y()+0.055, 0.);
+			posn = geomSvc()->localToGlobal(posn3, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y()+0.055, 0.);
+			posn = geomSvc()->localToGlobal(posn4, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			outputLine += "\n";
+			myfile << outputLine;
+  	}
+	}
+	myfile.close();
+}
+
+
+//=============================================================================
+// Viewer output.
+//=============================================================================
+
+void TbEffPur::outputViewerData()
+{
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat", std::ofstream::app);
+  std::string outputLine;
+//
+//  // First output the chips.
+//  for (unsigned int i=0; i<m_nPlanes; i++) {
+//  	outputLine = "Chip ";
+//  	Gaudi::XYZPoint posn1(0., 14.08, 0.);
+//    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+//    posn = geomSvc()->localToGlobal(posn2, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+//    posn = geomSvc()->localToGlobal(posn3, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    Gaudi::XYZPoint posn4(0., 0., 0.);
+//    posn = geomSvc()->localToGlobal(posn4, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    outputLine += "\n";
+//    myfile << outputLine;
+//  }
+
+
+  // Clusters.
+  auto ic = m_clusters->begin();
+	const auto end = m_clusters->end();
+	for (; ic != end; ++ic) {
+		outputLine = "Cluster ";
+		outputLine += std::to_string((*ic)->x()) + " ";
+		outputLine += std::to_string((*ic)->y()) + " ";
+		outputLine += std::to_string((*ic)->z()) + " ";
+		outputLine += std::to_string((*ic)->htime()) + " ";
+
+		// if ((*ic)->endCluster() && (*ic)->vertexed()) outputLine += "5 \n";
+		//if ((*ic)->vertexed()) outputLine += "4 \n";
+//			else if ((*ic)->endCluster()) outputLine += "3 \n";
+		if ((*ic)->associated()) outputLine += "2 \n";
+//			else if ((*ic)->volumed()) outputLine += "1 \n";
+
+		else {
+			outputLine += "0 \n";
+		}
+		myfile << outputLine;
+	}
+
+	outputLine = "CentralRegion ";
+	outputLine += std::to_string(m_xLow) + " ";
+	outputLine += std::to_string(m_xUp) + " ";
+	outputLine += std::to_string(m_yLow) + " ";
+	outputLine += std::to_string(m_yUp) + " ";
+	outputLine += std::to_string(geomSvc()->module(m_DUTindex)->z()) + " ";
+	myfile << outputLine;
+
+//		// Its hits.
+//		for (auto hit : (*ic)->hits()) {
+//			outputLine = "Pixel ";
+//			const double xLocal = (hit->col()) * m_pitch; // Dont want the middle!
+//			const double yLocal = (hit->row()) * m_pitch; // Dont want the middle!
+//			Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+//
+//			Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			Gaudi::XYZPoint posn2(pLocal.x() + 0.055, pLocal.y(), 0.);
+//			posn = geomSvc()->localToGlobal(posn2, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			Gaudi::XYZPoint posn3(pLocal.x() + 0.055, pLocal.y()+0.055, 0.);
+//			posn = geomSvc()->localToGlobal(posn3, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y()+0.055, 0.);
+//			posn = geomSvc()->localToGlobal(posn4, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			outputLine += std::to_string(hit->htime()) + " ";
+//			outputLine += std::to_string(hit->ToT()) + " ";
+//
+//			outputLine += "\n";
+//			myfile << outputLine;
+//		}
+
+  myfile.close();
+}
+
+
+//=============================================================================
+// END
+//=============================================================================
diff --git a/TbAnalysis/src/.svn/text-base/TbEffPur.h.svn-base b/TbAnalysis/src/.svn/text-base/TbEffPur.h.svn-base
new file mode 100644
index 0000000..41083b5
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbEffPur.h.svn-base
@@ -0,0 +1,142 @@
+#ifndef TB_EFFICIENCY_H
+#define TB_EFFICIENCY_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+#include "TEfficiency.h"
+#include "AIDA/IAxis.h"
+
+#include "AIDA/IProfile2D.h"
+#include "AIDA/IProfile1D.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+#include "Event/TbVertex.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/ITbClusterFinder.h"
+
+#include "TFile.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+#include "TH2D.h"
+
+
+/** @class TbEffPur TbEffPur.h
+ *
+ *  @author Dan Saunders
+ */
+
+class TbEffPur : public TbAlgorithm {
+ public:
+  TbEffPur(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TbEffPur() {}
+
+  // Gaudi methods.
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  // Members.
+  std::string m_trackLocation;
+  std::string m_vertexLocation;
+  std::string m_clusterLocation;
+  unsigned int m_DUTindex;
+  LHCb::TbTracks * m_tracks;
+  LHCb::TbClusters * m_clusters;
+  ITbTrackFit * m_trackFit;
+  double m_pitch;
+  int m_nDUTpixels;
+
+
+  unsigned int m_nTracks;
+  unsigned int m_nClusters;
+  unsigned int m_nTrackedClusters;
+
+  unsigned int m_nClustersPassedCentral;
+  unsigned int m_nTracksCentral;
+
+  unsigned int m_nClustersPassedCorner;
+  unsigned int m_nTracksCorner;
+
+  double m_eff;
+  double m_pur;
+  double m_telescopeClusterVetoDelT;
+  double m_edgeVetoDistance;
+
+  TEfficiency * m_effs;
+  TEfficiency * m_purs;
+  TEfficiency * m_effHitmap;
+  TEfficiency * m_purHitmap;
+  TEfficiency * m_effHitmapInterPixel;
+  TEfficiency * m_effHitmapInterPixelTriple;
+  TEfficiency * m_purHitmapInterPixel;
+  TEfficiency * m_effX;
+  TEfficiency * m_effY;
+  std::vector<TEfficiency*> m_effHitmapInterPixelVsSizes;
+
+  unsigned int m_deadAreaRadius;
+  double m_xLow;
+  double m_xUp;
+  double m_yLow;
+  double m_yUp;
+  double m_probCut;
+
+  double m_rResidualCut;
+  double m_tResidualCut;
+
+  unsigned int m_chargeCutLow;
+  unsigned int m_chargeCutUp;
+
+  unsigned int m_litSquareSide;
+  unsigned int m_nEvent;
+  bool m_viewerOutput;
+  unsigned int m_viewerEvent;
+  double m_tGap;
+  double m_correlationTimeWindow;
+  bool m_applyVeto;
+  std::vector<bool> * m_trackAssociated;
+
+  // Plots.
+  AIDA::IHistogram2D * m_remainsCorrelationsX;
+  AIDA::IHistogram2D * m_remainsCorrelationsY;
+  AIDA::IHistogram2D * m_remainsDifferencesXY;
+  AIDA::IHistogram2D * m_clusterRemainsPositionsGlobal;
+  AIDA::IHistogram2D * m_trackRemainsPositionsGlobal;
+  AIDA::IHistogram2D * m_clusterRemainsPositionsLocal;
+  AIDA::IHistogram2D * m_trackRemainsPositionsLocal;
+  AIDA::IHistogram2D * m_vetoTracksHitmap;
+  AIDA::IHistogram2D * m_vetoClustersHitmap;
+  AIDA::IHistogram2D * m_timeResidualVsColumn;
+
+
+  // Methods.
+  void effPur();
+  void trackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks);
+  bool matchTrackToCluster(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track);
+  double getRadialSeparation(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track);
+  bool litPixel(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track);
+  bool globalCutPosition(Gaudi::XYZPoint);
+  void outputViewerData();
+  void applyVeto(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks);
+  void correlateRemains(std::vector<LHCb::TbTrack*> * cutTracks,
+  		std::vector<LHCb::TbCluster*> * cutClusters);
+  void fillTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks, double tlow, double tup);
+  void fillAllTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks);
+  void outputDeadRegion(unsigned int, unsigned int);
+  bool outsideDUT(Gaudi::XYZPoint);
+  bool interceptDeadPixel(Gaudi::XYZPoint);
+};
+#endif
diff --git a/TbAnalysis/src/.svn/text-base/TbEfficiency.cpp.svn-base b/TbAnalysis/src/.svn/text-base/TbEfficiency.cpp.svn-base
new file mode 100644
index 0000000..0851f86
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbEfficiency.cpp.svn-base
@@ -0,0 +1,216 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+// TODO (hschindl)
+#include "GaudiKernel/IEventProcessor.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbEfficiency.h"
+
+DECLARE_ALGORITHM_FACTORY(TbEfficiency)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbEfficiency::TbEfficiency(const std::string& name,
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+			m_nTracksConsidered(0),
+			m_nTracksAssociated(0),
+			m_event(0),
+			m_pitch(0.055) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("DUT", m_dut = 4);
+  declareProperty("CheckHitDUT", m_checkHitDUT = true);
+  declareProperty("CheckHitAlivePixel", m_checkHitAlivePixel = true);
+  declareProperty("PointingResAllowance", m_pointingResAllowance = 0.01);
+  declareProperty("PointingResAllowanceDeadPixel", m_pointingResAllowance_deadPixels = 1);
+  declareProperty("TakeDeadPixelsFromFile", m_takeDeadPixelsFromFile = true);
+  declareProperty("nTotalTracks", m_nTotalTracks = 0);
+  declareProperty("MaxChi", m_maxChi = 0);
+}
+
+//=============================================================================
+// Finalization
+//=============================================================================
+StatusCode TbEfficiency::finalize() {
+
+  info() <<"DUT Efficiency: "<<m_nTracksAssociated/(1.*m_nTracksConsidered)<<endmsg;
+  info()<<"nTracksAssociated: "<<m_nTracksAssociated<<endmsg;
+  info()<<"nTracksConsidered: "<<m_nTracksConsidered<<endmsg;
+  info()<<"cf: "<<m_eff->GetEfficiency(1)<<"\t ±"<<m_eff->GetEfficiencyErrorLow(1)<<endmsg;
+
+  TFile * f = new TFile("EfficiencyResults.root", "RECREATE");
+  h_row->Write();
+  h_col->Write();
+  m_eff->Write();
+  h_hitmap->Write();
+  h_pixel->Write();
+  h_pixel2x2->Write();
+
+  m_eff->CreateGraph()->Write();
+  h_hitmap->CreateHistogram()->Write();
+  h_col->CreateGraph()->Write();
+  h_row->CreateGraph()->Write();
+  h_pixel->CreateHistogram()->Write();
+  h_pixel2x2->CreateHistogram()->Write();
+  f->Close();
+
+  return TbAlgorithm::finalize();
+}
+
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbEfficiency::initialize() {
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  uint nBins = 80;
+  h_row = new TEfficiency("row", "row", 256, 0, 256);
+  h_col = new TEfficiency("col", "col", 3*256+2, 0, 3*256+2);
+  m_eff = new TEfficiency("eff", "eff", 1, 0, 1);
+  h_hitmap = new TEfficiency("hitmap", "hitmap", 3*256+2, 0, 3*256+2, 256, 0, 256);
+  h_pixel = new TEfficiency("pixel", "pixel", nBins, 0, m_pitch, nBins, 0, m_pitch);
+  h_pixel2x2 = new TEfficiency("pixel2x2", "pixel2x2", 2*nBins, 0, 2*m_pitch, 2*nBins, 0, 2*m_pitch);
+
+  if (m_takeDeadPixelsFromFile) {
+    TFile * fIn = new TFile("telPlaneRef.root", "READ");
+    const std::string name = "Tb/TbHitMonitor/HitMap/Plane" + std::to_string(m_dut);
+    m_deadPixelMap = (TH2F*)fIn->Get(name.c_str());
+    info() <<"DeadPixelMap name: "<<m_deadPixelMap->GetName()<<endmsg;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbEfficiency::execute() {
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+	// Loop over the tracks.
+	for (LHCb::TbTrack* track : *tracks) {
+		if (m_nTotalTracks != 0 && m_nTracksConsidered >= m_nTotalTracks) {
+			SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+			if (app) app->stopRun();
+			return StatusCode::SUCCESS;
+		}
+
+		// Find the local position of the track intercept with the DUT.
+		const Gaudi::XYZPoint interceptUG = geomSvc()->intercept(track, m_dut);
+		const auto interceptUL = geomSvc()->globalToLocal(interceptUG, m_dut);
+
+		if (!passSelectionCriteria(track, interceptUL)) continue;
+		m_nTracksConsidered++;
+		bool pass = false;
+		if (track->associatedClusters().size() > 0) pass = true;
+
+		int row = interceptUL.y()/m_pitch - 0.5;
+		int col = interceptUL.x()/m_pitch - 0.5;
+
+		h_pixel->Fill(pass, fmod(interceptUL.x(), m_pitch), fmod(interceptUL.y(), m_pitch));
+		h_pixel2x2->Fill(pass, fmod(interceptUL.x(), 2*m_pitch), fmod(interceptUL.y(), 2*m_pitch));
+		h_row->Fill(pass, row);
+		h_col->Fill(pass, col);
+		h_hitmap->Fill(pass, col, row);
+		m_eff->Fill(pass, 0);
+		if (pass) m_nTracksAssociated++;
+		if (!pass && m_event == 1050) info()<<track->htime()<<endmsg;
+	}
+
+	m_event++;
+  return StatusCode::SUCCESS;
+}
+
+
+//=============================================================================
+
+bool TbEfficiency::passSelectionCriteria(LHCb::TbTrack * track, Gaudi::XYZPoint interceptUL)
+{
+	if (m_maxChi > 0 && track->chi2PerNdof() > m_maxChi) return false;
+	if (m_checkHitDUT && !passedThroughDUT(interceptUL)) {
+		return false;
+	}
+	if (m_checkHitAlivePixel && !passedThroughAlivePixel(interceptUL)) return false;
+
+	return true;
+}
+
+
+//=============================================================================
+
+bool TbEfficiency::passedThroughDUT(Gaudi::XYZPoint interceptUL)
+{
+	double xLow = 0.0 + m_pointingResAllowance;
+	double yLow = 0.0 + m_pointingResAllowance;
+	double yUp = 14.08 - m_pointingResAllowance;
+	double xUp = 14.08;
+
+	if (geomSvc()->modules().at(m_dut)->nChips() == 1)
+		xUp = 14.08 - m_pointingResAllowance;
+	else if (geomSvc()->modules().at(m_dut)->nChips() == 3)
+		xUp = 42.35 - m_pointingResAllowance;
+	else error()<<"Unknown device!"<<endmsg;
+
+	if (interceptUL.x() < xLow ||
+			interceptUL.x() > xUp ||
+			interceptUL.y() < yLow ||
+			interceptUL.y() > yUp) {
+		counter("nTracksNotStrikingDUT") += 1;
+		return false;
+	}
+	return true;
+}
+
+
+//=============================================================================
+
+bool TbEfficiency::passedThroughAlivePixel(Gaudi::XYZPoint interceptUL)
+{
+	int row = interceptUL.y()/0.055 - 0.5;
+  int col = interceptUL.x()/0.055 - 0.5;
+  int one = 1;
+  for (int iRow = row - m_pointingResAllowance_deadPixels;
+  		iRow != row+m_pointingResAllowance_deadPixels+one; iRow++) {
+  	for (int iCol = col - m_pointingResAllowance_deadPixels;
+  			iCol != col + m_pointingResAllowance_deadPixels+one; iCol++) {
+
+  		int colLim;
+  		if (geomSvc()->modules().at(m_dut)->nChips() == 3) colLim = 3*256+2;
+  		else colLim = 256;
+  		if (iRow < 0 || iCol < 0 || iRow >= 256 || iCol >= colLim) continue;
+			if (pixelSvc()->isMasked(pixelSvc()->address(iCol, iRow), m_dut)) {
+				counter("nTracksStrikingMaskedPixels") += 1;
+				return false;
+			}
+			else if (m_takeDeadPixelsFromFile && m_deadPixelMap->GetBinContent(iCol, iRow) == 0) {
+				counter("nTracksStrikingDeadPixels") += 1;
+				return false;
+			}
+
+  	}
+  }
+  return true;
+}
+
+
+//=============================================================================
diff --git a/TbAnalysis/src/.svn/text-base/TbEfficiency.h.svn-base b/TbAnalysis/src/.svn/text-base/TbEfficiency.h.svn-base
new file mode 100644
index 0000000..190b975
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbEfficiency.h.svn-base
@@ -0,0 +1,56 @@
+#ifndef TB_EFFICIENCY_H
+#define TB_EFFICIENCY_H 1
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "AIDA/IHistogram1D.h"
+#include "TEfficiency.h"
+#include "TH2.h"
+#include "TFile.h"
+#include "TGraphAsymmErrors.h"
+
+/** @class TbEfficiency TbEfficiency.h
+ *
+ */
+
+class TbEfficiency : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbEfficiency(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbEfficiency() {}
+
+  bool m_checkHitDUT;
+  bool m_checkHitAlivePixel;
+  double m_pointingResAllowance;
+  uint m_nTracksConsidered;
+  uint m_nTracksAssociated;
+  uint m_event;
+  int m_pointingResAllowance_deadPixels;
+  bool m_takeDeadPixelsFromFile;
+  TH2F * m_deadPixelMap;
+  double m_pitch;
+  uint m_nTotalTracks;
+  double m_maxChi;
+
+  bool passedThroughDUT(Gaudi::XYZPoint interceptUL);
+  bool passedThroughAlivePixel(Gaudi::XYZPoint interceptUL);
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();
+  bool passSelectionCriteria(LHCb::TbTrack * track, Gaudi::XYZPoint interceptUL);
+
+  TEfficiency * h_row;
+  TEfficiency * h_col;
+  TEfficiency * m_eff;
+  TEfficiency * h_hitmap;
+  TEfficiency * h_pixel;
+  TEfficiency * h_pixel2x2;
+
+ private:
+  uint m_dut;
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+};
+#endif
diff --git a/TbAnalysis/src/.svn/text-base/TbResolutionMonitor.cpp.svn-base b/TbAnalysis/src/.svn/text-base/TbResolutionMonitor.cpp.svn-base
new file mode 100644
index 0000000..159301a
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbResolutionMonitor.cpp.svn-base
@@ -0,0 +1,107 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbResolutionMonitor.h"
+
+DECLARE_ALGORITHM_FACTORY(TbResolutionMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbResolutionMonitor::TbResolutionMonitor(const std::string& name, 
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+  declareProperty("DUTs", m_duts);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbResolutionMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbResolutionMonitor::execute() {
+
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    error() << "No tracks in " << m_trackLocation << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  for (const auto dut : m_duts) {
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(dut);
+    const LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    for (const LHCb::TbCluster* cluster : *clusters) {
+      plot(cluster->charge(), "ChargeAll", "ChargeAll", 0., 50000., 200);
+    }
+    if (!clusters) continue;
+    // Loop over the tracks.
+    for (const LHCb::TbTrack* track : *tracks) {
+      // Cut on track quality.
+      if (track->chi2PerNdof() > 20.) continue;
+      const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, dut);
+      const auto pLocal = geomSvc()->globalToLocal(pGlobal, dut);
+      if (pLocal.x() < 0. || pLocal.y() < 0.) continue;
+      const double fcol = pLocal.x() / Tb::PixelPitch;
+      const double frow = pLocal.y() / Tb::PixelPitch;
+      const int col = int(fcol);
+      const int row = int(frow);
+      if (col > 255 || row > 255) continue;
+      // Calculate inter-pixel coordinates.
+      const double xCell = 1.e3 * (fcol - col) * Tb::PixelPitch;
+      const double yCell = 1.e3 * (frow - row) * Tb::PixelPitch;
+      const LHCb::TbCluster* match = NULL;
+      for (const LHCb::TbCluster* cluster : *clusters) {
+        const double dt = cluster->htime() - track->htime();
+        if (fabs(dt) > 200.) continue;
+        const double dx = cluster->xloc() - pLocal.x();
+        const double dy = cluster->yloc() - pLocal.y();
+        if (fabs(dx) < 0.15 && fabs(dy) < 0.15) {
+          match = cluster;
+          break;
+        }
+      }
+      plot2D(xCell, yCell, "NTracks", "NTracks",
+             0., 55., 0., 55., 9, 9);
+      if (!match) continue;
+      plot2D(xCell, yCell, "NClusters", "NClusters",
+             0., 55., 0., 55., 9, 9);
+      plot(match->x() - pGlobal.x(), "ResGlobalX", "ResGlobalX", -0.2, 0.2, 100);
+      plot(match->y() - pGlobal.y(), "ResGlobalY", "ResGlobalY", -0.2, 0.2, 100);
+      plot(match->xloc() - pLocal.x(), "ResLocalX", "ResLocalX", -0.2, 0.2, 100);
+      plot(match->yloc() - pLocal.y(), "ResLocalY", "ResLocalX", -0.2, 0.2, 100);
+      plot(match->htime() - track->htime(), "ResTime", "ResTime", -200., 200., 400); 
+      const unsigned int cls = match->size();
+      if (cls > 4) continue;
+      const std::string title = "InterceptCls" + std::to_string(cls);
+      plot2D(xCell, yCell, title, title,
+             0., 55., 0., 55., 50, 50);
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
diff --git a/TbAnalysis/src/.svn/text-base/TbResolutionMonitor.h.svn-base b/TbAnalysis/src/.svn/text-base/TbResolutionMonitor.h.svn-base
new file mode 100644
index 0000000..80162f3
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbResolutionMonitor.h.svn-base
@@ -0,0 +1,25 @@
+#pragma once
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbResolutionMonitor TbResolutionMonitor.h
+ *
+ */
+
+class TbResolutionMonitor : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbResolutionMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbResolutionMonitor() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<unsigned int> m_duts;
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+
+};
diff --git a/TbAnalysis/src/.svn/text-base/TbTimewalkMonitor.cpp.svn-base b/TbAnalysis/src/.svn/text-base/TbTimewalkMonitor.cpp.svn-base
new file mode 100644
index 0000000..9f66b8f
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbTimewalkMonitor.cpp.svn-base
@@ -0,0 +1,211 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbTimewalkMonitor.h"
+
+// ROOT
+#include "TH1D.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbTimewalkMonitor)
+
+  //=============================================================================
+  // Standard constructor
+  //=============================================================================
+TbTimewalkMonitor::TbTimewalkMonitor(const std::string& name, 
+    ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator) {
+
+    declareProperty("TrackLocation",
+        m_trackLocation = LHCb::TbTrackLocation::Default);
+    declareProperty("WidthMin", m_widthMin = 37 );
+    declareProperty("WidthMax", m_widthMax = 42 );
+  }
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTimewalkMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Book the histograms.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+    m_space.push_back(bookProfile1D("SpatialResidual/Plane"+plane,title,-0.5,255.5,256));
+
+    m_spd2D.push_back(book2D("spd2D/Plane"+plane,title,-0.5,255.5,256,-100,100,20));
+    m_twd.push_back(book2D("twd/Plane"+plane,title,1.,101.,100,0.,62.5,40));
+    m_twdQ.push_back(book2D("twdQ/Plane"+plane,title,1000,10000,100,0.,62.5,40));
+    m_twdQL.push_back(book2D("twdQL/Plane"+plane,title,1000,10000,100,0.,62.5,40));
+    m_twdQR.push_back(book2D("twdQR/Plane"+plane,title,1000,10000,100,0.,62.5,40));
+
+    setAxisLabels( m_twd[i], "ToT", "#Delta t [ns]");
+
+    m_twdL.push_back(book2D("twdL/Plane"+plane,title,0.,100.,100,0.,62.5,40));
+    m_twdR.push_back(book2D("twdR/Plane"+plane,title,0.,100.,100,0.,62.5,40));
+    m_LRSYNC.emplace_back(bookProfile1D("LR_SYNC/Plane"+plane,title,-0.5,255.5,256));
+    m_UDSYNC.emplace_back(bookProfile1D("UD_SYNC/Plane"+plane,title,-0.5,255.5,256));
+
+    m_quad.emplace_back(bookProfile1D("QUAD/Plane"+plane,title,-0.5,255.5,256));
+
+    m_inscol.emplace_back(bookProfile1D("Scol/Plane"+plane,title,-0.5,127.5,128));
+    m_interscol.emplace_back(bookProfile1D("InterScol/Plane"+plane,title,-0.5,127.5,128));
+
+    m_timewalk.push_back(bookProfile1D("Timewalk/Plane"+plane,title, 1., 401., 400));
+    m_dtDist.push_back( book1D( "dtDist/Plane"+plane,title, 0., 90., 58 ) );
+    m_cDist.push_back( book1D( "cDist/Plane"+plane,title,0.,90.,58 ) );
+    m_timewalkQ.push_back(bookProfile1D("TimewalkQ/Plane"+plane,title,0,20000,200));
+    setAxisLabels(m_timewalkQ[i], "charge [e^{-}]","#Delta t [ns]");
+    setAxisLabels(m_timewalk[i], "ToT", "#Delta t [ns]");
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TbTimewalkMonitor::finalize() {
+
+  for( unsigned int i = 0 ; i < m_nPlanes; ++i ){
+    TH1D* tdist = Gaudi::Utils::Aida2ROOT::aida2root( m_dtDist[i] );
+    AIDA::IHistogram1D* cdist = m_cDist[i];
+    int total = 0;    
+    for (int i=0;i<tdist->GetNbinsX();i++)
+    {
+      total += tdist->GetBinContent(i);
+      cdist->fill( tdist->GetBinCenter(i) , total /tdist->GetEntries() ) ;
+    }    
+  }
+  return StatusCode::SUCCESS; 
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTimewalkMonitor::execute() {
+
+  // Grab the tracks.
+
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) return StatusCode::SUCCESS; 
+  for (const LHCb::TbTrack* track : *tracks) {
+ //   info() << track << endmsg; 
+    const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters();
+    const auto ref = std::min_element(
+        clusters.begin(), clusters.end(),
+        [](const LHCb::TbCluster* h1,
+          const LHCb::TbCluster* h2) { return h1->htime() < h2->htime(); });
+    const double tref = (*ref)->htime();
+    const double syncRef = (*clusters.rbegin())->htime();
+    unsigned int p = (*clusters.rbegin())->plane();
+
+    for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it){
+
+      auto hits = (*it)->hits();
+      for (const auto hit : hits) {
+        if( p==5 ){
+          m_space[(*it)->plane()]->fill( hit->col(), hit->htime() - syncRef );
+          m_spd2D[(*it)->plane()]->fill( hit->col(), hit->htime() - syncRef );
+        }
+        m_timewalk[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        m_twd[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        m_timewalkQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        m_twdQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        m_dtDist[(*it)->plane()]->fill( hit->htime() - tref );   
+      }
+      if( (*it)->size() == 2 ){
+        auto minmax = std::minmax_element(hits.begin(), hits.end(),[](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+        if( (*minmax.first)->col()  != (*minmax.second)->col() ){
+          m_twdL[(*it)->plane()]->fill( (*minmax.first)->ToT(), (*minmax.first)->htime() - tref );
+          m_twdR[(*it)->plane()]->fill( (*minmax.second)->ToT(), (*minmax.second)->htime() - tref );
+          m_twdQL[(*it)->plane()]->fill( (*minmax.first)->charge(), (*minmax.first)->htime() - tref );
+          m_twdQR[(*it)->plane()]->fill( (*minmax.second)->charge(), (*minmax.second)->htime() - tref );
+        }
+      }
+    }
+    const SmartRefVector<LHCb::TbCluster>& associatedClusters  = track->associatedClusters();
+
+    for (auto it = associatedClusters.cbegin(), end = associatedClusters.cend(); it != end; ++it){
+      auto hits = (*it)->hits();
+      //info() << "Filling associated clusters for " << track << endmsg; 
+      for (const auto hit : (*it)->hits()) {
+        m_timewalk[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        m_twd[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        //m_twdQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        //m_dtDist[(*it)->plane()]->fill( hit->htime() - tref );
+        m_timewalkQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        //if( (*it)->size() == 1 ) m_timewalkOneHit[(*it)->plane()]->fill(hit->ToT(), ( hit->htime() - tref ));
+        //if( (*it)->size() == 2 ) m_timewalkTwoHit[(*it)->plane()]->fill(hit->ToT(), ( hit->htime() - tref ));
+      }
+      /*
+      if( (*it)->size() == 2 ){
+        auto minmax = std::minmax_element(hits.begin(), hits.end(),[](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+        if( (*minmax.first)->col()  != (*minmax.second)->col() ){
+          m_twdL[(*it)->plane()]->fill( (*minmax.first)->ToT(), (*minmax.first)->htime() - tref );
+          m_twdR[(*it)->plane()]->fill( (*minmax.second)->ToT(), (*minmax.second)->htime() - tref );
+          m_twdQL[(*it)->plane()]->fill( (*minmax.first)->charge(), (*minmax.first)->htime() - tref );
+          m_twdQR[(*it)->plane()]->fill( (*minmax.second)->charge(), (*minmax.second)->htime() - tref );
+        }
+      }
+      */
+      //info() << "Filled associated clusters " << endmsg; 
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+/*
+   for(unsigned int plane=0;plane<m_nPlanes; ++plane ){
+   const LHCb::TbClusters* clusters = 
+   getIfExists<LHCb::TbClusters>(LHCb::TbClusterLocation::Default+std::to_string(plane));
+   for( auto& cluster : *clusters ){
+   if( cluster->size() == 2 ){
+   auto hits = cluster->hits();
+   auto minmax = std::minmax_element(hits.begin(), hits.end(),
+   [](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+   const LHCb::TbHit* left = (*minmax.first);
+   const LHCb::TbHit* right = (*minmax.second);
+   if( left->col() != right->col() ){
+   m_LRSYNC[plane]->fill( left->col() , left->htime() - right->htime() );
+   if( int(left->col() /2 ) == int(right->col() /2 ) ) 
+   m_inscol[plane]->fill( int(left->col()/2) , left->htime() - right->htime() );
+   else 
+   m_interscol[plane]->fill( int(left->col()/2) , left->htime() - right->htime() );
+   }
+   else {
+   minmax = std::minmax_element(hits.begin(), hits.end(),
+   [](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->row() < h2->row(); });
+   m_UDSYNC[plane]->fill( (*minmax.first)->row(), 
+   (*minmax.first)->htime() - (*minmax.second)->htime());
+   }
+   }
+   if( cluster->size() == 4 ){
+   auto hits = cluster->hits();
+   auto minmax = std::minmax_element(hits.begin(), hits.end(),
+   [](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+   const LHCb::TbHit* left = (*minmax.first);
+   const LHCb::TbHit* right = (*minmax.second);
+   if( left->col() == right->col() + 4 ){
+   m_quad[plane]->fill( left->col() , left->htime() - right->htime() );
+   }
+   }
+
+   }
+   }
+   return StatusCode::SUCCESS;
+   }
+   */
diff --git a/TbAnalysis/src/.svn/text-base/TbTimewalkMonitor.h.svn-base b/TbAnalysis/src/.svn/text-base/TbTimewalkMonitor.h.svn-base
new file mode 100644
index 0000000..4acaeb9
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbTimewalkMonitor.h.svn-base
@@ -0,0 +1,53 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IProfile1D.h"
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTimewalkMonitor TbTimewalkMonitor.h
+ *
+ */
+
+class TbTimewalkMonitor : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTimewalkMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTimewalkMonitor() {}
+  virtual StatusCode finalize(); 
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::string m_trackLocation;
+  unsigned int m_widthMax, m_widthMin;
+  std::vector<AIDA::IProfile1D*> m_timewalk;
+  std::vector<AIDA::IProfile1D*> m_timewalkOneHit;
+  std::vector<AIDA::IProfile1D*> m_timewalkTwoHit;
+  std::vector<AIDA::IProfile1D*> m_timewalkQ;
+  std::vector<AIDA::IHistogram1D*> m_dtDist;
+  std::vector<AIDA::IHistogram1D*> m_cDist;
+  
+  std::vector<AIDA::IProfile1D*> m_space;
+  std::vector<AIDA::IHistogram1D*> m_dt;
+  std::vector<AIDA::IProfile1D*> m_LRSYNC; 
+ 
+  std::vector<AIDA::IProfile1D*> m_UDSYNC;
+  std::vector<AIDA::IProfile1D*> m_quad;
+
+  std::vector<AIDA::IProfile1D*> m_inscol;
+  std::vector<AIDA::IProfile1D*> m_interscol;
+
+  std::vector<AIDA::IHistogram2D*> m_twd;
+  std::vector<AIDA::IHistogram2D*> m_twdQ;
+  std::vector<AIDA::IHistogram2D*> m_twdQL;
+  std::vector<AIDA::IHistogram2D*> m_twdQR;
+  std::vector<AIDA::IHistogram2D*> m_spd2D;
+  
+  std::vector<AIDA::IHistogram2D*> m_twdL;
+  std::vector<AIDA::IHistogram2D*> m_twdR;
+  
+};
diff --git a/TbAnalysis/src/.svn/text-base/TbVertexing.cpp.svn-base b/TbAnalysis/src/.svn/text-base/TbVertexing.cpp.svn-base
new file mode 100644
index 0000000..715a011
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbVertexing.cpp.svn-base
@@ -0,0 +1,136 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbVertexing.h"
+
+// ROOT
+#include "TH1D.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbVertexing)
+
+  template <class TYPE>
+  class itlowerBound {
+    public:
+      bool operator()(TYPE lhs, const double t) const { return (*lhs)->htime() < t; }
+  };
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbVertexing::TbVertexing(const std::string& name, 
+    ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator) {
+    declareProperty("TimeWindow",m_timeWindow);
+    declareProperty("MaxDoca2",m_maxDoca2);
+    declareProperty("TrackLocation", m_trackLocation = LHCb::TbTrackLocation::Default);
+  }
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbVertexing::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  if( m_trackFit == NULL ){
+    error() << "Failed to initialise trackfit" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Vertices");
+  // Check if already booked.
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Vertices",
+      CLID_ColumnWiseTuple, "nTuple of Vertices");
+  nt->addItem("nPlanes", m_index, 0, 10);
+  nt->addIndexedItem("X", m_index, m_vtxX);
+  nt->addIndexedItem("Y", m_index, m_vtxY);
+  nt->addIndexedItem("Z", m_index, m_vtxZ);
+  nt->addItem("Matched", m_matched );
+ // nt->addItem("Tk1Size",m_tkSize1);
+ // nt->addItem("Tk2Size",m_tkSize2);
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TbVertexing::finalize() {
+
+  return StatusCode::SUCCESS; 
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbVertexing::execute() {
+
+  // Grab the tracks.
+
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (tracks) {
+    for( auto& track1 : *tracks ){
+
+      const double tMin = track1->htime() - m_timeWindow;
+      const double tMax = track1->htime() + m_timeWindow;
+      auto track2 = std::lower_bound(tracks->begin(),
+          tracks->end(),
+          tMin, lowerBound<const LHCb::TbTrack*>());
+
+      for(; track2 != tracks->end() && (*track2)->htime() < tMax ; ++track2 ){
+        if( track1 == *track2 ) continue; 
+        const double DOCA = doca2(track1,*track2);
+        if( DOCA > m_maxDoca2 ) continue;
+        /// track separation ///
+        const double avgX = ( track1->firstState().tx() + (*track2)->firstState().tx() ) /2.;
+        const double avgY = ( track1->firstState().ty() + (*track2)->firstState().ty() ) /2.;
+
+        const double dt = pow ( ( track1->firstState().tx() - (*track2)->firstState().tx() ) / avgX, 2.0 ) +
+          pow ( ( ( track1->firstState().ty() - (*track2)->firstState().ty() ) ) / avgY , 2.0 ) ; 
+        auto chi2_pos = vertexPosition( {track1,*track2} );
+        plot( sqrt(DOCA), "DOCA", 0, 0.5, 100 ); /// 500 micron 
+        plot( dt, "Angle", -2., 2., 1000);
+        plot( chi2_pos[0]  , "VertexChi2_X",0.,14.,100);
+        plot( chi2_pos[1]  , "VertexChi2_Y",0.,14.,100);
+        plot( chi2_pos[2]  , "VertexChi2_Z",-700.,650.,2500);
+        m_vtxX[0] =  chi2_pos[0];
+        m_vtxY[0] =  chi2_pos[1];
+        m_vtxZ[0] =  chi2_pos[2];
+
+        ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Vertices");
+        m_index = 10;
+        m_matched = matched( track1, *track2 );
+        for( unsigned int plane = 0 ; plane != 9 ; ++plane ){
+          m_trackFit->maskPlane( plane );
+          m_trackFit->fit( track1 );
+          m_trackFit->fit( *track2 );
+          //m_vtxX[plane+1] 
+          auto up = vertexPosition( {track1,*track2});
+          m_vtxX[plane+1] = up[0];
+          m_vtxY[plane+1] = up[1];
+          m_vtxZ[plane+1] = up[2];
+          plot( up[2]  , "VertexChi2_Z_"+std::to_string(plane),-700.,650.,2500);
+          m_trackFit->unmaskPlane(plane);
+        }
+        m_trackFit->fit( track1 );
+        m_trackFit->fit( *track2);
+      }
+    }
+
+  }
+
+  return StatusCode::SUCCESS;
+}
+
diff --git a/TbAnalysis/src/.svn/text-base/TbVertexing.h.svn-base b/TbAnalysis/src/.svn/text-base/TbVertexing.h.svn-base
new file mode 100644
index 0000000..6fbbca3
--- /dev/null
+++ b/TbAnalysis/src/.svn/text-base/TbVertexing.h.svn-base
@@ -0,0 +1,96 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IProfile1D.h"
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/ITbTrackFit.h"
+#include "Event/TbTrack.h"
+
+#include "TVector3.h"
+#include "TMatrixD.h"
+#include "TVectorD.h"
+
+class TbVertexing : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbVertexing(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbVertexing() {}
+  virtual StatusCode finalize(); 
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  double m_timeWindow;
+  double m_maxDoca2;
+  NTuple::Item<unsigned int> m_index;
+  NTuple::Item<unsigned int> m_matched;
+  NTuple::Item<unsigned int> m_common;
+  NTuple::Array<double> m_vtxX;
+  NTuple::Array<double> m_vtxY;
+  NTuple::Array<double> m_vtxZ;
+  ITbTrackFit* m_trackFit;
+
+  std::string m_trackLocation;
+
+  double doca2( const LHCb::TbTrack* track1, const LHCb::TbTrack* track2 ) const {
+    const TVector3 r1( track1->firstState().x(), track1->firstState().y(), 0. );
+    const TVector3 r2( track2->firstState().y(), track2->firstState().y(), 0. );
+    const TVector3 t1( track1->firstState().tx(), track1->firstState().ty(), 1.);
+    const TVector3 t2( track2->firstState().tx(), track2->firstState().ty(), 1.);
+    
+    const double z0 = - (t1 -t2).Dot( r1 - r2 ) / (t1-t2).Mag2();
+    return (r1-r2).Mag2() + 2*z0*(t1-t2).Dot(r1-r2) + z0*z0*(t1-t2).Mag2();
+  };
+
+  /// checks if has > 3 vertices in the forward direction, with unmatched clusters /// 
+  int matched( const LHCb::TbTrack* track1, const LHCb::TbTrack* track2 ) const {
+    auto clusters1 = track1->clusters();
+    auto clusters2 = track2->clusters();
+    int nCommon = 0;
+    int nMatched = 0;
+    for( auto& cluster1 : clusters1 ){
+      for( auto& cluster2 : clusters2 ){
+        if( cluster1->plane() == cluster2->plane() ){
+          if( cluster1 != cluster2 ) nMatched++;
+          else nCommon++;
+          break;
+        }
+      }
+    }
+    return nMatched;
+  }
+
+  TVectorD vertexPosition( const std::vector<const LHCb::TbTrack*>& tracks ) const {
+    
+    TMatrixD cov(3,3);
+    TVectorD res(3);
+    for( auto& track : tracks ){
+      TVectorD t(3);
+      t[0] = track->firstState().tx();
+      t[1] = track->firstState().ty();
+      t[2] = 1;
+      const double norm = t.Norm2Sqr();
+      TVectorD r(3);
+      r[0] = track->firstState().x();
+      r[1] = track->firstState().y();
+      r[2] = 0;
+      double ip = t[0]*r[0] + t[1]*r[1] + t[2]*r[2];
+
+      res += r - (ip /norm ) * t;
+
+      for( unsigned int i=0;i!=3;++i){  
+        for( unsigned int j=0; j !=3 ;++j){
+          if(i==j) cov[i][j] += 1 - t[i]*t[j] / norm;
+          else cov[i][j] += - t[i]*t[j] / norm;
+        }
+      } 
+    }
+    TMatrixD inv = cov.Invert();
+    return inv * res ; 
+  }
+
+};
diff --git a/TbAnalysis/src/TbChargeCalib.cpp b/TbAnalysis/src/TbChargeCalib.cpp
new file mode 100644
index 0000000..ebd8678
--- /dev/null
+++ b/TbAnalysis/src/TbChargeCalib.cpp
@@ -0,0 +1,74 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbChargeCalib.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbChargeCalib)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbChargeCalib::TbChargeCalib(const std::string& name, 
+                                     ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbChargeCalib::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  info() << "Booking histograms for Chargecalib ... " << endmsg;
+  m_ToTHists.reserve(256*256);
+  for( unsigned int i = 0 ; i < 256*256; ++i){
+    const std::string name = "c=" + std::to_string( i/256 ) + ", r=" + std::to_string(i%256);
+    if( i % 256 == 0 ) info() << "Booked histogram for column " << i << endmsg;
+    m_ToTHists.push_back(book1D(name, name, 0.5, 200.5, 200));
+    setAxisLabels(m_ToTHists[i], "ToT", "Entries");
+  }
+  info() << "Booked 60000 ish hists" << endmsg; 
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbChargeCalib::execute() {
+
+   LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation+std::to_string(0));
+   if (!clusters) {
+     error() << "No clusters in " << m_clusterLocation << endmsg;
+     return StatusCode::FAILURE;
+   }
+  for( const LHCb::TbCluster* c : *clusters  ){
+    if( c->size() != 1 ) continue;
+ 
+    unsigned int col = c->hits()[0]->col();
+    unsigned int row = c->hits()[0]->row();
+    unsigned int tot = c->hits()[0]->ToT();
+    //info() << c->hits()[0] << endmsg;
+    m_ToTHists[ col*256 + row ]->fill( tot );
+
+  } 
+  return StatusCode::SUCCESS;
+}
+
diff --git a/TbAnalysis/src/TbChargeCalib.h b/TbAnalysis/src/TbChargeCalib.h
new file mode 100644
index 0000000..8e3860b
--- /dev/null
+++ b/TbAnalysis/src/TbChargeCalib.h
@@ -0,0 +1,28 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbChargeCalib TbChargeCalib.h
+ *
+ */
+
+class TbChargeCalib : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbChargeCalib(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbChargeCalib() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::string m_clusterLocation;
+
+  std::vector<AIDA::IHistogram1D*> m_ToTHists;
+
+};
diff --git a/TbAnalysis/src/TbEffPur.cpp b/TbAnalysis/src/TbEffPur.cpp
new file mode 100644
index 0000000..9503401
--- /dev/null
+++ b/TbAnalysis/src/TbEffPur.cpp
@@ -0,0 +1,900 @@
+#include <fstream>
+
+// ROOT
+#include "TMath.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbEffPur.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbEffPur)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbEffPur::TbEffPur(const std::string& name, ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator),
+  m_pitch(0.055),
+  m_nDUTpixels(256),
+  m_nTracks(0),
+  m_nClusters(0),
+  m_nTrackedClusters(0),
+	m_nClustersPassedCentral(0),
+	m_nTracksCentral(0),
+	m_nClustersPassedCorner(0),
+	m_nTracksCorner(0),
+  m_eff(0.),
+  m_pur(0.),
+  m_deadAreaRadius(2.),
+  m_trackAssociated(NULL)
+{
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("VertexLocation",
+                  m_vertexLocation = LHCb::TbVertexLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+  // Parameters.
+  declareProperty("DUTindex", m_DUTindex = 4);
+  declareProperty("GlobalCutXLow", m_xLow = 3);
+  declareProperty("GlobalCutXUp", m_xUp = 9);
+  declareProperty("GlobalCutYLow", m_yLow = 3);
+  declareProperty("GlobalCutYUp", m_yUp = 9);
+  declareProperty("LocalProbabilityCut", m_probCut = 0.5);
+
+  declareProperty("RResidualCut", m_rResidualCut = 0.1);
+  declareProperty("TResidualCut", m_tResidualCut = 100);
+  declareProperty("ChargeCutLow", m_chargeCutLow = 0);
+  // ... note this global cut enforced at different point to above.
+  declareProperty("ChargeCutUp", m_chargeCutUp = 1000000);
+  declareProperty("LitSquareSide", m_litSquareSide = 0);
+
+  declareProperty("ViewerOutput", m_viewerOutput = false);
+  declareProperty("ViewerEventNum", m_viewerEvent = 100);
+  declareProperty("TGap", m_tGap = 200);
+  declareProperty("CorrelationTimeWindow", m_correlationTimeWindow = 100);
+  declareProperty("ApplyVeto", m_applyVeto = true);
+  declareProperty("TelescopeClusterVetoDelT", m_telescopeClusterVetoDelT = 30);
+  declareProperty("EdgeVetoDistance", m_edgeVetoDistance = 0.025);
+  m_nEvent = -1;
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbEffPur::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+	// Efficiency objects.
+	m_effX = new TEfficiency("efficiencyX", "efficiencyX", 40, 0.0, 0.11);
+	m_effY = new TEfficiency("efficiencyY", "efficiencyY", 40, 0.0, 0.11);
+	m_effs = new TEfficiency("efficiency", "efficiency", 1, -0.5, 0.5);
+  m_purs = new TEfficiency("purity", "Tb/TbEffPur/pur", 1, -0.5, 0.5);
+  m_effHitmap = new TEfficiency("efficiencyHitmap", "efficiencyHitmap",
+  		64, 0.0, 14.08, 64, 0.0, 14.08);
+  m_purHitmap = new TEfficiency("puritHitmap", "purityHitmap",
+  		64, 0.0, 14.08, 64, 0.0, 14.08);
+
+  int nBins = 50;
+  m_effHitmapInterPixel = new TEfficiency("efficiencyHitmapInterPixel", "efficiencyHitmapInterPixel",
+  		nBins, 0.0, 0.055, nBins, 0.0, 0.055);
+  m_purHitmapInterPixel = new TEfficiency("puritHitmapInterPixel", "purityHitmapInterPixel",
+  		nBins, 0.0, 0.055, nBins, 0.0, 0.055);
+
+  m_effHitmapInterPixelTriple = new TEfficiency("efficiencyHitmapInterPixelTriple", "efficiencyHitmapInterPixelTriple",
+  		150, 0.0, 10*0.055, 20, 0.0, 2*0.055);
+
+  for (unsigned int i=1; i<5; i++) {
+  	std::string name = "efficiencyHitmapInterClusterSize" + std::to_string(i);
+  	TEfficiency * e = new TEfficiency(name.c_str(), name.c_str(),
+  		nBins, 0.0, 0.055, nBins, 0.0, 0.055);
+  	m_effHitmapInterPixelVsSizes.push_back(e);
+  }
+
+  // Plots for post correlations.
+  m_remainsCorrelationsX = book2D("remainsClusterCorrelationsX", "remainsClusterCorrelationsX", 0, 14, 200, 0, 14, 200);
+  m_remainsCorrelationsY = book2D("remainsClusterCorrelationsY", "remainsClusterCorrelationsY", 0, 14, 200, 0, 14, 200);
+  m_remainsDifferencesXY = book2D("remainsDifferencesXY", "remainsDifferencesXY", -1.5, 1.5, 150, -1.5, 1.5, 150);
+  m_clusterRemainsPositionsLocal = book2D("clusterRemainsPositionsLocal", "clusterRemainsPositionsLocal", -5, 20, 600, -5, 20, 600);
+  m_trackRemainsPositionsLocal = book2D("trackRemainsPositionsLocal", "trackRemainsPositionsLocal", 0, 256, 600, 0, 256, 600);
+  m_clusterRemainsPositionsGlobal = book2D("clusterRemainsPositionsGlobal", "clusterRemainsPositionsGlobal", -5, 20, 600, -5, 20, 600);
+  m_trackRemainsPositionsGlobal = book2D("trackRemainsPositionsGlobal", "trackRemainsPositionsGlobal", -5, 20, 600, -5, 20, 600);
+  m_vetoTracksHitmap = book2D("vetoTrackHitmap", "vetoTrackHitmap", -5, 20, 600, -5, 20, 600);
+  m_vetoClustersHitmap = book2D("vetoClusterHitmap", "vetoClusterHitmap", -5, 20, 600, -5, 20, 600);
+  m_timeResidualVsColumn = book2D("timeResidualVsColumn", "timeResidualVsColumn", 0, 256, 256, -50, 50, 500);
+
+
+  // Setup the tools.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  // h_effVsCharge = new TH2F("effVsCharge", "effVsCharge", 50, 0.5, 1, 20, 0.5, 20.5);
+  // TFile * f = new TFile("/afs/cern.ch/user/d/dsaunder/cmtuser/KEPLER/KEPLER_HEAD/EDR_plots/EfficiencyResults/Eff-S22-Run6309-500V.root", "READ");
+  // h_effInter = (TH2F*)f->Get("eff_histo");
+  return StatusCode::SUCCESS;
+
+}
+
+
+//=============================================================================
+// Finalizer
+//=============================================================================
+StatusCode TbEffPur::finalize() {
+	m_effs->SetTotalEvents(0, m_nTracks);
+	m_effs->SetPassedEvents(0, m_nTrackedClusters);
+
+	m_purs->SetTotalEvents(0, m_nClusters);
+	m_purs->SetPassedEvents(0, m_nTrackedClusters);
+
+	m_eff = m_nTrackedClusters/(1.0*m_nTracks);
+	m_pur = m_nTrackedClusters/(1.0*m_nClusters);
+	std::cout<<"ith ROOT Efficiency: " << m_effs->GetEfficiency(0) << " + " << m_effs->GetEfficiencyErrorUp(0) <<" - "<< m_effs->GetEfficiencyErrorLow(0) <<std::endl;
+	std::cout<<"ith ROOT Purity: " << m_purs->GetEfficiency(0) << " + " << m_purs->GetEfficiencyErrorUp(0) <<" - "<< m_purs->GetEfficiencyErrorLow(0) <<std::endl;
+
+	std::cout<<"Corner efficiency: "<<m_nClustersPassedCorner/(1.*m_nTracksCorner)<<std::endl;
+	std::cout<<"Central efficiency: "<<m_nClustersPassedCentral/(1.*m_nTracksCentral)<<std::endl;
+
+	plot(m_eff, "Efficiency", "Efficiency", 0.0, 1, 1);
+	plot(m_pur, "Purity", "Purity", 0.0, 1, 1);
+	plot(m_effs->GetEfficiencyErrorUp(0), "EfficiencyError", "EfficiencyError", 0.0, 1, 1);
+	plot(m_purs->GetEfficiencyErrorUp(0), "PurityError", "PurityError", 0.0, 1, 1);
+
+	TH2D * h = Gaudi::Utils::Aida2ROOT::aida2root(m_trackRemainsPositionsLocal);
+	double maxBin = h->GetBinContent(h->GetMaximumBin());
+	double minBin = h->GetBinContent(h->GetMinimumBin());
+	for (int i=0; i<m_trackRemainsPositionsLocal->xAxis().bins(); i++) {
+		for (int j=0; j<m_trackRemainsPositionsLocal->yAxis().bins(); j++) {
+			plot(m_trackRemainsPositionsLocal->binHeight(i, j), "trackRemainsBins",
+					"trackRemainsBins", minBin, maxBin, int(maxBin-minBin));
+		}
+	}
+
+	TFile * f = new TFile("EfficiencyResults.root", "RECREATE");
+	//m_effs->Write();
+
+	m_effHitmapInterPixel->Write();
+	m_effHitmapInterPixelTriple->Write();
+	//h_effVsCharge->Write();
+	//m_effs->CreateHistogram()->Write();
+	m_effHitmapInterPixel->CreateHistogram()->Write();
+	m_effHitmapInterPixelTriple->CreateHistogram()->Write();
+
+
+
+//	for (unsigned int i=0; i<m_effHitmapInterPixelVsSizes.size(); i++) {
+//		m_effHitmapInterPixelVsSizes[i]->Write();
+//		//m_effHitmapInterPixelVsSizes[i]->CreateHistogram()->Write();
+//	}
+	f->Close();
+  return TbAlgorithm::finalize();
+}
+
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbEffPur::execute()
+{
+	m_nEvent++;
+
+  m_tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  //m_vertices = getIfExists<LHCb::TbVertices>(m_vertexLocation);
+  m_clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(m_DUTindex));
+
+  if (m_clusters->size() < 100 || m_tracks->size() < 100) return StatusCode::SUCCESS;
+
+  // Matching.
+  effPur();
+  return StatusCode::SUCCESS;
+}
+
+
+//=============================================================================
+// Efficiency finding
+//=============================================================================
+void TbEffPur::effPur()
+{
+	// Non-veto'd containers.
+  std::vector<LHCb::TbCluster*> * cutClusters = new std::vector<LHCb::TbCluster*>();
+  std::vector<LHCb::TbTrack*> cutTracks;
+  int nClustersPreVeto = m_clusters->size();
+  int nTracksPreVeto  = m_tracks->size();
+
+
+  // Apply veto.
+  if (m_applyVeto) applyVeto(cutClusters, &cutTracks);
+  else fillAllTrackClusters(cutClusters, &cutTracks);
+  m_trackAssociated = new std::vector<bool>(cutTracks.size(), false);
+  //std::cout<<"Fraction tracks not veto'd: "<<cutTracks.size()/(1.0*nTracksPreVeto)<<"\tEvent: "<<m_nEvent<<std::endl;
+  //std::cout<<"Fraction clusters not veto'd: "<<cutClusters->size()/(1.0*nClustersPreVeto)<<"\tEvent: "<<m_nEvent<<std::endl;
+  plot(cutClusters->size()/(1.0*nClustersPreVeto), "clusterFractionVetod", "clusterFractionVetod", 0.0, 1.0, 200);
+  plot(cutTracks.size()/(1.0*nTracksPreVeto), "trackFractionVetod", "trackFractionVetod", 0.0, 1.0, 200);
+
+
+  // Do matching.
+  m_nClusters += cutClusters->size();
+  m_nTracks += cutTracks.size();
+  trackClusters(cutClusters, &cutTracks);
+
+
+  // Viewer options.
+  if (m_nEvent == m_viewerEvent) {
+  	if (m_viewerOutput) outputViewerData();
+		for (LHCb::TbClusters::iterator iclust = cutClusters->begin();
+				iclust != cutClusters->end(); iclust++) {
+//			if (!(*iclust)->associated())
+//				std::cout<<"Note: non-associated clusters at hTime: "<<(*iclust)->htime()<<std::endl;
+		}
+  }
+
+  // Correlate remains.
+  //correlateRemains(&cutTracks, cutClusters);
+  delete cutClusters;
+  delete m_trackAssociated;
+}
+
+
+//=============================================================================
+// Global cuts
+//=============================================================================
+void TbEffPur::applyVeto(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks)
+{
+  // Gather all cluster times (over all planes) and sort it ___________________
+	std::vector<double> allClusterTimes;
+	for (unsigned int i=0; i<m_nPlanes; i++) {
+    LHCb::TbClusters * clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(i));
+		for (LHCb::TbClusters::const_iterator it = clusters->begin(); it != clusters->end(); ++it)
+			allClusterTimes.push_back((*it)->htime());
+	}
+	std::sort(allClusterTimes.begin(), allClusterTimes.end());
+
+
+
+	// Get big enough gaps in pairs _____________________________________________
+	std::vector<double> tGapCenters;
+	tGapCenters.push_back(0);
+	for (std::vector<double>::iterator itime = allClusterTimes.begin()+1;
+			itime != allClusterTimes.end(); itime++) {
+		plot((*itime) - (*(itime-1)), "allGapWidths", "allGapWidths", 0.0, 3000.0, 200);
+		if ((*itime) - (*(itime-1)) > m_tGap) {
+			tGapCenters.push_back(0.5*((*itime) + (*(itime-1))));
+			plot((*itime) - (*(itime-1)), "bigGapWidths", "bigGapWidths", 0.0, 3000.0, 200);
+		}
+	}
+	tGapCenters.push_back(allClusterTimes.back());
+	counter("nGaps") += tGapCenters.size();
+	plot(tGapCenters.size(), "nGaps", "nGaps", 0.0, 1000.0, 200);
+
+
+
+	// Loop over these sub events and veto ______________________________________
+	std::vector<double>::iterator igap;
+	for (igap = tGapCenters.begin(); igap != tGapCenters.end() - 1; igap++) {
+		bool veto = false;
+
+		if (igap == tGapCenters.begin() || igap == tGapCenters.end() -1) veto = true;
+
+		// Loop tracks.
+		if (!veto) {
+			for (LHCb::TbTrack* track : *m_tracks) {
+				if (track->htime() > (*igap) && track->htime() < (*(igap+1))) {
+					// Veto on tracks outside cuts.
+					const Gaudi::XYZPoint trackInterceptGlobal = geomSvc()->intercept(track, m_DUTindex);
+					if (!globalCutPosition(trackInterceptGlobal)) veto = true;
+					else if (outsideDUT(trackInterceptGlobal)) veto = true;
+					else if (interceptDeadPixel(trackInterceptGlobal)) veto = true;
+				}
+			}
+		}
+
+
+		// Loop vertices.
+//		if (!veto) {
+//			for (LHCb::TbVertex* vertex : *m_vertices) {
+//				if (vertex->htime() > (*igap) && vertex->htime() < (*(igap+1))) {
+//					veto = true;
+//				}
+//			}
+//		}
+
+
+		// Loop DUT clusters.
+		if (!veto) {
+			for (const LHCb::TbCluster* cluster : *m_clusters) {
+				if (cluster->htime() > (*igap) && cluster->htime() < (*(igap+1))) {
+					// Veto on clusters outside cuts.
+					Gaudi::XYZPoint clusterInterceptGlobal(cluster->x(), cluster->y(), cluster->z());
+					if (!globalCutPosition(clusterInterceptGlobal)) veto = true;
+					if (cluster->charge() > m_chargeCutUp || cluster->charge() < m_chargeCutLow) veto = true;
+				}
+			}
+		}
+
+
+		// Loop telescope clusters.
+		if (!veto) {
+			for (unsigned int i=0; i<m_nPlanes; i++) {
+				if (i == m_DUTindex) continue;
+				LHCb::TbClusters * clusters = getIfExists<LHCb::TbClusters>(m_clusterLocation + std::to_string(i));
+				for (LHCb::TbClusters::const_iterator it = clusters->begin(); it != clusters->end()-1; ++it) {
+					if ((*it)->htime() > (*igap) && (*it)->htime() < (*(igap+1))) {
+						double delt = (*it)->htime() - (*(it+1))->htime();
+						if (fabs(delt) < m_telescopeClusterVetoDelT) {
+							veto = true;
+							break;
+						}
+					}
+				}
+			}
+		}
+
+
+		if (!veto) fillTrackClusters(cutClusters, cutTracks, (*igap), (*(igap+1)));
+		else counter("nGapsFiltered") += 1;
+	}
+}
+
+
+
+//=============================================================================
+// Correlate remains
+//=============================================================================
+void TbEffPur::correlateRemains(std::vector<LHCb::TbTrack*> * cutTracks,
+		std::vector<LHCb::TbCluster*> * cutClusters)
+{
+	for (std::vector<LHCb::TbCluster*>::iterator ic = cutClusters->begin();
+	  		ic != cutClusters->end(); ++ic) {
+		if (!(*ic)->associated()) {
+			m_clusterRemainsPositionsGlobal->fill((*ic)->x(), (*ic)->y());
+			m_clusterRemainsPositionsLocal->fill((*ic)->xloc(), (*ic)->yloc());
+			plot((*ic)->charge(), "chargeClusterRemains", "chargeClusterRemains", 0.0, 1000.0, 125);
+		}
+	}
+
+	unsigned int i = 0;
+	for (std::vector<LHCb::TbTrack*>::iterator itrack = cutTracks->begin();
+			itrack != cutTracks->end(); itrack++) {
+		if (!m_trackAssociated->at(i)) {
+		  Gaudi::XYZPoint trackIntercept = geomSvc()->intercept((*itrack), m_DUTindex);
+		  m_trackRemainsPositionsGlobal->fill(trackIntercept.x(), trackIntercept.y());
+		  auto interceptUL = geomSvc()->globalToLocal(trackIntercept, m_DUTindex);
+		  m_trackRemainsPositionsLocal->fill(interceptUL.x()/m_pitch - 0.5, interceptUL.y()/m_pitch - 0.5);
+		}
+		i++;
+	}
+
+
+  // Draws correlations plots between non-associated clusters and tracks.
+	for (std::vector<LHCb::TbTrack*>::iterator itrack = cutTracks->begin();
+			itrack != cutTracks->end(); itrack++) {
+	  for (std::vector<LHCb::TbCluster*>::iterator ic = cutClusters->begin();
+	  		ic != cutClusters->end(); ++ic) {
+	  	if ((*ic)->htime() < (*itrack)->htime() - m_correlationTimeWindow) continue;
+	  	if (!(*ic)->associated()) {
+	  		//if (m_nEvent == m_viewerEvent) std::cout<<"Impurity at time: "<<(*ic)->htime()<<std::endl;
+	  		Gaudi::XYZPoint trackIntercept = geomSvc()->intercept((*itrack), m_DUTindex);
+	  		m_remainsCorrelationsX->fill(trackIntercept.x(), (*ic)->x());
+	  		m_remainsCorrelationsY->fill(trackIntercept.y(), (*ic)->y());
+
+	  		plot(trackIntercept.x() - (*ic)->x(), "remainClustDifferencesX", "remainsClustDifferencesX", -1.5, 1.5, 150);
+	  		plot(trackIntercept.y() - (*ic)->y(), "remainClustDifferencesY", "remainClustDifferencesY", -1.5, 1.5, 150);
+	  		plot((*itrack)->htime() - (*ic)->htime(), "remainClustDifferencesT", "remainClustDifferencesT", -50, 50, 150);
+
+	  		m_remainsDifferencesXY->fill(trackIntercept.y() - (*ic)->y(), trackIntercept.x() - (*ic)->x());
+	  	}
+	  	if ((*ic)->htime() > (*itrack)->htime() + m_correlationTimeWindow) break;
+	  }
+	}
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void TbEffPur::fillAllTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks)
+{
+  for (LHCb::TbTrack* track : *m_tracks) cutTracks->push_back(track);
+  for (std::vector<LHCb::TbCluster*>::iterator iClust = m_clusters->begin();
+  		iClust != m_clusters->end(); iClust++) cutClusters->push_back(*iClust);
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+void TbEffPur::fillTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks, double tlow, double tup)
+{
+	// Push tracks and clusters inside this time window, which passed the veto.
+  for (LHCb::TbTrack* track : *m_tracks) {
+  	if (track->htime() > tlow && track->htime() < tup) {
+  		Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+  		cutTracks->push_back(track);
+  		m_vetoTracksHitmap->fill(trackIntercept.x(), trackIntercept.y());
+
+  		Gaudi::XYZPoint trackInterceptLocal = geomSvc()->globalToLocal(trackIntercept, m_DUTindex);
+			int row = trackInterceptLocal.y()/m_pitch - 0.5;
+			int col = trackInterceptLocal.x()/m_pitch - 0.5;
+
+			if (pixelSvc()->isMasked(pixelSvc()->address(col, row), m_DUTindex)) {
+				std::cout<<"Shouldn't be here!"<<std::endl;
+			}
+  	}
+  }
+
+  for (LHCb::TbCluster* cluster : *m_clusters) {
+		if (cluster->htime() > tlow && cluster->htime() < tup) {
+			cutClusters->push_back(cluster);
+			m_vetoClustersHitmap->fill(cluster->x(), cluster->y());
+		}
+  }
+}
+
+
+//=============================================================================
+// Global cuts
+//=============================================================================
+void TbEffPur::trackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks)
+{
+  for (std::vector<LHCb::TbTrack*>::iterator itrack = cutTracks->begin();
+  		itrack != cutTracks->end(); itrack++) {
+
+  	// Get local position of track.
+  	const auto interceptUG = geomSvc()->intercept((*itrack), m_DUTindex);
+    const auto interceptUL = geomSvc()->globalToLocal(interceptUG, m_DUTindex);
+
+
+  	// Loop over clusters to find the closest.
+  	LHCb::TbCluster * closestCluster = NULL;
+  	double bestRadialDistance;
+  	for (std::vector<LHCb::TbCluster*>::iterator iclust = cutClusters->begin();
+  			iclust != cutClusters->end(); iclust++) {
+  		bool match = matchTrackToCluster((*iclust), (*itrack));
+  		double radialDistance = getRadialSeparation((*iclust), (*itrack));
+  		if (match) {
+  			if (!closestCluster) {
+  				closestCluster = (*iclust);
+  				bestRadialDistance = radialDistance;
+  			}
+  			else if (radialDistance<bestRadialDistance) {
+  				closestCluster = (*iclust);
+  				bestRadialDistance = radialDistance;
+  			}
+  		}
+
+  		if ((*iclust)->htime() - (*itrack)->htime() > m_tResidualCut) break;
+  	}
+
+  	double trackX = interceptUL.x();
+  	double trackY = interceptUL.y();
+
+		if (closestCluster != NULL && closestCluster->charge() > m_chargeCutLow) {
+			closestCluster->setAssociated(true);
+			m_nTrackedClusters++;
+			m_effHitmap->Fill(true, trackX, trackY);
+			m_effX->Fill(true, trackX);
+			m_effY->Fill(true, trackY);
+
+			if (fmod(trackX, m_pitch)<0.0183 && fmod(trackY, m_pitch) < 0.0183) m_nClustersPassedCorner++;
+			if (fmod(trackX, m_pitch) > 0.0183 &&
+					fmod(trackX, m_pitch) < (2*0.0183) &&
+					fmod(trackY, m_pitch) > 0.0183 &&
+					fmod(trackY, m_pitch) < (2*0.0183)) m_nClustersPassedCentral++;
+
+
+			//h_effVsCharge->Fill(h_effInter->Interpolate(fmod(trackX, m_pitch), fmod(trackY, m_pitch)), closestCluster->charge());
+			// if (trackY > 9.25 && trackY < 10.25) m_effHitmapInterPixel->Fill(true, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+			// if (trackX > 28.05 &&
+			// 		trackX < 28.6) m_effHitmapInterPixelTriple->Fill(true, trackX-28.05, fmod(trackY, m_pitch));
+
+
+      m_effHitmapInterPixel->Fill(true, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+      m_effHitmapInterPixelTriple->Fill(true, trackX-28.05, fmod(trackY, m_pitch));
+
+
+			if (closestCluster->size() <= m_effHitmapInterPixelVsSizes.size())
+				m_effHitmapInterPixelVsSizes[closestCluster->size()-1]->Fill(true, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+			m_trackAssociated->at(itrack - cutTracks->begin()) = true;
+			plot(closestCluster->x() - interceptUG.x(), "xResidualsClustMinusTrack", "xResidualsClustMinusTrack", -0.2, 0.2, 400);
+			plot(closestCluster->y() - interceptUG.y(), "yResidualsClustMinusTrack", "yResidualsClustMinusTrack", -0.2, 0.2, 400);
+			plot(closestCluster->htime() - (*itrack)->htime(), "hTimeResidualClustMinusTrack", "hTimeResidualClustMinusTrack", -50, 50, 400);
+			if (closestCluster->size() == 1) {
+				auto hits = closestCluster->hits();
+				int col = (*hits.begin())->col();
+				m_timeResidualVsColumn->fill(col, closestCluster->htime() - (*itrack)->htime());
+			}
+			if ((*itrack)->vertexed()) counter("nVerticesCorrelated") += 1;
+		}
+		else {
+			m_effHitmap->Fill(false, trackX, trackY);
+			// if (trackY > 9.25 && trackY < 10.25) m_effHitmapInterPixel->Fill(false, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+			// if (trackX > 28.05 &&
+			// 		trackX < 28.6) m_effHitmapInterPixelTriple->Fill(false, trackX-28.05, fmod(trackY, m_pitch));
+
+      m_effHitmapInterPixel->Fill(false, fmod(trackX, m_pitch), fmod(trackY, m_pitch));
+      m_effHitmapInterPixelTriple->Fill(false, trackX-28.05, fmod(trackY, m_pitch));
+			m_effX->Fill(false, trackX);
+			m_effY->Fill(false, trackY);
+			//std::cout<<"Inefficiency at time: "<<(*itrack)->htime()<<std::endl;
+		}
+		if (fmod(trackX, m_pitch)<0.0183 && fmod(trackY, m_pitch) < 0.0183) m_nTracksCorner++;
+		if (fmod(trackX, m_pitch) > 0.0183 &&
+					fmod(trackX, m_pitch) < (2*0.0183) &&
+					fmod(trackY, m_pitch) > 0.0183 &&
+					fmod(trackY, m_pitch) < (2*0.0183)) m_nTracksCentral++;
+  }
+}
+
+
+
+//=============================================================================
+//
+//=============================================================================
+double TbEffPur::getRadialSeparation(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track)
+{
+  Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+	double xResidual = cluster->x() - trackIntercept.x();
+	double yResidual = cluster->y() - trackIntercept.y();
+
+	double r2 = xResidual*xResidual + yResidual*yResidual;
+	return pow(r2, 0.5);
+}
+
+
+//=============================================================================
+// Local cuts
+//=============================================================================
+bool TbEffPur::matchTrackToCluster(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track)
+{
+  Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+	double xResidual = cluster->x() - trackIntercept.x();
+	double yResidual = cluster->y() - trackIntercept.y();
+	double tResidual = cluster->htime() - track->htime();
+	double delr = pow(pow(xResidual, 2) + pow(yResidual, 2), 0.5);
+
+//	if (track->vertexed()) plot(xResidual, "vertexResiduals/X", "vertexResiduals/X", -0.5, 0.5, 200);
+//	if (track->vertexed()) plot(yResidual, "vertexResiduals/Y", "vertexResiduals/Y", -0.5, 0.5, 200);
+//	if (track->vertexed()) plot(tResidual, "vertexResiduals/T", "vertexResiduals/T", -0.5, 0.5, 200);
+//
+//	if (track->vertexed() && litPixel(cluster, track)) {
+//		plot(xResidual, "vertexResiduals/Xlit", "vertexResiduals/Xlit", -0.5, 0.5, 200);
+//		plot(yResidual, "vertexResiduals/Ylit", "vertexResiduals/Ylit", -0.5, 0.5, 200);
+//	}
+
+
+	if (fabs(tResidual) > m_tResidualCut) {
+  	counter("nTimeRejected") += 1;
+		return false;
+	}
+
+  if (delr > m_rResidualCut) {
+  	counter("nSpatialRejected") += 1;
+  	if (litPixel(cluster, track)) return true;
+  	else {
+  		counter("nSpatialAndLitRejected") += 1;
+  		return false;
+  	}
+  }
+
+//	if (!litPixel(cluster, track)) return false;
+
+  return true;
+}
+
+
+//=============================================================================
+//
+//=============================================================================
+bool TbEffPur::interceptDeadPixel(Gaudi::XYZPoint trackInterceptGlobal)
+{
+	// Find the row and column corresponding to the track intercept.
+	Gaudi::XYZPoint trackInterceptLocal = geomSvc()->globalToLocal(trackInterceptGlobal, m_DUTindex);
+  int row = trackInterceptLocal.y()/m_pitch - 0.5;
+  int col = trackInterceptLocal.x()/m_pitch - 0.5;
+
+  for (int icol = col - 1; icol != col+2; icol++) {
+  	for (int irow = row - 1; irow != row+2; irow++) {
+  		if (icol >= 0 && icol <256 && irow>=0 && irow<256) {
+  			if (pixelSvc()->isMasked(pixelSvc()->address(icol, irow), m_DUTindex)) {
+					return true;
+				}
+
+//  			if (icol == 17 && irow == 36) {
+//  				return true;
+//  			}
+//				if (icol == 18 && irow == 36) {
+//  				return true;
+//  			}
+//				if (icol == 53 && irow == 3) {
+//  				return true;
+//  			}
+//				if (icol == 54 && irow == 3) {
+//  				return true;
+//  			}
+//				if (icol == 73 && irow == 26) {
+//  				return true;
+//  			}
+//				if (icol == 74 && irow == 26) {
+//  				return true;
+//  			}
+//				if (icol == 19 && irow == 103) {
+//  				return true;
+//  			}
+//				if (icol == 31 && irow == 106) {
+//  				return true;
+//  			}
+//				if (icol == 32 && irow == 106) {
+//  				return true;
+//  			}
+//				if (icol == 38 && irow == 108) {
+//  				return true;
+//  			}
+//				if (icol == 63 && irow == 95) {
+//  				return true;
+//  			}
+//				if (icol == 64 && irow == 95) {
+//  				return true;
+//  			}
+//				if (icol == 103 && irow == 23) {
+//  				return true;
+//  			}
+//				if (icol == 104 && irow == 23) {
+//  				return true;
+//  			}
+//				if (icol == 115 && irow == 20) {
+//  				return true;
+//  			}
+//				if (icol == 116 && irow == 94) {
+//  				return true;
+//  			}
+  		}
+  	}
+  }
+
+
+
+  return false;
+}
+
+//=============================================================================
+//
+//=============================================================================
+bool TbEffPur::litPixel(LHCb::TbCluster * cluster, LHCb::TbTrack * track)
+{
+	// Find the row and column corresponding to the track intercept.
+	Gaudi::XYZPoint trackIntercept = geomSvc()->intercept(track, m_DUTindex);
+	Gaudi::XYZPoint pLocal = geomSvc()->globalToLocal(trackIntercept, m_DUTindex);
+  int row = pLocal.y()/m_pitch - 0.5;
+  int col = pLocal.x()/m_pitch - 0.5;
+
+  // See if within a pre-defined square of pixels.
+  for (unsigned int i=0; i<cluster->size(); i++) {
+  	unsigned int delRow = abs(row - int(cluster->hits()[i]->row()));
+  	unsigned int delCol = abs(col - int(cluster->hits()[i]->col()));
+
+  	if (delRow <= m_litSquareSide && delCol <= m_litSquareSide) {
+		  counter("nLitPixels") += 1;
+  		return true;
+  	}
+  }
+
+  return false;
+}
+
+
+//=============================================================================
+// Excluding dead regions.
+//=============================================================================
+bool TbEffPur::globalCutPosition(Gaudi::XYZPoint pGlobal)
+{
+	if (pGlobal.x() < m_xLow + m_edgeVetoDistance) return false;
+	else if (pGlobal.x() > m_xUp - m_edgeVetoDistance) return false;
+	else if (pGlobal.y() < m_yLow + m_edgeVetoDistance) return false;
+	else if	(pGlobal.y() > m_yUp - m_edgeVetoDistance) return false;
+  return true; // Inside.
+}
+
+
+//=============================================================================
+// Excluding dead regions.
+//=============================================================================
+bool TbEffPur::outsideDUT(Gaudi::XYZPoint interceptUG)
+{
+	const auto interceptUL = geomSvc()->globalToLocal(interceptUG, m_DUTindex);
+	if (interceptUL.x() < 0 + m_edgeVetoDistance ||
+			interceptUL.x() > 14.08 - m_edgeVetoDistance ||
+			interceptUL.y() < 0 + m_edgeVetoDistance||
+			interceptUL.y() > 14.08 - m_edgeVetoDistance) return true;
+	return false;
+}
+
+
+
+//=============================================================================
+// Viewer output.
+//=============================================================================
+//=============================================================================
+// Viewer output.
+//=============================================================================
+//=============================================================================
+// Viewer output.
+//=============================================================================
+
+void TbEffPur::outputDeadRegion(unsigned int col, unsigned int row) {
+	std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat", std::ofstream::app);
+	std::string outputLine;
+	for (int irow = std::max(int(row-m_deadAreaRadius), 0);
+  		irow < std::min(int(row+m_deadAreaRadius+1), m_nDUTpixels); irow++) {
+  	for (int icol = std::max(int(col-m_deadAreaRadius), 0);
+  		icol < std::min(int(col+m_deadAreaRadius+1), m_nDUTpixels); icol++) {
+
+
+			outputLine = "DeadPixel ";
+			const double xLocal = (col-icol) * m_pitch; // Dont want the middle!
+			const double yLocal = (row-irow) * m_pitch; // Dont want the middle!
+			Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+
+			Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			Gaudi::XYZPoint posn2(pLocal.x() + 0.055, pLocal.y(), 0.);
+			posn = geomSvc()->localToGlobal(posn2, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			Gaudi::XYZPoint posn3(pLocal.x() + 0.055, pLocal.y()+0.055, 0.);
+			posn = geomSvc()->localToGlobal(posn3, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y()+0.055, 0.);
+			posn = geomSvc()->localToGlobal(posn4, m_DUTindex);
+			outputLine += std::to_string(posn.x()) + " ";
+			outputLine += std::to_string(posn.y()) + " ";
+			outputLine += std::to_string(posn.z()) + " ";
+
+			outputLine += "\n";
+			myfile << outputLine;
+  	}
+	}
+	myfile.close();
+}
+
+
+//=============================================================================
+// Viewer output.
+//=============================================================================
+
+void TbEffPur::outputViewerData()
+{
+  std::ofstream myfile;
+  myfile.open("/afs/cern.ch/user/d/dsaunder/KeplerViewerData.dat", std::ofstream::app);
+  std::string outputLine;
+//
+//  // First output the chips.
+//  for (unsigned int i=0; i<m_nPlanes; i++) {
+//  	outputLine = "Chip ";
+//  	Gaudi::XYZPoint posn1(0., 14.08, 0.);
+//    Gaudi::XYZPoint posn = geomSvc()->localToGlobal(posn1, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    Gaudi::XYZPoint posn2(14.08, 14.08, 0.);
+//    posn = geomSvc()->localToGlobal(posn2, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    Gaudi::XYZPoint posn3(14.08, 0., 0.);
+//    posn = geomSvc()->localToGlobal(posn3, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    Gaudi::XYZPoint posn4(0., 0., 0.);
+//    posn = geomSvc()->localToGlobal(posn4, i);
+//    outputLine += std::to_string(posn.x()) + " ";
+//    outputLine += std::to_string(posn.y()) + " ";
+//    outputLine += std::to_string(posn.z()) + " ";
+//
+//    outputLine += "\n";
+//    myfile << outputLine;
+//  }
+
+
+  // Clusters.
+  auto ic = m_clusters->begin();
+	const auto end = m_clusters->end();
+	for (; ic != end; ++ic) {
+		outputLine = "Cluster ";
+		outputLine += std::to_string((*ic)->x()) + " ";
+		outputLine += std::to_string((*ic)->y()) + " ";
+		outputLine += std::to_string((*ic)->z()) + " ";
+		outputLine += std::to_string((*ic)->htime()) + " ";
+
+		// if ((*ic)->endCluster() && (*ic)->vertexed()) outputLine += "5 \n";
+		//if ((*ic)->vertexed()) outputLine += "4 \n";
+//			else if ((*ic)->endCluster()) outputLine += "3 \n";
+		if ((*ic)->associated()) outputLine += "2 \n";
+//			else if ((*ic)->volumed()) outputLine += "1 \n";
+
+		else {
+			outputLine += "0 \n";
+		}
+		myfile << outputLine;
+	}
+
+	outputLine = "CentralRegion ";
+	outputLine += std::to_string(m_xLow) + " ";
+	outputLine += std::to_string(m_xUp) + " ";
+	outputLine += std::to_string(m_yLow) + " ";
+	outputLine += std::to_string(m_yUp) + " ";
+	outputLine += std::to_string(geomSvc()->module(m_DUTindex)->z()) + " ";
+	myfile << outputLine;
+
+//		// Its hits.
+//		for (auto hit : (*ic)->hits()) {
+//			outputLine = "Pixel ";
+//			const double xLocal = (hit->col()) * m_pitch; // Dont want the middle!
+//			const double yLocal = (hit->row()) * m_pitch; // Dont want the middle!
+//			Gaudi::XYZPoint pLocal(xLocal, yLocal, 0.);
+//
+//			Gaudi::XYZPoint posn = geomSvc()->localToGlobal(pLocal, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			Gaudi::XYZPoint posn2(pLocal.x() + 0.055, pLocal.y(), 0.);
+//			posn = geomSvc()->localToGlobal(posn2, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			Gaudi::XYZPoint posn3(pLocal.x() + 0.055, pLocal.y()+0.055, 0.);
+//			posn = geomSvc()->localToGlobal(posn3, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			Gaudi::XYZPoint posn4(pLocal.x(), pLocal.y()+0.055, 0.);
+//			posn = geomSvc()->localToGlobal(posn4, i);
+//			outputLine += std::to_string(posn.x()) + " ";
+//			outputLine += std::to_string(posn.y()) + " ";
+//			outputLine += std::to_string(posn.z()) + " ";
+//
+//			outputLine += std::to_string(hit->htime()) + " ";
+//			outputLine += std::to_string(hit->ToT()) + " ";
+//
+//			outputLine += "\n";
+//			myfile << outputLine;
+//		}
+
+  myfile.close();
+}
+
+
+//=============================================================================
+// END
+//=============================================================================
diff --git a/TbAnalysis/src/TbEffPur.h b/TbAnalysis/src/TbEffPur.h
new file mode 100644
index 0000000..41083b5
--- /dev/null
+++ b/TbAnalysis/src/TbEffPur.h
@@ -0,0 +1,142 @@
+#ifndef TB_EFFICIENCY_H
+#define TB_EFFICIENCY_H 1
+
+// AIDA
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+#include "TEfficiency.h"
+#include "AIDA/IAxis.h"
+
+#include "AIDA/IProfile2D.h"
+#include "AIDA/IProfile1D.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+#include "Event/TbVertex.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/ITbClusterFinder.h"
+
+#include "TFile.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+#include "TH2D.h"
+
+
+/** @class TbEffPur TbEffPur.h
+ *
+ *  @author Dan Saunders
+ */
+
+class TbEffPur : public TbAlgorithm {
+ public:
+  TbEffPur(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TbEffPur() {}
+
+  // Gaudi methods.
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  // Members.
+  std::string m_trackLocation;
+  std::string m_vertexLocation;
+  std::string m_clusterLocation;
+  unsigned int m_DUTindex;
+  LHCb::TbTracks * m_tracks;
+  LHCb::TbClusters * m_clusters;
+  ITbTrackFit * m_trackFit;
+  double m_pitch;
+  int m_nDUTpixels;
+
+
+  unsigned int m_nTracks;
+  unsigned int m_nClusters;
+  unsigned int m_nTrackedClusters;
+
+  unsigned int m_nClustersPassedCentral;
+  unsigned int m_nTracksCentral;
+
+  unsigned int m_nClustersPassedCorner;
+  unsigned int m_nTracksCorner;
+
+  double m_eff;
+  double m_pur;
+  double m_telescopeClusterVetoDelT;
+  double m_edgeVetoDistance;
+
+  TEfficiency * m_effs;
+  TEfficiency * m_purs;
+  TEfficiency * m_effHitmap;
+  TEfficiency * m_purHitmap;
+  TEfficiency * m_effHitmapInterPixel;
+  TEfficiency * m_effHitmapInterPixelTriple;
+  TEfficiency * m_purHitmapInterPixel;
+  TEfficiency * m_effX;
+  TEfficiency * m_effY;
+  std::vector<TEfficiency*> m_effHitmapInterPixelVsSizes;
+
+  unsigned int m_deadAreaRadius;
+  double m_xLow;
+  double m_xUp;
+  double m_yLow;
+  double m_yUp;
+  double m_probCut;
+
+  double m_rResidualCut;
+  double m_tResidualCut;
+
+  unsigned int m_chargeCutLow;
+  unsigned int m_chargeCutUp;
+
+  unsigned int m_litSquareSide;
+  unsigned int m_nEvent;
+  bool m_viewerOutput;
+  unsigned int m_viewerEvent;
+  double m_tGap;
+  double m_correlationTimeWindow;
+  bool m_applyVeto;
+  std::vector<bool> * m_trackAssociated;
+
+  // Plots.
+  AIDA::IHistogram2D * m_remainsCorrelationsX;
+  AIDA::IHistogram2D * m_remainsCorrelationsY;
+  AIDA::IHistogram2D * m_remainsDifferencesXY;
+  AIDA::IHistogram2D * m_clusterRemainsPositionsGlobal;
+  AIDA::IHistogram2D * m_trackRemainsPositionsGlobal;
+  AIDA::IHistogram2D * m_clusterRemainsPositionsLocal;
+  AIDA::IHistogram2D * m_trackRemainsPositionsLocal;
+  AIDA::IHistogram2D * m_vetoTracksHitmap;
+  AIDA::IHistogram2D * m_vetoClustersHitmap;
+  AIDA::IHistogram2D * m_timeResidualVsColumn;
+
+
+  // Methods.
+  void effPur();
+  void trackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks);
+  bool matchTrackToCluster(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track);
+  double getRadialSeparation(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track);
+  bool litPixel(LHCb::TbCluster * cluster,
+		LHCb::TbTrack * track);
+  bool globalCutPosition(Gaudi::XYZPoint);
+  void outputViewerData();
+  void applyVeto(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks);
+  void correlateRemains(std::vector<LHCb::TbTrack*> * cutTracks,
+  		std::vector<LHCb::TbCluster*> * cutClusters);
+  void fillTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks, double tlow, double tup);
+  void fillAllTrackClusters(std::vector<LHCb::TbCluster*> * cutClusters,
+		std::vector<LHCb::TbTrack*> * cutTracks);
+  void outputDeadRegion(unsigned int, unsigned int);
+  bool outsideDUT(Gaudi::XYZPoint);
+  bool interceptDeadPixel(Gaudi::XYZPoint);
+};
+#endif
diff --git a/TbAnalysis/src/TbEfficiency.cpp b/TbAnalysis/src/TbEfficiency.cpp
new file mode 100644
index 0000000..0851f86
--- /dev/null
+++ b/TbAnalysis/src/TbEfficiency.cpp
@@ -0,0 +1,216 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+// TODO (hschindl)
+#include "GaudiKernel/IEventProcessor.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbEfficiency.h"
+
+DECLARE_ALGORITHM_FACTORY(TbEfficiency)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbEfficiency::TbEfficiency(const std::string& name,
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+			m_nTracksConsidered(0),
+			m_nTracksAssociated(0),
+			m_event(0),
+			m_pitch(0.055) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("DUT", m_dut = 4);
+  declareProperty("CheckHitDUT", m_checkHitDUT = true);
+  declareProperty("CheckHitAlivePixel", m_checkHitAlivePixel = true);
+  declareProperty("PointingResAllowance", m_pointingResAllowance = 0.01);
+  declareProperty("PointingResAllowanceDeadPixel", m_pointingResAllowance_deadPixels = 1);
+  declareProperty("TakeDeadPixelsFromFile", m_takeDeadPixelsFromFile = true);
+  declareProperty("nTotalTracks", m_nTotalTracks = 0);
+  declareProperty("MaxChi", m_maxChi = 0);
+}
+
+//=============================================================================
+// Finalization
+//=============================================================================
+StatusCode TbEfficiency::finalize() {
+
+  info() <<"DUT Efficiency: "<<m_nTracksAssociated/(1.*m_nTracksConsidered)<<endmsg;
+  info()<<"nTracksAssociated: "<<m_nTracksAssociated<<endmsg;
+  info()<<"nTracksConsidered: "<<m_nTracksConsidered<<endmsg;
+  info()<<"cf: "<<m_eff->GetEfficiency(1)<<"\t ±"<<m_eff->GetEfficiencyErrorLow(1)<<endmsg;
+
+  TFile * f = new TFile("EfficiencyResults.root", "RECREATE");
+  h_row->Write();
+  h_col->Write();
+  m_eff->Write();
+  h_hitmap->Write();
+  h_pixel->Write();
+  h_pixel2x2->Write();
+
+  m_eff->CreateGraph()->Write();
+  h_hitmap->CreateHistogram()->Write();
+  h_col->CreateGraph()->Write();
+  h_row->CreateGraph()->Write();
+  h_pixel->CreateHistogram()->Write();
+  h_pixel2x2->CreateHistogram()->Write();
+  f->Close();
+
+  return TbAlgorithm::finalize();
+}
+
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbEfficiency::initialize() {
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  uint nBins = 80;
+  h_row = new TEfficiency("row", "row", 256, 0, 256);
+  h_col = new TEfficiency("col", "col", 3*256+2, 0, 3*256+2);
+  m_eff = new TEfficiency("eff", "eff", 1, 0, 1);
+  h_hitmap = new TEfficiency("hitmap", "hitmap", 3*256+2, 0, 3*256+2, 256, 0, 256);
+  h_pixel = new TEfficiency("pixel", "pixel", nBins, 0, m_pitch, nBins, 0, m_pitch);
+  h_pixel2x2 = new TEfficiency("pixel2x2", "pixel2x2", 2*nBins, 0, 2*m_pitch, 2*nBins, 0, 2*m_pitch);
+
+  if (m_takeDeadPixelsFromFile) {
+    TFile * fIn = new TFile("telPlaneRef.root", "READ");
+    const std::string name = "Tb/TbHitMonitor/HitMap/Plane" + std::to_string(m_dut);
+    m_deadPixelMap = (TH2F*)fIn->Get(name.c_str());
+    info() <<"DeadPixelMap name: "<<m_deadPixelMap->GetName()<<endmsg;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbEfficiency::execute() {
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    return Error("No tracks in " + m_trackLocation);
+  }
+
+	// Loop over the tracks.
+	for (LHCb::TbTrack* track : *tracks) {
+		if (m_nTotalTracks != 0 && m_nTracksConsidered >= m_nTotalTracks) {
+			SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+			if (app) app->stopRun();
+			return StatusCode::SUCCESS;
+		}
+
+		// Find the local position of the track intercept with the DUT.
+		const Gaudi::XYZPoint interceptUG = geomSvc()->intercept(track, m_dut);
+		const auto interceptUL = geomSvc()->globalToLocal(interceptUG, m_dut);
+
+		if (!passSelectionCriteria(track, interceptUL)) continue;
+		m_nTracksConsidered++;
+		bool pass = false;
+		if (track->associatedClusters().size() > 0) pass = true;
+
+		int row = interceptUL.y()/m_pitch - 0.5;
+		int col = interceptUL.x()/m_pitch - 0.5;
+
+		h_pixel->Fill(pass, fmod(interceptUL.x(), m_pitch), fmod(interceptUL.y(), m_pitch));
+		h_pixel2x2->Fill(pass, fmod(interceptUL.x(), 2*m_pitch), fmod(interceptUL.y(), 2*m_pitch));
+		h_row->Fill(pass, row);
+		h_col->Fill(pass, col);
+		h_hitmap->Fill(pass, col, row);
+		m_eff->Fill(pass, 0);
+		if (pass) m_nTracksAssociated++;
+		if (!pass && m_event == 1050) info()<<track->htime()<<endmsg;
+	}
+
+	m_event++;
+  return StatusCode::SUCCESS;
+}
+
+
+//=============================================================================
+
+bool TbEfficiency::passSelectionCriteria(LHCb::TbTrack * track, Gaudi::XYZPoint interceptUL)
+{
+	if (m_maxChi > 0 && track->chi2PerNdof() > m_maxChi) return false;
+	if (m_checkHitDUT && !passedThroughDUT(interceptUL)) {
+		return false;
+	}
+	if (m_checkHitAlivePixel && !passedThroughAlivePixel(interceptUL)) return false;
+
+	return true;
+}
+
+
+//=============================================================================
+
+bool TbEfficiency::passedThroughDUT(Gaudi::XYZPoint interceptUL)
+{
+	double xLow = 0.0 + m_pointingResAllowance;
+	double yLow = 0.0 + m_pointingResAllowance;
+	double yUp = 14.08 - m_pointingResAllowance;
+	double xUp = 14.08;
+
+	if (geomSvc()->modules().at(m_dut)->nChips() == 1)
+		xUp = 14.08 - m_pointingResAllowance;
+	else if (geomSvc()->modules().at(m_dut)->nChips() == 3)
+		xUp = 42.35 - m_pointingResAllowance;
+	else error()<<"Unknown device!"<<endmsg;
+
+	if (interceptUL.x() < xLow ||
+			interceptUL.x() > xUp ||
+			interceptUL.y() < yLow ||
+			interceptUL.y() > yUp) {
+		counter("nTracksNotStrikingDUT") += 1;
+		return false;
+	}
+	return true;
+}
+
+
+//=============================================================================
+
+bool TbEfficiency::passedThroughAlivePixel(Gaudi::XYZPoint interceptUL)
+{
+	int row = interceptUL.y()/0.055 - 0.5;
+  int col = interceptUL.x()/0.055 - 0.5;
+  int one = 1;
+  for (int iRow = row - m_pointingResAllowance_deadPixels;
+  		iRow != row+m_pointingResAllowance_deadPixels+one; iRow++) {
+  	for (int iCol = col - m_pointingResAllowance_deadPixels;
+  			iCol != col + m_pointingResAllowance_deadPixels+one; iCol++) {
+
+  		int colLim;
+  		if (geomSvc()->modules().at(m_dut)->nChips() == 3) colLim = 3*256+2;
+  		else colLim = 256;
+  		if (iRow < 0 || iCol < 0 || iRow >= 256 || iCol >= colLim) continue;
+			if (pixelSvc()->isMasked(pixelSvc()->address(iCol, iRow), m_dut)) {
+				counter("nTracksStrikingMaskedPixels") += 1;
+				return false;
+			}
+			else if (m_takeDeadPixelsFromFile && m_deadPixelMap->GetBinContent(iCol, iRow) == 0) {
+				counter("nTracksStrikingDeadPixels") += 1;
+				return false;
+			}
+
+  	}
+  }
+  return true;
+}
+
+
+//=============================================================================
diff --git a/TbAnalysis/src/TbEfficiency.h b/TbAnalysis/src/TbEfficiency.h
new file mode 100644
index 0000000..190b975
--- /dev/null
+++ b/TbAnalysis/src/TbEfficiency.h
@@ -0,0 +1,56 @@
+#ifndef TB_EFFICIENCY_H
+#define TB_EFFICIENCY_H 1
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "AIDA/IHistogram1D.h"
+#include "TEfficiency.h"
+#include "TH2.h"
+#include "TFile.h"
+#include "TGraphAsymmErrors.h"
+
+/** @class TbEfficiency TbEfficiency.h
+ *
+ */
+
+class TbEfficiency : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbEfficiency(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbEfficiency() {}
+
+  bool m_checkHitDUT;
+  bool m_checkHitAlivePixel;
+  double m_pointingResAllowance;
+  uint m_nTracksConsidered;
+  uint m_nTracksAssociated;
+  uint m_event;
+  int m_pointingResAllowance_deadPixels;
+  bool m_takeDeadPixelsFromFile;
+  TH2F * m_deadPixelMap;
+  double m_pitch;
+  uint m_nTotalTracks;
+  double m_maxChi;
+
+  bool passedThroughDUT(Gaudi::XYZPoint interceptUL);
+  bool passedThroughAlivePixel(Gaudi::XYZPoint interceptUL);
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();
+  bool passSelectionCriteria(LHCb::TbTrack * track, Gaudi::XYZPoint interceptUL);
+
+  TEfficiency * h_row;
+  TEfficiency * h_col;
+  TEfficiency * m_eff;
+  TEfficiency * h_hitmap;
+  TEfficiency * h_pixel;
+  TEfficiency * h_pixel2x2;
+
+ private:
+  uint m_dut;
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+};
+#endif
diff --git a/TbAnalysis/src/TbResolutionMonitor.cpp b/TbAnalysis/src/TbResolutionMonitor.cpp
new file mode 100644
index 0000000..159301a
--- /dev/null
+++ b/TbAnalysis/src/TbResolutionMonitor.cpp
@@ -0,0 +1,107 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbResolutionMonitor.h"
+
+DECLARE_ALGORITHM_FACTORY(TbResolutionMonitor)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbResolutionMonitor::TbResolutionMonitor(const std::string& name, 
+                                         ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+
+  declareProperty("DUTs", m_duts);
+}
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbResolutionMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbResolutionMonitor::execute() {
+
+  // Grab the tracks.
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) {
+    error() << "No tracks in " << m_trackLocation << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  for (const auto dut : m_duts) {
+    // Get the clusters for this plane.
+    const std::string clusterLocation = m_clusterLocation + std::to_string(dut);
+    const LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusterLocation);
+    for (const LHCb::TbCluster* cluster : *clusters) {
+      plot(cluster->charge(), "ChargeAll", "ChargeAll", 0., 50000., 200);
+    }
+    if (!clusters) continue;
+    // Loop over the tracks.
+    for (const LHCb::TbTrack* track : *tracks) {
+      // Cut on track quality.
+      if (track->chi2PerNdof() > 20.) continue;
+      const Gaudi::XYZPoint pGlobal = geomSvc()->intercept(track, dut);
+      const auto pLocal = geomSvc()->globalToLocal(pGlobal, dut);
+      if (pLocal.x() < 0. || pLocal.y() < 0.) continue;
+      const double fcol = pLocal.x() / Tb::PixelPitch;
+      const double frow = pLocal.y() / Tb::PixelPitch;
+      const int col = int(fcol);
+      const int row = int(frow);
+      if (col > 255 || row > 255) continue;
+      // Calculate inter-pixel coordinates.
+      const double xCell = 1.e3 * (fcol - col) * Tb::PixelPitch;
+      const double yCell = 1.e3 * (frow - row) * Tb::PixelPitch;
+      const LHCb::TbCluster* match = NULL;
+      for (const LHCb::TbCluster* cluster : *clusters) {
+        const double dt = cluster->htime() - track->htime();
+        if (fabs(dt) > 200.) continue;
+        const double dx = cluster->xloc() - pLocal.x();
+        const double dy = cluster->yloc() - pLocal.y();
+        if (fabs(dx) < 0.15 && fabs(dy) < 0.15) {
+          match = cluster;
+          break;
+        }
+      }
+      plot2D(xCell, yCell, "NTracks", "NTracks",
+             0., 55., 0., 55., 9, 9);
+      if (!match) continue;
+      plot2D(xCell, yCell, "NClusters", "NClusters",
+             0., 55., 0., 55., 9, 9);
+      plot(match->x() - pGlobal.x(), "ResGlobalX", "ResGlobalX", -0.2, 0.2, 100);
+      plot(match->y() - pGlobal.y(), "ResGlobalY", "ResGlobalY", -0.2, 0.2, 100);
+      plot(match->xloc() - pLocal.x(), "ResLocalX", "ResLocalX", -0.2, 0.2, 100);
+      plot(match->yloc() - pLocal.y(), "ResLocalY", "ResLocalX", -0.2, 0.2, 100);
+      plot(match->htime() - track->htime(), "ResTime", "ResTime", -200., 200., 400); 
+      const unsigned int cls = match->size();
+      if (cls > 4) continue;
+      const std::string title = "InterceptCls" + std::to_string(cls);
+      plot2D(xCell, yCell, title, title,
+             0., 55., 0., 55., 50, 50);
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
diff --git a/TbAnalysis/src/TbResolutionMonitor.h b/TbAnalysis/src/TbResolutionMonitor.h
new file mode 100644
index 0000000..80162f3
--- /dev/null
+++ b/TbAnalysis/src/TbResolutionMonitor.h
@@ -0,0 +1,25 @@
+#pragma once
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbResolutionMonitor TbResolutionMonitor.h
+ *
+ */
+
+class TbResolutionMonitor : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbResolutionMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbResolutionMonitor() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<unsigned int> m_duts;
+  std::string m_trackLocation;
+  std::string m_clusterLocation;
+
+};
diff --git a/TbAnalysis/src/TbTimewalkMonitor.cpp b/TbAnalysis/src/TbTimewalkMonitor.cpp
new file mode 100644
index 0000000..9f66b8f
--- /dev/null
+++ b/TbAnalysis/src/TbTimewalkMonitor.cpp
@@ -0,0 +1,211 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbTimewalkMonitor.h"
+
+// ROOT
+#include "TH1D.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbTimewalkMonitor)
+
+  //=============================================================================
+  // Standard constructor
+  //=============================================================================
+TbTimewalkMonitor::TbTimewalkMonitor(const std::string& name, 
+    ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator) {
+
+    declareProperty("TrackLocation",
+        m_trackLocation = LHCb::TbTrackLocation::Default);
+    declareProperty("WidthMin", m_widthMin = 37 );
+    declareProperty("WidthMax", m_widthMax = 42 );
+  }
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbTimewalkMonitor::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Book the histograms.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string plane = std::to_string(i);
+    const std::string title = geomSvc()->modules().at(i)->id();
+    m_space.push_back(bookProfile1D("SpatialResidual/Plane"+plane,title,-0.5,255.5,256));
+
+    m_spd2D.push_back(book2D("spd2D/Plane"+plane,title,-0.5,255.5,256,-100,100,20));
+    m_twd.push_back(book2D("twd/Plane"+plane,title,1.,101.,100,0.,62.5,40));
+    m_twdQ.push_back(book2D("twdQ/Plane"+plane,title,1000,10000,100,0.,62.5,40));
+    m_twdQL.push_back(book2D("twdQL/Plane"+plane,title,1000,10000,100,0.,62.5,40));
+    m_twdQR.push_back(book2D("twdQR/Plane"+plane,title,1000,10000,100,0.,62.5,40));
+
+    setAxisLabels( m_twd[i], "ToT", "#Delta t [ns]");
+
+    m_twdL.push_back(book2D("twdL/Plane"+plane,title,0.,100.,100,0.,62.5,40));
+    m_twdR.push_back(book2D("twdR/Plane"+plane,title,0.,100.,100,0.,62.5,40));
+    m_LRSYNC.emplace_back(bookProfile1D("LR_SYNC/Plane"+plane,title,-0.5,255.5,256));
+    m_UDSYNC.emplace_back(bookProfile1D("UD_SYNC/Plane"+plane,title,-0.5,255.5,256));
+
+    m_quad.emplace_back(bookProfile1D("QUAD/Plane"+plane,title,-0.5,255.5,256));
+
+    m_inscol.emplace_back(bookProfile1D("Scol/Plane"+plane,title,-0.5,127.5,128));
+    m_interscol.emplace_back(bookProfile1D("InterScol/Plane"+plane,title,-0.5,127.5,128));
+
+    m_timewalk.push_back(bookProfile1D("Timewalk/Plane"+plane,title, 1., 401., 400));
+    m_dtDist.push_back( book1D( "dtDist/Plane"+plane,title, 0., 90., 58 ) );
+    m_cDist.push_back( book1D( "cDist/Plane"+plane,title,0.,90.,58 ) );
+    m_timewalkQ.push_back(bookProfile1D("TimewalkQ/Plane"+plane,title,0,20000,200));
+    setAxisLabels(m_timewalkQ[i], "charge [e^{-}]","#Delta t [ns]");
+    setAxisLabels(m_timewalk[i], "ToT", "#Delta t [ns]");
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TbTimewalkMonitor::finalize() {
+
+  for( unsigned int i = 0 ; i < m_nPlanes; ++i ){
+    TH1D* tdist = Gaudi::Utils::Aida2ROOT::aida2root( m_dtDist[i] );
+    AIDA::IHistogram1D* cdist = m_cDist[i];
+    int total = 0;    
+    for (int i=0;i<tdist->GetNbinsX();i++)
+    {
+      total += tdist->GetBinContent(i);
+      cdist->fill( tdist->GetBinCenter(i) , total /tdist->GetEntries() ) ;
+    }    
+  }
+  return StatusCode::SUCCESS; 
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTimewalkMonitor::execute() {
+
+  // Grab the tracks.
+
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) return StatusCode::SUCCESS; 
+  for (const LHCb::TbTrack* track : *tracks) {
+ //   info() << track << endmsg; 
+    const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters();
+    const auto ref = std::min_element(
+        clusters.begin(), clusters.end(),
+        [](const LHCb::TbCluster* h1,
+          const LHCb::TbCluster* h2) { return h1->htime() < h2->htime(); });
+    const double tref = (*ref)->htime();
+    const double syncRef = (*clusters.rbegin())->htime();
+    unsigned int p = (*clusters.rbegin())->plane();
+
+    for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it){
+
+      auto hits = (*it)->hits();
+      for (const auto hit : hits) {
+        if( p==5 ){
+          m_space[(*it)->plane()]->fill( hit->col(), hit->htime() - syncRef );
+          m_spd2D[(*it)->plane()]->fill( hit->col(), hit->htime() - syncRef );
+        }
+        m_timewalk[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        m_twd[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        m_timewalkQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        m_twdQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        m_dtDist[(*it)->plane()]->fill( hit->htime() - tref );   
+      }
+      if( (*it)->size() == 2 ){
+        auto minmax = std::minmax_element(hits.begin(), hits.end(),[](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+        if( (*minmax.first)->col()  != (*minmax.second)->col() ){
+          m_twdL[(*it)->plane()]->fill( (*minmax.first)->ToT(), (*minmax.first)->htime() - tref );
+          m_twdR[(*it)->plane()]->fill( (*minmax.second)->ToT(), (*minmax.second)->htime() - tref );
+          m_twdQL[(*it)->plane()]->fill( (*minmax.first)->charge(), (*minmax.first)->htime() - tref );
+          m_twdQR[(*it)->plane()]->fill( (*minmax.second)->charge(), (*minmax.second)->htime() - tref );
+        }
+      }
+    }
+    const SmartRefVector<LHCb::TbCluster>& associatedClusters  = track->associatedClusters();
+
+    for (auto it = associatedClusters.cbegin(), end = associatedClusters.cend(); it != end; ++it){
+      auto hits = (*it)->hits();
+      //info() << "Filling associated clusters for " << track << endmsg; 
+      for (const auto hit : (*it)->hits()) {
+        m_timewalk[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        m_twd[(*it)->plane()]->fill(hit->ToT(), hit->htime() - tref);
+        //m_twdQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        //m_dtDist[(*it)->plane()]->fill( hit->htime() - tref );
+        m_timewalkQ[(*it)->plane()]->fill(hit->charge(), hit->htime() - tref );
+        //if( (*it)->size() == 1 ) m_timewalkOneHit[(*it)->plane()]->fill(hit->ToT(), ( hit->htime() - tref ));
+        //if( (*it)->size() == 2 ) m_timewalkTwoHit[(*it)->plane()]->fill(hit->ToT(), ( hit->htime() - tref ));
+      }
+      /*
+      if( (*it)->size() == 2 ){
+        auto minmax = std::minmax_element(hits.begin(), hits.end(),[](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+        if( (*minmax.first)->col()  != (*minmax.second)->col() ){
+          m_twdL[(*it)->plane()]->fill( (*minmax.first)->ToT(), (*minmax.first)->htime() - tref );
+          m_twdR[(*it)->plane()]->fill( (*minmax.second)->ToT(), (*minmax.second)->htime() - tref );
+          m_twdQL[(*it)->plane()]->fill( (*minmax.first)->charge(), (*minmax.first)->htime() - tref );
+          m_twdQR[(*it)->plane()]->fill( (*minmax.second)->charge(), (*minmax.second)->htime() - tref );
+        }
+      }
+      */
+      //info() << "Filled associated clusters " << endmsg; 
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+/*
+   for(unsigned int plane=0;plane<m_nPlanes; ++plane ){
+   const LHCb::TbClusters* clusters = 
+   getIfExists<LHCb::TbClusters>(LHCb::TbClusterLocation::Default+std::to_string(plane));
+   for( auto& cluster : *clusters ){
+   if( cluster->size() == 2 ){
+   auto hits = cluster->hits();
+   auto minmax = std::minmax_element(hits.begin(), hits.end(),
+   [](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+   const LHCb::TbHit* left = (*minmax.first);
+   const LHCb::TbHit* right = (*minmax.second);
+   if( left->col() != right->col() ){
+   m_LRSYNC[plane]->fill( left->col() , left->htime() - right->htime() );
+   if( int(left->col() /2 ) == int(right->col() /2 ) ) 
+   m_inscol[plane]->fill( int(left->col()/2) , left->htime() - right->htime() );
+   else 
+   m_interscol[plane]->fill( int(left->col()/2) , left->htime() - right->htime() );
+   }
+   else {
+   minmax = std::minmax_element(hits.begin(), hits.end(),
+   [](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->row() < h2->row(); });
+   m_UDSYNC[plane]->fill( (*minmax.first)->row(), 
+   (*minmax.first)->htime() - (*minmax.second)->htime());
+   }
+   }
+   if( cluster->size() == 4 ){
+   auto hits = cluster->hits();
+   auto minmax = std::minmax_element(hits.begin(), hits.end(),
+   [](LHCb::TbHit* h1, LHCb::TbHit* h2) { return h1->col() < h2->col(); });
+   const LHCb::TbHit* left = (*minmax.first);
+   const LHCb::TbHit* right = (*minmax.second);
+   if( left->col() == right->col() + 4 ){
+   m_quad[plane]->fill( left->col() , left->htime() - right->htime() );
+   }
+   }
+
+   }
+   }
+   return StatusCode::SUCCESS;
+   }
+   */
diff --git a/TbAnalysis/src/TbTimewalkMonitor.h b/TbAnalysis/src/TbTimewalkMonitor.h
new file mode 100644
index 0000000..4acaeb9
--- /dev/null
+++ b/TbAnalysis/src/TbTimewalkMonitor.h
@@ -0,0 +1,53 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IProfile1D.h"
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTimewalkMonitor TbTimewalkMonitor.h
+ *
+ */
+
+class TbTimewalkMonitor : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbTimewalkMonitor(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTimewalkMonitor() {}
+  virtual StatusCode finalize(); 
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::string m_trackLocation;
+  unsigned int m_widthMax, m_widthMin;
+  std::vector<AIDA::IProfile1D*> m_timewalk;
+  std::vector<AIDA::IProfile1D*> m_timewalkOneHit;
+  std::vector<AIDA::IProfile1D*> m_timewalkTwoHit;
+  std::vector<AIDA::IProfile1D*> m_timewalkQ;
+  std::vector<AIDA::IHistogram1D*> m_dtDist;
+  std::vector<AIDA::IHistogram1D*> m_cDist;
+  
+  std::vector<AIDA::IProfile1D*> m_space;
+  std::vector<AIDA::IHistogram1D*> m_dt;
+  std::vector<AIDA::IProfile1D*> m_LRSYNC; 
+ 
+  std::vector<AIDA::IProfile1D*> m_UDSYNC;
+  std::vector<AIDA::IProfile1D*> m_quad;
+
+  std::vector<AIDA::IProfile1D*> m_inscol;
+  std::vector<AIDA::IProfile1D*> m_interscol;
+
+  std::vector<AIDA::IHistogram2D*> m_twd;
+  std::vector<AIDA::IHistogram2D*> m_twdQ;
+  std::vector<AIDA::IHistogram2D*> m_twdQL;
+  std::vector<AIDA::IHistogram2D*> m_twdQR;
+  std::vector<AIDA::IHistogram2D*> m_spd2D;
+  
+  std::vector<AIDA::IHistogram2D*> m_twdL;
+  std::vector<AIDA::IHistogram2D*> m_twdR;
+  
+};
diff --git a/TbAnalysis/src/TbVertexing.cpp b/TbAnalysis/src/TbVertexing.cpp
new file mode 100644
index 0000000..715a011
--- /dev/null
+++ b/TbAnalysis/src/TbVertexing.cpp
@@ -0,0 +1,136 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/HistoLabels.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbModule.h"
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbVertexing.h"
+
+// ROOT
+#include "TH1D.h"
+
+using namespace Gaudi::Utils::Histos;
+
+DECLARE_ALGORITHM_FACTORY(TbVertexing)
+
+  template <class TYPE>
+  class itlowerBound {
+    public:
+      bool operator()(TYPE lhs, const double t) const { return (*lhs)->htime() < t; }
+  };
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbVertexing::TbVertexing(const std::string& name, 
+    ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator) {
+    declareProperty("TimeWindow",m_timeWindow);
+    declareProperty("MaxDoca2",m_maxDoca2);
+    declareProperty("TrackLocation", m_trackLocation = LHCb::TbTrackLocation::Default);
+  }
+
+//=============================================================================
+// Initialization
+//=============================================================================
+StatusCode TbVertexing::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  if( m_trackFit == NULL ){
+    error() << "Failed to initialise trackfit" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Vertices");
+  // Check if already booked.
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Vertices",
+      CLID_ColumnWiseTuple, "nTuple of Vertices");
+  nt->addItem("nPlanes", m_index, 0, 10);
+  nt->addIndexedItem("X", m_index, m_vtxX);
+  nt->addIndexedItem("Y", m_index, m_vtxY);
+  nt->addIndexedItem("Z", m_index, m_vtxZ);
+  nt->addItem("Matched", m_matched );
+ // nt->addItem("Tk1Size",m_tkSize1);
+ // nt->addItem("Tk2Size",m_tkSize2);
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TbVertexing::finalize() {
+
+  return StatusCode::SUCCESS; 
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbVertexing::execute() {
+
+  // Grab the tracks.
+
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (tracks) {
+    for( auto& track1 : *tracks ){
+
+      const double tMin = track1->htime() - m_timeWindow;
+      const double tMax = track1->htime() + m_timeWindow;
+      auto track2 = std::lower_bound(tracks->begin(),
+          tracks->end(),
+          tMin, lowerBound<const LHCb::TbTrack*>());
+
+      for(; track2 != tracks->end() && (*track2)->htime() < tMax ; ++track2 ){
+        if( track1 == *track2 ) continue; 
+        const double DOCA = doca2(track1,*track2);
+        if( DOCA > m_maxDoca2 ) continue;
+        /// track separation ///
+        const double avgX = ( track1->firstState().tx() + (*track2)->firstState().tx() ) /2.;
+        const double avgY = ( track1->firstState().ty() + (*track2)->firstState().ty() ) /2.;
+
+        const double dt = pow ( ( track1->firstState().tx() - (*track2)->firstState().tx() ) / avgX, 2.0 ) +
+          pow ( ( ( track1->firstState().ty() - (*track2)->firstState().ty() ) ) / avgY , 2.0 ) ; 
+        auto chi2_pos = vertexPosition( {track1,*track2} );
+        plot( sqrt(DOCA), "DOCA", 0, 0.5, 100 ); /// 500 micron 
+        plot( dt, "Angle", -2., 2., 1000);
+        plot( chi2_pos[0]  , "VertexChi2_X",0.,14.,100);
+        plot( chi2_pos[1]  , "VertexChi2_Y",0.,14.,100);
+        plot( chi2_pos[2]  , "VertexChi2_Z",-700.,650.,2500);
+        m_vtxX[0] =  chi2_pos[0];
+        m_vtxY[0] =  chi2_pos[1];
+        m_vtxZ[0] =  chi2_pos[2];
+
+        ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Vertices");
+        m_index = 10;
+        m_matched = matched( track1, *track2 );
+        for( unsigned int plane = 0 ; plane != 9 ; ++plane ){
+          m_trackFit->maskPlane( plane );
+          m_trackFit->fit( track1 );
+          m_trackFit->fit( *track2 );
+          //m_vtxX[plane+1] 
+          auto up = vertexPosition( {track1,*track2});
+          m_vtxX[plane+1] = up[0];
+          m_vtxY[plane+1] = up[1];
+          m_vtxZ[plane+1] = up[2];
+          plot( up[2]  , "VertexChi2_Z_"+std::to_string(plane),-700.,650.,2500);
+          m_trackFit->unmaskPlane(plane);
+        }
+        m_trackFit->fit( track1 );
+        m_trackFit->fit( *track2);
+      }
+    }
+
+  }
+
+  return StatusCode::SUCCESS;
+}
+
diff --git a/TbAnalysis/src/TbVertexing.h b/TbAnalysis/src/TbVertexing.h
new file mode 100644
index 0000000..6fbbca3
--- /dev/null
+++ b/TbAnalysis/src/TbVertexing.h
@@ -0,0 +1,96 @@
+#pragma once
+
+// AIDA
+#include "AIDA/IProfile1D.h"
+#include "AIDA/IHistogram1D.h"
+#include "AIDA/IHistogram2D.h"
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/ITbTrackFit.h"
+#include "Event/TbTrack.h"
+
+#include "TVector3.h"
+#include "TMatrixD.h"
+#include "TVectorD.h"
+
+class TbVertexing : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbVertexing(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbVertexing() {}
+  virtual StatusCode finalize(); 
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  double m_timeWindow;
+  double m_maxDoca2;
+  NTuple::Item<unsigned int> m_index;
+  NTuple::Item<unsigned int> m_matched;
+  NTuple::Item<unsigned int> m_common;
+  NTuple::Array<double> m_vtxX;
+  NTuple::Array<double> m_vtxY;
+  NTuple::Array<double> m_vtxZ;
+  ITbTrackFit* m_trackFit;
+
+  std::string m_trackLocation;
+
+  double doca2( const LHCb::TbTrack* track1, const LHCb::TbTrack* track2 ) const {
+    const TVector3 r1( track1->firstState().x(), track1->firstState().y(), 0. );
+    const TVector3 r2( track2->firstState().y(), track2->firstState().y(), 0. );
+    const TVector3 t1( track1->firstState().tx(), track1->firstState().ty(), 1.);
+    const TVector3 t2( track2->firstState().tx(), track2->firstState().ty(), 1.);
+    
+    const double z0 = - (t1 -t2).Dot( r1 - r2 ) / (t1-t2).Mag2();
+    return (r1-r2).Mag2() + 2*z0*(t1-t2).Dot(r1-r2) + z0*z0*(t1-t2).Mag2();
+  };
+
+  /// checks if has > 3 vertices in the forward direction, with unmatched clusters /// 
+  int matched( const LHCb::TbTrack* track1, const LHCb::TbTrack* track2 ) const {
+    auto clusters1 = track1->clusters();
+    auto clusters2 = track2->clusters();
+    int nCommon = 0;
+    int nMatched = 0;
+    for( auto& cluster1 : clusters1 ){
+      for( auto& cluster2 : clusters2 ){
+        if( cluster1->plane() == cluster2->plane() ){
+          if( cluster1 != cluster2 ) nMatched++;
+          else nCommon++;
+          break;
+        }
+      }
+    }
+    return nMatched;
+  }
+
+  TVectorD vertexPosition( const std::vector<const LHCb::TbTrack*>& tracks ) const {
+    
+    TMatrixD cov(3,3);
+    TVectorD res(3);
+    for( auto& track : tracks ){
+      TVectorD t(3);
+      t[0] = track->firstState().tx();
+      t[1] = track->firstState().ty();
+      t[2] = 1;
+      const double norm = t.Norm2Sqr();
+      TVectorD r(3);
+      r[0] = track->firstState().x();
+      r[1] = track->firstState().y();
+      r[2] = 0;
+      double ip = t[0]*r[0] + t[1]*r[1] + t[2]*r[2];
+
+      res += r - (ip /norm ) * t;
+
+      for( unsigned int i=0;i!=3;++i){  
+        for( unsigned int j=0; j !=3 ;++j){
+          if(i==j) cov[i][j] += 1 - t[i]*t[j] / norm;
+          else cov[i][j] += - t[i]*t[j] / norm;
+        }
+      } 
+    }
+    TMatrixD inv = cov.Invert();
+    return inv * res ; 
+  }
+
+};
diff --git a/TbEvent/.svn/all-wcprops b/TbEvent/.svn/all-wcprops
new file mode 100644
index 0000000..8fee684
--- /dev/null
+++ b/TbEvent/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 51
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/188485/Kepler/trunk/Tb/TbEvent/CMakeLists.txt
+END
diff --git a/TbEvent/.svn/entries b/TbEvent/.svn/entries
new file mode 100644
index 0000000..62a9499
--- /dev/null
+++ b/TbEvent/.svn/entries
@@ -0,0 +1,80 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+xml
+dir
+
+Event
+dir
+
+cmt
+dir
+
+dict
+dir
+
+doc
+dir
+
+src
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+9656d95ac0efada12e7dfceefd2d3a2f
+2015-05-19T09:51:16.878566Z
+188485
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+678
+
diff --git a/TbEvent/.svn/text-base/CMakeLists.txt.svn-base b/TbEvent/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..3e1d575
--- /dev/null
+++ b/TbEvent/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,23 @@
+################################################################################
+# Package: TbEvent
+################################################################################
+gaudi_subdir(TbEvent v2r2)
+
+gaudi_depends_on_subdirs(Event/EventBase
+                         GaudiObjDesc)
+
+find_package(GSL)
+
+include(GaudiObjDesc)
+
+god_build_headers(xml/*.xml)
+
+gaudi_add_library(TbEventLib src/*.cpp
+                  NO_PUBLIC_HEADERS
+                  INCLUDE_DIRS GSL 
+                  LINK_LIBRARIES GSL GaudiKernel)
+
+god_build_dictionary(xml/*.xml
+                     INCLUDE_DIRS GSL Event/EventBase
+                     LINK_LIBRARIES GSL GaudiObjDescLib TbEventLib)
+
diff --git a/TbEvent/CMakeLists.txt b/TbEvent/CMakeLists.txt
new file mode 100644
index 0000000..3e1d575
--- /dev/null
+++ b/TbEvent/CMakeLists.txt
@@ -0,0 +1,23 @@
+################################################################################
+# Package: TbEvent
+################################################################################
+gaudi_subdir(TbEvent v2r2)
+
+gaudi_depends_on_subdirs(Event/EventBase
+                         GaudiObjDesc)
+
+find_package(GSL)
+
+include(GaudiObjDesc)
+
+god_build_headers(xml/*.xml)
+
+gaudi_add_library(TbEventLib src/*.cpp
+                  NO_PUBLIC_HEADERS
+                  INCLUDE_DIRS GSL 
+                  LINK_LIBRARIES GSL GaudiKernel)
+
+god_build_dictionary(xml/*.xml
+                     INCLUDE_DIRS GSL Event/EventBase
+                     LINK_LIBRARIES GSL GaudiObjDescLib TbEventLib)
+
diff --git a/TbEvent/Event/.svn/all-wcprops b/TbEvent/Event/.svn/all-wcprops
new file mode 100644
index 0000000..0909887
--- /dev/null
+++ b/TbEvent/Event/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 57
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/Event
+END
+TbKalmanTrack.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/Event/TbKalmanTrack.h
+END
+TbKalmanNode.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/185530/Kepler/trunk/Tb/TbEvent/Event/TbKalmanNode.h
+END
+TbKalmanPixelMeasurement.h
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/Event/TbKalmanPixelMeasurement.h
+END
diff --git a/TbEvent/Event/.svn/entries b/TbEvent/Event/.svn/entries
new file mode 100644
index 0000000..ad36dcc
--- /dev/null
+++ b/TbEvent/Event/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/Event
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbKalmanTrack.h
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+2fae4ace705051d585d9682d3ef40688
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+876
+
+TbKalmanNode.h
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+14e3b9e0815a43b8bf5c2154e568f4ed
+2015-03-16T20:41:44.561223Z
+185530
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6502
+
+TbKalmanPixelMeasurement.h
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+c1044f5ab833079cd7dd03b1f80e6977
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1942
+
diff --git a/TbEvent/Event/.svn/text-base/TbKalmanNode.h.svn-base b/TbEvent/Event/.svn/text-base/TbKalmanNode.h.svn-base
new file mode 100644
index 0000000..3bd967b
--- /dev/null
+++ b/TbEvent/Event/.svn/text-base/TbKalmanNode.h.svn-base
@@ -0,0 +1,222 @@
+#ifndef TBTRACKFITNODE_H
+#define TBTRACKFITNODE_H 1
+
+// from TbEvent
+#include "Event/TbState.h"
+#include "Event/TbCluster.h"
+#include "Event/ChiSquare.h"
+
+// forward declarations
+namespace LHCb { class TbKalmanTrack; }
+
+namespace LHCb {
+
+/** @class TbKalmanFitNode TbKalmanFitNode.h Event/TbKalmanFitNode.h
+  *
+  *  This File contains the declaration of the TbKalmanFitNode.
+  *
+  *  A TbKalmanFitNode represents a node in the kalman fit.
+  *
+  */
+
+class TbKalmanNode {
+ public:
+  // important note: for the Forward fit, smoothed means
+  // 'classical'. for the backward fit, it means 'bidirectional'.
+  enum FilterStatus {
+    Uninitialized,
+    Initialized,
+    Predicted,
+    Filtered,
+    Smoothed
+  };
+  enum Direction {
+    Forward = 0,
+    Backward = 1
+  };
+  enum Type {
+    Reference,
+    Measurement,
+    Outlier
+  };
+  enum CachedBool {
+    False = 0,
+    True = 1,
+    Unknown = 2
+  };
+
+  typedef LHCb::TbState State;
+  typedef Gaudi::Vector4 StateParameters;
+  typedef Gaudi::SymMatrix4x4 StateCovariance;
+
+  // helper class that contains data for forward fit
+  /* struct ForwardFitState { */
+  /* ForwardFitState() : */
+  /*   deltaChi2(0), status(Initialized) {} */
+  /*   typedef  */
+  /*   enum FilterStatus {Initialized, Predicted, Filtered, Smoothed } ; */
+  /*   enum CachedBool   {False=0, True=1, Unknown=2;} ; */
+  /*   TbState           predictedState ;  ///< predicted state of
+   * forward/backward filter */
+  /*   TbState           filteredState ;   ///< filtered state of forward filter
+   */
+  /*   double            deltaChi2 ;       ///< chisq contribution in forward
+   * filter */
+  /*   FilterStatus      status ;          ///< Status of the Node in the fit
+   * process */
+  /* } ; */
+
+  /// Default constructor
+  TbKalmanNode();
+
+  /// Constructor from a z position
+  TbKalmanNode(TbKalmanTrack& parent, double zPos);
+
+  /// Destructor
+  virtual ~TbKalmanNode();
+
+  /// Clone the Node
+  //virtual TbKalmanNode* clone() const;
+
+  /// set the seed matrix
+  void setSeedCovariance(const StateCovariance& cov) {
+    m_predictedState[Forward].covariance() = cov;
+    m_predictedState[Backward].covariance() = cov;
+    resetFilterStatus();
+  }
+
+  /// set the seed
+  void setSeed(const State& seedstate) {
+    // just copy covariance (assuming it to be rather meaningless), but
+    // transport the state
+    State astate(seedstate);
+    double dz = z() - seedstate.z();
+    astate.parameters()(0) += dz * astate.parameters()(2);
+    astate.parameters()(1) += dz * astate.parameters()(3);
+    astate.setZ(z());
+    m_predictedState[Forward] = astate;
+    m_predictedState[Backward] = astate;
+    resetFilterStatus();
+  }
+
+  /// retrieve chisq contribution in upstream filter
+  const LHCb::ChiSquare& deltaChi2(int direction) const {
+    filteredState(direction);
+    return m_deltaChi2[direction];
+  }
+
+  /// get the z
+  double z() const { return m_state.z(); }
+
+  /// get the filter status (only useful for debugging)
+  FilterStatus filterStatus(int direction) const {
+    return m_filterStatus[direction];
+  }
+
+  /// return whether or not this node has active nodes upstream
+  bool hasInfoUpstream(int direction) const;
+
+  /// Get the index of this node. For debugging only.
+  int index() const;
+
+  /// Unlink this node
+  void unLink() {
+    m_prevNode = m_nextNode = 0;
+    m_parent = 0;
+  }
+
+  void link(TbKalmanNode* prevnode) {
+    m_prevNode = prevnode;
+    if (m_prevNode) m_prevNode->m_nextNode = this;
+    m_nextNode = 0;
+  }
+
+  /// set the parent
+  void setParent(TbKalmanTrack* p) { m_parent = p; }
+
+  /// get the parent
+  TbKalmanTrack* parent() { return m_parent; }
+
+ public:
+  const TbKalmanNode* prevNode(int direction) const {
+    return direction == Forward ? m_prevNode : m_nextNode;
+  }
+  const TbKalmanNode* nextNode(int direction) const {
+    return direction == Forward ? m_nextNode : m_prevNode;
+  }
+
+  /// retrieve the predicted state
+  const State& predictedState(int direction) const {
+    if (m_filterStatus[direction] < Predicted)
+      unConst().computePredictedState(direction);
+    return m_predictedState[direction];
+  }
+
+  /// retrieve the filtered state
+  const State& filteredState(int direction) const {
+    if (m_filterStatus[direction] < Filtered)
+      unConst().computeFilteredState(direction);
+    return m_filteredState[direction];
+  }
+
+  /// retrieve the bismoothed state
+  const State& state() const {
+    if (m_filterStatus[Backward] < Smoothed) unConst().computeBiSmoothedState();
+    return m_state;
+  }
+
+  /// This is used from the projectors (or from any set method?)
+  void resetFilterStatus(FilterStatus s = Initialized) {
+    resetFilterStatus(Forward, s);
+    resetFilterStatus(Backward, s);
+  }
+
+  /// Set the noise term
+  void setNoise2(double noise2) { m_Q = noise2; }
+
+ protected:
+  /// virtual function to be overloaded by Measurement implementations
+  virtual void updateResidual(const State& /* state */) {}
+  virtual LHCb::ChiSquare filter(State& /* state */) const {
+    return LHCb::ChiSquare();
+  }
+  virtual bool hasInfo() const { return false; }
+  virtual void deactivateMeasurement(bool /* deactivate */) {}
+
+ private:
+  void computePredictedState(int direction);
+  void computeFilteredState(int direction);
+  void computeBiSmoothedState();
+  void computeClassicalSmoothedState();
+  TbKalmanNode& unConst() const { return const_cast<TbKalmanNode&>(*this); }
+
+ protected:
+  /// reset the cache for the previous function
+  void resetHasInfoUpstream(int direction);
+
+  /// reset the filter status
+  void resetFilterStatus(int direction, FilterStatus s = Initialized);
+
+ private:
+
+  TbKalmanTrack* m_parent;         ///< Owner
+  FilterStatus m_filterStatus[2];  ///< Status of the Node in the fit process
+  CachedBool m_hasInfoUpstream[
+      2];  ///< Are the nodes with active measurement upstream of this node?
+  State m_predictedState[2];  ///< predicted state of forward/backward filter
+  State m_filteredState[2];   ///< filtered state of forward filter
+  State m_state;              ///< Smoothed state
+  LHCb::ChiSquare m_deltaChi2[2];  ///< chisq contribution in forward filter
+  //LHCb::ChiSquare       m_totalChi2[2];          ///< total chi2 after this
+  //filterstep
+  //Gaudi::TrackMatrix    m_smootherGainMatrix ;   ///< smoother gain matrix
+  //(smoothedfit only)
+  TbKalmanNode* m_prevNode;        ///< Previous Node
+  TbKalmanNode* m_nextNode;        ///< Next Node
+
+  double m_Q;  ///< noise between this node and the next node
+};
+
+}  // namespace LHCb
+
+#endif  // TRACKFITEVENT_FITNODE_H
diff --git a/TbEvent/Event/.svn/text-base/TbKalmanPixelMeasurement.h.svn-base b/TbEvent/Event/.svn/text-base/TbKalmanPixelMeasurement.h.svn-base
new file mode 100644
index 0000000..3ea6cf2
--- /dev/null
+++ b/TbEvent/Event/.svn/text-base/TbKalmanPixelMeasurement.h.svn-base
@@ -0,0 +1,68 @@
+#ifndef TBKALMANPIXELMEASUREMENT
+#define TBKALMANPIXELMEASUREMENT
+
+#include "Event/TbKalmanNode.h"
+
+namespace LHCb {
+class TbKalmanPixelMeasurement : public TbKalmanNode {
+ public:
+  // create from a cluster
+  TbKalmanPixelMeasurement(TbKalmanTrack& parent, const TbCluster& cluster,
+                           double measerr2)
+      : TbKalmanNode(parent, cluster.z()),
+        m_cluster(&cluster),
+        m_isactive(true) {
+    m_x = m_cluster->x();
+    m_covx = measerr2;
+    m_y = m_cluster->y();
+    m_covy = measerr2;
+  }
+
+  // filter this hit
+  LHCb::ChiSquare filter(State& state) const;
+
+  // compute residual with respect to given (smoothed) state
+  void updateResidual(const State& state);
+
+  // tell if this meausurement should be used in fit
+  bool hasInfo() const { return m_isactive; }
+
+  //=========================================================================
+  // Turn this node into an outlier
+  //=========================================================================
+  void deactivateMeasurement(bool deactivate);
+
+  double residualX() const { return m_residualX; }
+  double residualCovX() const { return m_residualCovX; }
+  double residualY() const { return m_residualY; }
+  double residualCovY() const { return m_residualCovY; }
+  double covX() const { return m_covx; }
+  double covY() const { return m_covy; }
+
+  const TbCluster& cluster() const { return *m_cluster; }
+
+  LHCb::ChiSquare chi2() const {
+    return LHCb::ChiSquare(m_residualX * m_residualX / m_residualCovX +
+                           m_residualY * m_residualY / m_residualCovY,
+                           2);
+  }
+
+ private:
+  const TbCluster* m_cluster;
+  bool m_isactive;
+  /// Measured X coordinate
+  double m_x;
+  /// Error^2 in X
+  double m_covx;  
+  /// Measured Y coordinate
+  double m_y;     
+  /// Error^2 in Y
+  double m_covy;
+  double m_residualX;
+  double m_residualY;
+  double m_residualCovX;
+  double m_residualCovY;
+};
+}
+
+#endif
diff --git a/TbEvent/Event/.svn/text-base/TbKalmanTrack.h.svn-base b/TbEvent/Event/.svn/text-base/TbKalmanTrack.h.svn-base
new file mode 100644
index 0000000..30e6298
--- /dev/null
+++ b/TbEvent/Event/.svn/text-base/TbKalmanTrack.h.svn-base
@@ -0,0 +1,43 @@
+#ifndef TBKALMANTRACK_H
+#define TBKALMANTRACK_H
+
+#include "Event/TbTrack.h"
+
+namespace LHCb {
+class TbKalmanNode;
+
+class TbKalmanTrack : public TbTrack {
+ public:
+  /// Constructor
+  TbKalmanTrack(const LHCb::TbTrack& track, const double hiterror2, 
+                const double noise2);
+  // Destructor
+  ~TbKalmanTrack();
+
+  // get the nodes
+  const std::vector<TbKalmanNode*>& nodes() const { return m_nodes; }
+
+  // called by daughter node if something changes
+  void resetCache() {}
+
+  // fit
+  void fit();
+
+  // dump some debug info
+  void print() const;
+
+  // add a node
+  void addNode(TbKalmanNode*);
+
+  // add a 'reference' node (without a measurement, just to have the state)
+  void addReferenceNode(double z);
+
+  // deactivate a measurement on the track
+  void deactivateCluster(const TbCluster& clus);
+
+ private:
+  std::vector<TbKalmanNode*> m_nodes;
+};
+}
+
+#endif
diff --git a/TbEvent/Event/TbKalmanNode.h b/TbEvent/Event/TbKalmanNode.h
new file mode 100644
index 0000000..3bd967b
--- /dev/null
+++ b/TbEvent/Event/TbKalmanNode.h
@@ -0,0 +1,222 @@
+#ifndef TBTRACKFITNODE_H
+#define TBTRACKFITNODE_H 1
+
+// from TbEvent
+#include "Event/TbState.h"
+#include "Event/TbCluster.h"
+#include "Event/ChiSquare.h"
+
+// forward declarations
+namespace LHCb { class TbKalmanTrack; }
+
+namespace LHCb {
+
+/** @class TbKalmanFitNode TbKalmanFitNode.h Event/TbKalmanFitNode.h
+  *
+  *  This File contains the declaration of the TbKalmanFitNode.
+  *
+  *  A TbKalmanFitNode represents a node in the kalman fit.
+  *
+  */
+
+class TbKalmanNode {
+ public:
+  // important note: for the Forward fit, smoothed means
+  // 'classical'. for the backward fit, it means 'bidirectional'.
+  enum FilterStatus {
+    Uninitialized,
+    Initialized,
+    Predicted,
+    Filtered,
+    Smoothed
+  };
+  enum Direction {
+    Forward = 0,
+    Backward = 1
+  };
+  enum Type {
+    Reference,
+    Measurement,
+    Outlier
+  };
+  enum CachedBool {
+    False = 0,
+    True = 1,
+    Unknown = 2
+  };
+
+  typedef LHCb::TbState State;
+  typedef Gaudi::Vector4 StateParameters;
+  typedef Gaudi::SymMatrix4x4 StateCovariance;
+
+  // helper class that contains data for forward fit
+  /* struct ForwardFitState { */
+  /* ForwardFitState() : */
+  /*   deltaChi2(0), status(Initialized) {} */
+  /*   typedef  */
+  /*   enum FilterStatus {Initialized, Predicted, Filtered, Smoothed } ; */
+  /*   enum CachedBool   {False=0, True=1, Unknown=2;} ; */
+  /*   TbState           predictedState ;  ///< predicted state of
+   * forward/backward filter */
+  /*   TbState           filteredState ;   ///< filtered state of forward filter
+   */
+  /*   double            deltaChi2 ;       ///< chisq contribution in forward
+   * filter */
+  /*   FilterStatus      status ;          ///< Status of the Node in the fit
+   * process */
+  /* } ; */
+
+  /// Default constructor
+  TbKalmanNode();
+
+  /// Constructor from a z position
+  TbKalmanNode(TbKalmanTrack& parent, double zPos);
+
+  /// Destructor
+  virtual ~TbKalmanNode();
+
+  /// Clone the Node
+  //virtual TbKalmanNode* clone() const;
+
+  /// set the seed matrix
+  void setSeedCovariance(const StateCovariance& cov) {
+    m_predictedState[Forward].covariance() = cov;
+    m_predictedState[Backward].covariance() = cov;
+    resetFilterStatus();
+  }
+
+  /// set the seed
+  void setSeed(const State& seedstate) {
+    // just copy covariance (assuming it to be rather meaningless), but
+    // transport the state
+    State astate(seedstate);
+    double dz = z() - seedstate.z();
+    astate.parameters()(0) += dz * astate.parameters()(2);
+    astate.parameters()(1) += dz * astate.parameters()(3);
+    astate.setZ(z());
+    m_predictedState[Forward] = astate;
+    m_predictedState[Backward] = astate;
+    resetFilterStatus();
+  }
+
+  /// retrieve chisq contribution in upstream filter
+  const LHCb::ChiSquare& deltaChi2(int direction) const {
+    filteredState(direction);
+    return m_deltaChi2[direction];
+  }
+
+  /// get the z
+  double z() const { return m_state.z(); }
+
+  /// get the filter status (only useful for debugging)
+  FilterStatus filterStatus(int direction) const {
+    return m_filterStatus[direction];
+  }
+
+  /// return whether or not this node has active nodes upstream
+  bool hasInfoUpstream(int direction) const;
+
+  /// Get the index of this node. For debugging only.
+  int index() const;
+
+  /// Unlink this node
+  void unLink() {
+    m_prevNode = m_nextNode = 0;
+    m_parent = 0;
+  }
+
+  void link(TbKalmanNode* prevnode) {
+    m_prevNode = prevnode;
+    if (m_prevNode) m_prevNode->m_nextNode = this;
+    m_nextNode = 0;
+  }
+
+  /// set the parent
+  void setParent(TbKalmanTrack* p) { m_parent = p; }
+
+  /// get the parent
+  TbKalmanTrack* parent() { return m_parent; }
+
+ public:
+  const TbKalmanNode* prevNode(int direction) const {
+    return direction == Forward ? m_prevNode : m_nextNode;
+  }
+  const TbKalmanNode* nextNode(int direction) const {
+    return direction == Forward ? m_nextNode : m_prevNode;
+  }
+
+  /// retrieve the predicted state
+  const State& predictedState(int direction) const {
+    if (m_filterStatus[direction] < Predicted)
+      unConst().computePredictedState(direction);
+    return m_predictedState[direction];
+  }
+
+  /// retrieve the filtered state
+  const State& filteredState(int direction) const {
+    if (m_filterStatus[direction] < Filtered)
+      unConst().computeFilteredState(direction);
+    return m_filteredState[direction];
+  }
+
+  /// retrieve the bismoothed state
+  const State& state() const {
+    if (m_filterStatus[Backward] < Smoothed) unConst().computeBiSmoothedState();
+    return m_state;
+  }
+
+  /// This is used from the projectors (or from any set method?)
+  void resetFilterStatus(FilterStatus s = Initialized) {
+    resetFilterStatus(Forward, s);
+    resetFilterStatus(Backward, s);
+  }
+
+  /// Set the noise term
+  void setNoise2(double noise2) { m_Q = noise2; }
+
+ protected:
+  /// virtual function to be overloaded by Measurement implementations
+  virtual void updateResidual(const State& /* state */) {}
+  virtual LHCb::ChiSquare filter(State& /* state */) const {
+    return LHCb::ChiSquare();
+  }
+  virtual bool hasInfo() const { return false; }
+  virtual void deactivateMeasurement(bool /* deactivate */) {}
+
+ private:
+  void computePredictedState(int direction);
+  void computeFilteredState(int direction);
+  void computeBiSmoothedState();
+  void computeClassicalSmoothedState();
+  TbKalmanNode& unConst() const { return const_cast<TbKalmanNode&>(*this); }
+
+ protected:
+  /// reset the cache for the previous function
+  void resetHasInfoUpstream(int direction);
+
+  /// reset the filter status
+  void resetFilterStatus(int direction, FilterStatus s = Initialized);
+
+ private:
+
+  TbKalmanTrack* m_parent;         ///< Owner
+  FilterStatus m_filterStatus[2];  ///< Status of the Node in the fit process
+  CachedBool m_hasInfoUpstream[
+      2];  ///< Are the nodes with active measurement upstream of this node?
+  State m_predictedState[2];  ///< predicted state of forward/backward filter
+  State m_filteredState[2];   ///< filtered state of forward filter
+  State m_state;              ///< Smoothed state
+  LHCb::ChiSquare m_deltaChi2[2];  ///< chisq contribution in forward filter
+  //LHCb::ChiSquare       m_totalChi2[2];          ///< total chi2 after this
+  //filterstep
+  //Gaudi::TrackMatrix    m_smootherGainMatrix ;   ///< smoother gain matrix
+  //(smoothedfit only)
+  TbKalmanNode* m_prevNode;        ///< Previous Node
+  TbKalmanNode* m_nextNode;        ///< Next Node
+
+  double m_Q;  ///< noise between this node and the next node
+};
+
+}  // namespace LHCb
+
+#endif  // TRACKFITEVENT_FITNODE_H
diff --git a/TbEvent/Event/TbKalmanPixelMeasurement.h b/TbEvent/Event/TbKalmanPixelMeasurement.h
new file mode 100644
index 0000000..3ea6cf2
--- /dev/null
+++ b/TbEvent/Event/TbKalmanPixelMeasurement.h
@@ -0,0 +1,68 @@
+#ifndef TBKALMANPIXELMEASUREMENT
+#define TBKALMANPIXELMEASUREMENT
+
+#include "Event/TbKalmanNode.h"
+
+namespace LHCb {
+class TbKalmanPixelMeasurement : public TbKalmanNode {
+ public:
+  // create from a cluster
+  TbKalmanPixelMeasurement(TbKalmanTrack& parent, const TbCluster& cluster,
+                           double measerr2)
+      : TbKalmanNode(parent, cluster.z()),
+        m_cluster(&cluster),
+        m_isactive(true) {
+    m_x = m_cluster->x();
+    m_covx = measerr2;
+    m_y = m_cluster->y();
+    m_covy = measerr2;
+  }
+
+  // filter this hit
+  LHCb::ChiSquare filter(State& state) const;
+
+  // compute residual with respect to given (smoothed) state
+  void updateResidual(const State& state);
+
+  // tell if this meausurement should be used in fit
+  bool hasInfo() const { return m_isactive; }
+
+  //=========================================================================
+  // Turn this node into an outlier
+  //=========================================================================
+  void deactivateMeasurement(bool deactivate);
+
+  double residualX() const { return m_residualX; }
+  double residualCovX() const { return m_residualCovX; }
+  double residualY() const { return m_residualY; }
+  double residualCovY() const { return m_residualCovY; }
+  double covX() const { return m_covx; }
+  double covY() const { return m_covy; }
+
+  const TbCluster& cluster() const { return *m_cluster; }
+
+  LHCb::ChiSquare chi2() const {
+    return LHCb::ChiSquare(m_residualX * m_residualX / m_residualCovX +
+                           m_residualY * m_residualY / m_residualCovY,
+                           2);
+  }
+
+ private:
+  const TbCluster* m_cluster;
+  bool m_isactive;
+  /// Measured X coordinate
+  double m_x;
+  /// Error^2 in X
+  double m_covx;  
+  /// Measured Y coordinate
+  double m_y;     
+  /// Error^2 in Y
+  double m_covy;
+  double m_residualX;
+  double m_residualY;
+  double m_residualCovX;
+  double m_residualCovY;
+};
+}
+
+#endif
diff --git a/TbEvent/Event/TbKalmanTrack.h b/TbEvent/Event/TbKalmanTrack.h
new file mode 100644
index 0000000..30e6298
--- /dev/null
+++ b/TbEvent/Event/TbKalmanTrack.h
@@ -0,0 +1,43 @@
+#ifndef TBKALMANTRACK_H
+#define TBKALMANTRACK_H
+
+#include "Event/TbTrack.h"
+
+namespace LHCb {
+class TbKalmanNode;
+
+class TbKalmanTrack : public TbTrack {
+ public:
+  /// Constructor
+  TbKalmanTrack(const LHCb::TbTrack& track, const double hiterror2, 
+                const double noise2);
+  // Destructor
+  ~TbKalmanTrack();
+
+  // get the nodes
+  const std::vector<TbKalmanNode*>& nodes() const { return m_nodes; }
+
+  // called by daughter node if something changes
+  void resetCache() {}
+
+  // fit
+  void fit();
+
+  // dump some debug info
+  void print() const;
+
+  // add a node
+  void addNode(TbKalmanNode*);
+
+  // add a 'reference' node (without a measurement, just to have the state)
+  void addReferenceNode(double z);
+
+  // deactivate a measurement on the track
+  void deactivateCluster(const TbCluster& clus);
+
+ private:
+  std::vector<TbKalmanNode*> m_nodes;
+};
+}
+
+#endif
diff --git a/TbEvent/cmt/.svn/all-wcprops b/TbEvent/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..3201f7f
--- /dev/null
+++ b/TbEvent/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/guest/lhcb/!svn/ver/188485/Kepler/trunk/Tb/TbEvent/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/188485/Kepler/trunk/Tb/TbEvent/cmt/requirements
+END
diff --git a/TbEvent/cmt/.svn/entries b/TbEvent/cmt/.svn/entries
new file mode 100644
index 0000000..0a79cc3
--- /dev/null
+++ b/TbEvent/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T09:51:16.878566Z
+188485
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+0f1be6e1b5bbdbfe4cb3439fc2566f3f
+2015-05-19T09:51:16.878566Z
+188485
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1155
+
diff --git a/TbEvent/cmt/.svn/text-base/requirements.svn-base b/TbEvent/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..87248a2
--- /dev/null
+++ b/TbEvent/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,33 @@
+package Tb/TbEvent
+version v2r2
+
+# Structure, i.e. directories to process.
+#========================================================================
+branches          cmt doc dict Event xml
+
+# Used packages.
+#========================================================================
+use EventBase    v*      Event
+
+# Produce Header-Files from XML description
+#========================================================================
+private
+use GaudiObjDesc v* -no_auto_imports
+end_private
+
+apply_pattern god_headers files=../xml/*.xml
+apply_pattern install_more_includes more=Event
+
+# Make custom dictionary. Must be before GOD generation
+#========================================================================
+document customdict TbEventCustomDict ../dict/lcgDict.h
+macro_append TbEventObj2Dict_dependencies TbEventCustomDict
+
+apply_pattern god_dictionary files=../xml/*.xml
+macro_append TbEventDict_cppflags "-std=c++11" \
+                       target-icc " -wd191"
+
+# Make the linker library
+#=====================================================================
+library       TbEvent           *.cpp
+apply_pattern linker_library    library=TbEvent
diff --git a/TbEvent/cmt/requirements b/TbEvent/cmt/requirements
new file mode 100644
index 0000000..87248a2
--- /dev/null
+++ b/TbEvent/cmt/requirements
@@ -0,0 +1,33 @@
+package Tb/TbEvent
+version v2r2
+
+# Structure, i.e. directories to process.
+#========================================================================
+branches          cmt doc dict Event xml
+
+# Used packages.
+#========================================================================
+use EventBase    v*      Event
+
+# Produce Header-Files from XML description
+#========================================================================
+private
+use GaudiObjDesc v* -no_auto_imports
+end_private
+
+apply_pattern god_headers files=../xml/*.xml
+apply_pattern install_more_includes more=Event
+
+# Make custom dictionary. Must be before GOD generation
+#========================================================================
+document customdict TbEventCustomDict ../dict/lcgDict.h
+macro_append TbEventObj2Dict_dependencies TbEventCustomDict
+
+apply_pattern god_dictionary files=../xml/*.xml
+macro_append TbEventDict_cppflags "-std=c++11" \
+                       target-icc " -wd191"
+
+# Make the linker library
+#=====================================================================
+library       TbEvent           *.cpp
+apply_pattern linker_library    library=TbEvent
diff --git a/TbEvent/dict/.svn/all-wcprops b/TbEvent/dict/.svn/all-wcprops
new file mode 100644
index 0000000..3d539c1
--- /dev/null
+++ b/TbEvent/dict/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/170762/Kepler/trunk/Tb/TbEvent/dict
+END
+lcgDict.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/170762/Kepler/trunk/Tb/TbEvent/dict/lcgDict.h
+END
diff --git a/TbEvent/dict/.svn/entries b/TbEvent/dict/.svn/entries
new file mode 100644
index 0000000..1aa0b5e
--- /dev/null
+++ b/TbEvent/dict/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/dict
+http://svn.cern.ch/guest/lhcb
+
+
+
+2014-03-31T17:37:58.454693Z
+170762
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+lcgDict.h
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+3b7265f47cb5603efe9339e7f6b55471
+2014-03-31T17:37:58.454693Z
+170762
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+133
+
diff --git a/TbEvent/dict/.svn/text-base/lcgDict.h.svn-base b/TbEvent/dict/.svn/text-base/lcgDict.h.svn-base
new file mode 100644
index 0000000..bde7cc3
--- /dev/null
+++ b/TbEvent/dict/.svn/text-base/lcgDict.h.svn-base
@@ -0,0 +1,6 @@
+#ifndef TBEVENT_LCGDICT_H 
+#define TBEVENT_LCGDICT_H 1
+
+// Additional classes to be added to automatically generated lcgdict
+
+#endif
diff --git a/TbEvent/dict/lcgDict.h b/TbEvent/dict/lcgDict.h
new file mode 100644
index 0000000..bde7cc3
--- /dev/null
+++ b/TbEvent/dict/lcgDict.h
@@ -0,0 +1,6 @@
+#ifndef TBEVENT_LCGDICT_H 
+#define TBEVENT_LCGDICT_H 1
+
+// Additional classes to be added to automatically generated lcgdict
+
+#endif
diff --git a/TbEvent/doc/.svn/all-wcprops b/TbEvent/doc/.svn/all-wcprops
new file mode 100644
index 0000000..465b3ae
--- /dev/null
+++ b/TbEvent/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/doc/release.notes
+END
diff --git a/TbEvent/doc/.svn/entries b/TbEvent/doc/.svn/entries
new file mode 100644
index 0000000..194bf13
--- /dev/null
+++ b/TbEvent/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+19ce020eddebab875b915bf3071b8e51
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3578
+
diff --git a/TbEvent/doc/.svn/text-base/release.notes.svn-base b/TbEvent/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..f1e417c
--- /dev/null
+++ b/TbEvent/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,114 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbEvent
+! Responsible : 
+! Purpose     : Event model for Timepix3 testbeam analysis
+!-----------------------------------------------------------------------------
+
+! 2016-02-14 - Heinrich Schindler
+ - Replace BOOST_FOREACH by intrinsic range-based for loop.
+
+! 2016-02-04 - Heinrich Schindler
+ - TbCluster: store cluster width along column and row directions.
+
+! 2016-01-28 - Heinrich Schindler
+ - TbHit: move code in constructor to TbEventBuilder.
+ - TbCluster: add attribute ToT.
+
+!========================= TbEvent v2r2 2015-05-19 ===========================
+
+! 2015-03-24 - Heinrich Schindler
+ - TbTrack: change states from std::vector<TbState*> to std::vector<TbState>.
+ - TbState: add attribute plane.
+ - Reserve hits, clusters, ... in constructor.
+
+! 2015-01-21 - Heinrich Schindler
+ - Change TbCluster::charge to double (was unsigned int).
+
+! 2015-01-20 - Heinrich Schindler
+ - Rename TbTrack::tracked to TbTrack::associated for consistency.
+   Add associatedClusters to TbTrack.
+
+! 2014-12-31 - Heinrich Schindler
+ - Add attribute scol to TbHit.
+
+! 2014-12-28 - Heinrich Schindler
+ - Remove attributes vertexed, endCluster, volumed from TbCluster.
+
+! 2014-12-12 - Heinrich Schindler
+ - Rename attribute "plane" of TbHit to "device".
+
+! 2014-12-07 - Heinrich Schindler
+ - Remove clustered attribute from TbHit.
+
+!========================= TbEvent v2r1 2014-11-30 ===========================
+
+! 2014-11-11 - Dan Saunders
+ - Add TbVertex.
+
+! 2014-10-12 - Panos Tsopelas
+ - Add TbKalmanTrack, TbKalmanNode, TbKalmanPixelMeasurement.
+ 
+!========================= TbEvent v2r0 2014-08-18 ===========================
+
+! 2014-08-07 - Wouter Hulsbergen
+ - add copy constructor and ::clearStates to TbTrack
+
+! 2014-07-18 - Heinrich Schindler
+ - Change default path of TbCluster, TbTrack and TbState from Raw to Rec.
+
+! 2014-07-17 - Tim Evans
+ - Removed redundant fields from TbHit and fixed for 64 bit time stamps
+
+! 2014-07-17 - Heinrich Schindler
+ - Add TbTrigger event class.
+ - Add htime attribute to TbHit, TbCluster, TbTrack and TbTrigger.
+
+! 2014-07-16 - Heinrich Schindler
+ - Change timestamp to unsigned long.
+
+! 2014-07-08 - Heinrich Schindler
+ - Rename "chip" to "plane" in TbHit and TbCluster.
+
+! 2014-07-02 - Heinrich Schindler
+ - Remove unused members and functions from event classes.
+ - Consistent spelling of "Spidr".
+
+! 2014-06-27 - Tim Evans
+ - Added header event classes SpiderHeader and DeviceHeader
+ - Added decoding functionality to TbHit.
+
+!========================= TbEvent v1r0 2014-05-30 ===========================
+
+! 2014-05-29 - Heinrich Schindler
+ - Change attribute name "chip_num" of TbCluster to "chip".
+
+! 2014-05-24 - Heinrich Schindler
+ - Consistent formatting
+ - Remove unused member variables from TbHit, TbCluster, TbTrack.
+ - Rename addToTbStates to addToStates and similar changes.
+ - Make TbState destructor virtual (fixes compiler warning).
+ - Remove unnecessary includes.
+
+! 2014-05-23 - Panagiotis Tsopelas
+ - Edited members of TbTrack ( chi2 -> chi2PerNdof ) 
+   Added clone, TbState vector
+ - Added covariance matrix and clone in TbState
+
+! 2014-05-15 - Marco Clemencic
+ - Fixed CMake configuration.
+
+! 2014-05-06 - Panagiotis Tsopelas
+ - Added ndof in TbTrack
+
+! 2014-04-29 - Panagiotis Tsopelas
+ - Added TbState
+ - Modified TbTrack (added firstState)
+
+! 2014-04-14 - Heinrich Schindler
+ - Add TbTrack
+
+! 2014-04-02 - Tim Evans
+ - Add TbHit, add timing information to TbCluster
+
+! 2014-03-31 - Heinrich Schindler
+ - Initial import 
diff --git a/TbEvent/doc/release.notes b/TbEvent/doc/release.notes
new file mode 100644
index 0000000..f1e417c
--- /dev/null
+++ b/TbEvent/doc/release.notes
@@ -0,0 +1,114 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbEvent
+! Responsible : 
+! Purpose     : Event model for Timepix3 testbeam analysis
+!-----------------------------------------------------------------------------
+
+! 2016-02-14 - Heinrich Schindler
+ - Replace BOOST_FOREACH by intrinsic range-based for loop.
+
+! 2016-02-04 - Heinrich Schindler
+ - TbCluster: store cluster width along column and row directions.
+
+! 2016-01-28 - Heinrich Schindler
+ - TbHit: move code in constructor to TbEventBuilder.
+ - TbCluster: add attribute ToT.
+
+!========================= TbEvent v2r2 2015-05-19 ===========================
+
+! 2015-03-24 - Heinrich Schindler
+ - TbTrack: change states from std::vector<TbState*> to std::vector<TbState>.
+ - TbState: add attribute plane.
+ - Reserve hits, clusters, ... in constructor.
+
+! 2015-01-21 - Heinrich Schindler
+ - Change TbCluster::charge to double (was unsigned int).
+
+! 2015-01-20 - Heinrich Schindler
+ - Rename TbTrack::tracked to TbTrack::associated for consistency.
+   Add associatedClusters to TbTrack.
+
+! 2014-12-31 - Heinrich Schindler
+ - Add attribute scol to TbHit.
+
+! 2014-12-28 - Heinrich Schindler
+ - Remove attributes vertexed, endCluster, volumed from TbCluster.
+
+! 2014-12-12 - Heinrich Schindler
+ - Rename attribute "plane" of TbHit to "device".
+
+! 2014-12-07 - Heinrich Schindler
+ - Remove clustered attribute from TbHit.
+
+!========================= TbEvent v2r1 2014-11-30 ===========================
+
+! 2014-11-11 - Dan Saunders
+ - Add TbVertex.
+
+! 2014-10-12 - Panos Tsopelas
+ - Add TbKalmanTrack, TbKalmanNode, TbKalmanPixelMeasurement.
+ 
+!========================= TbEvent v2r0 2014-08-18 ===========================
+
+! 2014-08-07 - Wouter Hulsbergen
+ - add copy constructor and ::clearStates to TbTrack
+
+! 2014-07-18 - Heinrich Schindler
+ - Change default path of TbCluster, TbTrack and TbState from Raw to Rec.
+
+! 2014-07-17 - Tim Evans
+ - Removed redundant fields from TbHit and fixed for 64 bit time stamps
+
+! 2014-07-17 - Heinrich Schindler
+ - Add TbTrigger event class.
+ - Add htime attribute to TbHit, TbCluster, TbTrack and TbTrigger.
+
+! 2014-07-16 - Heinrich Schindler
+ - Change timestamp to unsigned long.
+
+! 2014-07-08 - Heinrich Schindler
+ - Rename "chip" to "plane" in TbHit and TbCluster.
+
+! 2014-07-02 - Heinrich Schindler
+ - Remove unused members and functions from event classes.
+ - Consistent spelling of "Spidr".
+
+! 2014-06-27 - Tim Evans
+ - Added header event classes SpiderHeader and DeviceHeader
+ - Added decoding functionality to TbHit.
+
+!========================= TbEvent v1r0 2014-05-30 ===========================
+
+! 2014-05-29 - Heinrich Schindler
+ - Change attribute name "chip_num" of TbCluster to "chip".
+
+! 2014-05-24 - Heinrich Schindler
+ - Consistent formatting
+ - Remove unused member variables from TbHit, TbCluster, TbTrack.
+ - Rename addToTbStates to addToStates and similar changes.
+ - Make TbState destructor virtual (fixes compiler warning).
+ - Remove unnecessary includes.
+
+! 2014-05-23 - Panagiotis Tsopelas
+ - Edited members of TbTrack ( chi2 -> chi2PerNdof ) 
+   Added clone, TbState vector
+ - Added covariance matrix and clone in TbState
+
+! 2014-05-15 - Marco Clemencic
+ - Fixed CMake configuration.
+
+! 2014-05-06 - Panagiotis Tsopelas
+ - Added ndof in TbTrack
+
+! 2014-04-29 - Panagiotis Tsopelas
+ - Added TbState
+ - Modified TbTrack (added firstState)
+
+! 2014-04-14 - Heinrich Schindler
+ - Add TbTrack
+
+! 2014-04-02 - Tim Evans
+ - Add TbHit, add timing information to TbCluster
+
+! 2014-03-31 - Heinrich Schindler
+ - Initial import 
diff --git a/TbEvent/src/.svn/all-wcprops b/TbEvent/src/.svn/all-wcprops
new file mode 100644
index 0000000..ac72a2a
--- /dev/null
+++ b/TbEvent/src/.svn/all-wcprops
@@ -0,0 +1,47 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/src
+END
+TbKalmanTrack.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/src/TbKalmanTrack.cpp
+END
+TbKalmanNode.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/src/TbKalmanNode.cpp
+END
+TbKalmanPixelMeasurement.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/201498/Kepler/trunk/Tb/TbEvent/src/TbKalmanPixelMeasurement.cpp
+END
+ChiSquare.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/185530/Kepler/trunk/Tb/TbEvent/src/ChiSquare.cpp
+END
+TbState.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/173162/Kepler/trunk/Tb/TbEvent/src/TbState.cpp
+END
+TbCluster.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/182079/Kepler/trunk/Tb/TbEvent/src/TbCluster.cpp
+END
+TbTrack.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/197049/Kepler/trunk/Tb/TbEvent/src/TbTrack.cpp
+END
diff --git a/TbEvent/src/.svn/entries b/TbEvent/src/.svn/entries
new file mode 100644
index 0000000..df68de5
--- /dev/null
+++ b/TbEvent/src/.svn/entries
@@ -0,0 +1,266 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbKalmanTrack.cpp
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+d08e3a578bc56780f73136ef63e4dcb0
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6320
+
+TbKalmanNode.cpp
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+9ab06b2fb44f39bc95290768abbec534
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10541
+
+TbKalmanPixelMeasurement.cpp
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+479aff0b28b1dc77e5ab6f9f7b1e88d6
+2016-02-14T10:34:45.226731Z
+201498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2742
+
+ChiSquare.cpp
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+b4e5ff6ad6ad890c9c407cadbaa40639
+2015-03-16T20:41:44.561223Z
+185530
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+327
+
+TbState.cpp
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+20596b0ee888875a177e44edaa2abb10
+2014-05-24T14:29:04.255487Z
+173162
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+665
+
+TbCluster.cpp
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+e774b6db1aa0f57fb253e04ff09af1e1
+2014-12-28T21:37:52.040452Z
+182079
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+518
+
+TbTrack.cpp
+file
+
+
+
+
+2016-05-09T14:27:55.000000Z
+fa1e02880d8c23a46e1b920e584d77a7
+2015-10-31T10:24:39.647329Z
+197049
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1741
+
diff --git a/TbEvent/src/.svn/prop-base/TbKalmanNode.cpp.svn-base b/TbEvent/src/.svn/prop-base/TbKalmanNode.cpp.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbEvent/src/.svn/prop-base/TbKalmanNode.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbEvent/src/.svn/text-base/ChiSquare.cpp.svn-base b/TbEvent/src/.svn/text-base/ChiSquare.cpp.svn-base
new file mode 100644
index 0000000..9a66641
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/ChiSquare.cpp.svn-base
@@ -0,0 +1,15 @@
+// local
+#include "Event/ChiSquare.h"
+#include "gsl/gsl_cdf.h"
+
+namespace LHCb {
+double ChiSquare::prob() const {
+  double val(0);
+  if (nDoF() > 0) {
+    const double limit = 1e-15;
+    double chi2max = gsl_cdf_chisq_Qinv(limit, nDoF());
+    val = chi2() < chi2max ? gsl_cdf_chisq_Q(chi2(), nDoF()) : 0;
+  }
+  return val;
+}
+}
diff --git a/TbEvent/src/.svn/text-base/TbCluster.cpp.svn-base b/TbEvent/src/.svn/text-base/TbCluster.cpp.svn-base
new file mode 100644
index 0000000..f62e5f6
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/TbCluster.cpp.svn-base
@@ -0,0 +1,22 @@
+#include "Event/TbCluster.h"
+
+using namespace LHCb;
+
+//=============================================================================
+// Clone method
+//=============================================================================
+TbCluster *TbCluster::clone() {
+  TbCluster *c = new TbCluster();
+  c->setX(x());
+  c->setY(y());
+  c->setZ(z());
+  c->setXloc(xloc());
+  c->setYloc(yloc());
+  c->setCharge(charge());
+  c->setPlane(plane());
+  c->setTime(time());
+  c->setXErr(xErr());
+  c->setYErr(yErr());
+  return c;
+}
+
diff --git a/TbEvent/src/.svn/text-base/TbKalmanNode.cpp.svn-base b/TbEvent/src/.svn/text-base/TbKalmanNode.cpp.svn-base
new file mode 100644
index 0000000..f71a803
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/TbKalmanNode.cpp.svn-base
@@ -0,0 +1,282 @@
+// local
+#include "Event/TbKalmanNode.h"
+
+/** @file FitNode.cpp
+ *
+ *  This File contains the implementation of the FitNode.
+ *  A FitNode is a basket of objects at a given z position.
+ *  The information inside the FitNode has to be sufficient
+ *  to allow smoothing and refitting.
+ *  At the moment a FitNode contains or allows you to access
+ *  info on the the (kth) measurement,
+ *  transport from k --> k + 1 , predicted state at k+1
+ *  (predicted from filter step)  and the best state at k
+ *  (notation note filter procedes from k -> k + 1 -> k + 2 ......)
+ * 
+ *  @author Victor Coco and Wouter Hulsbergen (moved K-math here)
+ *  @date   2011-02-01
+ *
+ *  @author Eduardo Rodrigues (adaptations to the new track event model)
+ *  @date   2005-04-15
+ *
+ *  @author Matt Needham
+ *  @date   11-11-1999
+ */
+
+namespace LHCb {
+
+/// Standard constructor, initializes variables
+// TbKalmanNode::TbKalmanNode():
+//   m_prevNode(0),
+//   m_nextNode(0),
+//   m_parent(0)
+// {
+//   // TbKalmanNode default constructor
+//   m_filterStatus[Forward] = m_filterStatus[Backward] = Uninitialized ;
+//   m_hasInfoUpstream[Forward] = m_hasInfoUpstream[Backward] = Unknown ;
+// }
+
+/// Constructor from a z position
+TbKalmanNode::TbKalmanNode(TbKalmanTrack& parent, double z)
+    : m_parent(&parent), m_prevNode(0), m_nextNode(0), m_Q(0) {
+  m_state.setZ(z);
+  m_filterStatus[Forward] = m_filterStatus[Backward] = Uninitialized;
+  m_hasInfoUpstream[Forward] = m_hasInfoUpstream[Backward] = Unknown;
+}
+
+/// Destructor
+TbKalmanNode::~TbKalmanNode() {
+  if (m_prevNode && m_prevNode->m_nextNode == this) m_prevNode->m_nextNode = 0;
+  if (m_nextNode && m_nextNode->m_prevNode == this) m_nextNode->m_prevNode = 0;
+}
+
+// Clone the node
+//LHCb::TbKalmanNode* TbKalmanNode::clone() const
+//{
+//  LHCb::TbKalmanNode* rc = new LHCb::TbKalmanNode(*this) ;
+//  rc->m_prevNode = rc->m_nextNode = 0 ;
+//  return rc ;
+//}
+
+//=========================================================================
+// Helper function to decide if we need to use the upstream filtered state
+//=========================================================================
+bool TbKalmanNode::hasInfoUpstream(int direction) const {
+  if (m_hasInfoUpstream[direction] == LHCb::TbKalmanNode::Unknown) {
+    bool rc = false;
+    const TbKalmanNode* prev = prevNode(direction);
+    if (prev) {
+      if (prev->hasInfo())
+        rc = true;
+      else
+        rc = prev->hasInfoUpstream(direction);
+    }
+    unConst().m_hasInfoUpstream[direction] =
+        rc ? LHCb::TbKalmanNode::True : LHCb::TbKalmanNode::False;
+  }
+  return (m_hasInfoUpstream[direction] == LHCb::TbKalmanNode::True);
+}
+
+void TbKalmanNode::resetHasInfoUpstream(int direction) {
+  m_hasInfoUpstream[direction] = False;
+  if (!hasInfo()) {
+    TbKalmanNode* next = const_cast<TbKalmanNode*>(nextNode(direction));
+    if (next) next->resetHasInfoUpstream(direction);
+  }
+}
+
+//=========================================================================
+// Reset the status of this node
+//=========================================================================
+void TbKalmanNode::resetFilterStatus(int direction, FilterStatus s) {
+  // The logic here is tedious, because of the smoothed states have
+  // a strange depence, which depends on the type of smoother.
+  if (m_filterStatus[direction] > s) {
+    m_filterStatus[direction] = s;
+
+    if (s < Filtered) {
+      // if the backward filter is in 'Smoothed' state, it needs to be
+      // reset to filtered, because the bi-directional smoother relies
+      // on both filtered states
+      if (m_filterStatus[Backward] ==
+          Smoothed)  // Note: Backward=Smoothed means 'bi-directional smoother'
+        m_filterStatus[Backward] = Filtered;
+
+      // reset the status of any node that depends on this one. now
+      // be careful: if this node has been copied it may be pointing
+      // to a wrong node.
+      const TbKalmanNode* next = nextNode(direction);
+      if (next && next->m_filterStatus[direction] > s &&
+          next->prevNode(direction) == this)
+        const_cast<TbKalmanNode*>(next)
+            ->resetFilterStatus(direction, std::min(s, Initialized));
+    }
+
+    if (direction == Forward) {
+      // for the classical filter, we actually need to put the
+      // upstream node back to filtered, if it is in a classicly
+      // smoothed status
+      const TbKalmanNode* prev = prevNode(Forward);
+      if (prev && prev->m_filterStatus[Forward] == Smoothed &&
+          prev->nextNode(Forward) ==
+              this)  // Note: Forward=Smoothed means 'classical smoother'
+        const_cast<TbKalmanNode*>(prev)->resetFilterStatus(Forward, Filtered);
+    }
+  }
+}
+
+//=========================================================================
+// Predict the state to this node
+//=========================================================================
+void TbKalmanNode::computePredictedState(int direction) {
+  //std::cout << "In TbKalmanNode::computePredictedState( "
+  //<< direction << " ) for node " << index() << std::endl ;
+
+  // get the filtered state from the previous node. if there wasn't
+  // any, we will want to copy the reference vector and leave the
+  // covariance the way it is
+  m_predictedState[direction].setZ(z());
+  StateParameters& stateVec = m_predictedState[direction].parameters();
+  StateCovariance& stateCov = m_predictedState[direction].covariance();
+
+  const TbKalmanNode* prevnode = prevNode(direction);
+  if (prevnode) {
+    const State& prevState = prevnode->filteredState(direction);
+    if (!hasInfoUpstream(direction)) {
+      // just _copy_ the covariance matrix from upstream, assuming
+      // that this is the seed matrix. (that saves us from copying
+      // the seed matrix to every state from the start.
+      stateCov = prevState.covariance();
+      // new: start the backward filter from the forward filter
+      if (direction == Backward) stateVec = filteredState(Forward).parameters();
+      //std::cout << "no information upstream. copying seed." << index() <<
+      //std::endl ;
+    } else {
+
+      // For the testbeam, the transport is really trivial, assuming x and y are
+      // uncorrelated
+      double dz = z() - prevnode->z();
+      stateVec = prevState.parameters();
+      stateVec[0] += dz * stateVec[2];
+      stateVec[1] += dz * stateVec[3];
+
+      // compute the predicted covariance
+      stateCov = prevState.covariance();
+      stateCov(0, 0) += 2 * dz * stateCov(0, 2) + dz * dz * stateCov(2, 2);
+      stateCov(0, 2) += dz * stateCov(2, 2);
+      stateCov(1, 1) += 2 * dz * stateCov(1, 3) + dz * dz * stateCov(3, 3);
+      stateCov(1, 3) += dz * stateCov(3, 3);
+
+      // finally add the noise, on the direction only
+      double Q = direction == Forward ? prevnode->m_Q : m_Q;
+      stateCov(2, 2) += Q;
+      stateCov(3, 3) += Q;
+    }
+  }
+  // update the status flag
+  m_filterStatus[direction] = Predicted;
+}
+
+//=========================================================================
+// Filter this node
+//=========================================================================
+void TbKalmanNode::computeFilteredState(int direction) {
+  //std::cout << "In TbKalmanNode::computeFilteredState( "
+  //          << direction << " ) for node " << index() << std::endl ;
+
+  // copy the predicted state
+  State& state = m_filteredState[direction];
+  state = predictedState(direction);
+
+  // apply the filter if needed
+  m_deltaChi2[direction] = filter(state);
+
+  //std::cout << "Filtering node " << index() << " " << direction
+  //<< " chi2 = "
+  //<< m_deltaChi2[direction] << std::endl ;
+
+  m_filterStatus[direction] = Filtered;
+}
+
+//=========================================================================
+// Bi-directional smoother
+//=========================================================================
+void TbKalmanNode::computeBiSmoothedState() {
+  //std::cout << "In TbKalmanNode::computeBiSmoothedState() for node " <<
+  //index() << std::endl ;
+
+  State& state = m_state;
+  if (!hasInfoUpstream(Forward)) {
+    // last node in backward direction
+    state = filteredState(Backward);
+  } else if (!hasInfoUpstream(Backward)) {
+    // last node in forward direction
+    state = filteredState(Forward);
+  } else {
+    // Take the weighted average of two states. We now need to
+    // choose for which one we take the filtered state. AFAIU the
+    // weighted average behaves better if the weights are more
+    // equal. So, we filter the 'worst' prediction. In the end, it
+    // all doesn't seem to make much difference.
+
+    const State* s1, *s2;
+    if (predictedState(Backward).covariance()(0, 0) >
+        predictedState(Forward).covariance()(0, 0)) {
+      s1 = &(filteredState(Backward));
+      s2 = &(predictedState(Forward));
+    } else {
+      s1 = &(filteredState(Forward));
+      s2 = &(predictedState(Backward));
+    }
+
+    const StateParameters& X1 = s1->parameters();
+    const StateCovariance& C1 = s1->covariance();
+    const StateParameters& X2 = s2->parameters();
+    const StateCovariance& C2 = s2->covariance();
+
+    //state = predictedState(Forward) ;
+    StateParameters& X = state.parameters();
+    StateCovariance& C = state.covariance();
+
+    // compute the inverse of the covariance in the difference: R=(C1+C2)
+    static StateCovariance invR;
+    invR = C1 + C2;
+    bool success = invR.InvertChol();
+    if (!success) {
+      std::cout << "error inverting cov matrix in smoother" << std::endl;
+      //&& !m_parent->inError())
+      //m_parent->setErrorFlag(2,KalmanFitResult::Smooth
+      //,KalmanFitResult::MatrixInversion ) ;
+    }
+    // compute the gain matrix:
+    static ROOT::Math::SMatrix<double, 4, 4> K;
+    K = C1 * invR;
+    X = X1 + K * (X2 - X1);
+    ROOT::Math::AssignSym::Evaluate(C, K * C2);
+    // the following used to be more stable, but isn't any longer, it seems:
+    //ROOT::Math::AssignSym::Evaluate(C, -2 * K * C1) ;
+    //C += C1 + ROOT::Math::Similarity(K,R) ;
+
+    //std::cout << "smoothing two states with errors on slope: "
+    //<< std::sqrt(C1(2,2)) << " " << std::sqrt(C2(2,2)) << " "
+    //<< std::sqrt(C(2,2)) << std::endl ;
+
+  }
+  //if(!isPositiveDiagonal(state.covariance())&& !m_parent->inError()){
+  //  m_parent->setErrorFlag(2,KalmanFitResult::Smooth
+  // ,KalmanFitResult::AlgError ) ;
+  //}
+  updateResidual(state);
+
+  // bug fix: we cannot set backward to state 'Smoothed', unless we have passed
+  // its filter step!
+  filteredState(Backward);
+  m_filterStatus[Backward] = Smoothed;
+}
+
+int TbKalmanNode::index() const {
+  int rc = 0;
+  if (m_prevNode) rc = m_prevNode->index() + 1;
+  return rc;
+}
+}
diff --git a/TbEvent/src/.svn/text-base/TbKalmanPixelMeasurement.cpp.svn-base b/TbEvent/src/.svn/text-base/TbKalmanPixelMeasurement.cpp.svn-base
new file mode 100644
index 0000000..b0fd9c4
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/TbKalmanPixelMeasurement.cpp.svn-base
@@ -0,0 +1,79 @@
+#include "Event/TbKalmanPixelMeasurement.h"
+#include "Event/TbKalmanTrack.h"
+
+namespace {
+/// Helper function to filter one hit
+inline double filterX(double& x, double& tx, double& covXX, double& covXTx,
+                      double& covTxTx, const double xhit,
+                      const double xhitcov) {
+  const double predcovXX = covXX;
+  const double predcovXTx = covXTx;
+  const double predcovTxTx = covTxTx;
+  const double predx = x;
+  const double predtx = tx;
+
+  // compute the gain matrix
+  const double R = xhitcov + predcovXX;
+  const double Kx = predcovXX / R;
+  const double KTx = predcovXTx / R;
+  // update the state vector
+  double r = xhit - predx;
+  x = predx + Kx * r;
+  tx = predtx + KTx * r;
+  // update the covariance matrix. we can write it in many ways ...
+  covXX /*= predcovXX  - Kx * predcovXX */ = (1 - Kx) * predcovXX;
+  covXTx /*= predcovXTx - predcovXX * predcovXTx / R */ = (1 - Kx) * predcovXTx;
+  covTxTx = predcovTxTx - KTx * predcovXTx;
+  // return the chi2
+  return r * r / R;
+}
+}
+
+namespace LHCb {
+
+LHCb::ChiSquare TbKalmanPixelMeasurement::filter(State& state) const {
+  // filter X and Y independently. could easily be complicated if needed.
+
+  double chi2(0);
+  Gaudi::SymMatrix4x4& stateCov = state.covariance();
+  Gaudi::Vector4& stateVec = state.parameters();
+
+  // first X
+  chi2 += filterX(stateVec(0), stateVec(2), stateCov(0, 0), stateCov(0, 2),
+                  stateCov(2, 2), m_x, m_covx);
+
+  // then Y
+  chi2 += filterX(stateVec(1), stateVec(3), stateCov(1, 1), stateCov(1, 3),
+                  stateCov(3, 3), m_y, m_covy);
+  // chi2 has 2 dofs
+
+  return LHCb::ChiSquare(chi2, 2);
+}
+
+// compute residual with respect to given (smoothed) state
+void TbKalmanPixelMeasurement::updateResidual(const State& state) {
+  m_residualX = m_x - state.x();
+  m_residualY = m_y - state.y();
+  int sign = m_isactive ? -1 : +1;
+  m_residualCovX = m_covx + sign * state.covariance()(0, 0);
+  m_residualCovY = m_covy + sign * state.covariance()(1, 1);
+}
+
+void TbKalmanPixelMeasurement::deactivateMeasurement(bool deactivate) {
+  // only do something if this is actually an active hit
+  if ((deactivate && m_isactive) || (!deactivate && !m_isactive)) {
+    // set type to outlier
+    m_isactive = !deactivate;
+    // this will take care of upstream and downstream nodes as well:
+    // they will be reset to initialized. we need to check this
+    // carefully
+    resetFilterStatus(Predicted);
+    // make sure the KalmanFitResult knows something has changed
+    if (parent()) parent()->resetCache();
+    // now make sure others do not rely on this one anymore
+    if (!hasInfoUpstream(Forward)) resetHasInfoUpstream(Forward);
+    if (!hasInfoUpstream(Backward)) resetHasInfoUpstream(Backward);
+  }
+}
+
+}
diff --git a/TbEvent/src/.svn/text-base/TbKalmanTrack.cpp.svn-base b/TbEvent/src/.svn/text-base/TbKalmanTrack.cpp.svn-base
new file mode 100644
index 0000000..331fc45
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/TbKalmanTrack.cpp.svn-base
@@ -0,0 +1,168 @@
+
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanPixelMeasurement.h"
+
+namespace {
+
+struct OrderInZ {
+  bool operator()(const LHCb::TbKalmanNode* lhs,
+                  const LHCb::TbKalmanNode* rhs) const {
+    return lhs->z() < rhs->z();
+  }
+};
+
+double errorfromcov(double cov) { return cov > 0 ? std::sqrt(cov) : cov; }
+
+void printState(const LHCb::TbState& state, std::ostream& os) {
+  os << "(" << state.parameters()(0) << "," << state.parameters()(1) << ","
+     << state.parameters()(2) << "," << state.parameters()(3) << ") +/- ("
+     << errorfromcov(state.covariance()(0, 0)) << ","
+     << errorfromcov(state.covariance()(1, 1)) << ","
+     << errorfromcov(state.covariance()(2, 2)) << ","
+     << errorfromcov(state.covariance()(3, 3)) << ")";
+}
+}
+
+namespace LHCb {
+//============================================================================
+// Constructor
+//============================================================================
+TbKalmanTrack::TbKalmanTrack(const LHCb::TbTrack& track, const double hiterror2,
+                             const double noise2)
+    : TbTrack(track) {
+  // Create nodes for all clusters
+  for (const LHCb::TbCluster* cluster : track.clusters()) {
+    TbKalmanNode* node = new TbKalmanPixelMeasurement(*this, *cluster, hiterror2);
+    node->setNoise2(noise2);
+    m_nodes.push_back(node);
+  }
+
+  // Make sure they are sorted in z
+  std::sort(m_nodes.begin(), m_nodes.end(), OrderInZ());
+
+  // Now set the links
+  TbKalmanNode* prevnode(nullptr);
+  for (LHCb::TbKalmanNode* node : m_nodes) {
+    node->link(prevnode);
+    prevnode = node;
+  }
+}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbKalmanTrack::~TbKalmanTrack() {
+  for (LHCb::TbKalmanNode* node : m_nodes) delete node;
+}
+
+//============================================================================
+// Add a node
+//============================================================================
+void TbKalmanTrack::addNode(TbKalmanNode* node) {
+  // This can be optimized a little bit by insorting in the right place.
+  // If so, make sure to fix the 'link' method in TbKalmanNode
+  m_nodes.push_back(node);
+  // Make sure the nodes are sorted in z
+  std::sort(m_nodes.begin(), m_nodes.end(), OrderInZ());
+  // Now set the links
+  TbKalmanNode* prevnode(nullptr);
+  for (LHCb::TbKalmanNode* node : m_nodes) {
+    node->link(prevnode);
+    prevnode = node;
+  }
+}
+
+//============================================================================
+// Add a reference node 
+//============================================================================
+void TbKalmanTrack::addReferenceNode(double z) {
+  addNode(new TbKalmanNode(*this, z));
+}
+
+//============================================================================
+// Deactivate a measurement 
+//============================================================================
+void TbKalmanTrack::deactivateCluster(const TbCluster& clus) {
+  for (LHCb::TbKalmanNode* node : m_nodes) {
+    TbKalmanPixelMeasurement* meas =
+        dynamic_cast<TbKalmanPixelMeasurement*>(node);
+    if (meas && &(meas->cluster()) == &clus)
+      meas->deactivateMeasurement(true);
+  }
+}
+
+//============================================================================
+// Perform the fit
+//============================================================================
+void TbKalmanTrack::fit() {
+  // remove existing states
+  clearStates();
+
+  // do the fit
+  if (!m_nodes.empty()) {
+    // initialize the seed: very simple for now. later we may want
+    // to run some iterations and then this becomes more
+    // complicated.
+    LHCb::TbState seedstate(firstState());
+    Gaudi::SymMatrix4x4 seedcov;
+    seedcov(0, 0) = seedcov(1, 1) = 1e4;
+    seedcov(2, 2) = seedcov(3, 3) = 1;
+    seedstate.covariance() = seedcov;
+    m_nodes.front()->setSeed(seedstate);
+    m_nodes.back()->setSeed(seedstate);
+
+    // everything happens on demand, I hope. so all we need to do is copy the
+    // smoothed states back.
+    LHCb::ChiSquare chi2(0, -4);
+    for (LHCb::TbKalmanNode* node : m_nodes) {
+      // get the smoothed state
+      addToStates(node->state());
+      // add to the chi2
+      chi2 += node->deltaChi2(0);
+    }
+
+    setNdof(chi2.nDoF());
+    if (chi2.nDoF() > 0) {
+      setChi2PerNdof(chi2.chi2() / chi2.nDoF());
+    } else {
+      setChi2PerNdof(0);
+    }
+  }
+}
+
+//============================================================================
+// Print some debug info
+//============================================================================
+void TbKalmanTrack::print() const {
+  std::cout << "This is a kalman fitted tracks with chi2/ndof=" << chi2() << "/"
+            << ndof() << std::endl;
+  // compute forward/backward chi2
+  LHCb::ChiSquare forwardchi2, backwardchi2;
+  double chi2X(0), chi2Y(0);
+  std::cout << "These are the nodes, with some residuals: " << std::endl;
+  for (const LHCb::TbKalmanNode * node : m_nodes) {
+    std::cout << node->index() << " " << node->z() << " ";
+    //<< node->hasInfoUpstream( LHCb::TbKalmanNode::Forward) << " "
+    //<< node->hasInfoUpstream( LHCb::TbKalmanNode::Backward) << " " ;
+    printState(node->state(), std::cout);
+    //std::cout << node->filterStatus( LHCb::TbKalmanNode::Forward) << " "
+    //<< node->filterStatus( LHCb::TbKalmanNode::Backward) << " " ;
+    const TbKalmanPixelMeasurement* pixelhit =
+        dynamic_cast<const TbKalmanPixelMeasurement*>(node);
+    if (pixelhit) {
+      std::cout << "residual x = " << pixelhit->residualX() << " +/- "
+                << std::sqrt(pixelhit->residualCovX()) << " "
+                << "residual y = " << pixelhit->residualY() << " +/- "
+                << std::sqrt(pixelhit->residualCovY()) << " ";
+      chi2X += pixelhit->residualX() * pixelhit->residualX() / pixelhit->covX();
+      chi2Y += pixelhit->residualY() * pixelhit->residualY() / pixelhit->covY();
+    }
+    std::cout << std::endl;
+    forwardchi2 += node->deltaChi2(LHCb::TbKalmanNode::Forward);
+    backwardchi2 += node->deltaChi2(LHCb::TbKalmanNode::Backward);
+  }
+  std::cout << "Forward/backward chi2: " << forwardchi2.chi2() << "/"
+            << backwardchi2.chi2() << std::endl;
+  std::cout << "X/Y chi2: " << chi2X << "/" << chi2Y << std::endl;
+}
+}
diff --git a/TbEvent/src/.svn/text-base/TbState.cpp.svn-base b/TbEvent/src/.svn/text-base/TbState.cpp.svn-base
new file mode 100644
index 0000000..820b6b0
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/TbState.cpp.svn-base
@@ -0,0 +1,19 @@
+#include "Event/TbState.h"
+
+using namespace LHCb;
+
+//=============================================================================
+// Update the state vector
+//=============================================================================
+void TbState::setState(double x, double y, double tx, double ty, double z) {
+  m_parameters[0] = x;
+  m_parameters[1] = y;
+  m_parameters[2] = tx;
+  m_parameters[3] = ty;
+  m_z = z;
+}
+
+//=============================================================================
+// Clone the state
+//=============================================================================
+TbState* TbState::clone() const { return new TbState(*this); }
diff --git a/TbEvent/src/.svn/text-base/TbTrack.cpp.svn-base b/TbEvent/src/.svn/text-base/TbTrack.cpp.svn-base
new file mode 100644
index 0000000..081c61d
--- /dev/null
+++ b/TbEvent/src/.svn/text-base/TbTrack.cpp.svn-base
@@ -0,0 +1,57 @@
+#include "Event/TbTrack.h"
+
+using namespace LHCb;
+
+//=============================================================================
+// Track copy constructor 
+//=============================================================================
+TbTrack::TbTrack(const LHCb::TbTrack& rhs) :
+  KeyedObject<int>(),
+  m_time(rhs.m_time),
+  m_htime(rhs.m_htime),
+  m_firstState(rhs.m_firstState),
+  m_chi2PerNdof(rhs.m_chi2PerNdof),
+  m_ndof(rhs.m_ndof),
+  m_clusters(rhs.m_clusters),
+  m_triggers(rhs.m_triggers),
+  m_associatedClusters(rhs.m_associatedClusters) {
+
+  // Copy the states
+  for (auto it = rhs.m_states.begin(), end = rhs.m_states.end(); it != end; ++it) {
+    addToStates(*it);
+  }
+}
+
+
+//=============================================================================
+// Track clone method
+//=============================================================================
+TbTrack* TbTrack::clone() {
+  TbTrack* track = new TbTrack();
+  track->setTime(time());
+  track->setHtime(htime());
+  track->setFirstState(firstState());
+  track->setChi2PerNdof(chi2PerNdof());
+  track->setNdof(ndof());
+
+  // Copy the states
+  for (auto it = m_states.begin(), end = m_states.end(); it != end; ++it) {
+    track->addToStates(*it);
+  }
+
+  return track;
+}
+
+//=============================================================================
+// States clone method
+//=============================================================================
+void TbTrack::addToStates(const TbState& state) {
+  m_states.push_back(state);
+}
+
+//=============================================================================
+// Clear the states
+//=============================================================================
+void TbTrack::clearStates() {
+  m_states.clear() ;
+}
diff --git a/TbEvent/src/ChiSquare.cpp b/TbEvent/src/ChiSquare.cpp
new file mode 100644
index 0000000..9a66641
--- /dev/null
+++ b/TbEvent/src/ChiSquare.cpp
@@ -0,0 +1,15 @@
+// local
+#include "Event/ChiSquare.h"
+#include "gsl/gsl_cdf.h"
+
+namespace LHCb {
+double ChiSquare::prob() const {
+  double val(0);
+  if (nDoF() > 0) {
+    const double limit = 1e-15;
+    double chi2max = gsl_cdf_chisq_Qinv(limit, nDoF());
+    val = chi2() < chi2max ? gsl_cdf_chisq_Q(chi2(), nDoF()) : 0;
+  }
+  return val;
+}
+}
diff --git a/TbEvent/src/TbCluster.cpp b/TbEvent/src/TbCluster.cpp
new file mode 100644
index 0000000..f62e5f6
--- /dev/null
+++ b/TbEvent/src/TbCluster.cpp
@@ -0,0 +1,22 @@
+#include "Event/TbCluster.h"
+
+using namespace LHCb;
+
+//=============================================================================
+// Clone method
+//=============================================================================
+TbCluster *TbCluster::clone() {
+  TbCluster *c = new TbCluster();
+  c->setX(x());
+  c->setY(y());
+  c->setZ(z());
+  c->setXloc(xloc());
+  c->setYloc(yloc());
+  c->setCharge(charge());
+  c->setPlane(plane());
+  c->setTime(time());
+  c->setXErr(xErr());
+  c->setYErr(yErr());
+  return c;
+}
+
diff --git a/TbEvent/src/TbKalmanNode.cpp b/TbEvent/src/TbKalmanNode.cpp
new file mode 100755
index 0000000..f71a803
--- /dev/null
+++ b/TbEvent/src/TbKalmanNode.cpp
@@ -0,0 +1,282 @@
+// local
+#include "Event/TbKalmanNode.h"
+
+/** @file FitNode.cpp
+ *
+ *  This File contains the implementation of the FitNode.
+ *  A FitNode is a basket of objects at a given z position.
+ *  The information inside the FitNode has to be sufficient
+ *  to allow smoothing and refitting.
+ *  At the moment a FitNode contains or allows you to access
+ *  info on the the (kth) measurement,
+ *  transport from k --> k + 1 , predicted state at k+1
+ *  (predicted from filter step)  and the best state at k
+ *  (notation note filter procedes from k -> k + 1 -> k + 2 ......)
+ * 
+ *  @author Victor Coco and Wouter Hulsbergen (moved K-math here)
+ *  @date   2011-02-01
+ *
+ *  @author Eduardo Rodrigues (adaptations to the new track event model)
+ *  @date   2005-04-15
+ *
+ *  @author Matt Needham
+ *  @date   11-11-1999
+ */
+
+namespace LHCb {
+
+/// Standard constructor, initializes variables
+// TbKalmanNode::TbKalmanNode():
+//   m_prevNode(0),
+//   m_nextNode(0),
+//   m_parent(0)
+// {
+//   // TbKalmanNode default constructor
+//   m_filterStatus[Forward] = m_filterStatus[Backward] = Uninitialized ;
+//   m_hasInfoUpstream[Forward] = m_hasInfoUpstream[Backward] = Unknown ;
+// }
+
+/// Constructor from a z position
+TbKalmanNode::TbKalmanNode(TbKalmanTrack& parent, double z)
+    : m_parent(&parent), m_prevNode(0), m_nextNode(0), m_Q(0) {
+  m_state.setZ(z);
+  m_filterStatus[Forward] = m_filterStatus[Backward] = Uninitialized;
+  m_hasInfoUpstream[Forward] = m_hasInfoUpstream[Backward] = Unknown;
+}
+
+/// Destructor
+TbKalmanNode::~TbKalmanNode() {
+  if (m_prevNode && m_prevNode->m_nextNode == this) m_prevNode->m_nextNode = 0;
+  if (m_nextNode && m_nextNode->m_prevNode == this) m_nextNode->m_prevNode = 0;
+}
+
+// Clone the node
+//LHCb::TbKalmanNode* TbKalmanNode::clone() const
+//{
+//  LHCb::TbKalmanNode* rc = new LHCb::TbKalmanNode(*this) ;
+//  rc->m_prevNode = rc->m_nextNode = 0 ;
+//  return rc ;
+//}
+
+//=========================================================================
+// Helper function to decide if we need to use the upstream filtered state
+//=========================================================================
+bool TbKalmanNode::hasInfoUpstream(int direction) const {
+  if (m_hasInfoUpstream[direction] == LHCb::TbKalmanNode::Unknown) {
+    bool rc = false;
+    const TbKalmanNode* prev = prevNode(direction);
+    if (prev) {
+      if (prev->hasInfo())
+        rc = true;
+      else
+        rc = prev->hasInfoUpstream(direction);
+    }
+    unConst().m_hasInfoUpstream[direction] =
+        rc ? LHCb::TbKalmanNode::True : LHCb::TbKalmanNode::False;
+  }
+  return (m_hasInfoUpstream[direction] == LHCb::TbKalmanNode::True);
+}
+
+void TbKalmanNode::resetHasInfoUpstream(int direction) {
+  m_hasInfoUpstream[direction] = False;
+  if (!hasInfo()) {
+    TbKalmanNode* next = const_cast<TbKalmanNode*>(nextNode(direction));
+    if (next) next->resetHasInfoUpstream(direction);
+  }
+}
+
+//=========================================================================
+// Reset the status of this node
+//=========================================================================
+void TbKalmanNode::resetFilterStatus(int direction, FilterStatus s) {
+  // The logic here is tedious, because of the smoothed states have
+  // a strange depence, which depends on the type of smoother.
+  if (m_filterStatus[direction] > s) {
+    m_filterStatus[direction] = s;
+
+    if (s < Filtered) {
+      // if the backward filter is in 'Smoothed' state, it needs to be
+      // reset to filtered, because the bi-directional smoother relies
+      // on both filtered states
+      if (m_filterStatus[Backward] ==
+          Smoothed)  // Note: Backward=Smoothed means 'bi-directional smoother'
+        m_filterStatus[Backward] = Filtered;
+
+      // reset the status of any node that depends on this one. now
+      // be careful: if this node has been copied it may be pointing
+      // to a wrong node.
+      const TbKalmanNode* next = nextNode(direction);
+      if (next && next->m_filterStatus[direction] > s &&
+          next->prevNode(direction) == this)
+        const_cast<TbKalmanNode*>(next)
+            ->resetFilterStatus(direction, std::min(s, Initialized));
+    }
+
+    if (direction == Forward) {
+      // for the classical filter, we actually need to put the
+      // upstream node back to filtered, if it is in a classicly
+      // smoothed status
+      const TbKalmanNode* prev = prevNode(Forward);
+      if (prev && prev->m_filterStatus[Forward] == Smoothed &&
+          prev->nextNode(Forward) ==
+              this)  // Note: Forward=Smoothed means 'classical smoother'
+        const_cast<TbKalmanNode*>(prev)->resetFilterStatus(Forward, Filtered);
+    }
+  }
+}
+
+//=========================================================================
+// Predict the state to this node
+//=========================================================================
+void TbKalmanNode::computePredictedState(int direction) {
+  //std::cout << "In TbKalmanNode::computePredictedState( "
+  //<< direction << " ) for node " << index() << std::endl ;
+
+  // get the filtered state from the previous node. if there wasn't
+  // any, we will want to copy the reference vector and leave the
+  // covariance the way it is
+  m_predictedState[direction].setZ(z());
+  StateParameters& stateVec = m_predictedState[direction].parameters();
+  StateCovariance& stateCov = m_predictedState[direction].covariance();
+
+  const TbKalmanNode* prevnode = prevNode(direction);
+  if (prevnode) {
+    const State& prevState = prevnode->filteredState(direction);
+    if (!hasInfoUpstream(direction)) {
+      // just _copy_ the covariance matrix from upstream, assuming
+      // that this is the seed matrix. (that saves us from copying
+      // the seed matrix to every state from the start.
+      stateCov = prevState.covariance();
+      // new: start the backward filter from the forward filter
+      if (direction == Backward) stateVec = filteredState(Forward).parameters();
+      //std::cout << "no information upstream. copying seed." << index() <<
+      //std::endl ;
+    } else {
+
+      // For the testbeam, the transport is really trivial, assuming x and y are
+      // uncorrelated
+      double dz = z() - prevnode->z();
+      stateVec = prevState.parameters();
+      stateVec[0] += dz * stateVec[2];
+      stateVec[1] += dz * stateVec[3];
+
+      // compute the predicted covariance
+      stateCov = prevState.covariance();
+      stateCov(0, 0) += 2 * dz * stateCov(0, 2) + dz * dz * stateCov(2, 2);
+      stateCov(0, 2) += dz * stateCov(2, 2);
+      stateCov(1, 1) += 2 * dz * stateCov(1, 3) + dz * dz * stateCov(3, 3);
+      stateCov(1, 3) += dz * stateCov(3, 3);
+
+      // finally add the noise, on the direction only
+      double Q = direction == Forward ? prevnode->m_Q : m_Q;
+      stateCov(2, 2) += Q;
+      stateCov(3, 3) += Q;
+    }
+  }
+  // update the status flag
+  m_filterStatus[direction] = Predicted;
+}
+
+//=========================================================================
+// Filter this node
+//=========================================================================
+void TbKalmanNode::computeFilteredState(int direction) {
+  //std::cout << "In TbKalmanNode::computeFilteredState( "
+  //          << direction << " ) for node " << index() << std::endl ;
+
+  // copy the predicted state
+  State& state = m_filteredState[direction];
+  state = predictedState(direction);
+
+  // apply the filter if needed
+  m_deltaChi2[direction] = filter(state);
+
+  //std::cout << "Filtering node " << index() << " " << direction
+  //<< " chi2 = "
+  //<< m_deltaChi2[direction] << std::endl ;
+
+  m_filterStatus[direction] = Filtered;
+}
+
+//=========================================================================
+// Bi-directional smoother
+//=========================================================================
+void TbKalmanNode::computeBiSmoothedState() {
+  //std::cout << "In TbKalmanNode::computeBiSmoothedState() for node " <<
+  //index() << std::endl ;
+
+  State& state = m_state;
+  if (!hasInfoUpstream(Forward)) {
+    // last node in backward direction
+    state = filteredState(Backward);
+  } else if (!hasInfoUpstream(Backward)) {
+    // last node in forward direction
+    state = filteredState(Forward);
+  } else {
+    // Take the weighted average of two states. We now need to
+    // choose for which one we take the filtered state. AFAIU the
+    // weighted average behaves better if the weights are more
+    // equal. So, we filter the 'worst' prediction. In the end, it
+    // all doesn't seem to make much difference.
+
+    const State* s1, *s2;
+    if (predictedState(Backward).covariance()(0, 0) >
+        predictedState(Forward).covariance()(0, 0)) {
+      s1 = &(filteredState(Backward));
+      s2 = &(predictedState(Forward));
+    } else {
+      s1 = &(filteredState(Forward));
+      s2 = &(predictedState(Backward));
+    }
+
+    const StateParameters& X1 = s1->parameters();
+    const StateCovariance& C1 = s1->covariance();
+    const StateParameters& X2 = s2->parameters();
+    const StateCovariance& C2 = s2->covariance();
+
+    //state = predictedState(Forward) ;
+    StateParameters& X = state.parameters();
+    StateCovariance& C = state.covariance();
+
+    // compute the inverse of the covariance in the difference: R=(C1+C2)
+    static StateCovariance invR;
+    invR = C1 + C2;
+    bool success = invR.InvertChol();
+    if (!success) {
+      std::cout << "error inverting cov matrix in smoother" << std::endl;
+      //&& !m_parent->inError())
+      //m_parent->setErrorFlag(2,KalmanFitResult::Smooth
+      //,KalmanFitResult::MatrixInversion ) ;
+    }
+    // compute the gain matrix:
+    static ROOT::Math::SMatrix<double, 4, 4> K;
+    K = C1 * invR;
+    X = X1 + K * (X2 - X1);
+    ROOT::Math::AssignSym::Evaluate(C, K * C2);
+    // the following used to be more stable, but isn't any longer, it seems:
+    //ROOT::Math::AssignSym::Evaluate(C, -2 * K * C1) ;
+    //C += C1 + ROOT::Math::Similarity(K,R) ;
+
+    //std::cout << "smoothing two states with errors on slope: "
+    //<< std::sqrt(C1(2,2)) << " " << std::sqrt(C2(2,2)) << " "
+    //<< std::sqrt(C(2,2)) << std::endl ;
+
+  }
+  //if(!isPositiveDiagonal(state.covariance())&& !m_parent->inError()){
+  //  m_parent->setErrorFlag(2,KalmanFitResult::Smooth
+  // ,KalmanFitResult::AlgError ) ;
+  //}
+  updateResidual(state);
+
+  // bug fix: we cannot set backward to state 'Smoothed', unless we have passed
+  // its filter step!
+  filteredState(Backward);
+  m_filterStatus[Backward] = Smoothed;
+}
+
+int TbKalmanNode::index() const {
+  int rc = 0;
+  if (m_prevNode) rc = m_prevNode->index() + 1;
+  return rc;
+}
+}
diff --git a/TbEvent/src/TbKalmanPixelMeasurement.cpp b/TbEvent/src/TbKalmanPixelMeasurement.cpp
new file mode 100644
index 0000000..b0fd9c4
--- /dev/null
+++ b/TbEvent/src/TbKalmanPixelMeasurement.cpp
@@ -0,0 +1,79 @@
+#include "Event/TbKalmanPixelMeasurement.h"
+#include "Event/TbKalmanTrack.h"
+
+namespace {
+/// Helper function to filter one hit
+inline double filterX(double& x, double& tx, double& covXX, double& covXTx,
+                      double& covTxTx, const double xhit,
+                      const double xhitcov) {
+  const double predcovXX = covXX;
+  const double predcovXTx = covXTx;
+  const double predcovTxTx = covTxTx;
+  const double predx = x;
+  const double predtx = tx;
+
+  // compute the gain matrix
+  const double R = xhitcov + predcovXX;
+  const double Kx = predcovXX / R;
+  const double KTx = predcovXTx / R;
+  // update the state vector
+  double r = xhit - predx;
+  x = predx + Kx * r;
+  tx = predtx + KTx * r;
+  // update the covariance matrix. we can write it in many ways ...
+  covXX /*= predcovXX  - Kx * predcovXX */ = (1 - Kx) * predcovXX;
+  covXTx /*= predcovXTx - predcovXX * predcovXTx / R */ = (1 - Kx) * predcovXTx;
+  covTxTx = predcovTxTx - KTx * predcovXTx;
+  // return the chi2
+  return r * r / R;
+}
+}
+
+namespace LHCb {
+
+LHCb::ChiSquare TbKalmanPixelMeasurement::filter(State& state) const {
+  // filter X and Y independently. could easily be complicated if needed.
+
+  double chi2(0);
+  Gaudi::SymMatrix4x4& stateCov = state.covariance();
+  Gaudi::Vector4& stateVec = state.parameters();
+
+  // first X
+  chi2 += filterX(stateVec(0), stateVec(2), stateCov(0, 0), stateCov(0, 2),
+                  stateCov(2, 2), m_x, m_covx);
+
+  // then Y
+  chi2 += filterX(stateVec(1), stateVec(3), stateCov(1, 1), stateCov(1, 3),
+                  stateCov(3, 3), m_y, m_covy);
+  // chi2 has 2 dofs
+
+  return LHCb::ChiSquare(chi2, 2);
+}
+
+// compute residual with respect to given (smoothed) state
+void TbKalmanPixelMeasurement::updateResidual(const State& state) {
+  m_residualX = m_x - state.x();
+  m_residualY = m_y - state.y();
+  int sign = m_isactive ? -1 : +1;
+  m_residualCovX = m_covx + sign * state.covariance()(0, 0);
+  m_residualCovY = m_covy + sign * state.covariance()(1, 1);
+}
+
+void TbKalmanPixelMeasurement::deactivateMeasurement(bool deactivate) {
+  // only do something if this is actually an active hit
+  if ((deactivate && m_isactive) || (!deactivate && !m_isactive)) {
+    // set type to outlier
+    m_isactive = !deactivate;
+    // this will take care of upstream and downstream nodes as well:
+    // they will be reset to initialized. we need to check this
+    // carefully
+    resetFilterStatus(Predicted);
+    // make sure the KalmanFitResult knows something has changed
+    if (parent()) parent()->resetCache();
+    // now make sure others do not rely on this one anymore
+    if (!hasInfoUpstream(Forward)) resetHasInfoUpstream(Forward);
+    if (!hasInfoUpstream(Backward)) resetHasInfoUpstream(Backward);
+  }
+}
+
+}
diff --git a/TbEvent/src/TbKalmanTrack.cpp b/TbEvent/src/TbKalmanTrack.cpp
new file mode 100644
index 0000000..331fc45
--- /dev/null
+++ b/TbEvent/src/TbKalmanTrack.cpp
@@ -0,0 +1,168 @@
+
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanPixelMeasurement.h"
+
+namespace {
+
+struct OrderInZ {
+  bool operator()(const LHCb::TbKalmanNode* lhs,
+                  const LHCb::TbKalmanNode* rhs) const {
+    return lhs->z() < rhs->z();
+  }
+};
+
+double errorfromcov(double cov) { return cov > 0 ? std::sqrt(cov) : cov; }
+
+void printState(const LHCb::TbState& state, std::ostream& os) {
+  os << "(" << state.parameters()(0) << "," << state.parameters()(1) << ","
+     << state.parameters()(2) << "," << state.parameters()(3) << ") +/- ("
+     << errorfromcov(state.covariance()(0, 0)) << ","
+     << errorfromcov(state.covariance()(1, 1)) << ","
+     << errorfromcov(state.covariance()(2, 2)) << ","
+     << errorfromcov(state.covariance()(3, 3)) << ")";
+}
+}
+
+namespace LHCb {
+//============================================================================
+// Constructor
+//============================================================================
+TbKalmanTrack::TbKalmanTrack(const LHCb::TbTrack& track, const double hiterror2,
+                             const double noise2)
+    : TbTrack(track) {
+  // Create nodes for all clusters
+  for (const LHCb::TbCluster* cluster : track.clusters()) {
+    TbKalmanNode* node = new TbKalmanPixelMeasurement(*this, *cluster, hiterror2);
+    node->setNoise2(noise2);
+    m_nodes.push_back(node);
+  }
+
+  // Make sure they are sorted in z
+  std::sort(m_nodes.begin(), m_nodes.end(), OrderInZ());
+
+  // Now set the links
+  TbKalmanNode* prevnode(nullptr);
+  for (LHCb::TbKalmanNode* node : m_nodes) {
+    node->link(prevnode);
+    prevnode = node;
+  }
+}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbKalmanTrack::~TbKalmanTrack() {
+  for (LHCb::TbKalmanNode* node : m_nodes) delete node;
+}
+
+//============================================================================
+// Add a node
+//============================================================================
+void TbKalmanTrack::addNode(TbKalmanNode* node) {
+  // This can be optimized a little bit by insorting in the right place.
+  // If so, make sure to fix the 'link' method in TbKalmanNode
+  m_nodes.push_back(node);
+  // Make sure the nodes are sorted in z
+  std::sort(m_nodes.begin(), m_nodes.end(), OrderInZ());
+  // Now set the links
+  TbKalmanNode* prevnode(nullptr);
+  for (LHCb::TbKalmanNode* node : m_nodes) {
+    node->link(prevnode);
+    prevnode = node;
+  }
+}
+
+//============================================================================
+// Add a reference node 
+//============================================================================
+void TbKalmanTrack::addReferenceNode(double z) {
+  addNode(new TbKalmanNode(*this, z));
+}
+
+//============================================================================
+// Deactivate a measurement 
+//============================================================================
+void TbKalmanTrack::deactivateCluster(const TbCluster& clus) {
+  for (LHCb::TbKalmanNode* node : m_nodes) {
+    TbKalmanPixelMeasurement* meas =
+        dynamic_cast<TbKalmanPixelMeasurement*>(node);
+    if (meas && &(meas->cluster()) == &clus)
+      meas->deactivateMeasurement(true);
+  }
+}
+
+//============================================================================
+// Perform the fit
+//============================================================================
+void TbKalmanTrack::fit() {
+  // remove existing states
+  clearStates();
+
+  // do the fit
+  if (!m_nodes.empty()) {
+    // initialize the seed: very simple for now. later we may want
+    // to run some iterations and then this becomes more
+    // complicated.
+    LHCb::TbState seedstate(firstState());
+    Gaudi::SymMatrix4x4 seedcov;
+    seedcov(0, 0) = seedcov(1, 1) = 1e4;
+    seedcov(2, 2) = seedcov(3, 3) = 1;
+    seedstate.covariance() = seedcov;
+    m_nodes.front()->setSeed(seedstate);
+    m_nodes.back()->setSeed(seedstate);
+
+    // everything happens on demand, I hope. so all we need to do is copy the
+    // smoothed states back.
+    LHCb::ChiSquare chi2(0, -4);
+    for (LHCb::TbKalmanNode* node : m_nodes) {
+      // get the smoothed state
+      addToStates(node->state());
+      // add to the chi2
+      chi2 += node->deltaChi2(0);
+    }
+
+    setNdof(chi2.nDoF());
+    if (chi2.nDoF() > 0) {
+      setChi2PerNdof(chi2.chi2() / chi2.nDoF());
+    } else {
+      setChi2PerNdof(0);
+    }
+  }
+}
+
+//============================================================================
+// Print some debug info
+//============================================================================
+void TbKalmanTrack::print() const {
+  std::cout << "This is a kalman fitted tracks with chi2/ndof=" << chi2() << "/"
+            << ndof() << std::endl;
+  // compute forward/backward chi2
+  LHCb::ChiSquare forwardchi2, backwardchi2;
+  double chi2X(0), chi2Y(0);
+  std::cout << "These are the nodes, with some residuals: " << std::endl;
+  for (const LHCb::TbKalmanNode * node : m_nodes) {
+    std::cout << node->index() << " " << node->z() << " ";
+    //<< node->hasInfoUpstream( LHCb::TbKalmanNode::Forward) << " "
+    //<< node->hasInfoUpstream( LHCb::TbKalmanNode::Backward) << " " ;
+    printState(node->state(), std::cout);
+    //std::cout << node->filterStatus( LHCb::TbKalmanNode::Forward) << " "
+    //<< node->filterStatus( LHCb::TbKalmanNode::Backward) << " " ;
+    const TbKalmanPixelMeasurement* pixelhit =
+        dynamic_cast<const TbKalmanPixelMeasurement*>(node);
+    if (pixelhit) {
+      std::cout << "residual x = " << pixelhit->residualX() << " +/- "
+                << std::sqrt(pixelhit->residualCovX()) << " "
+                << "residual y = " << pixelhit->residualY() << " +/- "
+                << std::sqrt(pixelhit->residualCovY()) << " ";
+      chi2X += pixelhit->residualX() * pixelhit->residualX() / pixelhit->covX();
+      chi2Y += pixelhit->residualY() * pixelhit->residualY() / pixelhit->covY();
+    }
+    std::cout << std::endl;
+    forwardchi2 += node->deltaChi2(LHCb::TbKalmanNode::Forward);
+    backwardchi2 += node->deltaChi2(LHCb::TbKalmanNode::Backward);
+  }
+  std::cout << "Forward/backward chi2: " << forwardchi2.chi2() << "/"
+            << backwardchi2.chi2() << std::endl;
+  std::cout << "X/Y chi2: " << chi2X << "/" << chi2Y << std::endl;
+}
+}
diff --git a/TbEvent/src/TbState.cpp b/TbEvent/src/TbState.cpp
new file mode 100644
index 0000000..820b6b0
--- /dev/null
+++ b/TbEvent/src/TbState.cpp
@@ -0,0 +1,19 @@
+#include "Event/TbState.h"
+
+using namespace LHCb;
+
+//=============================================================================
+// Update the state vector
+//=============================================================================
+void TbState::setState(double x, double y, double tx, double ty, double z) {
+  m_parameters[0] = x;
+  m_parameters[1] = y;
+  m_parameters[2] = tx;
+  m_parameters[3] = ty;
+  m_z = z;
+}
+
+//=============================================================================
+// Clone the state
+//=============================================================================
+TbState* TbState::clone() const { return new TbState(*this); }
diff --git a/TbEvent/src/TbTrack.cpp b/TbEvent/src/TbTrack.cpp
new file mode 100644
index 0000000..081c61d
--- /dev/null
+++ b/TbEvent/src/TbTrack.cpp
@@ -0,0 +1,57 @@
+#include "Event/TbTrack.h"
+
+using namespace LHCb;
+
+//=============================================================================
+// Track copy constructor 
+//=============================================================================
+TbTrack::TbTrack(const LHCb::TbTrack& rhs) :
+  KeyedObject<int>(),
+  m_time(rhs.m_time),
+  m_htime(rhs.m_htime),
+  m_firstState(rhs.m_firstState),
+  m_chi2PerNdof(rhs.m_chi2PerNdof),
+  m_ndof(rhs.m_ndof),
+  m_clusters(rhs.m_clusters),
+  m_triggers(rhs.m_triggers),
+  m_associatedClusters(rhs.m_associatedClusters) {
+
+  // Copy the states
+  for (auto it = rhs.m_states.begin(), end = rhs.m_states.end(); it != end; ++it) {
+    addToStates(*it);
+  }
+}
+
+
+//=============================================================================
+// Track clone method
+//=============================================================================
+TbTrack* TbTrack::clone() {
+  TbTrack* track = new TbTrack();
+  track->setTime(time());
+  track->setHtime(htime());
+  track->setFirstState(firstState());
+  track->setChi2PerNdof(chi2PerNdof());
+  track->setNdof(ndof());
+
+  // Copy the states
+  for (auto it = m_states.begin(), end = m_states.end(); it != end; ++it) {
+    track->addToStates(*it);
+  }
+
+  return track;
+}
+
+//=============================================================================
+// States clone method
+//=============================================================================
+void TbTrack::addToStates(const TbState& state) {
+  m_states.push_back(state);
+}
+
+//=============================================================================
+// Clear the states
+//=============================================================================
+void TbTrack::clearStates() {
+  m_states.clear() ;
+}
diff --git a/TbEvent/xml/.svn/all-wcprops b/TbEvent/xml/.svn/all-wcprops
new file mode 100644
index 0000000..2d9bedd
--- /dev/null
+++ b/TbEvent/xml/.svn/all-wcprops
@@ -0,0 +1,53 @@
+K 25
+svn:wc:ra_dav:version-url
+V 55
+/guest/lhcb/!svn/ver/200901/Kepler/trunk/Tb/TbEvent/xml
+END
+TbVertex.xml
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/180600/Kepler/trunk/Tb/TbEvent/xml/TbVertex.xml
+END
+ChiSquare.xml
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/179152/Kepler/trunk/Tb/TbEvent/xml/ChiSquare.xml
+END
+TbState.xml
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/185837/Kepler/trunk/Tb/TbEvent/xml/TbState.xml
+END
+TbCluster.xml
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/200901/Kepler/trunk/Tb/TbEvent/xml/TbCluster.xml
+END
+TbTrigger.xml
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/179695/Kepler/trunk/Tb/TbEvent/xml/TbTrigger.xml
+END
+gdd.dtd
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/170762/Kepler/trunk/Tb/TbEvent/xml/gdd.dtd
+END
+TbHit.xml
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/200589/Kepler/trunk/Tb/TbEvent/xml/TbHit.xml
+END
+TbTrack.xml
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/185857/Kepler/trunk/Tb/TbEvent/xml/TbTrack.xml
+END
diff --git a/TbEvent/xml/.svn/entries b/TbEvent/xml/.svn/entries
new file mode 100644
index 0000000..a71fc80
--- /dev/null
+++ b/TbEvent/xml/.svn/entries
@@ -0,0 +1,303 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/xml
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-04T17:03:58.484591Z
+200901
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbVertex.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+87e31bd2fe0a51c78866b895799e0729
+2014-11-23T16:26:09.716773Z
+180600
+dsaunder
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1360
+
+ChiSquare.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+83522e27c0212db544259ea577bafb6e
+2014-10-20T12:11:38.986809Z
+179152
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2240
+
+TbState.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+c4572572817b9e20e8571d25487e11da
+2015-03-24T11:06:24.702813Z
+185837
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6699
+
+TbCluster.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+d0e1b945b09bb490fc894e08e2e54eaa
+2016-02-04T17:03:58.484591Z
+200901
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3759
+
+TbTrigger.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+730843cce7e54d7273021bf037aa4998
+2014-11-02T12:09:43.753299Z
+179695
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1802
+
+gdd.dtd
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+f30759bfd18065f36d66ad486065f567
+2014-03-31T17:37:58.454693Z
+170762
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10369
+
+lcgdict
+dir
+
+TbHit.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+a79f3df4fffc5c967050c8f3c4038ae8
+2016-01-28T20:16:13.414912Z
+200589
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2319
+
+TbTrack.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+7500172449de331648dab23af07048d1
+2015-03-24T18:08:07.088543Z
+185857
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4194
+
diff --git a/TbEvent/xml/.svn/prop-base/TbHit.xml.svn-base b/TbEvent/xml/.svn/prop-base/TbHit.xml.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/TbEvent/xml/.svn/prop-base/TbHit.xml.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/TbEvent/xml/.svn/prop-base/TbTrigger.xml.svn-base b/TbEvent/xml/.svn/prop-base/TbTrigger.xml.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbEvent/xml/.svn/prop-base/TbTrigger.xml.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbEvent/xml/.svn/prop-base/gdd.dtd.svn-base b/TbEvent/xml/.svn/prop-base/gdd.dtd.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/TbEvent/xml/.svn/prop-base/gdd.dtd.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/TbEvent/xml/.svn/text-base/ChiSquare.xml.svn-base b/TbEvent/xml/.svn/text-base/ChiSquare.xml.svn-base
new file mode 100644
index 0000000..f81f20e
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/ChiSquare.xml.svn-base
@@ -0,0 +1,100 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE gdd SYSTEM 'gdd.dtd'>
+<gdd>
+  <package name='TbEvent'>
+    <class
+      name        = 'ChiSquare'
+      author      = 'Wouter Hulsbergen'
+      desc        = 'structure holding a chisquare and associated number of dofs'
+      allocator   = 'NO'
+      virtual     = 'FALSE'
+      >
+
+      <constructor
+        desc = 'Constructor'
+        initList = "m_chi2(chi2),m_nDoF(ndof)">
+        <arg type='double' name='chi2' const='TRUE' />
+        <arg type='int' name='ndof' />
+      </constructor>
+
+      <attribute
+        type = 'double'
+        name = 'chi2'
+        desc = 'chi square' 
+        setMeth = 'FALSE' />
+
+       <attribute
+	 type = 'int'
+	 name = 'nDoF'
+	 desc = 'number of degrees of freedom'
+	 setMeth = 'FALSE' />
+      
+      <method
+	type = 'double'
+	name = 'chi2PerDoF'
+	desc = 'return chi2/ndof if ndof>0. returns zero otherwise.'
+	const = 'TRUE'>
+	<code>
+  return m_nDoF>0 ? m_chi2/m_nDoF : 0 ;
+        </code>
+      </method>
+	
+      <method
+        type = 'double'
+        name = 'prob'
+        desc = 'return chisquare upper tail probability if ndof>0. returns zero otherwise.'
+        const = 'TRUE'>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare&amp;'
+	name = 'operator+='
+	desc = 'addition operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+        <code>
+  m_chi2 += rhs.m_chi2 ;
+  m_nDoF += rhs.m_nDoF ;
+  return *this ;
+        </code>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare&amp;'
+	name = 'operator-='
+	desc = 'subtraction operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+        <code>
+  m_chi2 -= rhs.m_chi2 ;
+  m_nDoF -= rhs.m_nDoF ;
+  return *this ;
+        </code>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare'
+	name = 'operator+'
+	desc = 'addition operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+	<code>
+  ChiSquare rc = *this ;
+  rc += rhs ;
+  return rc ;
+	</code>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare'
+	name = 'operator-'
+	desc = 'subtraction operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+	<code>
+  ChiSquare rc = *this ;
+  rc -= rhs ;
+  return rc ;
+	</code>
+      </method>
+
+      
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/.svn/text-base/TbCluster.xml.svn-base b/TbEvent/xml/.svn/text-base/TbCluster.xml.svn-base
new file mode 100644
index 0000000..c62df24
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/TbCluster.xml.svn-base
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbCluster"
+           id = "4511"
+           author = "H. Schindler"
+           desc = "Generic cluster object for testbeam analysis"
+           serializers = "FALSE">
+      <location name = "Default" place = "Rec/Tb/Clusters"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedObject;
+      <import name = "Event/TbHit"/>
+
+      <constructor desc = 'Default constructor'
+                   initList = 'm_wx(1.), m_wy(1.), m_associated(false)'>
+        <code>
+  m_hits.reserve(10);
+        </code>
+      </constructor>
+  
+      <relation name = 'hits' 
+                type = 'LHCb::TbHit' 
+                desc = 'hits forming this cluster'
+                multiplicity = 'm'/>
+
+      <attribute name = "x"
+                 desc = "global x"
+                 type = "double"/>
+                    
+      <attribute name = "y"
+                 desc = "global y"
+                 type = "double"/>
+                 
+      <attribute name = "xErr"
+                 desc = "global x error"
+                 type = "double"/>
+                    
+      <attribute name = "yErr"
+                 desc = "global y error"
+                 type = "double"/>
+                 
+      <attribute name = "z"
+                 desc = "global z"
+                 type = "double"/>
+                 
+      <attribute name = "xloc"
+                 desc = "local x"
+                 type = "double"/>
+                 
+      <attribute name = "yloc"
+                 desc = "local y"
+                 type = "double"/>
+
+      <attribute name = "wx"
+                 desc = "weight in global x"
+                 type = "double"/>
+
+      <attribute name = "wy"
+                 desc = "weight in global y"
+                 type = "double"/>
+
+      <attribute name = "ToT"     
+                 desc = "time over threshold"
+                 type = "unsigned int"/> 
+
+      <attribute name = "charge"
+                 desc = "total charge (in electrons)"
+                 type = "double"/>
+                 
+      <attribute name = "plane"
+                 desc = "index of the telescope plane"
+                 type = "unsigned int"/>
+                 
+      <attribute name = "time"
+                 type = "uint64_t"
+                 desc = "global timestamp"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "cols"
+                 type = "unsigned int"
+                 desc = "number of columns covered by the cluster"/>
+
+      <attribute name = "rows"
+                 type = "unsigned int"
+                 desc = "number of rows covered by the cluster"/>
+
+      <attribute name = "associated"
+                 desc = "flag for whether the cluster is part of a track"
+                 type = "bool"
+                 setMeth = "FALSE"/>
+     
+      <method name = "clone"
+              desc = "Clone the cluster without keeping the hits (you take ownership of the pointer)"
+              type = "LHCb::TbCluster*"
+              virtual = "TRUE"/>
+
+      <method name = "size"
+              desc = "Return the cluster size"
+              type = "unsigned int"
+              const = "TRUE">
+        <code>
+  return m_hits.size();
+        </code>
+      </method>
+ 
+      <method name = "setAssociated"
+              desc = "Set the cluster and its hits to be associated to a track"
+              argList = "const bool tracked">
+        <code>
+  m_associated = tracked;
+  for (auto it = m_hits.begin(), end = m_hits.end(); it != end; ++it) {
+    (*it)->setAssociated(tracked);
+  }
+        </code>
+      </method>
+
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/.svn/text-base/TbHit.xml.svn-base b/TbEvent/xml/.svn/text-base/TbHit.xml.svn-base
new file mode 100644
index 0000000..364111a
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/TbHit.xml.svn-base
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = 'TbEvent'>
+
+    <class name = "TbHit"
+           id = "4510"
+           author = "T. Evans"
+           desc = "Single pixel hit">
+      <location name = "Default" place = "Raw/Tb/Hits"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedContainer;
+ 
+      <constructor desc = 'Default constructor'
+                   initList = 'm_associated(false)'>
+      </constructor>
+   
+      <constructor desc = "Copy Constructor"
+                   argList = 'const LHCb::TbHit* other'>
+        <code>
+  m_row = other->row();
+  m_col = other->col();
+  m_scol = other->scol();
+  m_time = other->time();
+  m_htime = other->htime();
+  m_pixelAddress = other->pixelAddress();
+  m_ToT = other->ToT();
+  m_data = other->data();
+  m_device = other->device();
+  m_associated = other->associated();
+        </code>
+      </constructor>
+
+      <attribute name = "row"     
+                 type = "unsigned int"  
+                 desc = "row number"/>
+
+      <attribute name = "col" 
+                 type = "unsigned int"  
+                 desc = "column number"/>
+
+      <attribute name = "scol" 
+                 type = "unsigned int"  
+                 desc = "sensor column number"/>
+
+      <attribute name = "time"    
+                 type = "uint64_t"  
+                 desc = "global timestamp"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "pixelAddress"
+                 type = "unsigned int"
+                 desc = "address of the pixel on the chip"/>
+   
+      <attribute name = "ToT"     
+                 type = "unsigned int" 
+                 desc = "time over threshold"/>
+
+      <attribute name = "charge"
+                 type = "double"
+                 desc = "collected charge (in electrons)"/>
+
+      <attribute name = "data"
+                 type = "uint64_t" 
+                 desc = "complete data line"/>
+
+      <attribute name = "device"
+                 type = "unsigned int"
+                 desc = "index of the chip"/>
+
+      <attribute name = "associated"
+                 type = "bool"
+                 desc = "flag for whether the hit is associated to a track"/>
+
+  </class>  
+ </package>
+</gdd>
diff --git a/TbEvent/xml/.svn/text-base/TbState.xml.svn-base b/TbEvent/xml/.svn/text-base/TbState.xml.svn-base
new file mode 100644
index 0000000..100a791
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/TbState.xml.svn-base
@@ -0,0 +1,219 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE gdd SYSTEM 'gdd.dtd'>
+<gdd>
+  <package name = 'TbEvent'>
+    <class name = 'TbState'
+           author = 'Panagiotis Tsopelas, Wouter Hulsbergen'
+           desc = '4D state vector with z position'>
+      
+      <location name = "Default" place = "Rec/Tb/TbStates"/>
+      <import name = "GaudiKernel/MsgStream" />
+      <import name = "GaudiKernel/Point3DTypes"/>
+      <import name = "GaudiKernel/Vector3DTypes"/>
+      <import name = "GaudiKernel/GenericVectorTypes"/>
+      <import name = "GaudiKernel/SymmetricMatrixTypes"/>
+      &StlPtrVector;
+      
+      <constructor desc = 'Default constructor'
+                   initList = "m_parameters(), m_covariance(), m_z(0.), m_plane(0)">
+      </constructor>
+      
+      <constructor desc = "Constructor with arguments"
+                   argList = "const Gaudi::Vector4&amp; state, 
+                              const Gaudi::SymMatrix4x4&amp; cov, 
+                              const double&amp; z, const unsigned int&amp; plane"
+                   initList = "m_parameters(state), m_covariance(cov), m_z(z), m_plane(plane)">
+      </constructor>
+      
+      <attribute type = 'Gaudi::Vector4'
+                 name = 'parameters'
+                 desc = 'the parameter vector'
+                 setMeth = 'FALSE'
+                 access  = 'PRIVATE'
+                 nonconstaccessor = 'TRUE'/>
+      
+      <attribute type = 'Gaudi::SymMatrix4x4'
+                 name = 'covariance'
+                 desc = 'covariance matrix (indices 0 ... 3 for x, y, tx, ty)'
+                 setMeth = 'FALSE'
+                 access  = 'PRIVATE'
+                 nonconstaccessor = 'TRUE'/>
+      
+      <attribute type = 'double'
+                 name = 'z'
+                 desc = 'the z-position of the state'
+                 setMeth = 'FALSE'
+                 access = 'PRIVATE'/>
+
+      <attribute type = 'unsigned int'
+                 name = 'plane'
+                 desc = 'the plane of the state'/>
+
+      <method type = 'double'
+              name = 'errX2'
+              desc = 'Retrieve the squared error on the x-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(0, 0);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'errY2'
+              desc = 'Retrieve the squared error on the y-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(1, 1);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'errTx2'
+              desc = 'Retrieve the squared error on the x-slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(2, 2);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'errTy2'
+              desc = 'Retrieve the squared error on the y-slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(3, 3);
+        </code>
+      </method>
+
+      <method type = 'LHCb::TbState*'
+              name = 'clone'
+              desc = 'Clone the TbState (you then own the pointer)'
+              virtual = 'TRUE'
+              const = 'TRUE'>
+      </method>
+      
+      <method type = 'Gaudi::XYZPoint'
+              name = 'position'
+              desc = 'Retrieve the 3D-position vector (x,y,z) of the state'
+              const = 'TRUE'>
+        <code>
+  return Gaudi::XYZPoint(m_parameters[0], m_parameters[1], m_z);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'x'
+              desc = 'Retrieve the x-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[0];
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'y'
+              desc = 'Retrieve the y-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[1];
+        </code>
+      </method>
+      
+      <method type = 'Gaudi::XYZVector'
+              name = 'slopes'
+              desc = 'Retrieve the slopes (dx/dz, dy/dz, 1.) of the state'
+              const = 'TRUE'>
+        <code>
+  return Gaudi::XYZVector(m_parameters[2], m_parameters[3], 1.);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'tx'
+              desc = 'Retrieve the Tx=dx/dz slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[2];
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'ty'
+              desc = 'Retrieve the Ty=dy/dz slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[3];
+        </code>
+      </method>
+      
+      <method name = 'setX'
+              argList = 'const double value'
+              desc = 'Update the x-position of the state'>
+        <code>
+  m_parameters[0] = value;
+        </code>
+      </method>
+      
+      <method name = 'setY'
+              argList = 'const double value'
+              desc    = 'Update the y-position of the state'>
+        <code>
+  m_parameters[1] = value;
+        </code>
+      </method>
+      
+      <method name = 'setZ'
+              argList = 'const double value'
+              desc = 'Update the z-position of the state'>
+        <code>
+  m_z = value;
+        </code>
+      </method>
+      
+      <method name = 'setTx'
+              argList = 'const double value'
+              desc = 'Update the x-slope tx = dx/dz of the state'>
+        <code>
+  m_parameters[2] = value;
+        </code>
+      </method>
+      
+      <method name = 'setTy'
+              argList = 'const double value'
+              desc = 'Update the y-slope ty = dy/dz of the state'>
+        <code>
+  m_parameters[3] = value;
+        </code>
+      </method>
+      
+      <method name = 'setState'
+              argList = 'double x, double y, double tx, double ty, double z'
+              desc = 'Update the state vector'/>
+      
+      <method name = 'setCovariance'
+             argList = 'Gaudi::SymMatrix4x4 value'
+             desc = 'Update the covariance matrix'>
+        <code>
+  m_covariance = value;
+        </code>
+      </method>
+  
+      <method name = "fillStream"
+              desc = "Print to message stream"
+              type = "MsgStream&amp;"
+              const = "TRUE">
+        <arg name = "os" type = "MsgStream" inout = "BOTH"/>
+        <code>
+          os &lt;&lt; "{ " 
+          &lt;&lt; "parameters: " &lt;&lt; m_parameters &lt;&lt; std::endl
+          &lt;&lt; "z:          " &lt;&lt; m_z &lt;&lt; std::endl
+          &lt;&lt; " }";
+          return os;
+        </code>
+      </method>
+      
+    </class>
+    
+  </package>
+</gdd>
+
diff --git a/TbEvent/xml/.svn/text-base/TbTrack.xml.svn-base b/TbEvent/xml/.svn/text-base/TbTrack.xml.svn-base
new file mode 100644
index 0000000..0aa5c65
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/TbTrack.xml.svn-base
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbTrack"
+           id = "4512"
+           author = "H. Schindler"
+           desc = "Reconstructed telescope track"
+           serializers = "FALSE">
+      <location name = "Default" place = "Rec/Tb/TbTracks"/>
+      <import name = "Event/TbCluster"/>
+      <import name = "Event/TbTrigger"/>
+      <import name = "Event/TbState"/>
+      <import name = "vector" std = "TRUE"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedObject;
+      
+      <constructor desc = 'Default constructor'
+                   initList = "m_time(0), m_htime(0.), m_firstState(), m_chi2PerNdof(0.), m_ndof(0), m_states(), m_vertexed(false), m_parentVertex(false)">
+        <code>
+  m_clusters.reserve(10);
+  m_triggers.reserve(10);
+  m_associatedClusters.reserve(10);
+  m_states.reserve(10);
+        </code>
+      </constructor>
+      
+      <relation name = 'clusters' 
+                type = 'LHCb::TbCluster' 
+                desc = 'clusters forming this track'
+                multiplicity = 'm'/>
+      
+      <relation name = 'triggers' 
+                type = 'LHCb::TbTrigger' 
+                desc = 'triggers associated to this track'
+                multiplicity = 'm'/>
+
+      <relation name = 'associatedClusters' 
+                type = 'LHCb::TbCluster' 
+                desc = 'clusters associated to this track'
+                multiplicity = 'm'/>
+
+      <attribute name = "time"
+                 type = "uint64_t" 
+                 desc = "global timestamp"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "firstState"
+                 desc = "first state of the track"
+                 type = 'LHCb::TbState'/>
+      
+      <attribute name = "chi2PerNdof"
+                 desc = "chi-squared per degree of freedom of the track"
+                 type = "double"/>
+      
+      <attribute name = "ndof"
+                 desc = "number of degrees of freedom"
+                 type = "unsigned int"/>
+      
+      <attribute type = 'std::vector&lt;LHCb::TbState&gt;'
+                 name = 'states'
+                 desc = 'container with all states'
+                 setMeth= 'FALSE'/>
+                 
+      <attribute name = 'vertexed'
+                 desc = 'flag whether this track forms part of a vertex'
+                 type = 'bool'/>
+                                  
+      <attribute name = 'parentVertex'
+                 desc = 'flag whether this track forms the start of a vertex'
+                 type = 'bool'/>
+      
+      <constructor desc = "Copy constructor" >
+         <arg const="TRUE" name="track" type="LHCb::TbTrack"/>
+      </constructor>
+
+      <method type = 'void'
+              name = 'clearStates'
+              desc = 'Clear the State vector'>
+      </method>
+
+      <method type = 'double'
+              name = 'chi2'
+              desc = 'Retrieve the chi-squared of the track'
+              const = 'TRUE'>
+        <code>
+  return m_chi2PerNdof * m_ndof;
+        </code>
+      </method>
+
+      <method name = "clone"
+              desc = "Clone the track without keeping the clusters (you take ownership of the pointer)"
+              type = "LHCb::TbTrack*"
+              virtual = "TRUE"/>
+
+      <method name = 'addToStates'
+              desc = 'Add a state to the list of states associated to the track'>
+        <arg type = 'const LHCb::TbState' name = 'state'/>
+      </method>
+  
+      <method name = "size"
+              desc = "Return the number of clusters forming this track"
+              type = "unsigned int"
+              const = "TRUE">
+        <code>
+  return m_clusters.size();
+        </code>
+      </method>
+      
+      <method name = "setAssociated"
+              desc = "Flag the clusters in a track as associated / unassociated"
+              type = "void"
+              argList = "const bool flag">
+        <code>
+  for (auto it = m_clusters.begin(), end = m_clusters.end(); it != end; ++it) {
+    (*it)->setAssociated(flag);
+  }
+        </code>
+      </method>
+  
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/.svn/text-base/TbTrigger.xml.svn-base b/TbEvent/xml/.svn/text-base/TbTrigger.xml.svn-base
new file mode 100644
index 0000000..1770d5c
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/TbTrigger.xml.svn-base
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbTrigger"
+           id = "4513"
+           author = "H. Schindler"
+           desc = "Trigger timestamp">
+      <location name = "Default" place = "Raw/Tb/Triggers"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedContainer;
+      
+      <constructor desc = 'Constructor with pixel packet'
+                   argList = 'uint64_t data'
+                   initList = 'm_associated(false)'>
+        <code>
+  m_plane = 0;
+  m_data = data;
+  m_time = 0xFFFFFFFFFFF &amp; data;
+  m_counter = (data >> 44) &amp; 0xFFF;
+        </code>
+      </constructor>
+
+      <constructor desc = 'Copy constructor'
+                   argList = 'const LHCb::TbTrigger* other'>
+        <code>
+  m_plane = other->plane();
+  m_data = other->data();
+  m_time = other->time();
+  m_counter = other->counter();
+  m_htime = other->htime();
+  m_associated = other->associated();
+        </code>
+      </constructor>
+
+      <attribute name = "counter"
+                 type = "unsigned int"
+                 desc = "counter"/>
+
+      <attribute name = "time"    
+                 type = "uint64_t"
+                 desc = "global timestamp"/>
+
+      <attribute name = "data"    
+                 type = "uint64_t"
+                 desc = "complete data packet"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "associated"
+                 type = "bool"
+                 desc = "flag whether the trigger is associated to a track"/>
+      <attribute name = "plane"
+                 type = "int"
+                 desc = "Plane of the trigger, dummy for the alignment"/>
+  </class> 
+ </package>
+</gdd>
diff --git a/TbEvent/xml/.svn/text-base/TbVertex.xml.svn-base b/TbEvent/xml/.svn/text-base/TbVertex.xml.svn-base
new file mode 100644
index 0000000..eb8a99d
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/TbVertex.xml.svn-base
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbVertex"
+           id = "4515"
+           author = "D. Saunders"
+           desc = "Reconstructed telescope vertex"
+           serializers = "FALSE">
+      <location name = "Default" place = "Rec/Tb/TbVertices"/>
+      <import name = "Event/TbTrack"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedObject;
+      
+      <relation name = 'tracks' 
+                type = 'LHCb::TbTrack' 
+                desc = 'tracks connecting at the vertex'
+                multiplicity = 'm'/>
+                
+      <attribute name = "x"
+                 type = "double"
+                 desc = "x position of the vertex"/>
+                 
+      <attribute name = "y"
+                 type = "double"
+                 desc = "y position of the vertex"/>
+                 
+      <attribute name = "z"
+                 type = "double"
+                 desc = "z position of the vertex"/>
+                 
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "htime position of the vertex"/>
+                 
+                 
+      <attribute name = "interactionPlane"
+                 type = "unsigned int"
+                 desc = "plane forming the vertex"/>
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/.svn/text-base/gdd.dtd.svn-base b/TbEvent/xml/.svn/text-base/gdd.dtd.svn-base
new file mode 100644
index 0000000..05489ca
--- /dev/null
+++ b/TbEvent/xml/.svn/text-base/gdd.dtd.svn-base
@@ -0,0 +1,221 @@
+<?xml encoding="UTF-8"?>
+<!-- ?xml encoding="ISO-8859-1"? -->
+<!ELEMENT gdd ((import*, package+)+)>
+<!ATTLIST gdd
+        version          CDATA                             "1.0"
+>
+
+<!ELEMENT import EMPTY>
+<!ATTLIST import
+        name             CDATA                             #REQUIRED
+        std              (TRUE | FALSE)                    "FALSE"
+        soft             (TRUE | FALSE | FORWARDONLY)      "FALSE"
+        namespace        CDATA                             #IMPLIED
+>
+
+<!ELEMENT package ((import*, class*, namespace*, assoc*)*)>
+<!ATTLIST package
+        name             CDATA                             #REQUIRED
+        namespace        CDATA                             #IMPLIED
+>
+<!-- ELEMENT class ((class?, ..... -->
+<!ELEMENT class ((desc?, base?, copyconstructor?, assignmentoperator?, import?, location?, enum?, typedef?, constructor?, destructor?, method?, attribute?, relation?, template?)*)>
+<!ATTLIST class
+        name              CDATA                            #REQUIRED
+        author            CDATA                            #REQUIRED
+        desc              CDATA                            #REQUIRED
+        id                CDATA                            #IMPLIED
+        version           CDATA                            #IMPLIED
+        location          CDATA                            #IMPLIED
+        namespace         CDATA                            #IMPLIED
+        stdVectorTypeDef  (TRUE | FALSE)                   "FALSE"  
+        keyedContTypeDef  (TRUE | FALSE)                   "FALSE"  
+        contObjectTypeDef (TRUE | FALSE)                   "FALSE"
+        serializers       (TRUE | FALSE)                   "TRUE"    
+        virtual           (TRUE | FALSE)                   "TRUE"
+        allocator         (DEFAULT | NO | BOOST | BOOST2 | DEBUG )  "DEFAULT"    
+        defaultconstructor (TRUE | FALSE)                  "TRUE"
+        defaultdestructor  (TRUE | FALSE)                  "TRUE">
+       
+<!ELEMENT desc (#PCDATA)>
+<!ATTLIST desc
+        xml:space        (default | preserve)              #FIXED "preserve"
+>
+<!ELEMENT copyconstructor EMPTY>
+<!ELEMENT assignmentoperator EMPTY>
+<!ELEMENT location EMPTY>
+<!ATTLIST location
+        name             CDATA                             #REQUIRED
+        place            CDATA                             #REQUIRED
+        noQuote          (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT namespace ((desc?, typedef?, enum?, class?, import?, attribute?, method?)*)>
+<!ATTLIST namespace
+        name             CDATA                             #REQUIRED
+        author           CDATA                             #IMPLIED
+        desc             CDATA                             #REQUIRED
+        scope            CDATA                             #IMPLIED
+>
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+        name             CDATA                             #REQUIRED
+        virtual          (TRUE | FALSE)                    "FALSE"
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PUBLIC"
+>
+<!ELEMENT enum (enumval*)>
+<!ATTLIST enum
+        name             CDATA                             #REQUIRED
+        desc             CDATA                             #REQUIRED
+        value            CDATA                             #IMPLIED
+        strTypConv       (TRUE | FALSE )                   "FALSE"
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PRIVATE"
+        unknownValue     CDATA                             "Unknown"
+>
+<!ELEMENT enumval EMPTY>
+<!ATTLIST enumval
+        name             CDATA                             #REQUIRED
+        value            CDATA                             #IMPLIED
+        desc             CDATA                             #REQUIRED
+>
+<!ELEMENT typedef EMPTY>
+<!ATTLIST typedef 
+        desc             CDATA                             #REQUIRED
+        type             CDATA                             #REQUIRED
+        def              CDATA                             #REQUIRED
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PRIVATE"
+>
+<!ELEMENT constructor (arg*, code?, arg*)>
+<!ATTLIST constructor
+        desc             CDATA                             #REQUIRED
+        argList          CDATA                             #IMPLIED
+        initList         CDATA                             #IMPLIED
+        explicit         (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT destructor (arg*, code?, arg*)>
+<!ATTLIST destructor
+        desc             CDATA                             #REQUIRED
+        argList          CDATA                             #IMPLIED
+        virtual          (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT method ((arg*, return?, arg*, code?, arg*) | (arg*, code?, arg*, return?, arg*))>
+<!ATTLIST method
+        name             CDATA                             #REQUIRED
+        desc             CDATA                             #REQUIRED
+        template         CDATA                             #IMPLIED
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PUBLIC"
+        const            (TRUE | FALSE)                    "FALSE"
+        virtual          (TRUE | FALSE | PURE)             "FALSE"
+        static           (TRUE | FALSE)                    "FALSE"
+        inline           (TRUE | FALSE)                    "FALSE"
+        friend           (TRUE | FALSE)                    "FALSE"
+        type             CDATA                             "void"
+        argList          CDATA                             #IMPLIED
+        useBase          CDATA                             #IMPLIED
+>
+<!ELEMENT arg EMPTY>
+<!ATTLIST arg
+        type             CDATA                             #REQUIRED
+        name             CDATA                             #IMPLIED
+        const            (TRUE | FALSE)                    "FALSE"
+        inout            (BYVALUE | INPUT | INOUT | BOTH)  "INPUT"
+>
+<!ELEMENT return EMPTY>
+<!ATTLIST return
+        type             CDATA                             #REQUIRED
+        const            (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT code (#PCDATA)>
+<!ATTLIST code
+        xml:space        (default | preserve)              #FIXED "preserve"
+>
+<!ELEMENT attribute (bitfield*)>
+<!ATTLIST attribute
+        type             CDATA                            #REQUIRED
+        name             CDATA                            #REQUIRED
+        desc             CDATA                            #REQUIRED
+        init             CDATA                            #IMPLIED
+        dictalias        CDATA                            #IMPLIED
+        access           (PUBLIC | PROTECTED | PRIVATE)   "PRIVATE"
+        compression      (TRUE | FALSE)                   "TRUE"
+        setMeth          (TRUE | FALSE)                   "TRUE"
+        getMeth          (TRUE | FALSE)                   "TRUE"
+        transient        (TRUE | FALSE)                   "FALSE"    
+        nonconstaccessor (TRUE | FALSE)                   "FALSE"
+>
+<!ELEMENT relation EMPTY>
+<!ATTLIST relation
+        type             CDATA                            #REQUIRED
+        name             CDATA                            #REQUIRED
+        desc             CDATA                            #REQUIRED
+        access           (PUBLIC | PROTECTED | PRIVATE)   "PRIVATE"
+        multiplicity     (1 | N | n | M | m)              "1"
+        serialize        (TRUE | FALSE)                   "TRUE"
+        setMeth          (TRUE | FALSE)                   "TRUE"
+        getMeth          (TRUE | FALSE)                   "TRUE"
+        addMeth          (TRUE | FALSE)                   "TRUE"
+        remMeth          (TRUE | FALSE)                   "TRUE"
+        clrMeth          (TRUE | FALSE)                   "TRUE"
+        nonconstaccessor (TRUE | FALSE)                   "FALSE"
+>
+<!ELEMENT bitfield EMPTY>
+<!ATTLIST bitfield
+        name             CDATA                             #REQUIRED
+        type             CDATA                             #IMPLIED
+        length           CDATA                             #REQUIRED
+        desc             CDATA                             #REQUIRED
+        startBit         CDATA                             #IMPLIED
+        exclusive        (TRUE | FALSE)                    "TRUE"
+        setMeth          (TRUE | FALSE)                    "TRUE"
+        getMeth          (TRUE | FALSE)                    "TRUE"
+        checkMeth        (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT template EMPTY>
+<!ATTLIST template
+        name             CDATA                             #REQUIRED
+        t1               CDATA                             "THIS"
+        t2               CDATA                             #IMPLIED
+        t3               CDATA                             #IMPLIED
+        t4               CDATA                             #IMPLIED
+>
+
+<!ELEMENT assoc EMPTY>
+<!ATTLIST assoc
+        type             (1D | 2D)                         "1D"
+        weight           CDATA                             "NONE"
+        from             CDATA                             #REQUIRED
+        to               CDATA                             #REQUIRED
+>
+
+<!ENTITY KeyedObjectKey 'int'>
+<!ENTITY Reference '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>'
+>
+<!ENTITY StlVector '<template name="vector" t1="THIS"/>'
+>
+<!ENTITY StlConstVector '<template name="vector" t1="const THIS"/>'
+>
+<!ENTITY StlPtrVector '<template name="vector" t1="THIS*"/>'
+>
+<!ENTITY StlConstPtrVector '<template name="vector" t1="const THIS*"/>'
+>
+<!ENTITY DataObject '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>'
+>
+<!ENTITY ContainedObject '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>
+        <template name="vector" t1="THIS*"/>
+        <template name="ObjectVector"/>'
+>
+<!ENTITY KeyedContainer '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>
+        <template name="vector" t1="THIS*"/>
+        <template name="ObjectVector"/>
+        <template name="KeyedContainer"/>'
+>
+<!ENTITY KeyedObject '<template name="KeyedObject" t1="int"/>
+        <template name="SmartRef"/>
+        <template name="SmartRefVector"/>
+        <template name="vector" t1="THIS*"/>
+        <template name="ObjectVector"/>
+        <template name="KeyedContainer"/>'
+>
diff --git a/TbEvent/xml/ChiSquare.xml b/TbEvent/xml/ChiSquare.xml
new file mode 100644
index 0000000..f81f20e
--- /dev/null
+++ b/TbEvent/xml/ChiSquare.xml
@@ -0,0 +1,100 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE gdd SYSTEM 'gdd.dtd'>
+<gdd>
+  <package name='TbEvent'>
+    <class
+      name        = 'ChiSquare'
+      author      = 'Wouter Hulsbergen'
+      desc        = 'structure holding a chisquare and associated number of dofs'
+      allocator   = 'NO'
+      virtual     = 'FALSE'
+      >
+
+      <constructor
+        desc = 'Constructor'
+        initList = "m_chi2(chi2),m_nDoF(ndof)">
+        <arg type='double' name='chi2' const='TRUE' />
+        <arg type='int' name='ndof' />
+      </constructor>
+
+      <attribute
+        type = 'double'
+        name = 'chi2'
+        desc = 'chi square' 
+        setMeth = 'FALSE' />
+
+       <attribute
+	 type = 'int'
+	 name = 'nDoF'
+	 desc = 'number of degrees of freedom'
+	 setMeth = 'FALSE' />
+      
+      <method
+	type = 'double'
+	name = 'chi2PerDoF'
+	desc = 'return chi2/ndof if ndof>0. returns zero otherwise.'
+	const = 'TRUE'>
+	<code>
+  return m_nDoF>0 ? m_chi2/m_nDoF : 0 ;
+        </code>
+      </method>
+	
+      <method
+        type = 'double'
+        name = 'prob'
+        desc = 'return chisquare upper tail probability if ndof>0. returns zero otherwise.'
+        const = 'TRUE'>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare&amp;'
+	name = 'operator+='
+	desc = 'addition operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+        <code>
+  m_chi2 += rhs.m_chi2 ;
+  m_nDoF += rhs.m_nDoF ;
+  return *this ;
+        </code>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare&amp;'
+	name = 'operator-='
+	desc = 'subtraction operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+        <code>
+  m_chi2 -= rhs.m_chi2 ;
+  m_nDoF -= rhs.m_nDoF ;
+  return *this ;
+        </code>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare'
+	name = 'operator+'
+	desc = 'addition operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+	<code>
+  ChiSquare rc = *this ;
+  rc += rhs ;
+  return rc ;
+	</code>
+      </method>
+
+      <method
+	type = 'LHCb::ChiSquare'
+	name = 'operator-'
+	desc = 'subtraction operator' >
+	<arg type = 'LHCb::ChiSquare' name='rhs' const='TRUE'/>
+	<code>
+  ChiSquare rc = *this ;
+  rc -= rhs ;
+  return rc ;
+	</code>
+      </method>
+
+      
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/TbCluster.xml b/TbEvent/xml/TbCluster.xml
new file mode 100644
index 0000000..c62df24
--- /dev/null
+++ b/TbEvent/xml/TbCluster.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbCluster"
+           id = "4511"
+           author = "H. Schindler"
+           desc = "Generic cluster object for testbeam analysis"
+           serializers = "FALSE">
+      <location name = "Default" place = "Rec/Tb/Clusters"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedObject;
+      <import name = "Event/TbHit"/>
+
+      <constructor desc = 'Default constructor'
+                   initList = 'm_wx(1.), m_wy(1.), m_associated(false)'>
+        <code>
+  m_hits.reserve(10);
+        </code>
+      </constructor>
+  
+      <relation name = 'hits' 
+                type = 'LHCb::TbHit' 
+                desc = 'hits forming this cluster'
+                multiplicity = 'm'/>
+
+      <attribute name = "x"
+                 desc = "global x"
+                 type = "double"/>
+                    
+      <attribute name = "y"
+                 desc = "global y"
+                 type = "double"/>
+                 
+      <attribute name = "xErr"
+                 desc = "global x error"
+                 type = "double"/>
+                    
+      <attribute name = "yErr"
+                 desc = "global y error"
+                 type = "double"/>
+                 
+      <attribute name = "z"
+                 desc = "global z"
+                 type = "double"/>
+                 
+      <attribute name = "xloc"
+                 desc = "local x"
+                 type = "double"/>
+                 
+      <attribute name = "yloc"
+                 desc = "local y"
+                 type = "double"/>
+
+      <attribute name = "wx"
+                 desc = "weight in global x"
+                 type = "double"/>
+
+      <attribute name = "wy"
+                 desc = "weight in global y"
+                 type = "double"/>
+
+      <attribute name = "ToT"     
+                 desc = "time over threshold"
+                 type = "unsigned int"/> 
+
+      <attribute name = "charge"
+                 desc = "total charge (in electrons)"
+                 type = "double"/>
+                 
+      <attribute name = "plane"
+                 desc = "index of the telescope plane"
+                 type = "unsigned int"/>
+                 
+      <attribute name = "time"
+                 type = "uint64_t"
+                 desc = "global timestamp"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "cols"
+                 type = "unsigned int"
+                 desc = "number of columns covered by the cluster"/>
+
+      <attribute name = "rows"
+                 type = "unsigned int"
+                 desc = "number of rows covered by the cluster"/>
+
+      <attribute name = "associated"
+                 desc = "flag for whether the cluster is part of a track"
+                 type = "bool"
+                 setMeth = "FALSE"/>
+     
+      <method name = "clone"
+              desc = "Clone the cluster without keeping the hits (you take ownership of the pointer)"
+              type = "LHCb::TbCluster*"
+              virtual = "TRUE"/>
+
+      <method name = "size"
+              desc = "Return the cluster size"
+              type = "unsigned int"
+              const = "TRUE">
+        <code>
+  return m_hits.size();
+        </code>
+      </method>
+ 
+      <method name = "setAssociated"
+              desc = "Set the cluster and its hits to be associated to a track"
+              argList = "const bool tracked">
+        <code>
+  m_associated = tracked;
+  for (auto it = m_hits.begin(), end = m_hits.end(); it != end; ++it) {
+    (*it)->setAssociated(tracked);
+  }
+        </code>
+      </method>
+
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/TbHit.xml b/TbEvent/xml/TbHit.xml
new file mode 100755
index 0000000..364111a
--- /dev/null
+++ b/TbEvent/xml/TbHit.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = 'TbEvent'>
+
+    <class name = "TbHit"
+           id = "4510"
+           author = "T. Evans"
+           desc = "Single pixel hit">
+      <location name = "Default" place = "Raw/Tb/Hits"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedContainer;
+ 
+      <constructor desc = 'Default constructor'
+                   initList = 'm_associated(false)'>
+      </constructor>
+   
+      <constructor desc = "Copy Constructor"
+                   argList = 'const LHCb::TbHit* other'>
+        <code>
+  m_row = other->row();
+  m_col = other->col();
+  m_scol = other->scol();
+  m_time = other->time();
+  m_htime = other->htime();
+  m_pixelAddress = other->pixelAddress();
+  m_ToT = other->ToT();
+  m_data = other->data();
+  m_device = other->device();
+  m_associated = other->associated();
+        </code>
+      </constructor>
+
+      <attribute name = "row"     
+                 type = "unsigned int"  
+                 desc = "row number"/>
+
+      <attribute name = "col" 
+                 type = "unsigned int"  
+                 desc = "column number"/>
+
+      <attribute name = "scol" 
+                 type = "unsigned int"  
+                 desc = "sensor column number"/>
+
+      <attribute name = "time"    
+                 type = "uint64_t"  
+                 desc = "global timestamp"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "pixelAddress"
+                 type = "unsigned int"
+                 desc = "address of the pixel on the chip"/>
+   
+      <attribute name = "ToT"     
+                 type = "unsigned int" 
+                 desc = "time over threshold"/>
+
+      <attribute name = "charge"
+                 type = "double"
+                 desc = "collected charge (in electrons)"/>
+
+      <attribute name = "data"
+                 type = "uint64_t" 
+                 desc = "complete data line"/>
+
+      <attribute name = "device"
+                 type = "unsigned int"
+                 desc = "index of the chip"/>
+
+      <attribute name = "associated"
+                 type = "bool"
+                 desc = "flag for whether the hit is associated to a track"/>
+
+  </class>  
+ </package>
+</gdd>
diff --git a/TbEvent/xml/TbState.xml b/TbEvent/xml/TbState.xml
new file mode 100644
index 0000000..100a791
--- /dev/null
+++ b/TbEvent/xml/TbState.xml
@@ -0,0 +1,219 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE gdd SYSTEM 'gdd.dtd'>
+<gdd>
+  <package name = 'TbEvent'>
+    <class name = 'TbState'
+           author = 'Panagiotis Tsopelas, Wouter Hulsbergen'
+           desc = '4D state vector with z position'>
+      
+      <location name = "Default" place = "Rec/Tb/TbStates"/>
+      <import name = "GaudiKernel/MsgStream" />
+      <import name = "GaudiKernel/Point3DTypes"/>
+      <import name = "GaudiKernel/Vector3DTypes"/>
+      <import name = "GaudiKernel/GenericVectorTypes"/>
+      <import name = "GaudiKernel/SymmetricMatrixTypes"/>
+      &StlPtrVector;
+      
+      <constructor desc = 'Default constructor'
+                   initList = "m_parameters(), m_covariance(), m_z(0.), m_plane(0)">
+      </constructor>
+      
+      <constructor desc = "Constructor with arguments"
+                   argList = "const Gaudi::Vector4&amp; state, 
+                              const Gaudi::SymMatrix4x4&amp; cov, 
+                              const double&amp; z, const unsigned int&amp; plane"
+                   initList = "m_parameters(state), m_covariance(cov), m_z(z), m_plane(plane)">
+      </constructor>
+      
+      <attribute type = 'Gaudi::Vector4'
+                 name = 'parameters'
+                 desc = 'the parameter vector'
+                 setMeth = 'FALSE'
+                 access  = 'PRIVATE'
+                 nonconstaccessor = 'TRUE'/>
+      
+      <attribute type = 'Gaudi::SymMatrix4x4'
+                 name = 'covariance'
+                 desc = 'covariance matrix (indices 0 ... 3 for x, y, tx, ty)'
+                 setMeth = 'FALSE'
+                 access  = 'PRIVATE'
+                 nonconstaccessor = 'TRUE'/>
+      
+      <attribute type = 'double'
+                 name = 'z'
+                 desc = 'the z-position of the state'
+                 setMeth = 'FALSE'
+                 access = 'PRIVATE'/>
+
+      <attribute type = 'unsigned int'
+                 name = 'plane'
+                 desc = 'the plane of the state'/>
+
+      <method type = 'double'
+              name = 'errX2'
+              desc = 'Retrieve the squared error on the x-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(0, 0);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'errY2'
+              desc = 'Retrieve the squared error on the y-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(1, 1);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'errTx2'
+              desc = 'Retrieve the squared error on the x-slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(2, 2);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'errTy2'
+              desc = 'Retrieve the squared error on the y-slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_covariance(3, 3);
+        </code>
+      </method>
+
+      <method type = 'LHCb::TbState*'
+              name = 'clone'
+              desc = 'Clone the TbState (you then own the pointer)'
+              virtual = 'TRUE'
+              const = 'TRUE'>
+      </method>
+      
+      <method type = 'Gaudi::XYZPoint'
+              name = 'position'
+              desc = 'Retrieve the 3D-position vector (x,y,z) of the state'
+              const = 'TRUE'>
+        <code>
+  return Gaudi::XYZPoint(m_parameters[0], m_parameters[1], m_z);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'x'
+              desc = 'Retrieve the x-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[0];
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'y'
+              desc = 'Retrieve the y-position of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[1];
+        </code>
+      </method>
+      
+      <method type = 'Gaudi::XYZVector'
+              name = 'slopes'
+              desc = 'Retrieve the slopes (dx/dz, dy/dz, 1.) of the state'
+              const = 'TRUE'>
+        <code>
+  return Gaudi::XYZVector(m_parameters[2], m_parameters[3], 1.);
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'tx'
+              desc = 'Retrieve the Tx=dx/dz slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[2];
+        </code>
+      </method>
+      
+      <method type = 'double'
+              name = 'ty'
+              desc = 'Retrieve the Ty=dy/dz slope of the state'
+              const = 'TRUE'>
+        <code>
+  return m_parameters[3];
+        </code>
+      </method>
+      
+      <method name = 'setX'
+              argList = 'const double value'
+              desc = 'Update the x-position of the state'>
+        <code>
+  m_parameters[0] = value;
+        </code>
+      </method>
+      
+      <method name = 'setY'
+              argList = 'const double value'
+              desc    = 'Update the y-position of the state'>
+        <code>
+  m_parameters[1] = value;
+        </code>
+      </method>
+      
+      <method name = 'setZ'
+              argList = 'const double value'
+              desc = 'Update the z-position of the state'>
+        <code>
+  m_z = value;
+        </code>
+      </method>
+      
+      <method name = 'setTx'
+              argList = 'const double value'
+              desc = 'Update the x-slope tx = dx/dz of the state'>
+        <code>
+  m_parameters[2] = value;
+        </code>
+      </method>
+      
+      <method name = 'setTy'
+              argList = 'const double value'
+              desc = 'Update the y-slope ty = dy/dz of the state'>
+        <code>
+  m_parameters[3] = value;
+        </code>
+      </method>
+      
+      <method name = 'setState'
+              argList = 'double x, double y, double tx, double ty, double z'
+              desc = 'Update the state vector'/>
+      
+      <method name = 'setCovariance'
+             argList = 'Gaudi::SymMatrix4x4 value'
+             desc = 'Update the covariance matrix'>
+        <code>
+  m_covariance = value;
+        </code>
+      </method>
+  
+      <method name = "fillStream"
+              desc = "Print to message stream"
+              type = "MsgStream&amp;"
+              const = "TRUE">
+        <arg name = "os" type = "MsgStream" inout = "BOTH"/>
+        <code>
+          os &lt;&lt; "{ " 
+          &lt;&lt; "parameters: " &lt;&lt; m_parameters &lt;&lt; std::endl
+          &lt;&lt; "z:          " &lt;&lt; m_z &lt;&lt; std::endl
+          &lt;&lt; " }";
+          return os;
+        </code>
+      </method>
+      
+    </class>
+    
+  </package>
+</gdd>
+
diff --git a/TbEvent/xml/TbTrack.xml b/TbEvent/xml/TbTrack.xml
new file mode 100644
index 0000000..0aa5c65
--- /dev/null
+++ b/TbEvent/xml/TbTrack.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbTrack"
+           id = "4512"
+           author = "H. Schindler"
+           desc = "Reconstructed telescope track"
+           serializers = "FALSE">
+      <location name = "Default" place = "Rec/Tb/TbTracks"/>
+      <import name = "Event/TbCluster"/>
+      <import name = "Event/TbTrigger"/>
+      <import name = "Event/TbState"/>
+      <import name = "vector" std = "TRUE"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedObject;
+      
+      <constructor desc = 'Default constructor'
+                   initList = "m_time(0), m_htime(0.), m_firstState(), m_chi2PerNdof(0.), m_ndof(0), m_states(), m_vertexed(false), m_parentVertex(false)">
+        <code>
+  m_clusters.reserve(10);
+  m_triggers.reserve(10);
+  m_associatedClusters.reserve(10);
+  m_states.reserve(10);
+        </code>
+      </constructor>
+      
+      <relation name = 'clusters' 
+                type = 'LHCb::TbCluster' 
+                desc = 'clusters forming this track'
+                multiplicity = 'm'/>
+      
+      <relation name = 'triggers' 
+                type = 'LHCb::TbTrigger' 
+                desc = 'triggers associated to this track'
+                multiplicity = 'm'/>
+
+      <relation name = 'associatedClusters' 
+                type = 'LHCb::TbCluster' 
+                desc = 'clusters associated to this track'
+                multiplicity = 'm'/>
+
+      <attribute name = "time"
+                 type = "uint64_t" 
+                 desc = "global timestamp"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "firstState"
+                 desc = "first state of the track"
+                 type = 'LHCb::TbState'/>
+      
+      <attribute name = "chi2PerNdof"
+                 desc = "chi-squared per degree of freedom of the track"
+                 type = "double"/>
+      
+      <attribute name = "ndof"
+                 desc = "number of degrees of freedom"
+                 type = "unsigned int"/>
+      
+      <attribute type = 'std::vector&lt;LHCb::TbState&gt;'
+                 name = 'states'
+                 desc = 'container with all states'
+                 setMeth= 'FALSE'/>
+                 
+      <attribute name = 'vertexed'
+                 desc = 'flag whether this track forms part of a vertex'
+                 type = 'bool'/>
+                                  
+      <attribute name = 'parentVertex'
+                 desc = 'flag whether this track forms the start of a vertex'
+                 type = 'bool'/>
+      
+      <constructor desc = "Copy constructor" >
+         <arg const="TRUE" name="track" type="LHCb::TbTrack"/>
+      </constructor>
+
+      <method type = 'void'
+              name = 'clearStates'
+              desc = 'Clear the State vector'>
+      </method>
+
+      <method type = 'double'
+              name = 'chi2'
+              desc = 'Retrieve the chi-squared of the track'
+              const = 'TRUE'>
+        <code>
+  return m_chi2PerNdof * m_ndof;
+        </code>
+      </method>
+
+      <method name = "clone"
+              desc = "Clone the track without keeping the clusters (you take ownership of the pointer)"
+              type = "LHCb::TbTrack*"
+              virtual = "TRUE"/>
+
+      <method name = 'addToStates'
+              desc = 'Add a state to the list of states associated to the track'>
+        <arg type = 'const LHCb::TbState' name = 'state'/>
+      </method>
+  
+      <method name = "size"
+              desc = "Return the number of clusters forming this track"
+              type = "unsigned int"
+              const = "TRUE">
+        <code>
+  return m_clusters.size();
+        </code>
+      </method>
+      
+      <method name = "setAssociated"
+              desc = "Flag the clusters in a track as associated / unassociated"
+              type = "void"
+              argList = "const bool flag">
+        <code>
+  for (auto it = m_clusters.begin(), end = m_clusters.end(); it != end; ++it) {
+    (*it)->setAssociated(flag);
+  }
+        </code>
+      </method>
+  
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/TbTrigger.xml b/TbEvent/xml/TbTrigger.xml
new file mode 100755
index 0000000..1770d5c
--- /dev/null
+++ b/TbEvent/xml/TbTrigger.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbTrigger"
+           id = "4513"
+           author = "H. Schindler"
+           desc = "Trigger timestamp">
+      <location name = "Default" place = "Raw/Tb/Triggers"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedContainer;
+      
+      <constructor desc = 'Constructor with pixel packet'
+                   argList = 'uint64_t data'
+                   initList = 'm_associated(false)'>
+        <code>
+  m_plane = 0;
+  m_data = data;
+  m_time = 0xFFFFFFFFFFF &amp; data;
+  m_counter = (data >> 44) &amp; 0xFFF;
+        </code>
+      </constructor>
+
+      <constructor desc = 'Copy constructor'
+                   argList = 'const LHCb::TbTrigger* other'>
+        <code>
+  m_plane = other->plane();
+  m_data = other->data();
+  m_time = other->time();
+  m_counter = other->counter();
+  m_htime = other->htime();
+  m_associated = other->associated();
+        </code>
+      </constructor>
+
+      <attribute name = "counter"
+                 type = "unsigned int"
+                 desc = "counter"/>
+
+      <attribute name = "time"    
+                 type = "uint64_t"
+                 desc = "global timestamp"/>
+
+      <attribute name = "data"    
+                 type = "uint64_t"
+                 desc = "complete data packet"/>
+
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "local timestamp in ns"/>
+
+      <attribute name = "associated"
+                 type = "bool"
+                 desc = "flag whether the trigger is associated to a track"/>
+      <attribute name = "plane"
+                 type = "int"
+                 desc = "Plane of the trigger, dummy for the alignment"/>
+  </class> 
+ </package>
+</gdd>
diff --git a/TbEvent/xml/TbVertex.xml b/TbEvent/xml/TbVertex.xml
new file mode 100644
index 0000000..eb8a99d
--- /dev/null
+++ b/TbEvent/xml/TbVertex.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE gdd SYSTEM "gdd.dtd" >
+<gdd>
+  <package name = "TbEvent">
+    <class name = "TbVertex"
+           id = "4515"
+           author = "D. Saunders"
+           desc = "Reconstructed telescope vertex"
+           serializers = "FALSE">
+      <location name = "Default" place = "Rec/Tb/TbVertices"/>
+      <import name = "Event/TbTrack"/>
+      <base name = "KeyedObject&lt;int&gt;"/>
+      &KeyedObject;
+      
+      <relation name = 'tracks' 
+                type = 'LHCb::TbTrack' 
+                desc = 'tracks connecting at the vertex'
+                multiplicity = 'm'/>
+                
+      <attribute name = "x"
+                 type = "double"
+                 desc = "x position of the vertex"/>
+                 
+      <attribute name = "y"
+                 type = "double"
+                 desc = "y position of the vertex"/>
+                 
+      <attribute name = "z"
+                 type = "double"
+                 desc = "z position of the vertex"/>
+                 
+      <attribute name = "htime"
+                 type = "double"
+                 desc = "htime position of the vertex"/>
+                 
+                 
+      <attribute name = "interactionPlane"
+                 type = "unsigned int"
+                 desc = "plane forming the vertex"/>
+    </class>
+  </package>
+</gdd>
diff --git a/TbEvent/xml/gdd.dtd b/TbEvent/xml/gdd.dtd
new file mode 100755
index 0000000..05489ca
--- /dev/null
+++ b/TbEvent/xml/gdd.dtd
@@ -0,0 +1,221 @@
+<?xml encoding="UTF-8"?>
+<!-- ?xml encoding="ISO-8859-1"? -->
+<!ELEMENT gdd ((import*, package+)+)>
+<!ATTLIST gdd
+        version          CDATA                             "1.0"
+>
+
+<!ELEMENT import EMPTY>
+<!ATTLIST import
+        name             CDATA                             #REQUIRED
+        std              (TRUE | FALSE)                    "FALSE"
+        soft             (TRUE | FALSE | FORWARDONLY)      "FALSE"
+        namespace        CDATA                             #IMPLIED
+>
+
+<!ELEMENT package ((import*, class*, namespace*, assoc*)*)>
+<!ATTLIST package
+        name             CDATA                             #REQUIRED
+        namespace        CDATA                             #IMPLIED
+>
+<!-- ELEMENT class ((class?, ..... -->
+<!ELEMENT class ((desc?, base?, copyconstructor?, assignmentoperator?, import?, location?, enum?, typedef?, constructor?, destructor?, method?, attribute?, relation?, template?)*)>
+<!ATTLIST class
+        name              CDATA                            #REQUIRED
+        author            CDATA                            #REQUIRED
+        desc              CDATA                            #REQUIRED
+        id                CDATA                            #IMPLIED
+        version           CDATA                            #IMPLIED
+        location          CDATA                            #IMPLIED
+        namespace         CDATA                            #IMPLIED
+        stdVectorTypeDef  (TRUE | FALSE)                   "FALSE"  
+        keyedContTypeDef  (TRUE | FALSE)                   "FALSE"  
+        contObjectTypeDef (TRUE | FALSE)                   "FALSE"
+        serializers       (TRUE | FALSE)                   "TRUE"    
+        virtual           (TRUE | FALSE)                   "TRUE"
+        allocator         (DEFAULT | NO | BOOST | BOOST2 | DEBUG )  "DEFAULT"    
+        defaultconstructor (TRUE | FALSE)                  "TRUE"
+        defaultdestructor  (TRUE | FALSE)                  "TRUE">
+       
+<!ELEMENT desc (#PCDATA)>
+<!ATTLIST desc
+        xml:space        (default | preserve)              #FIXED "preserve"
+>
+<!ELEMENT copyconstructor EMPTY>
+<!ELEMENT assignmentoperator EMPTY>
+<!ELEMENT location EMPTY>
+<!ATTLIST location
+        name             CDATA                             #REQUIRED
+        place            CDATA                             #REQUIRED
+        noQuote          (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT namespace ((desc?, typedef?, enum?, class?, import?, attribute?, method?)*)>
+<!ATTLIST namespace
+        name             CDATA                             #REQUIRED
+        author           CDATA                             #IMPLIED
+        desc             CDATA                             #REQUIRED
+        scope            CDATA                             #IMPLIED
+>
+<!ELEMENT base EMPTY>
+<!ATTLIST base
+        name             CDATA                             #REQUIRED
+        virtual          (TRUE | FALSE)                    "FALSE"
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PUBLIC"
+>
+<!ELEMENT enum (enumval*)>
+<!ATTLIST enum
+        name             CDATA                             #REQUIRED
+        desc             CDATA                             #REQUIRED
+        value            CDATA                             #IMPLIED
+        strTypConv       (TRUE | FALSE )                   "FALSE"
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PRIVATE"
+        unknownValue     CDATA                             "Unknown"
+>
+<!ELEMENT enumval EMPTY>
+<!ATTLIST enumval
+        name             CDATA                             #REQUIRED
+        value            CDATA                             #IMPLIED
+        desc             CDATA                             #REQUIRED
+>
+<!ELEMENT typedef EMPTY>
+<!ATTLIST typedef 
+        desc             CDATA                             #REQUIRED
+        type             CDATA                             #REQUIRED
+        def              CDATA                             #REQUIRED
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PRIVATE"
+>
+<!ELEMENT constructor (arg*, code?, arg*)>
+<!ATTLIST constructor
+        desc             CDATA                             #REQUIRED
+        argList          CDATA                             #IMPLIED
+        initList         CDATA                             #IMPLIED
+        explicit         (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT destructor (arg*, code?, arg*)>
+<!ATTLIST destructor
+        desc             CDATA                             #REQUIRED
+        argList          CDATA                             #IMPLIED
+        virtual          (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT method ((arg*, return?, arg*, code?, arg*) | (arg*, code?, arg*, return?, arg*))>
+<!ATTLIST method
+        name             CDATA                             #REQUIRED
+        desc             CDATA                             #REQUIRED
+        template         CDATA                             #IMPLIED
+        access           (PUBLIC | PROTECTED | PRIVATE)    "PUBLIC"
+        const            (TRUE | FALSE)                    "FALSE"
+        virtual          (TRUE | FALSE | PURE)             "FALSE"
+        static           (TRUE | FALSE)                    "FALSE"
+        inline           (TRUE | FALSE)                    "FALSE"
+        friend           (TRUE | FALSE)                    "FALSE"
+        type             CDATA                             "void"
+        argList          CDATA                             #IMPLIED
+        useBase          CDATA                             #IMPLIED
+>
+<!ELEMENT arg EMPTY>
+<!ATTLIST arg
+        type             CDATA                             #REQUIRED
+        name             CDATA                             #IMPLIED
+        const            (TRUE | FALSE)                    "FALSE"
+        inout            (BYVALUE | INPUT | INOUT | BOTH)  "INPUT"
+>
+<!ELEMENT return EMPTY>
+<!ATTLIST return
+        type             CDATA                             #REQUIRED
+        const            (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT code (#PCDATA)>
+<!ATTLIST code
+        xml:space        (default | preserve)              #FIXED "preserve"
+>
+<!ELEMENT attribute (bitfield*)>
+<!ATTLIST attribute
+        type             CDATA                            #REQUIRED
+        name             CDATA                            #REQUIRED
+        desc             CDATA                            #REQUIRED
+        init             CDATA                            #IMPLIED
+        dictalias        CDATA                            #IMPLIED
+        access           (PUBLIC | PROTECTED | PRIVATE)   "PRIVATE"
+        compression      (TRUE | FALSE)                   "TRUE"
+        setMeth          (TRUE | FALSE)                   "TRUE"
+        getMeth          (TRUE | FALSE)                   "TRUE"
+        transient        (TRUE | FALSE)                   "FALSE"    
+        nonconstaccessor (TRUE | FALSE)                   "FALSE"
+>
+<!ELEMENT relation EMPTY>
+<!ATTLIST relation
+        type             CDATA                            #REQUIRED
+        name             CDATA                            #REQUIRED
+        desc             CDATA                            #REQUIRED
+        access           (PUBLIC | PROTECTED | PRIVATE)   "PRIVATE"
+        multiplicity     (1 | N | n | M | m)              "1"
+        serialize        (TRUE | FALSE)                   "TRUE"
+        setMeth          (TRUE | FALSE)                   "TRUE"
+        getMeth          (TRUE | FALSE)                   "TRUE"
+        addMeth          (TRUE | FALSE)                   "TRUE"
+        remMeth          (TRUE | FALSE)                   "TRUE"
+        clrMeth          (TRUE | FALSE)                   "TRUE"
+        nonconstaccessor (TRUE | FALSE)                   "FALSE"
+>
+<!ELEMENT bitfield EMPTY>
+<!ATTLIST bitfield
+        name             CDATA                             #REQUIRED
+        type             CDATA                             #IMPLIED
+        length           CDATA                             #REQUIRED
+        desc             CDATA                             #REQUIRED
+        startBit         CDATA                             #IMPLIED
+        exclusive        (TRUE | FALSE)                    "TRUE"
+        setMeth          (TRUE | FALSE)                    "TRUE"
+        getMeth          (TRUE | FALSE)                    "TRUE"
+        checkMeth        (TRUE | FALSE)                    "FALSE"
+>
+<!ELEMENT template EMPTY>
+<!ATTLIST template
+        name             CDATA                             #REQUIRED
+        t1               CDATA                             "THIS"
+        t2               CDATA                             #IMPLIED
+        t3               CDATA                             #IMPLIED
+        t4               CDATA                             #IMPLIED
+>
+
+<!ELEMENT assoc EMPTY>
+<!ATTLIST assoc
+        type             (1D | 2D)                         "1D"
+        weight           CDATA                             "NONE"
+        from             CDATA                             #REQUIRED
+        to               CDATA                             #REQUIRED
+>
+
+<!ENTITY KeyedObjectKey 'int'>
+<!ENTITY Reference '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>'
+>
+<!ENTITY StlVector '<template name="vector" t1="THIS"/>'
+>
+<!ENTITY StlConstVector '<template name="vector" t1="const THIS"/>'
+>
+<!ENTITY StlPtrVector '<template name="vector" t1="THIS*"/>'
+>
+<!ENTITY StlConstPtrVector '<template name="vector" t1="const THIS*"/>'
+>
+<!ENTITY DataObject '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>'
+>
+<!ENTITY ContainedObject '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>
+        <template name="vector" t1="THIS*"/>
+        <template name="ObjectVector"/>'
+>
+<!ENTITY KeyedContainer '<template name="SmartRef"/>
+        <template name="SmartRefVector"/>
+        <template name="vector" t1="THIS*"/>
+        <template name="ObjectVector"/>
+        <template name="KeyedContainer"/>'
+>
+<!ENTITY KeyedObject '<template name="KeyedObject" t1="int"/>
+        <template name="SmartRef"/>
+        <template name="SmartRefVector"/>
+        <template name="vector" t1="THIS*"/>
+        <template name="ObjectVector"/>
+        <template name="KeyedContainer"/>'
+>
diff --git a/TbEvent/xml/lcgdict/.svn/all-wcprops b/TbEvent/xml/lcgdict/.svn/all-wcprops
new file mode 100644
index 0000000..ef9450f
--- /dev/null
+++ b/TbEvent/xml/lcgdict/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/170762/Kepler/trunk/Tb/TbEvent/xml/lcgdict
+END
+lcg_selection.xml
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/170762/Kepler/trunk/Tb/TbEvent/xml/lcgdict/lcg_selection.xml
+END
diff --git a/TbEvent/xml/lcgdict/.svn/entries b/TbEvent/xml/lcgdict/.svn/entries
new file mode 100644
index 0000000..d102307
--- /dev/null
+++ b/TbEvent/xml/lcgdict/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbEvent/xml/lcgdict
+http://svn.cern.ch/guest/lhcb
+
+
+
+2014-03-31T17:37:58.454693Z
+170762
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+lcg_selection.xml
+file
+
+
+
+
+2016-05-09T14:27:54.000000Z
+2cb43c48d23c7e00f36372bc03be1c00
+2014-03-31T17:37:58.454693Z
+170762
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+21
+
diff --git a/TbEvent/xml/lcgdict/.svn/prop-base/lcg_selection.xml.svn-base b/TbEvent/xml/lcgdict/.svn/prop-base/lcg_selection.xml.svn-base
new file mode 100644
index 0000000..a669705
--- /dev/null
+++ b/TbEvent/xml/lcgdict/.svn/prop-base/lcg_selection.xml.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 0
+
+END
diff --git a/TbEvent/xml/lcgdict/.svn/text-base/lcg_selection.xml.svn-base b/TbEvent/xml/lcgdict/.svn/text-base/lcg_selection.xml.svn-base
new file mode 100644
index 0000000..2eff49d
--- /dev/null
+++ b/TbEvent/xml/lcgdict/.svn/text-base/lcg_selection.xml.svn-base
@@ -0,0 +1,2 @@
+<lcgdict>
+</lcgdict>
diff --git a/TbEvent/xml/lcgdict/lcg_selection.xml b/TbEvent/xml/lcgdict/lcg_selection.xml
new file mode 100755
index 0000000..2eff49d
--- /dev/null
+++ b/TbEvent/xml/lcgdict/lcg_selection.xml
@@ -0,0 +1,2 @@
+<lcgdict>
+</lcgdict>
diff --git a/TbIO/.svn/all-wcprops b/TbIO/.svn/all-wcprops
new file mode 100644
index 0000000..50a5f3f
--- /dev/null
+++ b/TbIO/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 48
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/188491/Kepler/trunk/Tb/TbIO/CMakeLists.txt
+END
diff --git a/TbIO/.svn/entries b/TbIO/.svn/entries
new file mode 100644
index 0000000..863431a
--- /dev/null
+++ b/TbIO/.svn/entries
@@ -0,0 +1,71 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbIO
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+src
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+fa6502398dff8d76e187cd2d71d03ee8
+2015-05-19T09:54:16.789200Z
+188491
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+478
+
diff --git a/TbIO/.svn/text-base/CMakeLists.txt.svn-base b/TbIO/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..dbf4ff6
--- /dev/null
+++ b/TbIO/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,15 @@
+################################################################################
+# Package: TbIO
+################################################################################
+gaudi_subdir(TbIO v2r0)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbIO
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost)
+
diff --git a/TbIO/CMakeLists.txt b/TbIO/CMakeLists.txt
new file mode 100644
index 0000000..dbf4ff6
--- /dev/null
+++ b/TbIO/CMakeLists.txt
@@ -0,0 +1,15 @@
+################################################################################
+# Package: TbIO
+################################################################################
+gaudi_subdir(TbIO v2r0)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbIO
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost)
+
diff --git a/TbIO/cmt/.svn/all-wcprops b/TbIO/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..e964b03
--- /dev/null
+++ b/TbIO/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/188491/Kepler/trunk/Tb/TbIO/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/188491/Kepler/trunk/Tb/TbIO/cmt/requirements
+END
diff --git a/TbIO/cmt/.svn/entries b/TbIO/cmt/.svn/entries
new file mode 100644
index 0000000..5c4defe
--- /dev/null
+++ b/TbIO/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbIO/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T09:54:16.789200Z
+188491
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+490498ee5e8554949c1657b2245b4871
+2015-05-19T09:54:16.789200Z
+188491
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+482
+
diff --git a/TbIO/cmt/.svn/text-base/requirements.svn-base b/TbIO/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..b347711
--- /dev/null
+++ b/TbIO/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,16 @@
+package TbIO 
+version v2r0
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+use  Boost        v*  LCG_Interfaces
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbIO    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbIO
diff --git a/TbIO/cmt/requirements b/TbIO/cmt/requirements
new file mode 100644
index 0000000..b347711
--- /dev/null
+++ b/TbIO/cmt/requirements
@@ -0,0 +1,16 @@
+package TbIO 
+version v2r0
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+use  Boost        v*  LCG_Interfaces
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbIO    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbIO
diff --git a/TbIO/doc/.svn/all-wcprops b/TbIO/doc/.svn/all-wcprops
new file mode 100644
index 0000000..e38995b
--- /dev/null
+++ b/TbIO/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/doc/release.notes
+END
diff --git a/TbIO/doc/.svn/entries b/TbIO/doc/.svn/entries
new file mode 100644
index 0000000..a69e24c
--- /dev/null
+++ b/TbIO/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbIO/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+044d99dfd731aac8cccd0b4da40e9a65
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2728
+
diff --git a/TbIO/doc/.svn/text-base/release.notes.svn-base b/TbIO/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..d1ab3fa
--- /dev/null
+++ b/TbIO/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,79 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbIO
+! Responsible :
+! Purpose     : Testbeam algorithms dealing with input/output
+!-----------------------------------------------------------------------------
+
+! 2016-04-26 - Tim Evans
+ - Added option to use TPX3 to set global heartbeat.
+
+! 2016-01-28 - Heinrich Schindler
+ - Move code from constructor of TbHit to TbEventBuilder.
+
+! 2015-10-23 - Heinrich Schindler
+ - Fix compiler warnings in TbCombatBuilder (unused class members) and 
+   TbEventBuilder (replace fabs by abs).
+
+!=========================== TbIO v3r0  ============================
+
+! 2015-07-16 - Panagiotis Tsopelas
+ - Added sCol() method in TbTupleWriter to access extra columns on Triples.
+
+!=========================== TbIO v2r0 2015-05-19 ============================
+
+! 2015-05-18 - Tim Evans
+ - Added trigger output for tracks for external users
+
+! 2015-01-24 - Heinrich Schindler
+ - Add .cpp file for TbRawFile. Add comments.
+ - Add back some checks in TbEventBuilder.
+
+! 2015-01-22 - Heinrich Schindler
+ - Follow renamings in TbKernel (mainly TbGeometrySvc).
+
+! 2014-12-12 - Heinrich Schindler
+ - Follow renaming of TbHit::plane to TbHit::device.
+
+! 2014-11-17 - Tim Evans
+ - TbRawFile now inherits from ITbRawFile and is (semi) obsolete, in favour of 
+   TbNetworkRawFile, which can use EOS without mounting - currently only network 
+   version is used.
+ - Input parameter out of the EventBuilder to reflect Kernel changes - now 
+   gets data from TbDataSvc
+
+!=========================== TbIO v1r1 2014-11-30 ============================
+
+! 2014-10-4 - Tim Evans
+ - Add new algorithm TbPacketRecycler to facilitate 
+   trading of hits between events
+ - TbRawStream changed to a GaudiTool such that packets can be recached
+
+! 2014-09-24 - Dan Saunders
+ - Added alternative event builder and .py files to allow use with Combat 
+   Telescope. 
+
+!=========================== TbIO v1r0 2014-08-18 ============================
+ 
+! 2014-08-12 - Heinrich Schindler
+ - Fix constexpr bug introduced in previous commit.
+ - Minor changes in TbTupleWriter.
+
+! 2014-08-11 - Heinrich Schindler
+ - Small speed improvements in TbEventBuilder and helper classes.
+
+! 2014-08-08 - Tim Evans
+ - Restyled the TupleWriter so that branches are preallocated and 
+   variable size fixed 
+ - Added dynamic arrays for cluster - hit association and track - cluster 
+   association
+
+! 2014-08-02 - Heinrich Schindler
+ - Make min. number of non-empty devices required for an event configurable.
+
+! 2014-07-25 - Tim Evans
+ - Added split file support
+ - Added file / event skipping
+
+! 2014-07-21 - Heinrich Schindler
+ - Initial import.
+ - Move over TbTupleWriter from TbAlgorithms.
diff --git a/TbIO/doc/release.notes b/TbIO/doc/release.notes
new file mode 100644
index 0000000..d1ab3fa
--- /dev/null
+++ b/TbIO/doc/release.notes
@@ -0,0 +1,79 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbIO
+! Responsible :
+! Purpose     : Testbeam algorithms dealing with input/output
+!-----------------------------------------------------------------------------
+
+! 2016-04-26 - Tim Evans
+ - Added option to use TPX3 to set global heartbeat.
+
+! 2016-01-28 - Heinrich Schindler
+ - Move code from constructor of TbHit to TbEventBuilder.
+
+! 2015-10-23 - Heinrich Schindler
+ - Fix compiler warnings in TbCombatBuilder (unused class members) and 
+   TbEventBuilder (replace fabs by abs).
+
+!=========================== TbIO v3r0  ============================
+
+! 2015-07-16 - Panagiotis Tsopelas
+ - Added sCol() method in TbTupleWriter to access extra columns on Triples.
+
+!=========================== TbIO v2r0 2015-05-19 ============================
+
+! 2015-05-18 - Tim Evans
+ - Added trigger output for tracks for external users
+
+! 2015-01-24 - Heinrich Schindler
+ - Add .cpp file for TbRawFile. Add comments.
+ - Add back some checks in TbEventBuilder.
+
+! 2015-01-22 - Heinrich Schindler
+ - Follow renamings in TbKernel (mainly TbGeometrySvc).
+
+! 2014-12-12 - Heinrich Schindler
+ - Follow renaming of TbHit::plane to TbHit::device.
+
+! 2014-11-17 - Tim Evans
+ - TbRawFile now inherits from ITbRawFile and is (semi) obsolete, in favour of 
+   TbNetworkRawFile, which can use EOS without mounting - currently only network 
+   version is used.
+ - Input parameter out of the EventBuilder to reflect Kernel changes - now 
+   gets data from TbDataSvc
+
+!=========================== TbIO v1r1 2014-11-30 ============================
+
+! 2014-10-4 - Tim Evans
+ - Add new algorithm TbPacketRecycler to facilitate 
+   trading of hits between events
+ - TbRawStream changed to a GaudiTool such that packets can be recached
+
+! 2014-09-24 - Dan Saunders
+ - Added alternative event builder and .py files to allow use with Combat 
+   Telescope. 
+
+!=========================== TbIO v1r0 2014-08-18 ============================
+ 
+! 2014-08-12 - Heinrich Schindler
+ - Fix constexpr bug introduced in previous commit.
+ - Minor changes in TbTupleWriter.
+
+! 2014-08-11 - Heinrich Schindler
+ - Small speed improvements in TbEventBuilder and helper classes.
+
+! 2014-08-08 - Tim Evans
+ - Restyled the TupleWriter so that branches are preallocated and 
+   variable size fixed 
+ - Added dynamic arrays for cluster - hit association and track - cluster 
+   association
+
+! 2014-08-02 - Heinrich Schindler
+ - Make min. number of non-empty devices required for an event configurable.
+
+! 2014-07-25 - Tim Evans
+ - Added split file support
+ - Added file / event skipping
+
+! 2014-07-21 - Heinrich Schindler
+ - Initial import.
+ - Move over TbTupleWriter from TbAlgorithms.
diff --git a/TbIO/src/.svn/all-wcprops b/TbIO/src/.svn/all-wcprops
new file mode 100644
index 0000000..74fcc27
--- /dev/null
+++ b/TbIO/src/.svn/all-wcprops
@@ -0,0 +1,89 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/src
+END
+TbEventBuilder.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/src/TbEventBuilder.cpp
+END
+TbRawFile.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/183200/Kepler/trunk/Tb/TbIO/src/TbRawFile.cpp
+END
+TbRawStream.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/src/TbRawStream.h
+END
+TbTupleWriter.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/205429/Kepler/trunk/Tb/TbIO/src/TbTupleWriter.h
+END
+TbCombatBuilder.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/196683/Kepler/trunk/Tb/TbIO/src/TbCombatBuilder.cpp
+END
+TbEventBuilder.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/src/TbEventBuilder.h
+END
+TbHeaderDecoder.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/196750/Kepler/trunk/Tb/TbIO/src/TbHeaderDecoder.cpp
+END
+TbRawFile.h
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/guest/lhcb/!svn/ver/198356/Kepler/trunk/Tb/TbIO/src/TbRawFile.h
+END
+TbPacketRecycler.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/196750/Kepler/trunk/Tb/TbIO/src/TbPacketRecycler.cpp
+END
+TbCombatBuilder.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/196683/Kepler/trunk/Tb/TbIO/src/TbCombatBuilder.h
+END
+TbHeaderDecoder.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/182097/Kepler/trunk/Tb/TbIO/src/TbHeaderDecoder.h
+END
+TbPacketRecycler.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/181195/Kepler/trunk/Tb/TbIO/src/TbPacketRecycler.h
+END
+TbRawStream.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/205730/Kepler/trunk/Tb/TbIO/src/TbRawStream.cpp
+END
+TbTupleWriter.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/205429/Kepler/trunk/Tb/TbIO/src/TbTupleWriter.cpp
+END
diff --git a/TbIO/src/.svn/entries b/TbIO/src/.svn/entries
new file mode 100644
index 0000000..5bf3675
--- /dev/null
+++ b/TbIO/src/.svn/entries
@@ -0,0 +1,504 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbIO/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbEventBuilder.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+2952466fb7fa8fa0923f939d1cfeb120
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+22032
+
+TbRawFile.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+6db8108b6cf2ab0b926c9e9f366aa456
+2015-01-24T19:56:28.901022Z
+183200
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1293
+
+TbRawStream.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+830f69ca4b528dd947fc042484be2c63
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3067
+
+TbTupleWriter.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+97ba3153b7c3e5c73602caf38fd9ddf0
+2016-04-26T21:12:12.239267Z
+205429
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2930
+
+TbCombatBuilder.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+0ceb26d193c3514c80bca2a7adeb56d5
+2015-10-23T11:15:02.549411Z
+196683
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6575
+
+TbEventBuilder.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+1f2133cd9516b27f4e7fd326960a86c2
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5294
+
+TbHeaderDecoder.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+733cc6f6b4f2ec82bf43dd351e38d6f6
+2015-10-24T14:26:49.957067Z
+196750
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8258
+
+TbRawFile.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+4bfe8b7cad4c27d382b10e863ef17458
+2015-11-27T21:01:44.399604Z
+198356
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1276
+
+TbPacketRecycler.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+9c7bcf6b83ff425dd616391495042757
+2015-10-24T14:26:49.957067Z
+196750
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4230
+
+TbCombatBuilder.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+7b08e552eab5c28e039a3ee355323516
+2015-10-23T11:15:02.549411Z
+196683
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1617
+
+TbHeaderDecoder.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+3c6c3c6b5f1829772fd8bf6038c16991
+2015-01-03T11:53:00.925632Z
+182097
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1579
+
+TbPacketRecycler.h
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+4ffe888b959f00567915fb0d13f6fe12
+2014-12-07T16:56:21.899047Z
+181195
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1463
+
+TbRawStream.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+ca59821a305ecc8b0e5c82829c30526c
+2016-05-06T09:21:52.601495Z
+205730
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6313
+
+TbTupleWriter.cpp
+file
+
+
+
+
+2016-05-09T14:27:58.000000Z
+617f9e0c90a71730adf364cfd847755c
+2016-04-26T21:12:12.239267Z
+205429
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+12706
+
diff --git a/TbIO/src/.svn/text-base/TbCombatBuilder.cpp.svn-base b/TbIO/src/.svn/text-base/TbCombatBuilder.cpp.svn-base
new file mode 100644
index 0000000..2c18bf6
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbCombatBuilder.cpp.svn-base
@@ -0,0 +1,208 @@
+#include <algorithm>
+
+// Boost
+#include <boost/filesystem.hpp>
+
+// Gaudi
+#include "GaudiKernel/IEventProcessor.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbCombatBuilder.h"
+
+DECLARE_ALGORITHM_FACTORY(TbCombatBuilder)
+
+namespace fs = boost::filesystem;
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbCombatBuilder::TbCombatBuilder(const std::string& name,
+                                 ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_nPixels(256),
+      m_nEvents(0),
+      m_neof(true) {
+
+  declareProperty("CombatInputFile0", m_fileName0);
+  declareProperty("CombatInputFile1", m_fileName1 = "DefaultFileName1.dat");
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("MinPlanesWithHits", m_nMinPlanesWithHits = 1);  // TODO
+  declareProperty("SkipEvents", m_skipEvents = 0);                 // TODO
+  declareProperty("PrintFreq", m_printFreq = 100);
+  declareProperty("ReadoutFormat", m_readoutFormat);
+  declareProperty("FakeTime", m_fakeTime = 1);
+  declareProperty("NumberArms", m_nArms);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbCombatBuilder::~TbCombatBuilder() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbCombatBuilder::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Prepare the hit containers.
+  m_hits.resize(m_nPlanes, NULL);
+
+  // Open the hit files.
+  m_dataStream0.open(m_fileName0.c_str());
+  if (!m_dataStream0.is_open()) {
+    error() << "Cannot open file name: " << m_fileName0 << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if (m_nArms == 2 && m_readoutFormat=="Pixelman") {
+    m_dataStream1.open(m_fileName1.c_str());
+    if (!m_dataStream1.is_open()) {
+      error() << "Cannot open file name: " << m_fileName1 << endmsg;
+      return StatusCode::FAILURE;
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbCombatBuilder::execute() {
+  // Printing.
+  if (m_nEvents % m_printFreq == 0)
+    info() << "Loading event: " << m_nEvents << endmsg;
+
+  // Create containers for hits.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string ext = std::to_string(i);
+    m_hits[i] = new LHCb::TbHits();
+    put(m_hits[i], m_hitLocation + ext);
+  }
+
+
+  if(m_readoutFormat=="Pixelman"){
+	  if (m_nArms == 1) {
+		  fillEventFromPixelmanFile(0);
+	  } else if (m_nArms == 2) {
+		  fillEventFromPixelmanFile(0);
+		  fillEventFromPixelmanFile(1);
+	  }
+  }
+  else if(m_readoutFormat=="RelaxD"){
+	  fillEventFromRelaxDFile();
+  }
+
+  // Check whether there are any events left.
+  if (!m_neof) {
+    // Terminate.
+    SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+    if (app) app->stopRun();
+  } else {
+    // Ordering.
+    for (unsigned int i = 0; i < m_nPlanes; i++) {
+      std::sort(m_hits[i]->begin(), m_hits[i]->end(),
+                TbFunctors::GreaterByToT<const LHCb::TbHit*>());
+    }
+    m_nEvents++;
+  }
+
+  // Prepare for the next event.
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+StatusCode TbCombatBuilder::finalize() { return TbAlgorithm::finalize(); }
+
+//=============================================================================
+// Event filling handling Pixelman files
+//=============================================================================
+void TbCombatBuilder::fillEventFromPixelmanFile(const int armID) {
+  // Check we havent reached the next event.
+  bool sameEvent = true;  
+  while (sameEvent) {
+    std::string line;
+    if (armID == 0)
+      m_neof = std::getline(m_dataStream0, line);
+    else
+      m_neof = std::getline(m_dataStream1, line);
+    if (!m_neof) break;
+    if (line.substr(0, 1) == "#")
+      sameEvent = false;
+    else
+      fillHit(line, armID);
+  }
+}
+
+//=============================================================================
+// Event filling handling RelaxD files
+//=============================================================================
+void TbCombatBuilder::fillEventFromRelaxDFile() {
+
+//For the RelaxD files, in one event the first series of hits come from the upper arm and the second from the downstream arm.
+     for(int iArm=0;iArm<m_nArms;iArm++){
+        // Check we havent reached the next event.
+        bool sameEvent = true;
+        bool frameStart = false;
+        while (sameEvent) {
+               std::string line;
+               m_neof = std::getline(m_dataStream0, line);
+               if (!m_neof) break;
+               if (line.substr(0,1) != "#"){
+                   frameStart= true;
+                   fillHit(line, iArm);
+               }
+               if (line.substr(0, 1) == "#"&& frameStart==true)
+                   sameEvent = false;
+        }
+     }
+}
+//=============================================================================
+// Event filling
+//=============================================================================
+void TbCombatBuilder::fillHit(std::string line, int armID) {
+  std::stringstream lineStream;
+  lineStream << line;
+  int rowTemp, colTemp, ToT;
+  lineStream >> colTemp >> rowTemp >> ToT;
+
+  int plane;
+  if (colTemp > 255) {
+    if (rowTemp > 255)
+      plane = 1;
+    else
+      plane = 3;
+  } else {
+    if (rowTemp > 255)
+      plane = 0;
+    else
+      plane = 2;
+  }
+
+  // Arm modification.
+  if (armID == 1) plane += 4;
+
+  // Make the hit.
+  LHCb::TbHit* hit = new LHCb::TbHit();
+  hit->setRow(rowTemp % m_nPixels);
+  hit->setCol(colTemp % m_nPixels);
+  hit->setToT(ToT);
+  hit->setPixelAddress(hit->row() + hit->col() * m_nPixels);
+  hit->setTime(m_fakeTime);
+  hit->setHtime(timingSvc()->globalToLocal(hit->time()));
+
+  m_hits[plane]->insert(hit);
+}
+
+//=============================================================================
+// End
+//=============================================================================
diff --git a/TbIO/src/.svn/text-base/TbCombatBuilder.h.svn-base b/TbIO/src/.svn/text-base/TbCombatBuilder.h.svn-base
new file mode 100644
index 0000000..23b439c
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbCombatBuilder.h.svn-base
@@ -0,0 +1,65 @@
+#ifndef TB_COMBATBUILDER_H
+#define TB_COMBATBUILDER_H 1
+
+#include <fstream>
+
+// Boost
+#include <boost/iostreams/device/mapped_file.hpp>
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbCombatBuilder TbCombatBuilder.h
+ *  @author Dan Saunders & Vinicius Franco
+ *  @date   2014-09-22
+ */
+
+class TbCombatBuilder : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbCombatBuilder(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbCombatBuilder();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm termination
+
+ private:
+  /// Input data files
+  std::string m_readoutFormat;
+  std::string m_fileName0;
+  std::string m_fileName1;
+  std::ifstream m_dataStream0;
+  std::ifstream m_dataStream1;
+  /// TES location of output hits
+  std::string m_hitLocation;
+  int m_nPixels;
+
+  /// Number of events to skip TODO
+  unsigned int m_skipEvents;
+  /// Min. number of non-empty planes required to make an event TODO
+  unsigned int m_nMinPlanesWithHits;
+
+  /// Frequency to print event count.
+  unsigned int m_printFreq;
+
+  /// Number of processed events
+  unsigned int m_nEvents;
+  std::vector<LHCb::TbHits*> m_hits;
+
+  /// Fake timestamp (not htime).
+  int m_fakeTime;
+  bool m_neof;
+  int m_nArms;  // 1 for vertical lab cases, 2 for testbeams.
+
+  void fillHit(std::string, int);
+  void fillEventFromPixelmanFile(const int arm);
+  void fillEventFromRelaxDFile();
+};
+
+#endif
diff --git a/TbIO/src/.svn/text-base/TbEventBuilder.cpp.svn-base b/TbIO/src/.svn/text-base/TbEventBuilder.cpp.svn-base
new file mode 100644
index 0000000..62ad713
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbEventBuilder.cpp.svn-base
@@ -0,0 +1,580 @@
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/IEventProcessor.h"
+#include "GaudiAlg/ISequencerTimerTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbEventBuilder.h"
+#include "TbRawFile.h"
+
+#include <chrono>
+#include <ctime>
+
+DECLARE_ALGORITHM_FACTORY(TbEventBuilder)
+
+const int64_t TbEventBuilder::m_maxTimeDifference = std::pow(2, 40);
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbEventBuilder::TbEventBuilder(const std::string& name, 
+                               ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator),
+    m_streams(), m_triggers(), m_hits() {
+
+    declareProperty("HitLocation", 
+        m_hitLocation = LHCb::TbHitLocation::Default);
+    declareProperty("TriggerLocation",
+        m_triggerLocation = LHCb::TbTriggerLocation::Default);
+
+    // Length of event in global time units.
+    declareProperty("EventLength", m_tick = 10 * Tb::SpidrTime);
+    // Length to look into 'future' events to correct
+    // for time misordering around event boundaries
+    declareProperty("CacheLength", m_cachelength = 20 * Tb::SpidrTime);
+
+    // The time by which events 'overlap' to prevent tracks / clusters
+    // being cut between different events. Implementation is rather
+    // convoluted, relies on track identification and global event defintion
+    // via the TbTimingSvc
+    declareProperty("OverlapTime", m_overlapTime = 0 * Tb::ToA);
+
+    // Min. number of planes with at least one hit required to make an event
+    declareProperty("MinPlanesWithHits", m_nMinPlanesWithHits = 1);
+    // Print frequency
+    declareProperty("PrintFreq", m_printFreq = 100);
+    // Size of the header, if not set is read in
+    declareProperty("HeaderSize", m_headerSize = 0);
+    // Flag to print out the header information
+    declareProperty("PrintHeader", m_printHeader = false);
+    // Flag to switch monitoring print-out and histograms.
+    declareProperty("Monitoring", m_monitoring = false);
+    // Time to start data processing, in s 
+    declareProperty("StartTime", m_startTime = 0);
+    // Time to end data processing, in ms
+    declareProperty("EndTime", m_endTime = 0);
+    // Flag to produce Equalisation maps
+    declareProperty("EqualisationHistos", m_equal = false );
+    // Maximum number of packets that can be lost before 
+    // considered a critical failure 
+    declareProperty("MaxLostPackets", m_maxLostPackets = 1000);
+    // Maximum number of timing packets that not read
+    // before considered a critical failure
+    declareProperty("MaxLostTimers", m_maxLostTimers = 10);
+    // Force the cache to update every cycle, as opposed to
+    // waiting until the first packet is in view
+    declareProperty("ForceCaching", m_forceCaching = false);
+    declareProperty("IgnoreGlobalClock", m_ignoreGlobalClock = false );
+  }
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbEventBuilder::~TbEventBuilder() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbEventBuilder::initialize() {
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Prepare the hit containers.
+  m_hits.resize(m_nPlanes, nullptr);
+  m_triggers.resize(m_nPlanes, nullptr);
+  // Setup the raw stream tools.
+  for (unsigned int i = 0; i < m_nDevices; ++i){
+    const std::string toolname = "TbRawStream/TbRawStream"+ std::to_string(i);
+    m_streams.push_back(tool<TbRawStream>(toolname));
+    if (!m_streams[i]) return Error("Cannot initialise " + toolname);
+    m_streams[i]->setDevice(i);
+  }
+  // Setup the header decoder tool.
+  m_headerDecoder = tool<TbHeaderDecoder>("TbHeaderDecoder");
+  if (!m_headerDecoder) return Error("Cannot initialise header decoder.");
+  m_headerDecoder->print(m_printHeader);
+  // Propagate the overlap time to the timing service.
+  timingSvc()->setOverlap(m_overlapTime);
+  // Get the list of input data 
+  auto files = dataSvc()->getInputFiles();
+  for (const auto& filename : files) {
+    // Check the filename.
+    const size_t pos = filename.find(".dat");
+    const size_t dash = filename.find_last_of("-");
+    if (pos == std::string::npos) {
+      warning() << "Skipping " << filename << " (not a .dat file)" << endmsg;
+      continue; 
+    }
+    if (!(pos - dash > 1)) {
+      warning() << "Unexpected filename (" << filename << ")" << endmsg;
+      warning() << "Skipping " << filename << endmsg;
+      continue;
+    }
+    TbRawFile* f = new TbRawFile(filename, m_headerDecoder);
+    if (!f->good()) {
+      if (!f->is_open()) {
+        error() << "Cannot open " << filename << endmsg;
+      } else {
+        f->close();
+      }
+      warning() << "Skipping " << filename << endmsg; 
+      delete f;
+      continue;
+    }
+    const std::string id = f->id();
+    const unsigned int plane = geomSvc()->plane(id);
+    if (plane == 999) {
+      warning() << id << " is not listed in the alignment file" << endmsg;
+      warning() << "Skipping " << filename << endmsg; 
+      f->close();
+      delete f;
+      continue;
+    }
+    const unsigned int deviceIndex = geomSvc()->deviceIndex(id);
+    if (deviceIndex == 999) {
+      warning() << id << " is not listed in the alignment file" << endmsg;
+      warning() << "Skipping " << filename << endmsg;
+      f->close();
+      delete f;
+      continue;
+    } 
+    if (m_streams[deviceIndex]->files().empty()) { 
+      info() << id << " (device " << deviceIndex 
+             << ") is mapped to plane " << plane << endmsg;
+    }
+    unsigned int col = 0;
+    auto chips = geomSvc()->module(plane)->chips();
+    for (auto chip : chips) {
+      if (chip.id == id) {
+        col = chip.col;
+      }
+    } 
+    m_streams[deviceIndex]->setPlane(plane);
+    m_streams[deviceIndex]->setDevice(deviceIndex);
+    m_streams[deviceIndex]->setOffset(col);
+    m_streams[deviceIndex]->addFile(f);
+  }
+  // Make sure that there are data files for all planes.
+  for (unsigned int i = 0; i < m_nDevices; ++i) {
+    if (m_streams[i]->files().empty()) {
+      return Error("No input files for device " + std::to_string(i));
+    }
+  }
+
+  // Convert start and end times to FToA.
+  m_startTime *= Tb::millisecond * 1000;
+  m_endTime *= Tb::millisecond;
+  for (auto& f : m_streams) {
+    std::sort(f->files().begin(), f->files().end(), lessBySplitIndex());
+    f->prepare();
+    m_nDataInFiles += f->size();
+    // Convert starting time to FToA times
+    if (m_startTime != 0) f->fastForward(m_startTime);
+  }
+  info() << "Total data size: " << m_nDataInFiles << " packets" << endmsg;
+  m_clock = m_tick + m_startTime;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbEventBuilder::execute() {
+
+  std::clock_t c_end = std::clock();
+  std::chrono::_V2::system_clock::time_point t_end = std::chrono::high_resolution_clock::now();
+  if (m_nPackets != 0) {
+    double time = std::chrono::duration<double, std::milli>(t_end-t_start).count() ;
+    plot2D(m_nPackets, time, "RateVsTime",0.,1000000.,0.,3000.,100,100);
+    plot2D(m_nPackets, time / (double)m_nPackets, "RateVsTimePerPacket",0.,1000000.,0.,0.01,100,100);
+    //info() << " packets = " << m_nPackets << " time = " << time << endmsg;
+    m_nPackets = 0;
+  }
+  /*
+     std::cout << std::fixed << std::setprecision(2) << "CPU time used: "
+     << 1000.0 * (c_end-c_start) / CLOCKS_PER_SEC << " ms\n"
+     << "Wall clock time passed: "
+     << std::chrono::duration<double, std::milli>(t_end-t_start).count()
+     << " ms\n";
+     */
+
+  c_start = c_end;
+  t_start = t_end; 
+
+  // Create containers for hits and triggers.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string ext = std::to_string(i);
+    LHCb::TbHits* hits = new LHCb::TbHits();
+    put(hits, m_hitLocation + ext);
+    m_hits[i] = hits;
+    LHCb::TbTriggers* triggers = new LHCb::TbTriggers();
+    put(triggers, m_triggerLocation + ext);
+    m_triggers[i] = triggers;
+  }
+  bool done = false;
+  bool eof = true;
+  bool eot = false;
+  while (!done) {
+    eof = true;
+    // Update the event boundaries.
+    if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+      debug() << "Event definition: " << m_clock - m_tick 
+        << " to " << m_clock + m_overlapTime
+        << endmsg;
+    }
+    timingSvc()->setEventDefinition(m_clock - m_tick,
+        m_clock + m_overlapTime);
+    for (unsigned int i = 0 ; i < m_nPlanes; ++i) {
+      m_hits[i]->clear();
+      m_triggers[i]->clear();
+    }
+    for (auto f : m_streams) {
+      eof &= f->eos();
+      fill(f, m_hits[f->plane()], m_triggers[f->plane()], eot);
+    } 
+    unsigned int nPlanesWithHits = 0;
+    bool gotTrigger = false;
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (!m_triggers[i]->empty()) {
+        gotTrigger = true;
+        break;
+      }
+      if (!m_hits[i]->empty()) ++nPlanesWithHits;
+    }
+    if (gotTrigger || nPlanesWithHits >= m_nMinPlanesWithHits) {
+      done = true;
+    } else {
+      ++m_nNoiseEvents;
+    }
+    m_clock += m_tick;
+    if (eof) break;
+  }
+  // Sort hits and triggers by time. 
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    std::sort(m_hits[i]->begin(), m_hits[i]->end(),
+        TbFunctors::LessByTime<const LHCb::TbHit*>());
+    std::sort(m_triggers[i]->begin(), m_triggers[i]->end(),
+        TbFunctors::LessByTime<const LHCb::TbTrigger*>());
+    m_nPackets += m_hits[i]->size() ; 
+  }
+  // Increment the event counter.
+  ++m_nEvents;
+  if (m_nEvents % m_printFreq == 0) {
+    info() << format(" %8u events read, %12u hits, %12u triggers", 
+        m_nEvents, m_nHitsRead, m_nTriggersRead) << endmsg; 
+    if (m_monitoring) {
+      info() << "Hits:     ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_hits[i]->size());
+      }
+      info() << endmsg << "Cache:    ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_streams[i]->hitCache().size());
+      }
+      info() << endmsg << "Triggers: ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_triggers[i]->size());
+      }
+      info() << endmsg << "Cache:    ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_streams[i]->trgCache().size());
+      }
+      info() << endmsg;
+    }
+  }
+  bool emptyCache = true;
+  for (const auto& f : m_streams) {
+    if (!f->hitCache().empty() || !f->trgCache().empty()) {
+      emptyCache = false;
+      break;
+    }
+  }
+  // Check if there are any events left to process.
+  if (((m_nData == m_nDataInFiles || eof) && emptyCache) || eot) {
+    // Terminate the application.
+    SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+    if (app) app->stopRun();
+  }
+  if (m_nLostTimers > m_maxLostTimers) {
+    return Error("More than " + std::to_string(m_maxLostTimers) + 
+        " clock packets dropped. Critical problem with global clock");
+  }
+  if (m_nLostPackets > m_maxLostPackets) {
+    return Error("More than " + std::to_string(m_maxLostPackets) +  
+        " packets  dropped. Critical problem with timing");
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Add hits and triggers to the containers
+//=============================================================================
+bool TbEventBuilder::fill(TbRawStream* f, LHCb::TbHits* hits,
+    LHCb::TbTriggers* triggers,
+    bool& eot) {
+  if (!dumpCache(f, hits) && !m_forceCaching) {
+    if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+      debug() << "Event boundary: " << m_clock << endmsg;
+      if (f->hitCache().size() > 0) {
+        debug() << "First hit in cache:" << f->hitCache().front()->time()
+          << endmsg;
+      }
+      if (f->trgCache().size() > 0) {
+        debug() << "First trigger in cache: " << f->trgCache().front()->time()
+          << endmsg;
+      }
+    }
+    dumpCache(f, triggers);
+    return false;
+  }
+  dumpCache(f, triggers);
+  const unsigned int device = f->device();
+  uint64_t currentTime = 0;
+  while (likely(currentTime < m_clock + m_cachelength && !f->eos())) {
+    const uint64_t packet = f->getNext();
+    ++m_nData;
+    const unsigned int header = 0xF & (packet >> 60);
+    if (likely(header == 0xA || header == 0xB)) {
+      // Pixel packets.
+      ++m_nHitsRead;     
+      // Get the pixel adress.
+      const unsigned int pixelAddress = 0xFFFF & (packet >> 44);
+      // Skip masked pixels.
+      if (unlikely(pixelSvc()->isMasked(pixelAddress, device))) continue;
+      LHCb::TbHit* hit = decodeTPX3Hit( packet, pixelAddress, device , f->col() );
+      hit->setCharge(pixelSvc()->charge(hit->ToT(), pixelAddress, device));
+      extendTimeStamp(hit, m_ignoreGlobalClock ? f->m_tpx3Timer : f->timer());
+      pixelSvc()->applyPhaseCorrection(hit);
+      writePacket(hit, f, hits);
+      currentTime = hit->time();
+      
+      //info() << std::dec << (double)prevTime / (double)Tb::second << "   " << (double)currentTime / (double)Tb::second << "    " << f->hClock() << endmsg;
+      syncTPX3( currentTime, f ) ; 
+      if (UNLIKELY(m_monitoring)) {
+        plot(hit->time() / Tb::millisecond, "HitDataRate", 
+            "Rate of hit packets", 0.0, 620000.0, 6200000);
+      }
+    } else if ((header == 0x6 || header == 0x4) &&
+        (( packet >> 56) & 0xF) == 0xF) {
+      // New trigger packets
+      LHCb::TbTrigger* trigger = new LHCb::TbTrigger(packet);
+      extendTimeStamp(trigger, f->timer());
+      trigger->setPlane(f->plane());
+      writePacket(trigger, f, triggers);
+      ++m_nTriggersRead;
+      if (m_monitoring) {
+        plot(trigger->time() / Tb::millisecond, "TriggerDataRate",
+            "Rate of trigger packets", 0.0, 620000.0, 620000);
+      }
+    } else if (header == 0x4 && ! m_ignoreGlobalClock ) {
+      // Timing packets
+      int state = f->addTimingPacket(packet);
+      if (state == 2) 
+      {
+        warning() << "Jump in timing of greater than 6.7s detected."
+          << format("Dropping timing packet: 0x%x", packet) 
+          << endmsg;
+        warning() << "Will attempt to resynchronise using a different SPIDR's"
+          << " global clock" << endmsg;
+        attemptResync( f , packet );
+        if( m_nLostTimers > m_maxLostTimers ) return true;      
+        // If fail to add as a timing packet, data packet unknown
+      }
+      else if (state == 0) {
+        ++m_unknownPackets;
+        if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+          debug() << format("Timing packet with subheader 0x%x, packet = 0x%x",
+              ((packet >> 56) & 0xF), packet) 
+            << endmsg; 
+        }
+      }
+    }   
+    else {
+      // Packet is neither hit, nor a trigger, nor a timing packet.
+      ++m_unknownPackets;
+      if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+        warning() << format("Packet with header 0x%x, packet = 0x%x", 
+            header, packet) << endmsg;
+      }
+    }
+  }
+  std::sort(f->hitCache().begin(), f->hitCache().end(),
+      TbFunctors::LessByTimeBP<const LHCb::TbHit*>());
+  std::sort(f->trgCache().begin(), f->trgCache().end(),
+      TbFunctors::LessByTimeBP<const LHCb::TbTrigger*>());
+
+  if (m_endTime != 0 && currentTime > m_endTime) eot = true;
+  if (!hits->empty() || !triggers->empty() || f->eos()) return true;
+  return false;
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+void TbEventBuilder::syncTPX3(const uint64_t& thisPacketTime, TbRawStream* f) { 
+
+  int timerMsbs = 0x3 & ( f->m_tpx3Timer >> 40 );
+  int thisMsb = 0x3 & ( thisPacketTime >> 40 ); 
+  constexpr uint64_t one = (uint64_t)(1) << 40;
+
+  if( thisMsb == timerMsbs+1 || thisMsb == timerMsbs-3){
+    info() << "Updating clock " << (double)(f->m_tpx3Timer + one)/(double)Tb::second << endmsg; 
+    f->m_tpx3Timer += one;
+  }
+  if( thisMsb > timerMsbs ){
+    info() << thisMsb << "   " << timerMsbs << endmsg; 
+  }
+}
+
+bool TbEventBuilder::attemptResync(TbRawStream* f, const uint64_t& packet) {
+
+  for (unsigned int chip = 0 ; chip != m_nPlanes; ++chip) {
+    int64_t dt = (int64_t)f->timer() - (int64_t)m_streams[chip]->timer();
+    if (std::abs(dt) > m_maxTimeDifference) {
+      f->setLSB(m_streams[chip]->lsb());
+      f->setGlobalClock(m_streams[chip]->timer());
+      const int state = f->addTimingPacket(packet);
+      if (state != 2) {
+        info() << "Resync of device " << chip << " successful!" << endmsg;
+        return true; 
+      }
+    }
+  }
+  warning() << "Resynchronisation of device fails" << endmsg;
+  // Empty the cache.
+  for (auto it = f->hitCache().begin(); it != f->hitCache().end(); ++it) {
+    if (*it) delete *it;
+  }
+  f->hitCache().clear();
+  for (auto it = f->trgCache().begin(); it != f->trgCache().end(); ++it) {
+    if (*it) delete *it;
+  }
+  f->trgCache().clear();
+  m_nLostTimers++;
+  return false; 
+}
+
+StatusCode TbEventBuilder::finalize() {
+
+  for (auto& f : m_streams) {
+    info() << format("Plane %2u: %12u packets in file, %12u hits in cache",
+        f->plane(), f->size(), f->hitCache().size()) << endmsg;
+    for (auto it = f->hitCache().begin(); it != f->hitCache().end(); ++it) {
+      if (*it) delete *it;
+    }
+    for (auto it = f->trgCache().begin(); it != f->trgCache().end(); ++it) {
+      if (*it) delete *it;
+    }
+    f->close();
+  }
+  info() << "Fraction of data read: " << (double)m_nData /
+    (double)m_nDataInFiles << endmsg;
+  info() << "Number of packets lost: " << m_nLostPackets << endmsg;
+  info() << "Unknown packets: " << m_unknownPackets << endmsg;
+  if (m_nNoiseEvents > 0) {
+    info() << "Skipped " << m_nNoiseEvents << " noise events." << endmsg;
+  }
+  // Finalise the base class.
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Dump cached packets into the current event
+//=============================================================================
+template <typename T>
+bool TbEventBuilder::dumpCache(
+    TbRawStream* stream, KeyedContainer<T, Containers::HashMap>* container) {
+
+  // Load the hits/triggers stored in the cache.
+  std::vector<T*>* cache = stream->cache<T*>();
+  auto it = cache->begin();
+  const auto end = cache->end();
+  for (; it != end; ++it) {
+    const auto time = (*it)->time();
+    if (unlikely(time >= m_clock + m_overlapTime)) break;
+    if (unlikely(time < m_clock - m_tick ) ) {
+      // Packet is earlier than the current event.
+      // If this happens, the cache may be too short.
+      warning() << format("Packet 0x%016llX", (*it)->data()) << " is "
+        << " ns before event low edge! Current event definition: "
+        << (m_clock - m_tick) / Tb::SpidrTime << " to "
+        << (m_clock + m_overlapTime) / Tb::SpidrTime << endmsg;
+      ++m_nLostPackets;
+      delete *it;
+      if (m_nLostPackets > m_maxLostPackets) {
+        error() << "Large number of packets lost -> critical failure" << endmsg;
+        return false;
+      }
+      continue;
+    }
+    (*it)->setHtime(timingSvc()->globalToLocal(time));
+    // Move packet to the TES.
+    container->insert(*it);
+  }
+  cache->erase(cache->begin(), it);
+  if (container->empty() && !cache->empty()) return false;
+  return true;
+}
+
+//=============================================================================
+// Extend the timestamp of a packet
+//=============================================================================
+template <typename T>
+void TbEventBuilder::extendTimeStamp(T* packet, uint64_t global_time) {
+
+  const uint64_t packet_time = packet->time();
+  const int diff = (0x3 & (global_time >> 40)) - (0x3 & (packet_time >> 40));
+  constexpr uint64_t one = (uint64_t)(1) << 40;
+  // Calculate the difference between the bits that should match between
+  // the spidr time and the global time, if they do not match, increment or
+  // decrement the global time so that they match and add the 18 m.s.f.
+  // of the global time to the packet time
+  if (diff == 1 || diff == -3) {
+    global_time = global_time - one;
+  } else if (diff == -1 || diff == 3) {
+    global_time = global_time + one;
+  }
+  packet->setTime((0x3FFFFFFFFFF & packet_time) +
+      (global_time & 0xFFFFC0000000000));
+}
+
+LHCb::TbHit* TbEventBuilder::decodeTPX3Hit( const uint64_t& packet,const unsigned int& pixelAddress, const unsigned int& device , const unsigned int& fCol ){
+
+  LHCb::TbHit* hit = new LHCb::TbHit();
+  hit->setDevice(device);
+  hit->setData(packet);
+  hit->setPixelAddress(pixelAddress);
+  // Decode the pixel address, first get the double column. 
+  const unsigned int dcol = (0xFE00 & pixelAddress) >> 8;
+  // Get the super pixel address.
+  const unsigned int spix = (0x01F8 & pixelAddress) >> 1;
+  // Get the address of the pixel within the super pixel. 
+  const unsigned int pix = (0x0007 & pixelAddress);
+  // Calculate and store the row and column numbers.
+  const unsigned int col = dcol + pix / 4;
+  const unsigned int row = spix + (pix & 0x3);
+  hit->setCol(col);
+  hit->setRow(row);
+  hit->setScol(col + fCol);
+  const unsigned int data = (packet & 0x00000FFFFFFF0000) >> 16;
+  // Extract and store the ToT and the corresponding charge.
+  const unsigned int tot = (data & 0x00003FF0) >> 4;
+  hit->setToT(tot);
+  //  hit->setCharge(pixelSvc()->charge(tot, pixelAddress, device));
+  // Get the time stamps.
+  const uint64_t spidrTime = packet & 0x000000000000FFFF;
+  const uint64_t ftoa = data & 0x0000000F;
+  const uint64_t toa = (data & 0x0FFFC000) >> 14;
+  // Calculate the global timestamp.
+  const uint64_t fulltime = ((spidrTime << 18) + (toa << 4) + (15 - ftoa)) << 8;
+  hit->setTime(fulltime);
+
+  return hit;
+}
+
diff --git a/TbIO/src/.svn/text-base/TbEventBuilder.h.svn-base b/TbIO/src/.svn/text-base/TbEventBuilder.h.svn-base
new file mode 100644
index 0000000..7860532
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbEventBuilder.h.svn-base
@@ -0,0 +1,162 @@
+#ifndef TB_EVENTBUILDER_H
+#define TB_EVENTBUILDER_H 1
+
+// Boost
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbRawStream.h"
+#include "TbRawFile.h"
+#include "TbHeaderDecoder.h"
+#include <ctime>
+#include <chrono>
+/** @class TbEventBuilder TbEventBuilder.h
+ *
+ *  Algorithm to populate TES with time ordered gaudi events with data read in
+ *  in the SPIDR data format
+ *
+ *  @author Tim Evans (timothy.david.evans@cern.ch)
+ *  @date   2014-04-01
+ */
+
+class TbEventBuilder : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbEventBuilder(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbEventBuilder();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm termination
+ 
+ private:
+  /// Max. time difference for resynchronisation
+  static const int64_t m_maxTimeDifference;  
+  std::clock_t c_start;
+  std::chrono::_V2::system_clock::time_point t_start; 
+  /// Input data files
+  std::vector<std::string> m_input;
+  /// TES location of output hits
+  std::string m_hitLocation;
+  /// TES location of output triggers
+  std::string m_triggerLocation;
+
+
+  /// The length of the time window used by the event definition
+  uint64_t m_tick;
+  /// The length of time looking in the the next event
+  uint64_t m_cachelength;
+  /// The length of time by which event definitions 'overlap', 
+  /// to be sorted out by tracking
+  uint64_t m_overlapTime;
+
+  /// Time at which to start reading (in trigger FToA times)
+  uint64_t m_startTime;
+  /// Time at which to stop reading (specified in ms, converted later to FToA)
+  uint64_t m_endTime;
+
+  /// Min. number of non-empty planes required to make an event
+  unsigned int m_nMinPlanesWithHits;
+
+  /// Frequency to print event count.
+  unsigned int m_printFreq;
+  /// The total header size. If set to 0, is read from header.
+  unsigned int m_headerSize;
+  /// Flag to dump header or not.
+  bool m_printHeader;
+  /// Flag to activate detailed print-out and histograms.
+  bool m_monitoring;
+  /// Flag to activate pixel configuration histograms
+  bool m_equal;
+  /// Flag to ignore the global clock packets
+  bool m_ignoreGlobalClock;
+  /// The end of the time window used by the event definition
+  uint64_t m_clock;
+
+  /// Number of processed events
+  unsigned int m_nEvents = 0;
+  /// Number of skipped noise events
+  unsigned int m_nNoiseEvents = 0;
+  /// Number of created hits
+  uint64_t m_nData = 0;
+  /// Number of read hit packets
+  uint64_t m_nHitsRead = 0;
+  /// Number of read trigger packets
+  unsigned int m_nTriggersRead = 0;
+  /// Number of unknown packets  
+  unsigned int m_unknownPackets = 0;
+  /// Number of out-of-time packets
+  unsigned int m_nLostPackets = 0;
+  unsigned int m_nLostTimers = 0;
+  /// Maximum number of lost packets / clock packets
+  unsigned int m_maxLostPackets;
+  unsigned int m_maxLostTimers;
+  /// Another eof checksum
+  uint64_t m_nDataInFiles = 0;
+  /// Number of packets per event
+  unsigned int m_nPackets = 0;
+
+  /// Forces the cache to update every cycle, useful 
+  /// for runs where a bad packet has confused the caching
+  bool m_forceCaching;
+  /// TbRawStreams for each plane
+  std::vector<TbRawStream*> m_streams;
+  /// Triggers in each plane
+  std::vector<LHCb::TbTriggers*> m_triggers;
+  /// Hits in each plane
+  std::vector<LHCb::TbHits*> m_hits;
+
+  /// Header decoder tool
+  TbHeaderDecoder* m_headerDecoder = nullptr;
+
+  bool fill(TbRawStream* f, LHCb::TbHits* hits, LHCb::TbTriggers* triggers, bool& eot);
+
+  /// Templated cache dump for triggers and hits (extendible to other
+  /// data packets with a time field and a htime field
+  template <typename T>
+  bool dumpCache(TbRawStream* stream,
+                 KeyedContainer<T, Containers::HashMap>* container);
+ 
+  /// Extend the timestamp of a packet to include the global time
+  template <typename T>
+  void extendTimeStamp(T* packet, uint64_t global_time);
+
+  /// Write a data packet to either a cache or the TES, depending on
+  /// whether it is contained within the current event definition
+  template <typename T>
+  void writePacket(T* packet, TbRawStream* stream,
+                   KeyedContainer<T, Containers::HashMap>* container) {
+    const uint64_t time = packet->time();
+    if (time < m_clock + m_overlapTime && time >= m_clock - m_tick) {
+      // Timestamp is inside the current event. Add the packet to the TES.
+      packet->setHtime(timingSvc()->globalToLocal(time));
+      container->insert(packet);
+    } else {
+      stream->insert(packet);
+    }
+  }
+  LHCb::TbHit* decodeTPX3Hit(const uint64_t& packet, 
+                             const unsigned int& pixelAddress, 
+                             const unsigned int& device, 
+                             const unsigned int& fCol); 
+  void syncTPX3(const uint64_t& thisPacketTime, TbRawStream* f);  
+  bool attemptResync(TbRawStream* f, const uint64_t& packet); 
+  /// Functor for sorting files by split index
+  class lessBySplitIndex {
+   public:
+    bool operator()(const TbRawFile* a, const TbRawFile* b) const {
+      return a->splitIndex() < b->splitIndex();
+    }
+  };
+
+};
+
+#endif
diff --git a/TbIO/src/.svn/text-base/TbHeaderDecoder.cpp.svn-base b/TbIO/src/.svn/text-base/TbHeaderDecoder.cpp.svn-base
new file mode 100644
index 0000000..a7fdcee
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbHeaderDecoder.cpp.svn-base
@@ -0,0 +1,209 @@
+// Boost
+#include "boost/format.hpp"
+
+// Local
+#include "TbHeaderDecoder.h"
+
+DECLARE_TOOL_FACTORY(TbHeaderDecoder)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbHeaderDecoder::TbHeaderDecoder(const std::string& type,
+                                 const std::string& name,
+                                 const IInterface* parent)
+    : GaudiTool(type, name, parent), 
+      m_print(true), m_geomSvc(nullptr), m_pixelSvc(nullptr) {
+
+  declareInterface<TbHeaderDecoder>(this);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbHeaderDecoder::~TbHeaderDecoder() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbHeaderDecoder::initialize() {
+
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Read the first fields of the Spidr header from a given file.
+//=============================================================================
+bool TbHeaderDecoder::readCommon(const char* data, unsigned int& size,
+                                 unsigned int& fmt) {
+
+  struct CommonHeader {
+    uint32_t headerId;
+    uint32_t headerSizeTotal;
+    uint32_t headerSize;
+    uint32_t format;
+  };
+  CommonHeader* hdr = (CommonHeader*)data;
+  size = hdr->headerSizeTotal;
+  if (size > 66304) size = 66304;
+  fmt = hdr->format;
+  return true;
+}
+
+//=============================================================================
+// Read the Spidr header from a given file.
+//=============================================================================
+bool TbHeaderDecoder::read(const char* data, const unsigned int& fmt,
+                           std::string& deviceId) {
+
+  if (fmt == 0x30 || fmt == 0x1) {
+    return readV1(data, deviceId);
+  }
+  error() << format("Unknown format (0x%x)", fmt) << endmsg;
+  return false;
+}
+
+
+//=============================================================================
+// Read version 1 of the Spidr header.
+//=============================================================================
+bool TbHeaderDecoder::readV1(const char* data, std::string& deviceId) {
+
+  struct Tpx3Header {
+    uint32_t headerId;
+    uint32_t headerSizeTotal;
+    uint32_t headerSize;
+    uint32_t format;
+    uint32_t deviceId;
+    uint32_t genConfig;
+    uint32_t outblockConfig;
+    uint32_t pllConfig;
+    uint32_t testPulseConfig;
+    uint32_t slvsConfig;
+    uint32_t pwrPulseConfig;
+    uint32_t dac[32];
+    uint8_t ctpr[256 / 8];
+    uint32_t unused[64 - 11 - 32 - (256 / 8) / 4];
+  };
+
+  struct SpidrTpx3Header {
+    uint32_t headerId;
+    uint32_t headerSizeTotal;
+    uint32_t headerSize;
+    uint32_t format;
+    uint32_t spidrId;
+    uint32_t libVersion;
+    uint32_t softwVersion;
+    uint32_t firmwVersion;
+    uint32_t ipAddress;
+    uint32_t ipPort;
+    uint32_t yyyyMmDd;
+    uint32_t hhMmSsMs;
+    uint32_t runNr;
+    uint32_t seqNr;
+    uint32_t spidrConfig;  // Trigger mode, decoder on/off
+    uint32_t spidrFilter;
+    uint32_t spidrBiasVoltage;
+    // Spare
+    uint32_t unused[128 - 17 - 128 / 4];
+    // Description string
+    char descr[128];
+    // Device header
+    Tpx3Header devHeader;
+  };
+
+  SpidrTpx3Header* hdr = (SpidrTpx3Header*)data;
+  Tpx3Header devHdr = hdr->devHeader;
+  // Get the chip id.
+  const int devid0 = (hdr->devHeader.deviceId >> 8) & 0xFFF;
+  const int devid1 = (hdr->devHeader.deviceId >> 4) & 0xF;
+  const int devid2 = (hdr->devHeader.deviceId >> 0) & 0xF;
+  const char devidchar = (char)(devid2 + 64);
+  deviceId = str(boost::format("W%04d_%d%02d") % devid0 % devidchar % devid1);
+
+  // Transfer the header information to the pixel configuration service.
+  const unsigned int deviceIndex = geomSvc()->deviceIndex(deviceId);
+  if (deviceIndex == 999) {
+    error() << deviceId << " is not listed in the alignment file." << endmsg;
+    return false;
+  } 
+  pixelSvc()->setPhase(deviceIndex, devHdr.pllConfig);
+  if (devHdr.headerSizeTotal - devHdr.headerSize == 65536) {
+    const char* trimDac = data + (hdr->headerSize + devHdr.headerSize);
+    pixelSvc()->setTrim(deviceIndex, trimDac);
+  }
+  if (!m_print) return true;
+
+  boost::format fmts(" %|-30.30s|%|32t| %s ");
+  boost::format fmtx(" %|-30.30s|%|32t| 0x%x ");
+  boost::format fmt8x(" %|-30.30s|%|32t| 0x%08x ");
+  boost::format fmtd(" %|-30.30s|%|32t| %d ");
+  info() << std::string(70, '-') << endmsg;
+  info() << "                        File header " << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "ID" % hdr->headerId << endmsg;
+  info() << fmtd % "Total size" % hdr->headerSizeTotal << endmsg;
+  info() << fmtd % "Size" % hdr->headerSize << endmsg;
+  info() << fmt8x % "Format" % hdr->format << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "SPIDR ID" % hdr->spidrId << endmsg;
+  info() << fmtx % "Library version" % hdr->libVersion << endmsg;
+  info() << fmtx % "Software version" % hdr->softwVersion << endmsg;
+  info() << fmtx % "Firmware version" % hdr->firmwVersion << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  const int ip0 = (hdr->ipAddress >> 24) & 0xFF;
+  const int ip1 = (hdr->ipAddress >> 16) & 0xFF;
+  const int ip2 = (hdr->ipAddress >> 8) & 0xFF;
+  const int ip3 = (hdr->ipAddress >> 0) & 0xFF;
+  const std::string ip = std::to_string(ip0) + "." + std::to_string(ip1) + "." +
+                         std::to_string(ip2) + "." + std::to_string(ip3);
+  info() << fmts % "IP address" % ip << endmsg;
+  info() << fmtd % "IP port" % hdr->ipPort << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  const int date0 = (hdr->yyyyMmDd >> 16) & 0xFFFF;
+  const int date1 = (hdr->yyyyMmDd >> 8) & 0xFF;
+  const int date2 = (hdr->yyyyMmDd >> 0) & 0xFF;
+  const int time0 = (hdr->hhMmSsMs >> 24) & 0xFF;
+  const int time1 = (hdr->hhMmSsMs >> 16) & 0xFF;
+  const int time2 = (hdr->hhMmSsMs >> 8) & 0xFF;
+  const int time3 = (hdr->hhMmSsMs >> 0) & 0xFF;
+  info() << boost::format(" %|-30.30s|%|32t| %04x-%02x-%02x") % "Date" % date0 %
+                date1 % date2 << endmsg;
+  info() << boost::format(" %|-30.30s|%|32t| %02x:%02x:%02x.%02x") % "Time" %
+                time0 % time1 % time2 % time3 << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtd % "Run number" % hdr->runNr << endmsg;
+  info() << fmtd % "Sequence number" % hdr->seqNr << endmsg;
+  info() << fmts % "Run info" % hdr->descr << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmt8x % "Spidr configuration" % hdr->spidrConfig << endmsg;
+  info() << fmt8x % "Data filter" % hdr->spidrFilter << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << "                       Device header" << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "Type ID" % devHdr.headerId << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "Device ID" % devHdr.deviceId << endmsg;
+  info() << fmts % "" % deviceId << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmt8x % "General config" % devHdr.genConfig << endmsg;
+  info() << fmt8x % "Output block config" % devHdr.outblockConfig << endmsg;
+  info() << fmt8x % "PLL config" % devHdr.pllConfig << endmsg;
+  info() << fmt8x % "Testpulse config" % devHdr.testPulseConfig << endmsg;
+  info() << fmt8x % "SLVS config" % devHdr.slvsConfig << endmsg;
+  info() << fmt8x % "Power pulsing config" % devHdr.pwrPulseConfig << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  boost::format fmt(" %|-30.30s|%|32t| %03d %03d %03d %03d");
+  std::string title = "DAC values";
+  for (unsigned int i = 0; i < 5; ++i) {
+    const unsigned int offset = 4 * i;
+    info() << fmt % title % devHdr.dac[offset] % devHdr.dac[offset + 1] %
+                  devHdr.dac[offset + 2] % devHdr.dac[offset + 3] << endmsg;
+    title = "";
+  }
+  info() << std::string(70, '-') << endmsg; 
+  return true;
+}
diff --git a/TbIO/src/.svn/text-base/TbHeaderDecoder.h.svn-base b/TbIO/src/.svn/text-base/TbHeaderDecoder.h.svn-base
new file mode 100644
index 0000000..3c37160
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbHeaderDecoder.h.svn-base
@@ -0,0 +1,59 @@
+#ifndef TBHEADERDECODER_H
+#define TBHEADERDECODER_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/ITbPixelSvc.h"
+
+/** @class TbHeaderDecoder TbHeaderDecoder.h
+ *
+ * Tool to read SPIDR header from raw data file.
+ *
+ */
+
+static const InterfaceID IID_TbHeaderDecoder("TbHeaderDecoder", 1, 0);
+
+class TbHeaderDecoder : public GaudiTool {
+ public:
+  // Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_TbHeaderDecoder; }
+
+  /// Constructor
+  TbHeaderDecoder(const std::string& type, const std::string& name,
+                  const IInterface* parent);
+  /// Destructor
+  virtual ~TbHeaderDecoder();
+
+  virtual StatusCode initialize();
+
+  void print(const bool& flag) { m_print = flag; }
+  bool read(const char* data, const unsigned int& fmt, 
+            std::string& deviceId);
+  bool readCommon(const char* data, unsigned int& size, unsigned int& fmt);
+
+ private:
+  /// Flag to activate print-out or not.
+  bool m_print;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+
+  /// Pointer to pixel service
+  mutable ITbPixelSvc* m_pixelSvc;
+  /// Access pixel service on-demand
+  ITbPixelSvc* pixelSvc() const {
+    if (!m_pixelSvc) m_pixelSvc = svc<ITbPixelSvc>("TbPixelSvc", true);
+    return m_pixelSvc;
+  }
+  /// Read version 1
+  bool readV1(const char* data, std::string& deviceId);
+};
+
+#endif
diff --git a/TbIO/src/.svn/text-base/TbPacketRecycler.cpp.svn-base b/TbIO/src/.svn/text-base/TbPacketRecycler.cpp.svn-base
new file mode 100644
index 0000000..13bc92c
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbPacketRecycler.cpp.svn-base
@@ -0,0 +1,105 @@
+#include "TbPacketRecycler.h"
+#include "Event/TbTrack.h"
+
+DECLARE_ALGORITHM_FACTORY(TbPacketRecycler)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbPacketRecycler::TbPacketRecycler(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("TriggerLocation",
+                  m_trgLocation = LHCb::TbTriggerLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusLocation = LHCb::TbClusterLocation::Default);
+}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbPacketRecycler::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  IToolSvc* toolsvc = nullptr;
+  sc = service("ToolSvc", toolsvc);
+  if (!sc.isSuccess()) {
+    return Error("Unable to get a handle to the tool service", sc);
+  }
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    TbRawStream* foo = nullptr;
+    sc = toolSvc()->retrieveTool("TbRawStream/" + std::to_string(i), foo);
+    if (!sc.isSuccess()) {
+      return Error("Unable to retrieve TbRawStream for plane " + 
+                   std::to_string(i), sc);
+    }
+    m_streams.push_back(foo);
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbPacketRecycler::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string hitLocation = m_hitLocation + std::to_string(i);
+    const std::string trgLocation = m_trgLocation + std::to_string(i);
+    const std::string clusLocation = m_clusLocation + std::to_string(i);
+
+    LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(hitLocation);
+    LHCb::TbTriggers* trgs = getIfExists<LHCb::TbTriggers>(trgLocation);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusLocation);
+
+    removeClusters(clusters);
+    recycle(hits, m_streams[i]);
+    recycle(trgs, m_streams[i]);
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Copy unused hits and triggers to the cache. 
+//=============================================================================
+template <typename TYPE>
+void TbPacketRecycler::recycle(
+    KeyedContainer<TYPE, Containers::HashMap>* container, TbRawStream* s) {
+  if (!container) return;
+  std::vector<TYPE*> tmp_cache;
+  tmp_cache.clear();
+  typename KeyedContainer<TYPE, Containers::HashMap>::reverse_iterator packet;
+  for (packet = container->rbegin(); packet != container->rend(); ++packet) {
+    // Break when outside the overlap time window.
+    if (timingSvc()->beforeOverlap((*packet)->time())){
+      break;
+    }
+    // If unused, add the hit/trigger to the temporary cache.
+    if (!(*packet)->associated()) {
+      tmp_cache.push_back(new TYPE(*packet));
+      container->remove(*packet);
+    }
+  }
+  std::reverse(tmp_cache.begin(), tmp_cache.end());
+  s->cache<TYPE*>()->insert(s->cache<TYPE*>()->begin(), tmp_cache.begin(),
+                            tmp_cache.end());
+}
+
+//=============================================================================
+// Remove non-associated clusters from a container
+//=============================================================================
+void TbPacketRecycler::removeClusters(LHCb::TbClusters* clusters) {
+  if (!clusters) return;
+  LHCb::TbClusters::reverse_iterator it;
+  for (it = clusters->rbegin(); it != clusters->rend(); ++it) {
+    // Break when outside the overlap time window.
+    if (timingSvc()->beforeOverlap((*it)->time())) break;
+    // If unused, remove the cluster from the container.
+    if (!(*it)->associated()) clusters->remove(*it); 
+  }
+}
diff --git a/TbIO/src/.svn/text-base/TbPacketRecycler.h.svn-base b/TbIO/src/.svn/text-base/TbPacketRecycler.h.svn-base
new file mode 100644
index 0000000..105e79c
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbPacketRecycler.h.svn-base
@@ -0,0 +1,54 @@
+// Gaudi
+#include "GaudiKernel/IToolSvc.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbRawStream.h"
+
+/** @class TbPacketRecycler TbPacketRecycler.h
+ *
+ *  Algorithm to move unprocessed data in the overlap into the next event
+ *  designed to prevent clusters / tracks being cut between events
+ *
+ *  @author Tim Evans (timothy.david.evans@cern.ch)
+ *  @date   2014-04-01
+ */
+
+class TbPacketRecycler : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbPacketRecycler(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbPacketRecycler() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<TbRawStream*> m_streams;
+  std::string m_hitLocation;
+  std::string m_trgLocation;
+  std::string m_clusLocation;
+  template <typename TYPE>
+  void recycle(KeyedContainer<TYPE, Containers::HashMap>* container,
+               TbRawStream* s);
+  void removeClusters(LHCb::TbClusters* clusters);
+  template <typename TYPE>
+  void addToCache(std::vector<TYPE*> cache, TYPE* packet) {
+    cache.push_back(packet);
+  }
+};
+
+template <>
+void TbPacketRecycler::addToCache(std::vector<LHCb::TbHit*> cache,
+                                  LHCb::TbHit* packet) {
+  cache.push_back(packet);
+}
diff --git a/TbIO/src/.svn/text-base/TbRawFile.cpp.svn-base b/TbIO/src/.svn/text-base/TbRawFile.cpp.svn-base
new file mode 100644
index 0000000..7199636
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbRawFile.cpp.svn-base
@@ -0,0 +1,51 @@
+// ROOT
+#include "TFile.h"
+
+// Local
+#include "TbRawFile.h"
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbRawFile::TbRawFile(const std::string& filename, 
+                     TbHeaderDecoder* headerDecoder) 
+    : TbBufferedFile(filename, 0) {
+
+  if (!is_open()) {
+    m_good = false;
+    return;
+  }
+  const size_t pos = m_filename.find(".dat");
+  const size_t dash = m_filename.find_last_of("-");
+
+  if (pos == std::string::npos) {
+    m_good = false;
+    return;
+  }
+
+  if (!(pos - dash > 1)) {
+    m_good = false;
+    return;
+  }
+  m_split_index = atoi(m_filename.substr(dash + 1, pos - dash - 1).c_str());
+  if (m_split_index == 1) initialise();
+  m_good = true;
+
+  char header[16];
+  m_file->ReadBuffer(header, 0, 16);
+  unsigned int format = 0;
+  headerDecoder->readCommon(header, m_headerSize, format);
+
+  char* devHeader = new char[m_headerSize];
+  m_file->ReadBuffer(devHeader, 0, m_headerSize);
+
+  if (!headerDecoder->read(devHeader, format, m_id)) {
+    m_good = false;
+    return;
+  }
+  m_file->Seek(m_headerSize);
+  m_size = m_file->GetSize();
+  m_nPackets = (m_size - m_headerSize) / 8;
+  m_bytesRead = m_headerSize;
+  m_good = true;
+}
diff --git a/TbIO/src/.svn/text-base/TbRawFile.h.svn-base b/TbIO/src/.svn/text-base/TbRawFile.h.svn-base
new file mode 100644
index 0000000..463a4bb
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbRawFile.h.svn-base
@@ -0,0 +1,48 @@
+#pragma once
+
+// Tb/TbKernel
+#include "TbKernel/TbBufferedFile.h"
+
+// Local
+#include "TbHeaderDecoder.h"
+
+/** @class TbRawFile TbRawFile.h
+ *
+ * Interface for raw files in SPIDR format via TbBufferedFile (ROOT I/O)
+ *
+ */
+
+class TbRawFile : public TbBufferedFile<1000000, uint64_t> {
+ public:
+  /// Constructor
+  TbRawFile(const std::string& filename, TbHeaderDecoder* headerDecoder);
+  /// Destructor
+  virtual ~TbRawFile() {}
+
+  /// Return the file index
+  unsigned int splitIndex() const { return m_split_index; }
+  uint64_t size() const { return m_size; }
+  /// Return the chip identifier
+  std::string id() const { return m_id; }
+  /// Return whether the file has been opened successfully
+  bool good() const { return m_good; }
+  /// Return the number of data packets in the file
+  uint64_t nPackets() const { return m_nPackets; }
+
+  /// Set the offset in size of packets
+  virtual void setOffset(const uint64_t offset) {
+    TbBufferedFile::setOffset(offset * 8 + m_headerSize);
+  }
+
+ protected:
+  uint64_t m_size;
+  /// Number of data packets in the file
+  uint64_t m_nPackets;
+  /// Index by which large files are divided
+  unsigned int m_split_index;
+  /// Header size in bytes
+  unsigned int m_headerSize;
+  /// Chip identifier
+  std::string m_id;
+  bool m_good;
+};
diff --git a/TbIO/src/.svn/text-base/TbRawStream.cpp.svn-base b/TbIO/src/.svn/text-base/TbRawStream.cpp.svn-base
new file mode 100644
index 0000000..65051bb
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbRawStream.cpp.svn-base
@@ -0,0 +1,184 @@
+#include "TbRawStream.h"
+#include <cmath>
+
+DECLARE_TOOL_FACTORY(TbRawStream)
+
+const int64_t TbRawStream::m_tenSeconds = 256 * std::pow(10, 11);
+const int64_t TbRawStream::m_maxTimeDifference = pow(2, 40);
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbRawStream::TbRawStream(const std::string& type, const std::string& name,
+                         const IInterface* parent)
+    : GaudiTool(type, name, parent),
+      m_hitCache(), m_trgCache() {
+  declareInterface<TbRawStream>(this);
+}
+
+bool TbRawStream::setMSB(uint64_t msb) {
+  uint64_t currentTime = (m_lsb + (msb << 32)) << 12;
+  const int64_t timeDifference = currentTime - m_timer;
+  if (timeDifference > m_tenSeconds) {
+    // Detected jump of greater than 10s
+    // warning() << "Jump detected - this is okay, probably means "
+    // << "a bit has been updated between LSB and MSB" << endmsg;
+    if (msb > 0) msb -= 1;
+    currentTime = (m_lsb + (msb << 32)) << 12;
+  }
+  if (timeDifference > m_maxTimeDifference ||
+      timeDifference < -m_maxTimeDifference) {
+    // warning << "Current global time = " <<
+    // m_timer*25*pow(10,-6)/4096 << " clock is trying to update to " <<
+    // currentTime*25*pow(10,-6)/4096 << endmsg;
+    return false;
+  }
+  m_timer = currentTime;
+  // info() <<  "Current global time: " <<
+  // currentTime*25/(4096*pow(10,9)) << " s" <<endmsg;
+  return true;
+}
+
+void TbRawStream::fastForward(const uint64_t timeToSkipTo) {
+  // Go one second before we need to
+  const double coarse_time = timeToSkipTo * 25 / (4096 * pow(10, 9)); 
+  coarseFastForward(coarse_time);
+  fineFastForward(timeToSkipTo);
+}
+
+//=============================================================================
+// Binary search of the stream to find a particular time
+//=============================================================================
+void TbRawStream::coarseFastForward(const double timeToSkipTo) {
+
+  info() << "Skipping forward to time = " << timeToSkipTo << endmsg;
+  // Need to work out which file to read first
+  if (m_files.size() > 1) {
+    for (auto it = m_files.begin(), end = m_files.end(); it != end; ++it) {
+      m_currentFile = it;
+      (*it)->initialise();
+      const double timeInSeconds = getCurrentTime() * 25 / pow(10, 9);
+      if (timeInSeconds > timeToSkipTo) {
+        (*it)->reset();
+        m_currentFile--;
+        break;
+      }
+      (*it)->reset();
+    }
+  }
+
+  (*m_currentFile)->initialise();
+  uint64_t dt = (*m_currentFile)->nPackets() / 2;
+  uint64_t pos = dt;
+  uint64_t timer = 0;
+  double timeInSeconds = 0;
+  while (!eos() && fabs(timeToSkipTo - timeInSeconds) > 0.6 && dt > 1) {
+    // Scroll to the new position
+    (*m_currentFile)->setOffset(pos);  
+    dt /= 2;
+    timer = getCurrentTime();
+    timeInSeconds = timer * 25 / pow(10, 9);
+    pos = timeToSkipTo > timeInSeconds ? (pos + dt) : (pos - dt);
+  }
+  if (dt <= 1) info() << "Binary search has failed!" << endmsg;
+  m_timer = timer << 12;
+}
+
+void TbRawStream::fineFastForward(const uint64_t timeToSkipTo) {
+  uint64_t currentTime(0);
+  while (!eos() && currentTime < timeToSkipTo) {
+    const uint64_t data_packet = getNext();
+    const unsigned int header = data_packet >> 60;
+    if (header == 0xA || header == 0xB) {
+      uint64_t global_time = timer();
+      uint64_t packet_time = (0xFFFF & data_packet) << 26;
+      const int diff =
+          (0x3 & (global_time >> 40)) - (0x3 & (packet_time >> 40));
+      constexpr uint64_t one = (uint64_t)(1) << 40;
+      if (diff == 1 || diff == -3)
+        global_time = global_time - one;
+      else if (diff == -1 || diff == 3)
+        global_time = global_time + one;
+    } else if (header == 0x4) {
+      addTimingPacket(data_packet);
+      currentTime = m_timer;
+    }
+  }
+}
+
+uint64_t TbRawStream::getCurrentTime() {
+  m_lsb = 0;
+  uint64_t currentTime = 0;
+  bool gotTime = false;
+  while (!eos() && !gotTime) {
+    // measures the current time in the stream//
+    const uint64_t data_packet = getNext();
+    const unsigned int header = data_packet >> 60;
+    if (header == 0x4 && (0xF & (data_packet >> 54)) != 0xF) {
+      const unsigned int subheader = 0xF & (data_packet >> 56);
+      if (subheader == 0x4) {
+        m_lsb = 0xFFFFFFFF & (data_packet >> 16);
+      } else if (subheader == 0x5 && m_lsb != 0) {
+        const uint64_t msb = 0xFFFFFFFF & (data_packet >> 16);
+        currentTime = (m_lsb + (msb << 32));
+        gotTime = true;
+      }
+    }
+  }
+  return currentTime;
+}
+
+int TbRawStream::addTimingPacket(const uint64_t data_packet) {
+  const unsigned int subheader = 0xF & (data_packet >> 56);
+  int state = 1;
+  if (subheader == 0x5) {
+    // info() << "Current msb = Setting msb of clock: 0x" <<
+    // std::hex << data_packet <<  std::dec <<endmsg;
+    if (setMSB(0xFFFFFFFF & (data_packet >> 16)) == 0) state = 2;
+  } else if (subheader == 0x4) {
+    // info() << "Setting lsb of stream: 0x" << std::hex <<
+    // data_packet << ", current = " << m_lsb << std::dec << endmsg;
+    setLSB(0xFFFFFFFF & (data_packet >> 16));
+  } else {
+    state = 0;
+  }
+  return state;
+}
+
+void TbRawStream::prepare() {
+  m_currentFile = m_files.begin();
+  (*m_currentFile)->initialise();
+  m_size = 0;
+  for (const auto& raw_file : m_files) m_size = m_size + raw_file->nPackets();
+  //info() << "Stream = " << m_size << " 8-byte packets" << endmsg; 
+  unsigned int header(0);
+  // Find the first pixel hit
+  unsigned int prep_packets(0);
+  while (!eos() && !(header == 0xA || header == 0xB)) {
+    uint64_t packet = getNext();
+    // info() << std::hex << packet << endmsg;
+    header = 0xF & (packet >> 60);
+    ++prep_packets;
+  }
+  // for (unsigned int i = 0; i < 100; ++i) {
+  //   info() << std::hex << "0x" << getNext() << std::dec << endmsg;
+  // }
+  // info() << "Number of prep packets skipped = " << prep_packets << endmsg;
+  m_size = m_size - prep_packets + 1;
+  getPrevious();
+}
+
+template <>
+std::vector<LHCb::TbHit*>* TbRawStream::cache() {
+  return &m_hitCache;
+}
+template <>
+std::vector<LHCb::TbTrigger*>* TbRawStream::cache() {
+  return &m_trgCache;
+}
+
+void TbRawStream::insert(LHCb::TbHit* packet) { m_hitCache.push_back(packet); }
+
+void TbRawStream::insert(LHCb::TbTrigger* packet) {
+  m_trgCache.push_back(packet);
+}
diff --git a/TbIO/src/.svn/text-base/TbRawStream.h.svn-base b/TbIO/src/.svn/text-base/TbRawStream.h.svn-base
new file mode 100644
index 0000000..242c899
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbRawStream.h.svn-base
@@ -0,0 +1,94 @@
+#pragma once
+
+#include "TbRawFile.h"
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+#include "TbKernel/TbFunctors.h"
+#include "GaudiAlg/GaudiTool.h"
+#include "TbKernel/TbConstants.h"
+
+static const InterfaceID IID_TbRawStream("TbRawStream", 1, 0);
+
+class TbRawStream : public GaudiTool {
+
+ public:
+  /// Constructor
+  TbRawStream(const std::string& type, const std::string& name,
+              const IInterface* parent);
+
+  static const InterfaceID& interfaceID() { return IID_TbRawStream; }
+
+  uint64_t timer() const { return m_timer; }
+  unsigned int lsb() const { return m_lsb; }
+  // this is for explicitly setting the clock, if device sync fails
+  void setGlobalClock(const uint64_t timer) { m_timer = timer; }
+  unsigned int size() const { return m_size; }
+  void setLSB(const unsigned int lsb) { m_lsb = lsb; }
+  bool setMSB(uint64_t msb);
+
+  std::vector<LHCb::TbHit*>& hitCache() { return m_hitCache; }
+  std::vector<LHCb::TbTrigger*>& trgCache() { return m_trgCache; }
+  void addFile(TbRawFile* file) { m_files.push_back(file); }
+  void close() {
+    for (auto& raw_file : m_files) {
+      if (raw_file->is_open()) raw_file->close();
+    }
+  }
+
+  uint64_t getNext() { return (*m_currentFile)->getNext(); }
+  uint64_t getPrevious() { return (*m_currentFile)->getPrevious(); }
+
+  bool eos() {
+    if (unlikely( m_currentFile == m_files.end() ) ) return true;
+    if (unlikely((*m_currentFile)->eof() == true)) {
+      (*m_currentFile)->close();
+      m_currentFile++;
+      if (m_currentFile != m_files.end()) (*m_currentFile)->initialise();
+    }
+    return unlikely(m_currentFile == m_files.end());
+  }
+  double hClock() const {
+    return (double)m_timer / (double) Tb::second; 
+  }
+  void prepare();
+
+  // these functions collectively control fast forwarding to some point in the
+  // stream
+  void fastForward(const uint64_t timeToSkipTo);
+  void coarseFastForward(const double timeToSkipTo);
+  void fineFastForward(const uint64_t timeToSkipTo);
+  uint64_t getCurrentTime();
+
+  int addTimingPacket(const uint64_t data_packet);
+  std::vector<TbRawFile*>& files() { return m_files; }
+  unsigned int plane() const { return m_plane; }
+  void setOffset(const int colOffset) {
+    m_colOffset = colOffset;
+  }
+  void setDevice(const unsigned int device) { m_device = device; }
+  void setPlane(const unsigned int plane) { m_plane = plane; }
+  unsigned int col() const { return m_colOffset; }
+  unsigned int device() const { return m_device; }
+
+  template <typename T>
+  std::vector<T>* cache();
+
+  void insert(LHCb::TbTrigger* packet);
+  void insert(LHCb::TbHit* packet);
+  uint64_t m_tpx3Timer = 0; 
+ private:
+  static const int64_t m_tenSeconds;
+  static const int64_t m_maxTimeDifference;
+
+  std::vector<TbRawFile*>::iterator m_currentFile;
+  std::vector<TbRawFile*> m_files;
+  std::vector<LHCb::TbHit*> m_hitCache;
+  std::vector<LHCb::TbTrigger*> m_trgCache;
+  unsigned int m_plane;
+  unsigned int m_device;
+  uint64_t m_size = 0;
+  /// Temporary lsb of the global timer
+  unsigned int m_lsb = 0;
+  uint64_t m_timer = 0;
+  unsigned int m_colOffset;
+};
diff --git a/TbIO/src/.svn/text-base/TbTupleWriter.cpp.svn-base b/TbIO/src/.svn/text-base/TbTupleWriter.cpp.svn-base
new file mode 100644
index 0000000..46c0d5c
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbTupleWriter.cpp.svn-base
@@ -0,0 +1,324 @@
+// Tb/TbEvent
+#include "Event/TbTrigger.h"
+#include "Event/TbHit.h"
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTupleWriter.h"
+
+DECLARE_ALGORITHM_FACTORY(TbTupleWriter)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTupleWriter::TbTupleWriter(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("WriteTriggers", m_writeTriggers = false);
+  declareProperty("WriteHits", m_writeHits = false);
+  declareProperty("WriteClusters", m_writeClusters = true);
+  declareProperty("WriteTracks", m_writeTracks = false);
+
+  declareProperty("MaxClusterSize", m_maxclustersize = 200);
+  declareProperty("WriteClusterHits", m_writeClusterHits = true);
+
+  declareProperty("TriggerLocation",
+                  m_triggerLocation = LHCb::TbTriggerLocation::Default);
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+
+  /// Stripped nTuples for low rate external users, 
+  /// only output tracks that have associated triggers 
+  declareProperty("StrippedNTuple", m_strippedNTuple = false);
+  declareProperty("MaxTriggers", m_maxTriggers = 20 );
+  // Switch off output during finalize.
+  setProperty("NTuplePrint", false);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTupleWriter::~TbTupleWriter() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbTupleWriter::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  if (m_writeTriggers) bookTriggers();
+  if (m_writeHits) bookHits();
+  if (m_writeTracks) bookTracks();
+  if (m_writeClusters) bookClusters();
+  m_evtNo = 0;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTupleWriter::execute() {
+
+  if (m_writeTriggers) fillTriggers();
+  if (m_writeHits) fillHits();
+  if (m_writeTracks) fillTracks();
+  if (m_writeClusters) fillClusters();
+  ++m_evtNo;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Book trigger tuple
+//=============================================================================
+void TbTupleWriter::bookTriggers() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Trigger");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Trigger",
+                         CLID_ColumnWiseTuple, "nTuple of Triggers");
+  nt->addItem("TgID", m_TgID);
+  nt->addItem("TgTime", m_TgTime);
+  nt->addItem("TgHTime", m_TgHTime);
+  nt->addItem("TgEvt", m_TgEvt);
+  nt->addItem("TgPlane", m_TgPlane);
+  nt->addItem("TgCounter",m_TgCounter);
+}
+
+//=============================================================================
+// Book hit tuple
+//=============================================================================
+void TbTupleWriter::bookHits() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Hits");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Hits",
+                         CLID_ColumnWiseTuple, "nTuple of Hits");
+  nt->addItem("hID", m_hID);
+  nt->addItem("hCol", m_hCol);
+  nt->addItem("hRow", m_hRow);
+  nt->addItem("hTime", m_hTime);
+  nt->addItem("hHTime", m_hHTime);
+  nt->addItem("hToT", m_hToT);
+  nt->addItem("hPlane", m_hPlane);
+}
+
+//=============================================================================
+// Book cluster tuple
+//=============================================================================
+void TbTupleWriter::bookClusters() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Clusters");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Clusters",
+                         CLID_ColumnWiseTuple, "nTuple of Clusters");
+  nt->addItem("clID", m_clID);
+  nt->addItem("clGx", m_clGx);
+  nt->addItem("clGy", m_clGy);
+  nt->addItem("clGz", m_clGz);
+  nt->addItem("clLx", m_clLx);
+  nt->addItem("clLy", m_clLy);
+  nt->addItem("clTime", m_clTime);
+  nt->addItem("clHTime", m_clHTime);
+  nt->addItem("clSize", m_clSize);
+  nt->addItem("clCharge", m_clCharge);
+  nt->addItem("clIsTracked", m_clTracked);
+  nt->addItem("clPlane", m_clPlane);
+  nt->addItem("clEvtNo", m_clEvtNo);
+  nt->addItem("clNHits", m_clN, 0, (int)m_maxclustersize);
+  nt->addIndexedItem("hRow", m_clN, m_clhRow);
+  nt->addIndexedItem("hCol", m_clN, m_clhCol);
+  nt->addIndexedItem("sCol", m_clN, m_clsCol);
+  nt->addIndexedItem("hHTime", m_clN, m_clhHTime);
+  nt->addIndexedItem("hToT", m_clN, m_clhToT);
+}
+
+//=============================================================================
+// Book track tuple
+//=============================================================================
+void TbTupleWriter::bookTracks() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Tracks");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Tracks",
+                         CLID_ColumnWiseTuple, "nTuple of Tracks");
+  nt->addItem("TkID", m_TkID);
+  nt->addItem("TkTime", m_TkTime);
+  nt->addItem("TkHTime", m_TkHTime);
+  nt->addItem("TkNCl", m_TkNCl, 0, 10);
+  nt->addItem("TkX", m_TkX0);
+  nt->addItem("TkY", m_TkY0);
+  nt->addItem("TkTx", m_TkTx);
+  nt->addItem("TkTy", m_TkTy);
+  nt->addItem("TkChi2PerNdof", m_TkChi2ndof);
+  nt->addIndexedItem("TkClId", m_TkNCl, m_TkClId);
+  nt->addItem("TkEvt",m_TkEvt);
+  nt->addItem("TkNTg",m_TkNTg,0,(int)m_maxTriggers);
+  nt->addIndexedItem("TkTgId",m_TkNTg,m_TkTgId);
+  nt->addIndexedItem("TkTgPlane",m_TkNTg,m_TkTgPlane);
+  nt->addIndexedItem("TkXResidual",m_TkNCl, m_TkXResidual); 
+  nt->addIndexedItem("TkYResidual",m_TkNCl, m_TkYResidual); 
+
+}
+
+//=============================================================================
+// Fill trigger tuple
+//=============================================================================
+void TbTupleWriter::fillTriggers() {
+
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (unsigned int i = 0 ; i < m_nPlanes; ++i) {
+    const std::string location = m_triggerLocation + std::to_string(i);
+    const LHCb::TbTriggers* triggers = getIfExists<LHCb::TbTriggers>(location);
+    if (!triggers) continue;
+    for (const LHCb::TbTrigger* trigger : *triggers) {
+      // if (m_triggerChannel != 999 && m_triggerChannel != trigger->plane()) continue; 
+      const uint64_t offset = ((uint64_t)trigger->plane() << 32) + evtOffset;
+      m_TgID = trigger->index() + offset;
+      m_TgTime = trigger->time();
+      m_TgHTime = trigger->htime();
+      m_TgPlane = i;
+      m_TgCounter = trigger->counter();
+      ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Trigger");
+      m_TgEvt = m_evtNo;
+    }
+  }
+}
+
+//=============================================================================
+// Fill hit tuple
+//=============================================================================
+void TbTupleWriter::fillHits() {
+
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string location = m_hitLocation + std::to_string(i);
+    const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(location);
+    if (!hits) continue;
+    const uint64_t offset = ((uint64_t)i << 32) + evtOffset;
+    for (const LHCb::TbHit* hit : *hits) {
+      m_hID = hit->index() + offset;
+      m_hCol = hit->col();
+      m_hRow = hit->row();
+      m_hTime = hit->time();
+      m_hHTime = hit->htime();
+      m_hToT = hit->ToT();
+      m_hPlane = i;
+      ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Hits");
+    }
+  }
+}
+
+//=============================================================================
+// Fill cluster tuple
+//=============================================================================
+void TbTupleWriter::fillClusters() {
+
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string location = m_clusterLocation + std::to_string(i);
+    const LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(location);
+    if (!clusters) continue;
+    const uint64_t offset = ((uint64_t)i << 32) + evtOffset;
+    for (const LHCb::TbCluster* cluster : *clusters) {
+      const unsigned long long clid = cluster->index() + offset;
+      m_clID = clid;
+      m_clGx = cluster->x();
+      m_clGy = cluster->y();
+      m_clGz = cluster->z();
+      m_clLx = cluster->xloc();
+      m_clLy = cluster->yloc();
+      m_clTime = cluster->time();
+      m_clHTime = cluster->htime();
+      m_clSize = cluster->hits().size();
+      m_clCharge = cluster->charge();
+      m_clTracked = cluster->associated();
+      m_clPlane = cluster->plane();
+      m_clEvtNo = m_evtNo;
+      m_clN = m_clSize > m_maxclustersize ? m_maxclustersize : m_clSize;
+      for (unsigned int j = 0; j < m_clN; ++j) {
+        const auto& h = cluster->hits()[j];
+        m_clhRow[j] = h->row();
+        m_clhCol[j] = h->col();
+        m_clsCol[j] = h->scol();
+        m_clhToT[j] = h->ToT();
+        m_clhHTime[j] = h->htime();
+      }
+      ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Clusters");
+    }
+  }
+}
+
+//=============================================================================
+// Fill track tuple
+//=============================================================================
+void TbTupleWriter::fillTracks() {
+
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) return;
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (const LHCb::TbTrack* track : *tracks) {
+    if (m_strippedNTuple && track->triggers().empty()) continue;
+    m_TkX0 = track->firstState().x();
+    m_TkY0 = track->firstState().y();
+    m_TkTx = track->firstState().tx();
+    m_TkTy = track->firstState().ty();
+    m_TkHTime = track->htime();
+    m_TkTime = track->time();
+    m_TkID = track->index() + evtOffset;
+    m_TkNCl = track->clusters().size();
+    m_TkChi2ndof = track->chi2PerNdof();
+    m_TkEvt = m_evtNo;
+    unsigned int i = 0;
+    const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters();
+    for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+      const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset;
+      const unsigned long long clid = (*it)->index() + offset;
+      m_TkClId[i] = clid;
+      auto intercept = geomSvc()->intercept( track, (*it)->plane() );
+      m_TkXResidual[(*it)->plane()] = (*it)->x() - intercept.x() ;
+      m_TkYResidual[(*it)->plane()] = (*it)->y() - intercept.y() ;
+      ++i;
+    }
+    const SmartRefVector<LHCb::TbCluster>& associatedClusters = track->associatedClusters();
+    for( auto it = associatedClusters.cbegin(), end = associatedClusters.cend(); it != end; ++it ){
+      const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset;
+      const unsigned long long clid = (*it)->index() + offset;
+      m_TkClId[i] = clid;
+      auto intercept = geomSvc()->intercept( track, (*it)->plane() );
+      m_TkXResidual[(*it)->plane()] = (*it)->x() - intercept.x() ;
+      m_TkYResidual[(*it)->plane()] = (*it)->y() - intercept.y() ;
+      ++i;
+    }
+    m_TkNTg = track->triggers().size();
+    i = 0;
+    const SmartRefVector<LHCb::TbTrigger>& triggers = track->triggers();
+    for (auto it = triggers.cbegin(), end = triggers.cend(); it != end; ++it) {
+      const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset;
+      const unsigned long long clid = (*it)->index() + offset;
+      if (i == 20) {
+        warning() << "More than 20 triggers associated to track: skipping" 
+          << endmsg;
+        break;
+      }
+      m_TkTgId[i] = clid;
+      m_TkTgPlane[i] = (*it)->plane();
+      ++i;
+    }
+    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Tracks");
+  }
+}
diff --git a/TbIO/src/.svn/text-base/TbTupleWriter.h.svn-base b/TbIO/src/.svn/text-base/TbTupleWriter.h.svn-base
new file mode 100644
index 0000000..92a6de9
--- /dev/null
+++ b/TbIO/src/.svn/text-base/TbTupleWriter.h.svn-base
@@ -0,0 +1,103 @@
+#ifndef TB_TUPLEWRITER_H
+#define TB_TUPLEWRITER_H 1
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTupleWriter TbTupleWriter.h
+ *
+ *  Algorithm to write out hits/clusters/tracks/triggers in ntuple format.
+ *
+ *  @author Heinrich Schindler
+ *  @date   2014-06-19
+ */
+
+class TbTupleWriter : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbTupleWriter(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTupleWriter();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  bool m_writeTriggers;
+  bool m_writeHits;
+  bool m_writeClusters;
+  bool m_writeTracks;
+  bool m_writeClusterHits;
+  /// Flag to produce a stripped nTuple
+  bool m_strippedNTuple; 
+  
+  unsigned int m_maxclustersize;
+  unsigned int m_maxTriggers;
+  unsigned long long m_evtNo;
+  std::string m_triggerLocation;
+  std::string m_hitLocation;
+  std::string m_clusterLocation;
+  std::string m_trackLocation;
+
+  void fillTriggers();
+  void fillHits();
+  void fillClusters();
+  void fillTracks();
+
+  void bookTriggers();
+  void bookHits();
+  void bookClusters();
+  void bookTracks();
+
+  // Trigger nTuple entries
+  NTuple::Item<unsigned long long> m_TgID;
+  NTuple::Item<unsigned long long> m_TgTime;
+  NTuple::Item<double> m_TgHTime;
+  NTuple::Item<unsigned int> m_TgEvt;
+  NTuple::Item<unsigned int> m_TgPlane;
+  NTuple::Item<unsigned int> m_TgCounter;
+
+  // Hit nTuple entries
+  NTuple::Item<unsigned long long> m_hID;
+  NTuple::Item<unsigned long long> m_hTime;
+  NTuple::Item<unsigned int> m_hCol;
+  NTuple::Item<unsigned int> m_hRow;
+  NTuple::Item<double> m_hHTime;
+  NTuple::Item<unsigned int> m_hToT;
+  NTuple::Item<unsigned int> m_hPlane;
+
+  // Track nTuple entries
+  NTuple::Item<unsigned long long> m_TkID;
+  NTuple::Item<unsigned long long> m_TkTime;
+  NTuple::Array<unsigned long long> m_TkClId;
+  NTuple::Array<unsigned long long> m_TkTgId;
+  NTuple::Array<unsigned int> m_TkTgPlane;
+  NTuple::Array<double> m_TkXResidual; 
+  NTuple::Array<double> m_TkYResidual;  
+
+  NTuple::Item<double> m_TkX0;
+  NTuple::Item<double> m_TkY0;
+  NTuple::Item<double> m_TkTx;
+  NTuple::Item<double> m_TkTy;
+  NTuple::Item<double> m_TkHTime;
+  NTuple::Item<double> m_TkChi2ndof;
+  NTuple::Item<unsigned int> m_TkNCl;
+  NTuple::Item<unsigned int> m_TkNTg;
+  NTuple::Item<unsigned int> m_TkNTgPlane;
+  
+  NTuple::Item<unsigned int> m_TkEvt;
+
+  // Cluster nTuple entries
+  NTuple::Item<double> m_clGx, m_clGy, m_clGz;
+  NTuple::Item<double> m_clLx, m_clLy, m_clHTime;
+  NTuple::Item<unsigned int> m_clSize;
+  NTuple::Item<double> m_clCharge;
+  NTuple::Item<unsigned int>  m_clPlane, m_clN;
+  NTuple::Item<unsigned long long> m_clEvtNo, m_clID, m_clTime;
+  NTuple::Item<bool> m_clTracked;
+  NTuple::Array<int> m_clhRow, m_clhCol, m_clhToT;
+  NTuple::Array<unsigned int> m_clsCol;
+  NTuple::Array<double> m_clhHTime;
+};
+
+#endif
diff --git a/TbIO/src/TbCombatBuilder.cpp b/TbIO/src/TbCombatBuilder.cpp
new file mode 100644
index 0000000..2c18bf6
--- /dev/null
+++ b/TbIO/src/TbCombatBuilder.cpp
@@ -0,0 +1,208 @@
+#include <algorithm>
+
+// Boost
+#include <boost/filesystem.hpp>
+
+// Gaudi
+#include "GaudiKernel/IEventProcessor.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+
+// Local
+#include "TbCombatBuilder.h"
+
+DECLARE_ALGORITHM_FACTORY(TbCombatBuilder)
+
+namespace fs = boost::filesystem;
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbCombatBuilder::TbCombatBuilder(const std::string& name,
+                                 ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator),
+      m_nPixels(256),
+      m_nEvents(0),
+      m_neof(true) {
+
+  declareProperty("CombatInputFile0", m_fileName0);
+  declareProperty("CombatInputFile1", m_fileName1 = "DefaultFileName1.dat");
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("MinPlanesWithHits", m_nMinPlanesWithHits = 1);  // TODO
+  declareProperty("SkipEvents", m_skipEvents = 0);                 // TODO
+  declareProperty("PrintFreq", m_printFreq = 100);
+  declareProperty("ReadoutFormat", m_readoutFormat);
+  declareProperty("FakeTime", m_fakeTime = 1);
+  declareProperty("NumberArms", m_nArms);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbCombatBuilder::~TbCombatBuilder() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbCombatBuilder::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Prepare the hit containers.
+  m_hits.resize(m_nPlanes, NULL);
+
+  // Open the hit files.
+  m_dataStream0.open(m_fileName0.c_str());
+  if (!m_dataStream0.is_open()) {
+    error() << "Cannot open file name: " << m_fileName0 << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if (m_nArms == 2 && m_readoutFormat=="Pixelman") {
+    m_dataStream1.open(m_fileName1.c_str());
+    if (!m_dataStream1.is_open()) {
+      error() << "Cannot open file name: " << m_fileName1 << endmsg;
+      return StatusCode::FAILURE;
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbCombatBuilder::execute() {
+  // Printing.
+  if (m_nEvents % m_printFreq == 0)
+    info() << "Loading event: " << m_nEvents << endmsg;
+
+  // Create containers for hits.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string ext = std::to_string(i);
+    m_hits[i] = new LHCb::TbHits();
+    put(m_hits[i], m_hitLocation + ext);
+  }
+
+
+  if(m_readoutFormat=="Pixelman"){
+	  if (m_nArms == 1) {
+		  fillEventFromPixelmanFile(0);
+	  } else if (m_nArms == 2) {
+		  fillEventFromPixelmanFile(0);
+		  fillEventFromPixelmanFile(1);
+	  }
+  }
+  else if(m_readoutFormat=="RelaxD"){
+	  fillEventFromRelaxDFile();
+  }
+
+  // Check whether there are any events left.
+  if (!m_neof) {
+    // Terminate.
+    SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+    if (app) app->stopRun();
+  } else {
+    // Ordering.
+    for (unsigned int i = 0; i < m_nPlanes; i++) {
+      std::sort(m_hits[i]->begin(), m_hits[i]->end(),
+                TbFunctors::GreaterByToT<const LHCb::TbHit*>());
+    }
+    m_nEvents++;
+  }
+
+  // Prepare for the next event.
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+StatusCode TbCombatBuilder::finalize() { return TbAlgorithm::finalize(); }
+
+//=============================================================================
+// Event filling handling Pixelman files
+//=============================================================================
+void TbCombatBuilder::fillEventFromPixelmanFile(const int armID) {
+  // Check we havent reached the next event.
+  bool sameEvent = true;  
+  while (sameEvent) {
+    std::string line;
+    if (armID == 0)
+      m_neof = std::getline(m_dataStream0, line);
+    else
+      m_neof = std::getline(m_dataStream1, line);
+    if (!m_neof) break;
+    if (line.substr(0, 1) == "#")
+      sameEvent = false;
+    else
+      fillHit(line, armID);
+  }
+}
+
+//=============================================================================
+// Event filling handling RelaxD files
+//=============================================================================
+void TbCombatBuilder::fillEventFromRelaxDFile() {
+
+//For the RelaxD files, in one event the first series of hits come from the upper arm and the second from the downstream arm.
+     for(int iArm=0;iArm<m_nArms;iArm++){
+        // Check we havent reached the next event.
+        bool sameEvent = true;
+        bool frameStart = false;
+        while (sameEvent) {
+               std::string line;
+               m_neof = std::getline(m_dataStream0, line);
+               if (!m_neof) break;
+               if (line.substr(0,1) != "#"){
+                   frameStart= true;
+                   fillHit(line, iArm);
+               }
+               if (line.substr(0, 1) == "#"&& frameStart==true)
+                   sameEvent = false;
+        }
+     }
+}
+//=============================================================================
+// Event filling
+//=============================================================================
+void TbCombatBuilder::fillHit(std::string line, int armID) {
+  std::stringstream lineStream;
+  lineStream << line;
+  int rowTemp, colTemp, ToT;
+  lineStream >> colTemp >> rowTemp >> ToT;
+
+  int plane;
+  if (colTemp > 255) {
+    if (rowTemp > 255)
+      plane = 1;
+    else
+      plane = 3;
+  } else {
+    if (rowTemp > 255)
+      plane = 0;
+    else
+      plane = 2;
+  }
+
+  // Arm modification.
+  if (armID == 1) plane += 4;
+
+  // Make the hit.
+  LHCb::TbHit* hit = new LHCb::TbHit();
+  hit->setRow(rowTemp % m_nPixels);
+  hit->setCol(colTemp % m_nPixels);
+  hit->setToT(ToT);
+  hit->setPixelAddress(hit->row() + hit->col() * m_nPixels);
+  hit->setTime(m_fakeTime);
+  hit->setHtime(timingSvc()->globalToLocal(hit->time()));
+
+  m_hits[plane]->insert(hit);
+}
+
+//=============================================================================
+// End
+//=============================================================================
diff --git a/TbIO/src/TbCombatBuilder.h b/TbIO/src/TbCombatBuilder.h
new file mode 100644
index 0000000..23b439c
--- /dev/null
+++ b/TbIO/src/TbCombatBuilder.h
@@ -0,0 +1,65 @@
+#ifndef TB_COMBATBUILDER_H
+#define TB_COMBATBUILDER_H 1
+
+#include <fstream>
+
+// Boost
+#include <boost/iostreams/device/mapped_file.hpp>
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbCombatBuilder TbCombatBuilder.h
+ *  @author Dan Saunders & Vinicius Franco
+ *  @date   2014-09-22
+ */
+
+class TbCombatBuilder : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbCombatBuilder(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbCombatBuilder();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm termination
+
+ private:
+  /// Input data files
+  std::string m_readoutFormat;
+  std::string m_fileName0;
+  std::string m_fileName1;
+  std::ifstream m_dataStream0;
+  std::ifstream m_dataStream1;
+  /// TES location of output hits
+  std::string m_hitLocation;
+  int m_nPixels;
+
+  /// Number of events to skip TODO
+  unsigned int m_skipEvents;
+  /// Min. number of non-empty planes required to make an event TODO
+  unsigned int m_nMinPlanesWithHits;
+
+  /// Frequency to print event count.
+  unsigned int m_printFreq;
+
+  /// Number of processed events
+  unsigned int m_nEvents;
+  std::vector<LHCb::TbHits*> m_hits;
+
+  /// Fake timestamp (not htime).
+  int m_fakeTime;
+  bool m_neof;
+  int m_nArms;  // 1 for vertical lab cases, 2 for testbeams.
+
+  void fillHit(std::string, int);
+  void fillEventFromPixelmanFile(const int arm);
+  void fillEventFromRelaxDFile();
+};
+
+#endif
diff --git a/TbIO/src/TbEventBuilder.cpp b/TbIO/src/TbEventBuilder.cpp
new file mode 100644
index 0000000..62ad713
--- /dev/null
+++ b/TbIO/src/TbEventBuilder.cpp
@@ -0,0 +1,580 @@
+#include <algorithm>
+
+// Gaudi
+#include "GaudiKernel/IEventProcessor.h"
+#include "GaudiAlg/ISequencerTimerTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbEventBuilder.h"
+#include "TbRawFile.h"
+
+#include <chrono>
+#include <ctime>
+
+DECLARE_ALGORITHM_FACTORY(TbEventBuilder)
+
+const int64_t TbEventBuilder::m_maxTimeDifference = std::pow(2, 40);
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbEventBuilder::TbEventBuilder(const std::string& name, 
+                               ISvcLocator* pSvcLocator)
+  : TbAlgorithm(name, pSvcLocator),
+    m_streams(), m_triggers(), m_hits() {
+
+    declareProperty("HitLocation", 
+        m_hitLocation = LHCb::TbHitLocation::Default);
+    declareProperty("TriggerLocation",
+        m_triggerLocation = LHCb::TbTriggerLocation::Default);
+
+    // Length of event in global time units.
+    declareProperty("EventLength", m_tick = 10 * Tb::SpidrTime);
+    // Length to look into 'future' events to correct
+    // for time misordering around event boundaries
+    declareProperty("CacheLength", m_cachelength = 20 * Tb::SpidrTime);
+
+    // The time by which events 'overlap' to prevent tracks / clusters
+    // being cut between different events. Implementation is rather
+    // convoluted, relies on track identification and global event defintion
+    // via the TbTimingSvc
+    declareProperty("OverlapTime", m_overlapTime = 0 * Tb::ToA);
+
+    // Min. number of planes with at least one hit required to make an event
+    declareProperty("MinPlanesWithHits", m_nMinPlanesWithHits = 1);
+    // Print frequency
+    declareProperty("PrintFreq", m_printFreq = 100);
+    // Size of the header, if not set is read in
+    declareProperty("HeaderSize", m_headerSize = 0);
+    // Flag to print out the header information
+    declareProperty("PrintHeader", m_printHeader = false);
+    // Flag to switch monitoring print-out and histograms.
+    declareProperty("Monitoring", m_monitoring = false);
+    // Time to start data processing, in s 
+    declareProperty("StartTime", m_startTime = 0);
+    // Time to end data processing, in ms
+    declareProperty("EndTime", m_endTime = 0);
+    // Flag to produce Equalisation maps
+    declareProperty("EqualisationHistos", m_equal = false );
+    // Maximum number of packets that can be lost before 
+    // considered a critical failure 
+    declareProperty("MaxLostPackets", m_maxLostPackets = 1000);
+    // Maximum number of timing packets that not read
+    // before considered a critical failure
+    declareProperty("MaxLostTimers", m_maxLostTimers = 10);
+    // Force the cache to update every cycle, as opposed to
+    // waiting until the first packet is in view
+    declareProperty("ForceCaching", m_forceCaching = false);
+    declareProperty("IgnoreGlobalClock", m_ignoreGlobalClock = false );
+  }
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbEventBuilder::~TbEventBuilder() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbEventBuilder::initialize() {
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Prepare the hit containers.
+  m_hits.resize(m_nPlanes, nullptr);
+  m_triggers.resize(m_nPlanes, nullptr);
+  // Setup the raw stream tools.
+  for (unsigned int i = 0; i < m_nDevices; ++i){
+    const std::string toolname = "TbRawStream/TbRawStream"+ std::to_string(i);
+    m_streams.push_back(tool<TbRawStream>(toolname));
+    if (!m_streams[i]) return Error("Cannot initialise " + toolname);
+    m_streams[i]->setDevice(i);
+  }
+  // Setup the header decoder tool.
+  m_headerDecoder = tool<TbHeaderDecoder>("TbHeaderDecoder");
+  if (!m_headerDecoder) return Error("Cannot initialise header decoder.");
+  m_headerDecoder->print(m_printHeader);
+  // Propagate the overlap time to the timing service.
+  timingSvc()->setOverlap(m_overlapTime);
+  // Get the list of input data 
+  auto files = dataSvc()->getInputFiles();
+  for (const auto& filename : files) {
+    // Check the filename.
+    const size_t pos = filename.find(".dat");
+    const size_t dash = filename.find_last_of("-");
+    if (pos == std::string::npos) {
+      warning() << "Skipping " << filename << " (not a .dat file)" << endmsg;
+      continue; 
+    }
+    if (!(pos - dash > 1)) {
+      warning() << "Unexpected filename (" << filename << ")" << endmsg;
+      warning() << "Skipping " << filename << endmsg;
+      continue;
+    }
+    TbRawFile* f = new TbRawFile(filename, m_headerDecoder);
+    if (!f->good()) {
+      if (!f->is_open()) {
+        error() << "Cannot open " << filename << endmsg;
+      } else {
+        f->close();
+      }
+      warning() << "Skipping " << filename << endmsg; 
+      delete f;
+      continue;
+    }
+    const std::string id = f->id();
+    const unsigned int plane = geomSvc()->plane(id);
+    if (plane == 999) {
+      warning() << id << " is not listed in the alignment file" << endmsg;
+      warning() << "Skipping " << filename << endmsg; 
+      f->close();
+      delete f;
+      continue;
+    }
+    const unsigned int deviceIndex = geomSvc()->deviceIndex(id);
+    if (deviceIndex == 999) {
+      warning() << id << " is not listed in the alignment file" << endmsg;
+      warning() << "Skipping " << filename << endmsg;
+      f->close();
+      delete f;
+      continue;
+    } 
+    if (m_streams[deviceIndex]->files().empty()) { 
+      info() << id << " (device " << deviceIndex 
+             << ") is mapped to plane " << plane << endmsg;
+    }
+    unsigned int col = 0;
+    auto chips = geomSvc()->module(plane)->chips();
+    for (auto chip : chips) {
+      if (chip.id == id) {
+        col = chip.col;
+      }
+    } 
+    m_streams[deviceIndex]->setPlane(plane);
+    m_streams[deviceIndex]->setDevice(deviceIndex);
+    m_streams[deviceIndex]->setOffset(col);
+    m_streams[deviceIndex]->addFile(f);
+  }
+  // Make sure that there are data files for all planes.
+  for (unsigned int i = 0; i < m_nDevices; ++i) {
+    if (m_streams[i]->files().empty()) {
+      return Error("No input files for device " + std::to_string(i));
+    }
+  }
+
+  // Convert start and end times to FToA.
+  m_startTime *= Tb::millisecond * 1000;
+  m_endTime *= Tb::millisecond;
+  for (auto& f : m_streams) {
+    std::sort(f->files().begin(), f->files().end(), lessBySplitIndex());
+    f->prepare();
+    m_nDataInFiles += f->size();
+    // Convert starting time to FToA times
+    if (m_startTime != 0) f->fastForward(m_startTime);
+  }
+  info() << "Total data size: " << m_nDataInFiles << " packets" << endmsg;
+  m_clock = m_tick + m_startTime;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbEventBuilder::execute() {
+
+  std::clock_t c_end = std::clock();
+  std::chrono::_V2::system_clock::time_point t_end = std::chrono::high_resolution_clock::now();
+  if (m_nPackets != 0) {
+    double time = std::chrono::duration<double, std::milli>(t_end-t_start).count() ;
+    plot2D(m_nPackets, time, "RateVsTime",0.,1000000.,0.,3000.,100,100);
+    plot2D(m_nPackets, time / (double)m_nPackets, "RateVsTimePerPacket",0.,1000000.,0.,0.01,100,100);
+    //info() << " packets = " << m_nPackets << " time = " << time << endmsg;
+    m_nPackets = 0;
+  }
+  /*
+     std::cout << std::fixed << std::setprecision(2) << "CPU time used: "
+     << 1000.0 * (c_end-c_start) / CLOCKS_PER_SEC << " ms\n"
+     << "Wall clock time passed: "
+     << std::chrono::duration<double, std::milli>(t_end-t_start).count()
+     << " ms\n";
+     */
+
+  c_start = c_end;
+  t_start = t_end; 
+
+  // Create containers for hits and triggers.
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string ext = std::to_string(i);
+    LHCb::TbHits* hits = new LHCb::TbHits();
+    put(hits, m_hitLocation + ext);
+    m_hits[i] = hits;
+    LHCb::TbTriggers* triggers = new LHCb::TbTriggers();
+    put(triggers, m_triggerLocation + ext);
+    m_triggers[i] = triggers;
+  }
+  bool done = false;
+  bool eof = true;
+  bool eot = false;
+  while (!done) {
+    eof = true;
+    // Update the event boundaries.
+    if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+      debug() << "Event definition: " << m_clock - m_tick 
+        << " to " << m_clock + m_overlapTime
+        << endmsg;
+    }
+    timingSvc()->setEventDefinition(m_clock - m_tick,
+        m_clock + m_overlapTime);
+    for (unsigned int i = 0 ; i < m_nPlanes; ++i) {
+      m_hits[i]->clear();
+      m_triggers[i]->clear();
+    }
+    for (auto f : m_streams) {
+      eof &= f->eos();
+      fill(f, m_hits[f->plane()], m_triggers[f->plane()], eot);
+    } 
+    unsigned int nPlanesWithHits = 0;
+    bool gotTrigger = false;
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      if (!m_triggers[i]->empty()) {
+        gotTrigger = true;
+        break;
+      }
+      if (!m_hits[i]->empty()) ++nPlanesWithHits;
+    }
+    if (gotTrigger || nPlanesWithHits >= m_nMinPlanesWithHits) {
+      done = true;
+    } else {
+      ++m_nNoiseEvents;
+    }
+    m_clock += m_tick;
+    if (eof) break;
+  }
+  // Sort hits and triggers by time. 
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    std::sort(m_hits[i]->begin(), m_hits[i]->end(),
+        TbFunctors::LessByTime<const LHCb::TbHit*>());
+    std::sort(m_triggers[i]->begin(), m_triggers[i]->end(),
+        TbFunctors::LessByTime<const LHCb::TbTrigger*>());
+    m_nPackets += m_hits[i]->size() ; 
+  }
+  // Increment the event counter.
+  ++m_nEvents;
+  if (m_nEvents % m_printFreq == 0) {
+    info() << format(" %8u events read, %12u hits, %12u triggers", 
+        m_nEvents, m_nHitsRead, m_nTriggersRead) << endmsg; 
+    if (m_monitoring) {
+      info() << "Hits:     ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_hits[i]->size());
+      }
+      info() << endmsg << "Cache:    ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_streams[i]->hitCache().size());
+      }
+      info() << endmsg << "Triggers: ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_triggers[i]->size());
+      }
+      info() << endmsg << "Cache:    ";
+      for (unsigned int i = 0; i < m_nPlanes; ++i) {
+        info() << format(" %12d", m_streams[i]->trgCache().size());
+      }
+      info() << endmsg;
+    }
+  }
+  bool emptyCache = true;
+  for (const auto& f : m_streams) {
+    if (!f->hitCache().empty() || !f->trgCache().empty()) {
+      emptyCache = false;
+      break;
+    }
+  }
+  // Check if there are any events left to process.
+  if (((m_nData == m_nDataInFiles || eof) && emptyCache) || eot) {
+    // Terminate the application.
+    SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+    if (app) app->stopRun();
+  }
+  if (m_nLostTimers > m_maxLostTimers) {
+    return Error("More than " + std::to_string(m_maxLostTimers) + 
+        " clock packets dropped. Critical problem with global clock");
+  }
+  if (m_nLostPackets > m_maxLostPackets) {
+    return Error("More than " + std::to_string(m_maxLostPackets) +  
+        " packets  dropped. Critical problem with timing");
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Add hits and triggers to the containers
+//=============================================================================
+bool TbEventBuilder::fill(TbRawStream* f, LHCb::TbHits* hits,
+    LHCb::TbTriggers* triggers,
+    bool& eot) {
+  if (!dumpCache(f, hits) && !m_forceCaching) {
+    if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+      debug() << "Event boundary: " << m_clock << endmsg;
+      if (f->hitCache().size() > 0) {
+        debug() << "First hit in cache:" << f->hitCache().front()->time()
+          << endmsg;
+      }
+      if (f->trgCache().size() > 0) {
+        debug() << "First trigger in cache: " << f->trgCache().front()->time()
+          << endmsg;
+      }
+    }
+    dumpCache(f, triggers);
+    return false;
+  }
+  dumpCache(f, triggers);
+  const unsigned int device = f->device();
+  uint64_t currentTime = 0;
+  while (likely(currentTime < m_clock + m_cachelength && !f->eos())) {
+    const uint64_t packet = f->getNext();
+    ++m_nData;
+    const unsigned int header = 0xF & (packet >> 60);
+    if (likely(header == 0xA || header == 0xB)) {
+      // Pixel packets.
+      ++m_nHitsRead;     
+      // Get the pixel adress.
+      const unsigned int pixelAddress = 0xFFFF & (packet >> 44);
+      // Skip masked pixels.
+      if (unlikely(pixelSvc()->isMasked(pixelAddress, device))) continue;
+      LHCb::TbHit* hit = decodeTPX3Hit( packet, pixelAddress, device , f->col() );
+      hit->setCharge(pixelSvc()->charge(hit->ToT(), pixelAddress, device));
+      extendTimeStamp(hit, m_ignoreGlobalClock ? f->m_tpx3Timer : f->timer());
+      pixelSvc()->applyPhaseCorrection(hit);
+      writePacket(hit, f, hits);
+      currentTime = hit->time();
+      
+      //info() << std::dec << (double)prevTime / (double)Tb::second << "   " << (double)currentTime / (double)Tb::second << "    " << f->hClock() << endmsg;
+      syncTPX3( currentTime, f ) ; 
+      if (UNLIKELY(m_monitoring)) {
+        plot(hit->time() / Tb::millisecond, "HitDataRate", 
+            "Rate of hit packets", 0.0, 620000.0, 6200000);
+      }
+    } else if ((header == 0x6 || header == 0x4) &&
+        (( packet >> 56) & 0xF) == 0xF) {
+      // New trigger packets
+      LHCb::TbTrigger* trigger = new LHCb::TbTrigger(packet);
+      extendTimeStamp(trigger, f->timer());
+      trigger->setPlane(f->plane());
+      writePacket(trigger, f, triggers);
+      ++m_nTriggersRead;
+      if (m_monitoring) {
+        plot(trigger->time() / Tb::millisecond, "TriggerDataRate",
+            "Rate of trigger packets", 0.0, 620000.0, 620000);
+      }
+    } else if (header == 0x4 && ! m_ignoreGlobalClock ) {
+      // Timing packets
+      int state = f->addTimingPacket(packet);
+      if (state == 2) 
+      {
+        warning() << "Jump in timing of greater than 6.7s detected."
+          << format("Dropping timing packet: 0x%x", packet) 
+          << endmsg;
+        warning() << "Will attempt to resynchronise using a different SPIDR's"
+          << " global clock" << endmsg;
+        attemptResync( f , packet );
+        if( m_nLostTimers > m_maxLostTimers ) return true;      
+        // If fail to add as a timing packet, data packet unknown
+      }
+      else if (state == 0) {
+        ++m_unknownPackets;
+        if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+          debug() << format("Timing packet with subheader 0x%x, packet = 0x%x",
+              ((packet >> 56) & 0xF), packet) 
+            << endmsg; 
+        }
+      }
+    }   
+    else {
+      // Packet is neither hit, nor a trigger, nor a timing packet.
+      ++m_unknownPackets;
+      if (UNLIKELY(msgLevel(MSG::DEBUG))) {
+        warning() << format("Packet with header 0x%x, packet = 0x%x", 
+            header, packet) << endmsg;
+      }
+    }
+  }
+  std::sort(f->hitCache().begin(), f->hitCache().end(),
+      TbFunctors::LessByTimeBP<const LHCb::TbHit*>());
+  std::sort(f->trgCache().begin(), f->trgCache().end(),
+      TbFunctors::LessByTimeBP<const LHCb::TbTrigger*>());
+
+  if (m_endTime != 0 && currentTime > m_endTime) eot = true;
+  if (!hits->empty() || !triggers->empty() || f->eos()) return true;
+  return false;
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+void TbEventBuilder::syncTPX3(const uint64_t& thisPacketTime, TbRawStream* f) { 
+
+  int timerMsbs = 0x3 & ( f->m_tpx3Timer >> 40 );
+  int thisMsb = 0x3 & ( thisPacketTime >> 40 ); 
+  constexpr uint64_t one = (uint64_t)(1) << 40;
+
+  if( thisMsb == timerMsbs+1 || thisMsb == timerMsbs-3){
+    info() << "Updating clock " << (double)(f->m_tpx3Timer + one)/(double)Tb::second << endmsg; 
+    f->m_tpx3Timer += one;
+  }
+  if( thisMsb > timerMsbs ){
+    info() << thisMsb << "   " << timerMsbs << endmsg; 
+  }
+}
+
+bool TbEventBuilder::attemptResync(TbRawStream* f, const uint64_t& packet) {
+
+  for (unsigned int chip = 0 ; chip != m_nPlanes; ++chip) {
+    int64_t dt = (int64_t)f->timer() - (int64_t)m_streams[chip]->timer();
+    if (std::abs(dt) > m_maxTimeDifference) {
+      f->setLSB(m_streams[chip]->lsb());
+      f->setGlobalClock(m_streams[chip]->timer());
+      const int state = f->addTimingPacket(packet);
+      if (state != 2) {
+        info() << "Resync of device " << chip << " successful!" << endmsg;
+        return true; 
+      }
+    }
+  }
+  warning() << "Resynchronisation of device fails" << endmsg;
+  // Empty the cache.
+  for (auto it = f->hitCache().begin(); it != f->hitCache().end(); ++it) {
+    if (*it) delete *it;
+  }
+  f->hitCache().clear();
+  for (auto it = f->trgCache().begin(); it != f->trgCache().end(); ++it) {
+    if (*it) delete *it;
+  }
+  f->trgCache().clear();
+  m_nLostTimers++;
+  return false; 
+}
+
+StatusCode TbEventBuilder::finalize() {
+
+  for (auto& f : m_streams) {
+    info() << format("Plane %2u: %12u packets in file, %12u hits in cache",
+        f->plane(), f->size(), f->hitCache().size()) << endmsg;
+    for (auto it = f->hitCache().begin(); it != f->hitCache().end(); ++it) {
+      if (*it) delete *it;
+    }
+    for (auto it = f->trgCache().begin(); it != f->trgCache().end(); ++it) {
+      if (*it) delete *it;
+    }
+    f->close();
+  }
+  info() << "Fraction of data read: " << (double)m_nData /
+    (double)m_nDataInFiles << endmsg;
+  info() << "Number of packets lost: " << m_nLostPackets << endmsg;
+  info() << "Unknown packets: " << m_unknownPackets << endmsg;
+  if (m_nNoiseEvents > 0) {
+    info() << "Skipped " << m_nNoiseEvents << " noise events." << endmsg;
+  }
+  // Finalise the base class.
+  return TbAlgorithm::finalize();
+}
+
+//=============================================================================
+// Dump cached packets into the current event
+//=============================================================================
+template <typename T>
+bool TbEventBuilder::dumpCache(
+    TbRawStream* stream, KeyedContainer<T, Containers::HashMap>* container) {
+
+  // Load the hits/triggers stored in the cache.
+  std::vector<T*>* cache = stream->cache<T*>();
+  auto it = cache->begin();
+  const auto end = cache->end();
+  for (; it != end; ++it) {
+    const auto time = (*it)->time();
+    if (unlikely(time >= m_clock + m_overlapTime)) break;
+    if (unlikely(time < m_clock - m_tick ) ) {
+      // Packet is earlier than the current event.
+      // If this happens, the cache may be too short.
+      warning() << format("Packet 0x%016llX", (*it)->data()) << " is "
+        << " ns before event low edge! Current event definition: "
+        << (m_clock - m_tick) / Tb::SpidrTime << " to "
+        << (m_clock + m_overlapTime) / Tb::SpidrTime << endmsg;
+      ++m_nLostPackets;
+      delete *it;
+      if (m_nLostPackets > m_maxLostPackets) {
+        error() << "Large number of packets lost -> critical failure" << endmsg;
+        return false;
+      }
+      continue;
+    }
+    (*it)->setHtime(timingSvc()->globalToLocal(time));
+    // Move packet to the TES.
+    container->insert(*it);
+  }
+  cache->erase(cache->begin(), it);
+  if (container->empty() && !cache->empty()) return false;
+  return true;
+}
+
+//=============================================================================
+// Extend the timestamp of a packet
+//=============================================================================
+template <typename T>
+void TbEventBuilder::extendTimeStamp(T* packet, uint64_t global_time) {
+
+  const uint64_t packet_time = packet->time();
+  const int diff = (0x3 & (global_time >> 40)) - (0x3 & (packet_time >> 40));
+  constexpr uint64_t one = (uint64_t)(1) << 40;
+  // Calculate the difference between the bits that should match between
+  // the spidr time and the global time, if they do not match, increment or
+  // decrement the global time so that they match and add the 18 m.s.f.
+  // of the global time to the packet time
+  if (diff == 1 || diff == -3) {
+    global_time = global_time - one;
+  } else if (diff == -1 || diff == 3) {
+    global_time = global_time + one;
+  }
+  packet->setTime((0x3FFFFFFFFFF & packet_time) +
+      (global_time & 0xFFFFC0000000000));
+}
+
+LHCb::TbHit* TbEventBuilder::decodeTPX3Hit( const uint64_t& packet,const unsigned int& pixelAddress, const unsigned int& device , const unsigned int& fCol ){
+
+  LHCb::TbHit* hit = new LHCb::TbHit();
+  hit->setDevice(device);
+  hit->setData(packet);
+  hit->setPixelAddress(pixelAddress);
+  // Decode the pixel address, first get the double column. 
+  const unsigned int dcol = (0xFE00 & pixelAddress) >> 8;
+  // Get the super pixel address.
+  const unsigned int spix = (0x01F8 & pixelAddress) >> 1;
+  // Get the address of the pixel within the super pixel. 
+  const unsigned int pix = (0x0007 & pixelAddress);
+  // Calculate and store the row and column numbers.
+  const unsigned int col = dcol + pix / 4;
+  const unsigned int row = spix + (pix & 0x3);
+  hit->setCol(col);
+  hit->setRow(row);
+  hit->setScol(col + fCol);
+  const unsigned int data = (packet & 0x00000FFFFFFF0000) >> 16;
+  // Extract and store the ToT and the corresponding charge.
+  const unsigned int tot = (data & 0x00003FF0) >> 4;
+  hit->setToT(tot);
+  //  hit->setCharge(pixelSvc()->charge(tot, pixelAddress, device));
+  // Get the time stamps.
+  const uint64_t spidrTime = packet & 0x000000000000FFFF;
+  const uint64_t ftoa = data & 0x0000000F;
+  const uint64_t toa = (data & 0x0FFFC000) >> 14;
+  // Calculate the global timestamp.
+  const uint64_t fulltime = ((spidrTime << 18) + (toa << 4) + (15 - ftoa)) << 8;
+  hit->setTime(fulltime);
+
+  return hit;
+}
+
diff --git a/TbIO/src/TbEventBuilder.h b/TbIO/src/TbEventBuilder.h
new file mode 100644
index 0000000..7860532
--- /dev/null
+++ b/TbIO/src/TbEventBuilder.h
@@ -0,0 +1,162 @@
+#ifndef TB_EVENTBUILDER_H
+#define TB_EVENTBUILDER_H 1
+
+// Boost
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/TbModule.h"
+
+// Local
+#include "TbRawStream.h"
+#include "TbRawFile.h"
+#include "TbHeaderDecoder.h"
+#include <ctime>
+#include <chrono>
+/** @class TbEventBuilder TbEventBuilder.h
+ *
+ *  Algorithm to populate TES with time ordered gaudi events with data read in
+ *  in the SPIDR data format
+ *
+ *  @author Tim Evans (timothy.david.evans@cern.ch)
+ *  @date   2014-04-01
+ */
+
+class TbEventBuilder : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbEventBuilder(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbEventBuilder();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm termination
+ 
+ private:
+  /// Max. time difference for resynchronisation
+  static const int64_t m_maxTimeDifference;  
+  std::clock_t c_start;
+  std::chrono::_V2::system_clock::time_point t_start; 
+  /// Input data files
+  std::vector<std::string> m_input;
+  /// TES location of output hits
+  std::string m_hitLocation;
+  /// TES location of output triggers
+  std::string m_triggerLocation;
+
+
+  /// The length of the time window used by the event definition
+  uint64_t m_tick;
+  /// The length of time looking in the the next event
+  uint64_t m_cachelength;
+  /// The length of time by which event definitions 'overlap', 
+  /// to be sorted out by tracking
+  uint64_t m_overlapTime;
+
+  /// Time at which to start reading (in trigger FToA times)
+  uint64_t m_startTime;
+  /// Time at which to stop reading (specified in ms, converted later to FToA)
+  uint64_t m_endTime;
+
+  /// Min. number of non-empty planes required to make an event
+  unsigned int m_nMinPlanesWithHits;
+
+  /// Frequency to print event count.
+  unsigned int m_printFreq;
+  /// The total header size. If set to 0, is read from header.
+  unsigned int m_headerSize;
+  /// Flag to dump header or not.
+  bool m_printHeader;
+  /// Flag to activate detailed print-out and histograms.
+  bool m_monitoring;
+  /// Flag to activate pixel configuration histograms
+  bool m_equal;
+  /// Flag to ignore the global clock packets
+  bool m_ignoreGlobalClock;
+  /// The end of the time window used by the event definition
+  uint64_t m_clock;
+
+  /// Number of processed events
+  unsigned int m_nEvents = 0;
+  /// Number of skipped noise events
+  unsigned int m_nNoiseEvents = 0;
+  /// Number of created hits
+  uint64_t m_nData = 0;
+  /// Number of read hit packets
+  uint64_t m_nHitsRead = 0;
+  /// Number of read trigger packets
+  unsigned int m_nTriggersRead = 0;
+  /// Number of unknown packets  
+  unsigned int m_unknownPackets = 0;
+  /// Number of out-of-time packets
+  unsigned int m_nLostPackets = 0;
+  unsigned int m_nLostTimers = 0;
+  /// Maximum number of lost packets / clock packets
+  unsigned int m_maxLostPackets;
+  unsigned int m_maxLostTimers;
+  /// Another eof checksum
+  uint64_t m_nDataInFiles = 0;
+  /// Number of packets per event
+  unsigned int m_nPackets = 0;
+
+  /// Forces the cache to update every cycle, useful 
+  /// for runs where a bad packet has confused the caching
+  bool m_forceCaching;
+  /// TbRawStreams for each plane
+  std::vector<TbRawStream*> m_streams;
+  /// Triggers in each plane
+  std::vector<LHCb::TbTriggers*> m_triggers;
+  /// Hits in each plane
+  std::vector<LHCb::TbHits*> m_hits;
+
+  /// Header decoder tool
+  TbHeaderDecoder* m_headerDecoder = nullptr;
+
+  bool fill(TbRawStream* f, LHCb::TbHits* hits, LHCb::TbTriggers* triggers, bool& eot);
+
+  /// Templated cache dump for triggers and hits (extendible to other
+  /// data packets with a time field and a htime field
+  template <typename T>
+  bool dumpCache(TbRawStream* stream,
+                 KeyedContainer<T, Containers::HashMap>* container);
+ 
+  /// Extend the timestamp of a packet to include the global time
+  template <typename T>
+  void extendTimeStamp(T* packet, uint64_t global_time);
+
+  /// Write a data packet to either a cache or the TES, depending on
+  /// whether it is contained within the current event definition
+  template <typename T>
+  void writePacket(T* packet, TbRawStream* stream,
+                   KeyedContainer<T, Containers::HashMap>* container) {
+    const uint64_t time = packet->time();
+    if (time < m_clock + m_overlapTime && time >= m_clock - m_tick) {
+      // Timestamp is inside the current event. Add the packet to the TES.
+      packet->setHtime(timingSvc()->globalToLocal(time));
+      container->insert(packet);
+    } else {
+      stream->insert(packet);
+    }
+  }
+  LHCb::TbHit* decodeTPX3Hit(const uint64_t& packet, 
+                             const unsigned int& pixelAddress, 
+                             const unsigned int& device, 
+                             const unsigned int& fCol); 
+  void syncTPX3(const uint64_t& thisPacketTime, TbRawStream* f);  
+  bool attemptResync(TbRawStream* f, const uint64_t& packet); 
+  /// Functor for sorting files by split index
+  class lessBySplitIndex {
+   public:
+    bool operator()(const TbRawFile* a, const TbRawFile* b) const {
+      return a->splitIndex() < b->splitIndex();
+    }
+  };
+
+};
+
+#endif
diff --git a/TbIO/src/TbHeaderDecoder.cpp b/TbIO/src/TbHeaderDecoder.cpp
new file mode 100644
index 0000000..a7fdcee
--- /dev/null
+++ b/TbIO/src/TbHeaderDecoder.cpp
@@ -0,0 +1,209 @@
+// Boost
+#include "boost/format.hpp"
+
+// Local
+#include "TbHeaderDecoder.h"
+
+DECLARE_TOOL_FACTORY(TbHeaderDecoder)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbHeaderDecoder::TbHeaderDecoder(const std::string& type,
+                                 const std::string& name,
+                                 const IInterface* parent)
+    : GaudiTool(type, name, parent), 
+      m_print(true), m_geomSvc(nullptr), m_pixelSvc(nullptr) {
+
+  declareInterface<TbHeaderDecoder>(this);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbHeaderDecoder::~TbHeaderDecoder() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbHeaderDecoder::initialize() {
+
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Read the first fields of the Spidr header from a given file.
+//=============================================================================
+bool TbHeaderDecoder::readCommon(const char* data, unsigned int& size,
+                                 unsigned int& fmt) {
+
+  struct CommonHeader {
+    uint32_t headerId;
+    uint32_t headerSizeTotal;
+    uint32_t headerSize;
+    uint32_t format;
+  };
+  CommonHeader* hdr = (CommonHeader*)data;
+  size = hdr->headerSizeTotal;
+  if (size > 66304) size = 66304;
+  fmt = hdr->format;
+  return true;
+}
+
+//=============================================================================
+// Read the Spidr header from a given file.
+//=============================================================================
+bool TbHeaderDecoder::read(const char* data, const unsigned int& fmt,
+                           std::string& deviceId) {
+
+  if (fmt == 0x30 || fmt == 0x1) {
+    return readV1(data, deviceId);
+  }
+  error() << format("Unknown format (0x%x)", fmt) << endmsg;
+  return false;
+}
+
+
+//=============================================================================
+// Read version 1 of the Spidr header.
+//=============================================================================
+bool TbHeaderDecoder::readV1(const char* data, std::string& deviceId) {
+
+  struct Tpx3Header {
+    uint32_t headerId;
+    uint32_t headerSizeTotal;
+    uint32_t headerSize;
+    uint32_t format;
+    uint32_t deviceId;
+    uint32_t genConfig;
+    uint32_t outblockConfig;
+    uint32_t pllConfig;
+    uint32_t testPulseConfig;
+    uint32_t slvsConfig;
+    uint32_t pwrPulseConfig;
+    uint32_t dac[32];
+    uint8_t ctpr[256 / 8];
+    uint32_t unused[64 - 11 - 32 - (256 / 8) / 4];
+  };
+
+  struct SpidrTpx3Header {
+    uint32_t headerId;
+    uint32_t headerSizeTotal;
+    uint32_t headerSize;
+    uint32_t format;
+    uint32_t spidrId;
+    uint32_t libVersion;
+    uint32_t softwVersion;
+    uint32_t firmwVersion;
+    uint32_t ipAddress;
+    uint32_t ipPort;
+    uint32_t yyyyMmDd;
+    uint32_t hhMmSsMs;
+    uint32_t runNr;
+    uint32_t seqNr;
+    uint32_t spidrConfig;  // Trigger mode, decoder on/off
+    uint32_t spidrFilter;
+    uint32_t spidrBiasVoltage;
+    // Spare
+    uint32_t unused[128 - 17 - 128 / 4];
+    // Description string
+    char descr[128];
+    // Device header
+    Tpx3Header devHeader;
+  };
+
+  SpidrTpx3Header* hdr = (SpidrTpx3Header*)data;
+  Tpx3Header devHdr = hdr->devHeader;
+  // Get the chip id.
+  const int devid0 = (hdr->devHeader.deviceId >> 8) & 0xFFF;
+  const int devid1 = (hdr->devHeader.deviceId >> 4) & 0xF;
+  const int devid2 = (hdr->devHeader.deviceId >> 0) & 0xF;
+  const char devidchar = (char)(devid2 + 64);
+  deviceId = str(boost::format("W%04d_%d%02d") % devid0 % devidchar % devid1);
+
+  // Transfer the header information to the pixel configuration service.
+  const unsigned int deviceIndex = geomSvc()->deviceIndex(deviceId);
+  if (deviceIndex == 999) {
+    error() << deviceId << " is not listed in the alignment file." << endmsg;
+    return false;
+  } 
+  pixelSvc()->setPhase(deviceIndex, devHdr.pllConfig);
+  if (devHdr.headerSizeTotal - devHdr.headerSize == 65536) {
+    const char* trimDac = data + (hdr->headerSize + devHdr.headerSize);
+    pixelSvc()->setTrim(deviceIndex, trimDac);
+  }
+  if (!m_print) return true;
+
+  boost::format fmts(" %|-30.30s|%|32t| %s ");
+  boost::format fmtx(" %|-30.30s|%|32t| 0x%x ");
+  boost::format fmt8x(" %|-30.30s|%|32t| 0x%08x ");
+  boost::format fmtd(" %|-30.30s|%|32t| %d ");
+  info() << std::string(70, '-') << endmsg;
+  info() << "                        File header " << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "ID" % hdr->headerId << endmsg;
+  info() << fmtd % "Total size" % hdr->headerSizeTotal << endmsg;
+  info() << fmtd % "Size" % hdr->headerSize << endmsg;
+  info() << fmt8x % "Format" % hdr->format << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "SPIDR ID" % hdr->spidrId << endmsg;
+  info() << fmtx % "Library version" % hdr->libVersion << endmsg;
+  info() << fmtx % "Software version" % hdr->softwVersion << endmsg;
+  info() << fmtx % "Firmware version" % hdr->firmwVersion << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  const int ip0 = (hdr->ipAddress >> 24) & 0xFF;
+  const int ip1 = (hdr->ipAddress >> 16) & 0xFF;
+  const int ip2 = (hdr->ipAddress >> 8) & 0xFF;
+  const int ip3 = (hdr->ipAddress >> 0) & 0xFF;
+  const std::string ip = std::to_string(ip0) + "." + std::to_string(ip1) + "." +
+                         std::to_string(ip2) + "." + std::to_string(ip3);
+  info() << fmts % "IP address" % ip << endmsg;
+  info() << fmtd % "IP port" % hdr->ipPort << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  const int date0 = (hdr->yyyyMmDd >> 16) & 0xFFFF;
+  const int date1 = (hdr->yyyyMmDd >> 8) & 0xFF;
+  const int date2 = (hdr->yyyyMmDd >> 0) & 0xFF;
+  const int time0 = (hdr->hhMmSsMs >> 24) & 0xFF;
+  const int time1 = (hdr->hhMmSsMs >> 16) & 0xFF;
+  const int time2 = (hdr->hhMmSsMs >> 8) & 0xFF;
+  const int time3 = (hdr->hhMmSsMs >> 0) & 0xFF;
+  info() << boost::format(" %|-30.30s|%|32t| %04x-%02x-%02x") % "Date" % date0 %
+                date1 % date2 << endmsg;
+  info() << boost::format(" %|-30.30s|%|32t| %02x:%02x:%02x.%02x") % "Time" %
+                time0 % time1 % time2 % time3 << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtd % "Run number" % hdr->runNr << endmsg;
+  info() << fmtd % "Sequence number" % hdr->seqNr << endmsg;
+  info() << fmts % "Run info" % hdr->descr << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmt8x % "Spidr configuration" % hdr->spidrConfig << endmsg;
+  info() << fmt8x % "Data filter" % hdr->spidrFilter << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << "                       Device header" << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "Type ID" % devHdr.headerId << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmtx % "Device ID" % devHdr.deviceId << endmsg;
+  info() << fmts % "" % deviceId << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  info() << fmt8x % "General config" % devHdr.genConfig << endmsg;
+  info() << fmt8x % "Output block config" % devHdr.outblockConfig << endmsg;
+  info() << fmt8x % "PLL config" % devHdr.pllConfig << endmsg;
+  info() << fmt8x % "Testpulse config" % devHdr.testPulseConfig << endmsg;
+  info() << fmt8x % "SLVS config" % devHdr.slvsConfig << endmsg;
+  info() << fmt8x % "Power pulsing config" % devHdr.pwrPulseConfig << endmsg;
+  info() << std::string(70, '-') << endmsg;
+  boost::format fmt(" %|-30.30s|%|32t| %03d %03d %03d %03d");
+  std::string title = "DAC values";
+  for (unsigned int i = 0; i < 5; ++i) {
+    const unsigned int offset = 4 * i;
+    info() << fmt % title % devHdr.dac[offset] % devHdr.dac[offset + 1] %
+                  devHdr.dac[offset + 2] % devHdr.dac[offset + 3] << endmsg;
+    title = "";
+  }
+  info() << std::string(70, '-') << endmsg; 
+  return true;
+}
diff --git a/TbIO/src/TbHeaderDecoder.h b/TbIO/src/TbHeaderDecoder.h
new file mode 100644
index 0000000..3c37160
--- /dev/null
+++ b/TbIO/src/TbHeaderDecoder.h
@@ -0,0 +1,59 @@
+#ifndef TBHEADERDECODER_H
+#define TBHEADERDECODER_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/ITbPixelSvc.h"
+
+/** @class TbHeaderDecoder TbHeaderDecoder.h
+ *
+ * Tool to read SPIDR header from raw data file.
+ *
+ */
+
+static const InterfaceID IID_TbHeaderDecoder("TbHeaderDecoder", 1, 0);
+
+class TbHeaderDecoder : public GaudiTool {
+ public:
+  // Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_TbHeaderDecoder; }
+
+  /// Constructor
+  TbHeaderDecoder(const std::string& type, const std::string& name,
+                  const IInterface* parent);
+  /// Destructor
+  virtual ~TbHeaderDecoder();
+
+  virtual StatusCode initialize();
+
+  void print(const bool& flag) { m_print = flag; }
+  bool read(const char* data, const unsigned int& fmt, 
+            std::string& deviceId);
+  bool readCommon(const char* data, unsigned int& size, unsigned int& fmt);
+
+ private:
+  /// Flag to activate print-out or not.
+  bool m_print;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+
+  /// Pointer to pixel service
+  mutable ITbPixelSvc* m_pixelSvc;
+  /// Access pixel service on-demand
+  ITbPixelSvc* pixelSvc() const {
+    if (!m_pixelSvc) m_pixelSvc = svc<ITbPixelSvc>("TbPixelSvc", true);
+    return m_pixelSvc;
+  }
+  /// Read version 1
+  bool readV1(const char* data, std::string& deviceId);
+};
+
+#endif
diff --git a/TbIO/src/TbPacketRecycler.cpp b/TbIO/src/TbPacketRecycler.cpp
new file mode 100644
index 0000000..13bc92c
--- /dev/null
+++ b/TbIO/src/TbPacketRecycler.cpp
@@ -0,0 +1,105 @@
+#include "TbPacketRecycler.h"
+#include "Event/TbTrack.h"
+
+DECLARE_ALGORITHM_FACTORY(TbPacketRecycler)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbPacketRecycler::TbPacketRecycler(const std::string& name,
+                                   ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  // Declare algorithm properties - see header for description.
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("TriggerLocation",
+                  m_trgLocation = LHCb::TbTriggerLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusLocation = LHCb::TbClusterLocation::Default);
+}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbPacketRecycler::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  IToolSvc* toolsvc = nullptr;
+  sc = service("ToolSvc", toolsvc);
+  if (!sc.isSuccess()) {
+    return Error("Unable to get a handle to the tool service", sc);
+  }
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    TbRawStream* foo = nullptr;
+    sc = toolSvc()->retrieveTool("TbRawStream/" + std::to_string(i), foo);
+    if (!sc.isSuccess()) {
+      return Error("Unable to retrieve TbRawStream for plane " + 
+                   std::to_string(i), sc);
+    }
+    m_streams.push_back(foo);
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbPacketRecycler::execute() {
+
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string hitLocation = m_hitLocation + std::to_string(i);
+    const std::string trgLocation = m_trgLocation + std::to_string(i);
+    const std::string clusLocation = m_clusLocation + std::to_string(i);
+
+    LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(hitLocation);
+    LHCb::TbTriggers* trgs = getIfExists<LHCb::TbTriggers>(trgLocation);
+    LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(clusLocation);
+
+    removeClusters(clusters);
+    recycle(hits, m_streams[i]);
+    recycle(trgs, m_streams[i]);
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Copy unused hits and triggers to the cache. 
+//=============================================================================
+template <typename TYPE>
+void TbPacketRecycler::recycle(
+    KeyedContainer<TYPE, Containers::HashMap>* container, TbRawStream* s) {
+  if (!container) return;
+  std::vector<TYPE*> tmp_cache;
+  tmp_cache.clear();
+  typename KeyedContainer<TYPE, Containers::HashMap>::reverse_iterator packet;
+  for (packet = container->rbegin(); packet != container->rend(); ++packet) {
+    // Break when outside the overlap time window.
+    if (timingSvc()->beforeOverlap((*packet)->time())){
+      break;
+    }
+    // If unused, add the hit/trigger to the temporary cache.
+    if (!(*packet)->associated()) {
+      tmp_cache.push_back(new TYPE(*packet));
+      container->remove(*packet);
+    }
+  }
+  std::reverse(tmp_cache.begin(), tmp_cache.end());
+  s->cache<TYPE*>()->insert(s->cache<TYPE*>()->begin(), tmp_cache.begin(),
+                            tmp_cache.end());
+}
+
+//=============================================================================
+// Remove non-associated clusters from a container
+//=============================================================================
+void TbPacketRecycler::removeClusters(LHCb::TbClusters* clusters) {
+  if (!clusters) return;
+  LHCb::TbClusters::reverse_iterator it;
+  for (it = clusters->rbegin(); it != clusters->rend(); ++it) {
+    // Break when outside the overlap time window.
+    if (timingSvc()->beforeOverlap((*it)->time())) break;
+    // If unused, remove the cluster from the container.
+    if (!(*it)->associated()) clusters->remove(*it); 
+  }
+}
diff --git a/TbIO/src/TbPacketRecycler.h b/TbIO/src/TbPacketRecycler.h
new file mode 100644
index 0000000..105e79c
--- /dev/null
+++ b/TbIO/src/TbPacketRecycler.h
@@ -0,0 +1,54 @@
+// Gaudi
+#include "GaudiKernel/IToolSvc.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+#include "Event/TbCluster.h"
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+#include "TbKernel/TbConstants.h"
+
+// Local
+#include "TbRawStream.h"
+
+/** @class TbPacketRecycler TbPacketRecycler.h
+ *
+ *  Algorithm to move unprocessed data in the overlap into the next event
+ *  designed to prevent clusters / tracks being cut between events
+ *
+ *  @author Tim Evans (timothy.david.evans@cern.ch)
+ *  @date   2014-04-01
+ */
+
+class TbPacketRecycler : public TbAlgorithm {
+ public:
+  /// Constructor
+  TbPacketRecycler(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbPacketRecycler() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  std::vector<TbRawStream*> m_streams;
+  std::string m_hitLocation;
+  std::string m_trgLocation;
+  std::string m_clusLocation;
+  template <typename TYPE>
+  void recycle(KeyedContainer<TYPE, Containers::HashMap>* container,
+               TbRawStream* s);
+  void removeClusters(LHCb::TbClusters* clusters);
+  template <typename TYPE>
+  void addToCache(std::vector<TYPE*> cache, TYPE* packet) {
+    cache.push_back(packet);
+  }
+};
+
+template <>
+void TbPacketRecycler::addToCache(std::vector<LHCb::TbHit*> cache,
+                                  LHCb::TbHit* packet) {
+  cache.push_back(packet);
+}
diff --git a/TbIO/src/TbRawFile.cpp b/TbIO/src/TbRawFile.cpp
new file mode 100644
index 0000000..7199636
--- /dev/null
+++ b/TbIO/src/TbRawFile.cpp
@@ -0,0 +1,51 @@
+// ROOT
+#include "TFile.h"
+
+// Local
+#include "TbRawFile.h"
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbRawFile::TbRawFile(const std::string& filename, 
+                     TbHeaderDecoder* headerDecoder) 
+    : TbBufferedFile(filename, 0) {
+
+  if (!is_open()) {
+    m_good = false;
+    return;
+  }
+  const size_t pos = m_filename.find(".dat");
+  const size_t dash = m_filename.find_last_of("-");
+
+  if (pos == std::string::npos) {
+    m_good = false;
+    return;
+  }
+
+  if (!(pos - dash > 1)) {
+    m_good = false;
+    return;
+  }
+  m_split_index = atoi(m_filename.substr(dash + 1, pos - dash - 1).c_str());
+  if (m_split_index == 1) initialise();
+  m_good = true;
+
+  char header[16];
+  m_file->ReadBuffer(header, 0, 16);
+  unsigned int format = 0;
+  headerDecoder->readCommon(header, m_headerSize, format);
+
+  char* devHeader = new char[m_headerSize];
+  m_file->ReadBuffer(devHeader, 0, m_headerSize);
+
+  if (!headerDecoder->read(devHeader, format, m_id)) {
+    m_good = false;
+    return;
+  }
+  m_file->Seek(m_headerSize);
+  m_size = m_file->GetSize();
+  m_nPackets = (m_size - m_headerSize) / 8;
+  m_bytesRead = m_headerSize;
+  m_good = true;
+}
diff --git a/TbIO/src/TbRawFile.h b/TbIO/src/TbRawFile.h
new file mode 100644
index 0000000..463a4bb
--- /dev/null
+++ b/TbIO/src/TbRawFile.h
@@ -0,0 +1,48 @@
+#pragma once
+
+// Tb/TbKernel
+#include "TbKernel/TbBufferedFile.h"
+
+// Local
+#include "TbHeaderDecoder.h"
+
+/** @class TbRawFile TbRawFile.h
+ *
+ * Interface for raw files in SPIDR format via TbBufferedFile (ROOT I/O)
+ *
+ */
+
+class TbRawFile : public TbBufferedFile<1000000, uint64_t> {
+ public:
+  /// Constructor
+  TbRawFile(const std::string& filename, TbHeaderDecoder* headerDecoder);
+  /// Destructor
+  virtual ~TbRawFile() {}
+
+  /// Return the file index
+  unsigned int splitIndex() const { return m_split_index; }
+  uint64_t size() const { return m_size; }
+  /// Return the chip identifier
+  std::string id() const { return m_id; }
+  /// Return whether the file has been opened successfully
+  bool good() const { return m_good; }
+  /// Return the number of data packets in the file
+  uint64_t nPackets() const { return m_nPackets; }
+
+  /// Set the offset in size of packets
+  virtual void setOffset(const uint64_t offset) {
+    TbBufferedFile::setOffset(offset * 8 + m_headerSize);
+  }
+
+ protected:
+  uint64_t m_size;
+  /// Number of data packets in the file
+  uint64_t m_nPackets;
+  /// Index by which large files are divided
+  unsigned int m_split_index;
+  /// Header size in bytes
+  unsigned int m_headerSize;
+  /// Chip identifier
+  std::string m_id;
+  bool m_good;
+};
diff --git a/TbIO/src/TbRawStream.cpp b/TbIO/src/TbRawStream.cpp
new file mode 100644
index 0000000..65051bb
--- /dev/null
+++ b/TbIO/src/TbRawStream.cpp
@@ -0,0 +1,184 @@
+#include "TbRawStream.h"
+#include <cmath>
+
+DECLARE_TOOL_FACTORY(TbRawStream)
+
+const int64_t TbRawStream::m_tenSeconds = 256 * std::pow(10, 11);
+const int64_t TbRawStream::m_maxTimeDifference = pow(2, 40);
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbRawStream::TbRawStream(const std::string& type, const std::string& name,
+                         const IInterface* parent)
+    : GaudiTool(type, name, parent),
+      m_hitCache(), m_trgCache() {
+  declareInterface<TbRawStream>(this);
+}
+
+bool TbRawStream::setMSB(uint64_t msb) {
+  uint64_t currentTime = (m_lsb + (msb << 32)) << 12;
+  const int64_t timeDifference = currentTime - m_timer;
+  if (timeDifference > m_tenSeconds) {
+    // Detected jump of greater than 10s
+    // warning() << "Jump detected - this is okay, probably means "
+    // << "a bit has been updated between LSB and MSB" << endmsg;
+    if (msb > 0) msb -= 1;
+    currentTime = (m_lsb + (msb << 32)) << 12;
+  }
+  if (timeDifference > m_maxTimeDifference ||
+      timeDifference < -m_maxTimeDifference) {
+    // warning << "Current global time = " <<
+    // m_timer*25*pow(10,-6)/4096 << " clock is trying to update to " <<
+    // currentTime*25*pow(10,-6)/4096 << endmsg;
+    return false;
+  }
+  m_timer = currentTime;
+  // info() <<  "Current global time: " <<
+  // currentTime*25/(4096*pow(10,9)) << " s" <<endmsg;
+  return true;
+}
+
+void TbRawStream::fastForward(const uint64_t timeToSkipTo) {
+  // Go one second before we need to
+  const double coarse_time = timeToSkipTo * 25 / (4096 * pow(10, 9)); 
+  coarseFastForward(coarse_time);
+  fineFastForward(timeToSkipTo);
+}
+
+//=============================================================================
+// Binary search of the stream to find a particular time
+//=============================================================================
+void TbRawStream::coarseFastForward(const double timeToSkipTo) {
+
+  info() << "Skipping forward to time = " << timeToSkipTo << endmsg;
+  // Need to work out which file to read first
+  if (m_files.size() > 1) {
+    for (auto it = m_files.begin(), end = m_files.end(); it != end; ++it) {
+      m_currentFile = it;
+      (*it)->initialise();
+      const double timeInSeconds = getCurrentTime() * 25 / pow(10, 9);
+      if (timeInSeconds > timeToSkipTo) {
+        (*it)->reset();
+        m_currentFile--;
+        break;
+      }
+      (*it)->reset();
+    }
+  }
+
+  (*m_currentFile)->initialise();
+  uint64_t dt = (*m_currentFile)->nPackets() / 2;
+  uint64_t pos = dt;
+  uint64_t timer = 0;
+  double timeInSeconds = 0;
+  while (!eos() && fabs(timeToSkipTo - timeInSeconds) > 0.6 && dt > 1) {
+    // Scroll to the new position
+    (*m_currentFile)->setOffset(pos);  
+    dt /= 2;
+    timer = getCurrentTime();
+    timeInSeconds = timer * 25 / pow(10, 9);
+    pos = timeToSkipTo > timeInSeconds ? (pos + dt) : (pos - dt);
+  }
+  if (dt <= 1) info() << "Binary search has failed!" << endmsg;
+  m_timer = timer << 12;
+}
+
+void TbRawStream::fineFastForward(const uint64_t timeToSkipTo) {
+  uint64_t currentTime(0);
+  while (!eos() && currentTime < timeToSkipTo) {
+    const uint64_t data_packet = getNext();
+    const unsigned int header = data_packet >> 60;
+    if (header == 0xA || header == 0xB) {
+      uint64_t global_time = timer();
+      uint64_t packet_time = (0xFFFF & data_packet) << 26;
+      const int diff =
+          (0x3 & (global_time >> 40)) - (0x3 & (packet_time >> 40));
+      constexpr uint64_t one = (uint64_t)(1) << 40;
+      if (diff == 1 || diff == -3)
+        global_time = global_time - one;
+      else if (diff == -1 || diff == 3)
+        global_time = global_time + one;
+    } else if (header == 0x4) {
+      addTimingPacket(data_packet);
+      currentTime = m_timer;
+    }
+  }
+}
+
+uint64_t TbRawStream::getCurrentTime() {
+  m_lsb = 0;
+  uint64_t currentTime = 0;
+  bool gotTime = false;
+  while (!eos() && !gotTime) {
+    // measures the current time in the stream//
+    const uint64_t data_packet = getNext();
+    const unsigned int header = data_packet >> 60;
+    if (header == 0x4 && (0xF & (data_packet >> 54)) != 0xF) {
+      const unsigned int subheader = 0xF & (data_packet >> 56);
+      if (subheader == 0x4) {
+        m_lsb = 0xFFFFFFFF & (data_packet >> 16);
+      } else if (subheader == 0x5 && m_lsb != 0) {
+        const uint64_t msb = 0xFFFFFFFF & (data_packet >> 16);
+        currentTime = (m_lsb + (msb << 32));
+        gotTime = true;
+      }
+    }
+  }
+  return currentTime;
+}
+
+int TbRawStream::addTimingPacket(const uint64_t data_packet) {
+  const unsigned int subheader = 0xF & (data_packet >> 56);
+  int state = 1;
+  if (subheader == 0x5) {
+    // info() << "Current msb = Setting msb of clock: 0x" <<
+    // std::hex << data_packet <<  std::dec <<endmsg;
+    if (setMSB(0xFFFFFFFF & (data_packet >> 16)) == 0) state = 2;
+  } else if (subheader == 0x4) {
+    // info() << "Setting lsb of stream: 0x" << std::hex <<
+    // data_packet << ", current = " << m_lsb << std::dec << endmsg;
+    setLSB(0xFFFFFFFF & (data_packet >> 16));
+  } else {
+    state = 0;
+  }
+  return state;
+}
+
+void TbRawStream::prepare() {
+  m_currentFile = m_files.begin();
+  (*m_currentFile)->initialise();
+  m_size = 0;
+  for (const auto& raw_file : m_files) m_size = m_size + raw_file->nPackets();
+  //info() << "Stream = " << m_size << " 8-byte packets" << endmsg; 
+  unsigned int header(0);
+  // Find the first pixel hit
+  unsigned int prep_packets(0);
+  while (!eos() && !(header == 0xA || header == 0xB)) {
+    uint64_t packet = getNext();
+    // info() << std::hex << packet << endmsg;
+    header = 0xF & (packet >> 60);
+    ++prep_packets;
+  }
+  // for (unsigned int i = 0; i < 100; ++i) {
+  //   info() << std::hex << "0x" << getNext() << std::dec << endmsg;
+  // }
+  // info() << "Number of prep packets skipped = " << prep_packets << endmsg;
+  m_size = m_size - prep_packets + 1;
+  getPrevious();
+}
+
+template <>
+std::vector<LHCb::TbHit*>* TbRawStream::cache() {
+  return &m_hitCache;
+}
+template <>
+std::vector<LHCb::TbTrigger*>* TbRawStream::cache() {
+  return &m_trgCache;
+}
+
+void TbRawStream::insert(LHCb::TbHit* packet) { m_hitCache.push_back(packet); }
+
+void TbRawStream::insert(LHCb::TbTrigger* packet) {
+  m_trgCache.push_back(packet);
+}
diff --git a/TbIO/src/TbRawStream.h b/TbIO/src/TbRawStream.h
new file mode 100644
index 0000000..242c899
--- /dev/null
+++ b/TbIO/src/TbRawStream.h
@@ -0,0 +1,94 @@
+#pragma once
+
+#include "TbRawFile.h"
+#include "Event/TbHit.h"
+#include "Event/TbTrigger.h"
+#include "TbKernel/TbFunctors.h"
+#include "GaudiAlg/GaudiTool.h"
+#include "TbKernel/TbConstants.h"
+
+static const InterfaceID IID_TbRawStream("TbRawStream", 1, 0);
+
+class TbRawStream : public GaudiTool {
+
+ public:
+  /// Constructor
+  TbRawStream(const std::string& type, const std::string& name,
+              const IInterface* parent);
+
+  static const InterfaceID& interfaceID() { return IID_TbRawStream; }
+
+  uint64_t timer() const { return m_timer; }
+  unsigned int lsb() const { return m_lsb; }
+  // this is for explicitly setting the clock, if device sync fails
+  void setGlobalClock(const uint64_t timer) { m_timer = timer; }
+  unsigned int size() const { return m_size; }
+  void setLSB(const unsigned int lsb) { m_lsb = lsb; }
+  bool setMSB(uint64_t msb);
+
+  std::vector<LHCb::TbHit*>& hitCache() { return m_hitCache; }
+  std::vector<LHCb::TbTrigger*>& trgCache() { return m_trgCache; }
+  void addFile(TbRawFile* file) { m_files.push_back(file); }
+  void close() {
+    for (auto& raw_file : m_files) {
+      if (raw_file->is_open()) raw_file->close();
+    }
+  }
+
+  uint64_t getNext() { return (*m_currentFile)->getNext(); }
+  uint64_t getPrevious() { return (*m_currentFile)->getPrevious(); }
+
+  bool eos() {
+    if (unlikely( m_currentFile == m_files.end() ) ) return true;
+    if (unlikely((*m_currentFile)->eof() == true)) {
+      (*m_currentFile)->close();
+      m_currentFile++;
+      if (m_currentFile != m_files.end()) (*m_currentFile)->initialise();
+    }
+    return unlikely(m_currentFile == m_files.end());
+  }
+  double hClock() const {
+    return (double)m_timer / (double) Tb::second; 
+  }
+  void prepare();
+
+  // these functions collectively control fast forwarding to some point in the
+  // stream
+  void fastForward(const uint64_t timeToSkipTo);
+  void coarseFastForward(const double timeToSkipTo);
+  void fineFastForward(const uint64_t timeToSkipTo);
+  uint64_t getCurrentTime();
+
+  int addTimingPacket(const uint64_t data_packet);
+  std::vector<TbRawFile*>& files() { return m_files; }
+  unsigned int plane() const { return m_plane; }
+  void setOffset(const int colOffset) {
+    m_colOffset = colOffset;
+  }
+  void setDevice(const unsigned int device) { m_device = device; }
+  void setPlane(const unsigned int plane) { m_plane = plane; }
+  unsigned int col() const { return m_colOffset; }
+  unsigned int device() const { return m_device; }
+
+  template <typename T>
+  std::vector<T>* cache();
+
+  void insert(LHCb::TbTrigger* packet);
+  void insert(LHCb::TbHit* packet);
+  uint64_t m_tpx3Timer = 0; 
+ private:
+  static const int64_t m_tenSeconds;
+  static const int64_t m_maxTimeDifference;
+
+  std::vector<TbRawFile*>::iterator m_currentFile;
+  std::vector<TbRawFile*> m_files;
+  std::vector<LHCb::TbHit*> m_hitCache;
+  std::vector<LHCb::TbTrigger*> m_trgCache;
+  unsigned int m_plane;
+  unsigned int m_device;
+  uint64_t m_size = 0;
+  /// Temporary lsb of the global timer
+  unsigned int m_lsb = 0;
+  uint64_t m_timer = 0;
+  unsigned int m_colOffset;
+};
diff --git a/TbIO/src/TbTupleWriter.cpp b/TbIO/src/TbTupleWriter.cpp
new file mode 100644
index 0000000..46c0d5c
--- /dev/null
+++ b/TbIO/src/TbTupleWriter.cpp
@@ -0,0 +1,324 @@
+// Tb/TbEvent
+#include "Event/TbTrigger.h"
+#include "Event/TbHit.h"
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTupleWriter.h"
+
+DECLARE_ALGORITHM_FACTORY(TbTupleWriter)
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbTupleWriter::TbTupleWriter(const std::string& name, ISvcLocator* pSvcLocator)
+    : TbAlgorithm(name, pSvcLocator) {
+
+  declareProperty("WriteTriggers", m_writeTriggers = false);
+  declareProperty("WriteHits", m_writeHits = false);
+  declareProperty("WriteClusters", m_writeClusters = true);
+  declareProperty("WriteTracks", m_writeTracks = false);
+
+  declareProperty("MaxClusterSize", m_maxclustersize = 200);
+  declareProperty("WriteClusterHits", m_writeClusterHits = true);
+
+  declareProperty("TriggerLocation",
+                  m_triggerLocation = LHCb::TbTriggerLocation::Default);
+  declareProperty("HitLocation", m_hitLocation = LHCb::TbHitLocation::Default);
+  declareProperty("ClusterLocation",
+                  m_clusterLocation = LHCb::TbClusterLocation::Default);
+  declareProperty("TrackLocation",
+                  m_trackLocation = LHCb::TbTrackLocation::Default);
+
+  /// Stripped nTuples for low rate external users, 
+  /// only output tracks that have associated triggers 
+  declareProperty("StrippedNTuple", m_strippedNTuple = false);
+  declareProperty("MaxTriggers", m_maxTriggers = 20 );
+  // Switch off output during finalize.
+  setProperty("NTuplePrint", false);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTupleWriter::~TbTupleWriter() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbTupleWriter::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = TbAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  if (m_writeTriggers) bookTriggers();
+  if (m_writeHits) bookHits();
+  if (m_writeTracks) bookTracks();
+  if (m_writeClusters) bookClusters();
+  m_evtNo = 0;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbTupleWriter::execute() {
+
+  if (m_writeTriggers) fillTriggers();
+  if (m_writeHits) fillHits();
+  if (m_writeTracks) fillTracks();
+  if (m_writeClusters) fillClusters();
+  ++m_evtNo;
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Book trigger tuple
+//=============================================================================
+void TbTupleWriter::bookTriggers() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Trigger");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Trigger",
+                         CLID_ColumnWiseTuple, "nTuple of Triggers");
+  nt->addItem("TgID", m_TgID);
+  nt->addItem("TgTime", m_TgTime);
+  nt->addItem("TgHTime", m_TgHTime);
+  nt->addItem("TgEvt", m_TgEvt);
+  nt->addItem("TgPlane", m_TgPlane);
+  nt->addItem("TgCounter",m_TgCounter);
+}
+
+//=============================================================================
+// Book hit tuple
+//=============================================================================
+void TbTupleWriter::bookHits() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Hits");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Hits",
+                         CLID_ColumnWiseTuple, "nTuple of Hits");
+  nt->addItem("hID", m_hID);
+  nt->addItem("hCol", m_hCol);
+  nt->addItem("hRow", m_hRow);
+  nt->addItem("hTime", m_hTime);
+  nt->addItem("hHTime", m_hHTime);
+  nt->addItem("hToT", m_hToT);
+  nt->addItem("hPlane", m_hPlane);
+}
+
+//=============================================================================
+// Book cluster tuple
+//=============================================================================
+void TbTupleWriter::bookClusters() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Clusters");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Clusters",
+                         CLID_ColumnWiseTuple, "nTuple of Clusters");
+  nt->addItem("clID", m_clID);
+  nt->addItem("clGx", m_clGx);
+  nt->addItem("clGy", m_clGy);
+  nt->addItem("clGz", m_clGz);
+  nt->addItem("clLx", m_clLx);
+  nt->addItem("clLy", m_clLy);
+  nt->addItem("clTime", m_clTime);
+  nt->addItem("clHTime", m_clHTime);
+  nt->addItem("clSize", m_clSize);
+  nt->addItem("clCharge", m_clCharge);
+  nt->addItem("clIsTracked", m_clTracked);
+  nt->addItem("clPlane", m_clPlane);
+  nt->addItem("clEvtNo", m_clEvtNo);
+  nt->addItem("clNHits", m_clN, 0, (int)m_maxclustersize);
+  nt->addIndexedItem("hRow", m_clN, m_clhRow);
+  nt->addIndexedItem("hCol", m_clN, m_clhCol);
+  nt->addIndexedItem("sCol", m_clN, m_clsCol);
+  nt->addIndexedItem("hHTime", m_clN, m_clhHTime);
+  nt->addIndexedItem("hToT", m_clN, m_clhToT);
+}
+
+//=============================================================================
+// Book track tuple
+//=============================================================================
+void TbTupleWriter::bookTracks() {
+
+  NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+  NTuplePtr nt(ntupleSvc(), "/NTUPLES/FILE1/TbTupleWriter/Tracks");
+  // Check if already booked.
+  if (nt) return;
+  nt = ntupleSvc()->book("/NTUPLES/FILE1/TbTupleWriter/Tracks",
+                         CLID_ColumnWiseTuple, "nTuple of Tracks");
+  nt->addItem("TkID", m_TkID);
+  nt->addItem("TkTime", m_TkTime);
+  nt->addItem("TkHTime", m_TkHTime);
+  nt->addItem("TkNCl", m_TkNCl, 0, 10);
+  nt->addItem("TkX", m_TkX0);
+  nt->addItem("TkY", m_TkY0);
+  nt->addItem("TkTx", m_TkTx);
+  nt->addItem("TkTy", m_TkTy);
+  nt->addItem("TkChi2PerNdof", m_TkChi2ndof);
+  nt->addIndexedItem("TkClId", m_TkNCl, m_TkClId);
+  nt->addItem("TkEvt",m_TkEvt);
+  nt->addItem("TkNTg",m_TkNTg,0,(int)m_maxTriggers);
+  nt->addIndexedItem("TkTgId",m_TkNTg,m_TkTgId);
+  nt->addIndexedItem("TkTgPlane",m_TkNTg,m_TkTgPlane);
+  nt->addIndexedItem("TkXResidual",m_TkNCl, m_TkXResidual); 
+  nt->addIndexedItem("TkYResidual",m_TkNCl, m_TkYResidual); 
+
+}
+
+//=============================================================================
+// Fill trigger tuple
+//=============================================================================
+void TbTupleWriter::fillTriggers() {
+
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (unsigned int i = 0 ; i < m_nPlanes; ++i) {
+    const std::string location = m_triggerLocation + std::to_string(i);
+    const LHCb::TbTriggers* triggers = getIfExists<LHCb::TbTriggers>(location);
+    if (!triggers) continue;
+    for (const LHCb::TbTrigger* trigger : *triggers) {
+      // if (m_triggerChannel != 999 && m_triggerChannel != trigger->plane()) continue; 
+      const uint64_t offset = ((uint64_t)trigger->plane() << 32) + evtOffset;
+      m_TgID = trigger->index() + offset;
+      m_TgTime = trigger->time();
+      m_TgHTime = trigger->htime();
+      m_TgPlane = i;
+      m_TgCounter = trigger->counter();
+      ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Trigger");
+      m_TgEvt = m_evtNo;
+    }
+  }
+}
+
+//=============================================================================
+// Fill hit tuple
+//=============================================================================
+void TbTupleWriter::fillHits() {
+
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string location = m_hitLocation + std::to_string(i);
+    const LHCb::TbHits* hits = getIfExists<LHCb::TbHits>(location);
+    if (!hits) continue;
+    const uint64_t offset = ((uint64_t)i << 32) + evtOffset;
+    for (const LHCb::TbHit* hit : *hits) {
+      m_hID = hit->index() + offset;
+      m_hCol = hit->col();
+      m_hRow = hit->row();
+      m_hTime = hit->time();
+      m_hHTime = hit->htime();
+      m_hToT = hit->ToT();
+      m_hPlane = i;
+      ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Hits");
+    }
+  }
+}
+
+//=============================================================================
+// Fill cluster tuple
+//=============================================================================
+void TbTupleWriter::fillClusters() {
+
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    const std::string location = m_clusterLocation + std::to_string(i);
+    const LHCb::TbClusters* clusters = getIfExists<LHCb::TbClusters>(location);
+    if (!clusters) continue;
+    const uint64_t offset = ((uint64_t)i << 32) + evtOffset;
+    for (const LHCb::TbCluster* cluster : *clusters) {
+      const unsigned long long clid = cluster->index() + offset;
+      m_clID = clid;
+      m_clGx = cluster->x();
+      m_clGy = cluster->y();
+      m_clGz = cluster->z();
+      m_clLx = cluster->xloc();
+      m_clLy = cluster->yloc();
+      m_clTime = cluster->time();
+      m_clHTime = cluster->htime();
+      m_clSize = cluster->hits().size();
+      m_clCharge = cluster->charge();
+      m_clTracked = cluster->associated();
+      m_clPlane = cluster->plane();
+      m_clEvtNo = m_evtNo;
+      m_clN = m_clSize > m_maxclustersize ? m_maxclustersize : m_clSize;
+      for (unsigned int j = 0; j < m_clN; ++j) {
+        const auto& h = cluster->hits()[j];
+        m_clhRow[j] = h->row();
+        m_clhCol[j] = h->col();
+        m_clsCol[j] = h->scol();
+        m_clhToT[j] = h->ToT();
+        m_clhHTime[j] = h->htime();
+      }
+      ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Clusters");
+    }
+  }
+}
+
+//=============================================================================
+// Fill track tuple
+//=============================================================================
+void TbTupleWriter::fillTracks() {
+
+  const LHCb::TbTracks* tracks = getIfExists<LHCb::TbTracks>(m_trackLocation);
+  if (!tracks) return;
+  const uint64_t evtOffset = (uint64_t)m_evtNo << 36;
+  for (const LHCb::TbTrack* track : *tracks) {
+    if (m_strippedNTuple && track->triggers().empty()) continue;
+    m_TkX0 = track->firstState().x();
+    m_TkY0 = track->firstState().y();
+    m_TkTx = track->firstState().tx();
+    m_TkTy = track->firstState().ty();
+    m_TkHTime = track->htime();
+    m_TkTime = track->time();
+    m_TkID = track->index() + evtOffset;
+    m_TkNCl = track->clusters().size();
+    m_TkChi2ndof = track->chi2PerNdof();
+    m_TkEvt = m_evtNo;
+    unsigned int i = 0;
+    const SmartRefVector<LHCb::TbCluster>& clusters = track->clusters();
+    for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+      const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset;
+      const unsigned long long clid = (*it)->index() + offset;
+      m_TkClId[i] = clid;
+      auto intercept = geomSvc()->intercept( track, (*it)->plane() );
+      m_TkXResidual[(*it)->plane()] = (*it)->x() - intercept.x() ;
+      m_TkYResidual[(*it)->plane()] = (*it)->y() - intercept.y() ;
+      ++i;
+    }
+    const SmartRefVector<LHCb::TbCluster>& associatedClusters = track->associatedClusters();
+    for( auto it = associatedClusters.cbegin(), end = associatedClusters.cend(); it != end; ++it ){
+      const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset;
+      const unsigned long long clid = (*it)->index() + offset;
+      m_TkClId[i] = clid;
+      auto intercept = geomSvc()->intercept( track, (*it)->plane() );
+      m_TkXResidual[(*it)->plane()] = (*it)->x() - intercept.x() ;
+      m_TkYResidual[(*it)->plane()] = (*it)->y() - intercept.y() ;
+      ++i;
+    }
+    m_TkNTg = track->triggers().size();
+    i = 0;
+    const SmartRefVector<LHCb::TbTrigger>& triggers = track->triggers();
+    for (auto it = triggers.cbegin(), end = triggers.cend(); it != end; ++it) {
+      const uint64_t offset = ((uint64_t)(*it)->plane() << 32) + evtOffset;
+      const unsigned long long clid = (*it)->index() + offset;
+      if (i == 20) {
+        warning() << "More than 20 triggers associated to track: skipping" 
+          << endmsg;
+        break;
+      }
+      m_TkTgId[i] = clid;
+      m_TkTgPlane[i] = (*it)->plane();
+      ++i;
+    }
+    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbTupleWriter/Tracks");
+  }
+}
diff --git a/TbIO/src/TbTupleWriter.h b/TbIO/src/TbTupleWriter.h
new file mode 100644
index 0000000..92a6de9
--- /dev/null
+++ b/TbIO/src/TbTupleWriter.h
@@ -0,0 +1,103 @@
+#ifndef TB_TUPLEWRITER_H
+#define TB_TUPLEWRITER_H 1
+
+// Tb/TbKernel
+#include "TbKernel/TbAlgorithm.h"
+
+/** @class TbTupleWriter TbTupleWriter.h
+ *
+ *  Algorithm to write out hits/clusters/tracks/triggers in ntuple format.
+ *
+ *  @author Heinrich Schindler
+ *  @date   2014-06-19
+ */
+
+class TbTupleWriter : public TbAlgorithm {
+ public:
+  /// Standard constructor
+  TbTupleWriter(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbTupleWriter();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  bool m_writeTriggers;
+  bool m_writeHits;
+  bool m_writeClusters;
+  bool m_writeTracks;
+  bool m_writeClusterHits;
+  /// Flag to produce a stripped nTuple
+  bool m_strippedNTuple; 
+  
+  unsigned int m_maxclustersize;
+  unsigned int m_maxTriggers;
+  unsigned long long m_evtNo;
+  std::string m_triggerLocation;
+  std::string m_hitLocation;
+  std::string m_clusterLocation;
+  std::string m_trackLocation;
+
+  void fillTriggers();
+  void fillHits();
+  void fillClusters();
+  void fillTracks();
+
+  void bookTriggers();
+  void bookHits();
+  void bookClusters();
+  void bookTracks();
+
+  // Trigger nTuple entries
+  NTuple::Item<unsigned long long> m_TgID;
+  NTuple::Item<unsigned long long> m_TgTime;
+  NTuple::Item<double> m_TgHTime;
+  NTuple::Item<unsigned int> m_TgEvt;
+  NTuple::Item<unsigned int> m_TgPlane;
+  NTuple::Item<unsigned int> m_TgCounter;
+
+  // Hit nTuple entries
+  NTuple::Item<unsigned long long> m_hID;
+  NTuple::Item<unsigned long long> m_hTime;
+  NTuple::Item<unsigned int> m_hCol;
+  NTuple::Item<unsigned int> m_hRow;
+  NTuple::Item<double> m_hHTime;
+  NTuple::Item<unsigned int> m_hToT;
+  NTuple::Item<unsigned int> m_hPlane;
+
+  // Track nTuple entries
+  NTuple::Item<unsigned long long> m_TkID;
+  NTuple::Item<unsigned long long> m_TkTime;
+  NTuple::Array<unsigned long long> m_TkClId;
+  NTuple::Array<unsigned long long> m_TkTgId;
+  NTuple::Array<unsigned int> m_TkTgPlane;
+  NTuple::Array<double> m_TkXResidual; 
+  NTuple::Array<double> m_TkYResidual;  
+
+  NTuple::Item<double> m_TkX0;
+  NTuple::Item<double> m_TkY0;
+  NTuple::Item<double> m_TkTx;
+  NTuple::Item<double> m_TkTy;
+  NTuple::Item<double> m_TkHTime;
+  NTuple::Item<double> m_TkChi2ndof;
+  NTuple::Item<unsigned int> m_TkNCl;
+  NTuple::Item<unsigned int> m_TkNTg;
+  NTuple::Item<unsigned int> m_TkNTgPlane;
+  
+  NTuple::Item<unsigned int> m_TkEvt;
+
+  // Cluster nTuple entries
+  NTuple::Item<double> m_clGx, m_clGy, m_clGz;
+  NTuple::Item<double> m_clLx, m_clLy, m_clHTime;
+  NTuple::Item<unsigned int> m_clSize;
+  NTuple::Item<double> m_clCharge;
+  NTuple::Item<unsigned int>  m_clPlane, m_clN;
+  NTuple::Item<unsigned long long> m_clEvtNo, m_clID, m_clTime;
+  NTuple::Item<bool> m_clTracked;
+  NTuple::Array<int> m_clhRow, m_clhCol, m_clhToT;
+  NTuple::Array<unsigned int> m_clsCol;
+  NTuple::Array<double> m_clhHTime;
+};
+
+#endif
diff --git a/TbKernel/.svn/all-wcprops b/TbKernel/.svn/all-wcprops
new file mode 100644
index 0000000..88a9c80
--- /dev/null
+++ b/TbKernel/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/CMakeLists.txt
+END
diff --git a/TbKernel/.svn/entries b/TbKernel/.svn/entries
new file mode 100644
index 0000000..aac9e40
--- /dev/null
+++ b/TbKernel/.svn/entries
@@ -0,0 +1,74 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbKernel
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+TbKernel
+dir
+
+src
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+12c56ed8ffc063b29d58504513b4e426
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+701
+
diff --git a/TbKernel/.svn/text-base/CMakeLists.txt.svn-base b/TbKernel/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..5747f1c
--- /dev/null
+++ b/TbKernel/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,23 @@
+################################################################################
+# Package: TbKernel
+################################################################################
+gaudi_subdir(TbKernel v3r0)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS GenVector)
+find_package(Boost)
+
+gaudi_add_library(TbKernelLib
+                  src/lib/*.cpp
+                  PUBLIC_HEADERS TbKernel
+                  LINK_LIBRARIES GaudiAlgLib)
+
+gaudi_add_module(TbKernel
+                 src/*.cpp
+                 INCLUDE_DIRS AIDA Boost
+                 LINK_LIBRARIES Boost GaudiAlgLib TbKernelLib TbEventLib ROOT)
+
+gaudi_install_python_modules()
+
diff --git a/TbKernel/CMakeLists.txt b/TbKernel/CMakeLists.txt
new file mode 100644
index 0000000..5747f1c
--- /dev/null
+++ b/TbKernel/CMakeLists.txt
@@ -0,0 +1,23 @@
+################################################################################
+# Package: TbKernel
+################################################################################
+gaudi_subdir(TbKernel v3r0)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS GenVector)
+find_package(Boost)
+
+gaudi_add_library(TbKernelLib
+                  src/lib/*.cpp
+                  PUBLIC_HEADERS TbKernel
+                  LINK_LIBRARIES GaudiAlgLib)
+
+gaudi_add_module(TbKernel
+                 src/*.cpp
+                 INCLUDE_DIRS AIDA Boost
+                 LINK_LIBRARIES Boost GaudiAlgLib TbKernelLib TbEventLib ROOT)
+
+gaudi_install_python_modules()
+
diff --git a/TbKernel/TbKernel/.svn/all-wcprops b/TbKernel/TbKernel/.svn/all-wcprops
new file mode 100644
index 0000000..92ba6df
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/all-wcprops
@@ -0,0 +1,89 @@
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/TbKernel
+END
+TbAlignmentTrack.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/197783/Kepler/trunk/Tb/TbKernel/TbKernel/TbAlignmentTrack.h
+END
+TbCondFile.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/TbKernel/TbCondFile.h
+END
+TbFunctors.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197031/Kepler/trunk/Tb/TbKernel/TbKernel/TbFunctors.h
+END
+TbModule.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197056/Kepler/trunk/Tb/TbKernel/TbKernel/TbModule.h
+END
+ITbPixelSvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/196751/Kepler/trunk/Tb/TbKernel/TbKernel/ITbPixelSvc.h
+END
+TbAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/TbKernel/TbAlgorithm.h
+END
+ITbTimingSvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/196561/Kepler/trunk/Tb/TbKernel/TbKernel/ITbTimingSvc.h
+END
+TbConstants.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/187449/Kepler/trunk/Tb/TbKernel/TbKernel/TbConstants.h
+END
+ITbDataSvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/TbKernel/ITbDataSvc.h
+END
+ITbGeometrySvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/196751/Kepler/trunk/Tb/TbKernel/TbKernel/ITbGeometrySvc.h
+END
+ITbTrackFit.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/201499/Kepler/trunk/Tb/TbKernel/TbKernel/ITbTrackFit.h
+END
+TbGeomFunctions.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/197740/Kepler/trunk/Tb/TbKernel/TbKernel/TbGeomFunctions.h
+END
+ITbClusterFinder.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/196561/Kepler/trunk/Tb/TbKernel/TbKernel/ITbClusterFinder.h
+END
+TbBufferedFile.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/198356/Kepler/trunk/Tb/TbKernel/TbKernel/TbBufferedFile.h
+END
diff --git a/TbKernel/TbKernel/.svn/entries b/TbKernel/TbKernel/.svn/entries
new file mode 100644
index 0000000..e45c7a5
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/entries
@@ -0,0 +1,504 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbKernel/TbKernel
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbAlignmentTrack.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+62410a3195d66d10968d5aba7ed09928
+2015-11-19T10:45:50.948321Z
+197783
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1653
+
+TbCondFile.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+eeddb7d59ac6e1d5abe8426a1ebad183
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1839
+
+TbFunctors.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+61fdd303f79172220bd94ab5acc1cf79
+2015-10-30T13:04:31.938042Z
+197031
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2308
+
+TbModule.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+d5c273dc48dbb5984540f72885ff1096
+2015-11-01T07:19:31.695130Z
+197056
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5015
+
+ITbPixelSvc.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+30bd59b92d11c49cce980546fe82c963
+2015-10-24T15:48:48.286246Z
+196751
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1316
+
+TbAlgorithm.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+f234d3d97e69cb958b61badc3ee75c73
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2333
+
+ITbTimingSvc.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+9e038d21c84a0f7e205b7eb3429f24aa
+2015-10-21T16:27:52.865574Z
+196561
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+935
+
+TbConstants.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+dea1384f83f7ced9bea00f28c9d14d5b
+2015-04-28T20:45:47.324195Z
+187449
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+530
+
+ITbDataSvc.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+1e06a9f6ae5ba101fb01ef7fbdb125ba
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+550
+
+ITbGeometrySvc.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+92bb4d9187e1041c73894ec570ac3c90
+2015-10-24T15:48:48.286246Z
+196751
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2662
+
+ITbTrackFit.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+cd10102de712a3cd8737da2a4d4b26a5
+2016-02-14T10:35:31.791066Z
+201499
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+672
+
+TbGeomFunctions.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+7f8beb253ee124648f1e312e85d8bbcf
+2015-11-17T16:46:25.395546Z
+197740
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2360
+
+ITbClusterFinder.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+35c4ed2ac1bd6b358330485229cc37ac
+2015-10-21T16:27:52.865574Z
+196561
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1108
+
+TbBufferedFile.h
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+717a9efa61b65247fe1b423bd4e85dec
+2015-11-27T21:01:44.399604Z
+198356
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3969
+
diff --git a/TbKernel/TbKernel/.svn/prop-base/TbConstants.h.svn-base b/TbKernel/TbKernel/.svn/prop-base/TbConstants.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/prop-base/TbConstants.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbKernel/TbKernel/.svn/prop-base/TbFunctors.h.svn-base b/TbKernel/TbKernel/.svn/prop-base/TbFunctors.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/prop-base/TbFunctors.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbKernel/TbKernel/.svn/text-base/ITbClusterFinder.h.svn-base b/TbKernel/TbKernel/.svn/text-base/ITbClusterFinder.h.svn-base
new file mode 100644
index 0000000..802b1a0
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/ITbClusterFinder.h.svn-base
@@ -0,0 +1,35 @@
+#pragma once
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+/** @class ITbClusterFinder ITbClusterFinder.h
+ *
+ *  Interface for cluster finder tool.
+ *
+ */
+
+static const InterfaceID IID_ITbClusterFinder("ITbClusterFinder", 1, 0);
+
+class ITbClusterFinder : virtual public IAlgTool {
+ public:
+  typedef LHCb::TbClusters::const_iterator Iterator;
+
+  /// Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_ITbClusterFinder; }
+
+  /// Find iterator to first cluster on a given plane above a given time.
+  virtual Iterator getIterator(const double& t, const unsigned int& plane) = 0;
+  /// (Re)set the stored iterators for a given plane.
+  virtual void setClusters(LHCb::TbClusters* clusters,
+                           const unsigned int& plane) = 0;
+  /// Set the search algorithm to be used.
+  virtual void setSearchAlgorithm(const std::string& alg) = 0;
+
+  virtual Iterator first(const unsigned int& plane) const = 0;
+  virtual Iterator end(const unsigned int& plane) const = 0;
+  virtual bool empty(const unsigned int& plane) const = 0;
+};
diff --git a/TbKernel/TbKernel/.svn/text-base/ITbDataSvc.h.svn-base b/TbKernel/TbKernel/.svn/text-base/ITbDataSvc.h.svn-base
new file mode 100644
index 0000000..f149b52
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/ITbDataSvc.h.svn-base
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "GaudiKernel/IService.h"
+
+/** @class ITbDataSvc ITbDataSvc.h
+ *
+ * Interface for accessing raw and configuration data
+ *
+ */
+
+class GAUDI_API ITbDataSvc : virtual public IService {
+ public:
+  DeclareInterfaceID(ITbDataSvc, 1, 0);
+  virtual const std::vector<std::string>& getInputFiles() = 0;
+  virtual const std::vector<std::string>& getPixelConfig() = 0;
+  virtual const std::string& getTimingConfig() = 0;
+  virtual const std::string& getAlignmentFile() = 0;
+  virtual const std::vector<std::string>& getEtaConfig() = 0;
+};
diff --git a/TbKernel/TbKernel/.svn/text-base/ITbGeometrySvc.h.svn-base b/TbKernel/TbKernel/.svn/text-base/ITbGeometrySvc.h.svn-base
new file mode 100644
index 0000000..7ef78be
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/ITbGeometrySvc.h.svn-base
@@ -0,0 +1,72 @@
+#ifndef TBKERNEL_ITBGEOMETRYSVC_H
+#define TBKERNEL_ITBGEOMETRYSVC_H 1
+
+#include "GaudiKernel/IService.h"
+#include "GaudiKernel/Point3DTypes.h"
+#include "GaudiKernel/Vector3DTypes.h"
+
+/** @class ITbGeometrySvc ITbGeometrySvc.h
+ *
+ * Interface for the testbeam geometry service which holds
+ * the geometric transformations between local and global coordinates
+ * of the individual planes.
+ *
+ */
+
+class TbModule;
+namespace LHCb {
+class TbTrack;
+}
+
+class GAUDI_API ITbGeometrySvc : virtual public IService {
+
+ public:
+  /// InterfaceID
+  DeclareInterfaceID(ITbGeometrySvc, 1, 0);
+
+  /// Transform a point in the local frame of a plane to global coordinates
+  virtual Gaudi::XYZPoint localToGlobal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) = 0;
+  /// Transform a point in the global frame to the local frame of a plane
+  virtual Gaudi::XYZPoint globalToLocal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) = 0;
+
+  /// Calculate the local x, y coordinates of a given pixel
+  virtual bool pixelToPoint(const unsigned int scol, const unsigned int row,
+                            const unsigned int plane, double& x,
+                            double& y) = 0;
+  /// Calculate the pixel and inter-pixel position of a given local point
+  virtual bool pointToPixel(const double x, const double y,
+                            const unsigned int plane, unsigned int& scol,
+                            unsigned int& row) = 0;
+
+  /// Calculate the intercept of a track with a telescope plane
+  virtual Gaudi::XYZPoint intercept(const LHCb::TbTrack* t,
+                                    const unsigned int i) = 0;
+
+  virtual Gaudi::XYZPoint intercept(const Gaudi::XYZPoint& p,
+                                    const Gaudi::XYZVector& t,
+                                    const unsigned int i) = 0;
+
+  /// Return a pointer to the module object for a given plane index
+  virtual TbModule* module(const unsigned int i) = 0;
+  /// Return a pointer to the module object of a given plane identifier
+  virtual TbModule* module(const std::string& det) = 0;
+  /// Return the list of modules
+  virtual const std::vector<TbModule*>& modules() = 0;
+
+  virtual unsigned int nDevices() const = 0;
+
+  virtual unsigned int deviceIndex(const std::string& det) = 0;
+
+  virtual unsigned int plane(const std::string& det) = 0;
+
+  virtual bool readConditions(const std::string& file,
+                              std::vector<TbModule*>& modules) = 0;
+
+  virtual void printAlignment(const std::vector<TbModule*>& modules) = 0;
+
+  virtual void setModule(unsigned int i, TbModule* module) = 0;
+};
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/ITbPixelSvc.h.svn-base b/TbKernel/TbKernel/.svn/text-base/ITbPixelSvc.h.svn-base
new file mode 100644
index 0000000..5740fd2
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/ITbPixelSvc.h.svn-base
@@ -0,0 +1,44 @@
+#ifndef TBKERNEL_ITBPIXELSVC_H
+#define TBKERNEL_ITBPIXELSVC_H 1
+
+#include "GaudiKernel/IService.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+/** @class ITbPixelSvc ITbPixelSvc.h
+ *
+ * Interface for pixel by pixel configuration of Timepix3 devices
+ *
+ */
+
+class GAUDI_API ITbPixelSvc : virtual public IService {
+ public:
+  /// InterfaceID
+  DeclareInterfaceID(ITbPixelSvc, 1, 0);
+
+  /// Get the pixel address for a given column and row.
+  virtual unsigned int address(const unsigned int col,
+                               const unsigned int row) const = 0;
+
+  /// Return whether the pixel has been masked.
+  virtual bool isMasked(const unsigned int address,
+                        const unsigned int device) const = 0;
+
+  /// Correct the timestamp of a given hit.
+  virtual void applyPhaseCorrection(LHCb::TbHit* hit) = 0;
+
+  /// Set the clock phase correction.
+  virtual void setPhase(const unsigned int device,
+                        const unsigned int pll_config,
+                        const int amplitude = 1) = 0;
+
+  /// Set the trim DACs.
+  virtual void setTrim(const unsigned int device, const char* data) = 0;
+
+  /// Convert time-over-threshold to charge.
+  virtual double charge(const unsigned int tot, const unsigned int address,
+                        const unsigned int device) const = 0;
+};
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/ITbTimingSvc.h.svn-base b/TbKernel/TbKernel/.svn/text-base/ITbTimingSvc.h.svn-base
new file mode 100644
index 0000000..a68c189
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/ITbTimingSvc.h.svn-base
@@ -0,0 +1,33 @@
+#ifndef TBKERNEL_ITBTIMINGSVC_H
+#define TBKERNEL_ITBTIMINGSVC_H 1
+
+#include "GaudiKernel/IService.h"
+
+/** @class ITbTimingSvc ITbTimingSvc.h
+ *
+ * Interface for the testbeam timing service.
+ *
+ */
+
+class GAUDI_API ITbTimingSvc : virtual public IService {
+
+ public:
+  /// InterfaceID
+  DeclareInterfaceID(ITbTimingSvc, 1, 0);
+
+  virtual uint64_t localToGlobal(const double& htime) = 0;
+  virtual double globalToLocal(const uint64_t& time) = 0;
+
+  virtual void setEventDefinition(const uint64_t& evtMinTime,
+                                  const uint64_t& evtMaxTime) = 0;
+  virtual void eventDefinition(uint64_t& evtMinTime,
+                               uint64_t& evtMaxTime) const = 0;
+
+  virtual void setOverlap(const uint64_t& overlap) = 0;
+
+  virtual bool inEvent(const uint64_t& time) const = 0;
+  virtual bool inOverlap(const uint64_t& time) const = 0;
+  virtual bool beforeOverlap(const uint64_t& time) const = 0;
+};
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/ITbTrackFit.h.svn-base b/TbKernel/TbKernel/.svn/text-base/ITbTrackFit.h.svn-base
new file mode 100644
index 0000000..8c6b533
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/ITbTrackFit.h.svn-base
@@ -0,0 +1,29 @@
+#ifndef TBKERNEL_ITBTRACKFIT_H
+#define TBKERNEL_ITBTRACKFIT_H 1
+
+#include "GaudiKernel/IAlgTool.h"
+
+#include "Event/TbTrack.h"
+
+static const InterfaceID IID_ITbTrackFit("ITbTrackFit", 1, 0);
+
+/** @class ITbTrackFit ITbTrackFit.h
+ *
+ *  Interface for track fit tools
+ *
+ */
+
+class ITbTrackFit : virtual public IAlgTool {
+
+ public:
+  /// Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_ITbTrackFit; }
+
+  virtual void fit(LHCb::TbTrack* track) = 0;
+
+  /// Exclude a plane from the fit.
+  virtual void maskPlane(const unsigned int plane) = 0;
+  /// Include a plane in the fit.
+  virtual void unmaskPlane(const unsigned int plane) = 0;
+};
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/TbAlgorithm.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbAlgorithm.h.svn-base
new file mode 100644
index 0000000..a4003eb
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbAlgorithm.h.svn-base
@@ -0,0 +1,77 @@
+#ifndef TB_ALGORITHM_H
+#define TB_ALGORITHM_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTupleAlg.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/ITbTimingSvc.h"
+#include "TbKernel/ITbPixelSvc.h"
+#include "TbKernel/ITbDataSvc.h"
+
+/** @class TbAlgorithm TbAlgorithm.h
+ *
+ *  Base class for testbeam algorithms.
+ *
+ */
+
+class TbAlgorithm : public GaudiTupleAlg {
+ public:
+  /// Standard constructor
+  TbAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbAlgorithm();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+
+ protected:
+  /// Number of telescope planes
+  unsigned int m_nPlanes = 0;
+  /// Number of chips, counting chips in planes with multiple chips
+  unsigned int m_nDevices = 0;
+  /// Flag to print out algorithm properties during initialization.
+  bool m_printConfiguration = false;
+  /// Indices of planes to be masked.
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc = nullptr;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+  /// Pointer to pixel service
+  mutable ITbPixelSvc* m_pixelSvc = nullptr;
+  /// Access pixel service on-demand.
+  ITbPixelSvc* pixelSvc() const {
+    if (!m_pixelSvc) m_pixelSvc = svc<ITbPixelSvc>("TbPixelSvc", true);
+    return m_pixelSvc;
+  }
+  /// Pointer to timing service
+  mutable ITbTimingSvc* m_timingSvc = nullptr;
+  /// Access timing service on-demand.
+  ITbTimingSvc* timingSvc() const {
+    if (!m_timingSvc) m_timingSvc = svc<ITbTimingSvc>("TbTimingSvc", true);
+    return m_timingSvc;
+  }
+  /// Pointer to data service
+  mutable ITbDataSvc* m_dataSvc = nullptr;
+  /// Access data service on-demand.
+  ITbDataSvc* dataSvc() const {
+    if (!m_dataSvc) m_dataSvc = svc<ITbDataSvc>("TbDataSvc", true);
+    return m_dataSvc;
+  }
+
+  /// Retrieve the masked flag for a given plane.
+  bool masked(const unsigned int plane) const {
+    return plane < m_masked.size() ? m_masked[plane] : false;
+  }
+};
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/TbAlignmentTrack.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbAlignmentTrack.h.svn-base
new file mode 100644
index 0000000..aabd1d4
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbAlignmentTrack.h.svn-base
@@ -0,0 +1,58 @@
+#ifndef TBKERNEL_TBALIGNMENTTRACK_H
+#define TBKERNEL_TBALIGNMENTTRACK_H 1
+
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+/** @class TbAlignmentTrack TbAlignmentTrack.h TbKernel/TbAlignmentTrack.h
+ *
+ *
+ *  @author Angelo Di Canto
+ *  @date   2014-05-09
+ */
+
+class TbAlignmentTrack {
+ public:
+  /// Standard constructor
+  TbAlignmentTrack(LHCb::TbTrack *t) : 
+      m_track(nullptr), m_xref(0.), m_yref(0.) {
+    // Clone track without the clusters.
+    m_track = t->clone();
+    // Clone each cluster on the track.
+    SmartRefVector<LHCb::TbCluster> clusters = t->clusters();
+    for (auto it = clusters.begin(), end = clusters.end(); it != end; ++it) {
+      LHCb::TbCluster *c = (*it)->clone();
+      m_track->addToClusters(c);
+      m_clusters.push_back(c);
+    }
+  }
+
+  /// Destructor
+  virtual ~TbAlignmentTrack() {
+    if (m_track) delete m_track;
+    // Delete the associated clusters.
+    for (auto it = m_clusters.begin(); it != m_clusters.end(); ++it) {
+      if (*it) delete *it;
+    }
+    m_clusters.clear();
+  }
+
+  /// Setters
+  void setXOnReferencePlane(const double x) { m_xref = x; }
+  void setYOnReferencePlane(const double y) { m_yref = y; }
+  void addToClusters(LHCb::TbCluster *c) { m_clusters.push_back(c); }
+
+  /// Accessors
+  LHCb::TbTrack *track() const { return m_track; }
+  double xOnReferencePlane() const { return m_xref; }
+  double yOnReferencePlane() const { return m_yref; }
+  const std::vector<LHCb::TbCluster *> &clusters() { return m_clusters; }
+
+ protected:
+  LHCb::TbTrack *m_track;
+  double m_xref;
+  double m_yref;
+  std::vector<LHCb::TbCluster *> m_clusters;
+};
+
+#endif  // TBKERNEL_TBALIGNMENTTRACK_H
diff --git a/TbKernel/TbKernel/.svn/text-base/TbBufferedFile.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbBufferedFile.h.svn-base
new file mode 100644
index 0000000..24c2e2e
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbBufferedFile.h.svn-base
@@ -0,0 +1,139 @@
+#include <iostream>
+
+// ROOT
+#include "TFile.h"
+
+/* @class TbBufferedFile TbBufferedFile.h
+ *
+ * Generic buffered interface to ROOT IO for use of IO plugins
+ *
+ */
+
+// BUFFERSIZE is the number of objects that can be buffered
+template <unsigned int BUFFERSIZE, class TYPE>
+class TbBufferedFile {
+
+ public:
+  /// Constructor
+  TbBufferedFile(const std::string& filename, bool init = true)
+      : m_file(TFile::Open((filename + "?filetype=raw").c_str())),
+        m_bytesRead(0),
+        m_filename(filename),
+        m_buffer_size(BUFFERSIZE * sizeof(TYPE)),
+        m_buffer_pos(BUFFERSIZE),
+        m_init(false) {
+    if (is_open()) {
+      m_bytes = m_file->GetSize();
+      if (init) initialise();
+    } else {
+      std::cout << "File opening failed - waiting 5s then reconnecting"
+                << std::endl;
+      sleep(5);
+      m_file = TFile::Open((filename + "?filetype=raw").c_str());
+      if (is_open()) {
+        m_bytes = m_file->GetSize();
+        if (init) initialise();
+      } else {
+        std::cerr << "Cannot open file: " << filename << " critical error!"
+                  << std::endl;
+      }
+    }
+  }
+  /// Destructor
+  ~TbBufferedFile() { close(); }
+
+  // sets the offset in the file and loads the corresponding buffer (IN BYTES )
+  void setOffset(const uint64_t pos) {
+    if (pos < m_bytesRead && pos > m_bytesRead - m_buffer_size) {
+      m_buffer_pos = (pos - (m_bytesRead - m_buffer_size)) / sizeof(TYPE);
+      return;
+    }
+    if (pos > m_bytes) {
+      std::cout << "Attempted to read outside of file, offsetting cancelled"
+                << std::endl;
+      return;
+    }
+    m_file->SetOffset(pos, TFile::ERelativeTo::kBeg);
+    m_buffer_size = (m_bytesRead + BUFFERSIZE * sizeof(TYPE) > m_bytes)
+                        ? m_bytes - m_bytesRead
+                        : m_buffer_size;
+    m_file->ReadBuffer((char*)m_buffer, m_buffer_size);
+    m_buffer_pos = 0;
+    m_bytesRead = pos + m_buffer_size;
+  }
+
+  TYPE getNext() {
+
+    if (__builtin_expect(m_buffer_pos * sizeof(TYPE) == m_buffer_size, 0)) {
+      m_buffer_size = (m_bytesRead + BUFFERSIZE * sizeof(TYPE) > m_bytes)
+                          ? m_bytes - m_bytesRead
+                          : m_buffer_size;
+      if (m_file->ReadBuffer((char*)m_buffer, m_buffer_size)) {
+        /// this is to give additional protection in case of network timeouts
+        std::cout << "Reading the buffer of " << m_filename
+                  << " failed. Waiting for 5s" << std::endl;
+        sleep(5);
+        m_file->SetOffset(-m_buffer_size, TFile::ERelativeTo::kCur);
+        if (m_file->ReadBuffer((char*)m_buffer, m_buffer_size)) {
+          std::cout << "Reading the buffer failed again, closing file"
+                    << std::endl;
+          m_bytesRead = m_bytes;
+          m_buffer_pos = m_buffer_size / sizeof(TYPE);
+          return TYPE();
+        }
+      }
+      m_bytesRead = m_bytesRead + m_buffer_size;
+      m_buffer_pos = 0;
+    }
+    return m_buffer[m_buffer_pos++];
+  }
+  TYPE getPrevious() {
+    if (m_buffer_pos > 0) {
+      m_buffer_pos -= 1;
+      return m_buffer[m_buffer_pos];
+    } 
+    return TYPE();
+  }
+  bool eof() const {
+    return (m_bytesRead == m_bytes) &&
+           (m_buffer_pos * sizeof(TYPE) == m_buffer_size);
+  }
+  void close() {
+    if (m_init) {
+      delete[] m_buffer;
+      m_init = false;
+    }
+    if (is_open()) m_file->Close();
+  }
+
+  void reset() {
+    if (m_init) {
+      delete[] m_buffer;
+      m_init = false;
+    }
+    m_bytesRead = 0;
+    m_buffer_size = BUFFERSIZE * sizeof(TYPE);
+    m_buffer_pos = BUFFERSIZE;
+  }
+  bool is_open() const { return m_file != 0 && m_file->IsOpen(); }
+
+  void initialise() {
+    if (!m_init) {
+      m_buffer = new TYPE[BUFFERSIZE];
+      m_init = true;
+    }
+  }
+
+ protected:
+  TFile* m_file;
+  uint64_t m_bytesRead;
+  std::string m_filename;
+
+ private:
+  uint64_t m_buffer_size;
+  uint64_t m_buffer_pos;
+  uint64_t m_bytes;
+  TYPE* m_buffer;
+  bool m_failure;
+  bool m_init;
+};
diff --git a/TbKernel/TbKernel/.svn/text-base/TbCondFile.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbCondFile.h.svn-base
new file mode 100644
index 0000000..13f2af9
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbCondFile.h.svn-base
@@ -0,0 +1,67 @@
+#ifndef TBCONDFILE_H
+#define TBCONDFILE_H
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+#include "TbKernel/TbBufferedFile.h"
+
+/* @class TbCondFile TbCondFile.h
+ *
+ * Interface classes for dealing with conditions files,
+ * both locally and via more general TbBufferedFiles
+ *
+ */
+
+class TbCondFile : public TbBufferedFile<100000, char> {
+ public:
+  /// Constructor
+  TbCondFile(const std::string& filename) : TbBufferedFile(filename) {}
+
+  bool split(std::stringstream& ss, const char delim) {
+    std::string item;
+    std::getline(ss, item, delim);
+    return item.empty();
+  }
+
+  bool getLine(std::string& line) {
+    line = "";
+    char tmp('a');
+    while (tmp != '\n' && !TbBufferedFile::eof()) {
+      tmp = getNext();
+      if (tmp != '\n') line += tmp;
+    }
+    const size_t p = line.find_first_not_of(' ');
+    return (line.empty() || line[0] == '#' || p == std::string::npos) ? false
+                                                                      : true;
+  }
+
+  template <typename Type>
+  Type custom_cast(const std::string& ref);
+  template <typename Type, typename... Types>
+  bool split(std::stringstream& ss, const char delim, Type& val,
+             Types&... rest);
+  template <typename... Types>
+  bool split(const std::string& s, const char delim, Types&... rest);
+};
+
+template <typename... Types>
+bool TbCondFile::split(const std::string& s, const char delim, Types&... rest) {
+  std::stringstream ss(s);
+  return split(ss, delim, rest...);
+}
+
+template <typename Type, typename... Types>
+bool TbCondFile::split(std::stringstream& ss, const char delim, Type& val,
+                       Types&... rest) {
+  std::string item;
+  while (std::getline(ss, item, delim)) {
+    if (item == "") continue;
+    val = custom_cast<Type>(item);
+    return split(ss, delim, rest...);
+  }
+  return true;
+}
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/TbConstants.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbConstants.h.svn-base
new file mode 100644
index 0000000..4e5a3b2
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbConstants.h.svn-base
@@ -0,0 +1,22 @@
+#ifndef TB_CONSTANTS_H
+#define TB_CONSTANTS_H 1
+
+namespace Tb {
+
+// Time units
+static const uint64_t ToA = 4096;
+static const uint64_t SpidrTime = 16384 * ToA;
+
+static const double nanosecond = ToA / 25.;
+static const uint64_t millisecond = 40000 * ToA;
+static const uint64_t second = 1000 * millisecond;
+static const uint64_t minute = 60 * second;
+
+static const unsigned int NRows = 256;
+static const unsigned int NCols = 256;
+static const unsigned int NPixels = NRows * NCols;
+
+static const double PixelPitch = 0.055;
+}
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/TbFunctors.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbFunctors.h.svn-base
new file mode 100644
index 0000000..c0e1aa3
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbFunctors.h.svn-base
@@ -0,0 +1,81 @@
+#ifndef TB_FUNCTORS_H
+#define TB_FUNCTORS_H 1
+
+#include <functional>
+#include <numeric>
+#define USE_BRANCH_PREDICTION 1
+
+#if USE_BRANCH_PREDICTION
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+#else
+#define likely(x) x
+#define unlikely(x) x
+#endif
+
+namespace TbFunctors {
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class LessByTime : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the time stamps of two objects
+   *  @param o1   first object
+   *  @param o2   second object
+   *  @return  result of the comparison
+   */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return !o1 ? true : !o2 ? false : o1->time() < o2->time();
+  }
+};
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class LessByTimeBP : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the time stamps of two objects
+  *  @param o1   first object
+  *  @param o2   second object
+  *  @return  result of the comparison
+  *  Uses branch prediction for faster sorts in partially sorted data
+  */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return unlikely(!o1) ? true : unlikely(!o2)
+                                      ? false
+                                      : likely(o1->time() < o2->time());
+  }
+};
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class GreaterByToT : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the ADC values of two objects
+   *  @param o1   first object
+   *  @param o2   second object
+   *  @return  result of the comparison
+   */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return (!o2) ? true : (!o1) ? false : o1->ToT() > o2->ToT();
+  }
+};
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class LessByZ : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the z-coordinates of two objects
+   *  @param o1   first object
+   *  @param o2   second object
+   *  @return  result of the comparison
+   */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return (!o1) ? true : (!o2) ? false : o1->z() < o2->z();
+  }
+};
+}
+
+template <class TYPE>
+class lowerBound {
+ public:
+  bool operator()(TYPE lhs, const double t) const { return lhs->htime() < t; }
+  bool operator()(const double t, TYPE rhs) const { return t < rhs->htime(); }
+};
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/TbGeomFunctions.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbGeomFunctions.h.svn-base
new file mode 100644
index 0000000..d59bea8
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbGeomFunctions.h.svn-base
@@ -0,0 +1,63 @@
+#ifndef TB_GEOMFUNC
+#define TB_GEOMFUNC 1
+
+namespace Tb {
+/*
+inline static void getTaitBryanAngles(const ROOT::Math::Quaternion& Q, double& alpha,
+                               double& beta, double& gamma) {
+
+  double a, b, c, d;
+  Q.GetComponents(a, b, c, d);
+  alpha = atan2(-2 * (c * d - a * b), a * a - b * b - c * c + d * d);
+  beta = atan2(
+      -2 * (b * d + c * a),
+      sqrt(4 * (a * b - c * d) * (a * b - c * d) +
+           (a * a - b * b - c * c + d * d) * (a * a - b * b - c * c + d * d)));
+  gamma = atan2(-2 * (b * c - d * a), a * a + b * b - c * c - d * d);
+}
+
+inline static ROOT::Math::Quaternion getQuaternionRepresentation(
+    const ROOT::Math::Rotation3D& rot) {
+
+  double xx, xy, xz, yx, yy, yz, zx, zy, zz;
+  rot.GetComponents(xx, yx, zx, xy, yy, zy, xz, yz, zz);
+
+  const double a = 0.5 * sqrt(1 + xx + yy + zz);
+  const double b = (0.25 / a) * (yz - zy);
+  const double c = (0.25 / a) * (zx - xz);
+  const double d = (0.25 / a) * (xy - yx);
+
+  std::cout << "============= TAIT-BRYAN REPRESENTATION ===============" <<
+  std::endl;
+  std::cout << xx << "  " << yx << "  " << zx << std::endl;
+  std::cout << xy << "  " << yy << "  " << zy << std::endl;
+  std::cout << xz << "  " << yz << "  " << zz << std::endl;
+  std::cout << "=======================================================" <<
+  std::endl;
+  std::cout << a << ", " << b << ", " << c << ", " << d << std::endl;
+
+  std::cout << "============= HAMILTONIAN REPRESENTATION ==============" <<
+  std::endl;
+  std::cout << "| " << a*a + b*b - c*c - d*d << "  " << 2*(b*c - a*d) << "   "
+  << 2*(b*d + a*c) << " |" << std::endl;
+  std::cout << "| " << 2*(b*c + d*a) << "  " << 1 - 2*(b*b + d*d ) << "   " <<
+  2*(c*d - a*b ) << " |" << std::endl;
+  std::cout << "| " << 2*(b*d - c*a) << "  " << 2*(a*b + c*d ) << "   " << a*a -
+  b*b - c*c + d*d << " |" << std::endl;
+  std::cout << "=======================================================" <<
+  std::endl;
+
+  ROOT::Math::Quaternion Q(a, b, c, d);
+  return Q;
+}
+*/
+static void SmallRotation(const double& x0, const double& dx0, const double& y0,
+                          const double& dy0, const double& dz0, double& xr,
+                          double& yr, double& zr) {
+  xr = dx0 + tan(y0) * (dz0 * cos(x0) + dy0 * cos(x0));
+  yr = dy0 * cos(x0) + dz0 * sin(x0);
+  zr = (-cos(x0) * dz0 + sin(x0) * dy0) / cos(y0);
+}
+}
+
+#endif
diff --git a/TbKernel/TbKernel/.svn/text-base/TbModule.h.svn-base b/TbKernel/TbKernel/.svn/text-base/TbModule.h.svn-base
new file mode 100644
index 0000000..5d2a50b
--- /dev/null
+++ b/TbKernel/TbKernel/.svn/text-base/TbModule.h.svn-base
@@ -0,0 +1,167 @@
+#ifndef TB_MODULE_H
+#define TB_MODULE_H 1
+
+#include "GaudiKernel/Point3DTypes.h"
+#include "GaudiKernel/Vector3DTypes.h"
+#include "GaudiKernel/Transform3DTypes.h"
+#include "Math/Translation3D.h"
+#include "Math/RotationZYX.h"
+#include "TbKernel/TbConstants.h"
+#include "TMatrixD.h"
+#include "TMatrixDEigen.h"
+#include "TVectorD.h"
+
+struct TbChip {
+  TbChip(const std::string& _id, const unsigned int& _col,
+         const unsigned int& _num)
+      : col(_col), num(_num), id(_id) {};
+
+  unsigned int col;
+  unsigned int num;
+  std::string id;
+};
+
+class TbModule {
+
+ public:
+  /// Module types
+  enum Type {
+    Tpx3,        ///< Tpx3 single chip assembly
+    Tpx3Triple,  ///< Tpx3 3x1 tile
+    UT           ///< UT sensor
+  };
+
+  /// Constructor
+  TbModule() : m_chips(), m_centre(), m_normal() {}
+
+  /// Destructor
+  virtual ~TbModule() {
+    if (m_transform) delete m_transform;
+    if (m_inverse) delete m_inverse;
+  }
+
+  /// Return the module type.
+  TbModule::Type type() const { return m_type; }
+  /// Set the module type.
+  void setType(const TbModule::Type& type) { m_type = type; }
+
+  /// Return the module ID.
+  std::string id() const { return m_id; }
+  /// Set the module ID.
+  void setId(const std::string& id) { m_id = id; }
+  /// Return the chip ID (for modules with multiple chips).
+  std::string id(const unsigned int index) { return m_chips[index].id; }
+
+  /// Set the nominal position and orientation and the misalignment.
+  void setAlignment(const double x, const double y, const double z,
+                    const double rx, const double ry, const double rz,
+                    const double dx, const double dy, const double dz,
+                    const double drx, const double dry, const double drz) {
+    m_x = x;
+    m_y = y;
+    m_z = z;
+    m_rx = rx;
+    m_ry = ry;
+    m_rz = rz;
+    m_dx = dx;
+    m_dy = dy;
+    m_dz = dz;
+    m_drx = drx;
+    m_dry = dry;
+    m_drz = drz;
+    setTransform();
+  }
+  /// Set the misalignment.
+  void setAlignment(const double dx, const double dy, const double dz,
+                    const double drx, const double dry, const double drz) {
+    m_dx = dx;
+    m_dy = dy;
+    m_dz = dz;
+    m_drx = drx;
+    m_dry = dry;
+    m_drz = drz;
+    setTransform();
+  }
+  /// Return the centre position of the module.
+  const Gaudi::XYZPoint& centre() { return m_centre; }
+  /// Return the normal vector to the module plane.
+  const Gaudi::XYZVector& normal() { return m_normal; }
+  /// Return the transformation matrix from local to global coordinates.
+  Gaudi::Transform3D transform() { return *m_transform; }
+  /// Return the transformation matrix from global to local coordinates.
+  Gaudi::Transform3D inverse() { return *m_inverse; }
+
+  unsigned int nChips() const { return m_chips.size(); }
+
+  void addChip(const std::string& id) {
+    m_chips.push_back(TbChip(id, nChips() * Tb::NCols, nChips()));
+  }
+  unsigned int cols() const {
+    return m_type == TbModule::Tpx3Triple ? 3 * Tb::NCols : Tb::NCols;
+  }
+
+  const std::vector<TbChip>& chips() const { return m_chips; }
+
+  double x() const { return m_x; }
+  double y() const { return m_y; }
+  double z() const { return m_z; }
+  double rotX() const { return m_rx; }
+  double rotY() const { return m_ry; }
+  double rotZ() const { return m_rz; }
+  double dX() const { return m_dx; }
+  double dY() const { return m_dy; }
+  double dZ() const { return m_dz; }
+  double dRotX() const { return m_drx; }
+  double dRotY() const { return m_dry; }
+  double dRotZ() const { return m_drz; }
+
+  void setTransform() {
+    ROOT::Math::Translation3D t(m_x + m_dx, m_y + m_dy, m_z + m_dz);
+    ROOT::Math::RotationZYX r(m_rz + m_drz, m_ry + m_dry, m_rx + m_drx);
+    if (m_transform) delete m_transform;
+    if (m_inverse) delete m_inverse;
+
+    m_transform = new Gaudi::Transform3D(r, t);
+    m_inverse = new Gaudi::Transform3D(m_transform->Inverse());
+    // Calculate the coordinates of the module centre in the global frame.
+    m_centre = transform() * Gaudi::XYZPoint(0., 0., 0.);
+    // Calculate the normal vector in the global frame.
+    Gaudi::XYZPoint p = transform() * Gaudi::XYZPoint(0., 0., 1.);
+    m_normal = p - m_centre;
+  }
+
+ private:
+  /// Module type
+  TbModule::Type m_type = TbModule::Tpx3;
+  /// Chips constituting the module
+  std::vector<TbChip> m_chips;
+  /// Nominal positions and rotations
+  double m_x = 0.;
+  double m_y = 0.;
+  double m_z = 0.;
+  double m_rx = 0.;
+  double m_ry = 0.;
+  double m_rz = 0.;
+  /// Alignment
+  double m_dx = 0.;
+  double m_dy = 0.;
+  double m_dz = 0.;
+  double m_drx = 0.;
+  double m_dry = 0.;
+  double m_drz = 0.;
+  /// Module identifier
+  std::string m_id = "";
+  /// Centre position
+  Gaudi::XYZPoint m_centre;
+  /// Normal vector to the module plane
+  Gaudi::XYZVector m_normal;
+
+  /// Transformation matrix from local to global coordinates.
+  Gaudi::Transform3D* m_transform = NULL;
+  /// Transformation matrix from global to local coordinates.
+  Gaudi::Transform3D* m_inverse = NULL;
+
+  /// Calculate the transformation matrix and its inverse.
+};
+
+#endif
diff --git a/TbKernel/TbKernel/ITbClusterFinder.h b/TbKernel/TbKernel/ITbClusterFinder.h
new file mode 100644
index 0000000..802b1a0
--- /dev/null
+++ b/TbKernel/TbKernel/ITbClusterFinder.h
@@ -0,0 +1,35 @@
+#pragma once
+
+// Gaudi
+#include "GaudiKernel/IAlgTool.h"
+
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+
+/** @class ITbClusterFinder ITbClusterFinder.h
+ *
+ *  Interface for cluster finder tool.
+ *
+ */
+
+static const InterfaceID IID_ITbClusterFinder("ITbClusterFinder", 1, 0);
+
+class ITbClusterFinder : virtual public IAlgTool {
+ public:
+  typedef LHCb::TbClusters::const_iterator Iterator;
+
+  /// Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_ITbClusterFinder; }
+
+  /// Find iterator to first cluster on a given plane above a given time.
+  virtual Iterator getIterator(const double& t, const unsigned int& plane) = 0;
+  /// (Re)set the stored iterators for a given plane.
+  virtual void setClusters(LHCb::TbClusters* clusters,
+                           const unsigned int& plane) = 0;
+  /// Set the search algorithm to be used.
+  virtual void setSearchAlgorithm(const std::string& alg) = 0;
+
+  virtual Iterator first(const unsigned int& plane) const = 0;
+  virtual Iterator end(const unsigned int& plane) const = 0;
+  virtual bool empty(const unsigned int& plane) const = 0;
+};
diff --git a/TbKernel/TbKernel/ITbDataSvc.h b/TbKernel/TbKernel/ITbDataSvc.h
new file mode 100644
index 0000000..f149b52
--- /dev/null
+++ b/TbKernel/TbKernel/ITbDataSvc.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include "GaudiKernel/IService.h"
+
+/** @class ITbDataSvc ITbDataSvc.h
+ *
+ * Interface for accessing raw and configuration data
+ *
+ */
+
+class GAUDI_API ITbDataSvc : virtual public IService {
+ public:
+  DeclareInterfaceID(ITbDataSvc, 1, 0);
+  virtual const std::vector<std::string>& getInputFiles() = 0;
+  virtual const std::vector<std::string>& getPixelConfig() = 0;
+  virtual const std::string& getTimingConfig() = 0;
+  virtual const std::string& getAlignmentFile() = 0;
+  virtual const std::vector<std::string>& getEtaConfig() = 0;
+};
diff --git a/TbKernel/TbKernel/ITbGeometrySvc.h b/TbKernel/TbKernel/ITbGeometrySvc.h
new file mode 100644
index 0000000..7ef78be
--- /dev/null
+++ b/TbKernel/TbKernel/ITbGeometrySvc.h
@@ -0,0 +1,72 @@
+#ifndef TBKERNEL_ITBGEOMETRYSVC_H
+#define TBKERNEL_ITBGEOMETRYSVC_H 1
+
+#include "GaudiKernel/IService.h"
+#include "GaudiKernel/Point3DTypes.h"
+#include "GaudiKernel/Vector3DTypes.h"
+
+/** @class ITbGeometrySvc ITbGeometrySvc.h
+ *
+ * Interface for the testbeam geometry service which holds
+ * the geometric transformations between local and global coordinates
+ * of the individual planes.
+ *
+ */
+
+class TbModule;
+namespace LHCb {
+class TbTrack;
+}
+
+class GAUDI_API ITbGeometrySvc : virtual public IService {
+
+ public:
+  /// InterfaceID
+  DeclareInterfaceID(ITbGeometrySvc, 1, 0);
+
+  /// Transform a point in the local frame of a plane to global coordinates
+  virtual Gaudi::XYZPoint localToGlobal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) = 0;
+  /// Transform a point in the global frame to the local frame of a plane
+  virtual Gaudi::XYZPoint globalToLocal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) = 0;
+
+  /// Calculate the local x, y coordinates of a given pixel
+  virtual bool pixelToPoint(const unsigned int scol, const unsigned int row,
+                            const unsigned int plane, double& x,
+                            double& y) = 0;
+  /// Calculate the pixel and inter-pixel position of a given local point
+  virtual bool pointToPixel(const double x, const double y,
+                            const unsigned int plane, unsigned int& scol,
+                            unsigned int& row) = 0;
+
+  /// Calculate the intercept of a track with a telescope plane
+  virtual Gaudi::XYZPoint intercept(const LHCb::TbTrack* t,
+                                    const unsigned int i) = 0;
+
+  virtual Gaudi::XYZPoint intercept(const Gaudi::XYZPoint& p,
+                                    const Gaudi::XYZVector& t,
+                                    const unsigned int i) = 0;
+
+  /// Return a pointer to the module object for a given plane index
+  virtual TbModule* module(const unsigned int i) = 0;
+  /// Return a pointer to the module object of a given plane identifier
+  virtual TbModule* module(const std::string& det) = 0;
+  /// Return the list of modules
+  virtual const std::vector<TbModule*>& modules() = 0;
+
+  virtual unsigned int nDevices() const = 0;
+
+  virtual unsigned int deviceIndex(const std::string& det) = 0;
+
+  virtual unsigned int plane(const std::string& det) = 0;
+
+  virtual bool readConditions(const std::string& file,
+                              std::vector<TbModule*>& modules) = 0;
+
+  virtual void printAlignment(const std::vector<TbModule*>& modules) = 0;
+
+  virtual void setModule(unsigned int i, TbModule* module) = 0;
+};
+
+#endif
diff --git a/TbKernel/TbKernel/ITbPixelSvc.h b/TbKernel/TbKernel/ITbPixelSvc.h
new file mode 100644
index 0000000..5740fd2
--- /dev/null
+++ b/TbKernel/TbKernel/ITbPixelSvc.h
@@ -0,0 +1,44 @@
+#ifndef TBKERNEL_ITBPIXELSVC_H
+#define TBKERNEL_ITBPIXELSVC_H 1
+
+#include "GaudiKernel/IService.h"
+
+// Tb/TbEvent
+#include "Event/TbHit.h"
+
+/** @class ITbPixelSvc ITbPixelSvc.h
+ *
+ * Interface for pixel by pixel configuration of Timepix3 devices
+ *
+ */
+
+class GAUDI_API ITbPixelSvc : virtual public IService {
+ public:
+  /// InterfaceID
+  DeclareInterfaceID(ITbPixelSvc, 1, 0);
+
+  /// Get the pixel address for a given column and row.
+  virtual unsigned int address(const unsigned int col,
+                               const unsigned int row) const = 0;
+
+  /// Return whether the pixel has been masked.
+  virtual bool isMasked(const unsigned int address,
+                        const unsigned int device) const = 0;
+
+  /// Correct the timestamp of a given hit.
+  virtual void applyPhaseCorrection(LHCb::TbHit* hit) = 0;
+
+  /// Set the clock phase correction.
+  virtual void setPhase(const unsigned int device,
+                        const unsigned int pll_config,
+                        const int amplitude = 1) = 0;
+
+  /// Set the trim DACs.
+  virtual void setTrim(const unsigned int device, const char* data) = 0;
+
+  /// Convert time-over-threshold to charge.
+  virtual double charge(const unsigned int tot, const unsigned int address,
+                        const unsigned int device) const = 0;
+};
+
+#endif
diff --git a/TbKernel/TbKernel/ITbTimingSvc.h b/TbKernel/TbKernel/ITbTimingSvc.h
new file mode 100644
index 0000000..a68c189
--- /dev/null
+++ b/TbKernel/TbKernel/ITbTimingSvc.h
@@ -0,0 +1,33 @@
+#ifndef TBKERNEL_ITBTIMINGSVC_H
+#define TBKERNEL_ITBTIMINGSVC_H 1
+
+#include "GaudiKernel/IService.h"
+
+/** @class ITbTimingSvc ITbTimingSvc.h
+ *
+ * Interface for the testbeam timing service.
+ *
+ */
+
+class GAUDI_API ITbTimingSvc : virtual public IService {
+
+ public:
+  /// InterfaceID
+  DeclareInterfaceID(ITbTimingSvc, 1, 0);
+
+  virtual uint64_t localToGlobal(const double& htime) = 0;
+  virtual double globalToLocal(const uint64_t& time) = 0;
+
+  virtual void setEventDefinition(const uint64_t& evtMinTime,
+                                  const uint64_t& evtMaxTime) = 0;
+  virtual void eventDefinition(uint64_t& evtMinTime,
+                               uint64_t& evtMaxTime) const = 0;
+
+  virtual void setOverlap(const uint64_t& overlap) = 0;
+
+  virtual bool inEvent(const uint64_t& time) const = 0;
+  virtual bool inOverlap(const uint64_t& time) const = 0;
+  virtual bool beforeOverlap(const uint64_t& time) const = 0;
+};
+
+#endif
diff --git a/TbKernel/TbKernel/ITbTrackFit.h b/TbKernel/TbKernel/ITbTrackFit.h
new file mode 100644
index 0000000..8c6b533
--- /dev/null
+++ b/TbKernel/TbKernel/ITbTrackFit.h
@@ -0,0 +1,29 @@
+#ifndef TBKERNEL_ITBTRACKFIT_H
+#define TBKERNEL_ITBTRACKFIT_H 1
+
+#include "GaudiKernel/IAlgTool.h"
+
+#include "Event/TbTrack.h"
+
+static const InterfaceID IID_ITbTrackFit("ITbTrackFit", 1, 0);
+
+/** @class ITbTrackFit ITbTrackFit.h
+ *
+ *  Interface for track fit tools
+ *
+ */
+
+class ITbTrackFit : virtual public IAlgTool {
+
+ public:
+  /// Return the interface ID
+  static const InterfaceID& interfaceID() { return IID_ITbTrackFit; }
+
+  virtual void fit(LHCb::TbTrack* track) = 0;
+
+  /// Exclude a plane from the fit.
+  virtual void maskPlane(const unsigned int plane) = 0;
+  /// Include a plane in the fit.
+  virtual void unmaskPlane(const unsigned int plane) = 0;
+};
+#endif
diff --git a/TbKernel/TbKernel/TbAlgorithm.h b/TbKernel/TbKernel/TbAlgorithm.h
new file mode 100644
index 0000000..a4003eb
--- /dev/null
+++ b/TbKernel/TbKernel/TbAlgorithm.h
@@ -0,0 +1,77 @@
+#ifndef TB_ALGORITHM_H
+#define TB_ALGORITHM_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTupleAlg.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/ITbTimingSvc.h"
+#include "TbKernel/ITbPixelSvc.h"
+#include "TbKernel/ITbDataSvc.h"
+
+/** @class TbAlgorithm TbAlgorithm.h
+ *
+ *  Base class for testbeam algorithms.
+ *
+ */
+
+class TbAlgorithm : public GaudiTupleAlg {
+ public:
+  /// Standard constructor
+  TbAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+  /// Destructor
+  virtual ~TbAlgorithm();
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+
+ protected:
+  /// Number of telescope planes
+  unsigned int m_nPlanes = 0;
+  /// Number of chips, counting chips in planes with multiple chips
+  unsigned int m_nDevices = 0;
+  /// Flag to print out algorithm properties during initialization.
+  bool m_printConfiguration = false;
+  /// Indices of planes to be masked.
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc = nullptr;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+  /// Pointer to pixel service
+  mutable ITbPixelSvc* m_pixelSvc = nullptr;
+  /// Access pixel service on-demand.
+  ITbPixelSvc* pixelSvc() const {
+    if (!m_pixelSvc) m_pixelSvc = svc<ITbPixelSvc>("TbPixelSvc", true);
+    return m_pixelSvc;
+  }
+  /// Pointer to timing service
+  mutable ITbTimingSvc* m_timingSvc = nullptr;
+  /// Access timing service on-demand.
+  ITbTimingSvc* timingSvc() const {
+    if (!m_timingSvc) m_timingSvc = svc<ITbTimingSvc>("TbTimingSvc", true);
+    return m_timingSvc;
+  }
+  /// Pointer to data service
+  mutable ITbDataSvc* m_dataSvc = nullptr;
+  /// Access data service on-demand.
+  ITbDataSvc* dataSvc() const {
+    if (!m_dataSvc) m_dataSvc = svc<ITbDataSvc>("TbDataSvc", true);
+    return m_dataSvc;
+  }
+
+  /// Retrieve the masked flag for a given plane.
+  bool masked(const unsigned int plane) const {
+    return plane < m_masked.size() ? m_masked[plane] : false;
+  }
+};
+
+#endif
diff --git a/TbKernel/TbKernel/TbAlignmentTrack.h b/TbKernel/TbKernel/TbAlignmentTrack.h
new file mode 100644
index 0000000..aabd1d4
--- /dev/null
+++ b/TbKernel/TbKernel/TbAlignmentTrack.h
@@ -0,0 +1,58 @@
+#ifndef TBKERNEL_TBALIGNMENTTRACK_H
+#define TBKERNEL_TBALIGNMENTTRACK_H 1
+
+#include "Event/TbTrack.h"
+#include "Event/TbCluster.h"
+
+/** @class TbAlignmentTrack TbAlignmentTrack.h TbKernel/TbAlignmentTrack.h
+ *
+ *
+ *  @author Angelo Di Canto
+ *  @date   2014-05-09
+ */
+
+class TbAlignmentTrack {
+ public:
+  /// Standard constructor
+  TbAlignmentTrack(LHCb::TbTrack *t) : 
+      m_track(nullptr), m_xref(0.), m_yref(0.) {
+    // Clone track without the clusters.
+    m_track = t->clone();
+    // Clone each cluster on the track.
+    SmartRefVector<LHCb::TbCluster> clusters = t->clusters();
+    for (auto it = clusters.begin(), end = clusters.end(); it != end; ++it) {
+      LHCb::TbCluster *c = (*it)->clone();
+      m_track->addToClusters(c);
+      m_clusters.push_back(c);
+    }
+  }
+
+  /// Destructor
+  virtual ~TbAlignmentTrack() {
+    if (m_track) delete m_track;
+    // Delete the associated clusters.
+    for (auto it = m_clusters.begin(); it != m_clusters.end(); ++it) {
+      if (*it) delete *it;
+    }
+    m_clusters.clear();
+  }
+
+  /// Setters
+  void setXOnReferencePlane(const double x) { m_xref = x; }
+  void setYOnReferencePlane(const double y) { m_yref = y; }
+  void addToClusters(LHCb::TbCluster *c) { m_clusters.push_back(c); }
+
+  /// Accessors
+  LHCb::TbTrack *track() const { return m_track; }
+  double xOnReferencePlane() const { return m_xref; }
+  double yOnReferencePlane() const { return m_yref; }
+  const std::vector<LHCb::TbCluster *> &clusters() { return m_clusters; }
+
+ protected:
+  LHCb::TbTrack *m_track;
+  double m_xref;
+  double m_yref;
+  std::vector<LHCb::TbCluster *> m_clusters;
+};
+
+#endif  // TBKERNEL_TBALIGNMENTTRACK_H
diff --git a/TbKernel/TbKernel/TbBufferedFile.h b/TbKernel/TbKernel/TbBufferedFile.h
new file mode 100644
index 0000000..24c2e2e
--- /dev/null
+++ b/TbKernel/TbKernel/TbBufferedFile.h
@@ -0,0 +1,139 @@
+#include <iostream>
+
+// ROOT
+#include "TFile.h"
+
+/* @class TbBufferedFile TbBufferedFile.h
+ *
+ * Generic buffered interface to ROOT IO for use of IO plugins
+ *
+ */
+
+// BUFFERSIZE is the number of objects that can be buffered
+template <unsigned int BUFFERSIZE, class TYPE>
+class TbBufferedFile {
+
+ public:
+  /// Constructor
+  TbBufferedFile(const std::string& filename, bool init = true)
+      : m_file(TFile::Open((filename + "?filetype=raw").c_str())),
+        m_bytesRead(0),
+        m_filename(filename),
+        m_buffer_size(BUFFERSIZE * sizeof(TYPE)),
+        m_buffer_pos(BUFFERSIZE),
+        m_init(false) {
+    if (is_open()) {
+      m_bytes = m_file->GetSize();
+      if (init) initialise();
+    } else {
+      std::cout << "File opening failed - waiting 5s then reconnecting"
+                << std::endl;
+      sleep(5);
+      m_file = TFile::Open((filename + "?filetype=raw").c_str());
+      if (is_open()) {
+        m_bytes = m_file->GetSize();
+        if (init) initialise();
+      } else {
+        std::cerr << "Cannot open file: " << filename << " critical error!"
+                  << std::endl;
+      }
+    }
+  }
+  /// Destructor
+  ~TbBufferedFile() { close(); }
+
+  // sets the offset in the file and loads the corresponding buffer (IN BYTES )
+  void setOffset(const uint64_t pos) {
+    if (pos < m_bytesRead && pos > m_bytesRead - m_buffer_size) {
+      m_buffer_pos = (pos - (m_bytesRead - m_buffer_size)) / sizeof(TYPE);
+      return;
+    }
+    if (pos > m_bytes) {
+      std::cout << "Attempted to read outside of file, offsetting cancelled"
+                << std::endl;
+      return;
+    }
+    m_file->SetOffset(pos, TFile::ERelativeTo::kBeg);
+    m_buffer_size = (m_bytesRead + BUFFERSIZE * sizeof(TYPE) > m_bytes)
+                        ? m_bytes - m_bytesRead
+                        : m_buffer_size;
+    m_file->ReadBuffer((char*)m_buffer, m_buffer_size);
+    m_buffer_pos = 0;
+    m_bytesRead = pos + m_buffer_size;
+  }
+
+  TYPE getNext() {
+
+    if (__builtin_expect(m_buffer_pos * sizeof(TYPE) == m_buffer_size, 0)) {
+      m_buffer_size = (m_bytesRead + BUFFERSIZE * sizeof(TYPE) > m_bytes)
+                          ? m_bytes - m_bytesRead
+                          : m_buffer_size;
+      if (m_file->ReadBuffer((char*)m_buffer, m_buffer_size)) {
+        /// this is to give additional protection in case of network timeouts
+        std::cout << "Reading the buffer of " << m_filename
+                  << " failed. Waiting for 5s" << std::endl;
+        sleep(5);
+        m_file->SetOffset(-m_buffer_size, TFile::ERelativeTo::kCur);
+        if (m_file->ReadBuffer((char*)m_buffer, m_buffer_size)) {
+          std::cout << "Reading the buffer failed again, closing file"
+                    << std::endl;
+          m_bytesRead = m_bytes;
+          m_buffer_pos = m_buffer_size / sizeof(TYPE);
+          return TYPE();
+        }
+      }
+      m_bytesRead = m_bytesRead + m_buffer_size;
+      m_buffer_pos = 0;
+    }
+    return m_buffer[m_buffer_pos++];
+  }
+  TYPE getPrevious() {
+    if (m_buffer_pos > 0) {
+      m_buffer_pos -= 1;
+      return m_buffer[m_buffer_pos];
+    } 
+    return TYPE();
+  }
+  bool eof() const {
+    return (m_bytesRead == m_bytes) &&
+           (m_buffer_pos * sizeof(TYPE) == m_buffer_size);
+  }
+  void close() {
+    if (m_init) {
+      delete[] m_buffer;
+      m_init = false;
+    }
+    if (is_open()) m_file->Close();
+  }
+
+  void reset() {
+    if (m_init) {
+      delete[] m_buffer;
+      m_init = false;
+    }
+    m_bytesRead = 0;
+    m_buffer_size = BUFFERSIZE * sizeof(TYPE);
+    m_buffer_pos = BUFFERSIZE;
+  }
+  bool is_open() const { return m_file != 0 && m_file->IsOpen(); }
+
+  void initialise() {
+    if (!m_init) {
+      m_buffer = new TYPE[BUFFERSIZE];
+      m_init = true;
+    }
+  }
+
+ protected:
+  TFile* m_file;
+  uint64_t m_bytesRead;
+  std::string m_filename;
+
+ private:
+  uint64_t m_buffer_size;
+  uint64_t m_buffer_pos;
+  uint64_t m_bytes;
+  TYPE* m_buffer;
+  bool m_failure;
+  bool m_init;
+};
diff --git a/TbKernel/TbKernel/TbCondFile.h b/TbKernel/TbKernel/TbCondFile.h
new file mode 100644
index 0000000..13f2af9
--- /dev/null
+++ b/TbKernel/TbKernel/TbCondFile.h
@@ -0,0 +1,67 @@
+#ifndef TBCONDFILE_H
+#define TBCONDFILE_H
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+#include "TbKernel/TbBufferedFile.h"
+
+/* @class TbCondFile TbCondFile.h
+ *
+ * Interface classes for dealing with conditions files,
+ * both locally and via more general TbBufferedFiles
+ *
+ */
+
+class TbCondFile : public TbBufferedFile<100000, char> {
+ public:
+  /// Constructor
+  TbCondFile(const std::string& filename) : TbBufferedFile(filename) {}
+
+  bool split(std::stringstream& ss, const char delim) {
+    std::string item;
+    std::getline(ss, item, delim);
+    return item.empty();
+  }
+
+  bool getLine(std::string& line) {
+    line = "";
+    char tmp('a');
+    while (tmp != '\n' && !TbBufferedFile::eof()) {
+      tmp = getNext();
+      if (tmp != '\n') line += tmp;
+    }
+    const size_t p = line.find_first_not_of(' ');
+    return (line.empty() || line[0] == '#' || p == std::string::npos) ? false
+                                                                      : true;
+  }
+
+  template <typename Type>
+  Type custom_cast(const std::string& ref);
+  template <typename Type, typename... Types>
+  bool split(std::stringstream& ss, const char delim, Type& val,
+             Types&... rest);
+  template <typename... Types>
+  bool split(const std::string& s, const char delim, Types&... rest);
+};
+
+template <typename... Types>
+bool TbCondFile::split(const std::string& s, const char delim, Types&... rest) {
+  std::stringstream ss(s);
+  return split(ss, delim, rest...);
+}
+
+template <typename Type, typename... Types>
+bool TbCondFile::split(std::stringstream& ss, const char delim, Type& val,
+                       Types&... rest) {
+  std::string item;
+  while (std::getline(ss, item, delim)) {
+    if (item == "") continue;
+    val = custom_cast<Type>(item);
+    return split(ss, delim, rest...);
+  }
+  return true;
+}
+
+#endif
diff --git a/TbKernel/TbKernel/TbConstants.h b/TbKernel/TbKernel/TbConstants.h
new file mode 100755
index 0000000..4e5a3b2
--- /dev/null
+++ b/TbKernel/TbKernel/TbConstants.h
@@ -0,0 +1,22 @@
+#ifndef TB_CONSTANTS_H
+#define TB_CONSTANTS_H 1
+
+namespace Tb {
+
+// Time units
+static const uint64_t ToA = 4096;
+static const uint64_t SpidrTime = 16384 * ToA;
+
+static const double nanosecond = ToA / 25.;
+static const uint64_t millisecond = 40000 * ToA;
+static const uint64_t second = 1000 * millisecond;
+static const uint64_t minute = 60 * second;
+
+static const unsigned int NRows = 256;
+static const unsigned int NCols = 256;
+static const unsigned int NPixels = NRows * NCols;
+
+static const double PixelPitch = 0.055;
+}
+
+#endif
diff --git a/TbKernel/TbKernel/TbFunctors.h b/TbKernel/TbKernel/TbFunctors.h
new file mode 100755
index 0000000..c0e1aa3
--- /dev/null
+++ b/TbKernel/TbKernel/TbFunctors.h
@@ -0,0 +1,81 @@
+#ifndef TB_FUNCTORS_H
+#define TB_FUNCTORS_H 1
+
+#include <functional>
+#include <numeric>
+#define USE_BRANCH_PREDICTION 1
+
+#if USE_BRANCH_PREDICTION
+#define likely(x) __builtin_expect((x), 1)
+#define unlikely(x) __builtin_expect((x), 0)
+#else
+#define likely(x) x
+#define unlikely(x) x
+#endif
+
+namespace TbFunctors {
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class LessByTime : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the time stamps of two objects
+   *  @param o1   first object
+   *  @param o2   second object
+   *  @return  result of the comparison
+   */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return !o1 ? true : !o2 ? false : o1->time() < o2->time();
+  }
+};
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class LessByTimeBP : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the time stamps of two objects
+  *  @param o1   first object
+  *  @param o2   second object
+  *  @return  result of the comparison
+  *  Uses branch prediction for faster sorts in partially sorted data
+  */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return unlikely(!o1) ? true : unlikely(!o2)
+                                      ? false
+                                      : likely(o1->time() < o2->time());
+  }
+};
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class GreaterByToT : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the ADC values of two objects
+   *  @param o1   first object
+   *  @param o2   second object
+   *  @return  result of the comparison
+   */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return (!o2) ? true : (!o1) ? false : o1->ToT() > o2->ToT();
+  }
+};
+
+template <class TYPE1, class TYPE2 = TYPE1>
+class LessByZ : public std::binary_function<TYPE1, TYPE2, bool> {
+ public:
+  /** Compare the z-coordinates of two objects
+   *  @param o1   first object
+   *  @param o2   second object
+   *  @return  result of the comparison
+   */
+  inline bool operator()(TYPE1 o1, TYPE2 o2) const {
+    return (!o1) ? true : (!o2) ? false : o1->z() < o2->z();
+  }
+};
+}
+
+template <class TYPE>
+class lowerBound {
+ public:
+  bool operator()(TYPE lhs, const double t) const { return lhs->htime() < t; }
+  bool operator()(const double t, TYPE rhs) const { return t < rhs->htime(); }
+};
+
+#endif
diff --git a/TbKernel/TbKernel/TbGeomFunctions.h b/TbKernel/TbKernel/TbGeomFunctions.h
new file mode 100644
index 0000000..d59bea8
--- /dev/null
+++ b/TbKernel/TbKernel/TbGeomFunctions.h
@@ -0,0 +1,63 @@
+#ifndef TB_GEOMFUNC
+#define TB_GEOMFUNC 1
+
+namespace Tb {
+/*
+inline static void getTaitBryanAngles(const ROOT::Math::Quaternion& Q, double& alpha,
+                               double& beta, double& gamma) {
+
+  double a, b, c, d;
+  Q.GetComponents(a, b, c, d);
+  alpha = atan2(-2 * (c * d - a * b), a * a - b * b - c * c + d * d);
+  beta = atan2(
+      -2 * (b * d + c * a),
+      sqrt(4 * (a * b - c * d) * (a * b - c * d) +
+           (a * a - b * b - c * c + d * d) * (a * a - b * b - c * c + d * d)));
+  gamma = atan2(-2 * (b * c - d * a), a * a + b * b - c * c - d * d);
+}
+
+inline static ROOT::Math::Quaternion getQuaternionRepresentation(
+    const ROOT::Math::Rotation3D& rot) {
+
+  double xx, xy, xz, yx, yy, yz, zx, zy, zz;
+  rot.GetComponents(xx, yx, zx, xy, yy, zy, xz, yz, zz);
+
+  const double a = 0.5 * sqrt(1 + xx + yy + zz);
+  const double b = (0.25 / a) * (yz - zy);
+  const double c = (0.25 / a) * (zx - xz);
+  const double d = (0.25 / a) * (xy - yx);
+
+  std::cout << "============= TAIT-BRYAN REPRESENTATION ===============" <<
+  std::endl;
+  std::cout << xx << "  " << yx << "  " << zx << std::endl;
+  std::cout << xy << "  " << yy << "  " << zy << std::endl;
+  std::cout << xz << "  " << yz << "  " << zz << std::endl;
+  std::cout << "=======================================================" <<
+  std::endl;
+  std::cout << a << ", " << b << ", " << c << ", " << d << std::endl;
+
+  std::cout << "============= HAMILTONIAN REPRESENTATION ==============" <<
+  std::endl;
+  std::cout << "| " << a*a + b*b - c*c - d*d << "  " << 2*(b*c - a*d) << "   "
+  << 2*(b*d + a*c) << " |" << std::endl;
+  std::cout << "| " << 2*(b*c + d*a) << "  " << 1 - 2*(b*b + d*d ) << "   " <<
+  2*(c*d - a*b ) << " |" << std::endl;
+  std::cout << "| " << 2*(b*d - c*a) << "  " << 2*(a*b + c*d ) << "   " << a*a -
+  b*b - c*c + d*d << " |" << std::endl;
+  std::cout << "=======================================================" <<
+  std::endl;
+
+  ROOT::Math::Quaternion Q(a, b, c, d);
+  return Q;
+}
+*/
+static void SmallRotation(const double& x0, const double& dx0, const double& y0,
+                          const double& dy0, const double& dz0, double& xr,
+                          double& yr, double& zr) {
+  xr = dx0 + tan(y0) * (dz0 * cos(x0) + dy0 * cos(x0));
+  yr = dy0 * cos(x0) + dz0 * sin(x0);
+  zr = (-cos(x0) * dz0 + sin(x0) * dy0) / cos(y0);
+}
+}
+
+#endif
diff --git a/TbKernel/TbKernel/TbModule.h b/TbKernel/TbKernel/TbModule.h
new file mode 100644
index 0000000..5d2a50b
--- /dev/null
+++ b/TbKernel/TbKernel/TbModule.h
@@ -0,0 +1,167 @@
+#ifndef TB_MODULE_H
+#define TB_MODULE_H 1
+
+#include "GaudiKernel/Point3DTypes.h"
+#include "GaudiKernel/Vector3DTypes.h"
+#include "GaudiKernel/Transform3DTypes.h"
+#include "Math/Translation3D.h"
+#include "Math/RotationZYX.h"
+#include "TbKernel/TbConstants.h"
+#include "TMatrixD.h"
+#include "TMatrixDEigen.h"
+#include "TVectorD.h"
+
+struct TbChip {
+  TbChip(const std::string& _id, const unsigned int& _col,
+         const unsigned int& _num)
+      : col(_col), num(_num), id(_id) {};
+
+  unsigned int col;
+  unsigned int num;
+  std::string id;
+};
+
+class TbModule {
+
+ public:
+  /// Module types
+  enum Type {
+    Tpx3,        ///< Tpx3 single chip assembly
+    Tpx3Triple,  ///< Tpx3 3x1 tile
+    UT           ///< UT sensor
+  };
+
+  /// Constructor
+  TbModule() : m_chips(), m_centre(), m_normal() {}
+
+  /// Destructor
+  virtual ~TbModule() {
+    if (m_transform) delete m_transform;
+    if (m_inverse) delete m_inverse;
+  }
+
+  /// Return the module type.
+  TbModule::Type type() const { return m_type; }
+  /// Set the module type.
+  void setType(const TbModule::Type& type) { m_type = type; }
+
+  /// Return the module ID.
+  std::string id() const { return m_id; }
+  /// Set the module ID.
+  void setId(const std::string& id) { m_id = id; }
+  /// Return the chip ID (for modules with multiple chips).
+  std::string id(const unsigned int index) { return m_chips[index].id; }
+
+  /// Set the nominal position and orientation and the misalignment.
+  void setAlignment(const double x, const double y, const double z,
+                    const double rx, const double ry, const double rz,
+                    const double dx, const double dy, const double dz,
+                    const double drx, const double dry, const double drz) {
+    m_x = x;
+    m_y = y;
+    m_z = z;
+    m_rx = rx;
+    m_ry = ry;
+    m_rz = rz;
+    m_dx = dx;
+    m_dy = dy;
+    m_dz = dz;
+    m_drx = drx;
+    m_dry = dry;
+    m_drz = drz;
+    setTransform();
+  }
+  /// Set the misalignment.
+  void setAlignment(const double dx, const double dy, const double dz,
+                    const double drx, const double dry, const double drz) {
+    m_dx = dx;
+    m_dy = dy;
+    m_dz = dz;
+    m_drx = drx;
+    m_dry = dry;
+    m_drz = drz;
+    setTransform();
+  }
+  /// Return the centre position of the module.
+  const Gaudi::XYZPoint& centre() { return m_centre; }
+  /// Return the normal vector to the module plane.
+  const Gaudi::XYZVector& normal() { return m_normal; }
+  /// Return the transformation matrix from local to global coordinates.
+  Gaudi::Transform3D transform() { return *m_transform; }
+  /// Return the transformation matrix from global to local coordinates.
+  Gaudi::Transform3D inverse() { return *m_inverse; }
+
+  unsigned int nChips() const { return m_chips.size(); }
+
+  void addChip(const std::string& id) {
+    m_chips.push_back(TbChip(id, nChips() * Tb::NCols, nChips()));
+  }
+  unsigned int cols() const {
+    return m_type == TbModule::Tpx3Triple ? 3 * Tb::NCols : Tb::NCols;
+  }
+
+  const std::vector<TbChip>& chips() const { return m_chips; }
+
+  double x() const { return m_x; }
+  double y() const { return m_y; }
+  double z() const { return m_z; }
+  double rotX() const { return m_rx; }
+  double rotY() const { return m_ry; }
+  double rotZ() const { return m_rz; }
+  double dX() const { return m_dx; }
+  double dY() const { return m_dy; }
+  double dZ() const { return m_dz; }
+  double dRotX() const { return m_drx; }
+  double dRotY() const { return m_dry; }
+  double dRotZ() const { return m_drz; }
+
+  void setTransform() {
+    ROOT::Math::Translation3D t(m_x + m_dx, m_y + m_dy, m_z + m_dz);
+    ROOT::Math::RotationZYX r(m_rz + m_drz, m_ry + m_dry, m_rx + m_drx);
+    if (m_transform) delete m_transform;
+    if (m_inverse) delete m_inverse;
+
+    m_transform = new Gaudi::Transform3D(r, t);
+    m_inverse = new Gaudi::Transform3D(m_transform->Inverse());
+    // Calculate the coordinates of the module centre in the global frame.
+    m_centre = transform() * Gaudi::XYZPoint(0., 0., 0.);
+    // Calculate the normal vector in the global frame.
+    Gaudi::XYZPoint p = transform() * Gaudi::XYZPoint(0., 0., 1.);
+    m_normal = p - m_centre;
+  }
+
+ private:
+  /// Module type
+  TbModule::Type m_type = TbModule::Tpx3;
+  /// Chips constituting the module
+  std::vector<TbChip> m_chips;
+  /// Nominal positions and rotations
+  double m_x = 0.;
+  double m_y = 0.;
+  double m_z = 0.;
+  double m_rx = 0.;
+  double m_ry = 0.;
+  double m_rz = 0.;
+  /// Alignment
+  double m_dx = 0.;
+  double m_dy = 0.;
+  double m_dz = 0.;
+  double m_drx = 0.;
+  double m_dry = 0.;
+  double m_drz = 0.;
+  /// Module identifier
+  std::string m_id = "";
+  /// Centre position
+  Gaudi::XYZPoint m_centre;
+  /// Normal vector to the module plane
+  Gaudi::XYZVector m_normal;
+
+  /// Transformation matrix from local to global coordinates.
+  Gaudi::Transform3D* m_transform = NULL;
+  /// Transformation matrix from global to local coordinates.
+  Gaudi::Transform3D* m_inverse = NULL;
+
+  /// Calculate the transformation matrix and its inverse.
+};
+
+#endif
diff --git a/TbKernel/cmt/.svn/all-wcprops b/TbKernel/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..2d661d8
--- /dev/null
+++ b/TbKernel/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/193523/Kepler/trunk/Tb/TbKernel/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/193523/Kepler/trunk/Tb/TbKernel/cmt/requirements
+END
diff --git a/TbKernel/cmt/.svn/entries b/TbKernel/cmt/.svn/entries
new file mode 100644
index 0000000..8fd07fd
--- /dev/null
+++ b/TbKernel/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbKernel/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-08-11T11:58:17.894954Z
+193523
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+fd52f1adcd772bafd60eef4dd3be40e0
+2015-08-11T11:58:17.894954Z
+193523
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1134
+
diff --git a/TbKernel/cmt/.svn/text-base/requirements.svn-base b/TbKernel/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..1e681e0
--- /dev/null
+++ b/TbKernel/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,30 @@
+package TbKernel 
+version v3r0
+
+branches          TbKernel cmt doc src 
+include_path      none
+
+use GaudiAlg        v*
+use TbEvent         v* Tb
+use ROOT            v* LCG_Interfaces
+
+#=========================================================================
+# Own includes
+#=========================================================================
+apply_pattern install_more_includes more=TbKernel
+
+#=========================================================================
+# Linker library building rule
+#=========================================================================
+library          TbKernelLib    ../src/lib/*.cpp
+apply_pattern    linker_library library=TbKernelLib
+
+#=========================================================================
+# Component library building rule
+#=========================================================================
+library          TbKernel    ../src/*.cpp
+apply_pattern    component_library library=TbKernel
+
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append ROOT_linkopts " -lMathCore -lGenVector -lMatrix"
diff --git a/TbKernel/cmt/requirements b/TbKernel/cmt/requirements
new file mode 100644
index 0000000..1e681e0
--- /dev/null
+++ b/TbKernel/cmt/requirements
@@ -0,0 +1,30 @@
+package TbKernel 
+version v3r0
+
+branches          TbKernel cmt doc src 
+include_path      none
+
+use GaudiAlg        v*
+use TbEvent         v* Tb
+use ROOT            v* LCG_Interfaces
+
+#=========================================================================
+# Own includes
+#=========================================================================
+apply_pattern install_more_includes more=TbKernel
+
+#=========================================================================
+# Linker library building rule
+#=========================================================================
+library          TbKernelLib    ../src/lib/*.cpp
+apply_pattern    linker_library library=TbKernelLib
+
+#=========================================================================
+# Component library building rule
+#=========================================================================
+library          TbKernel    ../src/*.cpp
+apply_pattern    component_library library=TbKernel
+
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append ROOT_linkopts " -lMathCore -lGenVector -lMatrix"
diff --git a/TbKernel/doc/.svn/all-wcprops b/TbKernel/doc/.svn/all-wcprops
new file mode 100644
index 0000000..daafa1d
--- /dev/null
+++ b/TbKernel/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/doc/release.notes
+END
diff --git a/TbKernel/doc/.svn/entries b/TbKernel/doc/.svn/entries
new file mode 100644
index 0000000..9888be8
--- /dev/null
+++ b/TbKernel/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbKernel/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:52.000000Z
+ec5054df92b26917e8baf067b52542fe
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7023
+
diff --git a/TbKernel/doc/.svn/text-base/release.notes.svn-base b/TbKernel/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..46c73a0
--- /dev/null
+++ b/TbKernel/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,194 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbKernel
+! Responsible : 
+! Purpose     : Tools and services for Timepix3 testbeam analysis
+!-----------------------------------------------------------------------------
+
+! 2016-02-23 - Heinrich Schindler
+ - Move TbCondFile from src to src/lib (so it can be used by other packages).
+ - Add eta config to TbDataSvc.
+
+! 2015-11-17 - Tim Evans
+ - Changed the behaviour of the pixel service to deal with bad fits in the 
+   calibration. Now if the surrogate parameters are nan/inf, the average of
+   the nearest neighbours in the column is taken. If the neighbour is also bad, or an
+   edge, is not included. If no suitable neighbours are found, the pixel is masked 
+   (in practice, this should probably not happen) 
+
+! 2015-10-28 - Heinrich Schindler
+ - TbAlignmentTrack: also store the cloned clusters in m_clusters to avoid
+   memory leaks.
+
+! 2015-10-17 - Heinrich Schindler
+ - Remove unused flag refitclusters from (I)TbTrackFit.
+
+! 2015-08-11 - Tim Evans
+ - Added TbGeomFunctions.
+
+!========================= TbKernel v3r0 2015-05-19 ==========================
+
+! 2015-05-01 - Heinrich Schindler
+ - Move per-chip timing correction from TbTimingSvc to TbPixelSvc.
+
+! 2015-03-24 - Heinrich Schindler
+ - Add TbKalmanTrackFit tool.
+ - Adapt TbGeometrySvc::intercept function to handle multi-state tracks.
+
+! 2015-03-09 - Heinrich Schindler
+ - TbGeometrySvc: remove unused functions, add function pointToPixel.
+
+! 2015-03-04 - Heinrich Schindler
+ - TbTrackFit: add declareProperty for masked planes.
+
+! 2015-01-22 - Heinrich Schindler
+ - TbModule: rename chip to TbChip, remove unused code.
+ - (I)TbGeometrySvc: rename index to moduleIndex and deviceId to deviceIndex.
+ - Remove unused code in TbTimingSvc, small tidying up in TbPixelSvc.
+
+! 2015-01-20 - Heinrich Schindler
+ - Add function pixelToPoint to TbGeometrySvc. Cache pixel centres in 
+   TbGeometrySvc instead of in each TbModule. 
+
+! 2014-11-17 - Tim Evans
+ - Added TbBufferedFile as general interface to remote Root files that supports 
+   fast templated buffers, that can be used either by configuration files or 
+   for raw data
+ - Added TbDataSvc that handles all input files (data + configuration) in a 
+   common way. 
+ - Added TbCondFile and TbNetworkCondFile that inherit from ITbCondFile, 
+   that make common the handling between local and network files. Also unifies
+   the parsing in the configuration of the services.
+
+!========================= TbKernel v2r1 2014-11-30 ==========================
+
+! 2014-11-22 - Heinrich Schindler
+ - Add TbClusterFinder tool.
+
+! 2014-10-17 - Tim Evans
+ - Fixed a sign error in TbTimingSvc and added TrimDac functionality to TbPixelSvc
+
+! 2014-10-08 - Hella Snoek
+ - Added robustness against stdoperator[] feature
+
+! 2014-10-8 - Tim Evans
+ - Added configurable time offset per plane to the timing service.
+   This is defined such that the 0th plane is the reference plane, i.e.
+   does not have a time offset. Only affects hTime, not the time.
+
+! 2014-10-4 - Tim Evans
+ - Added column offsets to the pixel config service, changes the format 
+   of the options file with Mask and Offset keywords
+
+! 2014-09-29 - Dan Saunders
+ - Change track fit to use errors assigned to each cluster.
+
+!========================= TbKernel v2r0 2014-08-18 ==========================
+
+! 2014-08-11 - Heinrich Schindler
+ - Change format of pixel configuration file to use chip ID instead of plane.
+
+! 2014-08-05 - Heinrich Schindler
+ - TbPixelSvc: fix compiler warning (inline function in abstract interface).
+
+! 2014-07-27 - Tim Evans 
+ - TbPixelSvc : Added service to mask pixels 
+
+! 2014-07-22 - Heinrich Schindler
+ - TbTrackFit: add option to mask planes.
+
+! 2014-07-21 - Heinrich Schindler
+ - Add TbConstants (global constants).
+ - Update conversion factors between local and global timestamps.
+ - Bugfix in TbTimingSvc for times < offset. 
+
+! 2014-07-21 - Panagiotis Tsopelas
+ - Calculate chi2 residuals using intercept method from TbGeometrySvc
+
+! 2014-07-17 - Heinrich Schindler
+ - Add TbTimingSvc.
+
+! 2014-07-08 - Tim Evans
+ - Changes to reflect changes to naming in TbEvent
+
+! 2014-07-03 - Angelo Di Canto
+ - TbAlignmentTrack: clusters are stored within the TbTrack, added (x,y)
+   position of the track on the reference plane as a member 
+
+! 2014-06-27 - Heinrich Schindler
+ - Add functor for sorting by ToT value.
+ - Add functor for sorting by plane and timestamp.
+
+! 2014-06-24 - Heinrich Schindler
+ - Add function to calculate intercept of track and plane.
+ - Remove globalToLocal/localToGlobal transformations with module label 
+   as argument.
+
+! 2014-06-06 - Heinrich Schindler
+ - TbGeometrySvc: delete message service in constructor.
+ - TbTrackFit: fix warning from clang (implicit conversion NULL to int).
+
+!========================= TbKernel v1r0 2014-05-30 ==========================
+
+! 2014-05-29 - Heinrich Schindler
+ - TbGeometrySvc: fix unitialised message service pointer. 
+ - TbAlignmentTrack: delete the stored clusters.
+ - TbGeometrySvc: sort modules by z-position.
+
+! 2014-05-28 - Heinrich Schindler
+ - Add TbFunctors.
+
+! 2014-05-26 - Heinrich Schindler
+ - Trivial optimisations in TbTrackFit
+
+! 2014-05-23 - Panagiotis Tsopelas
+ - In TbTrackFit, TbAlignmentTrack :
+   Renamed "chi2" -> "chi2PerNdof" after change in TbTrack.
+   Changed every call to a first state parameter (x0, y0, tx, ty)
+   to a call through the "firstState".
+
+! 2014-05-21 - Heinrich Schindler
+ - Remove TbClusterFinder helper class (now in TbAlgorithms).
+
+! 2014-05-15 - Marco Clemencic
+ - Fixed CMake configuration.
+
+! 2014-05-06 - Panagiotis Tsopelas
+ - Added straight line fit in TbTrackFit. 
+   This method fills the first state of a TbTrack, its chi2 & ndof
+ - Modified ITbTrackFit: removed const from fit()
+
+! 2014-05-02 - Heinrich Schindler
+ - Add functions to retrieve TbModule(s) to ITbGeometrySvc interface.
+
+! 2014-04-30 - Heinrich Schindler
+ - Move TbModule from src to TbKernel.
+
+! 2014-04-29 - Dan Saunders
+ - Added TbClusterFinder.cpp (an object for retrieving clusters at 
+   particular times).
+
+! 2014-04-14 - Heinrich Schindler
+ - Updates to TbGeometrySvc
+
+! 2014-04-14 - Heinrich Schindler
+ - Add TbTrackFit interface and dummy implementation. 
+
+! 2014-04-11 - Heinrich Schindler
+ - Run clang-format to get consistent formatting
+ - Change class member functions to start with lower-case letters
+
+! 2014-04-07 - Christoph Hombach
+ - Added exception error in TbGeometrySvc in case Alignment-file is not found.
+
+! 2014-04-07 - Christoph Hombach
+ - Added TbModule class containing all information 
+   (position, transformation, name, number) regarding modules. 
+   Added vector of modules in TbGeometrySvc. 
+   A int is given to each module when reading in ConditionsFile 
+   (0 for first, 1 for second, etc..). 
+   This vector can be called e.g. by geomSvc()->Modules() 
+   or a specific module by geomSvc()->Module(<module id>) or 
+   geomSvc()->Module(<number>).
+
+! 2014-03-31 - Heinrich Schindler
+ - Initial import 
diff --git a/TbKernel/doc/release.notes b/TbKernel/doc/release.notes
new file mode 100644
index 0000000..46c73a0
--- /dev/null
+++ b/TbKernel/doc/release.notes
@@ -0,0 +1,194 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbKernel
+! Responsible : 
+! Purpose     : Tools and services for Timepix3 testbeam analysis
+!-----------------------------------------------------------------------------
+
+! 2016-02-23 - Heinrich Schindler
+ - Move TbCondFile from src to src/lib (so it can be used by other packages).
+ - Add eta config to TbDataSvc.
+
+! 2015-11-17 - Tim Evans
+ - Changed the behaviour of the pixel service to deal with bad fits in the 
+   calibration. Now if the surrogate parameters are nan/inf, the average of
+   the nearest neighbours in the column is taken. If the neighbour is also bad, or an
+   edge, is not included. If no suitable neighbours are found, the pixel is masked 
+   (in practice, this should probably not happen) 
+
+! 2015-10-28 - Heinrich Schindler
+ - TbAlignmentTrack: also store the cloned clusters in m_clusters to avoid
+   memory leaks.
+
+! 2015-10-17 - Heinrich Schindler
+ - Remove unused flag refitclusters from (I)TbTrackFit.
+
+! 2015-08-11 - Tim Evans
+ - Added TbGeomFunctions.
+
+!========================= TbKernel v3r0 2015-05-19 ==========================
+
+! 2015-05-01 - Heinrich Schindler
+ - Move per-chip timing correction from TbTimingSvc to TbPixelSvc.
+
+! 2015-03-24 - Heinrich Schindler
+ - Add TbKalmanTrackFit tool.
+ - Adapt TbGeometrySvc::intercept function to handle multi-state tracks.
+
+! 2015-03-09 - Heinrich Schindler
+ - TbGeometrySvc: remove unused functions, add function pointToPixel.
+
+! 2015-03-04 - Heinrich Schindler
+ - TbTrackFit: add declareProperty for masked planes.
+
+! 2015-01-22 - Heinrich Schindler
+ - TbModule: rename chip to TbChip, remove unused code.
+ - (I)TbGeometrySvc: rename index to moduleIndex and deviceId to deviceIndex.
+ - Remove unused code in TbTimingSvc, small tidying up in TbPixelSvc.
+
+! 2015-01-20 - Heinrich Schindler
+ - Add function pixelToPoint to TbGeometrySvc. Cache pixel centres in 
+   TbGeometrySvc instead of in each TbModule. 
+
+! 2014-11-17 - Tim Evans
+ - Added TbBufferedFile as general interface to remote Root files that supports 
+   fast templated buffers, that can be used either by configuration files or 
+   for raw data
+ - Added TbDataSvc that handles all input files (data + configuration) in a 
+   common way. 
+ - Added TbCondFile and TbNetworkCondFile that inherit from ITbCondFile, 
+   that make common the handling between local and network files. Also unifies
+   the parsing in the configuration of the services.
+
+!========================= TbKernel v2r1 2014-11-30 ==========================
+
+! 2014-11-22 - Heinrich Schindler
+ - Add TbClusterFinder tool.
+
+! 2014-10-17 - Tim Evans
+ - Fixed a sign error in TbTimingSvc and added TrimDac functionality to TbPixelSvc
+
+! 2014-10-08 - Hella Snoek
+ - Added robustness against stdoperator[] feature
+
+! 2014-10-8 - Tim Evans
+ - Added configurable time offset per plane to the timing service.
+   This is defined such that the 0th plane is the reference plane, i.e.
+   does not have a time offset. Only affects hTime, not the time.
+
+! 2014-10-4 - Tim Evans
+ - Added column offsets to the pixel config service, changes the format 
+   of the options file with Mask and Offset keywords
+
+! 2014-09-29 - Dan Saunders
+ - Change track fit to use errors assigned to each cluster.
+
+!========================= TbKernel v2r0 2014-08-18 ==========================
+
+! 2014-08-11 - Heinrich Schindler
+ - Change format of pixel configuration file to use chip ID instead of plane.
+
+! 2014-08-05 - Heinrich Schindler
+ - TbPixelSvc: fix compiler warning (inline function in abstract interface).
+
+! 2014-07-27 - Tim Evans 
+ - TbPixelSvc : Added service to mask pixels 
+
+! 2014-07-22 - Heinrich Schindler
+ - TbTrackFit: add option to mask planes.
+
+! 2014-07-21 - Heinrich Schindler
+ - Add TbConstants (global constants).
+ - Update conversion factors between local and global timestamps.
+ - Bugfix in TbTimingSvc for times < offset. 
+
+! 2014-07-21 - Panagiotis Tsopelas
+ - Calculate chi2 residuals using intercept method from TbGeometrySvc
+
+! 2014-07-17 - Heinrich Schindler
+ - Add TbTimingSvc.
+
+! 2014-07-08 - Tim Evans
+ - Changes to reflect changes to naming in TbEvent
+
+! 2014-07-03 - Angelo Di Canto
+ - TbAlignmentTrack: clusters are stored within the TbTrack, added (x,y)
+   position of the track on the reference plane as a member 
+
+! 2014-06-27 - Heinrich Schindler
+ - Add functor for sorting by ToT value.
+ - Add functor for sorting by plane and timestamp.
+
+! 2014-06-24 - Heinrich Schindler
+ - Add function to calculate intercept of track and plane.
+ - Remove globalToLocal/localToGlobal transformations with module label 
+   as argument.
+
+! 2014-06-06 - Heinrich Schindler
+ - TbGeometrySvc: delete message service in constructor.
+ - TbTrackFit: fix warning from clang (implicit conversion NULL to int).
+
+!========================= TbKernel v1r0 2014-05-30 ==========================
+
+! 2014-05-29 - Heinrich Schindler
+ - TbGeometrySvc: fix unitialised message service pointer. 
+ - TbAlignmentTrack: delete the stored clusters.
+ - TbGeometrySvc: sort modules by z-position.
+
+! 2014-05-28 - Heinrich Schindler
+ - Add TbFunctors.
+
+! 2014-05-26 - Heinrich Schindler
+ - Trivial optimisations in TbTrackFit
+
+! 2014-05-23 - Panagiotis Tsopelas
+ - In TbTrackFit, TbAlignmentTrack :
+   Renamed "chi2" -> "chi2PerNdof" after change in TbTrack.
+   Changed every call to a first state parameter (x0, y0, tx, ty)
+   to a call through the "firstState".
+
+! 2014-05-21 - Heinrich Schindler
+ - Remove TbClusterFinder helper class (now in TbAlgorithms).
+
+! 2014-05-15 - Marco Clemencic
+ - Fixed CMake configuration.
+
+! 2014-05-06 - Panagiotis Tsopelas
+ - Added straight line fit in TbTrackFit. 
+   This method fills the first state of a TbTrack, its chi2 & ndof
+ - Modified ITbTrackFit: removed const from fit()
+
+! 2014-05-02 - Heinrich Schindler
+ - Add functions to retrieve TbModule(s) to ITbGeometrySvc interface.
+
+! 2014-04-30 - Heinrich Schindler
+ - Move TbModule from src to TbKernel.
+
+! 2014-04-29 - Dan Saunders
+ - Added TbClusterFinder.cpp (an object for retrieving clusters at 
+   particular times).
+
+! 2014-04-14 - Heinrich Schindler
+ - Updates to TbGeometrySvc
+
+! 2014-04-14 - Heinrich Schindler
+ - Add TbTrackFit interface and dummy implementation. 
+
+! 2014-04-11 - Heinrich Schindler
+ - Run clang-format to get consistent formatting
+ - Change class member functions to start with lower-case letters
+
+! 2014-04-07 - Christoph Hombach
+ - Added exception error in TbGeometrySvc in case Alignment-file is not found.
+
+! 2014-04-07 - Christoph Hombach
+ - Added TbModule class containing all information 
+   (position, transformation, name, number) regarding modules. 
+   Added vector of modules in TbGeometrySvc. 
+   A int is given to each module when reading in ConditionsFile 
+   (0 for first, 1 for second, etc..). 
+   This vector can be called e.g. by geomSvc()->Modules() 
+   or a specific module by geomSvc()->Module(<module id>) or 
+   geomSvc()->Module(<number>).
+
+! 2014-03-31 - Heinrich Schindler
+ - Initial import 
diff --git a/TbKernel/src/.svn/all-wcprops b/TbKernel/src/.svn/all-wcprops
new file mode 100644
index 0000000..192d0cf
--- /dev/null
+++ b/TbKernel/src/.svn/all-wcprops
@@ -0,0 +1,89 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/src
+END
+TbTimingSvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/196561/Kepler/trunk/Tb/TbKernel/src/TbTimingSvc.h
+END
+TbClusterFinder.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/196561/Kepler/trunk/Tb/TbKernel/src/TbClusterFinder.cpp
+END
+TbDataSvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/src/TbDataSvc.h
+END
+TbKalmanTrackFit.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/201499/Kepler/trunk/Tb/TbKernel/src/TbKalmanTrackFit.cpp
+END
+TbGeometrySvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197740/Kepler/trunk/Tb/TbKernel/src/TbGeometrySvc.h
+END
+TbTrackFit.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/201499/Kepler/trunk/Tb/TbKernel/src/TbTrackFit.h
+END
+TbPixelSvc.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/197740/Kepler/trunk/Tb/TbKernel/src/TbPixelSvc.cpp
+END
+TbClusterFinder.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/196561/Kepler/trunk/Tb/TbKernel/src/TbClusterFinder.h
+END
+TbKalmanTrackFit.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/201499/Kepler/trunk/Tb/TbKernel/src/TbKalmanTrackFit.h
+END
+TbPixelSvc.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/198356/Kepler/trunk/Tb/TbKernel/src/TbPixelSvc.h
+END
+TbTimingSvc.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/196561/Kepler/trunk/Tb/TbKernel/src/TbTimingSvc.cpp
+END
+TbDataSvc.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/src/TbDataSvc.cpp
+END
+TbGeometrySvc.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197783/Kepler/trunk/Tb/TbKernel/src/TbGeometrySvc.cpp
+END
+TbTrackFit.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/201499/Kepler/trunk/Tb/TbKernel/src/TbTrackFit.cpp
+END
diff --git a/TbKernel/src/.svn/entries b/TbKernel/src/.svn/entries
new file mode 100644
index 0000000..d203f58
--- /dev/null
+++ b/TbKernel/src/.svn/entries
@@ -0,0 +1,507 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbKernel/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbTimingSvc.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+0030ffbc30a63055dd4ca6808aa86fe7
+2015-10-21T16:27:52.865574Z
+196561
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2086
+
+TbClusterFinder.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+85e443d88dd5a1867fda6eb05c387b8d
+2015-10-21T16:27:52.865574Z
+196561
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5076
+
+TbTrackFit.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+92335fb1fdfe3530bcb84c0283b4b829
+2016-02-14T10:35:31.791066Z
+201499
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1233
+
+TbGeometrySvc.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+7cd80fd9b6f1fa676c12a1ea17706a93
+2015-11-17T16:46:25.395546Z
+197740
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4001
+
+TbClusterFinder.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+ef64ef940056a17241ce2cb00b724918
+2015-10-21T16:27:52.865574Z
+196561
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2165
+
+TbDataSvc.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+7b13f6563e0c14efdf3863506cad794e
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4064
+
+TbDataSvc.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+a2e362b4fde964da575c9dc56e7f1ac2
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1705
+
+TbKalmanTrackFit.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+fc555965024c6afa88e7440e07329385
+2016-02-14T10:35:31.791066Z
+201499
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3292
+
+TbPixelSvc.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+535429708723d44904b19d415e07baed
+2015-11-17T16:46:25.395546Z
+197740
+tevans
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+12311
+
+lib
+dir
+
+TbKalmanTrackFit.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+7e4590e4676cc3820208916633693de9
+2016-02-14T10:35:31.791066Z
+201499
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1362
+
+TbPixelSvc.h
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+c3152fac3b857d53c955e0abf8305ca6
+2015-11-27T21:01:44.399604Z
+198356
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5924
+
+TbTimingSvc.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+789e964c80eda32b474fb2a1170047aa
+2015-10-21T16:27:52.865574Z
+196561
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2389
+
+TbTrackFit.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+1cdce74a0186bded3f57a7768f3e744c
+2016-02-14T10:35:31.791066Z
+201499
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5827
+
+TbGeometrySvc.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+3a37317913c652597f04206858fea9ef
+2015-11-19T10:45:50.948321Z
+197783
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9216
+
diff --git a/TbKernel/src/.svn/text-base/TbClusterFinder.cpp.svn-base b/TbKernel/src/.svn/text-base/TbClusterFinder.cpp.svn-base
new file mode 100644
index 0000000..d292cad
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbClusterFinder.cpp.svn-base
@@ -0,0 +1,147 @@
+// Local
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbClusterFinder.h"
+
+DECLARE_TOOL_FACTORY(TbClusterFinder)
+
+//=============================================================================
+// Constructor
+//=============================================================================
+TbClusterFinder::TbClusterFinder(const std::string& type,
+                                 const std::string& name,
+                                 const IInterface* parent)
+    : GaudiTool(type, name, parent), m_searchAlgo(1) {
+
+  declareInterface<ITbClusterFinder>(this);
+}
+
+//=============================================================================
+// Set the search algorithm
+//=============================================================================
+void TbClusterFinder::setSearchAlgorithm(const std::string& searchAlgorithm) {
+
+  if (searchAlgorithm == "seq") {
+    m_searchAlgo = SearchMethod::Seq;
+  } else if (searchAlgorithm == "adap_seq") {
+    m_searchAlgo = SearchMethod::AdapSeq;
+  }
+}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbClusterFinder::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Get the number of telescope planes from the geometry service.
+  ITbGeometrySvc* geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+  if (!geomSvc) {
+    error() << "Cannot access geometry service" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  const unsigned int nPlanes = geomSvc->modules().size();
+  m_first.resize(nPlanes);
+  m_last.resize(nPlanes);
+  m_end.resize(nPlanes);
+  m_nClusters.resize(nPlanes);
+  m_empty.resize(nPlanes);
+  m_prev_ts.resize(nPlanes);
+  m_prev.resize(nPlanes);
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Set the iterators and other properties for a given plane.
+//=============================================================================
+void TbClusterFinder::setClusters(LHCb::TbClusters* cs,
+                                  const unsigned int& plane) {
+
+  m_nClusters[plane] = cs->size();
+  m_empty[plane] = cs->empty();
+  if (!cs->empty()) {
+    m_first[plane] = cs->begin();
+    m_last[plane] = cs->end() - 1;
+    m_end[plane] = cs->end();
+    m_prev[plane] = cs->begin();
+    m_prev_ts[plane] = (*cs->begin())->htime();
+  }
+}
+
+//=============================================================================
+// Get iterator to first cluster on a given plane inside a given time window
+//=============================================================================
+TbClusterFinder::Iterator TbClusterFinder::getIterator(
+    const double& t, const unsigned int& plane) {
+
+  if (m_searchAlgo == SearchMethod::Seq) {
+    return seq_search(t, plane);
+  } else if (m_searchAlgo == SearchMethod::AdapSeq) {
+    return adap_seq_search(t, plane);
+  }
+  warning() << "Unknown search algorithm" << endmsg;
+  return adap_seq_search(t, plane);
+}
+
+//=============================================================================
+// Sequential search
+//=============================================================================
+TbClusterFinder::Iterator TbClusterFinder::seq_search(
+    const double& t, const unsigned int& plane) {
+
+  Iterator first = m_first[plane];
+  if (t <= (*first)->htime()) return first;
+  Iterator last = m_last[plane];
+  for (Iterator ic = first; ic != last; ++ic) {
+    if ((*ic)->htime() >= t) return ic;
+  }
+  return last;
+}
+
+//=============================================================================
+// Adaptive sequential search
+//=============================================================================
+TbClusterFinder::Iterator TbClusterFinder::adap_seq_search(
+    const double& t, const unsigned int& plane) {
+  // Returns the index in the clusters list of the cluster which arrived
+  // CURRENTLY RETURNS SOMETHING NEAR, BUT ISNT PERFECT.
+
+  // Get (and update) the previous timestamp.
+  const auto tPrev = m_prev_ts[plane];
+  m_prev_ts[plane] = t;
+
+  Iterator first = m_first[plane];
+  Iterator last = m_last[plane];
+  // Handle cases where requested time is outside the range of this plane.
+  if (t < (*first)->htime()) {
+    m_prev[plane] = first;
+    return first;
+  } else if (t >= (*last)->htime()) {
+    m_prev[plane] = last;
+    return last;
+  }
+
+  // Handle cases where requested time is inside the range of the clusters.
+  if (t == tPrev) {
+    // Case where t = previous asked t
+    // (Covers the case where t is equal to the first cluster, since this is
+    // default).
+    return m_prev[plane];
+  } else if (t < tPrev) {
+    // Case where t < previous asked t. (Unwise usage):
+    m_prev[plane] = first;
+    return first;
+  }
+
+  // Case where t > previous asked t (Majority of cases):
+  for (Iterator ic = m_prev[plane]; ic != last; ++ic) {
+    if ((*ic)->htime() >= t) {
+      m_prev[plane] = ic;
+      return ic;
+    }
+  }
+  m_prev[plane] = first;
+  return first;
+}
diff --git a/TbKernel/src/.svn/text-base/TbClusterFinder.h.svn-base b/TbKernel/src/.svn/text-base/TbClusterFinder.h.svn-base
new file mode 100644
index 0000000..34eb1c2
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbClusterFinder.h.svn-base
@@ -0,0 +1,66 @@
+#pragma once
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// Local
+#include "TbKernel/ITbClusterFinder.h"
+
+/** @class TbClusterFinder TbClusterFinder.h
+ *
+ *  This small class is used to find a particular cluster (on a particular
+ *  chip) nearest a particular time. This is done using a variety of funky
+ *  algorithms and conditions - specifically, using the condition that during
+ *  this object's lifetime, whenever asked to retrieve clusters for particular
+ *  time, these times are always increasing. (ALWAYS). Otherwise, expect O(N)
+ *  performance.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbClusterFinder : public GaudiTool, virtual public ITbClusterFinder {
+ public:
+  typedef LHCb::TbClusters::const_iterator Iterator;
+  enum SearchMethod {
+    Seq = 1,
+    AdapSeq = 2
+  };
+
+  /// Standard constructor
+  TbClusterFinder(const std::string& type, const std::string& name,
+                  const IInterface* parent);
+  /// Destructor
+  virtual ~TbClusterFinder() {}
+
+  virtual StatusCode initialize();
+
+  /// Find iterator to first cluster on a given plane above a given time.
+  virtual Iterator getIterator(const double& t, const unsigned int& plane);
+  /// (Re)set the stored iterators for a given plane.
+  virtual void setClusters(LHCb::TbClusters* clusters,
+                           const unsigned int& plane);
+  /// Set the search algorithm to be used.
+  virtual void setSearchAlgorithm(const std::string& alg);
+
+  virtual Iterator first(const unsigned int& plane) const {
+    return m_first[plane];
+  }
+  virtual Iterator end(const unsigned int& plane) const { return m_end[plane]; }
+  virtual bool empty(const unsigned int& plane) const { return m_empty[plane]; }
+
+ private:
+  unsigned int m_searchAlgo;
+
+  std::vector<Iterator> m_first;
+  std::vector<Iterator> m_last;
+  std::vector<Iterator> m_end;
+  std::vector<unsigned int> m_nClusters;
+  std::vector<bool> m_empty;
+  std::vector<double> m_prev_ts;
+  std::vector<Iterator> m_prev;
+
+  /// Sequential search method
+  Iterator seq_search(const double& t, const unsigned int& plane);
+  /// Adaptive sequential search method
+  Iterator adap_seq_search(const double& t, const unsigned int& plane);
+};
diff --git a/TbKernel/src/.svn/text-base/TbDataSvc.cpp.svn-base b/TbKernel/src/.svn/text-base/TbDataSvc.cpp.svn-base
new file mode 100644
index 0000000..028f45c
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbDataSvc.cpp.svn-base
@@ -0,0 +1,120 @@
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+
+// Boost
+#include <boost/filesystem.hpp>
+
+// Local
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbCondFile.h"
+#include "TbDataSvc.h"
+
+DECLARE_SERVICE_FACTORY(TbDataSvc)
+
+namespace fs = boost::filesystem;
+
+//============================================================================
+// Constructor
+//============================================================================
+TbDataSvc::TbDataSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc) {
+
+  declareProperty("AlignmentFile", m_alignmentFile = "");
+  declareProperty("TimingConfigFile", m_timingFile = "");
+  declareProperty("PixelConfigFile", m_pixelFiles);
+  declareProperty("EtaConfigFiles", m_etaFiles);
+  declareProperty("Input", m_inputs);
+}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbDataSvc::~TbDataSvc() {
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Finalisation
+//============================================================================
+StatusCode TbDataSvc::finalize() { return Service::finalize(); }
+
+//============================================================================
+// Add the prefix for reading files from EOS/CASTOR
+//============================================================================
+std::string TbDataSvc::expandPath(const std::string& file) {
+
+  if (file.find("eos") == 0) {
+    return "root://eoslhcb.cern.ch//" + file;
+  }
+  return file;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbDataSvc::initialize() {
+
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+
+  if (m_inputs.empty()) {
+    error() << "No input files specified." << endmsg;
+    return StatusCode::FAILURE;
+  }
+  for (auto its = m_inputs.cbegin(), end = m_inputs.cend(); its != end; ++its) {
+    if (its->find("eos") == 0) {
+      // EOS path.
+      if (its->find(".dat") != std::string::npos) {
+        // Specified path is a raw data file. Add it to the list.
+        m_inputFiles.push_back(expandPath(*its));
+        continue;
+      }
+      // Assume the specified path is a directory and list its contents.
+      const std::string eospath =
+          "/afs/cern.ch/project/eos/installation/0.3.15/";
+      const std::string cmd = eospath + "bin/eos.select ls " + *its;
+      FILE* proc = popen(cmd.c_str(), "r");
+      char buf[4096];
+      // Loop over the entries.
+      while (!feof(proc) && fgets(buf, sizeof(buf), proc)) {
+        std::string fname = buf;
+        // Skip non-.dat files.
+        const size_t p = fname.find(".dat");
+        if (p == std::string::npos) continue;
+        // Add the file to the list.
+        fname = fname.substr(0, p + 4);
+        m_inputFiles.push_back(expandPath(*its + fname));
+      }
+      pclose(proc);
+    } else {
+      // Local file/directory.
+      fs::path path(*its);
+      if (!fs::exists(path)) {
+        warning() << "File or directory " << *its << " not found." << endmsg;
+        continue;
+      }
+      if (fs::is_directory(path)) {
+        fs::directory_iterator itdEnd;
+        for (fs::directory_iterator itd(path); itd != itdEnd; ++itd) {
+          if (is_regular_file(itd->status()))
+            m_inputFiles.push_back((*itd).path().string());
+        }
+      } else
+        m_inputFiles.push_back(*its);
+    }
+  }
+
+  if (m_inputFiles.empty()) {
+    error() << "No input files specified." << endmsg;
+    return StatusCode::FAILURE;
+  }
+  for (auto& f : m_inputFiles) info() << "Reading File: " << f << endmsg;
+
+  m_alignmentFile = expandPath(m_alignmentFile);
+  m_timingFile = expandPath(m_timingFile);
+  for (auto& f : m_pixelFiles) f = expandPath(f);
+  for (auto& f : m_etaFiles) f = expandPath(f);
+  return StatusCode::SUCCESS;
+}
diff --git a/TbKernel/src/.svn/text-base/TbDataSvc.h.svn-base b/TbKernel/src/.svn/text-base/TbDataSvc.h.svn-base
new file mode 100644
index 0000000..51477e2
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbDataSvc.h.svn-base
@@ -0,0 +1,67 @@
+#ifndef TBPIXELSVC_H
+#define TBPIXELSVC_H
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+
+// Local
+#include "TbKernel/ITbDataSvc.h"
+#include <stdint.h>
+
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbDataSvc TbDataSvc.h
+ *
+ * Implementation of the Testbeam data / configuration lookup services
+ * for use with EOS
+ */
+
+class TbDataSvc : public extends1<Service, ITbDataSvc> {
+
+ public:
+  /// Constructor
+  TbDataSvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbDataSvc();
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  virtual const std::vector<std::string>& getInputFiles() {
+    return m_inputFiles;
+  }
+  virtual const std::vector<std::string>& getPixelConfig() {
+    return m_pixelFiles;
+  }
+  virtual const std::string& getTimingConfig() { return m_timingFile; }
+  virtual const std::string& getAlignmentFile() { return m_alignmentFile; }
+  virtual const std::vector<std::string>& getEtaConfig() {
+    return m_etaFiles;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbDataSvc>;
+
+  std::vector<std::string> m_inputs;
+  std::vector<std::string> m_inputFiles;
+  std::vector<std::string> m_pixelFiles;
+  std::string m_alignmentFile;
+  std::string m_timingFile;
+  std::vector<std::string> m_etaFiles;
+
+  /// Pointer to message stream
+  mutable MsgStream* m_msg = nullptr;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+  /// Add the prefix for reading network files.
+  std::string expandPath(const std::string& fname);
+};
+
+#endif
diff --git a/TbKernel/src/.svn/text-base/TbGeometrySvc.cpp.svn-base b/TbKernel/src/.svn/text-base/TbGeometrySvc.cpp.svn-base
new file mode 100644
index 0000000..f9274bf
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbGeometrySvc.cpp.svn-base
@@ -0,0 +1,253 @@
+#include <fstream>
+
+// ROOT
+#include "Math/Translation3D.h"
+#include "Math/RotationZYX.h"
+
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Service.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbKernel/TbCondFile.h"
+#include "TbKernel/ITbDataSvc.h"
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+#include "TbGeometrySvc.h"
+
+DECLARE_SERVICE_FACTORY(TbGeometrySvc)
+
+//============================================================================
+// Constructor
+//============================================================================
+TbGeometrySvc::TbGeometrySvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc),
+      m_modules(),
+      m_moduleIndex(),
+      m_deviceIndex(),
+      m_planes(),
+      m_nDevices(0),
+      m_msg(nullptr) {}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbGeometrySvc::~TbGeometrySvc() {
+
+  // Delete the modules.
+  for (auto it = m_modules.begin(), end = m_modules.end(); it != end; ++it) {
+    if (*it) delete (*it);
+  }
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbGeometrySvc::initialize() {
+
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+
+  const std::string& filename =
+      Gaudi::svcLocator()->service<ITbDataSvc>("TbDataSvc")->getAlignmentFile();
+  msg() << MSG::INFO << "Importing alignment conditions from " << filename
+        << endmsg;
+  // Import geometry conditions from alignment file.
+  if (!readConditions(filename, m_modules)) {
+    msg() << MSG::ERROR << "Cannot import alignment conditions" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  // Sort the modules by z-position.
+  std::sort(m_modules.begin(), m_modules.end(),
+            TbFunctors::LessByZ<const TbModule*>());
+  // Loop over the modules.
+  for (auto it = m_modules.begin(), end = m_modules.end(); it != end; ++it) {
+    // Map the name of the module to its index in the list.
+    const unsigned index = it - m_modules.begin();
+    const std::string name = (*it)->id();
+    m_moduleIndex[name] = index;
+    for (auto ic = (*it)->chips().begin(); ic != (*it)->chips().end(); ++ic)
+      m_planes[ic->id] = index;
+  }
+  // Cache the x-coordinates of the pixel centres for sensor tiles.
+  m_xTriple.resize(3 * Tb::NCols);
+  for (unsigned int chip = 0; chip < 3; ++chip) {
+    const double x0 = chip * (Tb::NCols + 2) * Tb::PixelPitch;
+    const unsigned int offset = chip * Tb::NCols;
+    for (unsigned int col = 0; col < Tb::NCols; ++col) {
+      const unsigned int scol = offset + col;
+      double x = x0 + (0.5 + col) * Tb::PixelPitch;
+      if (scol == 256 || col == 512) {
+        x -= 0.5 * Tb::PixelPitch;
+      } else if (scol == 255 || col == 511) {
+        x += 0.5 * Tb::PixelPitch;
+      }
+      m_xTriple[scol] = x;
+    }
+  }
+  printAlignment(m_modules);
+  return StatusCode::SUCCESS;
+}
+
+//============================================================================
+// Finalisation
+//============================================================================
+StatusCode TbGeometrySvc::finalize() { return Service::finalize(); }
+
+//============================================================================
+// Calculate the local coordinates (pixel centre) of a given pixel
+//============================================================================
+bool TbGeometrySvc::pixelToPoint(const unsigned int scol,
+                                 const unsigned int row,
+                                 const unsigned int plane, double& x,
+                                 double& y) {
+
+  if (m_modules[plane]->type() == TbModule::Tpx3) {
+    x = (scol + 0.5) * Tb::PixelPitch;
+    y = (row + 0.5) * Tb::PixelPitch;
+    return true;
+  } else if (m_modules[plane]->type() == TbModule::Tpx3Triple) {
+    x = m_xTriple[scol];
+    y = (row + 0.5) * Tb::PixelPitch;
+    return true;
+  }
+  return false;
+}
+
+//============================================================================
+// Calculate the pixel and inter-pixel position of a given local point
+//============================================================================
+bool TbGeometrySvc::pointToPixel(const double x, const double y,
+                                 const unsigned int plane, unsigned int& scol,
+                                 unsigned int& row) {
+
+  if (x < 0. || y < 0.) return false;
+  if (m_modules[plane]->type() == TbModule::Tpx3) {
+    const double fcol = x / Tb::PixelPitch;
+    const double frow = y / Tb::PixelPitch;
+    scol = int(fcol);
+    row = int(frow);
+    if (scol > 255 || row > 255) return false;
+    return true;
+  } else if (m_modules[plane]->type() == TbModule::Tpx3Triple) {
+    const double chipSize = Tb::NCols * Tb::PixelPitch;
+    const double interChipDistance = 2 * Tb::PixelPitch;
+    double x0 = 0.;
+    for (unsigned int i = 0; i < 3; ++i) {
+      const double xl = x - x0;
+      if (xl < chipSize + 0.5 * interChipDistance) {
+        unsigned int col = 0;
+        if (xl > 0.) {
+          col = int(xl / Tb::PixelPitch);
+          if (col >= Tb::NCols) col = Tb::NCols - 1;
+        }
+        scol = col + i * Tb::NCols;
+        row = int(y / Tb::PixelPitch);
+        if (row >= Tb::NRows) row = Tb::NRows - 1;
+        return true;
+      }
+      x0 += chipSize + interChipDistance;
+    }
+  }
+  return false;
+}
+
+//============================================================================
+// Calculate intercept of track with detector plane
+//============================================================================
+Gaudi::XYZPoint TbGeometrySvc::intercept(const LHCb::TbTrack* track,
+                                         const unsigned int i) {
+
+  const unsigned int nStates = track->states().size();
+  if (nStates > 1) {
+    auto states = track->states();
+    const double zPlane = m_modules[i]->centre().z();
+    if (zPlane < states.front().z()) {
+      return intercept(states.front().position(), states.front().slopes(), i);
+    } else if (zPlane > states.back().z()) {
+      return intercept(states.back().position(), states.back().slopes(), i);
+    }
+    for (auto it = states.cbegin(), end = states.cend(); it != end; ++it) {
+      if (zPlane < (*it).z()) {
+        const auto p = std::prev(it);
+        return intercept((*p).position(), (*p).slopes(), i);
+      }
+    }
+  }
+  return intercept(track->firstState().position(), track->firstState().slopes(),
+                   i);
+}
+
+//============================================================================
+// Import geometry conditions from alignment file
+//============================================================================
+bool TbGeometrySvc::readConditions(const std::string& filename,
+                                   std::vector<TbModule*>& modules) {
+  if (filename == "") return false;
+  TbCondFile f(filename);
+  if (!f.is_open()) return false;
+  while (!f.eof()) {
+    std::string line = "";
+    if (!f.getLine(line)) continue;
+    std::string id = "";
+    double dx(0.), dy(0.), dz(0.);
+    double rx(0.), ry(0.), rz(0.);
+    f.split(line, ' ', id, dx, dy, dz, rx, ry, rz);
+
+    TbModule* m = new TbModule();
+    std::string c1, c2, c3;
+    f.split(id, ',', c1, c2, c3);
+    m->setId(id);
+    m->setAlignment(dx, dy, dz, rx, ry, rz, 0., 0., 0., 0., 0., 0.);
+    m_deviceIndex[c1] = m_nDevices++;
+    if (c1 != "" && c2 != "" && c3 != "") {
+      m->setType(TbModule::Tpx3Triple);
+      m->addChip(c1);
+      m->addChip(c2);
+      m->addChip(c3);
+      m_deviceIndex[c2] = m_nDevices++;
+      m_deviceIndex[c3] = m_nDevices++;
+    } else {
+      m->setType(TbModule::Tpx3);
+      m->addChip(id);
+    }
+    modules.push_back(m);
+  }
+  f.close();
+  return true;
+}
+
+//============================================================================
+// Return the module for a given chip name
+//============================================================================
+TbModule* TbGeometrySvc::module(const std::string& id) {
+
+  if (m_moduleIndex.count(id) < 1) {
+    msg() << MSG::ERROR << "Module " << id << " not found" << endmsg;
+    return nullptr;
+  }
+
+  return m_modules[m_moduleIndex[id]];
+}
+
+//============================================================================
+// Print the geometry conditions for each module
+//============================================================================
+void TbGeometrySvc::printAlignment(const std::vector<TbModule*>& modules) {
+
+  for (auto it = modules.begin(), end = modules.end(); it != end; ++it) {
+    const std::string name = (*it)->id();
+    const unsigned index = m_moduleIndex[name];
+    // Print out the geometry conditions.
+    msg() << MSG::INFO << format("%2i", index) << format(" %-15s", name.c_str())
+          << format(" %10.3f", (*it)->x()) << format(" %10.3f", (*it)->y())
+          << format(" %10.3f", (*it)->z()) << format(" %10.3f", (*it)->rotX())
+          << format(" %10.3f", (*it)->rotY())
+          << format(" %10.3f", (*it)->rotZ()) << endmsg;
+  }
+}
diff --git a/TbKernel/src/.svn/text-base/TbGeometrySvc.h.svn-base b/TbKernel/src/.svn/text-base/TbGeometrySvc.h.svn-base
new file mode 100644
index 0000000..6407f97
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbGeometrySvc.h.svn-base
@@ -0,0 +1,117 @@
+#ifndef TBGEOMETRYSVC_H
+#define TBGEOMETRYSVC_H
+
+#include <map>
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/Transform3DTypes.h"
+
+// Local
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/TbModule.h"
+
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbGeometrySvc TbGeometrySvc.h
+ * Implementation of the testbeam geometry service.
+ *
+ */
+
+class TbGeometrySvc : public extends1<Service, ITbGeometrySvc> {
+
+ public:
+  /// Constructor
+  TbGeometrySvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbGeometrySvc();
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  /// Transform a point in the local frame of a plane to global coordinates
+  virtual Gaudi::XYZPoint localToGlobal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) {
+    return m_modules[i]->transform() * p;
+  }
+  /// Transform a point in the global frame to the local frame of a plane
+  virtual Gaudi::XYZPoint globalToLocal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) {
+    return m_modules[i]->inverse() * p;
+  }
+
+  /// Calculate the local x, y coordinates of a given pixel
+  virtual bool pixelToPoint(const unsigned int scol, const unsigned int row,
+                            const unsigned int plane, double& x, double& y);
+  /// Calculate the pixel and inter-pixel position of a given local point
+  virtual bool pointToPixel(const double x, const double y,
+                            const unsigned int plane, unsigned int& scol,
+                            unsigned int& row);
+
+  /// Calculate the intercept of a track with a telescope plane
+  virtual Gaudi::XYZPoint intercept(const LHCb::TbTrack* t,
+                                    const unsigned int i);
+
+  /// Return a pointer to the module object for a given plane index
+  virtual TbModule* module(const unsigned int i) { return m_modules[i]; }
+  /// Return a pointer to the module object of a given plane identifier
+  virtual TbModule* module(const std::string& det);
+  /// Return the list of modules
+  virtual const std::vector<TbModule*>& modules() { return m_modules; }
+
+  virtual unsigned int deviceIndex(const std::string& det) {
+    auto p = m_deviceIndex.find(det);
+    return p != m_deviceIndex.end() ? p->second : 999;
+  }
+  virtual unsigned int plane(const std::string& det) {
+    auto p = m_planes.find(det);
+    return p != m_planes.end() ? p->second : 999;
+  }
+
+  virtual unsigned int nDevices() const { return m_nDevices; }
+
+  bool readConditions(const std::string& filename,
+                      std::vector<TbModule*>& modules);
+  virtual void printAlignment(const std::vector<TbModule*>& modules);
+
+  virtual void setModule(unsigned int i, TbModule* module) {
+    m_modules[i] = module;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbGeometrySvc>;
+  /// Transforms for each plane
+  std::vector<TbModule*> m_modules;
+  /// Map of plane names and their indices in the list
+  std::map<std::string, unsigned int> m_moduleIndex;
+  /// Map of device ids to their chip names
+  std::map<std::string, unsigned int> m_deviceIndex;
+  /// Map of device names to their planes indices
+  std::map<std::string, unsigned int> m_planes;
+  unsigned int m_nDevices;
+
+  /// Cached x-coordinates of pixels on sensor tiles.
+  std::vector<double> m_xTriple;
+
+  /// Pointer to message stream
+  mutable MsgStream* m_msg;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+
+  /// Calculate the intercept of a straight line with a telescope plane
+  Gaudi::XYZPoint intercept(const Gaudi::XYZPoint& p, const Gaudi::XYZVector& t,
+                            const unsigned int i) {
+    const Gaudi::XYZVector n = m_modules[i]->normal();
+    const double s = n.Dot(m_modules[i]->centre() - p) / n.Dot(t);
+    return p + s * t;
+  }
+
+};
+
+#endif
diff --git a/TbKernel/src/.svn/text-base/TbKalmanTrackFit.cpp.svn-base b/TbKernel/src/.svn/text-base/TbKalmanTrackFit.cpp.svn-base
new file mode 100644
index 0000000..d596b1c
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbKalmanTrackFit.cpp.svn-base
@@ -0,0 +1,93 @@
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanNode.h"
+
+// Local
+#include "TbKalmanTrackFit.h"
+
+DECLARE_TOOL_FACTORY(TbKalmanTrackFit)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbKalmanTrackFit::TbKalmanTrackFit(const std::string& type,
+                                   const std::string& name,
+                                   const IInterface* parent)
+    : GaudiTool(type, name, parent), m_fitter(nullptr), m_geomSvc(nullptr) {
+
+  declareInterface<ITbTrackFit>(this);
+
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+  declareProperty("HitError", m_hiterror = 0.004);
+  declareProperty("Noise2", m_scat2 = 1.2e-8);
+
+  m_hiterror2 = m_hiterror * m_hiterror;
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbKalmanTrackFit::~TbKalmanTrackFit() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbKalmanTrackFit::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+  // Get the straight-line fit tool (used for seeding the Kalman filter).
+  m_fitter = tool<ITbTrackFit>("TbTrackFit", "StraightLineFitter", this);
+  // Get the number of telescope planes.
+  const auto nPlanes = geomSvc()->modules().size();
+  // Set the flags whether a plane is masked or not.
+  m_masked.resize(nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) {
+    m_masked[plane] = true;
+    m_fitter->maskPlane(plane);
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Exclude a plane from the fit
+//=============================================================================
+void TbKalmanTrackFit::maskPlane(const unsigned int plane) {
+
+  m_masked[plane] = true;
+  m_fitter->maskPlane(plane);
+}
+
+//=============================================================================
+// (Re-)include a plane in the fit
+//=============================================================================
+void TbKalmanTrackFit::unmaskPlane(const unsigned int plane) {
+
+  m_masked[plane] = false;
+  m_fitter->unmaskPlane(plane);
+}
+
+//=========================================================================
+// Perform the fit
+//=========================================================================
+void TbKalmanTrackFit::fit(LHCb::TbTrack* track) {
+
+  // Make a straight-line fit.
+  m_fitter->fit(track);
+  // Create a Kalman track.
+  LHCb::TbKalmanTrack ktrack(*track, m_hiterror2, m_scat2);
+  // Run the Kalman filter.
+  ktrack.fit();
+  // Update the track states.
+  track->clearStates();
+  auto nodes = ktrack.nodes();
+  for (auto it = nodes.cbegin(), end = nodes.cend(); it != end; ++it) {
+    track->addToStates((*it)->state());
+  }
+  // Set the chi2.
+  track->setChi2PerNdof(ktrack.chi2PerNdof());
+  track->setNdof(ktrack.ndof());
+}
diff --git a/TbKernel/src/.svn/text-base/TbKalmanTrackFit.h.svn-base b/TbKernel/src/.svn/text-base/TbKalmanTrackFit.h.svn-base
new file mode 100644
index 0000000..e29ae7c
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbKalmanTrackFit.h.svn-base
@@ -0,0 +1,58 @@
+#ifndef TBTRACKFIT_H
+#define TBTRACKFIT_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+/** @class TbKalmanTrackFit TbKalmanTrackFit.h
+ * Track fit tool implementation using a Kalman-filter
+ *
+ */
+
+class TbKalmanTrackFit : public GaudiTool, virtual public ITbTrackFit {
+
+ public:
+  /// Constructor
+  TbKalmanTrackFit(const std::string& type, const std::string& name,
+                   const IInterface* parent);
+  /// Destructor
+  virtual ~TbKalmanTrackFit();
+
+  virtual StatusCode initialize();
+
+  /// Fit the track
+  virtual void fit(LHCb::TbTrack* track);
+
+  virtual void maskPlane(const unsigned int plane);
+  virtual void unmaskPlane(const unsigned int plane);
+
+ protected:
+  /// Indices of planes to be masked.
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+
+  /// Hit error
+  double m_hiterror;
+  /// Hit error squared
+  double m_hiterror2;
+  /// Noise term squared
+  double m_scat2;
+
+  /// Straight-line fit
+  ITbTrackFit* m_fitter;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/.svn/text-base/TbPixelSvc.cpp.svn-base b/TbKernel/src/.svn/text-base/TbPixelSvc.cpp.svn-base
new file mode 100644
index 0000000..4f0f9f7
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbPixelSvc.cpp.svn-base
@@ -0,0 +1,307 @@
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+
+// Local
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbCondFile.h"
+#include "TbKernel/ITbDataSvc.h"
+#include "TbPixelSvc.h"
+
+DECLARE_SERVICE_FACTORY(TbPixelSvc)
+
+//============================================================================
+// Constructor
+//============================================================================
+TbPixelSvc::TbPixelSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc), m_geomSvc(nullptr), m_msg(nullptr) {
+  declareProperty("WriteTrimDACs", m_writeTrimDACs = false);
+}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbPixelSvc::~TbPixelSvc() {
+
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbPixelSvc::initialize() {
+
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+  // Get the number of chips.
+  const unsigned int nDevices = geomSvc()->nDevices();
+  m_pixelConfiguration.resize(nDevices);
+
+  m_protectPhase = std::vector<bool>(nDevices, 0);
+  for (unsigned int i = 0; i < nDevices; ++i) {
+    m_pixelConfiguration[i].resize(Tb::NPixels, PixelConfig());
+  }
+  // Retrieve the names of the configuration files to be parsed.
+  ITbDataSvc* dataSvc = Gaudi::svcLocator()->service<ITbDataSvc>("TbDataSvc");
+  std::vector<std::string> files = dataSvc->getPixelConfig();
+  files.push_back(dataSvc->getTimingConfig());
+  for (auto& f : files) {
+    if (f == "") continue;
+    msg() << MSG::INFO << "Importing pixel configuration from " << f << endmsg;
+    // Import conditions from configuration file.
+    if (!readConditions(f)) {
+      msg() << MSG::ERROR << "Cannot import pixel configuration" << endmsg;
+      return StatusCode::FAILURE;
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//============================================================================
+// Add a constant offset in time to a single super column
+//============================================================================
+void TbPixelSvc::addOffset(const int offset, const unsigned int device,
+                           const unsigned int dcol) {
+
+  for (unsigned int pix = 0; pix < 512; ++pix) {
+    const unsigned int address = pix + (0xFE00 & (dcol << 9));
+    m_pixelConfiguration[device][address].tOffset += offset;
+  }
+}
+
+//============================================================================
+// Export trim DACs and masked pixel flags to a text file
+//============================================================================
+void TbPixelSvc::writeTrimDAC(const unsigned int device) {
+  std::ofstream trimdac;
+  trimdac.open(("plane_" + std::to_string(device) + "_trimdac.txt").c_str());
+  trimdac << "#col  row trim mask tp_ena " << std::endl;
+  for (unsigned int col = 0; col < Tb::NCols; ++col) {
+    for (unsigned int row = 0; row < Tb::NRows; ++row) {
+      const unsigned int pixel = address(col, row);
+      trimdac << std::setw(3) << col << std::setw(4) << row << std::setw(4)
+              << (int)(m_pixelConfiguration[device][pixel].trim) << std::setw(4)
+              << m_pixelConfiguration[device][pixel].trimDac_isMasked
+              << std::setw(4) << m_pixelConfiguration[device][pixel].tp_ena
+              << std::endl;
+    }
+  }
+  trimdac.close();
+}
+
+//============================================================================
+// Set trim DACs for the entire pixel matrix of a chip
+//============================================================================
+void TbPixelSvc::setTrim(const unsigned int device, const char* data) {
+  for (unsigned int col = 0; col < Tb::NCols; ++col) {
+    for (unsigned int row = 0; row < Tb::NRows; ++row) {
+      const unsigned int pixel = address(col, row);
+      const uint8_t word = *(data + col + Tb::NRows * row);
+      m_pixelConfiguration[device][pixel].trim = 0xF & (word >> 1);
+      m_pixelConfiguration[device][pixel].tp_ena = 0x1 & (word >> 5);
+      m_pixelConfiguration[device][pixel].trimDac_isMasked = 0x1 & word;
+    }
+  }
+  if (m_writeTrimDACs) writeTrimDAC(device);
+}
+
+void TbPixelSvc::resetClockPhase(const unsigned int device) {
+
+  for (unsigned int pixel = 0; pixel < Tb::NPixels; ++pixel) {
+    m_pixelConfiguration[device][pixel].tOffset = 0;
+  }
+}
+
+//============================================================================
+// Calculate the clock phase correction.
+//============================================================================
+void TbPixelSvc::setPhase(const unsigned int device,
+                          const unsigned int pll_config = 1024,
+                          const int amplitude = 1) {
+  if (m_protectPhase[device]) return;
+  const unsigned int phase = pow(2, (pll_config & 0x1C0) >> 6);
+  if (phase == 1) return;
+
+  for (unsigned int pixel = 0; pixel < Tb::NPixels; ++pixel) {
+    // Decode the pixel address, first the double column.
+    const unsigned int dcol = (0xFE00 & pixel) >> 9;
+    // Get the pixel within the super pixel.
+    const unsigned int pix = (0x0007 & pixel);
+    // Calculate the column number.
+    const unsigned int col = 2 * dcol + pix / 4;
+    // col = col % 128;
+    int dt = 0;
+    if (phase == 16) {
+      dt = (-((16 - ((col / 2) % 16)) % 16)) << 8;
+    } else if (phase == 4) {
+      dt = (-4 * ((4 - ((col / 2) % 4)) % 4)) << 8;
+    } else if (phase == 2) {
+      dt = (((col % 4) < 2) ? 8 : 0) << 8;
+    }
+    m_pixelConfiguration[device][pixel].tOffset += amplitude * dt;
+  }
+  m_protectPhase[device] = true;
+}
+
+//============================================================================
+// Import pixel conditions from configuration file
+//============================================================================
+bool TbPixelSvc::readConditions(const std::string& filename) {
+
+  TbCondFile f(filename);
+  if (!f.is_open()) {
+    msg() << MSG::WARNING << "Cannot open " << filename << endmsg;
+    return false;
+  }
+  std::string mode = "";
+  std::string chip = "";
+  int deviceIndex = -1;
+  unsigned int col(0), row(0);
+  std::vector<unsigned int> badPixels;
+  while (!f.eof()) {
+    std::string line = "";
+    if (!f.getLine(line)) continue;
+    if (line.find("Charge") != std::string::npos) {
+      f.split(line, ' ', mode, chip);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        msg() << MSG::ERROR << "Stop parsing " << filename << endmsg;
+        break;
+      }
+    } else if (line.find("Mask") != std::string::npos ||
+        line.find("Offset") != std::string::npos ||
+        line.find("Timing") != std::string::npos ||
+        line.find("GlobalCharge") != std::string::npos ||
+        line.find("PLL") != std::string::npos) {
+      mode = line;
+    } else if (mode == "Charge") {
+      float a(0.), b(0.), c(0.), t(0.);
+      f.split(line, ' ', col, row, a, b, c, t);
+      const unsigned int pixel = address(col, row);
+
+      if( isnan(a) || isinf(a) || isnan(b) || isnan(c) || isnan(t) || isinf(b) || isinf(c) || isinf(t)){
+        badPixels.push_back(pixel);
+      }
+      m_pixelConfiguration[deviceIndex][pixel].p0 = a;
+      m_pixelConfiguration[deviceIndex][pixel].p1 = b;
+      m_pixelConfiguration[deviceIndex][pixel].c = c;
+      m_pixelConfiguration[deviceIndex][pixel].t = t;
+    } else if (mode == "Mask") {
+      f.split(line, ' ', chip, col, row);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      const unsigned int pixel = address(col, row);
+      msg() << MSG::INFO << "Masking pixel " << format("0x%04x", pixel)
+        << format(" (column %3d", col) << format(", row %3d)", row)
+        << " on device " << chip << endmsg;
+      m_pixelConfiguration[deviceIndex][pixel].isMasked = true;
+    } else if (mode == "GlobalCharge") {
+      double a(0.), b(0.), c(0.), t(0.);
+      f.split(line, ' ', chip, a, b, c, t);
+      //     if( isnan(a) || isnan(b) || isnan(c) || isnan(d) )
+
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      for (auto& pixel : m_pixelConfiguration[deviceIndex]) {
+        pixel.p0 = a;
+        pixel.p1 = b;
+        pixel.c = c;
+        pixel.t = t;
+      }
+      msg() << MSG::INFO << "Applying global charge calibration on device "
+        << chip << "(a = " << a << ", b = " << b << ", c = " << c
+        << ", t = " << t << ")" << endmsg;
+    } else if (mode == "Offset") {
+      int offset = 0;
+      f.split(line, ' ', chip, col, offset);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      msg() << MSG::INFO << "Adding time offset " << offset * 25 << " ns "
+        << "to double column " << col << " on chip " << chip << endmsg;
+      addOffset(offset * Tb::ToA, deviceIndex, col);
+    } else if (mode == "Timing") {
+      double dt = 0.;
+      f.split(line, ' ', chip, dt);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      const int offset = static_cast<int>(std::round(dt * Tb::nanosecond));
+      msg() << MSG::INFO << "Adding time offset " << dt << " ns (" << offset
+        << " time units) to chip " << chip << endmsg;
+      const unsigned int nDCols = Tb::NCols / 2;
+      for (unsigned int col = 0; col < nDCols; ++col) {
+        addOffset(offset, deviceIndex, col);
+      }
+    } else if (mode == "PLL") {
+      int amplitude = 0.;
+      unsigned int pll_mode;
+      f.split(line, ' ', chip, pll_mode, amplitude);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      msg() << MSG::INFO << "Overwriting PLL CONFIG for chip " << chip
+        << endmsg;
+      m_protectPhase[deviceIndex] = false;
+      resetClockPhase(deviceIndex);
+      setPhase(deviceIndex, pll_mode, amplitude);
+    }
+  }
+  for( auto& pixel : badPixels ){
+    auto pos = posFromAddress(pixel);
+    float avgt(0), avgc(0), avgp0(0), avgp1(0);
+    unsigned int nPixels=0;
+    if( pos.second != 255 ){
+      unsigned int neighbour = address( pos.first, pos.second+1 );
+      if( std::find( badPixels.begin(), badPixels.end(), neighbour) == badPixels.end() ){
+        avgt  += m_pixelConfiguration[deviceIndex][neighbour].t;
+        avgc  += m_pixelConfiguration[deviceIndex][neighbour].c;
+        avgp0 += m_pixelConfiguration[deviceIndex][neighbour].p0;
+        avgp1 += m_pixelConfiguration[deviceIndex][neighbour].p1;
+        nPixels++;
+      }
+    }
+    if( pos.second != 0 ){
+      unsigned int neighbour = address( pos.first, pos.second-1 );
+      if( std::find( badPixels.begin(), badPixels.end(), neighbour) == badPixels.end() ){
+        avgt  += m_pixelConfiguration[deviceIndex][neighbour].t;
+        avgc  += m_pixelConfiguration[deviceIndex][neighbour].c;
+        avgp0 += m_pixelConfiguration[deviceIndex][neighbour].p0;
+        avgp1 += m_pixelConfiguration[deviceIndex][neighbour].p1;
+        nPixels++;
+      }
+    }
+    if(nPixels==0){ 
+      m_pixelConfiguration[deviceIndex][pixel].isMasked = true;
+     // printConfig( deviceIndex, pixel ) ;
+      continue;
+    }
+    m_pixelConfiguration[deviceIndex][pixel].t = avgt / (float)nPixels;
+    m_pixelConfiguration[deviceIndex][pixel].p0 = avgp0 / (float)nPixels;
+    m_pixelConfiguration[deviceIndex][pixel].p1 = avgp1 / (float)nPixels;
+    m_pixelConfiguration[deviceIndex][pixel].c = avgc / (float)nPixels;
+    //printConfig( deviceIndex, pixel ) ;
+  }
+  f.close();
+  return true;
+}
diff --git a/TbKernel/src/.svn/text-base/TbPixelSvc.h.svn-base b/TbKernel/src/.svn/text-base/TbPixelSvc.h.svn-base
new file mode 100644
index 0000000..99f8cfa
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbPixelSvc.h.svn-base
@@ -0,0 +1,191 @@
+#ifndef TBPIXELSVC_H
+#define TBPIXELSVC_H
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+
+// Local
+#include "TbKernel/ITbPixelSvc.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+#include <stdint.h>
+
+// struct PixelConfig;
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbPixelSvc TbPixelSvc.h
+ *
+ * Implementation of the Timepix3 pixel configuration service.
+ *
+ */
+
+class TbPixelSvc : public extends1<Service, ITbPixelSvc> {
+
+ public:
+  /// Constructor
+  TbPixelSvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbPixelSvc();
+
+  virtual StatusCode initialize();
+
+  /// Get the pixel address for a given column and row.
+  virtual unsigned int address(const unsigned int col,
+                               const unsigned int row) const {
+    // Get the double-column and super-pixel.
+    const unsigned int dcol = col / 2;
+    const unsigned int spix = row / 4;
+    // Get the pixel number within the superpixel.
+    unsigned int pix = row % 4;
+    if (1 == col % 2) pix += 4;
+    return (dcol << 9) + (spix << 3) + pix;
+  }
+  std::pair<unsigned int, unsigned int> posFromAddress( const unsigned int& address ) const {
+    std::pair<unsigned int, unsigned int> pos;
+    // Decode the pixel address, first get the double column. 
+    const unsigned int dcol = (0xFE00 & address) >> 8;
+    // Get the super pixel address.
+    const unsigned int spix = (0x01F8 & address) >> 1;
+    // Get the address of the pixel within the super pixel. 
+    const unsigned int pix = (0x0007 & address); 
+    // Calculate the row and column numbers.
+    pos.first = dcol + pix / 4;
+    pos.second = spix + (pix & 0x3);
+    return pos;
+  }
+
+  /// Return whether the pixel has been masked.
+  virtual bool isMasked(const unsigned int address,
+      const unsigned int device) const {
+    return m_pixelConfiguration[device][address].isMasked ||
+           m_pixelConfiguration[device][address].trimDac_isMasked;
+  }
+
+  /// Correct the timestamp of a given hit.
+  virtual void applyPhaseCorrection(LHCb::TbHit* h) {
+    h->setTime(h->time() +
+        m_pixelConfiguration[h->device()][h->pixelAddress()].tOffset);
+  }
+
+  /// Set the clock phase correction.
+  virtual void setPhase(const unsigned int device,
+      const unsigned int pll_config, const int amplitude);
+
+  /// Set trim DACs.
+  virtual void setTrim(const unsigned int device, const char* data);
+
+  /// Convert time-over-threshold to charge.
+  virtual double charge(const unsigned int tot, const unsigned int address,
+      const unsigned int device) const {
+    const PixelConfig& conf = m_pixelConfiguration[device][address];
+    double value=inverseSurrogate(tot, conf.p1, conf.p0, conf.c, conf.t);
+    if( isnan(value)  ){ 
+      auto pos = posFromAddress( address );
+      warning() << "Pixel " << device << "/0x" 
+                << std::hex << address << std::dec << " tot = " << tot  
+                << " (" << pos.first << ", " << pos.second 
+                << ")" << conf.p1 << "  " << conf.p0 << "   " << conf.c << "   " << conf.t << endmsg;
+      return 1;
+    }
+    return value;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbPixelSvc>;
+
+  struct PixelConfig {
+    PixelConfig()
+      : isMasked(false),
+      trimDac_isMasked(false),
+      isDead(false),
+      tp_ena(0),
+      trim(4),
+      tOffset(0),
+      p0(0),
+      p1(1),
+      c(0),
+      t(0) {};
+    bool isMasked;
+    bool trimDac_isMasked;
+    bool isDead;
+    bool tp_ena;
+    uint8_t trim;
+    int tOffset;
+    /// Parameters of surrogate function
+    float p0;
+    float p1;
+    float c;
+    float t;
+  };
+
+
+  void resetClockPhase(const unsigned int device);
+  /// Add a constant offset in time to a single super column.
+  void addOffset(const int offset, const unsigned int device,
+      const unsigned int dcol);
+
+  /// Pixel configuration for each chip
+  std::vector<std::vector<PixelConfig> > m_pixelConfiguration;
+
+  void printConfig( const unsigned int& plane, const unsigned int& address){
+    auto pos = posFromAddress(address);
+    PixelConfig& conf = m_pixelConfiguration[plane][address];
+    info() << std::hex << "0x" << address << std::dec << " = ("<<pos.first << ", " << pos.second << ") : " << conf.p0 << " " << conf.p1 << " " << conf.c << "  " << conf.t << endmsg;
+  }
+  /// Functionality to write out the trim dacs written into the header
+  bool m_writeTrimDACs;
+  void writeTrimDAC(const unsigned int device);
+
+  /// ignore PLL config
+  std::vector<bool> m_protectPhase;
+  /// Surrogate function, taken from http://arxiv.org/pdf/1103.2739v3.pdf
+  double surrogate(const double& charge, const double& a, const double& b,
+      const double& c, const double& t) const {
+    double result = 0.;
+    const double r = (b + a * t);
+    const double d = r * r + 4 * a * c;
+    if (d > 0.) {
+      const double itcpt = ((t * a - b) + sqrt(d)) / (2 * a);
+      if (charge > itcpt) {
+        result = a * charge + b - c / (charge - t);
+      }
+    }
+    return result;
+  }
+
+  double inverseSurrogate(const uint32_t tot, const double a, const double b,
+      const double c, const double t) const {
+    double result = 1.;
+    const double r = (b + a * t - tot);
+    const double d = r * r + 4. * a * c;
+    if (d > 0.) {
+      result = (a * t + tot - b + sqrt(d)) / (2. * a);
+    }
+    return result;
+  }
+
+  bool readConditions(const std::string& file);
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) {
+      m_geomSvc = Gaudi::svcLocator()->service<ITbGeometrySvc>("TbGeometrySvc");
+    }
+    return m_geomSvc;
+  }
+  /// Pointer to message stream
+  mutable MsgStream* m_msg;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/.svn/text-base/TbTimingSvc.cpp.svn-base b/TbKernel/src/.svn/text-base/TbTimingSvc.cpp.svn-base
new file mode 100644
index 0000000..c98ec3b
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbTimingSvc.cpp.svn-base
@@ -0,0 +1,67 @@
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+
+// Local
+#include "TbTimingSvc.h"
+
+DECLARE_SERVICE_FACTORY(TbTimingSvc)
+
+//============================================================================
+// Constructor
+//============================================================================
+TbTimingSvc::TbTimingSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc),
+      m_evtMinTime(0UL),
+      m_evtMaxTime(0UL),
+      m_msg(NULL) {}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbTimingSvc::~TbTimingSvc() {
+
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbTimingSvc::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//============================================================================
+// Finalisation
+//============================================================================
+StatusCode TbTimingSvc::finalize() {
+
+  // Finalise the base class.
+  return Service::finalize();
+}
+
+//============================================================================
+// Convert local time (in ns) to global timestamp.
+//============================================================================
+uint64_t TbTimingSvc::localToGlobal(const double& htime) {
+
+  // Conversion factor (25 ns correspond to 4096 global time units).
+  constexpr double f = 4096. / 25.;
+  const double dt = floor(htime * f);
+  return dt < 0. ? m_evtMinTime - static_cast<uint64_t>(fabs(dt))
+                 : m_evtMinTime + static_cast<uint64_t>(dt);
+}
+
+//============================================================================
+// Convert global timestamp to local time (in ns).
+//============================================================================
+double TbTimingSvc::globalToLocal(const uint64_t& time) {
+  // Conversion factor (4096 global time units correspond to 25 ns).
+  constexpr double f = 25. / 4096.;
+  return time < m_evtMinTime ? -f * (m_evtMinTime - time)
+                             : f * (time - m_evtMinTime);
+}
diff --git a/TbKernel/src/.svn/text-base/TbTimingSvc.h.svn-base b/TbKernel/src/.svn/text-base/TbTimingSvc.h.svn-base
new file mode 100644
index 0000000..9af513a
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbTimingSvc.h.svn-base
@@ -0,0 +1,77 @@
+#ifndef TBTIMINGSVC_H
+#define TBTIMINGSVC_H 1
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+
+// Local
+#include "TbKernel/ITbTimingSvc.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbTimingSvc TbTimingSvc.h
+ *
+ * Implementation of the testbeam timing service.
+ *
+ */
+
+class TbTimingSvc : public extends1<Service, ITbTimingSvc> {
+
+ public:
+  /// Constructor
+  TbTimingSvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbTimingSvc();
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  virtual uint64_t localToGlobal(const double& htime);
+  virtual double globalToLocal(const uint64_t& time);
+
+  virtual void setEventDefinition(const uint64_t& evtMinTime,
+                                  const uint64_t& evtMaxTime) {
+    m_evtMinTime = evtMinTime;
+    m_evtMaxTime = evtMaxTime;
+  }
+  virtual void eventDefinition(uint64_t& evtMinTime,
+                               uint64_t& evtMaxTime) const {
+    evtMinTime = m_evtMinTime;
+    evtMaxTime = m_evtMaxTime;
+  }
+
+  virtual void setOverlap(const uint64_t& overlap) { m_overlap = overlap; }
+  virtual bool inEvent(const uint64_t& time) const {
+    return time > m_evtMinTime && time < m_evtMaxTime;
+  }
+  virtual bool inOverlap(const uint64_t& time) const {
+    return time > m_evtMaxTime - m_overlap && time < m_evtMaxTime;
+  }
+  virtual bool beforeOverlap(const uint64_t& time) const {
+    return time < m_evtMaxTime - m_overlap;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbTimingSvc>;
+
+  /// Lower limit of the current event (in global time units)
+  uint64_t m_evtMinTime;
+  /// Upper limit of the current event (in global time units)
+  uint64_t m_evtMaxTime;
+  /// Overlap with the next event (in global time units)
+  uint64_t m_overlap;
+
+  /// Pointer to message stream
+  mutable MsgStream* m_msg;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/.svn/text-base/TbTrackFit.cpp.svn-base b/TbKernel/src/.svn/text-base/TbTrackFit.cpp.svn-base
new file mode 100644
index 0000000..8612e98
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbTrackFit.cpp.svn-base
@@ -0,0 +1,187 @@
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTrackFit.h"
+
+DECLARE_TOOL_FACTORY(TbTrackFit)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbTrackFit::TbTrackFit(const std::string& type, const std::string& name,
+                       const IInterface* parent)
+    : GaudiTool(type, name, parent), m_geomSvc(nullptr) {
+
+  declareInterface<ITbTrackFit>(this);
+
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTrackFit::~TbTrackFit() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbTrackFit::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+  // Get the number of telescope planes.
+  const auto nPlanes = geomSvc()->modules().size();
+  // Set the flags whether a plane is masked or not.
+  m_masked.resize(nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) {
+    m_masked[plane] = true;
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Exclude a plane from the fit
+//=============================================================================
+void TbTrackFit::maskPlane(const unsigned int plane) {
+
+  m_masked[plane] = true;
+}
+
+//=============================================================================
+// (Re-)include a plane in the fit
+//=============================================================================
+void TbTrackFit::unmaskPlane(const unsigned int plane) {
+
+  m_masked[plane] = false;
+}
+
+//=========================================================================
+/// Perform a straight-line fit to the clusters of a given track
+//=========================================================================
+void TbTrackFit::fit(LHCb::TbTrack* track) {
+
+  // Sums for the x-slope fit
+  double s0 = 0.;
+  double sx = 0.;
+  double sz = 0.;
+  double sxz = 0.;
+  double sz2 = 0.;
+  // Sums for the y-slope fit
+  double u0 = 0.;
+  double uy = 0.;
+  double uz = 0.;
+  double uyz = 0.;
+  double uz2 = 0.;
+
+  // Count the number of planes included in the fit.
+  unsigned int nd = 0;
+
+  // Loop through the clusters.
+  auto clusters = track->clusters();
+  for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+    if (!(*it)) continue;
+    // Skip masked planes.
+    if (m_masked[(*it)->plane()]) continue;
+    ++nd;
+    const double wx = (*it)->wx();
+    const double wy = (*it)->wy();
+    const double x = (*it)->x();
+    const double y = (*it)->y();
+    const double z = (*it)->z();
+
+    // Straight line fit in x
+    s0 += wx;
+    sx += wx * x;
+    sz += wx * z;
+    sxz += wx * x * z;
+    sz2 += wx * z * z;
+    // Straight line fit in y
+    u0 += wy;
+    uy += wy * y;
+    uz += wy * z;
+    uyz += wy * y * z;
+    uz2 += wy * z * z;
+  }
+  //  if (nd < 3) {
+  //    error() << "Invalid track. Only " << nd << " non-masked clusters" <<
+  // endmsg;
+  //    return;
+  //  }
+  // Compute the track parameters for x.
+
+  double den = (sz2 * s0 - sz * sz);
+
+  if (fabs(den) < 10e-10) den = 1.;
+  const double tx = (sxz * s0 - sx * sz) / den;
+  const double x0 = (sx * sz2 - sxz * sz) / den;
+
+  // Compute the track parameters for y.
+  den = (uz2 * u0 - uz * uz);
+  if (fabs(den) < 10e-10) den = 1.;
+  const double ty = (uyz * u0 - uy * uz) / den;
+  const double y0 = (uy * uz2 - uyz * uz) / den;
+
+  // Calculate the covariance matrix.
+  // Ad hoc matrix inversion, as it is almost diagonal.
+  // Some terms vanish since we calculate the covariance matrix at z = 0.
+  const double m00 = s0;
+  const double m11 = u0;
+  const double m20 = sz;
+  const double m31 = uz;
+  const double m22 = sz2;
+  const double m33 = uz2;
+  const double den20 = m22 * m00 - m20 * m20;
+  const double den31 = m33 * m11 - m31 * m31;
+
+  Gaudi::SymMatrix4x4 cov;
+  cov(0, 0) = m22 / den20;
+  cov(2, 0) = -m20 / den20;
+  cov(2, 2) = m00 / den20;
+
+  cov(1, 1) = m33 / den31;
+  cov(3, 1) = -m31 / den31;
+  cov(3, 3) = m11 / den31;
+
+  // Create the first state.
+  LHCb::TbState fstate(Gaudi::Vector4(x0, y0, tx, ty), cov, 0., 0);
+
+  fstate.covariance()(0, 0) = cov(0, 0);
+  fstate.covariance()(0, 2) = cov(2, 0);
+  fstate.covariance()(1, 1) = cov(1, 1);
+  fstate.covariance()(2, 2) = cov(2, 2);
+  fstate.covariance()(1, 3) = cov(3, 1);
+  fstate.covariance()(3, 3) = cov(3, 3);
+  // Update the firstState of the track.
+  track->setFirstState(fstate);
+
+  // Compute chi2 and track time.
+  double chi2 = 0.;
+  double time = 0.;
+  for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+    if (!(*it)) continue;
+    // Skip masked planes.
+    if (m_masked[(*it)->plane()]) continue;
+    const double wx = (*it)->wx();
+    const double wy = (*it)->wy();
+    const unsigned int plane = (*it)->plane();
+    // Calculate global (biased) residuals in x and y.
+    const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, plane);
+    const Gaudi::XYZPoint local = geomSvc()->globalToLocal(intercept, plane);
+
+    const double dx = (*it)->xloc() - local.x();
+    const double dy = (*it)->yloc() - local.y();
+    chi2 += (dx * dx) * wx + (dy * dy) * wy;
+    time += (*it)->htime();
+  }
+  // Set track chi2PerNdof and ndof.
+  const unsigned int ndof = 2 * nd - 4;
+  track->setNdof(ndof);
+  track->setChi2PerNdof(chi2 / (double)ndof);
+
+  // Finally, set the track time.
+  time /= nd;
+  track->setHtime(time);
+}
diff --git a/TbKernel/src/.svn/text-base/TbTrackFit.h.svn-base b/TbKernel/src/.svn/text-base/TbTrackFit.h.svn-base
new file mode 100644
index 0000000..ec33071
--- /dev/null
+++ b/TbKernel/src/.svn/text-base/TbTrackFit.h.svn-base
@@ -0,0 +1,51 @@
+#ifndef TBTRACKFIT_H
+#define TBTRACKFIT_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+/** @class TbTrackFit TbTrackFit.h
+ * Implementation of track fit for Timepix3 testbeam analysis
+ *
+ * @author Panagiotis Tsopelas
+ * @date 2014-05-06
+ *
+ */
+
+class TbTrackFit : public GaudiTool, virtual public ITbTrackFit {
+
+ public:
+  /// Constructor
+  TbTrackFit(const std::string& type, const std::string& name,
+             const IInterface* parent);
+  /// Destructor
+  virtual ~TbTrackFit();
+
+  virtual StatusCode initialize();
+
+  /// Fit the track and set its firstState
+  virtual void fit(LHCb::TbTrack* track);
+
+  virtual void maskPlane(const unsigned int plane);
+  virtual void unmaskPlane(const unsigned int plane);
+
+ protected:
+  /// Indices of planes to be masked.
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/TbClusterFinder.cpp b/TbKernel/src/TbClusterFinder.cpp
new file mode 100644
index 0000000..d292cad
--- /dev/null
+++ b/TbKernel/src/TbClusterFinder.cpp
@@ -0,0 +1,147 @@
+// Local
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbClusterFinder.h"
+
+DECLARE_TOOL_FACTORY(TbClusterFinder)
+
+//=============================================================================
+// Constructor
+//=============================================================================
+TbClusterFinder::TbClusterFinder(const std::string& type,
+                                 const std::string& name,
+                                 const IInterface* parent)
+    : GaudiTool(type, name, parent), m_searchAlgo(1) {
+
+  declareInterface<ITbClusterFinder>(this);
+}
+
+//=============================================================================
+// Set the search algorithm
+//=============================================================================
+void TbClusterFinder::setSearchAlgorithm(const std::string& searchAlgorithm) {
+
+  if (searchAlgorithm == "seq") {
+    m_searchAlgo = SearchMethod::Seq;
+  } else if (searchAlgorithm == "adap_seq") {
+    m_searchAlgo = SearchMethod::AdapSeq;
+  }
+}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbClusterFinder::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+
+  // Get the number of telescope planes from the geometry service.
+  ITbGeometrySvc* geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+  if (!geomSvc) {
+    error() << "Cannot access geometry service" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  const unsigned int nPlanes = geomSvc->modules().size();
+  m_first.resize(nPlanes);
+  m_last.resize(nPlanes);
+  m_end.resize(nPlanes);
+  m_nClusters.resize(nPlanes);
+  m_empty.resize(nPlanes);
+  m_prev_ts.resize(nPlanes);
+  m_prev.resize(nPlanes);
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Set the iterators and other properties for a given plane.
+//=============================================================================
+void TbClusterFinder::setClusters(LHCb::TbClusters* cs,
+                                  const unsigned int& plane) {
+
+  m_nClusters[plane] = cs->size();
+  m_empty[plane] = cs->empty();
+  if (!cs->empty()) {
+    m_first[plane] = cs->begin();
+    m_last[plane] = cs->end() - 1;
+    m_end[plane] = cs->end();
+    m_prev[plane] = cs->begin();
+    m_prev_ts[plane] = (*cs->begin())->htime();
+  }
+}
+
+//=============================================================================
+// Get iterator to first cluster on a given plane inside a given time window
+//=============================================================================
+TbClusterFinder::Iterator TbClusterFinder::getIterator(
+    const double& t, const unsigned int& plane) {
+
+  if (m_searchAlgo == SearchMethod::Seq) {
+    return seq_search(t, plane);
+  } else if (m_searchAlgo == SearchMethod::AdapSeq) {
+    return adap_seq_search(t, plane);
+  }
+  warning() << "Unknown search algorithm" << endmsg;
+  return adap_seq_search(t, plane);
+}
+
+//=============================================================================
+// Sequential search
+//=============================================================================
+TbClusterFinder::Iterator TbClusterFinder::seq_search(
+    const double& t, const unsigned int& plane) {
+
+  Iterator first = m_first[plane];
+  if (t <= (*first)->htime()) return first;
+  Iterator last = m_last[plane];
+  for (Iterator ic = first; ic != last; ++ic) {
+    if ((*ic)->htime() >= t) return ic;
+  }
+  return last;
+}
+
+//=============================================================================
+// Adaptive sequential search
+//=============================================================================
+TbClusterFinder::Iterator TbClusterFinder::adap_seq_search(
+    const double& t, const unsigned int& plane) {
+  // Returns the index in the clusters list of the cluster which arrived
+  // CURRENTLY RETURNS SOMETHING NEAR, BUT ISNT PERFECT.
+
+  // Get (and update) the previous timestamp.
+  const auto tPrev = m_prev_ts[plane];
+  m_prev_ts[plane] = t;
+
+  Iterator first = m_first[plane];
+  Iterator last = m_last[plane];
+  // Handle cases where requested time is outside the range of this plane.
+  if (t < (*first)->htime()) {
+    m_prev[plane] = first;
+    return first;
+  } else if (t >= (*last)->htime()) {
+    m_prev[plane] = last;
+    return last;
+  }
+
+  // Handle cases where requested time is inside the range of the clusters.
+  if (t == tPrev) {
+    // Case where t = previous asked t
+    // (Covers the case where t is equal to the first cluster, since this is
+    // default).
+    return m_prev[plane];
+  } else if (t < tPrev) {
+    // Case where t < previous asked t. (Unwise usage):
+    m_prev[plane] = first;
+    return first;
+  }
+
+  // Case where t > previous asked t (Majority of cases):
+  for (Iterator ic = m_prev[plane]; ic != last; ++ic) {
+    if ((*ic)->htime() >= t) {
+      m_prev[plane] = ic;
+      return ic;
+    }
+  }
+  m_prev[plane] = first;
+  return first;
+}
diff --git a/TbKernel/src/TbClusterFinder.h b/TbKernel/src/TbClusterFinder.h
new file mode 100644
index 0000000..34eb1c2
--- /dev/null
+++ b/TbKernel/src/TbClusterFinder.h
@@ -0,0 +1,66 @@
+#pragma once
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// Local
+#include "TbKernel/ITbClusterFinder.h"
+
+/** @class TbClusterFinder TbClusterFinder.h
+ *
+ *  This small class is used to find a particular cluster (on a particular
+ *  chip) nearest a particular time. This is done using a variety of funky
+ *  algorithms and conditions - specifically, using the condition that during
+ *  this object's lifetime, whenever asked to retrieve clusters for particular
+ *  time, these times are always increasing. (ALWAYS). Otherwise, expect O(N)
+ *  performance.
+ *
+ *  @author Dan Saunders
+ */
+
+class TbClusterFinder : public GaudiTool, virtual public ITbClusterFinder {
+ public:
+  typedef LHCb::TbClusters::const_iterator Iterator;
+  enum SearchMethod {
+    Seq = 1,
+    AdapSeq = 2
+  };
+
+  /// Standard constructor
+  TbClusterFinder(const std::string& type, const std::string& name,
+                  const IInterface* parent);
+  /// Destructor
+  virtual ~TbClusterFinder() {}
+
+  virtual StatusCode initialize();
+
+  /// Find iterator to first cluster on a given plane above a given time.
+  virtual Iterator getIterator(const double& t, const unsigned int& plane);
+  /// (Re)set the stored iterators for a given plane.
+  virtual void setClusters(LHCb::TbClusters* clusters,
+                           const unsigned int& plane);
+  /// Set the search algorithm to be used.
+  virtual void setSearchAlgorithm(const std::string& alg);
+
+  virtual Iterator first(const unsigned int& plane) const {
+    return m_first[plane];
+  }
+  virtual Iterator end(const unsigned int& plane) const { return m_end[plane]; }
+  virtual bool empty(const unsigned int& plane) const { return m_empty[plane]; }
+
+ private:
+  unsigned int m_searchAlgo;
+
+  std::vector<Iterator> m_first;
+  std::vector<Iterator> m_last;
+  std::vector<Iterator> m_end;
+  std::vector<unsigned int> m_nClusters;
+  std::vector<bool> m_empty;
+  std::vector<double> m_prev_ts;
+  std::vector<Iterator> m_prev;
+
+  /// Sequential search method
+  Iterator seq_search(const double& t, const unsigned int& plane);
+  /// Adaptive sequential search method
+  Iterator adap_seq_search(const double& t, const unsigned int& plane);
+};
diff --git a/TbKernel/src/TbDataSvc.cpp b/TbKernel/src/TbDataSvc.cpp
new file mode 100644
index 0000000..028f45c
--- /dev/null
+++ b/TbKernel/src/TbDataSvc.cpp
@@ -0,0 +1,120 @@
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+
+// Boost
+#include <boost/filesystem.hpp>
+
+// Local
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbCondFile.h"
+#include "TbDataSvc.h"
+
+DECLARE_SERVICE_FACTORY(TbDataSvc)
+
+namespace fs = boost::filesystem;
+
+//============================================================================
+// Constructor
+//============================================================================
+TbDataSvc::TbDataSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc) {
+
+  declareProperty("AlignmentFile", m_alignmentFile = "");
+  declareProperty("TimingConfigFile", m_timingFile = "");
+  declareProperty("PixelConfigFile", m_pixelFiles);
+  declareProperty("EtaConfigFiles", m_etaFiles);
+  declareProperty("Input", m_inputs);
+}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbDataSvc::~TbDataSvc() {
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Finalisation
+//============================================================================
+StatusCode TbDataSvc::finalize() { return Service::finalize(); }
+
+//============================================================================
+// Add the prefix for reading files from EOS/CASTOR
+//============================================================================
+std::string TbDataSvc::expandPath(const std::string& file) {
+
+  if (file.find("eos") == 0) {
+    return "root://eoslhcb.cern.ch//" + file;
+  }
+  return file;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbDataSvc::initialize() {
+
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+
+  if (m_inputs.empty()) {
+    error() << "No input files specified." << endmsg;
+    return StatusCode::FAILURE;
+  }
+  for (auto its = m_inputs.cbegin(), end = m_inputs.cend(); its != end; ++its) {
+    if (its->find("eos") == 0) {
+      // EOS path.
+      if (its->find(".dat") != std::string::npos) {
+        // Specified path is a raw data file. Add it to the list.
+        m_inputFiles.push_back(expandPath(*its));
+        continue;
+      }
+      // Assume the specified path is a directory and list its contents.
+      const std::string eospath =
+          "/afs/cern.ch/project/eos/installation/0.3.15/";
+      const std::string cmd = eospath + "bin/eos.select ls " + *its;
+      FILE* proc = popen(cmd.c_str(), "r");
+      char buf[4096];
+      // Loop over the entries.
+      while (!feof(proc) && fgets(buf, sizeof(buf), proc)) {
+        std::string fname = buf;
+        // Skip non-.dat files.
+        const size_t p = fname.find(".dat");
+        if (p == std::string::npos) continue;
+        // Add the file to the list.
+        fname = fname.substr(0, p + 4);
+        m_inputFiles.push_back(expandPath(*its + fname));
+      }
+      pclose(proc);
+    } else {
+      // Local file/directory.
+      fs::path path(*its);
+      if (!fs::exists(path)) {
+        warning() << "File or directory " << *its << " not found." << endmsg;
+        continue;
+      }
+      if (fs::is_directory(path)) {
+        fs::directory_iterator itdEnd;
+        for (fs::directory_iterator itd(path); itd != itdEnd; ++itd) {
+          if (is_regular_file(itd->status()))
+            m_inputFiles.push_back((*itd).path().string());
+        }
+      } else
+        m_inputFiles.push_back(*its);
+    }
+  }
+
+  if (m_inputFiles.empty()) {
+    error() << "No input files specified." << endmsg;
+    return StatusCode::FAILURE;
+  }
+  for (auto& f : m_inputFiles) info() << "Reading File: " << f << endmsg;
+
+  m_alignmentFile = expandPath(m_alignmentFile);
+  m_timingFile = expandPath(m_timingFile);
+  for (auto& f : m_pixelFiles) f = expandPath(f);
+  for (auto& f : m_etaFiles) f = expandPath(f);
+  return StatusCode::SUCCESS;
+}
diff --git a/TbKernel/src/TbDataSvc.h b/TbKernel/src/TbDataSvc.h
new file mode 100644
index 0000000..51477e2
--- /dev/null
+++ b/TbKernel/src/TbDataSvc.h
@@ -0,0 +1,67 @@
+#ifndef TBPIXELSVC_H
+#define TBPIXELSVC_H
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+
+// Local
+#include "TbKernel/ITbDataSvc.h"
+#include <stdint.h>
+
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbDataSvc TbDataSvc.h
+ *
+ * Implementation of the Testbeam data / configuration lookup services
+ * for use with EOS
+ */
+
+class TbDataSvc : public extends1<Service, ITbDataSvc> {
+
+ public:
+  /// Constructor
+  TbDataSvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbDataSvc();
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  virtual const std::vector<std::string>& getInputFiles() {
+    return m_inputFiles;
+  }
+  virtual const std::vector<std::string>& getPixelConfig() {
+    return m_pixelFiles;
+  }
+  virtual const std::string& getTimingConfig() { return m_timingFile; }
+  virtual const std::string& getAlignmentFile() { return m_alignmentFile; }
+  virtual const std::vector<std::string>& getEtaConfig() {
+    return m_etaFiles;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbDataSvc>;
+
+  std::vector<std::string> m_inputs;
+  std::vector<std::string> m_inputFiles;
+  std::vector<std::string> m_pixelFiles;
+  std::string m_alignmentFile;
+  std::string m_timingFile;
+  std::vector<std::string> m_etaFiles;
+
+  /// Pointer to message stream
+  mutable MsgStream* m_msg = nullptr;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+  /// Add the prefix for reading network files.
+  std::string expandPath(const std::string& fname);
+};
+
+#endif
diff --git a/TbKernel/src/TbGeometrySvc.cpp b/TbKernel/src/TbGeometrySvc.cpp
new file mode 100644
index 0000000..f9274bf
--- /dev/null
+++ b/TbKernel/src/TbGeometrySvc.cpp
@@ -0,0 +1,253 @@
+#include <fstream>
+
+// ROOT
+#include "Math/Translation3D.h"
+#include "Math/RotationZYX.h"
+
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Service.h"
+
+// Tb/TbEvent
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbKernel/TbCondFile.h"
+#include "TbKernel/ITbDataSvc.h"
+#include "TbKernel/TbFunctors.h"
+#include "TbKernel/TbConstants.h"
+#include "TbGeometrySvc.h"
+
+DECLARE_SERVICE_FACTORY(TbGeometrySvc)
+
+//============================================================================
+// Constructor
+//============================================================================
+TbGeometrySvc::TbGeometrySvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc),
+      m_modules(),
+      m_moduleIndex(),
+      m_deviceIndex(),
+      m_planes(),
+      m_nDevices(0),
+      m_msg(nullptr) {}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbGeometrySvc::~TbGeometrySvc() {
+
+  // Delete the modules.
+  for (auto it = m_modules.begin(), end = m_modules.end(); it != end; ++it) {
+    if (*it) delete (*it);
+  }
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbGeometrySvc::initialize() {
+
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+
+  const std::string& filename =
+      Gaudi::svcLocator()->service<ITbDataSvc>("TbDataSvc")->getAlignmentFile();
+  msg() << MSG::INFO << "Importing alignment conditions from " << filename
+        << endmsg;
+  // Import geometry conditions from alignment file.
+  if (!readConditions(filename, m_modules)) {
+    msg() << MSG::ERROR << "Cannot import alignment conditions" << endmsg;
+    return StatusCode::FAILURE;
+  }
+  // Sort the modules by z-position.
+  std::sort(m_modules.begin(), m_modules.end(),
+            TbFunctors::LessByZ<const TbModule*>());
+  // Loop over the modules.
+  for (auto it = m_modules.begin(), end = m_modules.end(); it != end; ++it) {
+    // Map the name of the module to its index in the list.
+    const unsigned index = it - m_modules.begin();
+    const std::string name = (*it)->id();
+    m_moduleIndex[name] = index;
+    for (auto ic = (*it)->chips().begin(); ic != (*it)->chips().end(); ++ic)
+      m_planes[ic->id] = index;
+  }
+  // Cache the x-coordinates of the pixel centres for sensor tiles.
+  m_xTriple.resize(3 * Tb::NCols);
+  for (unsigned int chip = 0; chip < 3; ++chip) {
+    const double x0 = chip * (Tb::NCols + 2) * Tb::PixelPitch;
+    const unsigned int offset = chip * Tb::NCols;
+    for (unsigned int col = 0; col < Tb::NCols; ++col) {
+      const unsigned int scol = offset + col;
+      double x = x0 + (0.5 + col) * Tb::PixelPitch;
+      if (scol == 256 || col == 512) {
+        x -= 0.5 * Tb::PixelPitch;
+      } else if (scol == 255 || col == 511) {
+        x += 0.5 * Tb::PixelPitch;
+      }
+      m_xTriple[scol] = x;
+    }
+  }
+  printAlignment(m_modules);
+  return StatusCode::SUCCESS;
+}
+
+//============================================================================
+// Finalisation
+//============================================================================
+StatusCode TbGeometrySvc::finalize() { return Service::finalize(); }
+
+//============================================================================
+// Calculate the local coordinates (pixel centre) of a given pixel
+//============================================================================
+bool TbGeometrySvc::pixelToPoint(const unsigned int scol,
+                                 const unsigned int row,
+                                 const unsigned int plane, double& x,
+                                 double& y) {
+
+  if (m_modules[plane]->type() == TbModule::Tpx3) {
+    x = (scol + 0.5) * Tb::PixelPitch;
+    y = (row + 0.5) * Tb::PixelPitch;
+    return true;
+  } else if (m_modules[plane]->type() == TbModule::Tpx3Triple) {
+    x = m_xTriple[scol];
+    y = (row + 0.5) * Tb::PixelPitch;
+    return true;
+  }
+  return false;
+}
+
+//============================================================================
+// Calculate the pixel and inter-pixel position of a given local point
+//============================================================================
+bool TbGeometrySvc::pointToPixel(const double x, const double y,
+                                 const unsigned int plane, unsigned int& scol,
+                                 unsigned int& row) {
+
+  if (x < 0. || y < 0.) return false;
+  if (m_modules[plane]->type() == TbModule::Tpx3) {
+    const double fcol = x / Tb::PixelPitch;
+    const double frow = y / Tb::PixelPitch;
+    scol = int(fcol);
+    row = int(frow);
+    if (scol > 255 || row > 255) return false;
+    return true;
+  } else if (m_modules[plane]->type() == TbModule::Tpx3Triple) {
+    const double chipSize = Tb::NCols * Tb::PixelPitch;
+    const double interChipDistance = 2 * Tb::PixelPitch;
+    double x0 = 0.;
+    for (unsigned int i = 0; i < 3; ++i) {
+      const double xl = x - x0;
+      if (xl < chipSize + 0.5 * interChipDistance) {
+        unsigned int col = 0;
+        if (xl > 0.) {
+          col = int(xl / Tb::PixelPitch);
+          if (col >= Tb::NCols) col = Tb::NCols - 1;
+        }
+        scol = col + i * Tb::NCols;
+        row = int(y / Tb::PixelPitch);
+        if (row >= Tb::NRows) row = Tb::NRows - 1;
+        return true;
+      }
+      x0 += chipSize + interChipDistance;
+    }
+  }
+  return false;
+}
+
+//============================================================================
+// Calculate intercept of track with detector plane
+//============================================================================
+Gaudi::XYZPoint TbGeometrySvc::intercept(const LHCb::TbTrack* track,
+                                         const unsigned int i) {
+
+  const unsigned int nStates = track->states().size();
+  if (nStates > 1) {
+    auto states = track->states();
+    const double zPlane = m_modules[i]->centre().z();
+    if (zPlane < states.front().z()) {
+      return intercept(states.front().position(), states.front().slopes(), i);
+    } else if (zPlane > states.back().z()) {
+      return intercept(states.back().position(), states.back().slopes(), i);
+    }
+    for (auto it = states.cbegin(), end = states.cend(); it != end; ++it) {
+      if (zPlane < (*it).z()) {
+        const auto p = std::prev(it);
+        return intercept((*p).position(), (*p).slopes(), i);
+      }
+    }
+  }
+  return intercept(track->firstState().position(), track->firstState().slopes(),
+                   i);
+}
+
+//============================================================================
+// Import geometry conditions from alignment file
+//============================================================================
+bool TbGeometrySvc::readConditions(const std::string& filename,
+                                   std::vector<TbModule*>& modules) {
+  if (filename == "") return false;
+  TbCondFile f(filename);
+  if (!f.is_open()) return false;
+  while (!f.eof()) {
+    std::string line = "";
+    if (!f.getLine(line)) continue;
+    std::string id = "";
+    double dx(0.), dy(0.), dz(0.);
+    double rx(0.), ry(0.), rz(0.);
+    f.split(line, ' ', id, dx, dy, dz, rx, ry, rz);
+
+    TbModule* m = new TbModule();
+    std::string c1, c2, c3;
+    f.split(id, ',', c1, c2, c3);
+    m->setId(id);
+    m->setAlignment(dx, dy, dz, rx, ry, rz, 0., 0., 0., 0., 0., 0.);
+    m_deviceIndex[c1] = m_nDevices++;
+    if (c1 != "" && c2 != "" && c3 != "") {
+      m->setType(TbModule::Tpx3Triple);
+      m->addChip(c1);
+      m->addChip(c2);
+      m->addChip(c3);
+      m_deviceIndex[c2] = m_nDevices++;
+      m_deviceIndex[c3] = m_nDevices++;
+    } else {
+      m->setType(TbModule::Tpx3);
+      m->addChip(id);
+    }
+    modules.push_back(m);
+  }
+  f.close();
+  return true;
+}
+
+//============================================================================
+// Return the module for a given chip name
+//============================================================================
+TbModule* TbGeometrySvc::module(const std::string& id) {
+
+  if (m_moduleIndex.count(id) < 1) {
+    msg() << MSG::ERROR << "Module " << id << " not found" << endmsg;
+    return nullptr;
+  }
+
+  return m_modules[m_moduleIndex[id]];
+}
+
+//============================================================================
+// Print the geometry conditions for each module
+//============================================================================
+void TbGeometrySvc::printAlignment(const std::vector<TbModule*>& modules) {
+
+  for (auto it = modules.begin(), end = modules.end(); it != end; ++it) {
+    const std::string name = (*it)->id();
+    const unsigned index = m_moduleIndex[name];
+    // Print out the geometry conditions.
+    msg() << MSG::INFO << format("%2i", index) << format(" %-15s", name.c_str())
+          << format(" %10.3f", (*it)->x()) << format(" %10.3f", (*it)->y())
+          << format(" %10.3f", (*it)->z()) << format(" %10.3f", (*it)->rotX())
+          << format(" %10.3f", (*it)->rotY())
+          << format(" %10.3f", (*it)->rotZ()) << endmsg;
+  }
+}
diff --git a/TbKernel/src/TbGeometrySvc.h b/TbKernel/src/TbGeometrySvc.h
new file mode 100644
index 0000000..6407f97
--- /dev/null
+++ b/TbKernel/src/TbGeometrySvc.h
@@ -0,0 +1,117 @@
+#ifndef TBGEOMETRYSVC_H
+#define TBGEOMETRYSVC_H
+
+#include <map>
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/Transform3DTypes.h"
+
+// Local
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/TbModule.h"
+
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbGeometrySvc TbGeometrySvc.h
+ * Implementation of the testbeam geometry service.
+ *
+ */
+
+class TbGeometrySvc : public extends1<Service, ITbGeometrySvc> {
+
+ public:
+  /// Constructor
+  TbGeometrySvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbGeometrySvc();
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  /// Transform a point in the local frame of a plane to global coordinates
+  virtual Gaudi::XYZPoint localToGlobal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) {
+    return m_modules[i]->transform() * p;
+  }
+  /// Transform a point in the global frame to the local frame of a plane
+  virtual Gaudi::XYZPoint globalToLocal(const Gaudi::XYZPoint& p,
+                                        const unsigned int i) {
+    return m_modules[i]->inverse() * p;
+  }
+
+  /// Calculate the local x, y coordinates of a given pixel
+  virtual bool pixelToPoint(const unsigned int scol, const unsigned int row,
+                            const unsigned int plane, double& x, double& y);
+  /// Calculate the pixel and inter-pixel position of a given local point
+  virtual bool pointToPixel(const double x, const double y,
+                            const unsigned int plane, unsigned int& scol,
+                            unsigned int& row);
+
+  /// Calculate the intercept of a track with a telescope plane
+  virtual Gaudi::XYZPoint intercept(const LHCb::TbTrack* t,
+                                    const unsigned int i);
+
+  /// Return a pointer to the module object for a given plane index
+  virtual TbModule* module(const unsigned int i) { return m_modules[i]; }
+  /// Return a pointer to the module object of a given plane identifier
+  virtual TbModule* module(const std::string& det);
+  /// Return the list of modules
+  virtual const std::vector<TbModule*>& modules() { return m_modules; }
+
+  virtual unsigned int deviceIndex(const std::string& det) {
+    auto p = m_deviceIndex.find(det);
+    return p != m_deviceIndex.end() ? p->second : 999;
+  }
+  virtual unsigned int plane(const std::string& det) {
+    auto p = m_planes.find(det);
+    return p != m_planes.end() ? p->second : 999;
+  }
+
+  virtual unsigned int nDevices() const { return m_nDevices; }
+
+  bool readConditions(const std::string& filename,
+                      std::vector<TbModule*>& modules);
+  virtual void printAlignment(const std::vector<TbModule*>& modules);
+
+  virtual void setModule(unsigned int i, TbModule* module) {
+    m_modules[i] = module;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbGeometrySvc>;
+  /// Transforms for each plane
+  std::vector<TbModule*> m_modules;
+  /// Map of plane names and their indices in the list
+  std::map<std::string, unsigned int> m_moduleIndex;
+  /// Map of device ids to their chip names
+  std::map<std::string, unsigned int> m_deviceIndex;
+  /// Map of device names to their planes indices
+  std::map<std::string, unsigned int> m_planes;
+  unsigned int m_nDevices;
+
+  /// Cached x-coordinates of pixels on sensor tiles.
+  std::vector<double> m_xTriple;
+
+  /// Pointer to message stream
+  mutable MsgStream* m_msg;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+
+  /// Calculate the intercept of a straight line with a telescope plane
+  Gaudi::XYZPoint intercept(const Gaudi::XYZPoint& p, const Gaudi::XYZVector& t,
+                            const unsigned int i) {
+    const Gaudi::XYZVector n = m_modules[i]->normal();
+    const double s = n.Dot(m_modules[i]->centre() - p) / n.Dot(t);
+    return p + s * t;
+  }
+
+};
+
+#endif
diff --git a/TbKernel/src/TbKalmanTrackFit.cpp b/TbKernel/src/TbKalmanTrackFit.cpp
new file mode 100644
index 0000000..d596b1c
--- /dev/null
+++ b/TbKernel/src/TbKalmanTrackFit.cpp
@@ -0,0 +1,93 @@
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanNode.h"
+
+// Local
+#include "TbKalmanTrackFit.h"
+
+DECLARE_TOOL_FACTORY(TbKalmanTrackFit)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbKalmanTrackFit::TbKalmanTrackFit(const std::string& type,
+                                   const std::string& name,
+                                   const IInterface* parent)
+    : GaudiTool(type, name, parent), m_fitter(nullptr), m_geomSvc(nullptr) {
+
+  declareInterface<ITbTrackFit>(this);
+
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+  declareProperty("HitError", m_hiterror = 0.004);
+  declareProperty("Noise2", m_scat2 = 1.2e-8);
+
+  m_hiterror2 = m_hiterror * m_hiterror;
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbKalmanTrackFit::~TbKalmanTrackFit() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbKalmanTrackFit::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+  // Get the straight-line fit tool (used for seeding the Kalman filter).
+  m_fitter = tool<ITbTrackFit>("TbTrackFit", "StraightLineFitter", this);
+  // Get the number of telescope planes.
+  const auto nPlanes = geomSvc()->modules().size();
+  // Set the flags whether a plane is masked or not.
+  m_masked.resize(nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) {
+    m_masked[plane] = true;
+    m_fitter->maskPlane(plane);
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Exclude a plane from the fit
+//=============================================================================
+void TbKalmanTrackFit::maskPlane(const unsigned int plane) {
+
+  m_masked[plane] = true;
+  m_fitter->maskPlane(plane);
+}
+
+//=============================================================================
+// (Re-)include a plane in the fit
+//=============================================================================
+void TbKalmanTrackFit::unmaskPlane(const unsigned int plane) {
+
+  m_masked[plane] = false;
+  m_fitter->unmaskPlane(plane);
+}
+
+//=========================================================================
+// Perform the fit
+//=========================================================================
+void TbKalmanTrackFit::fit(LHCb::TbTrack* track) {
+
+  // Make a straight-line fit.
+  m_fitter->fit(track);
+  // Create a Kalman track.
+  LHCb::TbKalmanTrack ktrack(*track, m_hiterror2, m_scat2);
+  // Run the Kalman filter.
+  ktrack.fit();
+  // Update the track states.
+  track->clearStates();
+  auto nodes = ktrack.nodes();
+  for (auto it = nodes.cbegin(), end = nodes.cend(); it != end; ++it) {
+    track->addToStates((*it)->state());
+  }
+  // Set the chi2.
+  track->setChi2PerNdof(ktrack.chi2PerNdof());
+  track->setNdof(ktrack.ndof());
+}
diff --git a/TbKernel/src/TbKalmanTrackFit.h b/TbKernel/src/TbKalmanTrackFit.h
new file mode 100644
index 0000000..e29ae7c
--- /dev/null
+++ b/TbKernel/src/TbKalmanTrackFit.h
@@ -0,0 +1,58 @@
+#ifndef TBTRACKFIT_H
+#define TBTRACKFIT_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+/** @class TbKalmanTrackFit TbKalmanTrackFit.h
+ * Track fit tool implementation using a Kalman-filter
+ *
+ */
+
+class TbKalmanTrackFit : public GaudiTool, virtual public ITbTrackFit {
+
+ public:
+  /// Constructor
+  TbKalmanTrackFit(const std::string& type, const std::string& name,
+                   const IInterface* parent);
+  /// Destructor
+  virtual ~TbKalmanTrackFit();
+
+  virtual StatusCode initialize();
+
+  /// Fit the track
+  virtual void fit(LHCb::TbTrack* track);
+
+  virtual void maskPlane(const unsigned int plane);
+  virtual void unmaskPlane(const unsigned int plane);
+
+ protected:
+  /// Indices of planes to be masked.
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+
+  /// Hit error
+  double m_hiterror;
+  /// Hit error squared
+  double m_hiterror2;
+  /// Noise term squared
+  double m_scat2;
+
+  /// Straight-line fit
+  ITbTrackFit* m_fitter;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/TbPixelSvc.cpp b/TbKernel/src/TbPixelSvc.cpp
new file mode 100644
index 0000000..4f0f9f7
--- /dev/null
+++ b/TbKernel/src/TbPixelSvc.cpp
@@ -0,0 +1,307 @@
+#include <algorithm>
+#include <fstream>
+#include <sstream>
+
+// Local
+#include "TbKernel/TbConstants.h"
+#include "TbKernel/TbCondFile.h"
+#include "TbKernel/ITbDataSvc.h"
+#include "TbPixelSvc.h"
+
+DECLARE_SERVICE_FACTORY(TbPixelSvc)
+
+//============================================================================
+// Constructor
+//============================================================================
+TbPixelSvc::TbPixelSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc), m_geomSvc(nullptr), m_msg(nullptr) {
+  declareProperty("WriteTrimDACs", m_writeTrimDACs = false);
+}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbPixelSvc::~TbPixelSvc() {
+
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbPixelSvc::initialize() {
+
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+  // Get the number of chips.
+  const unsigned int nDevices = geomSvc()->nDevices();
+  m_pixelConfiguration.resize(nDevices);
+
+  m_protectPhase = std::vector<bool>(nDevices, 0);
+  for (unsigned int i = 0; i < nDevices; ++i) {
+    m_pixelConfiguration[i].resize(Tb::NPixels, PixelConfig());
+  }
+  // Retrieve the names of the configuration files to be parsed.
+  ITbDataSvc* dataSvc = Gaudi::svcLocator()->service<ITbDataSvc>("TbDataSvc");
+  std::vector<std::string> files = dataSvc->getPixelConfig();
+  files.push_back(dataSvc->getTimingConfig());
+  for (auto& f : files) {
+    if (f == "") continue;
+    msg() << MSG::INFO << "Importing pixel configuration from " << f << endmsg;
+    // Import conditions from configuration file.
+    if (!readConditions(f)) {
+      msg() << MSG::ERROR << "Cannot import pixel configuration" << endmsg;
+      return StatusCode::FAILURE;
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+//============================================================================
+// Add a constant offset in time to a single super column
+//============================================================================
+void TbPixelSvc::addOffset(const int offset, const unsigned int device,
+                           const unsigned int dcol) {
+
+  for (unsigned int pix = 0; pix < 512; ++pix) {
+    const unsigned int address = pix + (0xFE00 & (dcol << 9));
+    m_pixelConfiguration[device][address].tOffset += offset;
+  }
+}
+
+//============================================================================
+// Export trim DACs and masked pixel flags to a text file
+//============================================================================
+void TbPixelSvc::writeTrimDAC(const unsigned int device) {
+  std::ofstream trimdac;
+  trimdac.open(("plane_" + std::to_string(device) + "_trimdac.txt").c_str());
+  trimdac << "#col  row trim mask tp_ena " << std::endl;
+  for (unsigned int col = 0; col < Tb::NCols; ++col) {
+    for (unsigned int row = 0; row < Tb::NRows; ++row) {
+      const unsigned int pixel = address(col, row);
+      trimdac << std::setw(3) << col << std::setw(4) << row << std::setw(4)
+              << (int)(m_pixelConfiguration[device][pixel].trim) << std::setw(4)
+              << m_pixelConfiguration[device][pixel].trimDac_isMasked
+              << std::setw(4) << m_pixelConfiguration[device][pixel].tp_ena
+              << std::endl;
+    }
+  }
+  trimdac.close();
+}
+
+//============================================================================
+// Set trim DACs for the entire pixel matrix of a chip
+//============================================================================
+void TbPixelSvc::setTrim(const unsigned int device, const char* data) {
+  for (unsigned int col = 0; col < Tb::NCols; ++col) {
+    for (unsigned int row = 0; row < Tb::NRows; ++row) {
+      const unsigned int pixel = address(col, row);
+      const uint8_t word = *(data + col + Tb::NRows * row);
+      m_pixelConfiguration[device][pixel].trim = 0xF & (word >> 1);
+      m_pixelConfiguration[device][pixel].tp_ena = 0x1 & (word >> 5);
+      m_pixelConfiguration[device][pixel].trimDac_isMasked = 0x1 & word;
+    }
+  }
+  if (m_writeTrimDACs) writeTrimDAC(device);
+}
+
+void TbPixelSvc::resetClockPhase(const unsigned int device) {
+
+  for (unsigned int pixel = 0; pixel < Tb::NPixels; ++pixel) {
+    m_pixelConfiguration[device][pixel].tOffset = 0;
+  }
+}
+
+//============================================================================
+// Calculate the clock phase correction.
+//============================================================================
+void TbPixelSvc::setPhase(const unsigned int device,
+                          const unsigned int pll_config = 1024,
+                          const int amplitude = 1) {
+  if (m_protectPhase[device]) return;
+  const unsigned int phase = pow(2, (pll_config & 0x1C0) >> 6);
+  if (phase == 1) return;
+
+  for (unsigned int pixel = 0; pixel < Tb::NPixels; ++pixel) {
+    // Decode the pixel address, first the double column.
+    const unsigned int dcol = (0xFE00 & pixel) >> 9;
+    // Get the pixel within the super pixel.
+    const unsigned int pix = (0x0007 & pixel);
+    // Calculate the column number.
+    const unsigned int col = 2 * dcol + pix / 4;
+    // col = col % 128;
+    int dt = 0;
+    if (phase == 16) {
+      dt = (-((16 - ((col / 2) % 16)) % 16)) << 8;
+    } else if (phase == 4) {
+      dt = (-4 * ((4 - ((col / 2) % 4)) % 4)) << 8;
+    } else if (phase == 2) {
+      dt = (((col % 4) < 2) ? 8 : 0) << 8;
+    }
+    m_pixelConfiguration[device][pixel].tOffset += amplitude * dt;
+  }
+  m_protectPhase[device] = true;
+}
+
+//============================================================================
+// Import pixel conditions from configuration file
+//============================================================================
+bool TbPixelSvc::readConditions(const std::string& filename) {
+
+  TbCondFile f(filename);
+  if (!f.is_open()) {
+    msg() << MSG::WARNING << "Cannot open " << filename << endmsg;
+    return false;
+  }
+  std::string mode = "";
+  std::string chip = "";
+  int deviceIndex = -1;
+  unsigned int col(0), row(0);
+  std::vector<unsigned int> badPixels;
+  while (!f.eof()) {
+    std::string line = "";
+    if (!f.getLine(line)) continue;
+    if (line.find("Charge") != std::string::npos) {
+      f.split(line, ' ', mode, chip);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        msg() << MSG::ERROR << "Stop parsing " << filename << endmsg;
+        break;
+      }
+    } else if (line.find("Mask") != std::string::npos ||
+        line.find("Offset") != std::string::npos ||
+        line.find("Timing") != std::string::npos ||
+        line.find("GlobalCharge") != std::string::npos ||
+        line.find("PLL") != std::string::npos) {
+      mode = line;
+    } else if (mode == "Charge") {
+      float a(0.), b(0.), c(0.), t(0.);
+      f.split(line, ' ', col, row, a, b, c, t);
+      const unsigned int pixel = address(col, row);
+
+      if( isnan(a) || isinf(a) || isnan(b) || isnan(c) || isnan(t) || isinf(b) || isinf(c) || isinf(t)){
+        badPixels.push_back(pixel);
+      }
+      m_pixelConfiguration[deviceIndex][pixel].p0 = a;
+      m_pixelConfiguration[deviceIndex][pixel].p1 = b;
+      m_pixelConfiguration[deviceIndex][pixel].c = c;
+      m_pixelConfiguration[deviceIndex][pixel].t = t;
+    } else if (mode == "Mask") {
+      f.split(line, ' ', chip, col, row);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      const unsigned int pixel = address(col, row);
+      msg() << MSG::INFO << "Masking pixel " << format("0x%04x", pixel)
+        << format(" (column %3d", col) << format(", row %3d)", row)
+        << " on device " << chip << endmsg;
+      m_pixelConfiguration[deviceIndex][pixel].isMasked = true;
+    } else if (mode == "GlobalCharge") {
+      double a(0.), b(0.), c(0.), t(0.);
+      f.split(line, ' ', chip, a, b, c, t);
+      //     if( isnan(a) || isnan(b) || isnan(c) || isnan(d) )
+
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      for (auto& pixel : m_pixelConfiguration[deviceIndex]) {
+        pixel.p0 = a;
+        pixel.p1 = b;
+        pixel.c = c;
+        pixel.t = t;
+      }
+      msg() << MSG::INFO << "Applying global charge calibration on device "
+        << chip << "(a = " << a << ", b = " << b << ", c = " << c
+        << ", t = " << t << ")" << endmsg;
+    } else if (mode == "Offset") {
+      int offset = 0;
+      f.split(line, ' ', chip, col, offset);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      msg() << MSG::INFO << "Adding time offset " << offset * 25 << " ns "
+        << "to double column " << col << " on chip " << chip << endmsg;
+      addOffset(offset * Tb::ToA, deviceIndex, col);
+    } else if (mode == "Timing") {
+      double dt = 0.;
+      f.split(line, ' ', chip, dt);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      const int offset = static_cast<int>(std::round(dt * Tb::nanosecond));
+      msg() << MSG::INFO << "Adding time offset " << dt << " ns (" << offset
+        << " time units) to chip " << chip << endmsg;
+      const unsigned int nDCols = Tb::NCols / 2;
+      for (unsigned int col = 0; col < nDCols; ++col) {
+        addOffset(offset, deviceIndex, col);
+      }
+    } else if (mode == "PLL") {
+      int amplitude = 0.;
+      unsigned int pll_mode;
+      f.split(line, ' ', chip, pll_mode, amplitude);
+      deviceIndex = geomSvc()->deviceIndex(chip);
+      if (deviceIndex == 999) {
+        msg() << MSG::ERROR << "Device " << chip
+          << " is not in the alignment file" << endmsg;
+        continue;
+      }
+      msg() << MSG::INFO << "Overwriting PLL CONFIG for chip " << chip
+        << endmsg;
+      m_protectPhase[deviceIndex] = false;
+      resetClockPhase(deviceIndex);
+      setPhase(deviceIndex, pll_mode, amplitude);
+    }
+  }
+  for( auto& pixel : badPixels ){
+    auto pos = posFromAddress(pixel);
+    float avgt(0), avgc(0), avgp0(0), avgp1(0);
+    unsigned int nPixels=0;
+    if( pos.second != 255 ){
+      unsigned int neighbour = address( pos.first, pos.second+1 );
+      if( std::find( badPixels.begin(), badPixels.end(), neighbour) == badPixels.end() ){
+        avgt  += m_pixelConfiguration[deviceIndex][neighbour].t;
+        avgc  += m_pixelConfiguration[deviceIndex][neighbour].c;
+        avgp0 += m_pixelConfiguration[deviceIndex][neighbour].p0;
+        avgp1 += m_pixelConfiguration[deviceIndex][neighbour].p1;
+        nPixels++;
+      }
+    }
+    if( pos.second != 0 ){
+      unsigned int neighbour = address( pos.first, pos.second-1 );
+      if( std::find( badPixels.begin(), badPixels.end(), neighbour) == badPixels.end() ){
+        avgt  += m_pixelConfiguration[deviceIndex][neighbour].t;
+        avgc  += m_pixelConfiguration[deviceIndex][neighbour].c;
+        avgp0 += m_pixelConfiguration[deviceIndex][neighbour].p0;
+        avgp1 += m_pixelConfiguration[deviceIndex][neighbour].p1;
+        nPixels++;
+      }
+    }
+    if(nPixels==0){ 
+      m_pixelConfiguration[deviceIndex][pixel].isMasked = true;
+     // printConfig( deviceIndex, pixel ) ;
+      continue;
+    }
+    m_pixelConfiguration[deviceIndex][pixel].t = avgt / (float)nPixels;
+    m_pixelConfiguration[deviceIndex][pixel].p0 = avgp0 / (float)nPixels;
+    m_pixelConfiguration[deviceIndex][pixel].p1 = avgp1 / (float)nPixels;
+    m_pixelConfiguration[deviceIndex][pixel].c = avgc / (float)nPixels;
+    //printConfig( deviceIndex, pixel ) ;
+  }
+  f.close();
+  return true;
+}
diff --git a/TbKernel/src/TbPixelSvc.h b/TbKernel/src/TbPixelSvc.h
new file mode 100644
index 0000000..99f8cfa
--- /dev/null
+++ b/TbKernel/src/TbPixelSvc.h
@@ -0,0 +1,191 @@
+#ifndef TBPIXELSVC_H
+#define TBPIXELSVC_H
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/MsgStream.h"
+
+// Local
+#include "TbKernel/ITbPixelSvc.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+#include <stdint.h>
+
+// struct PixelConfig;
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbPixelSvc TbPixelSvc.h
+ *
+ * Implementation of the Timepix3 pixel configuration service.
+ *
+ */
+
+class TbPixelSvc : public extends1<Service, ITbPixelSvc> {
+
+ public:
+  /// Constructor
+  TbPixelSvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbPixelSvc();
+
+  virtual StatusCode initialize();
+
+  /// Get the pixel address for a given column and row.
+  virtual unsigned int address(const unsigned int col,
+                               const unsigned int row) const {
+    // Get the double-column and super-pixel.
+    const unsigned int dcol = col / 2;
+    const unsigned int spix = row / 4;
+    // Get the pixel number within the superpixel.
+    unsigned int pix = row % 4;
+    if (1 == col % 2) pix += 4;
+    return (dcol << 9) + (spix << 3) + pix;
+  }
+  std::pair<unsigned int, unsigned int> posFromAddress( const unsigned int& address ) const {
+    std::pair<unsigned int, unsigned int> pos;
+    // Decode the pixel address, first get the double column. 
+    const unsigned int dcol = (0xFE00 & address) >> 8;
+    // Get the super pixel address.
+    const unsigned int spix = (0x01F8 & address) >> 1;
+    // Get the address of the pixel within the super pixel. 
+    const unsigned int pix = (0x0007 & address); 
+    // Calculate the row and column numbers.
+    pos.first = dcol + pix / 4;
+    pos.second = spix + (pix & 0x3);
+    return pos;
+  }
+
+  /// Return whether the pixel has been masked.
+  virtual bool isMasked(const unsigned int address,
+      const unsigned int device) const {
+    return m_pixelConfiguration[device][address].isMasked ||
+           m_pixelConfiguration[device][address].trimDac_isMasked;
+  }
+
+  /// Correct the timestamp of a given hit.
+  virtual void applyPhaseCorrection(LHCb::TbHit* h) {
+    h->setTime(h->time() +
+        m_pixelConfiguration[h->device()][h->pixelAddress()].tOffset);
+  }
+
+  /// Set the clock phase correction.
+  virtual void setPhase(const unsigned int device,
+      const unsigned int pll_config, const int amplitude);
+
+  /// Set trim DACs.
+  virtual void setTrim(const unsigned int device, const char* data);
+
+  /// Convert time-over-threshold to charge.
+  virtual double charge(const unsigned int tot, const unsigned int address,
+      const unsigned int device) const {
+    const PixelConfig& conf = m_pixelConfiguration[device][address];
+    double value=inverseSurrogate(tot, conf.p1, conf.p0, conf.c, conf.t);
+    if( isnan(value)  ){ 
+      auto pos = posFromAddress( address );
+      warning() << "Pixel " << device << "/0x" 
+                << std::hex << address << std::dec << " tot = " << tot  
+                << " (" << pos.first << ", " << pos.second 
+                << ")" << conf.p1 << "  " << conf.p0 << "   " << conf.c << "   " << conf.t << endmsg;
+      return 1;
+    }
+    return value;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbPixelSvc>;
+
+  struct PixelConfig {
+    PixelConfig()
+      : isMasked(false),
+      trimDac_isMasked(false),
+      isDead(false),
+      tp_ena(0),
+      trim(4),
+      tOffset(0),
+      p0(0),
+      p1(1),
+      c(0),
+      t(0) {};
+    bool isMasked;
+    bool trimDac_isMasked;
+    bool isDead;
+    bool tp_ena;
+    uint8_t trim;
+    int tOffset;
+    /// Parameters of surrogate function
+    float p0;
+    float p1;
+    float c;
+    float t;
+  };
+
+
+  void resetClockPhase(const unsigned int device);
+  /// Add a constant offset in time to a single super column.
+  void addOffset(const int offset, const unsigned int device,
+      const unsigned int dcol);
+
+  /// Pixel configuration for each chip
+  std::vector<std::vector<PixelConfig> > m_pixelConfiguration;
+
+  void printConfig( const unsigned int& plane, const unsigned int& address){
+    auto pos = posFromAddress(address);
+    PixelConfig& conf = m_pixelConfiguration[plane][address];
+    info() << std::hex << "0x" << address << std::dec << " = ("<<pos.first << ", " << pos.second << ") : " << conf.p0 << " " << conf.p1 << " " << conf.c << "  " << conf.t << endmsg;
+  }
+  /// Functionality to write out the trim dacs written into the header
+  bool m_writeTrimDACs;
+  void writeTrimDAC(const unsigned int device);
+
+  /// ignore PLL config
+  std::vector<bool> m_protectPhase;
+  /// Surrogate function, taken from http://arxiv.org/pdf/1103.2739v3.pdf
+  double surrogate(const double& charge, const double& a, const double& b,
+      const double& c, const double& t) const {
+    double result = 0.;
+    const double r = (b + a * t);
+    const double d = r * r + 4 * a * c;
+    if (d > 0.) {
+      const double itcpt = ((t * a - b) + sqrt(d)) / (2 * a);
+      if (charge > itcpt) {
+        result = a * charge + b - c / (charge - t);
+      }
+    }
+    return result;
+  }
+
+  double inverseSurrogate(const uint32_t tot, const double a, const double b,
+      const double c, const double t) const {
+    double result = 1.;
+    const double r = (b + a * t - tot);
+    const double d = r * r + 4. * a * c;
+    if (d > 0.) {
+      result = (a * t + tot - b + sqrt(d)) / (2. * a);
+    }
+    return result;
+  }
+
+  bool readConditions(const std::string& file);
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) {
+      m_geomSvc = Gaudi::svcLocator()->service<ITbGeometrySvc>("TbGeometrySvc");
+    }
+    return m_geomSvc;
+  }
+  /// Pointer to message stream
+  mutable MsgStream* m_msg;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/TbTimingSvc.cpp b/TbKernel/src/TbTimingSvc.cpp
new file mode 100644
index 0000000..c98ec3b
--- /dev/null
+++ b/TbKernel/src/TbTimingSvc.cpp
@@ -0,0 +1,67 @@
+// Gaudi
+#include "GaudiKernel/MsgStream.h"
+
+// Local
+#include "TbTimingSvc.h"
+
+DECLARE_SERVICE_FACTORY(TbTimingSvc)
+
+//============================================================================
+// Constructor
+//============================================================================
+TbTimingSvc::TbTimingSvc(const std::string& name, ISvcLocator* svc)
+    : base_class(name, svc),
+      m_evtMinTime(0UL),
+      m_evtMaxTime(0UL),
+      m_msg(NULL) {}
+
+//============================================================================
+// Destructor
+//============================================================================
+TbTimingSvc::~TbTimingSvc() {
+
+  // Delete the message service.
+  if (m_msg) delete m_msg;
+}
+
+//============================================================================
+// Initialisation
+//============================================================================
+StatusCode TbTimingSvc::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = Service::initialize();
+  if (!sc.isSuccess()) return sc;
+  return StatusCode::SUCCESS;
+}
+
+//============================================================================
+// Finalisation
+//============================================================================
+StatusCode TbTimingSvc::finalize() {
+
+  // Finalise the base class.
+  return Service::finalize();
+}
+
+//============================================================================
+// Convert local time (in ns) to global timestamp.
+//============================================================================
+uint64_t TbTimingSvc::localToGlobal(const double& htime) {
+
+  // Conversion factor (25 ns correspond to 4096 global time units).
+  constexpr double f = 4096. / 25.;
+  const double dt = floor(htime * f);
+  return dt < 0. ? m_evtMinTime - static_cast<uint64_t>(fabs(dt))
+                 : m_evtMinTime + static_cast<uint64_t>(dt);
+}
+
+//============================================================================
+// Convert global timestamp to local time (in ns).
+//============================================================================
+double TbTimingSvc::globalToLocal(const uint64_t& time) {
+  // Conversion factor (4096 global time units correspond to 25 ns).
+  constexpr double f = 25. / 4096.;
+  return time < m_evtMinTime ? -f * (m_evtMinTime - time)
+                             : f * (time - m_evtMinTime);
+}
diff --git a/TbKernel/src/TbTimingSvc.h b/TbKernel/src/TbTimingSvc.h
new file mode 100644
index 0000000..9af513a
--- /dev/null
+++ b/TbKernel/src/TbTimingSvc.h
@@ -0,0 +1,77 @@
+#ifndef TBTIMINGSVC_H
+#define TBTIMINGSVC_H 1
+
+// Gaudi
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/Bootstrap.h"
+
+// Local
+#include "TbKernel/ITbTimingSvc.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+template <class TYPE>
+class SvcFactory;
+
+/** @class TbTimingSvc TbTimingSvc.h
+ *
+ * Implementation of the testbeam timing service.
+ *
+ */
+
+class TbTimingSvc : public extends1<Service, ITbTimingSvc> {
+
+ public:
+  /// Constructor
+  TbTimingSvc(const std::string& name, ISvcLocator* svc);
+  /// Destructor
+  virtual ~TbTimingSvc();
+
+  virtual StatusCode initialize();
+  virtual StatusCode finalize();
+
+  virtual uint64_t localToGlobal(const double& htime);
+  virtual double globalToLocal(const uint64_t& time);
+
+  virtual void setEventDefinition(const uint64_t& evtMinTime,
+                                  const uint64_t& evtMaxTime) {
+    m_evtMinTime = evtMinTime;
+    m_evtMaxTime = evtMaxTime;
+  }
+  virtual void eventDefinition(uint64_t& evtMinTime,
+                               uint64_t& evtMaxTime) const {
+    evtMinTime = m_evtMinTime;
+    evtMaxTime = m_evtMaxTime;
+  }
+
+  virtual void setOverlap(const uint64_t& overlap) { m_overlap = overlap; }
+  virtual bool inEvent(const uint64_t& time) const {
+    return time > m_evtMinTime && time < m_evtMaxTime;
+  }
+  virtual bool inOverlap(const uint64_t& time) const {
+    return time > m_evtMaxTime - m_overlap && time < m_evtMaxTime;
+  }
+  virtual bool beforeOverlap(const uint64_t& time) const {
+    return time < m_evtMaxTime - m_overlap;
+  }
+
+ private:
+  /// Allow SvcFactory to instantiate the service.
+  friend class SvcFactory<TbTimingSvc>;
+
+  /// Lower limit of the current event (in global time units)
+  uint64_t m_evtMinTime;
+  /// Upper limit of the current event (in global time units)
+  uint64_t m_evtMaxTime;
+  /// Overlap with the next event (in global time units)
+  uint64_t m_overlap;
+
+  /// Pointer to message stream
+  mutable MsgStream* m_msg;
+  /// On-demand access to message stream
+  MsgStream& msg() const {
+    if (!m_msg) m_msg = new MsgStream(msgSvc(), name());
+    return *m_msg;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/TbTrackFit.cpp b/TbKernel/src/TbTrackFit.cpp
new file mode 100644
index 0000000..8612e98
--- /dev/null
+++ b/TbKernel/src/TbTrackFit.cpp
@@ -0,0 +1,187 @@
+// Tb/TbEvent
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+// Local
+#include "TbTrackFit.h"
+
+DECLARE_TOOL_FACTORY(TbTrackFit)
+
+//=============================================================================
+// Standard constructor, initializes variables
+//=============================================================================
+TbTrackFit::TbTrackFit(const std::string& type, const std::string& name,
+                       const IInterface* parent)
+    : GaudiTool(type, name, parent), m_geomSvc(nullptr) {
+
+  declareInterface<ITbTrackFit>(this);
+
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbTrackFit::~TbTrackFit() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbTrackFit::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTool::initialize();
+  if (sc.isFailure()) return sc;
+  // Get the number of telescope planes.
+  const auto nPlanes = geomSvc()->modules().size();
+  // Set the flags whether a plane is masked or not.
+  m_masked.resize(nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) {
+    m_masked[plane] = true;
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Exclude a plane from the fit
+//=============================================================================
+void TbTrackFit::maskPlane(const unsigned int plane) {
+
+  m_masked[plane] = true;
+}
+
+//=============================================================================
+// (Re-)include a plane in the fit
+//=============================================================================
+void TbTrackFit::unmaskPlane(const unsigned int plane) {
+
+  m_masked[plane] = false;
+}
+
+//=========================================================================
+/// Perform a straight-line fit to the clusters of a given track
+//=========================================================================
+void TbTrackFit::fit(LHCb::TbTrack* track) {
+
+  // Sums for the x-slope fit
+  double s0 = 0.;
+  double sx = 0.;
+  double sz = 0.;
+  double sxz = 0.;
+  double sz2 = 0.;
+  // Sums for the y-slope fit
+  double u0 = 0.;
+  double uy = 0.;
+  double uz = 0.;
+  double uyz = 0.;
+  double uz2 = 0.;
+
+  // Count the number of planes included in the fit.
+  unsigned int nd = 0;
+
+  // Loop through the clusters.
+  auto clusters = track->clusters();
+  for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+    if (!(*it)) continue;
+    // Skip masked planes.
+    if (m_masked[(*it)->plane()]) continue;
+    ++nd;
+    const double wx = (*it)->wx();
+    const double wy = (*it)->wy();
+    const double x = (*it)->x();
+    const double y = (*it)->y();
+    const double z = (*it)->z();
+
+    // Straight line fit in x
+    s0 += wx;
+    sx += wx * x;
+    sz += wx * z;
+    sxz += wx * x * z;
+    sz2 += wx * z * z;
+    // Straight line fit in y
+    u0 += wy;
+    uy += wy * y;
+    uz += wy * z;
+    uyz += wy * y * z;
+    uz2 += wy * z * z;
+  }
+  //  if (nd < 3) {
+  //    error() << "Invalid track. Only " << nd << " non-masked clusters" <<
+  // endmsg;
+  //    return;
+  //  }
+  // Compute the track parameters for x.
+
+  double den = (sz2 * s0 - sz * sz);
+
+  if (fabs(den) < 10e-10) den = 1.;
+  const double tx = (sxz * s0 - sx * sz) / den;
+  const double x0 = (sx * sz2 - sxz * sz) / den;
+
+  // Compute the track parameters for y.
+  den = (uz2 * u0 - uz * uz);
+  if (fabs(den) < 10e-10) den = 1.;
+  const double ty = (uyz * u0 - uy * uz) / den;
+  const double y0 = (uy * uz2 - uyz * uz) / den;
+
+  // Calculate the covariance matrix.
+  // Ad hoc matrix inversion, as it is almost diagonal.
+  // Some terms vanish since we calculate the covariance matrix at z = 0.
+  const double m00 = s0;
+  const double m11 = u0;
+  const double m20 = sz;
+  const double m31 = uz;
+  const double m22 = sz2;
+  const double m33 = uz2;
+  const double den20 = m22 * m00 - m20 * m20;
+  const double den31 = m33 * m11 - m31 * m31;
+
+  Gaudi::SymMatrix4x4 cov;
+  cov(0, 0) = m22 / den20;
+  cov(2, 0) = -m20 / den20;
+  cov(2, 2) = m00 / den20;
+
+  cov(1, 1) = m33 / den31;
+  cov(3, 1) = -m31 / den31;
+  cov(3, 3) = m11 / den31;
+
+  // Create the first state.
+  LHCb::TbState fstate(Gaudi::Vector4(x0, y0, tx, ty), cov, 0., 0);
+
+  fstate.covariance()(0, 0) = cov(0, 0);
+  fstate.covariance()(0, 2) = cov(2, 0);
+  fstate.covariance()(1, 1) = cov(1, 1);
+  fstate.covariance()(2, 2) = cov(2, 2);
+  fstate.covariance()(1, 3) = cov(3, 1);
+  fstate.covariance()(3, 3) = cov(3, 3);
+  // Update the firstState of the track.
+  track->setFirstState(fstate);
+
+  // Compute chi2 and track time.
+  double chi2 = 0.;
+  double time = 0.;
+  for (auto it = clusters.cbegin(), end = clusters.cend(); it != end; ++it) {
+    if (!(*it)) continue;
+    // Skip masked planes.
+    if (m_masked[(*it)->plane()]) continue;
+    const double wx = (*it)->wx();
+    const double wy = (*it)->wy();
+    const unsigned int plane = (*it)->plane();
+    // Calculate global (biased) residuals in x and y.
+    const Gaudi::XYZPoint intercept = geomSvc()->intercept(track, plane);
+    const Gaudi::XYZPoint local = geomSvc()->globalToLocal(intercept, plane);
+
+    const double dx = (*it)->xloc() - local.x();
+    const double dy = (*it)->yloc() - local.y();
+    chi2 += (dx * dx) * wx + (dy * dy) * wy;
+    time += (*it)->htime();
+  }
+  // Set track chi2PerNdof and ndof.
+  const unsigned int ndof = 2 * nd - 4;
+  track->setNdof(ndof);
+  track->setChi2PerNdof(chi2 / (double)ndof);
+
+  // Finally, set the track time.
+  time /= nd;
+  track->setHtime(time);
+}
diff --git a/TbKernel/src/TbTrackFit.h b/TbKernel/src/TbTrackFit.h
new file mode 100644
index 0000000..ec33071
--- /dev/null
+++ b/TbKernel/src/TbTrackFit.h
@@ -0,0 +1,51 @@
+#ifndef TBTRACKFIT_H
+#define TBTRACKFIT_H 1
+
+// Gaudi
+#include "GaudiAlg/GaudiTool.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbGeometrySvc.h"
+
+/** @class TbTrackFit TbTrackFit.h
+ * Implementation of track fit for Timepix3 testbeam analysis
+ *
+ * @author Panagiotis Tsopelas
+ * @date 2014-05-06
+ *
+ */
+
+class TbTrackFit : public GaudiTool, virtual public ITbTrackFit {
+
+ public:
+  /// Constructor
+  TbTrackFit(const std::string& type, const std::string& name,
+             const IInterface* parent);
+  /// Destructor
+  virtual ~TbTrackFit();
+
+  virtual StatusCode initialize();
+
+  /// Fit the track and set its firstState
+  virtual void fit(LHCb::TbTrack* track);
+
+  virtual void maskPlane(const unsigned int plane);
+  virtual void unmaskPlane(const unsigned int plane);
+
+ protected:
+  /// Indices of planes to be masked.
+  std::vector<unsigned int> m_maskedPlanes;
+  /// Flags whether a plane is masked or not.
+  std::vector<bool> m_masked;
+
+  /// Pointer to geometry service
+  mutable ITbGeometrySvc* m_geomSvc;
+  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+};
+
+#endif
diff --git a/TbKernel/src/lib/.svn/all-wcprops b/TbKernel/src/lib/.svn/all-wcprops
new file mode 100644
index 0000000..192a7dc
--- /dev/null
+++ b/TbKernel/src/lib/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/src/lib
+END
+TbCondFile.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/src/lib/TbCondFile.cpp
+END
+TbAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/201949/Kepler/trunk/Tb/TbKernel/src/lib/TbAlgorithm.cpp
+END
diff --git a/TbKernel/src/lib/.svn/entries b/TbKernel/src/lib/.svn/entries
new file mode 100644
index 0000000..caf9fd6
--- /dev/null
+++ b/TbKernel/src/lib/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbKernel/src/lib
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbCondFile.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+df860dcce0b998c3e3e3affc7286ea80
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+511
+
+TbAlgorithm.cpp
+file
+
+
+
+
+2016-05-09T14:27:53.000000Z
+1bb0c1bf760d1dc786e530de40576460
+2016-02-24T06:51:17.339260Z
+201949
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2550
+
diff --git a/TbKernel/src/lib/.svn/text-base/TbAlgorithm.cpp.svn-base b/TbKernel/src/lib/.svn/text-base/TbAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..b814a8e
--- /dev/null
+++ b/TbKernel/src/lib/.svn/text-base/TbAlgorithm.cpp.svn-base
@@ -0,0 +1,75 @@
+// Boost
+#include "boost/format.hpp"
+
+// Local
+#include "TbKernel/TbAlgorithm.h"
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbAlgorithm::TbAlgorithm(const std::string& name, ISvcLocator* pSvcLocator)
+    : GaudiTupleAlg(name, pSvcLocator) {
+
+  declareProperty("PrintConfiguration", m_printConfiguration = false);
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlgorithm::~TbAlgorithm() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbAlgorithm::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTupleAlg::initialize();
+  if (sc.isFailure()) return sc;
+  // Get the number of telescope planes.
+  m_nPlanes = geomSvc()->modules().size();
+  m_nDevices = geomSvc()->nDevices();
+  // Set the flags whether a plane is masked or not.
+  m_masked.resize(m_nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) {
+    m_masked[plane] = true;
+  }
+
+  setHistoTopDir("Tb/");
+  // If requested, print the properties specific to this algorithm.
+  if (m_printConfiguration) {
+    boost::format fmt(" %|-30.30s|%|32t| %s "); 
+    const auto& props = this->getProperties();
+    info() << std::string(70, '-') << endmsg;
+    info() << "Configuration of " << this->name() << endmsg;
+    info() << std::string(70, '-') << endmsg;
+    for (auto it = props.crbegin(), end = props.crend(); it != end; ++it) {
+      const std::string name = (*it)->name();
+      // Stop when we reach the base class properties.
+      if (name == "PrintConfiguration") break;
+      info() << fmt % name % (*it)->toString() << endmsg;
+    }
+  }
+  return StatusCode::SUCCESS;
+
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbAlgorithm::execute() {
+
+  return StatusCode::SUCCESS;
+
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+StatusCode TbAlgorithm::finalize() {
+
+  return GaudiTupleAlg::finalize();
+  
+}
diff --git a/TbKernel/src/lib/.svn/text-base/TbCondFile.cpp.svn-base b/TbKernel/src/lib/.svn/text-base/TbCondFile.cpp.svn-base
new file mode 100644
index 0000000..e07865e
--- /dev/null
+++ b/TbKernel/src/lib/.svn/text-base/TbCondFile.cpp.svn-base
@@ -0,0 +1,23 @@
+#include "TbKernel/TbCondFile.h"
+
+template <>
+double TbCondFile::custom_cast(const std::string& ref) {
+  return std::stod(ref);
+}
+template <>
+int TbCondFile::custom_cast(const std::string& ref) {
+  return std::stoi(ref);
+}
+template <>
+std::string TbCondFile::custom_cast(const std::string& ref) {
+  return ref;
+}
+template <>
+unsigned int TbCondFile::custom_cast(const std::string& ref) {
+  return std::stoi(ref);
+}
+
+template <>
+float TbCondFile::custom_cast(const std::string& ref) {
+  return std::stof(ref);
+}
diff --git a/TbKernel/src/lib/TbAlgorithm.cpp b/TbKernel/src/lib/TbAlgorithm.cpp
new file mode 100644
index 0000000..b814a8e
--- /dev/null
+++ b/TbKernel/src/lib/TbAlgorithm.cpp
@@ -0,0 +1,75 @@
+// Boost
+#include "boost/format.hpp"
+
+// Local
+#include "TbKernel/TbAlgorithm.h"
+
+//=============================================================================
+// Standard constructor
+//=============================================================================
+TbAlgorithm::TbAlgorithm(const std::string& name, ISvcLocator* pSvcLocator)
+    : GaudiTupleAlg(name, pSvcLocator) {
+
+  declareProperty("PrintConfiguration", m_printConfiguration = false);
+  declareProperty("MaskedPlanes", m_maskedPlanes = {});
+
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+TbAlgorithm::~TbAlgorithm() {}
+
+//=============================================================================
+// Initialisation
+//=============================================================================
+StatusCode TbAlgorithm::initialize() {
+
+  // Initialise the base class.
+  StatusCode sc = GaudiTupleAlg::initialize();
+  if (sc.isFailure()) return sc;
+  // Get the number of telescope planes.
+  m_nPlanes = geomSvc()->modules().size();
+  m_nDevices = geomSvc()->nDevices();
+  // Set the flags whether a plane is masked or not.
+  m_masked.resize(m_nPlanes, false);
+  for (const unsigned int plane : m_maskedPlanes) {
+    m_masked[plane] = true;
+  }
+
+  setHistoTopDir("Tb/");
+  // If requested, print the properties specific to this algorithm.
+  if (m_printConfiguration) {
+    boost::format fmt(" %|-30.30s|%|32t| %s "); 
+    const auto& props = this->getProperties();
+    info() << std::string(70, '-') << endmsg;
+    info() << "Configuration of " << this->name() << endmsg;
+    info() << std::string(70, '-') << endmsg;
+    for (auto it = props.crbegin(), end = props.crend(); it != end; ++it) {
+      const std::string name = (*it)->name();
+      // Stop when we reach the base class properties.
+      if (name == "PrintConfiguration") break;
+      info() << fmt % name % (*it)->toString() << endmsg;
+    }
+  }
+  return StatusCode::SUCCESS;
+
+}
+
+//=============================================================================
+// Main execution
+//=============================================================================
+StatusCode TbAlgorithm::execute() {
+
+  return StatusCode::SUCCESS;
+
+}
+
+//=============================================================================
+// Finalisation
+//=============================================================================
+StatusCode TbAlgorithm::finalize() {
+
+  return GaudiTupleAlg::finalize();
+  
+}
diff --git a/TbKernel/src/lib/TbCondFile.cpp b/TbKernel/src/lib/TbCondFile.cpp
new file mode 100644
index 0000000..e07865e
--- /dev/null
+++ b/TbKernel/src/lib/TbCondFile.cpp
@@ -0,0 +1,23 @@
+#include "TbKernel/TbCondFile.h"
+
+template <>
+double TbCondFile::custom_cast(const std::string& ref) {
+  return std::stod(ref);
+}
+template <>
+int TbCondFile::custom_cast(const std::string& ref) {
+  return std::stoi(ref);
+}
+template <>
+std::string TbCondFile::custom_cast(const std::string& ref) {
+  return ref;
+}
+template <>
+unsigned int TbCondFile::custom_cast(const std::string& ref) {
+  return std::stoi(ref);
+}
+
+template <>
+float TbCondFile::custom_cast(const std::string& ref) {
+  return std::stof(ref);
+}
diff --git a/TbSimulation/.svn/all-wcprops b/TbSimulation/.svn/all-wcprops
new file mode 100644
index 0000000..9519bd5
--- /dev/null
+++ b/TbSimulation/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/196412/Kepler/trunk/Tb/TbSimulation
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/188496/Kepler/trunk/Tb/TbSimulation/CMakeLists.txt
+END
diff --git a/TbSimulation/.svn/entries b/TbSimulation/.svn/entries
new file mode 100644
index 0000000..9f910a9
--- /dev/null
+++ b/TbSimulation/.svn/entries
@@ -0,0 +1,74 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbSimulation
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-17T15:37:57.736429Z
+196412
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+src
+dir
+
+options
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+60f43943db63c51f2beb347421d00db2
+2015-05-19T10:05:23.816430Z
+188496
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+499
+
diff --git a/TbSimulation/.svn/text-base/CMakeLists.txt.svn-base b/TbSimulation/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..5e7702a
--- /dev/null
+++ b/TbSimulation/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,15 @@
+################################################################################
+# Package: TbSimulation
+################################################################################
+gaudi_subdir(TbSimulation v1r3)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS MathCore)
+
+gaudi_add_module(TbSimulation
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib ROOT)
+
diff --git a/TbSimulation/CMakeLists.txt b/TbSimulation/CMakeLists.txt
new file mode 100644
index 0000000..5e7702a
--- /dev/null
+++ b/TbSimulation/CMakeLists.txt
@@ -0,0 +1,15 @@
+################################################################################
+# Package: TbSimulation
+################################################################################
+gaudi_subdir(TbSimulation v1r3)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS MathCore)
+
+gaudi_add_module(TbSimulation
+                 src/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib ROOT)
+
diff --git a/TbSimulation/cmt/.svn/all-wcprops b/TbSimulation/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..9aa04af
--- /dev/null
+++ b/TbSimulation/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/188496/Kepler/trunk/Tb/TbSimulation/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/188496/Kepler/trunk/Tb/TbSimulation/cmt/requirements
+END
diff --git a/TbSimulation/cmt/.svn/entries b/TbSimulation/cmt/.svn/entries
new file mode 100644
index 0000000..b642a10
--- /dev/null
+++ b/TbSimulation/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbSimulation/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T10:05:23.816430Z
+188496
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-05-09T14:27:56.000000Z
+5d8ef55498c1675d87618d20ba200e23
+2015-05-19T10:05:23.816430Z
+188496
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+469
+
diff --git a/TbSimulation/cmt/.svn/text-base/requirements.svn-base b/TbSimulation/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..4834759
--- /dev/null
+++ b/TbSimulation/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,15 @@
+package TbSimulation 
+version v1r3
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbSimulation    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbSimulation
diff --git a/TbSimulation/cmt/requirements b/TbSimulation/cmt/requirements
new file mode 100644
index 0000000..4834759
--- /dev/null
+++ b/TbSimulation/cmt/requirements
@@ -0,0 +1,15 @@
+package TbSimulation 
+version v1r3
+
+branches          cmt doc src 
+include_path      none
+
+use  GaudiAlg     v*
+use  TbEvent      v*  Tb
+use  TbKernel     v*  Tb
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbSimulation    ../src/*.cpp -import=AIDA 
+apply_pattern    component_library library=TbSimulation
diff --git a/TbSimulation/doc/.svn/all-wcprops b/TbSimulation/doc/.svn/all-wcprops
new file mode 100644
index 0000000..82b5047
--- /dev/null
+++ b/TbSimulation/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/188496/Kepler/trunk/Tb/TbSimulation/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/188496/Kepler/trunk/Tb/TbSimulation/doc/release.notes
+END
diff --git a/TbSimulation/doc/.svn/entries b/TbSimulation/doc/.svn/entries
new file mode 100644
index 0000000..6ddec7b
--- /dev/null
+++ b/TbSimulation/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbSimulation/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T10:05:23.816430Z
+188496
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-05-09T14:27:56.000000Z
+f7f9866fe098a20880d82a098b043ab6
+2015-05-19T10:05:23.816430Z
+188496
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1237
+
diff --git a/TbSimulation/doc/.svn/text-base/release.notes.svn-base b/TbSimulation/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..ffebb77
--- /dev/null
+++ b/TbSimulation/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,36 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbSimulation
+! Responsible :
+! Purpose     : Algorithms for producing simulated testbeam data
+!-----------------------------------------------------------------------------
+
+!======================= TbSimulation v1r3 2015-05-19 ========================
+
+! 2015-03-24 - Heinrich Schindler
+ - Follow change in TbEvent (r185837).
+
+! 2015-03-09 - Heinrich Schindler
+ - Follow change in TbGeometrySvc (r185107).
+
+! 2014-12-12 - Heinrich Schindler
+ - Follow renaming of TbHit::plane to TbHit::device.
+
+!======================= TbSimulation v1r2 2014-11-30 ========================
+
+! 2014-10-12 - Panos Tsopelas
+ - Updated TrackFitter to generate random scattered tracks  
+   and fit them with a Kalman fit.
+
+!======================= TbSimulation v1r1 2014-08-18 ========================
+
+! 2014-07-08 - Tim Evans
+ - Changes to reflect changes in TbEvent
+
+! 2014-06-06 - Heinrich Schindler
+ - TbTrackFitter: remove unused member m_tracks.
+
+!======================= TbSimulation v1r0 2014-05-30 ========================
+
+! 2014-05-29 - Heinrich Schindler
+ - Initial import
+ - Move TbTestMC and TbTrackFitter from Tb/TbAlgorithms to this package.
diff --git a/TbSimulation/doc/release.notes b/TbSimulation/doc/release.notes
new file mode 100644
index 0000000..ffebb77
--- /dev/null
+++ b/TbSimulation/doc/release.notes
@@ -0,0 +1,36 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbSimulation
+! Responsible :
+! Purpose     : Algorithms for producing simulated testbeam data
+!-----------------------------------------------------------------------------
+
+!======================= TbSimulation v1r3 2015-05-19 ========================
+
+! 2015-03-24 - Heinrich Schindler
+ - Follow change in TbEvent (r185837).
+
+! 2015-03-09 - Heinrich Schindler
+ - Follow change in TbGeometrySvc (r185107).
+
+! 2014-12-12 - Heinrich Schindler
+ - Follow renaming of TbHit::plane to TbHit::device.
+
+!======================= TbSimulation v1r2 2014-11-30 ========================
+
+! 2014-10-12 - Panos Tsopelas
+ - Updated TrackFitter to generate random scattered tracks  
+   and fit them with a Kalman fit.
+
+!======================= TbSimulation v1r1 2014-08-18 ========================
+
+! 2014-07-08 - Tim Evans
+ - Changes to reflect changes in TbEvent
+
+! 2014-06-06 - Heinrich Schindler
+ - TbTrackFitter: remove unused member m_tracks.
+
+!======================= TbSimulation v1r0 2014-05-30 ========================
+
+! 2014-05-29 - Heinrich Schindler
+ - Initial import
+ - Move TbTestMC and TbTrackFitter from Tb/TbAlgorithms to this package.
diff --git a/TbSimulation/options/.svn/all-wcprops b/TbSimulation/options/.svn/all-wcprops
new file mode 100644
index 0000000..7d0a0f3
--- /dev/null
+++ b/TbSimulation/options/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/TbSimulation/options
+END
+trackfitter.py
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/TbSimulation/options/trackfitter.py
+END
+simulation.py
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/184842/Kepler/trunk/Tb/TbSimulation/options/simulation.py
+END
diff --git a/TbSimulation/options/.svn/entries b/TbSimulation/options/.svn/entries
new file mode 100644
index 0000000..c936bde
--- /dev/null
+++ b/TbSimulation/options/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbSimulation/options
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+trackfitter.py
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+4ef4d9e2ccbec9c0129d40a5bbbb8d70
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+737
+
+simulation.py
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+3005c2f5064be06b9e27532c6a4e858b
+2015-03-05T10:08:33.568013Z
+184842
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1602
+
diff --git a/TbSimulation/options/.svn/text-base/simulation.py.svn-base b/TbSimulation/options/.svn/text-base/simulation.py.svn-base
new file mode 100644
index 0000000..82bad6b
--- /dev/null
+++ b/TbSimulation/options/.svn/text-base/simulation.py.svn-base
@@ -0,0 +1,53 @@
+# Run with:
+# gaudirun.py $KEPLERROOT/options/simulation.py
+
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+
+# Set the number of events to run over 
+Kepler().EvtMax = 100
+
+# Change the sequence of code that is run ---------------
+def sim():
+  seq = GaudiSequencer("Telescope")
+ 
+  # TestMC options.
+  from Configurables import TbTestMC
+  TbTestMC().doMisAlign = False
+  TbTestMC().NTracks = 200
+  TbTestMC().RunDuration = 10000
+  TbTestMC().NNoiseClusters = 0
+  TbTestMC().HitTimeJitter = 20
+  TbTestMC().ClusterPosnError = 0.001
+  TbTestMC().ClusterADCMPV = 300.0 # Ish.
+  TbTestMC().ChargeSharingWidth = 0.033 # Best not to change much.
+  TbTestMC().ThresholdCut = 20
+  TbTestMC().ForceEfficiency = True
+  #TbTestMC().InitAlignment = "Alignment_perfect.dat"
+  #TbTestMC().InitAlignment = Alignment_raw.dat
+
+  # TbClustering options.   
+  from Configurables import TbClustering  
+  TbClustering().TimeWindow = 200
+
+  # TbTracking options.
+  from Configurables import TbTracking
+  TbTracking().TimeWindow = 300
+  TbTracking().SearchRadius = 1
+  TbTracking().MinNClusters = 7
+  TbTracking().Monitoring = True
+  TbTracking().SearchVolume = "cylinder" # {cylinder, diabolo}
+  
+  # TbTracking speed options.
+  TbTracking().nComboCut = 1000 # O(10) for speed.
+  TbTracking().SearchVolumeFillAlgorithm = "adap_seq" # {seq, adap_seq}. Adap faster.
+  
+  seq.Members = [TbTestMC(), TbClustering(), TbTracking()]
+  seq = GaudiSequencer("Monitoring")
+  from Configurables import TbClusterPlots, TbTrackPlots
+  seq.Members = [TbClusterPlots(), TbTrackPlots()]
+  
+appendPostConfigAction(sim)
+
+
diff --git a/TbSimulation/options/.svn/text-base/trackfitter.py.svn-base b/TbSimulation/options/.svn/text-base/trackfitter.py.svn-base
new file mode 100644
index 0000000..f07fd42
--- /dev/null
+++ b/TbSimulation/options/.svn/text-base/trackfitter.py.svn-base
@@ -0,0 +1,27 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+# Set the path to the directory/files to be processed
+Kepler().InputFiles =  ["/afs/cern.ch/work/t/tevans/public/Kepler_data_1MHz_120s_trigger/"]
+Kepler().EvtMax = 4000 
+
+
+def sim():
+  telseq = GaudiSequencer("Telescope")
+  
+  from Configurables import TbTrackFitter
+  telseq.Members = [ TbTrackFitter()]
+  # scattering estimate (theta0 squared?)
+  TbTrackFitter().scat2 = 1.e-9
+  #TbTrackFitter().scat2 = 0
+  TbTrackFitter().direction = -1
+  
+  # divergence of true track 
+  TbTrackFitter().theta0 = 1.e-4
+  #TbTrackFitter().hiterror2 = 9.0e-6
+  #TbTrackFitter().theta0 = 0
+  
+  monseq = GaudiSequencer("Monitoring")
+  monseq.Members = []
+
+appendPostConfigAction(sim)
diff --git a/TbSimulation/options/simulation.py b/TbSimulation/options/simulation.py
new file mode 100644
index 0000000..82bad6b
--- /dev/null
+++ b/TbSimulation/options/simulation.py
@@ -0,0 +1,53 @@
+# Run with:
+# gaudirun.py $KEPLERROOT/options/simulation.py
+
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+
+# Set the number of events to run over 
+Kepler().EvtMax = 100
+
+# Change the sequence of code that is run ---------------
+def sim():
+  seq = GaudiSequencer("Telescope")
+ 
+  # TestMC options.
+  from Configurables import TbTestMC
+  TbTestMC().doMisAlign = False
+  TbTestMC().NTracks = 200
+  TbTestMC().RunDuration = 10000
+  TbTestMC().NNoiseClusters = 0
+  TbTestMC().HitTimeJitter = 20
+  TbTestMC().ClusterPosnError = 0.001
+  TbTestMC().ClusterADCMPV = 300.0 # Ish.
+  TbTestMC().ChargeSharingWidth = 0.033 # Best not to change much.
+  TbTestMC().ThresholdCut = 20
+  TbTestMC().ForceEfficiency = True
+  #TbTestMC().InitAlignment = "Alignment_perfect.dat"
+  #TbTestMC().InitAlignment = Alignment_raw.dat
+
+  # TbClustering options.   
+  from Configurables import TbClustering  
+  TbClustering().TimeWindow = 200
+
+  # TbTracking options.
+  from Configurables import TbTracking
+  TbTracking().TimeWindow = 300
+  TbTracking().SearchRadius = 1
+  TbTracking().MinNClusters = 7
+  TbTracking().Monitoring = True
+  TbTracking().SearchVolume = "cylinder" # {cylinder, diabolo}
+  
+  # TbTracking speed options.
+  TbTracking().nComboCut = 1000 # O(10) for speed.
+  TbTracking().SearchVolumeFillAlgorithm = "adap_seq" # {seq, adap_seq}. Adap faster.
+  
+  seq.Members = [TbTestMC(), TbClustering(), TbTracking()]
+  seq = GaudiSequencer("Monitoring")
+  from Configurables import TbClusterPlots, TbTrackPlots
+  seq.Members = [TbClusterPlots(), TbTrackPlots()]
+  
+appendPostConfigAction(sim)
+
+
diff --git a/TbSimulation/options/trackfitter.py b/TbSimulation/options/trackfitter.py
new file mode 100644
index 0000000..f07fd42
--- /dev/null
+++ b/TbSimulation/options/trackfitter.py
@@ -0,0 +1,27 @@
+from Gaudi.Configuration import *
+
+from Configurables import Kepler
+# Set the path to the directory/files to be processed
+Kepler().InputFiles =  ["/afs/cern.ch/work/t/tevans/public/Kepler_data_1MHz_120s_trigger/"]
+Kepler().EvtMax = 4000 
+
+
+def sim():
+  telseq = GaudiSequencer("Telescope")
+  
+  from Configurables import TbTrackFitter
+  telseq.Members = [ TbTrackFitter()]
+  # scattering estimate (theta0 squared?)
+  TbTrackFitter().scat2 = 1.e-9
+  #TbTrackFitter().scat2 = 0
+  TbTrackFitter().direction = -1
+  
+  # divergence of true track 
+  TbTrackFitter().theta0 = 1.e-4
+  #TbTrackFitter().hiterror2 = 9.0e-6
+  #TbTrackFitter().theta0 = 0
+  
+  monseq = GaudiSequencer("Monitoring")
+  monseq.Members = []
+
+appendPostConfigAction(sim)
diff --git a/TbSimulation/src/.svn/all-wcprops b/TbSimulation/src/.svn/all-wcprops
new file mode 100644
index 0000000..6dda65f
--- /dev/null
+++ b/TbSimulation/src/.svn/all-wcprops
@@ -0,0 +1,29 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/196412/Kepler/trunk/Tb/TbSimulation/src
+END
+TbTestMC.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/196412/Kepler/trunk/Tb/TbSimulation/src/TbTestMC.cpp
+END
+TbTrackFitter.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/196412/Kepler/trunk/Tb/TbSimulation/src/TbTrackFitter.cpp
+END
+TbTestMC.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/185111/Kepler/trunk/Tb/TbSimulation/src/TbTestMC.h
+END
+TbTrackFitter.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/178736/Kepler/trunk/Tb/TbSimulation/src/TbTrackFitter.h
+END
diff --git a/TbSimulation/src/.svn/entries b/TbSimulation/src/.svn/entries
new file mode 100644
index 0000000..b6307ca
--- /dev/null
+++ b/TbSimulation/src/.svn/entries
@@ -0,0 +1,164 @@
+10
+
+dir
+205760
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbSimulation/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-17T15:37:57.736429Z
+196412
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbTestMC.cpp
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+8acc63255f8be9f7f970e5a29b0883bd
+2015-10-17T15:37:57.736429Z
+196412
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19715
+
+TbTrackFitter.cpp
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+9adfe24c86006399c03fb60369acda63
+2015-10-17T15:37:57.736429Z
+196412
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+20021
+
+TbTestMC.h
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+260a72bb63fea489c316061821ba0a7f
+2015-03-09T15:16:45.394213Z
+185111
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2529
+
+TbTrackFitter.h
+file
+
+
+
+
+2016-05-09T14:27:57.000000Z
+ff2f7a8c2f7d4d7a02b11a0f5c22082e
+2014-10-12T09:53:35.051479Z
+178736
+ptsopela
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2571
+
diff --git a/TbSimulation/src/.svn/prop-base/TbTrackFitter.cpp.svn-base b/TbSimulation/src/.svn/prop-base/TbTrackFitter.cpp.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbSimulation/src/.svn/prop-base/TbTrackFitter.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbSimulation/src/.svn/prop-base/TbTrackFitter.h.svn-base b/TbSimulation/src/.svn/prop-base/TbTrackFitter.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbSimulation/src/.svn/prop-base/TbTrackFitter.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbSimulation/src/.svn/text-base/TbTestMC.cpp.svn-base b/TbSimulation/src/.svn/text-base/TbTestMC.cpp.svn-base
new file mode 100644
index 0000000..65450d2
--- /dev/null
+++ b/TbSimulation/src/.svn/text-base/TbTestMC.cpp.svn-base
@@ -0,0 +1,598 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Local
+#include "TbTestMC.h"
+
+/** @file TbTestMC.cpp
+ *
+ *  Implementation of class : TbTestMC
+ *	Author: Dan Saunders
+ */
+
+DECLARE_ALGORITHM_FACTORY(TbTestMC)
+
+//=============================================================================
+/// Standard constructor
+//=============================================================================
+TbTestMC::TbTestMC(const std::string& name, ISvcLocator* pSvcLocator)
+    : GaudiTupleAlg(name, pSvcLocator) {
+  declareProperty("InitAlignment", m_filename = "Alignment_raw.dat");
+  declareProperty("doMisAlign", m_misalign = false);
+  declareProperty("NTracks", m_nTracks = 100); // Per event. Homogenous in t.
+  
+  declareProperty("RunDuration", m_EventLength = 10000); // Max clock time per event.
+  declareProperty("NNoiseClusters", m_nNoiseClusters = 20); // Per event, per plane. Homogenous in t.
+
+
+  declareProperty("HitTimeJitter", m_HitTimeJitter = 10); // Time jitter width (clocks).
+  declareProperty("ClusterPosnError", m_ClustPosnResolution = 0.01);
+
+  declareProperty("ChargeSharingWidth", m_ChargeSharingWidth = 0.01);
+  declareProperty("ThresholdCut", m_ThresholdCut = 50.0);
+  declareProperty("ClusterCharge", m_charge = 300.0);
+  declareProperty("ForceEfficiency", m_ForceEfficiency = true);
+  // ...A measure of charge sharing - see below.
+
+  m_ChipWidth = 14.08;  // mm
+  m_PosnSpread = 4.0;   // mm
+
+  m_ChargeSigma = 150;
+  m_Pitch = 0.055;
+  m_nEvents = 0;
+  m_nExportedHits = 0;
+  m_nExportedTracks = 0;
+  m_ExportHits = true;
+  m_ExportClusters = false;
+  m_ExportTracks = false;
+}
+
+//=============================================================================
+/// Initialization
+//=============================================================================
+StatusCode TbTestMC::initialize() {
+
+  StatusCode sc = GaudiAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  setHistoTopDir("Tb/");
+
+  if (m_misalign) {
+    geomSvc()->readConditions(m_filename, m_modules);
+    geomSvc()->printAlignment(m_modules);
+  }
+
+  else m_modules = geomSvc()->modules();
+  m_nPlanes = m_modules.size();
+
+  m_Hits.resize(m_nPlanes);
+
+  // Initialize the random number generators.
+  sc = m_uniform.initialize(randSvc(), Rndm::Flat(0.0, 1.0));
+  if (!sc) {
+    error() << "Cannot initialize uniform random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_gauss.initialize(randSvc(), Rndm::Gauss(0.0, 1.0));
+  if (!sc) {
+    error() << "Cannot initialize Gaussian random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_landau.initialize(randSvc(), Rndm::Landau(m_charge, m_ChargeSigma));
+  if (!sc) {
+    error() << "Cannot initialize Landau random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_gauss2.initialize(randSvc(), Rndm::Gauss(0.0, 1.0e-4));
+  if (!sc) {
+    error() << "Cannot initialize Gaussian random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_uniform2.initialize(randSvc(), Rndm::Flat(0,m_ChipWidth ));
+  if (!sc) {
+    error() << "Cannot initialize uniform random number generator." << endmsg;
+    return sc;
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+/// Main execution
+//=============================================================================
+StatusCode TbTestMC::execute() {
+  if (m_nEvents % 10 == 0)
+    std::cout << "Event number: " << m_nEvents << std::endl;
+
+  generate_tracks();
+  createClustFromTrack();
+
+  //make_noise();
+  //make_tracks();
+
+  sort_stuff();
+  add_to_TES();
+
+  m_nEvents++;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    m_nExportedHits += m_Hits[i].size();
+    // Prepare for next event.
+    m_Hits[i].clear();
+  }
+  m_Clusters.clear();
+  m_Tracks.clear();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalize
+//=============================================================================
+StatusCode TbTestMC::finalize() {
+
+  info() << "------------------------------------------------------" << endmsg;
+  info() << "                      TbTestMC                      " << endmsg;
+  info() << "------------------------------------------------------" << endmsg;
+  info() << "Number of exported hits:\t"<<m_nExportedHits<<endmsg;
+  info() << "------------------------------------------------------" << endmsg;
+  // Finalise the base class.
+  return GaudiTupleAlg::finalize();
+
+}
+
+//=============================================================================
+/// Sorting
+//=============================================================================
+void TbTestMC::add_to_TES() {
+  // Hits.
+  if (m_ExportHits) ExportHits();
+
+  // Clusters.
+  if (m_ExportClusters) {
+    LHCb::TbClusters* clusters = new LHCb::TbClusters();
+    for (std::vector<LHCb::TbCluster*>::iterator ic = m_Clusters.begin();
+         ic != m_Clusters.end(); ic++)
+      clusters->insert(*ic);
+
+    put(clusters, LHCb::TbClusterLocation::Default);
+  }
+
+  // Tracks.
+  if (m_ExportTracks) {
+    LHCb::TbTracks* tracks = new LHCb::TbTracks();
+    for (std::vector<LHCb::TbTrack*>::iterator it = m_Tracks.begin();
+         it != m_Tracks.end(); it++)
+      tracks->insert(*it);
+
+    put(tracks, LHCb::TbTrackLocation::Default);
+  }
+}
+
+//=============================================================================
+/// Export hits to different TES locations.
+//=============================================================================
+void TbTestMC::ExportHits() {
+  std::vector<LHCb::TbHits*> all_hits;
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    LHCb::TbHits* hits = new LHCb::TbHits();
+    put(hits, LHCb::TbHitLocation::Default + std::to_string(i));
+    for (std::vector<LHCb::TbHit*>::iterator ih = m_Hits[i].begin();
+         ih != m_Hits[i].end(); ih++) {
+      hits->insert(*ih);
+    }
+  }
+}
+
+//=============================================================================
+/// Sorting - no sorting if not exporting.
+//=============================================================================
+void TbTestMC::sort_stuff() {
+  sort_by_chip();
+  if (m_ExportHits) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      hit_torder(i);
+    }
+  }
+  if (m_ExportClusters) cluster_torder();
+  if (m_ExportTracks) track_torder();
+}
+
+//=============================================================================
+/// Sorting by chip
+//=============================================================================
+void TbTestMC::sort_by_chip() {
+  std::vector<LHCb::TbCluster*> old_Clusters(m_Clusters);
+  m_Clusters.clear();
+  std::vector<TbModule*>::iterator m;
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    std::vector<LHCb::TbCluster*>::iterator ic;
+    for (ic = old_Clusters.begin(); ic != old_Clusters.end(); ++ic) {
+      if ((*ic)->plane() == (unsigned int)iplane) m_Clusters.push_back(*ic);
+    }
+  }
+
+}
+
+//=============================================================================
+/// Track time ordering - honeycomb
+//=============================================================================
+void TbTestMC::track_torder() {
+  int N = m_Tracks.size();
+  float s_factor = 1.3;
+  LHCb::TbTrack* track1, *track2;
+  int gap = N / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    for (int i = 0; gap + i < N; ++i) {
+      track1 = m_Tracks[i];
+      track2 = m_Tracks[i + gap];
+
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        m_Tracks[i] = track2;
+        m_Tracks[i + gap] = track1;
+
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Hit time ordering - honeycomb
+//=============================================================================
+void TbTestMC::hit_torder(const unsigned int plane) {
+  int N = m_Hits[plane].size();
+  float s_factor = 1.3;
+  LHCb::TbHit* hit1, *hit2;
+  int gap = N / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    for (int i = 0; gap + i < N; ++i) {
+      hit1 = m_Hits[plane][i];
+      hit2 = m_Hits[plane][i + gap];
+
+      if (hit1->time() > hit2->time()) {
+        // Do the swap.
+        m_Hits[plane][i] = hit2;
+        m_Hits[plane][i + gap] = hit1;
+
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Cluster time ordering - honeycomb
+//=============================================================================
+void TbTestMC::cluster_torder() {
+  int N = m_Clusters.size();
+  float s_factor = 1.3;
+  LHCb::TbCluster* clust1, *clust2;
+  int gap = N / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    for (int i = 0; gap + i < N; ++i) {
+      clust1 = m_Clusters[i];
+      clust2 = m_Clusters[i + gap];
+
+      if (clust1->time() > clust2->time() &&
+          clust1->plane() == clust2->plane()) {
+
+        // Do the swap.
+        m_Clusters[i] = clust2;
+        m_Clusters[i + gap] = clust1;
+
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Noise cluster posn
+//=============================================================================
+Gaudi::XYZPoint TbTestMC::ClustGposn(int iplane) {
+  float x, y;
+  bool on = true;
+  while (on) {
+    x = 0.5 * m_ChipWidth + m_gauss() * m_PosnSpread;
+    y = 0.5 * m_ChipWidth + m_gauss() * m_PosnSpread;
+
+    if (x > 0.028 + (2 * 0.055) && x < 14.05 - (2 * 0.055) &&
+        y > 0.028 + (2 * 0.055) && y < 14.05 - (2 * 0.055))
+      on = false;
+  }  // NO EDGES TAKEN INTO ACCOUNT YET.
+
+  Gaudi::XYZPoint posn(x, y, m_modules.at((unsigned int)iplane)->z());
+  return posn;
+}
+
+//=============================================================================
+/// Noise cluster charge
+//=============================================================================
+int TbTestMC::ClustCharge() {
+  float charge;
+  bool on = true;
+  while (on) {
+    charge = m_landau();
+    if (charge > 3.0 && charge < 1000) on = false;
+  }
+  return (int)charge;
+}
+
+//=============================================================================
+/// Tracks
+//=============================================================================
+void TbTestMC::make_tracks() {
+  for (int i = 0; i < m_nTracks; i++) {
+    // Make a track at a particular position. Clusters and hits saved auto.
+    int time = (int)(m_uniform() * m_EventLength);
+    LHCb::TbTrack* track = make_track(ClustGposn(0), time, i);
+    m_Tracks.push_back(track);
+
+    unsigned int nActualClusters = 0;
+    for (unsigned int i=0; i<track->clusters().size(); i++) {
+    	if (track->clusters()[i]->size() != 0) nActualClusters++;
+    }
+
+    if (nActualClusters == m_nPlanes || nActualClusters == m_nPlanes-1)
+    		m_nExportedTracks++;
+  }
+}
+
+//=============================================================================
+/// Track
+//=============================================================================
+LHCb::TbTrack* TbTestMC::make_track(Gaudi::XYZPoint p, float t, int itrack) {
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    Gaudi::XYZPoint ClustPosn(p.x(), p.y(), m_modules.at(iplane)->z());
+    LHCb::TbCluster* cluster = make_cluster(ClustPosn, t, iplane, itrack);
+    track->addToClusters(cluster);
+    m_Clusters.push_back(cluster);
+  }
+  m_trackFit->fit(track);
+  return track;
+}
+
+//=============================================================================
+/// Noise
+//=============================================================================
+void TbTestMC::make_noise() {
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    for (int i = 0; i < m_nNoiseClusters; i++) {
+      // Make a cluster at a particular position. Hits saved auto.
+      int time = (int)(m_uniform() * m_EventLength);
+      LHCb::TbCluster* cluster = make_cluster(ClustGposn(iplane), time, iplane, -1);
+      m_Clusters.push_back(cluster);
+    }
+  }
+}
+
+//=============================================================================
+/// MC cluster maker.
+//=============================================================================
+LHCb::TbCluster* TbTestMC::make_cluster(Gaudi::XYZPoint pGlobal_perfect,
+                                        float t, int iplane, int track_tag) {
+  LHCb::TbCluster* clust = new LHCb::TbCluster();
+  clust->setTime(t);
+
+  double x = pGlobal_perfect.x();
+  double y = pGlobal_perfect.y();
+
+  
+  x += m_gauss() * m_ClustPosnResolution;
+  y += m_gauss() * m_ClustPosnResolution;
+
+  Gaudi::XYZPoint pGlobal_actual(x, y, pGlobal_perfect.z());
+
+  Gaudi::XYZPoint pLocal = geomSvc()->globalToLocal(pGlobal_actual, iplane);
+  clust->setXloc(pLocal.x());
+  clust->setYloc(pLocal.y());
+
+  //std::cout<<clust->xloc()<<"\t"<<pGlobal_actual.x()<<"\t"<<clust->yloc()<<"\t"<<pGlobal_actual.y()<<std::endl;
+
+  clust->setX(pGlobal_actual.x());
+  clust->setY(pGlobal_actual.y());
+  clust->setZ(pGlobal_actual.z());
+
+  clust->setPlane(iplane);
+  
+  setClusterHitsAndCharge(clust, track_tag); // Also sets Charge.
+
+  return clust;
+}
+
+//=============================================================================
+/// Cluster hits
+//=============================================================================
+void TbTestMC::setClusterHitsAndCharge(LHCb::TbCluster* clust, int /*track_tag*/) {
+  // This version will model the charge cloud as a gaussian that is ceneted
+  // at the cluster position, and whose height is set by the cluster charge
+  // (albeit abit sneakily). Width is set above. The charge of surrounding
+  // pixels is then taken to be the height of the gaussian at that pixels
+  // position (if passing the threshold - kind of zero suppression);
+  // like poor mans integration.
+  double SigSq = m_ChargeSharingWidth*m_ChargeSharingWidth;
+  int clustChargeish = ClustCharge();
+  double N = clustChargeish*0.4;
+  int SeedHitX = (int)(clust->xloc()/m_Pitch);
+  int SeedHitY = (int)(clust->yloc()/m_Pitch);
+
+
+  int ClustCharge = 0;
+  int HalfAreaSide = 1; // 3x3
+  // Search over area around the seed.
+  //std::cout<<"New cluster at:\t"<<clust->xloc()<<"\t"<<clust->yloc()<<std::endl;
+  for (int ix=SeedHitX-HalfAreaSide; ix!=SeedHitX+HalfAreaSide+1; ix++){
+	for (int iy=SeedHitY-HalfAreaSide; iy!=SeedHitY+HalfAreaSide+1; iy++){
+	  // Find distance to the pixel from the center of the gaussian.
+	  double delx = (double(ix)+0.5)*m_Pitch - clust->xloc();
+      double dely = (double(iy)+0.5)*m_Pitch - clust->yloc();
+	  double delrSq = delx*delx + dely*dely;
+	  int pixToT = (int)N*exp(-delrSq/SigSq);
+
+
+	  if ((float)pixToT > m_ThresholdCut) {
+	    LHCb::TbHit * hit = new LHCb::TbHit();
+            hit->setDevice(clust->plane());
+		hit->setCol(ix);
+		hit->setRow(iy);
+		hit->setToT(pixToT);
+		hit->setTime(clust->time() + m_gauss() * m_HitTimeJitter);
+		clust->addToHits(hit);
+		m_Hits[clust->plane()].push_back(hit);
+
+		// hit->setTrackTag(track_tag);
+		ClustCharge += pixToT;
+	  }
+	}
+  }
+
+  if (clust->size()==0 && m_ForceEfficiency){ // i.e. none of the hits passed the thresehold
+	LHCb::TbHit * hit = new LHCb::TbHit();
+	hit->setCol(SeedHitX);
+	hit->setRow(SeedHitY);
+	hit->setToT(clustChargeish);
+	hit->setTime(clust->time() + m_gauss() * m_HitTimeJitter);
+
+	// hit->setTrackTag(track_tag);
+
+	clust->addToHits(hit);
+	m_Hits[clust->plane()].push_back(hit);
+	ClustCharge += clustChargeish;
+  }
+  clust->setCharge(ClustCharge);
+}
+
+//=============================================================================
+// Randomly generates tracks (C.Hombach)
+//=============================================================================
+
+void TbTestMC::generate_tracks() 
+{
+  double slope_xz;
+  double slope_yz;
+  double inter_x;
+  double inter_y;
+  
+for (int i = 0; i < m_nTracks; i++) {  
+  //Generate slopes and intercepts equally distributed over the sensor
+  slope_xz = m_gauss2();
+  slope_yz = m_gauss2();
+  inter_x  = m_uniform2();
+  inter_y  = m_uniform2();
+  plot(slope_xz, "slopeXZ", "slopeXZ", -1.e-3,1.e-3,1000);
+  plot(slope_yz, "slopeYZ", "slopeYZ", -1.e-3,1.e-3,1000);
+  //Create track
+  LHCb::TbState state;// = new LHCb::TbState();
+  state.setTx(slope_xz);
+  state.setTy(slope_yz);
+  state.setX(inter_x);
+  state.setY(inter_y);
+  
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+  track->setFirstState(state);
+  m_Tracks.push_back(track);
+  
+ }
+}
+
+//=============================================================================
+//Calculates cluster from track intercepts with module planes
+//=============================================================================
+
+void TbTestMC::createClustFromTrack()
+{
+  std::vector<LHCb::TbTrack*>::iterator it = m_Tracks.begin();
+  for( ; it != m_Tracks.end(); ++it)
+  {
+    int time = (int)(m_uniform() * m_EventLength);
+    std::vector<TbModule*>::iterator im = m_modules.begin();
+    for( ; im != m_modules.end(); ++im)
+    {
+      
+      Gaudi::XYZPoint ip = getIntercept(im - m_modules.begin(), (*it));
+      Gaudi::XYZPoint pLocal = geomSvc()->globalToLocal(ip, im - m_modules.begin());
+            
+      LHCb::TbCluster* clust = new LHCb::TbCluster();
+      clust->setTime(time);
+      clust->setXloc(pLocal.x());
+      clust->setYloc(pLocal.y());      
+      clust->setX(ip.x());
+      clust->setY(ip.y());
+      clust->setZ(ip.z());
+      clust->setCharge(ClustCharge());
+      clust->setPlane(im - m_modules.begin());
+      
+      setClusterHitsAndCharge(clust,-1);
+      m_Clusters.push_back(clust);
+    }
+    
+  }
+  
+  
+}
+
+//============================================================================
+// Calculates Intercept of track and a module (Needs to be moved somewhere else)
+//============================================================================
+
+Gaudi::XYZPoint TbTestMC::getIntercept(const unsigned int& plane, LHCb::TbTrack* track)
+{
+  Gaudi::XYZPoint p1Local(0., 0., 0.), p2Local(0., 0., 1.);
+  Gaudi::XYZPoint p1Global =
+    geomSvc()->localToGlobal(p1Local, plane);
+  Gaudi::XYZPoint p2Global =
+    geomSvc()->localToGlobal(p2Local, plane);
+  Gaudi::XYZPoint normal(p2Global.x() - p1Global.x(),
+                         p2Global.y() - p1Global.y(),
+                         p2Global.z() - p1Global.z());
+  //  std::cout << track->firstState().tx() << std::endl;
+  const double dir_r =
+    sqrt(track->firstState().tx() * track->firstState().tx() +
+         track->firstState().ty() * track->firstState().ty() + 1.);
+  const double dir_x = track->firstState().tx() / dir_r;
+  const double dir_y = track->firstState().ty() / dir_r;
+  const double dir_z = 1. / dir_r;
+  const double length =
+    ((p1Global.x() - track->firstState().x()) * normal.x() +
+     (p1Global.y() - track->firstState().y()) * normal.y() +
+     (p1Global.z() - 0.) * normal.z()) /
+    (dir_x * normal.x() + dir_y * normal.y() + dir_z * normal.z());
+  const double x_inter = track->firstState().x() + dir_x * length;
+  const double y_inter = track->firstState().y() + dir_y * length;
+  const double z_inter = 0. + dir_z * length;
+  Gaudi::XYZPoint intersect_global(x_inter, y_inter, z_inter);
+  
+  return intersect_global;
+  
+}
+
+
+//=============================================================================
+/// End
+//=============================================================================
diff --git a/TbSimulation/src/.svn/text-base/TbTestMC.h.svn-base b/TbSimulation/src/.svn/text-base/TbTestMC.h.svn-base
new file mode 100644
index 0000000..6f87a42
--- /dev/null
+++ b/TbSimulation/src/.svn/text-base/TbTestMC.h.svn-base
@@ -0,0 +1,99 @@
+#ifndef TB_TESTMC_H
+#define TB_TESTMC_H 1
+
+#include "TH1.h"
+#include "TH2.h"
+
+#include "GaudiAlg/GaudiTupleAlg.h"
+#include "GaudiKernel/RndmGenerators.h"
+
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/TbModule.h"
+#include "Event/TbHit.h"
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+/** @class TbTestMC TbTestMC.h
+ *  Author: Dan Saunders
+ */
+
+class TbTestMC : public GaudiTupleAlg {
+ public:
+  TbTestMC(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TbTestMC() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+  int m_nEvents;
+  void generate_tracks();
+  void createClustFromTrack();
+  void add_to_TES();
+  void ExportHits();
+  void sort_stuff();
+  void sort_by_chip();
+  void track_torder();
+  void cluster_torder();
+  void hit_torder(const unsigned int plane);
+  Gaudi::XYZPoint ClustGposn(int);
+  int ClustCharge();
+  void make_tracks();
+  LHCb::TbTrack* make_track(Gaudi::XYZPoint, float, int);
+  void make_noise();
+  LHCb::TbCluster* make_cluster(Gaudi::XYZPoint, float, int, int);
+  int ClustSize();
+  void setClusterHitsAndCharge(LHCb::TbCluster*, int);
+  Gaudi::XYZPoint getIntercept(const unsigned int& plane, LHCb::TbTrack*);
+  
+
+  int m_nTracks;
+  int m_EventLength;
+  int m_nNoiseClusters;
+  int m_HitTimeJitter;
+  float m_ClustPosnResolution;
+  unsigned int m_nPlanes;
+  float m_ChipWidth;
+  float m_PosnSpread;
+  float m_charge;
+  bool m_ForceEfficiency;
+  float m_ChargeSigma;
+  float m_Pitch;
+  double m_ChargeSharingWidth;
+  float m_ThresholdCut;
+  unsigned int m_nExportedTracks;
+  bool m_ExportHits;
+  bool m_ExportClusters;
+  bool m_ExportTracks;
+
+  int m_nExportedHits;
+
+  std::string m_filename;
+  bool m_misalign;
+  
+  std::vector<TbModule*> m_modules;
+
+  std::vector<float> m_ClustSizeFracs;
+
+  std::vector<std::vector<LHCb::TbHit*> > m_Hits;          // Per event.
+  std::vector<LHCb::TbCluster*> m_Clusters;  // Per event.
+  std::vector<LHCb::TbTrack*> m_Tracks;      // Per event.
+
+
+  // Geometry service.
+  mutable ITbGeometrySvc* m_geomSvc;
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+  ITbTrackFit* m_trackFit;
+
+
+  // Random number genorators.
+  Rndm::Numbers m_uniform;
+  Rndm::Numbers m_gauss;
+  Rndm::Numbers m_landau;
+  Rndm::Numbers m_gauss2;
+  Rndm::Numbers m_uniform2;
+};
+#endif
diff --git a/TbSimulation/src/.svn/text-base/TbTrackFitter.cpp.svn-base b/TbSimulation/src/.svn/text-base/TbTrackFitter.cpp.svn-base
new file mode 100644
index 0000000..b284bbb
--- /dev/null
+++ b/TbSimulation/src/.svn/text-base/TbTrackFitter.cpp.svn-base
@@ -0,0 +1,511 @@
+// ROOT
+#include "TMath.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Tb
+#include "TbKernel/ITbGeometrySvc.h"
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+#include "Event/TbState.h"
+
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanNode.h"
+#include "Event/TbKalmanPixelMeasurement.h"
+
+#include <math.h>
+
+// Local
+#include "TbTrackFitter.h"
+
+/** @file TbTrackFitter.cpp
+ *
+ *  Implementation of class : TbTrackFitter
+ *	Author: Panagiotis Tsopelas
+ */
+
+DECLARE_ALGORITHM_FACTORY(TbTrackFitter)
+
+//=============================================================================
+/// Standard constructor
+//=============================================================================
+TbTrackFitter::TbTrackFitter(const std::string& name, ISvcLocator* pSvcLocator)
+    : GaudiTupleAlg(name, pSvcLocator), m_trackFit(NULL) {
+
+  // Global default values.
+  declareProperty("onOff_hists", m_onOff_hists = true);
+  declareProperty("scat2", m_scat2 = 1.35e-8);
+  declareProperty("hiterror2", m_hiterror2 = 1.6e-5);
+  declareProperty("theta0", m_theta0 = 1.e-4);
+  declareProperty("direction", m_direction = -1);
+  // Local default values.
+  m_nPlanes = 8;
+  sigmax = 0.004 * Gaudi::Units::mm;
+  sigmay = 0.004 * Gaudi::Units::mm;
+}
+
+//=============================================================================
+/// Initialization
+//=============================================================================
+StatusCode TbTrackFitter::initialize() {
+
+  StatusCode sc = GaudiAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  setHistoTopDir("Tb/");
+  if (m_onOff_hists) setup_hists();
+
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+
+  // Initialize the random number generator.
+  sc = m_gauss.initialize(randSvc(), Rndm::Gauss(0.0, 1.0));
+  if (!sc) {
+    error() << "Cannot initialize Gaussian random number generator." << endmsg;
+    return sc;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+/// Main execution
+//=============================================================================
+StatusCode TbTrackFitter::execute() {
+  if (msgLevel(MSG::DEBUG)) debug() << " ==> execute()" << endmsg;
+
+  // TbTrack container
+  std::vector<LHCb::TbTrack*> tracks_vec;
+  // TbKalmanTrack container
+  std::vector<LHCb::TbKalmanTrack*> ktracks_vec;
+  
+  const unsigned int nPlanes = m_nPlanes;
+//  const double sigmax = 0.004 * Gaudi::Units::mm;
+//  const double sigmay = 0.004 * Gaudi::Units::mm;
+
+  // Gap from next/previous event
+//  std::cout << std::endl << std::endl << std::endl ;
+
+  // make random track parameters -> True straight track - NO scattering
+  double Rx0 = m_gauss() * 15. * Gaudi::Units::mm ;
+  double Rtx = m_gauss() * 1.e-4 ;
+  double Ry0 = m_gauss() * 15. * Gaudi::Units::mm ;
+  double Rty = m_gauss() * 1.e-4 ;
+  // print random initial track parameters
+//  std::cout << "--> Random track with x0 = " << Rx0 << " and tx = " << Rtx << std::endl;
+ 
+  // theta0 for MCS through small angles
+  double theta0 = TMath::ATan(m_theta0) ;
+  // store true slope and intercept from scattering
+  std::vector<double> scatRtx(nPlanes);
+  std::vector<double> scatRty(nPlanes);
+  
+  // Declare TbTrack
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+
+  // make random clusters ..
+  std::vector<LHCb::TbCluster> clusters(nPlanes);
+  
+  // .. but fix their Z positions according to the Alignment File
+  clusters[0].setZ( 0. );           clusters[4].setZ( 306. );
+  clusters[1].setZ( 31. );          clusters[5].setZ( 336. );
+  clusters[2].setZ( 60. );          clusters[6].setZ( 366. );
+  clusters[3].setZ( 89. );          clusters[7].setZ( 397. );
+  
+  const double weight = 1. / (0.004 * 0.004); 
+  // initialize 1st cluster
+  clusters[0].setX( ( Rtx + Rx0 ) + m_gauss()*sigmax ); // random straight line
+  clusters[0].setY( ( Rty + Ry0 ) + m_gauss()*sigmay ); // random straight line
+  clusters[0].setXErr( 0.004 );
+  clusters[0].setYErr( 0.004 );
+  clusters[0].setWx(weight);
+  clusters[0].setWy(weight);
+  clusters[0].setPlane(0);
+  track->addToClusters(&clusters[0]);
+  
+//  std::cout << " Clusters in X: " ;
+//  std::cout << clusters[0].x() << ", " ;
+  // update x0 and tx due to scattering
+  scatRx0[0] = Rx0 ;
+  scatRtx[0] = Rtx + m_gauss()*theta0;
+  scatRy0[0] = Ry0;
+  scatRty[0] = Rty + m_gauss()*theta0;
+  
+  // fill the rest of the clusters
+  for (unsigned int i = 1; i < nPlanes; ++i) {
+  
+    // update x0 and tx due to scattering
+    scatRx0[i] = ( clusters[i].z() - clusters[i-1].z() ) * scatRtx[i-1] + scatRx0[i-1] ;
+    scatRtx[i] = scatRtx[i-1] + m_gauss() * theta0;
+    scatRy0[i] = ( clusters[i].z() - clusters[i-1].z() ) * scatRty[i-1] + scatRy0[i-1];
+    scatRty[i] = scatRty[i-1] + m_gauss() * theta0;
+  
+    clusters[i].setX( scatRx0[i] + m_gauss()*sigmax );
+    clusters[i].setY( scatRy0[i] + m_gauss()*sigmay );
+    clusters[i].setXErr( 0.004 );
+    clusters[i].setYErr( 0.004 );
+    clusters[i].setWx(weight);
+    clusters[i].setWy(weight);
+    clusters[i].setPlane(i);
+    track->addToClusters(&clusters[i]);
+    if (i==nPlanes) continue;
+    
+  }
+  
+  // const SmartRefVector<LHCb::TbCluster>& clustersL = track->clusters();
+//  std::cout << std::endl << "Track with " << track->size() << " clusters. " << std::endl;
+//  // print true positions of track
+//  std::cout << " True X positions of (scattered) track: ";
+//    std::cout << Rx0 << ",   " ;
+//  for (int i=0; i<nPlanes; i++){
+//    std::cout << scatRx0[i] << ",   " ;
+//  }
+//  std::cout << std::endl;
+//  std::cout << " Cluster X positions                  :             ";
+//  for (auto it = clustersL.cbegin(), end = clustersL.cend(); it != end; ++it) {
+//    std::cout << (*it)->x() << ", ";
+//  }
+//  std::cout << " Cluster X errors                  :             ";
+//  for (auto it = clustersL.cbegin(), end = clustersL.cend(); it != end; ++it) {
+//    std::cout << (*it)->xErr() << ", ";
+//  }
+////  for (int i=0; i<nPlanes; i++){
+////    std::cout << clusters[i].x() << ",   " ;
+////  }
+//
+//  std::cout << std::endl;
+//  std::cout << " Cluster Z positions                  :             ";
+//  for (auto it = clustersL.cbegin(), end = clustersL.cend(); it != end; ++it) {
+//    std::cout << (*it)->z() << ", ";
+//  }
+////  for (int i=0; i<nPlanes; i++){
+////    std::cout << clusters[i].z() << ",   " ;
+////  }
+//  std::cout << std::endl;
+  
+  
+  // fit the track
+  m_trackFit->fit(track);
+
+
+
+  // print results of simple fit
+//  std::cout << std::endl << " * chi2 on x-z plane: " << track->chi2() << " with ndof = " << track->ndof() << std::endl
+//			 << " x0: " << track->firstState().x() << " +/- " << TMath::Sqrt(track->firstState().errX2() )
+//			 << ", y0: " << track->firstState().y() << " +/- " << TMath::Sqrt(track->firstState().errY2() )
+//			 << std::endl 
+//			 << " tx: " << track->firstState().tx() << " +/- " << TMath::Sqrt( track->firstState().errTx2() )
+//			 << ", ty: " << track->firstState().ty() << " +/- " << TMath::Sqrt( track->firstState().errTy2() )
+//			 << std::endl ;
+
+
+
+
+
+  //---------------------------------------------------------------------------
+  // Wouter's new code
+  //---------------------------------------------------------------------------
+  
+  // node : combination of a measurement and a track state is referred to as a node
+  // std::cout << std::endl << " ==================================================   " << std::endl;
+  
+  // create a fit track object (which is actually also a TbTrack)
+  LHCb::TbKalmanTrack* ktrack = new LHCb::TbKalmanTrack(*track,  m_hiterror2, m_scat2) ;
+  // fit it
+  ktrack->fit() ;
+  
+  // dump some info about the fit
+//  ktrack->print() ;
+   // std::cout << " ==================================================   " << std::endl;
+  //---------------------------------------------------------------------------
+
+
+  // store the track in the track vector
+  tracks_vec.push_back(track);
+  // store the ktrack in the track vector
+  ktracks_vec.push_back(ktrack);
+
+  // Check whether to fill histograms
+  if (m_onOff_hists) {
+   fill_hists(tracks_vec);
+   fill_khists(ktracks_vec);
+  }
+
+  // delete the pointer to the track
+  delete track;
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+///               F  U  N  C  T  I  O  N  S
+//=============================================================================
+
+//=============================================================================
+/// Fill Histograms for TbTracks
+//=============================================================================
+void TbTrackFitter::fill_hists(std::vector<LHCb::TbTrack*>& tracks) {
+
+  std::vector<LHCb::TbTrack*>::iterator ictra;
+  for (ictra = tracks.begin(); ictra != tracks.end(); ictra++) {
+
+    // if ( TMath::Prob((*ictra)->chi2() , (*ictra)->ndof()) < 0.05) continue;
+
+    // Fill the track histos
+    m_slopesX->Fill((*ictra)->firstState().tx());
+    m_slopesY->Fill((*ictra)->firstState().ty());
+    m_Sfit_chi2->Fill((*ictra)->chi2PerNdof());
+    m_Sfit_prob->Fill( TMath::Prob((*ictra)->chi2() , (*ictra)->ndof()) );
+
+    // Get the clusters of this TbTrack
+    const SmartRefVector<LHCb::TbCluster> clusters = (*ictra)->clusters();
+
+    // Loop through the clusters of this TbTrack
+    SmartRefVector<LHCb::TbCluster>::const_iterator icclu;
+    for (icclu = clusters.begin(); icclu != clusters.end(); ++icclu) {
+      int ichip = (*icclu)->plane();
+
+      m_clustersX->Fill((*icclu)->x());
+      m_clustersY->Fill((*icclu)->y());
+
+      double xTraAtZclu = (*ictra)->firstState().x() +
+                          (*ictra)->firstState().tx() * (double)(*icclu)->z();
+      double yTraAtZclu = (*ictra)->firstState().y() +
+                          (*ictra)->firstState().ty() * (double)(*icclu)->z();
+
+      double resx = (*icclu)->x() - xTraAtZclu ;
+      double resy = (*icclu)->y() - yTraAtZclu ;
+      
+      // Fill residuals
+      m_resSfit_X[ichip]->Fill( resx );
+      m_resSfit_Y[ichip]->Fill( resy );
+      
+      // Fill residual pulls
+      m_respullSfit_X[ichip]->Fill((double) resx / sigmax);
+      m_respullSfit_Y[ichip]->Fill((double) resy / sigmay);
+      
+      // Fill differences from true track
+      m_trueSfit_X[ichip]->Fill( scatRx0[ichip] - xTraAtZclu );
+      m_trueSfit_Y[ichip]->Fill( scatRy0[ichip] - yTraAtZclu );
+      
+      // Fill true pulls
+      m_trackpullSfit_X[ichip]->Fill( (scatRx0[ichip] - xTraAtZclu) / std::sqrt((*ictra)->firstState().covariance()(0,0)) );
+      m_trackpullSfit_Y[ichip]->Fill( (scatRy0[ichip] - yTraAtZclu) / std::sqrt((*ictra)->firstState().covariance()(1,1)) );
+//      m_trackpullSfit_X[ichip]->Fill( (scatRx0[ichip] - xTraAtZclu) / sigmax );
+//      m_trackpullSfit_Y[ichip]->Fill( (scatRy0[ichip] - yTraAtZclu) / sigmay );
+      
+
+
+    }  // end of cluster loop
+
+  }  // end of track loop
+}
+
+//=============================================================================
+/// Fill Histograms for TbKalmanTracks
+//=============================================================================
+void TbTrackFitter::fill_khists(std::vector<LHCb::TbKalmanTrack*>& ktracks) {
+  
+  std::vector<LHCb::TbKalmanTrack*>::iterator icktra;
+  for (icktra = ktracks.begin(); icktra != ktracks.end(); icktra++) {
+    
+    // Fill the track histos
+    m_Kfit_chi2->Fill((*icktra)->chi2());
+    m_Kfit_prob->Fill( TMath::Prob((*icktra)->chi2(), (*icktra)->ndof()) );
+    
+//    node->residualX() / std::sqrt(pixelhit->residualCovX()
+    
+    // Get the nodes of this TbKalmanTrack
+    //const std::vector<LHCb::TbKalmanNode*>& knodes = (*icktra)->nodes();
+    
+    // Loop through the nodes of this TbKalmanTrack
+    for( auto node : (*icktra)->nodes() ) {
+      auto pixnode = dynamic_cast< LHCb::TbKalmanPixelMeasurement*>( node) ;
+      if( pixnode ) {
+        int ichip = pixnode->cluster().plane();
+        
+        // Fill unbiased residuals
+        m_XunresKfit[ichip]->Fill( pixnode->residualX() * pixnode->covX() / pixnode->residualCovX() );
+        m_YunresKfit[ichip]->Fill( pixnode->residualY() * pixnode->covY() / pixnode->residualCovY() );
+        
+        // Fill residuals
+        m_resKfit_X[ichip]->Fill( pixnode->residualX() );
+        m_resKfit_Y[ichip]->Fill( pixnode->residualY() );
+        
+        // Fill residual errors
+        m_reserrKfit_X[ichip]->Fill( std::sqrt(pixnode->residualCovX()) );
+        m_reserrKfit_Y[ichip]->Fill( std::sqrt(pixnode->residualCovY()) );
+        
+        // Fill residual pulls
+        m_respullKfit_X[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
+        m_respullKfit_Y[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
+        
+        // Fill differences from true tracks
+        m_trueKfit_X[ichip]->Fill( scatRx0[ichip] - pixnode->state().x() );
+        m_trueKfit_Y[ichip]->Fill( scatRy0[ichip] - pixnode->state().y() );
+        
+        // Fill differences errors from true tracks
+        m_trueerrKfit_X[ichip]->Fill( TMath::Sqrt(pixnode->state().covariance()(0,0)) );
+        m_trueerrKfit_Y[ichip]->Fill( TMath::Sqrt(pixnode->state().covariance()(1,1)) );
+        
+        // Fill true pulls
+        m_trackpullKfit_X[ichip]->Fill( (scatRx0[ichip] - pixnode->state().x() ) / TMath::Sqrt(pixnode->state().covariance()(0,0)) );
+        m_trackpullKfit_Y[ichip]->Fill( (scatRy0[ichip] - pixnode->state().y() ) / TMath::Sqrt(pixnode->state().covariance()(1,1)) );
+        
+      }
+    }
+  }  // end of Ktrack loop
+}
+
+
+//=============================================================================
+/// Setup Histograms
+//=============================================================================
+void TbTrackFitter::setup_hists() {
+
+  // TbTrack parameters plots
+  m_Sfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/chi2perndof", "Chi2/ndof", -0.5, 49.5, 100));
+  
+  m_Sfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/probability", "Chi2 prob of S fit", 0.0, 1.0, 100));
+
+  m_slopesX = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/slopesX", "slopes in X of TbTracks", -1.e-3, 1.e-3, 100));
+  
+  m_slopesY = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/slopesY", "slopes in Y of TbTracks", -1.e-3, 1.e-3, 100));
+
+  m_Kfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("KalmanFit/chi2", "Chi2", -0.5, 49.5, 100));
+  
+  m_Kfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("KalmanFit/probability", "Chi2 prob of K fit", 0.0, 1.0, 100));
+  
+  m_clustersX = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("clustersX", "cluster X positions ", -1.e-2, 1.e-2, 100));
+
+  m_clustersY = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("clustersY", "cluster Y positions ", -1.e-2, 1.e-2, 100));
+
+  
+
+  // Residual plots
+  std::string hist_name;
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    std::stringstream ss_chip;
+    ss_chip << i;
+
+    // straight line fit 
+    hist_name = "StraightLineFit/Residuals_on_X/plane_" + ss_chip.str();
+    m_resSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+
+    hist_name = "StraightLineFit/Residuals_on_Y/plane_" + ss_chip.str();
+    m_resSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+
+
+    hist_name = "StraightLineFit/ResidualPull_on_X/plane_" + ss_chip.str();
+    m_respullSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    hist_name = "StraightLineFit/ResidualPull_on_Y/plane_" + ss_chip.str();
+    m_respullSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+
+
+    hist_name = "StraightLineFit/Differences_from_true_on_X/plane_" + ss_chip.str();
+    m_trueSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    hist_name = "StraightLineFit/Differences_from_true_on_Y/plane_" + ss_chip.str();
+    m_trueSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+
+
+    hist_name = "StraightLineFit/TrackPull_on_X/plane_" + ss_chip.str();
+    m_trackpullSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+
+    hist_name = "StraightLineFit/TrackPull_on_Y/plane_" + ss_chip.str();
+    m_trackpullSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+
+    
+    // Kalman fit
+    hist_name = "KalmanFit/UnbiasedResidualsX/plane_" + ss_chip.str();
+    m_XunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    
+    hist_name = "KalmanFit/UnbiasedResidualsY/plane_" + ss_chip.str();
+    m_YunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    //
+    
+    hist_name = "KalmanFit/Residuals_on_X/plane_" + ss_chip.str();
+    m_resKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    
+    hist_name = "KalmanFit/Residuals_on_Y/plane_" + ss_chip.str();
+    m_resKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    hist_name = "KalmanFit/Residual_errors_on_X/plane_" + ss_chip.str();
+    m_reserrKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/Residual_errors_on_Y/plane_" + ss_chip.str();
+    m_reserrKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_X/plane_" + ss_chip.str();
+    m_respullKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_Y/plane_" + ss_chip.str();
+    m_respullKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+
+    hist_name = "KalmanFit/Differences_from_true_on_X/plane_" + ss_chip.str();
+    m_trueKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    
+    hist_name = "KalmanFit/Differences_from_true_on_Y/plane_" + ss_chip.str();
+    m_trueKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    hist_name = "KalmanFit/Differences_errors_from_true_on_X/plane_" + ss_chip.str();
+    m_trueerrKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/Differences_errors_from_true_on_Y/plane_" + ss_chip.str();
+    m_trueerrKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/TrackPull_on_X/plane_" + ss_chip.str();
+    m_trackpullKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/TrackPull_on_Y/plane_" + ss_chip.str();
+    m_trackpullKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+  }
+}
+
+//=============================================================================
+/// End
+//=============================================================================
diff --git a/TbSimulation/src/.svn/text-base/TbTrackFitter.h.svn-base b/TbSimulation/src/.svn/text-base/TbTrackFitter.h.svn-base
new file mode 100644
index 0000000..b18cf9f
--- /dev/null
+++ b/TbSimulation/src/.svn/text-base/TbTrackFitter.h.svn-base
@@ -0,0 +1,116 @@
+#ifndef TB_TRACKFITTER_H
+#define TB_TRACKFITTER_H 1
+
+#include "TH1.h"
+#include "TH2.h"
+
+#include "GaudiAlg/GaudiTupleAlg.h"
+#include "GaudiKernel/RndmGenerators.h"
+
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/ITbTrackFit.h"
+
+
+/** @class TbTrackFitter TbTrackFitter.h
+ *  Author: Panagiotis Tsopelas
+ */
+
+class TbTrackFitter : public GaudiTupleAlg {
+ public:
+  TbTrackFitter(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TbTrackFitter() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  Rndm::Numbers m_gauss;
+
+  bool m_onOff_hists;
+  unsigned int m_nPlanes;
+
+  ITbTrackFit* m_trackFit;
+  
+  double            m_scat2;
+  double            m_hiterror2;
+  double            m_theta0;
+  int               m_direction;
+  
+  double sigmax;
+  double sigmay;
+  
+  double scatRx0[8];
+  double scatRy0[8];
+  
+  mutable ITbGeometrySvc* m_geomSvc;  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+
+  // Histograms
+  
+  TH1D* m_clustersX;
+  TH1D* m_clustersY;
+  
+  // straight line fit
+  TH1D* m_Sfit_chi2;
+  TH1D* m_Sfit_prob;
+
+  TH1D* m_slopesX;
+  TH1D* m_slopesY;
+
+  std::vector<TH1D*> m_resSfit_X;
+  std::vector<TH1D*> m_resSfit_Y;
+  
+  std::vector<TH1D*> m_trueSfit_X;
+  std::vector<TH1D*> m_trueSfit_Y;
+  
+  std::vector<TH1D*> m_respullSfit_X;
+  std::vector<TH1D*> m_respullSfit_Y;
+  
+  std::vector<TH1D*> m_trackpullSfit_X;
+  std::vector<TH1D*> m_trackpullSfit_Y;
+
+
+  // Kalman filter
+  TH1D* m_Kfit_chi2;
+  TH1D* m_Kfit_prob;
+  
+  // unbiased residuals
+  std::vector<TH1D*> m_XunresKfit;
+  std::vector<TH1D*> m_YunresKfit;
+  
+  std::vector<TH1D*> m_resKfit_X;
+  std::vector<TH1D*> m_resKfit_Y;
+
+  std::vector<TH1D*> m_reserrKfit_X;
+  std::vector<TH1D*> m_reserrKfit_Y;
+
+  std::vector<TH1D*> m_respullKfit_X;
+  std::vector<TH1D*> m_respullKfit_Y;
+
+  std::vector<TH1D*> m_trueKfit_X;
+  std::vector<TH1D*> m_trueKfit_Y;
+
+  std::vector<TH1D*> m_trueerrKfit_X;
+  std::vector<TH1D*> m_trueerrKfit_Y;
+
+  std::vector<TH1D*> m_trackpullKfit_X;
+  std::vector<TH1D*> m_trackpullKfit_Y;
+
+  
+
+  // Histograms functions
+  void setup_hists();
+  void fill_hists(std::vector<LHCb::TbTrack*>&);
+  void fill_khists(std::vector<LHCb::TbKalmanTrack*>&);
+
+  // Modifiers and Accessors
+
+  void setNPlanes(unsigned int nplanes) { m_nPlanes = nplanes; }
+  int nPlanes() { return m_nPlanes; }
+
+  bool onOff_hists() { return m_onOff_hists; }
+};
+#endif
diff --git a/TbSimulation/src/TbTestMC.cpp b/TbSimulation/src/TbTestMC.cpp
new file mode 100644
index 0000000..65450d2
--- /dev/null
+++ b/TbSimulation/src/TbTestMC.cpp
@@ -0,0 +1,598 @@
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Local
+#include "TbTestMC.h"
+
+/** @file TbTestMC.cpp
+ *
+ *  Implementation of class : TbTestMC
+ *	Author: Dan Saunders
+ */
+
+DECLARE_ALGORITHM_FACTORY(TbTestMC)
+
+//=============================================================================
+/// Standard constructor
+//=============================================================================
+TbTestMC::TbTestMC(const std::string& name, ISvcLocator* pSvcLocator)
+    : GaudiTupleAlg(name, pSvcLocator) {
+  declareProperty("InitAlignment", m_filename = "Alignment_raw.dat");
+  declareProperty("doMisAlign", m_misalign = false);
+  declareProperty("NTracks", m_nTracks = 100); // Per event. Homogenous in t.
+  
+  declareProperty("RunDuration", m_EventLength = 10000); // Max clock time per event.
+  declareProperty("NNoiseClusters", m_nNoiseClusters = 20); // Per event, per plane. Homogenous in t.
+
+
+  declareProperty("HitTimeJitter", m_HitTimeJitter = 10); // Time jitter width (clocks).
+  declareProperty("ClusterPosnError", m_ClustPosnResolution = 0.01);
+
+  declareProperty("ChargeSharingWidth", m_ChargeSharingWidth = 0.01);
+  declareProperty("ThresholdCut", m_ThresholdCut = 50.0);
+  declareProperty("ClusterCharge", m_charge = 300.0);
+  declareProperty("ForceEfficiency", m_ForceEfficiency = true);
+  // ...A measure of charge sharing - see below.
+
+  m_ChipWidth = 14.08;  // mm
+  m_PosnSpread = 4.0;   // mm
+
+  m_ChargeSigma = 150;
+  m_Pitch = 0.055;
+  m_nEvents = 0;
+  m_nExportedHits = 0;
+  m_nExportedTracks = 0;
+  m_ExportHits = true;
+  m_ExportClusters = false;
+  m_ExportTracks = false;
+}
+
+//=============================================================================
+/// Initialization
+//=============================================================================
+StatusCode TbTestMC::initialize() {
+
+  StatusCode sc = GaudiAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+  setHistoTopDir("Tb/");
+
+  if (m_misalign) {
+    geomSvc()->readConditions(m_filename, m_modules);
+    geomSvc()->printAlignment(m_modules);
+  }
+
+  else m_modules = geomSvc()->modules();
+  m_nPlanes = m_modules.size();
+
+  m_Hits.resize(m_nPlanes);
+
+  // Initialize the random number generators.
+  sc = m_uniform.initialize(randSvc(), Rndm::Flat(0.0, 1.0));
+  if (!sc) {
+    error() << "Cannot initialize uniform random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_gauss.initialize(randSvc(), Rndm::Gauss(0.0, 1.0));
+  if (!sc) {
+    error() << "Cannot initialize Gaussian random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_landau.initialize(randSvc(), Rndm::Landau(m_charge, m_ChargeSigma));
+  if (!sc) {
+    error() << "Cannot initialize Landau random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_gauss2.initialize(randSvc(), Rndm::Gauss(0.0, 1.0e-4));
+  if (!sc) {
+    error() << "Cannot initialize Gaussian random number generator." << endmsg;
+    return sc;
+  }
+  sc = m_uniform2.initialize(randSvc(), Rndm::Flat(0,m_ChipWidth ));
+  if (!sc) {
+    error() << "Cannot initialize uniform random number generator." << endmsg;
+    return sc;
+  }
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+/// Main execution
+//=============================================================================
+StatusCode TbTestMC::execute() {
+  if (m_nEvents % 10 == 0)
+    std::cout << "Event number: " << m_nEvents << std::endl;
+
+  generate_tracks();
+  createClustFromTrack();
+
+  //make_noise();
+  //make_tracks();
+
+  sort_stuff();
+  add_to_TES();
+
+  m_nEvents++;
+  for (unsigned int i = 0; i < m_nPlanes; ++i) {
+    m_nExportedHits += m_Hits[i].size();
+    // Prepare for next event.
+    m_Hits[i].clear();
+  }
+  m_Clusters.clear();
+  m_Tracks.clear();
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+// Finalize
+//=============================================================================
+StatusCode TbTestMC::finalize() {
+
+  info() << "------------------------------------------------------" << endmsg;
+  info() << "                      TbTestMC                      " << endmsg;
+  info() << "------------------------------------------------------" << endmsg;
+  info() << "Number of exported hits:\t"<<m_nExportedHits<<endmsg;
+  info() << "------------------------------------------------------" << endmsg;
+  // Finalise the base class.
+  return GaudiTupleAlg::finalize();
+
+}
+
+//=============================================================================
+/// Sorting
+//=============================================================================
+void TbTestMC::add_to_TES() {
+  // Hits.
+  if (m_ExportHits) ExportHits();
+
+  // Clusters.
+  if (m_ExportClusters) {
+    LHCb::TbClusters* clusters = new LHCb::TbClusters();
+    for (std::vector<LHCb::TbCluster*>::iterator ic = m_Clusters.begin();
+         ic != m_Clusters.end(); ic++)
+      clusters->insert(*ic);
+
+    put(clusters, LHCb::TbClusterLocation::Default);
+  }
+
+  // Tracks.
+  if (m_ExportTracks) {
+    LHCb::TbTracks* tracks = new LHCb::TbTracks();
+    for (std::vector<LHCb::TbTrack*>::iterator it = m_Tracks.begin();
+         it != m_Tracks.end(); it++)
+      tracks->insert(*it);
+
+    put(tracks, LHCb::TbTrackLocation::Default);
+  }
+}
+
+//=============================================================================
+/// Export hits to different TES locations.
+//=============================================================================
+void TbTestMC::ExportHits() {
+  std::vector<LHCb::TbHits*> all_hits;
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    LHCb::TbHits* hits = new LHCb::TbHits();
+    put(hits, LHCb::TbHitLocation::Default + std::to_string(i));
+    for (std::vector<LHCb::TbHit*>::iterator ih = m_Hits[i].begin();
+         ih != m_Hits[i].end(); ih++) {
+      hits->insert(*ih);
+    }
+  }
+}
+
+//=============================================================================
+/// Sorting - no sorting if not exporting.
+//=============================================================================
+void TbTestMC::sort_stuff() {
+  sort_by_chip();
+  if (m_ExportHits) {
+    for (unsigned int i = 0; i < m_nPlanes; ++i) {
+      hit_torder(i);
+    }
+  }
+  if (m_ExportClusters) cluster_torder();
+  if (m_ExportTracks) track_torder();
+}
+
+//=============================================================================
+/// Sorting by chip
+//=============================================================================
+void TbTestMC::sort_by_chip() {
+  std::vector<LHCb::TbCluster*> old_Clusters(m_Clusters);
+  m_Clusters.clear();
+  std::vector<TbModule*>::iterator m;
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    std::vector<LHCb::TbCluster*>::iterator ic;
+    for (ic = old_Clusters.begin(); ic != old_Clusters.end(); ++ic) {
+      if ((*ic)->plane() == (unsigned int)iplane) m_Clusters.push_back(*ic);
+    }
+  }
+
+}
+
+//=============================================================================
+/// Track time ordering - honeycomb
+//=============================================================================
+void TbTestMC::track_torder() {
+  int N = m_Tracks.size();
+  float s_factor = 1.3;
+  LHCb::TbTrack* track1, *track2;
+  int gap = N / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    for (int i = 0; gap + i < N; ++i) {
+      track1 = m_Tracks[i];
+      track2 = m_Tracks[i + gap];
+
+      if (track1->time() > track2->time()) {
+        // Do the swap.
+        m_Tracks[i] = track2;
+        m_Tracks[i + gap] = track1;
+
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Hit time ordering - honeycomb
+//=============================================================================
+void TbTestMC::hit_torder(const unsigned int plane) {
+  int N = m_Hits[plane].size();
+  float s_factor = 1.3;
+  LHCb::TbHit* hit1, *hit2;
+  int gap = N / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    for (int i = 0; gap + i < N; ++i) {
+      hit1 = m_Hits[plane][i];
+      hit2 = m_Hits[plane][i + gap];
+
+      if (hit1->time() > hit2->time()) {
+        // Do the swap.
+        m_Hits[plane][i] = hit2;
+        m_Hits[plane][i + gap] = hit1;
+
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Cluster time ordering - honeycomb
+//=============================================================================
+void TbTestMC::cluster_torder() {
+  int N = m_Clusters.size();
+  float s_factor = 1.3;
+  LHCb::TbCluster* clust1, *clust2;
+  int gap = N / s_factor;
+  bool swapped = false;
+
+  // Start the swap loops.
+  while (gap > 1 || swapped) {
+    if (gap > 1) gap /= s_factor;
+
+    swapped = false;  // Reset per swap loop.
+
+    // Do the swaps.
+    for (int i = 0; gap + i < N; ++i) {
+      clust1 = m_Clusters[i];
+      clust2 = m_Clusters[i + gap];
+
+      if (clust1->time() > clust2->time() &&
+          clust1->plane() == clust2->plane()) {
+
+        // Do the swap.
+        m_Clusters[i] = clust2;
+        m_Clusters[i + gap] = clust1;
+
+        swapped = true;
+      }
+    }
+  }
+}
+
+//=============================================================================
+/// Noise cluster posn
+//=============================================================================
+Gaudi::XYZPoint TbTestMC::ClustGposn(int iplane) {
+  float x, y;
+  bool on = true;
+  while (on) {
+    x = 0.5 * m_ChipWidth + m_gauss() * m_PosnSpread;
+    y = 0.5 * m_ChipWidth + m_gauss() * m_PosnSpread;
+
+    if (x > 0.028 + (2 * 0.055) && x < 14.05 - (2 * 0.055) &&
+        y > 0.028 + (2 * 0.055) && y < 14.05 - (2 * 0.055))
+      on = false;
+  }  // NO EDGES TAKEN INTO ACCOUNT YET.
+
+  Gaudi::XYZPoint posn(x, y, m_modules.at((unsigned int)iplane)->z());
+  return posn;
+}
+
+//=============================================================================
+/// Noise cluster charge
+//=============================================================================
+int TbTestMC::ClustCharge() {
+  float charge;
+  bool on = true;
+  while (on) {
+    charge = m_landau();
+    if (charge > 3.0 && charge < 1000) on = false;
+  }
+  return (int)charge;
+}
+
+//=============================================================================
+/// Tracks
+//=============================================================================
+void TbTestMC::make_tracks() {
+  for (int i = 0; i < m_nTracks; i++) {
+    // Make a track at a particular position. Clusters and hits saved auto.
+    int time = (int)(m_uniform() * m_EventLength);
+    LHCb::TbTrack* track = make_track(ClustGposn(0), time, i);
+    m_Tracks.push_back(track);
+
+    unsigned int nActualClusters = 0;
+    for (unsigned int i=0; i<track->clusters().size(); i++) {
+    	if (track->clusters()[i]->size() != 0) nActualClusters++;
+    }
+
+    if (nActualClusters == m_nPlanes || nActualClusters == m_nPlanes-1)
+    		m_nExportedTracks++;
+  }
+}
+
+//=============================================================================
+/// Track
+//=============================================================================
+LHCb::TbTrack* TbTestMC::make_track(Gaudi::XYZPoint p, float t, int itrack) {
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    Gaudi::XYZPoint ClustPosn(p.x(), p.y(), m_modules.at(iplane)->z());
+    LHCb::TbCluster* cluster = make_cluster(ClustPosn, t, iplane, itrack);
+    track->addToClusters(cluster);
+    m_Clusters.push_back(cluster);
+  }
+  m_trackFit->fit(track);
+  return track;
+}
+
+//=============================================================================
+/// Noise
+//=============================================================================
+void TbTestMC::make_noise() {
+  for (unsigned int iplane = 0; iplane < m_nPlanes; iplane++) {
+    for (int i = 0; i < m_nNoiseClusters; i++) {
+      // Make a cluster at a particular position. Hits saved auto.
+      int time = (int)(m_uniform() * m_EventLength);
+      LHCb::TbCluster* cluster = make_cluster(ClustGposn(iplane), time, iplane, -1);
+      m_Clusters.push_back(cluster);
+    }
+  }
+}
+
+//=============================================================================
+/// MC cluster maker.
+//=============================================================================
+LHCb::TbCluster* TbTestMC::make_cluster(Gaudi::XYZPoint pGlobal_perfect,
+                                        float t, int iplane, int track_tag) {
+  LHCb::TbCluster* clust = new LHCb::TbCluster();
+  clust->setTime(t);
+
+  double x = pGlobal_perfect.x();
+  double y = pGlobal_perfect.y();
+
+  
+  x += m_gauss() * m_ClustPosnResolution;
+  y += m_gauss() * m_ClustPosnResolution;
+
+  Gaudi::XYZPoint pGlobal_actual(x, y, pGlobal_perfect.z());
+
+  Gaudi::XYZPoint pLocal = geomSvc()->globalToLocal(pGlobal_actual, iplane);
+  clust->setXloc(pLocal.x());
+  clust->setYloc(pLocal.y());
+
+  //std::cout<<clust->xloc()<<"\t"<<pGlobal_actual.x()<<"\t"<<clust->yloc()<<"\t"<<pGlobal_actual.y()<<std::endl;
+
+  clust->setX(pGlobal_actual.x());
+  clust->setY(pGlobal_actual.y());
+  clust->setZ(pGlobal_actual.z());
+
+  clust->setPlane(iplane);
+  
+  setClusterHitsAndCharge(clust, track_tag); // Also sets Charge.
+
+  return clust;
+}
+
+//=============================================================================
+/// Cluster hits
+//=============================================================================
+void TbTestMC::setClusterHitsAndCharge(LHCb::TbCluster* clust, int /*track_tag*/) {
+  // This version will model the charge cloud as a gaussian that is ceneted
+  // at the cluster position, and whose height is set by the cluster charge
+  // (albeit abit sneakily). Width is set above. The charge of surrounding
+  // pixels is then taken to be the height of the gaussian at that pixels
+  // position (if passing the threshold - kind of zero suppression);
+  // like poor mans integration.
+  double SigSq = m_ChargeSharingWidth*m_ChargeSharingWidth;
+  int clustChargeish = ClustCharge();
+  double N = clustChargeish*0.4;
+  int SeedHitX = (int)(clust->xloc()/m_Pitch);
+  int SeedHitY = (int)(clust->yloc()/m_Pitch);
+
+
+  int ClustCharge = 0;
+  int HalfAreaSide = 1; // 3x3
+  // Search over area around the seed.
+  //std::cout<<"New cluster at:\t"<<clust->xloc()<<"\t"<<clust->yloc()<<std::endl;
+  for (int ix=SeedHitX-HalfAreaSide; ix!=SeedHitX+HalfAreaSide+1; ix++){
+	for (int iy=SeedHitY-HalfAreaSide; iy!=SeedHitY+HalfAreaSide+1; iy++){
+	  // Find distance to the pixel from the center of the gaussian.
+	  double delx = (double(ix)+0.5)*m_Pitch - clust->xloc();
+      double dely = (double(iy)+0.5)*m_Pitch - clust->yloc();
+	  double delrSq = delx*delx + dely*dely;
+	  int pixToT = (int)N*exp(-delrSq/SigSq);
+
+
+	  if ((float)pixToT > m_ThresholdCut) {
+	    LHCb::TbHit * hit = new LHCb::TbHit();
+            hit->setDevice(clust->plane());
+		hit->setCol(ix);
+		hit->setRow(iy);
+		hit->setToT(pixToT);
+		hit->setTime(clust->time() + m_gauss() * m_HitTimeJitter);
+		clust->addToHits(hit);
+		m_Hits[clust->plane()].push_back(hit);
+
+		// hit->setTrackTag(track_tag);
+		ClustCharge += pixToT;
+	  }
+	}
+  }
+
+  if (clust->size()==0 && m_ForceEfficiency){ // i.e. none of the hits passed the thresehold
+	LHCb::TbHit * hit = new LHCb::TbHit();
+	hit->setCol(SeedHitX);
+	hit->setRow(SeedHitY);
+	hit->setToT(clustChargeish);
+	hit->setTime(clust->time() + m_gauss() * m_HitTimeJitter);
+
+	// hit->setTrackTag(track_tag);
+
+	clust->addToHits(hit);
+	m_Hits[clust->plane()].push_back(hit);
+	ClustCharge += clustChargeish;
+  }
+  clust->setCharge(ClustCharge);
+}
+
+//=============================================================================
+// Randomly generates tracks (C.Hombach)
+//=============================================================================
+
+void TbTestMC::generate_tracks() 
+{
+  double slope_xz;
+  double slope_yz;
+  double inter_x;
+  double inter_y;
+  
+for (int i = 0; i < m_nTracks; i++) {  
+  //Generate slopes and intercepts equally distributed over the sensor
+  slope_xz = m_gauss2();
+  slope_yz = m_gauss2();
+  inter_x  = m_uniform2();
+  inter_y  = m_uniform2();
+  plot(slope_xz, "slopeXZ", "slopeXZ", -1.e-3,1.e-3,1000);
+  plot(slope_yz, "slopeYZ", "slopeYZ", -1.e-3,1.e-3,1000);
+  //Create track
+  LHCb::TbState state;// = new LHCb::TbState();
+  state.setTx(slope_xz);
+  state.setTy(slope_yz);
+  state.setX(inter_x);
+  state.setY(inter_y);
+  
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+  track->setFirstState(state);
+  m_Tracks.push_back(track);
+  
+ }
+}
+
+//=============================================================================
+//Calculates cluster from track intercepts with module planes
+//=============================================================================
+
+void TbTestMC::createClustFromTrack()
+{
+  std::vector<LHCb::TbTrack*>::iterator it = m_Tracks.begin();
+  for( ; it != m_Tracks.end(); ++it)
+  {
+    int time = (int)(m_uniform() * m_EventLength);
+    std::vector<TbModule*>::iterator im = m_modules.begin();
+    for( ; im != m_modules.end(); ++im)
+    {
+      
+      Gaudi::XYZPoint ip = getIntercept(im - m_modules.begin(), (*it));
+      Gaudi::XYZPoint pLocal = geomSvc()->globalToLocal(ip, im - m_modules.begin());
+            
+      LHCb::TbCluster* clust = new LHCb::TbCluster();
+      clust->setTime(time);
+      clust->setXloc(pLocal.x());
+      clust->setYloc(pLocal.y());      
+      clust->setX(ip.x());
+      clust->setY(ip.y());
+      clust->setZ(ip.z());
+      clust->setCharge(ClustCharge());
+      clust->setPlane(im - m_modules.begin());
+      
+      setClusterHitsAndCharge(clust,-1);
+      m_Clusters.push_back(clust);
+    }
+    
+  }
+  
+  
+}
+
+//============================================================================
+// Calculates Intercept of track and a module (Needs to be moved somewhere else)
+//============================================================================
+
+Gaudi::XYZPoint TbTestMC::getIntercept(const unsigned int& plane, LHCb::TbTrack* track)
+{
+  Gaudi::XYZPoint p1Local(0., 0., 0.), p2Local(0., 0., 1.);
+  Gaudi::XYZPoint p1Global =
+    geomSvc()->localToGlobal(p1Local, plane);
+  Gaudi::XYZPoint p2Global =
+    geomSvc()->localToGlobal(p2Local, plane);
+  Gaudi::XYZPoint normal(p2Global.x() - p1Global.x(),
+                         p2Global.y() - p1Global.y(),
+                         p2Global.z() - p1Global.z());
+  //  std::cout << track->firstState().tx() << std::endl;
+  const double dir_r =
+    sqrt(track->firstState().tx() * track->firstState().tx() +
+         track->firstState().ty() * track->firstState().ty() + 1.);
+  const double dir_x = track->firstState().tx() / dir_r;
+  const double dir_y = track->firstState().ty() / dir_r;
+  const double dir_z = 1. / dir_r;
+  const double length =
+    ((p1Global.x() - track->firstState().x()) * normal.x() +
+     (p1Global.y() - track->firstState().y()) * normal.y() +
+     (p1Global.z() - 0.) * normal.z()) /
+    (dir_x * normal.x() + dir_y * normal.y() + dir_z * normal.z());
+  const double x_inter = track->firstState().x() + dir_x * length;
+  const double y_inter = track->firstState().y() + dir_y * length;
+  const double z_inter = 0. + dir_z * length;
+  Gaudi::XYZPoint intersect_global(x_inter, y_inter, z_inter);
+  
+  return intersect_global;
+  
+}
+
+
+//=============================================================================
+/// End
+//=============================================================================
diff --git a/TbSimulation/src/TbTestMC.h b/TbSimulation/src/TbTestMC.h
new file mode 100644
index 0000000..6f87a42
--- /dev/null
+++ b/TbSimulation/src/TbTestMC.h
@@ -0,0 +1,99 @@
+#ifndef TB_TESTMC_H
+#define TB_TESTMC_H 1
+
+#include "TH1.h"
+#include "TH2.h"
+
+#include "GaudiAlg/GaudiTupleAlg.h"
+#include "GaudiKernel/RndmGenerators.h"
+
+#include "TbKernel/ITbTrackFit.h"
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/TbModule.h"
+#include "Event/TbHit.h"
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+
+/** @class TbTestMC TbTestMC.h
+ *  Author: Dan Saunders
+ */
+
+class TbTestMC : public GaudiTupleAlg {
+ public:
+  TbTestMC(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TbTestMC() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+  virtual StatusCode finalize();    ///< Algorithm finalization
+  int m_nEvents;
+  void generate_tracks();
+  void createClustFromTrack();
+  void add_to_TES();
+  void ExportHits();
+  void sort_stuff();
+  void sort_by_chip();
+  void track_torder();
+  void cluster_torder();
+  void hit_torder(const unsigned int plane);
+  Gaudi::XYZPoint ClustGposn(int);
+  int ClustCharge();
+  void make_tracks();
+  LHCb::TbTrack* make_track(Gaudi::XYZPoint, float, int);
+  void make_noise();
+  LHCb::TbCluster* make_cluster(Gaudi::XYZPoint, float, int, int);
+  int ClustSize();
+  void setClusterHitsAndCharge(LHCb::TbCluster*, int);
+  Gaudi::XYZPoint getIntercept(const unsigned int& plane, LHCb::TbTrack*);
+  
+
+  int m_nTracks;
+  int m_EventLength;
+  int m_nNoiseClusters;
+  int m_HitTimeJitter;
+  float m_ClustPosnResolution;
+  unsigned int m_nPlanes;
+  float m_ChipWidth;
+  float m_PosnSpread;
+  float m_charge;
+  bool m_ForceEfficiency;
+  float m_ChargeSigma;
+  float m_Pitch;
+  double m_ChargeSharingWidth;
+  float m_ThresholdCut;
+  unsigned int m_nExportedTracks;
+  bool m_ExportHits;
+  bool m_ExportClusters;
+  bool m_ExportTracks;
+
+  int m_nExportedHits;
+
+  std::string m_filename;
+  bool m_misalign;
+  
+  std::vector<TbModule*> m_modules;
+
+  std::vector<float> m_ClustSizeFracs;
+
+  std::vector<std::vector<LHCb::TbHit*> > m_Hits;          // Per event.
+  std::vector<LHCb::TbCluster*> m_Clusters;  // Per event.
+  std::vector<LHCb::TbTrack*> m_Tracks;      // Per event.
+
+
+  // Geometry service.
+  mutable ITbGeometrySvc* m_geomSvc;
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+  ITbTrackFit* m_trackFit;
+
+
+  // Random number genorators.
+  Rndm::Numbers m_uniform;
+  Rndm::Numbers m_gauss;
+  Rndm::Numbers m_landau;
+  Rndm::Numbers m_gauss2;
+  Rndm::Numbers m_uniform2;
+};
+#endif
diff --git a/TbSimulation/src/TbTrackFitter.cpp b/TbSimulation/src/TbTrackFitter.cpp
new file mode 100755
index 0000000..b284bbb
--- /dev/null
+++ b/TbSimulation/src/TbTrackFitter.cpp
@@ -0,0 +1,511 @@
+// ROOT
+#include "TMath.h"
+
+// Gaudi
+#include "GaudiKernel/PhysicalConstants.h"
+#include "GaudiUtils/Aida2ROOT.h"
+
+// Tb
+#include "TbKernel/ITbGeometrySvc.h"
+#include "Event/TbCluster.h"
+#include "Event/TbTrack.h"
+#include "Event/TbState.h"
+
+#include "Event/TbKalmanTrack.h"
+#include "Event/TbKalmanNode.h"
+#include "Event/TbKalmanPixelMeasurement.h"
+
+#include <math.h>
+
+// Local
+#include "TbTrackFitter.h"
+
+/** @file TbTrackFitter.cpp
+ *
+ *  Implementation of class : TbTrackFitter
+ *	Author: Panagiotis Tsopelas
+ */
+
+DECLARE_ALGORITHM_FACTORY(TbTrackFitter)
+
+//=============================================================================
+/// Standard constructor
+//=============================================================================
+TbTrackFitter::TbTrackFitter(const std::string& name, ISvcLocator* pSvcLocator)
+    : GaudiTupleAlg(name, pSvcLocator), m_trackFit(NULL) {
+
+  // Global default values.
+  declareProperty("onOff_hists", m_onOff_hists = true);
+  declareProperty("scat2", m_scat2 = 1.35e-8);
+  declareProperty("hiterror2", m_hiterror2 = 1.6e-5);
+  declareProperty("theta0", m_theta0 = 1.e-4);
+  declareProperty("direction", m_direction = -1);
+  // Local default values.
+  m_nPlanes = 8;
+  sigmax = 0.004 * Gaudi::Units::mm;
+  sigmay = 0.004 * Gaudi::Units::mm;
+}
+
+//=============================================================================
+/// Initialization
+//=============================================================================
+StatusCode TbTrackFitter::initialize() {
+
+  StatusCode sc = GaudiAlgorithm::initialize();
+  if (sc.isFailure()) return sc;
+  setHistoTopDir("Tb/");
+  if (m_onOff_hists) setup_hists();
+
+  // Setup the track fit tool.
+  m_trackFit = tool<ITbTrackFit>("TbTrackFit", "Fitter", this);
+
+  // Initialize the random number generator.
+  sc = m_gauss.initialize(randSvc(), Rndm::Gauss(0.0, 1.0));
+  if (!sc) {
+    error() << "Cannot initialize Gaussian random number generator." << endmsg;
+    return sc;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+/// Main execution
+//=============================================================================
+StatusCode TbTrackFitter::execute() {
+  if (msgLevel(MSG::DEBUG)) debug() << " ==> execute()" << endmsg;
+
+  // TbTrack container
+  std::vector<LHCb::TbTrack*> tracks_vec;
+  // TbKalmanTrack container
+  std::vector<LHCb::TbKalmanTrack*> ktracks_vec;
+  
+  const unsigned int nPlanes = m_nPlanes;
+//  const double sigmax = 0.004 * Gaudi::Units::mm;
+//  const double sigmay = 0.004 * Gaudi::Units::mm;
+
+  // Gap from next/previous event
+//  std::cout << std::endl << std::endl << std::endl ;
+
+  // make random track parameters -> True straight track - NO scattering
+  double Rx0 = m_gauss() * 15. * Gaudi::Units::mm ;
+  double Rtx = m_gauss() * 1.e-4 ;
+  double Ry0 = m_gauss() * 15. * Gaudi::Units::mm ;
+  double Rty = m_gauss() * 1.e-4 ;
+  // print random initial track parameters
+//  std::cout << "--> Random track with x0 = " << Rx0 << " and tx = " << Rtx << std::endl;
+ 
+  // theta0 for MCS through small angles
+  double theta0 = TMath::ATan(m_theta0) ;
+  // store true slope and intercept from scattering
+  std::vector<double> scatRtx(nPlanes);
+  std::vector<double> scatRty(nPlanes);
+  
+  // Declare TbTrack
+  LHCb::TbTrack* track = new LHCb::TbTrack();
+
+  // make random clusters ..
+  std::vector<LHCb::TbCluster> clusters(nPlanes);
+  
+  // .. but fix their Z positions according to the Alignment File
+  clusters[0].setZ( 0. );           clusters[4].setZ( 306. );
+  clusters[1].setZ( 31. );          clusters[5].setZ( 336. );
+  clusters[2].setZ( 60. );          clusters[6].setZ( 366. );
+  clusters[3].setZ( 89. );          clusters[7].setZ( 397. );
+  
+  const double weight = 1. / (0.004 * 0.004); 
+  // initialize 1st cluster
+  clusters[0].setX( ( Rtx + Rx0 ) + m_gauss()*sigmax ); // random straight line
+  clusters[0].setY( ( Rty + Ry0 ) + m_gauss()*sigmay ); // random straight line
+  clusters[0].setXErr( 0.004 );
+  clusters[0].setYErr( 0.004 );
+  clusters[0].setWx(weight);
+  clusters[0].setWy(weight);
+  clusters[0].setPlane(0);
+  track->addToClusters(&clusters[0]);
+  
+//  std::cout << " Clusters in X: " ;
+//  std::cout << clusters[0].x() << ", " ;
+  // update x0 and tx due to scattering
+  scatRx0[0] = Rx0 ;
+  scatRtx[0] = Rtx + m_gauss()*theta0;
+  scatRy0[0] = Ry0;
+  scatRty[0] = Rty + m_gauss()*theta0;
+  
+  // fill the rest of the clusters
+  for (unsigned int i = 1; i < nPlanes; ++i) {
+  
+    // update x0 and tx due to scattering
+    scatRx0[i] = ( clusters[i].z() - clusters[i-1].z() ) * scatRtx[i-1] + scatRx0[i-1] ;
+    scatRtx[i] = scatRtx[i-1] + m_gauss() * theta0;
+    scatRy0[i] = ( clusters[i].z() - clusters[i-1].z() ) * scatRty[i-1] + scatRy0[i-1];
+    scatRty[i] = scatRty[i-1] + m_gauss() * theta0;
+  
+    clusters[i].setX( scatRx0[i] + m_gauss()*sigmax );
+    clusters[i].setY( scatRy0[i] + m_gauss()*sigmay );
+    clusters[i].setXErr( 0.004 );
+    clusters[i].setYErr( 0.004 );
+    clusters[i].setWx(weight);
+    clusters[i].setWy(weight);
+    clusters[i].setPlane(i);
+    track->addToClusters(&clusters[i]);
+    if (i==nPlanes) continue;
+    
+  }
+  
+  // const SmartRefVector<LHCb::TbCluster>& clustersL = track->clusters();
+//  std::cout << std::endl << "Track with " << track->size() << " clusters. " << std::endl;
+//  // print true positions of track
+//  std::cout << " True X positions of (scattered) track: ";
+//    std::cout << Rx0 << ",   " ;
+//  for (int i=0; i<nPlanes; i++){
+//    std::cout << scatRx0[i] << ",   " ;
+//  }
+//  std::cout << std::endl;
+//  std::cout << " Cluster X positions                  :             ";
+//  for (auto it = clustersL.cbegin(), end = clustersL.cend(); it != end; ++it) {
+//    std::cout << (*it)->x() << ", ";
+//  }
+//  std::cout << " Cluster X errors                  :             ";
+//  for (auto it = clustersL.cbegin(), end = clustersL.cend(); it != end; ++it) {
+//    std::cout << (*it)->xErr() << ", ";
+//  }
+////  for (int i=0; i<nPlanes; i++){
+////    std::cout << clusters[i].x() << ",   " ;
+////  }
+//
+//  std::cout << std::endl;
+//  std::cout << " Cluster Z positions                  :             ";
+//  for (auto it = clustersL.cbegin(), end = clustersL.cend(); it != end; ++it) {
+//    std::cout << (*it)->z() << ", ";
+//  }
+////  for (int i=0; i<nPlanes; i++){
+////    std::cout << clusters[i].z() << ",   " ;
+////  }
+//  std::cout << std::endl;
+  
+  
+  // fit the track
+  m_trackFit->fit(track);
+
+
+
+  // print results of simple fit
+//  std::cout << std::endl << " * chi2 on x-z plane: " << track->chi2() << " with ndof = " << track->ndof() << std::endl
+//			 << " x0: " << track->firstState().x() << " +/- " << TMath::Sqrt(track->firstState().errX2() )
+//			 << ", y0: " << track->firstState().y() << " +/- " << TMath::Sqrt(track->firstState().errY2() )
+//			 << std::endl 
+//			 << " tx: " << track->firstState().tx() << " +/- " << TMath::Sqrt( track->firstState().errTx2() )
+//			 << ", ty: " << track->firstState().ty() << " +/- " << TMath::Sqrt( track->firstState().errTy2() )
+//			 << std::endl ;
+
+
+
+
+
+  //---------------------------------------------------------------------------
+  // Wouter's new code
+  //---------------------------------------------------------------------------
+  
+  // node : combination of a measurement and a track state is referred to as a node
+  // std::cout << std::endl << " ==================================================   " << std::endl;
+  
+  // create a fit track object (which is actually also a TbTrack)
+  LHCb::TbKalmanTrack* ktrack = new LHCb::TbKalmanTrack(*track,  m_hiterror2, m_scat2) ;
+  // fit it
+  ktrack->fit() ;
+  
+  // dump some info about the fit
+//  ktrack->print() ;
+   // std::cout << " ==================================================   " << std::endl;
+  //---------------------------------------------------------------------------
+
+
+  // store the track in the track vector
+  tracks_vec.push_back(track);
+  // store the ktrack in the track vector
+  ktracks_vec.push_back(ktrack);
+
+  // Check whether to fill histograms
+  if (m_onOff_hists) {
+   fill_hists(tracks_vec);
+   fill_khists(ktracks_vec);
+  }
+
+  // delete the pointer to the track
+  delete track;
+
+  return StatusCode::SUCCESS;
+}
+
+//=============================================================================
+///               F  U  N  C  T  I  O  N  S
+//=============================================================================
+
+//=============================================================================
+/// Fill Histograms for TbTracks
+//=============================================================================
+void TbTrackFitter::fill_hists(std::vector<LHCb::TbTrack*>& tracks) {
+
+  std::vector<LHCb::TbTrack*>::iterator ictra;
+  for (ictra = tracks.begin(); ictra != tracks.end(); ictra++) {
+
+    // if ( TMath::Prob((*ictra)->chi2() , (*ictra)->ndof()) < 0.05) continue;
+
+    // Fill the track histos
+    m_slopesX->Fill((*ictra)->firstState().tx());
+    m_slopesY->Fill((*ictra)->firstState().ty());
+    m_Sfit_chi2->Fill((*ictra)->chi2PerNdof());
+    m_Sfit_prob->Fill( TMath::Prob((*ictra)->chi2() , (*ictra)->ndof()) );
+
+    // Get the clusters of this TbTrack
+    const SmartRefVector<LHCb::TbCluster> clusters = (*ictra)->clusters();
+
+    // Loop through the clusters of this TbTrack
+    SmartRefVector<LHCb::TbCluster>::const_iterator icclu;
+    for (icclu = clusters.begin(); icclu != clusters.end(); ++icclu) {
+      int ichip = (*icclu)->plane();
+
+      m_clustersX->Fill((*icclu)->x());
+      m_clustersY->Fill((*icclu)->y());
+
+      double xTraAtZclu = (*ictra)->firstState().x() +
+                          (*ictra)->firstState().tx() * (double)(*icclu)->z();
+      double yTraAtZclu = (*ictra)->firstState().y() +
+                          (*ictra)->firstState().ty() * (double)(*icclu)->z();
+
+      double resx = (*icclu)->x() - xTraAtZclu ;
+      double resy = (*icclu)->y() - yTraAtZclu ;
+      
+      // Fill residuals
+      m_resSfit_X[ichip]->Fill( resx );
+      m_resSfit_Y[ichip]->Fill( resy );
+      
+      // Fill residual pulls
+      m_respullSfit_X[ichip]->Fill((double) resx / sigmax);
+      m_respullSfit_Y[ichip]->Fill((double) resy / sigmay);
+      
+      // Fill differences from true track
+      m_trueSfit_X[ichip]->Fill( scatRx0[ichip] - xTraAtZclu );
+      m_trueSfit_Y[ichip]->Fill( scatRy0[ichip] - yTraAtZclu );
+      
+      // Fill true pulls
+      m_trackpullSfit_X[ichip]->Fill( (scatRx0[ichip] - xTraAtZclu) / std::sqrt((*ictra)->firstState().covariance()(0,0)) );
+      m_trackpullSfit_Y[ichip]->Fill( (scatRy0[ichip] - yTraAtZclu) / std::sqrt((*ictra)->firstState().covariance()(1,1)) );
+//      m_trackpullSfit_X[ichip]->Fill( (scatRx0[ichip] - xTraAtZclu) / sigmax );
+//      m_trackpullSfit_Y[ichip]->Fill( (scatRy0[ichip] - yTraAtZclu) / sigmay );
+      
+
+
+    }  // end of cluster loop
+
+  }  // end of track loop
+}
+
+//=============================================================================
+/// Fill Histograms for TbKalmanTracks
+//=============================================================================
+void TbTrackFitter::fill_khists(std::vector<LHCb::TbKalmanTrack*>& ktracks) {
+  
+  std::vector<LHCb::TbKalmanTrack*>::iterator icktra;
+  for (icktra = ktracks.begin(); icktra != ktracks.end(); icktra++) {
+    
+    // Fill the track histos
+    m_Kfit_chi2->Fill((*icktra)->chi2());
+    m_Kfit_prob->Fill( TMath::Prob((*icktra)->chi2(), (*icktra)->ndof()) );
+    
+//    node->residualX() / std::sqrt(pixelhit->residualCovX()
+    
+    // Get the nodes of this TbKalmanTrack
+    //const std::vector<LHCb::TbKalmanNode*>& knodes = (*icktra)->nodes();
+    
+    // Loop through the nodes of this TbKalmanTrack
+    for( auto node : (*icktra)->nodes() ) {
+      auto pixnode = dynamic_cast< LHCb::TbKalmanPixelMeasurement*>( node) ;
+      if( pixnode ) {
+        int ichip = pixnode->cluster().plane();
+        
+        // Fill unbiased residuals
+        m_XunresKfit[ichip]->Fill( pixnode->residualX() * pixnode->covX() / pixnode->residualCovX() );
+        m_YunresKfit[ichip]->Fill( pixnode->residualY() * pixnode->covY() / pixnode->residualCovY() );
+        
+        // Fill residuals
+        m_resKfit_X[ichip]->Fill( pixnode->residualX() );
+        m_resKfit_Y[ichip]->Fill( pixnode->residualY() );
+        
+        // Fill residual errors
+        m_reserrKfit_X[ichip]->Fill( std::sqrt(pixnode->residualCovX()) );
+        m_reserrKfit_Y[ichip]->Fill( std::sqrt(pixnode->residualCovY()) );
+        
+        // Fill residual pulls
+        m_respullKfit_X[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) );
+        m_respullKfit_Y[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) );
+        
+        // Fill differences from true tracks
+        m_trueKfit_X[ichip]->Fill( scatRx0[ichip] - pixnode->state().x() );
+        m_trueKfit_Y[ichip]->Fill( scatRy0[ichip] - pixnode->state().y() );
+        
+        // Fill differences errors from true tracks
+        m_trueerrKfit_X[ichip]->Fill( TMath::Sqrt(pixnode->state().covariance()(0,0)) );
+        m_trueerrKfit_Y[ichip]->Fill( TMath::Sqrt(pixnode->state().covariance()(1,1)) );
+        
+        // Fill true pulls
+        m_trackpullKfit_X[ichip]->Fill( (scatRx0[ichip] - pixnode->state().x() ) / TMath::Sqrt(pixnode->state().covariance()(0,0)) );
+        m_trackpullKfit_Y[ichip]->Fill( (scatRy0[ichip] - pixnode->state().y() ) / TMath::Sqrt(pixnode->state().covariance()(1,1)) );
+        
+      }
+    }
+  }  // end of Ktrack loop
+}
+
+
+//=============================================================================
+/// Setup Histograms
+//=============================================================================
+void TbTrackFitter::setup_hists() {
+
+  // TbTrack parameters plots
+  m_Sfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/chi2perndof", "Chi2/ndof", -0.5, 49.5, 100));
+  
+  m_Sfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/probability", "Chi2 prob of S fit", 0.0, 1.0, 100));
+
+  m_slopesX = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/slopesX", "slopes in X of TbTracks", -1.e-3, 1.e-3, 100));
+  
+  m_slopesY = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("StraightLineFit/slopesY", "slopes in Y of TbTracks", -1.e-3, 1.e-3, 100));
+
+  m_Kfit_chi2 = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("KalmanFit/chi2", "Chi2", -0.5, 49.5, 100));
+  
+  m_Kfit_prob = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("KalmanFit/probability", "Chi2 prob of K fit", 0.0, 1.0, 100));
+  
+  m_clustersX = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("clustersX", "cluster X positions ", -1.e-2, 1.e-2, 100));
+
+  m_clustersY = Gaudi::Utils::Aida2ROOT::aida2root(
+      book1D("clustersY", "cluster Y positions ", -1.e-2, 1.e-2, 100));
+
+  
+
+  // Residual plots
+  std::string hist_name;
+  for (unsigned int i = 0; i < m_nPlanes; i++) {
+    std::stringstream ss_chip;
+    ss_chip << i;
+
+    // straight line fit 
+    hist_name = "StraightLineFit/Residuals_on_X/plane_" + ss_chip.str();
+    m_resSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+
+    hist_name = "StraightLineFit/Residuals_on_Y/plane_" + ss_chip.str();
+    m_resSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+
+
+    hist_name = "StraightLineFit/ResidualPull_on_X/plane_" + ss_chip.str();
+    m_respullSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    hist_name = "StraightLineFit/ResidualPull_on_Y/plane_" + ss_chip.str();
+    m_respullSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+
+
+    hist_name = "StraightLineFit/Differences_from_true_on_X/plane_" + ss_chip.str();
+    m_trueSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    hist_name = "StraightLineFit/Differences_from_true_on_Y/plane_" + ss_chip.str();
+    m_trueSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+
+
+    hist_name = "StraightLineFit/TrackPull_on_X/plane_" + ss_chip.str();
+    m_trackpullSfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+
+    hist_name = "StraightLineFit/TrackPull_on_Y/plane_" + ss_chip.str();
+    m_trackpullSfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+
+    
+    // Kalman fit
+    hist_name = "KalmanFit/UnbiasedResidualsX/plane_" + ss_chip.str();
+    m_XunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    
+    hist_name = "KalmanFit/UnbiasedResidualsY/plane_" + ss_chip.str();
+    m_YunresKfit.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    //
+    
+    hist_name = "KalmanFit/Residuals_on_X/plane_" + ss_chip.str();
+    m_resKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    
+    hist_name = "KalmanFit/Residuals_on_Y/plane_" + ss_chip.str();
+    m_resKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    hist_name = "KalmanFit/Residual_errors_on_X/plane_" + ss_chip.str();
+    m_reserrKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/Residual_errors_on_Y/plane_" + ss_chip.str();
+    m_reserrKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_X/plane_" + ss_chip.str();
+    m_respullKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/ResidualPull_on_Y/plane_" + ss_chip.str();
+    m_respullKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+
+    hist_name = "KalmanFit/Differences_from_true_on_X/plane_" + ss_chip.str();
+    m_trueKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    
+    hist_name = "KalmanFit/Differences_from_true_on_Y/plane_" + ss_chip.str();
+    m_trueKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -1.e-2, 1.e-2, 100)));
+    
+    hist_name = "KalmanFit/Differences_errors_from_true_on_X/plane_" + ss_chip.str();
+    m_trueerrKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/Differences_errors_from_true_on_Y/plane_" + ss_chip.str();
+    m_trueerrKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), 0., 5.e-3, 1000)));
+    
+    
+    hist_name = "KalmanFit/TrackPull_on_X/plane_" + ss_chip.str();
+    m_trackpullKfit_X.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+    
+    
+    hist_name = "KalmanFit/TrackPull_on_Y/plane_" + ss_chip.str();
+    m_trackpullKfit_Y.push_back(Gaudi::Utils::Aida2ROOT::aida2root(
+        book1D(hist_name.c_str(), hist_name.c_str(), -10., 10., 100)));
+  }
+}
+
+//=============================================================================
+/// End
+//=============================================================================
diff --git a/TbSimulation/src/TbTrackFitter.h b/TbSimulation/src/TbTrackFitter.h
new file mode 100755
index 0000000..b18cf9f
--- /dev/null
+++ b/TbSimulation/src/TbTrackFitter.h
@@ -0,0 +1,116 @@
+#ifndef TB_TRACKFITTER_H
+#define TB_TRACKFITTER_H 1
+
+#include "TH1.h"
+#include "TH2.h"
+
+#include "GaudiAlg/GaudiTupleAlg.h"
+#include "GaudiKernel/RndmGenerators.h"
+
+#include "TbKernel/ITbGeometrySvc.h"
+#include "TbKernel/ITbTrackFit.h"
+
+
+/** @class TbTrackFitter TbTrackFitter.h
+ *  Author: Panagiotis Tsopelas
+ */
+
+class TbTrackFitter : public GaudiTupleAlg {
+ public:
+  TbTrackFitter(const std::string& name, ISvcLocator* pSvcLocator);
+  virtual ~TbTrackFitter() {}
+
+  virtual StatusCode initialize();  ///< Algorithm initialization
+  virtual StatusCode execute();     ///< Algorithm execution
+
+ private:
+  Rndm::Numbers m_gauss;
+
+  bool m_onOff_hists;
+  unsigned int m_nPlanes;
+
+  ITbTrackFit* m_trackFit;
+  
+  double            m_scat2;
+  double            m_hiterror2;
+  double            m_theta0;
+  int               m_direction;
+  
+  double sigmax;
+  double sigmay;
+  
+  double scatRx0[8];
+  double scatRy0[8];
+  
+  mutable ITbGeometrySvc* m_geomSvc;  /// Access geometry service on-demand
+  ITbGeometrySvc* geomSvc() const {
+    if (!m_geomSvc) m_geomSvc = svc<ITbGeometrySvc>("TbGeometrySvc", true);
+    return m_geomSvc;
+  }
+
+  // Histograms
+  
+  TH1D* m_clustersX;
+  TH1D* m_clustersY;
+  
+  // straight line fit
+  TH1D* m_Sfit_chi2;
+  TH1D* m_Sfit_prob;
+
+  TH1D* m_slopesX;
+  TH1D* m_slopesY;
+
+  std::vector<TH1D*> m_resSfit_X;
+  std::vector<TH1D*> m_resSfit_Y;
+  
+  std::vector<TH1D*> m_trueSfit_X;
+  std::vector<TH1D*> m_trueSfit_Y;
+  
+  std::vector<TH1D*> m_respullSfit_X;
+  std::vector<TH1D*> m_respullSfit_Y;
+  
+  std::vector<TH1D*> m_trackpullSfit_X;
+  std::vector<TH1D*> m_trackpullSfit_Y;
+
+
+  // Kalman filter
+  TH1D* m_Kfit_chi2;
+  TH1D* m_Kfit_prob;
+  
+  // unbiased residuals
+  std::vector<TH1D*> m_XunresKfit;
+  std::vector<TH1D*> m_YunresKfit;
+  
+  std::vector<TH1D*> m_resKfit_X;
+  std::vector<TH1D*> m_resKfit_Y;
+
+  std::vector<TH1D*> m_reserrKfit_X;
+  std::vector<TH1D*> m_reserrKfit_Y;
+
+  std::vector<TH1D*> m_respullKfit_X;
+  std::vector<TH1D*> m_respullKfit_Y;
+
+  std::vector<TH1D*> m_trueKfit_X;
+  std::vector<TH1D*> m_trueKfit_Y;
+
+  std::vector<TH1D*> m_trueerrKfit_X;
+  std::vector<TH1D*> m_trueerrKfit_Y;
+
+  std::vector<TH1D*> m_trackpullKfit_X;
+  std::vector<TH1D*> m_trackpullKfit_Y;
+
+  
+
+  // Histograms functions
+  void setup_hists();
+  void fill_hists(std::vector<LHCb::TbTrack*>&);
+  void fill_khists(std::vector<LHCb::TbKalmanTrack*>&);
+
+  // Modifiers and Accessors
+
+  void setNPlanes(unsigned int nplanes) { m_nPlanes = nplanes; }
+  int nPlanes() { return m_nPlanes; }
+
+  bool onOff_hists() { return m_onOff_hists; }
+};
+#endif
diff --git a/TbUT/.svn/all-wcprops b/TbUT/.svn/all-wcprops
new file mode 100644
index 0000000..148d5fe
--- /dev/null
+++ b/TbUT/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 48
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT
+END
+CMakeLists.txt
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/192041/Kepler/trunk/Tb/TbUT/CMakeLists.txt
+END
diff --git a/TbUT/.svn/entries b/TbUT/.svn/entries
new file mode 100644
index 0000000..89515a6
--- /dev/null
+++ b/TbUT/.svn/entries
@@ -0,0 +1,77 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+cmt
+dir
+
+doc
+dir
+
+scripts
+dir
+
+src
+dir
+
+options
+dir
+
+CMakeLists.txt
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+5b4d26cef26f2c9173133bce310d5a4f
+2015-07-19T05:55:29.257432Z
+192041
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+608
+
diff --git a/TbUT/.svn/text-base/CMakeLists.txt.svn-base b/TbUT/.svn/text-base/CMakeLists.txt.svn-base
new file mode 100644
index 0000000..659b565
--- /dev/null
+++ b/TbUT/.svn/text-base/CMakeLists.txt.svn-base
@@ -0,0 +1,18 @@
+################################################################################
+# Package: TbUT
+################################################################################
+gaudi_subdir(TbUT v1r1)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS Minuit MathCore GenVector)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbUT
+                 src/*.cpp 
+                 src/alibava/*.cpp
+                 src/mamba/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbUT/CMakeLists.txt b/TbUT/CMakeLists.txt
new file mode 100644
index 0000000..659b565
--- /dev/null
+++ b/TbUT/CMakeLists.txt
@@ -0,0 +1,18 @@
+################################################################################
+# Package: TbUT
+################################################################################
+gaudi_subdir(TbUT v1r1)
+
+gaudi_depends_on_subdirs(Tb/TbEvent
+                         Tb/TbKernel
+                         GaudiAlg)
+
+find_package(ROOT COMPONENTS Minuit MathCore GenVector)
+find_package(Boost COMPONENTS iostreams)
+
+gaudi_add_module(TbUT
+                 src/*.cpp 
+                 src/alibava/*.cpp
+                 src/mamba/*.cpp
+                 LINK_LIBRARIES TbEventLib TbKernelLib GaudiAlgLib Boost ROOT)
+
diff --git a/TbUT/cmt/.svn/all-wcprops b/TbUT/cmt/.svn/all-wcprops
new file mode 100644
index 0000000..5c5220d
--- /dev/null
+++ b/TbUT/cmt/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/cmt
+END
+requirements
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/cmt/requirements
+END
diff --git a/TbUT/cmt/.svn/entries b/TbUT/cmt/.svn/entries
new file mode 100644
index 0000000..ab9daa5
--- /dev/null
+++ b/TbUT/cmt/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/cmt
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+requirements
+file
+
+
+
+
+2016-03-16T13:50:20.000000Z
+756d96ee4b77d4fdff45510fa14b5ca8
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+899
+
diff --git a/TbUT/cmt/.svn/text-base/requirements.svn-base b/TbUT/cmt/.svn/text-base/requirements.svn-base
new file mode 100644
index 0000000..a2a7dd5
--- /dev/null
+++ b/TbUT/cmt/.svn/text-base/requirements.svn-base
@@ -0,0 +1,25 @@
+package TbUT 
+version v1r1
+
+branches          cmt doc src  
+include_path      none
+
+use  GaudiAlg     v*
+use  Boost        v*  LCG_Interfaces
+use TbEvent           v*    Tb
+use TbKernel           v*    Tb
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbUT    ../src/*.cpp -import=AIDA 
+library          TbUT    ../src/alibava/*.cpp -import=AIDA 
+library          TbUT    ../src/mamba/*.cpp -import=AIDA 
+
+apply_pattern    component_library library=TbUT
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append Boost_linkopts $(Boost_linkopts_serialization)
+macro_append Boost_linkopts $(Boost_linkopts_iostreams)
+macro_append ROOT_linkopts " -lHist -lMinuit -lMathCore"
+
diff --git a/TbUT/cmt/requirements b/TbUT/cmt/requirements
new file mode 100644
index 0000000..a2a7dd5
--- /dev/null
+++ b/TbUT/cmt/requirements
@@ -0,0 +1,25 @@
+package TbUT 
+version v1r1
+
+branches          cmt doc src  
+include_path      none
+
+use  GaudiAlg     v*
+use  Boost        v*  LCG_Interfaces
+use TbEvent           v*    Tb
+use TbKernel           v*    Tb
+
+#============================================================================
+# Component library building rule
+#============================================================================
+library          TbUT    ../src/*.cpp -import=AIDA 
+library          TbUT    ../src/alibava/*.cpp -import=AIDA 
+library          TbUT    ../src/mamba/*.cpp -import=AIDA 
+
+apply_pattern    component_library library=TbUT
+macro_append Boost_linkopts $(Boost_linkopts_system)
+macro_append Boost_linkopts $(Boost_linkopts_filesystem)
+macro_append Boost_linkopts $(Boost_linkopts_serialization)
+macro_append Boost_linkopts $(Boost_linkopts_iostreams)
+macro_append ROOT_linkopts " -lHist -lMinuit -lMathCore"
+
diff --git a/TbUT/doc/.svn/all-wcprops b/TbUT/doc/.svn/all-wcprops
new file mode 100644
index 0000000..a3871a7
--- /dev/null
+++ b/TbUT/doc/.svn/all-wcprops
@@ -0,0 +1,11 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/188498/Kepler/trunk/Tb/TbUT/doc
+END
+release.notes
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/188498/Kepler/trunk/Tb/TbUT/doc/release.notes
+END
diff --git a/TbUT/doc/.svn/entries b/TbUT/doc/.svn/entries
new file mode 100644
index 0000000..4657bf1
--- /dev/null
+++ b/TbUT/doc/.svn/entries
@@ -0,0 +1,62 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/doc
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-05-19T10:08:00.291234Z
+188498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+release.notes
+file
+
+
+
+
+2016-03-16T13:50:20.000000Z
+56de56aa86c32bc3328044bc3133723b
+2015-05-19T10:08:00.291234Z
+188498
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+607
+
diff --git a/TbUT/doc/.svn/text-base/release.notes.svn-base b/TbUT/doc/.svn/text-base/release.notes.svn-base
new file mode 100644
index 0000000..badde53
--- /dev/null
+++ b/TbUT/doc/.svn/text-base/release.notes.svn-base
@@ -0,0 +1,16 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbUT
+! Responsible : Adam Dendek, Jinlin Fu
+! Purpose     : Algorithms for UT testbeam analysis
+!-----------------------------------------------------------------------------
+
+!============================ TbUT v1r1 2015-05-19 ===========================
+
+! 2015-03-31 - Adam Dendek
+ - Many new classes.
+
+!============================ TbUT v1r0 2014-11-30 ===========================
+
+! 2014-11-17 - Heinrich Schindler
+ - Initial import (copy from Adam's git repository)
+ - Fix some trivial compiler warnings
diff --git a/TbUT/doc/release.notes b/TbUT/doc/release.notes
new file mode 100644
index 0000000..badde53
--- /dev/null
+++ b/TbUT/doc/release.notes
@@ -0,0 +1,16 @@
+!-----------------------------------------------------------------------------
+! Package     : Tb/TbUT
+! Responsible : Adam Dendek, Jinlin Fu
+! Purpose     : Algorithms for UT testbeam analysis
+!-----------------------------------------------------------------------------
+
+!============================ TbUT v1r1 2015-05-19 ===========================
+
+! 2015-03-31 - Adam Dendek
+ - Many new classes.
+
+!============================ TbUT v1r0 2014-11-30 ===========================
+
+! 2014-11-17 - Heinrich Schindler
+ - Initial import (copy from Adam's git repository)
+ - Fix some trivial compiler warnings
diff --git a/TbUT/options/.svn/all-wcprops b/TbUT/options/.svn/all-wcprops
new file mode 100644
index 0000000..99942ff
--- /dev/null
+++ b/TbUT/options/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/options
+END
+TbUTPedestal.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/196283/Kepler/trunk/Tb/TbUT/options/TbUTPedestal.py
+END
+TbUTRun.py
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/197306/Kepler/trunk/Tb/TbUT/options/TbUTRun.py
+END
diff --git a/TbUT/options/.svn/entries b/TbUT/options/.svn/entries
new file mode 100644
index 0000000..10d5a2b
--- /dev/null
+++ b/TbUT/options/.svn/entries
@@ -0,0 +1,102 @@
+10
+
+dir
+205728
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/options
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+python
+dir
+
+TbUTPedestal.py
+file
+
+
+
+
+2016-05-06T06:43:20.000000Z
+e48104e2beb371550c256ae91f09f55d
+2015-10-15T00:37:58.771367Z
+196283
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+534
+
+UT
+dir
+
+TbUTRun.py
+file
+
+
+
+
+2016-05-06T06:43:20.000000Z
+86c6f61235856e4ed5dde32e02a7a633
+2015-11-06T18:00:55.060165Z
+197306
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+412
+
diff --git a/TbUT/options/.svn/text-base/TbUTPedestal.py.svn-base b/TbUT/options/.svn/text-base/TbUTPedestal.py.svn-base
new file mode 100644
index 0000000..f46381a
--- /dev/null
+++ b/TbUT/options/.svn/text-base/TbUTPedestal.py.svn-base
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+import sys
+sys.path.append( "options/python" )
+
+from TbUTPedestalRunner import TbUTPedestalRunner
+app=TbUTPedestalRunner()
+# set parameter
+app.inputData= "/afs/cern.ch/user/a/adendek/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Pedestal-B6-A-209-0.dat"  
+app.isAType=True
+# have to be more than 4k (~10k)
+app.eventMax=20000
+#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!
+app.pedestalOutputData ="$KEPLERROOT/../TbUT/options/UT/Pedestal-BoardA6.dat"
+
+app.runPedestals()
+
diff --git a/TbUT/options/.svn/text-base/TbUTRun.py.svn-base b/TbUT/options/.svn/text-base/TbUTRun.py.svn-base
new file mode 100644
index 0000000..c44359b
--- /dev/null
+++ b/TbUT/options/.svn/text-base/TbUTRun.py.svn-base
@@ -0,0 +1,20 @@
+__author__ = 'ja'
+
+
+import sys
+sys.path.append("options/python")
+from TbUTClusterizator import TbUTClusterizator
+
+app = TbUTClusterizator()
+# set parameters
+app.inputData = "data/Run_Bias_Scan-B1-A-229-8713.dat"
+app.isAType = True
+app.sensorType = "PType"
+
+app.eventMax = 100000
+app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/ped-BoardA4Redo.dat"
+app.eventNumberDisplay = 100
+
+app.runClusterization()
+
+
diff --git a/TbUT/options/TbUTPedestal.py b/TbUT/options/TbUTPedestal.py
new file mode 100644
index 0000000..5c58d59
--- /dev/null
+++ b/TbUT/options/TbUTPedestal.py
@@ -0,0 +1,9 @@
+import sys
+sys.path.append( '../Tb/TbUT/options/python' )
+from TbUTPedestalRunner import TbUTPedestalRunner
+app=TbUTPedestalRunner()
+app.inputData="/afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/Tb/Kepler/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/Pedestal-M1-FanIn-51.dat"
+app.isAType=False
+app.eventMax=20000
+app.pedestalOutputData ='$KEPLERROOT/../../output/Pedestal-M1-FanIn-51.dat'
+app.runPedestals()
diff --git a/TbUT/options/TbUTPedestal.py~ b/TbUT/options/TbUTPedestal.py~
new file mode 100644
index 0000000..0f2d600
--- /dev/null
+++ b/TbUT/options/TbUTPedestal.py~
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+import sys
+sys.path.append( "options/python" )
+
+from TbUTPedestalRunner import TbUTPedestalRunner
+app=TbUTPedestalRunner()
+# set parameter
+app.inputData='/afs/cern.ch/user/c/cbetanco/public/Pedestal-M1-FanIn-5.dat'
+app.isAType=False
+# have to be more than 4k (~10k)
+app.eventMax=100000
+#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!
+app.pedestalOutputData ="$KEPLERROOT/../TbUT/options/UT/Pedestal-M1-FanIn-5.dat"
+
+app.runPedestals()
+
diff --git a/TbUT/options/TbUTPedestal_Ch.py b/TbUT/options/TbUTPedestal_Ch.py
new file mode 100644
index 0000000..ea01cad
--- /dev/null
+++ b/TbUT/options/TbUTPedestal_Ch.py
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+import sys
+sys.path.append( "options/python" )
+
+from TbUTPedestalRunner import TbUTPedestalRunner
+app=TbUTPedestalRunner()
+# set parameter
+app.inputData='/afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/Tb/Kepler/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/Pedestal-M1-FanIn-51.dat'
+app.isAType=False
+# have to be more than 4k (~10k)
+app.eventMax=100000
+#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!
+app.pedestalOutputData ="$KEPLERROOT/../TbUT/options/UT/Pedestal-M1-FanIn-51.dat"
+
+app.runPedestals()
+
diff --git a/TbUT/options/TbUTPedestal_conf.py b/TbUT/options/TbUTPedestal_conf.py
new file mode 100644
index 0000000..1409eae
--- /dev/null
+++ b/TbUT/options/TbUTPedestal_conf.py
@@ -0,0 +1,25 @@
+import sys, getopt, os
+if __name__=="__main__":
+	try:
+		opts,args = getopt.getopt(sys.argv[1:],"f:",["file"])
+	except getopt.GetoptError as err:
+		print str(err)
+		usage()
+		sys.exit(2)
+	for o, a in opts:
+		if o in ('-f','--file'):
+			fileName = str(a)
+			print fileName
+	if os.path.exists("options/TbUTPedestal.py"):os.system("rm options/TbUTPedestal.py")
+	fileP = open("options/TbUTPedestal.py","a")
+	fileP.write("import sys\n")
+        fileP.write("sys.path.append( '../Tb/TbUT/options/python' )\n")
+	fileP.write("from TbUTPedestalRunner import TbUTPedestalRunner\n")
+	fileP.write("app=TbUTPedestalRunner()\n")
+        fileP.write("app.inputData="+'"'+str(fileName)+'"'+"\n")
+	fileP.write("app.isAType=False\n")
+	fileP.write("app.eventMax=20000\n")
+	fileP.write("app.pedestalOutputData ='$KEPLERROOT/../../output/Pedestal-M1-FanIn-51.dat'\n")
+	fileP.write("app.runPedestals()\n")
+	fileP.close()
+
diff --git a/TbUT/options/TbUTRun.py b/TbUT/options/TbUTRun.py
new file mode 100644
index 0000000..810d3a5
--- /dev/null
+++ b/TbUT/options/TbUTRun.py
@@ -0,0 +1,11 @@
+import sys
+sys.path.append( '../Tb/TbUT/options/python' )
+from TbUTClusterizator import TbUTClusterizator
+app=TbUTClusterizator()
+app.inputData="/afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/Tb/Kepler/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/Run_Bias_Scan-M1-FanIn-50-15027.dat"
+app.isAType=False
+app.sensorType = 'NType'
+app.eventMax = 100000
+app.pedestalInputData = "$KEPLERROOT/../../output/Pedestal-M1-FanIn-51.dat"
+app.eventNumberDisplay = 100
+app.runClusterization()
diff --git a/TbUT/options/TbUTRun.py~ b/TbUT/options/TbUTRun.py~
new file mode 100644
index 0000000..24e5962
--- /dev/null
+++ b/TbUT/options/TbUTRun.py~
@@ -0,0 +1,20 @@
+__author__ = 'ja'
+
+
+import sys
+sys.path.append("options/python")
+from TbUTClusterizator import TbUTClusterizator
+
+app = TbUTClusterizator()
+# set parameters
+app.inputData = "/afs/cern.ch/user/c/cbetanco/public/Custom-M1-FanIn-4-15005.dat"
+app.isAType = False
+app.sensorType = "PType"
+
+app.eventMax = 100000
+app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/Pedestal-M1-FanIn-5.dat"
+app.eventNumberDisplay = 10
+
+app.runClusterization()
+
+
diff --git a/TbUT/options/TbUTRun_Ch.py b/TbUT/options/TbUTRun_Ch.py
new file mode 100644
index 0000000..d7e3be3
--- /dev/null
+++ b/TbUT/options/TbUTRun_Ch.py
@@ -0,0 +1,20 @@
+__author__ = 'ja'
+
+
+import sys
+sys.path.append("options/python")
+from TbUTClusterizator import TbUTClusterizator
+
+app = TbUTClusterizator()
+# set parameters
+app.inputData = "/afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/Tb/Kepler/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/Run_Bias_Scan-M1-FanIn-50-15027.dat"
+app.isAType = False
+app.sensorType = "NType"
+
+app.eventMax = 100000
+app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/Pedestal-M1-FanIn-51.dat"
+app.eventNumberDisplay = 10
+
+app.runClusterization()
+
+
diff --git a/TbUT/options/TbUTRun_conf.py b/TbUT/options/TbUTRun_conf.py
new file mode 100644
index 0000000..e0257a4
--- /dev/null
+++ b/TbUT/options/TbUTRun_conf.py
@@ -0,0 +1,28 @@
+import sys,getopt, os
+
+if __name__=="__main__":
+        try:
+                opts,args = getopt.getopt(sys.argv[1:],"f:",["file"])
+        except getopt.GetoptError as err:
+                print str(err)
+                usage()
+                sys.exit(2)
+        for o, a in opts:
+                if o in ('-f','--file'):
+                        fileName = str(a)
+                        print fileName
+        if os.path.exists("options/TbUTRun.py"):os.system("rm options/TbUTRun.py")
+        fileS = open("options/TbUTRun.py","a")
+        fileS.write("import sys\n")
+        fileS.write("sys.path.append( '../Tb/TbUT/options/python' )\n")
+	fileS.write("from TbUTClusterizator import TbUTClusterizator\n")
+	fileS.write("app=TbUTClusterizator()\n")
+	fileS.write("app.inputData="+'"'+str(fileName)+'"'+"\n")
+        fileS.write("app.isAType=False\n")
+        fileS.write("app.sensorType = 'NType'\n")
+	fileS.write("app.eventMax = 100000\n")
+	fileS.write('app.pedestalInputData = "$KEPLERROOT/../../output/Pedestal-M1-FanIn-51.dat"\n')
+	fileS.write('app.eventNumberDisplay = 100\n')
+	fileS.write('app.runClusterization()\n')
+        fileS.close()
+
diff --git a/TbUT/options/UT/.svn/all-wcprops b/TbUT/options/UT/.svn/all-wcprops
new file mode 100644
index 0000000..55d8255
--- /dev/null
+++ b/TbUT/options/UT/.svn/all-wcprops
@@ -0,0 +1,41 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/guest/lhcb/!svn/ver/196283/Kepler/trunk/Tb/TbUT/options/UT
+END
+MambaMasksSecond.dat
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/193730/Kepler/trunk/Tb/TbUT/options/UT/MambaMasksSecond.dat
+END
+noise_Mamba.dat
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/196283/Kepler/trunk/Tb/TbUT/options/UT/noise_Mamba.dat
+END
+MambaMasks.dat
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/194758/Kepler/trunk/Tb/TbUT/options/UT/MambaMasks.dat
+END
+Masks_DTypeSensor.dat
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/194560/Kepler/trunk/Tb/TbUT/options/UT/Masks_DTypeSensor.dat
+END
+ChannelMask_NO.dat
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/191831/Kepler/trunk/Tb/TbUT/options/UT/ChannelMask_NO.dat
+END
+ped_mamba.dat
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/options/UT/ped_mamba.dat
+END
diff --git a/TbUT/options/UT/.svn/entries b/TbUT/options/UT/.svn/entries
new file mode 100644
index 0000000..fc4cdd3
--- /dev/null
+++ b/TbUT/options/UT/.svn/entries
@@ -0,0 +1,232 @@
+10
+
+dir
+205728
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/options/UT
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-15T00:37:58.771367Z
+196283
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+MambaMasksSecond.dat
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+449a6978123b92c10c42ecf940fdd65c
+2015-08-14T17:20:42.072489Z
+193730
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1024
+
+noise_Mamba.dat
+file
+
+
+
+
+2016-05-06T06:43:20.000000Z
+6629373a1509abbd1874c523013acd51
+2015-10-15T00:37:58.771367Z
+196283
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4869
+
+MambaMasks.dat
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+53ed5732b232e39b0ed1c491e1f7c476
+2015-09-09T16:04:25.162348Z
+194758
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1024
+
+Masks_DTypeSensor.dat
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+e2893f41c614ee3180c78f490f30e623
+2015-09-01T19:30:54.038917Z
+194560
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1024
+
+ChannelMask_NO.dat
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+f0c836ade0a8d5c835057615fe32199e
+2015-07-14T15:46:54.883477Z
+191831
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+256
+
+ped_mamba.dat
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+d3c3769434870060dce2a00cb972bc19
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5066
+
diff --git a/TbUT/options/UT/.svn/text-base/ChannelMask_NO.dat.svn-base b/TbUT/options/UT/.svn/text-base/ChannelMask_NO.dat.svn-base
new file mode 100644
index 0000000..9e77e64
--- /dev/null
+++ b/TbUT/options/UT/.svn/text-base/ChannelMask_NO.dat.svn-base
@@ -0,0 +1,128 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options/UT/.svn/text-base/MambaMasks.dat.svn-base b/TbUT/options/UT/.svn/text-base/MambaMasks.dat.svn-base
new file mode 100644
index 0000000..96c51ca
--- /dev/null
+++ b/TbUT/options/UT/.svn/text-base/MambaMasks.dat.svn-base
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options/UT/.svn/text-base/MambaMasksSecond.dat.svn-base b/TbUT/options/UT/.svn/text-base/MambaMasksSecond.dat.svn-base
new file mode 100644
index 0000000..32e2c49
--- /dev/null
+++ b/TbUT/options/UT/.svn/text-base/MambaMasksSecond.dat.svn-base
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options/UT/.svn/text-base/Masks_DTypeSensor.dat.svn-base b/TbUT/options/UT/.svn/text-base/Masks_DTypeSensor.dat.svn-base
new file mode 100644
index 0000000..5485528
--- /dev/null
+++ b/TbUT/options/UT/.svn/text-base/Masks_DTypeSensor.dat.svn-base
@@ -0,0 +1,512 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options/UT/.svn/text-base/noise_Mamba.dat.svn-base b/TbUT/options/UT/.svn/text-base/noise_Mamba.dat.svn-base
new file mode 100644
index 0000000..02a1490
--- /dev/null
+++ b/TbUT/options/UT/.svn/text-base/noise_Mamba.dat.svn-base
@@ -0,0 +1 @@
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 107.127689 25.305770 24.985735 23.880182 22.809866 23.103255 21.446864 24.188582 23.685522 22.460031 23.555169 26.122744 22.838222 25.087562 22.850856 26.304380 23.125743 23.201400 22.981947 22.458851 22.031775 75.466407 51.881567 46.426626 47.246870 50.250365 50.780563 47.397003 50.889006 44.839078 59.207575 54.965865 114.590228 52.238674 49.750998 48.155621 47.201067 49.133314 57.518032 67.569805 45.230984 46.673350 45.512254 45.617092 45.259825 45.733567 43.473456 43.722568 46.309360 48.914275 46.195759 48.450691 46.991445 52.781011 44.938163 46.455350 48.689499 45.403610 45.369944 42.134903 49.988984 49.633555 48.905178 44.971312 102.454547 43.896938 46.025610 39.809658 48.892613 43.968920 46.158579 48.159849 45.339528 42.081082 44.699937 43.227861 47.410931 41.160049 40.516874 44.124118 44.146963 46.627116 46.580809 43.070769 44.394065 42.607589 40.539213 43.251907 41.822410 45.898057 42.565037 44.062626 45.326879 44.702859 42.397044 41.252848 88.335221 41.643967 34.608467 41.525864 46.433712 48.705537 48.037901 40.895212 44.268060 42.162424 50.315707 41.441086 44.912960 43.003265 43.192740 42.952157 41.882323 44.014815 47.021833 45.965268 47.058266 45.766898 47.100425 45.208550 45.255262 49.039370 45.584677 46.038130 48.700468 45.034562 48.017172 37.116766 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 103.574529 49.603625 40.932967 44.120129 46.989088 47.289385 42.539289 39.679308 44.850751 38.851602 40.150803 39.946870 41.222906 43.960259 42.801704 37.360752 46.740100 42.473749 42.270202 43.682044 40.628559 40.139477 41.239218 39.108411 42.487292 43.201841 45.324183 40.450401 42.599853 43.263448 45.212560 44.764607 93.965153 42.923984 39.283722 39.083817 39.157311 42.328685 42.607923 38.564660 38.176196 42.152569 41.570047 39.143071 43.732281 38.429395 42.671582 38.889019 39.934366 38.649476 40.492826 39.350685 40.119143 41.312342 40.456242 42.077608 42.515644 42.268116 36.987452 37.506325 43.455469 40.407518 42.938532 42.798971 100.449464 40.856808 41.654939 42.548901 42.424191 40.898803 44.610357 44.984962 43.038145 40.748126 40.054942 41.821774 45.159960 44.908427 38.535427 40.479968 45.914416 46.386506 40.581955 40.034090 40.590609 40.195188 40.987605 58.823488 57.836143 42.323127 43.008627 42.873627 45.115518 44.816727 43.700261 40.807038 90.034575 53.500508 52.928495 52.112731 51.841441 48.424681 64.076780 55.632418 58.952640 88.941295 30.695698 25.107800 21.129922 24.741665 23.513068 23.950656 24.211989 22.534383 24.610810 24.665741 24.676102 23.380582 22.372076 25.319500 24.445932 25.051063 23.579970 23.809439 26.151015 25.114798 26.635690 26.701423 
\ No newline at end of file
diff --git a/TbUT/options/UT/.svn/text-base/ped_mamba.dat.svn-base b/TbUT/options/UT/.svn/text-base/ped_mamba.dat.svn-base
new file mode 100644
index 0000000..7e91540
--- /dev/null
+++ b/TbUT/options/UT/.svn/text-base/ped_mamba.dat.svn-base
@@ -0,0 +1 @@
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 253.303620 182.152255 113.621122 171.792383 120.250645 126.309957 75.423440 102.072392 114.725425 82.405370 151.940059 84.144931 71.917179 118.425014 117.137358 84.390779 75.015043 90.755132 65.461158 46.014122 64.344552 80.897262 112.127927 54.915623 45.818448 52.950238 16.700947 71.737650 14.800828 133.171107 68.749285 64.216343 -3.042604 -50.037095 -13.973598 -8.117553 22.098067 -25.182776 -7.966707 7.813575 6.690435 21.166485 -6.230388 10.299291 -0.725338 -47.185526 -15.555366 35.919805 -14.279422 -5.116494 -11.734951 -11.662071 -19.722573 43.261414 -62.580983 -7.627199 -28.002529 -8.330377 -3.950406 -28.021400 -19.728195 7.892501 -31.709001 41.948884 -124.596325 -102.222637 -87.755193 -87.414674 -89.709446 -73.812742 -80.833287 -38.950896 -74.193490 -117.918792 -75.621606 -65.111905 -63.711267 -41.983475 -17.406442 -63.364378 -64.100100 -47.427178 -32.967984 -60.556476 -18.430178 -62.281692 -60.745267 -67.925346 -41.166868 -12.956771 -46.470189 -45.835735 -55.578225 -38.468060 -57.497110 -20.651953 -67.414970 -53.458051 -63.707500 -29.066766 -15.844467 -49.081892 -61.699898 -24.109353 -4.554722 -6.583131 -2.976649 -31.208461 -12.522903 21.183791 -5.809948 1.467180 -17.374387 2.076994 20.293797 14.632401 -25.909328 4.606503 -11.754167 -14.686661 2.097853 -5.521749 -33.690440 10.447020 -15.810531 -29.106253 -27.956672 -23.200000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 143.993046 115.828224 109.673023 106.361857 115.790176 82.309432 72.677026 58.555909 104.655509 102.352075 110.826122 93.752839 28.154396 61.213051 107.529156 92.244758 63.700139 60.831653 29.173439 31.680749 40.900467 30.245755 18.732808 70.098913 8.429895 14.924629 11.211726 8.837123 -3.912452 14.362007 -8.325015 59.556553 -121.673447 -83.755947 -72.989147 -47.662903 -102.619719 -70.219704 -124.456764 -52.542638 -82.776284 -106.094290 -96.277340 -94.058599 -53.445471 -87.519127 -56.428337 -55.483802 -65.867732 -88.360121 -87.809210 -88.161892 -113.359361 -74.942836 -81.374053 -96.570768 -92.027202 -81.096345 -78.035250 -92.508416 -105.824966 -92.563379 -121.485072 9.250579 -39.369626 -90.742052 -35.971429 16.150572 -36.636056 -21.913411 -22.966341 -18.654684 -16.591379 -35.352666 -38.975838 0.388029 -25.779884 -32.410839 -24.350973 10.411679 2.537695 -28.243678 -5.281909 11.206816 -31.605753 -40.174068 -31.377332 -21.089011 -13.557339 -42.849654 -23.016646 -55.255153 -24.170208 4.896151 -69.356790 58.576026 -198.837919 -156.184179 -168.412828 -110.136174 -175.706841 -176.130134 -167.096479 -119.977369 -167.642404 -136.715376 -121.941747 -144.694214 -112.558623 -142.421387 -152.528190 -177.043934 -136.622046 -175.270575 -163.614580 -132.154191 -163.317129 -135.253817 -143.470432 -129.417464 -175.972739 -132.394553 -177.009714 -148.318405 -144.174653 -145.692359 -161.386920 -50.137176 
\ No newline at end of file
diff --git a/TbUT/options/UT/ChannelMask_NO.dat b/TbUT/options/UT/ChannelMask_NO.dat
new file mode 100644
index 0000000..9e77e64
--- /dev/null
+++ b/TbUT/options/UT/ChannelMask_NO.dat
@@ -0,0 +1,128 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options/UT/MambaMasks.dat b/TbUT/options/UT/MambaMasks.dat
new file mode 100644
index 0000000..96c51ca
--- /dev/null
+++ b/TbUT/options/UT/MambaMasks.dat
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options/UT/MambaMasksSecond.dat b/TbUT/options/UT/MambaMasksSecond.dat
new file mode 100644
index 0000000..32e2c49
--- /dev/null
+++ b/TbUT/options/UT/MambaMasksSecond.dat
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options/UT/Masks_DTypeSensor.dat b/TbUT/options/UT/Masks_DTypeSensor.dat
new file mode 100644
index 0000000..5485528
--- /dev/null
+++ b/TbUT/options/UT/Masks_DTypeSensor.dat
@@ -0,0 +1,512 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options/UT/Pedestal-M1-FanIn-5.dat b/TbUT/options/UT/Pedestal-M1-FanIn-5.dat
new file mode 100644
index 0000000..3a3e566
--- /dev/null
+++ b/TbUT/options/UT/Pedestal-M1-FanIn-5.dat
@@ -0,0 +1 @@
+-142 -191 -158 -136 -117 -137 -148 -131 -166 -142 -135 -143 -146 -110 -114 -142 -130 -115 -103 -91 -124 -129 -124 -135 -96 -102 -117 -131 -124 -139 -118 -143 -53 30 30 22 14 19 0 6 44 33 -7 14 13 -2 16 17 36 13 38 36 23 17 30 15 35 72 28 14 41 -27 3 -11 -20 -4 25 0 41 8 -4 23 25 3 6 20 24 19 14 37 45 39 48 14 49 31 42 36 49 49 43 58 78 0 16 31 28 96 64 87 100 100 101 93 92 136 97 101 123 100 113 110 125 103 131 118 137 116 106 130 100 114 96 106 111 71 85 66 31 5 30 44 58 2 33 29 -2 21 38 35 17 54 27 27 18 31 45 34 64 50 56 49 53 33 27 73 1 65 54 0 -63 -67 -57 -45 -29 -73 -65 -74 -61 -78 -60 -89 -59 -61 -73 -44 -48 -72 -40 -59 -71 -52 -69 -65 -55 -34 -87 -43 -50 -80 -57 -102 -5 21 -17 10 3 19 -21 -19 4 15 1 19 9 19 30 28 15 19 15 5 13 -4 21 36 19 10 29 62 43 30 -1 12 73 139 135 137 138 162 131 120 144 129 149 156 151 130 148 104 132 171 150 158 131 151 169 144 128 131 134 158 134 153 105 113 64 82 87 94 103 83 76 91 84 84 92 61 80 118 120 116 106 116 107 87 89 61 104 53 86 70 113 90 106 90 88 83 -54 -25 -17 -29 -7 -17 -15 5 -14 -8 -15 -31 -10 -12 -30 -37 -7 -10 1 18 -7 1 16 9 -6 13 -2 17 11 17 13 -34 -52 -38 -29 -9 -10 -27 -30 -25 -27 -40 -17 -20 -22 -10 -43 -13 -16 -26 -25 -14 -27 -21 -52 -21 -40 -37 -20 -22 -22 7 -39 -57 -49 -15 9 -3 -9 -8 22 3 12 -5 -5 -3 12 -1 -1 -13 -3 -18 15 -1 7 35 19 13 20 7 23 -6 -11 7 -29 1 -23 -8 20 -23 -7 -14 -14 -9 3 6 1 -10 23 -16 -12 -30 -12 -7 35 25 25 17 -4 16 -17 23 4 -8 -2 -22 -14 4 -26 2 2 7 30 10 5 13 0 -4 29 38 17 1 22 18 17 19 56 16 20 32 11 15 8 35 12 22 26 15 17 15 -59 -27 -3 14 15 -9 8 -4 21 32 26 21 25 3 7 17 8 -16 4 7 12 14 13 -5 30 19 25 45 66 27 19 31 -36 32 5 7 17 32 16 31 35 12 8 29 33 1 17 49 32 34 38 28 25 34 28 3 36 47 52 11 37 26 22 32 
\ No newline at end of file
diff --git a/TbUT/options/UT/Pedestal-M1-FanIn-51.dat b/TbUT/options/UT/Pedestal-M1-FanIn-51.dat
new file mode 100644
index 0000000..946414f
--- /dev/null
+++ b/TbUT/options/UT/Pedestal-M1-FanIn-51.dat
@@ -0,0 +1 @@
+-145 -194 -158 -135 -118 -138 -150 -133 -167 -141 -138 -146 -147 -116 -111 -143 -133 -119 -106 -93 -128 -132 -126 -137 -96 -102 -117 -134 -120 -141 -120 -143 -52 30 34 23 14 20 2 7 49 33 -3 12 11 -3 19 17 38 18 40 39 24 19 33 11 36 71 29 15 40 -27 5 -7 -19 -3 26 0 41 10 -3 24 26 1 8 23 24 21 13 37 49 39 48 16 52 32 41 39 50 52 43 62 80 1 18 33 25 96 66 88 100 105 102 94 91 135 93 97 122 102 112 109 125 104 131 119 135 116 104 130 97 114 99 105 113 70 85 65 26 4 27 43 56 2 31 29 -4 20 37 33 16 52 28 25 18 31 43 33 62 50 54 42 49 33 23 72 -3 65 52 4 -61 -64 -55 -46 -27 -75 -63 -75 -60 -80 -57 -90 -56 -62 -69 -45 -45 -72 -37 -58 -69 -52 -67 -64 -52 -33 -84 -43 -47 -80 -55 -101 -2 22 -16 11 3 19 -20 -20 4 15 1 18 9 21 29 28 14 19 14 5 12 -5 17 38 22 12 31 65 45 32 1 14 69 135 132 136 138 162 130 119 143 129 149 155 149 130 147 104 132 171 151 157 130 150 169 144 128 131 133 158 134 153 104 109 65 84 88 98 104 81 76 95 86 88 90 62 79 121 119 117 105 116 110 88 92 58 105 53 86 70 113 87 107 92 89 84 -52 -25 -14 -33 -5 -16 -13 3 -11 -10 -14 -31 -9 -16 -26 -36 -8 -11 5 15 -4 0 19 8 -2 8 0 15 11 15 16 -37 -54 -38 -28 -11 -8 -29 -29 -25 -24 -42 -20 -19 -23 -8 -43 -16 -15 -27 -25 -11 -27 -22 -53 -21 -38 -37 -20 -21 -22 5 -41 -54 -49 -16 3 -5 -9 -12 22 2 12 -8 -5 -5 11 -4 -7 -14 -4 -25 15 -5 5 34 15 11 18 3 22 -11 -11 8 -31 -1 -21 -7 22 -21 -5 -12 -12 -8 6 7 3 -9 26 -15 -10 -28 -10 -6 37 26 26 18 -1 17 -16 23 5 -7 0 -21 -10 10 -23 0 1 7 29 9 3 13 -2 -5 27 37 16 0 21 18 15 18 54 14 19 30 9 14 6 35 10 21 24 15 14 20 -58 -25 -5 12 15 -11 8 -5 20 31 25 19 24 2 4 18 6 -19 5 7 13 11 12 -3 31 19 26 46 68 27 19 31 -32 35 7 10 19 34 17 33 36 14 10 29 33 4 19 50 32 34 40 32 25 36 27 7 37 49 54 16 36 25 23 36 
\ No newline at end of file
diff --git a/TbUT/options/UT/noise_Mamba.dat b/TbUT/options/UT/noise_Mamba.dat
new file mode 100644
index 0000000..34d568e
--- /dev/null
+++ b/TbUT/options/UT/noise_Mamba.dat
@@ -0,0 +1 @@
+16.708177 13.251469 13.042316 12.787692 13.256494 12.771904 12.839727 12.862744 12.959683 12.737297 12.877526 14.179095 13.076823 12.921302 12.918589 12.863983 12.912850 12.914107 12.934386 13.028907 12.926894 12.847827 12.894432 13.003000 12.981825 12.983496 13.015462 13.049881 13.007062 12.894146 13.027867 13.416557 14.608187 12.713521 12.677274 12.684571 12.802255 12.618815 12.580249 12.620478 12.690093 12.583570 12.461546 12.676711 12.722388 12.504062 12.614718 12.736391 12.732501 12.661005 12.608916 12.616182 12.665171 12.644067 12.620277 12.770358 12.702949 12.680966 12.583851 12.800045 12.718258 12.652013 12.646568 13.471713 15.128758 12.595766 12.478017 12.671437 12.539149 12.556624 12.470039 12.700235 12.559540 12.601904 12.529037 12.534791 12.578216 12.502020 12.483491 12.520459 12.598759 12.457650 12.518429 12.571163 12.663059 12.479124 12.536250 12.534667 12.731694 12.464764 12.567546 12.537672 12.794891 12.569636 12.546872 13.088698 14.641534 12.600033 12.490051 12.734115 12.467213 12.447857 12.544924 12.593980 12.449732 12.541873 12.412049 12.577893 12.451567 12.442777 12.391276 12.471157 12.425591 12.365402 12.358449 12.474230 12.516986 12.339853 12.301418 12.447101 12.500977 12.435111 12.500165 12.509025 12.878856 12.691830 13.640057 15.710382 20.355113 16.706632 15.973760 15.290436 16.176808 15.584283 15.692149 15.239461 15.900620 15.533393 15.470435 15.318646 15.687901 15.492675 15.392268 15.235891 15.515123 15.422802 15.210566 14.931859 15.515773 15.178869 14.417227 36.311114 29.972223 29.368522 28.218142 29.131049 27.906019 28.059486 27.533778 28.072437 20.901618 20.559464 19.254691 19.915383 18.331881 18.585137 17.816262 18.149887 17.502020 17.260659 17.267418 17.238614 17.594705 17.315568 17.544694 17.216642 17.827353 16.887864 17.162767 15.857872 16.572986 15.692643 16.135058 15.402579 16.551270 15.785498 16.389332 15.903471 17.086176 16.783382 17.213972 17.894055 22.351536 19.504453 20.290950 19.034250 24.370282 26.449986 24.261147 18.883293 19.496909 19.483417 19.750251 20.206055 20.248053 20.972798 20.913478 21.556885 21.061042 21.612957 21.225101 22.149479 21.776396 25.345136 34.040380 21.690735 23.197838 23.264329 23.083145 23.119413 23.237439 23.377289 23.213926 23.713416 15.099805 12.262725 12.190331 12.323225 12.118070 12.197083 12.082172 12.228245 12.067264 12.062245 11.971610 12.167209 12.057593 11.994585 11.958398 12.047668 12.021016 12.010024 11.850605 12.001862 11.982535 11.896760 12.010593 11.917642 12.011085 11.904264 12.077977 11.970074 12.389357 12.159126 12.981581 15.278978 15.151343 12.889191 12.628019 12.528578 12.639748 12.529515 12.439268 12.562512 12.656555 12.520112 12.507124 12.590040 12.466175 12.510212 12.526709 12.570223 12.567413 12.456390 12.440521 12.630171 12.462997 12.460926 12.458238 12.536645 12.572153 12.520400 12.467310 12.624504 12.514763 12.519709 12.466098 13.177653 13.961972 12.913239 12.231443 11.958419 12.222928 11.980823 12.009156 12.004273 12.131830 11.954498 11.936399 11.946485 12.123060 11.961192 11.979242 11.826711 12.053350 11.893386 11.909597 12.106791 11.988363 11.897415 11.943602 11.981933 12.000772 11.981782 11.905049 12.068423 12.035291 11.951590 11.986149 12.608241 14.442838 12.080885 11.771840 11.988275 11.847786 11.847843 11.790519 11.921474 11.943763 11.806243 11.863832 11.867596 11.916860 11.841356 11.823590 11.857803 11.899754 11.887405 11.811421 11.771709 11.871006 11.728488 11.784715 11.783890 11.897253 11.721348 11.817621 11.782387 11.879921 11.857273 11.785027 12.452578 14.082792 12.217596 12.098468 12.266003 11.989323 12.045858 12.004305 12.158732 12.084520 11.932894 11.944804 12.061424 12.038377 11.884367 11.877872 12.022774 11.890514 11.861720 11.844540 11.920729 11.955939 11.911893 11.955916 11.991938 11.972297 11.971925 11.991919 11.963925 12.089217 11.990623 12.687887 14.810269 15.757270 13.201941 13.062004 13.524885 13.062982 13.277070 13.040839 13.609453 12.939973 13.384330 13.088211 13.614497 12.998788 13.389380 13.091716 13.703064 12.877446 13.326282 13.118883 13.769703 12.896638 13.311140 12.751764 27.773517 23.700625 19.514912 20.036370 18.700287 20.313693 19.013209 19.816723 19.244660 16.784960 14.790414 14.744798 14.692767 15.139410 14.560083 14.807170 14.545473 14.930969 14.681728 15.186872 15.094098 15.029005 14.873154 15.010460 14.839278 14.950725 14.814230 14.904922 15.071936 15.196338 15.372462 15.047934 15.425176 15.872477 15.672293 15.665863 15.751289 15.802411 15.926524 15.607714 16.295467 19.647920 17.783125 19.798099 17.163454 18.036167 17.390376 17.785416 17.213038 18.008071 17.357359 17.822365 17.062637 18.073703 17.120958 17.412521 16.755668 17.696392 19.559305 17.725007 18.461701 16.714896 24.770292 29.139433 15.331825 15.840628 16.515039 16.209408 16.886917 15.998946 16.480543 16.114558 17.186747 14.114491 11.847328 11.671560 11.938847 11.744761 11.788744 11.639380 11.882421 11.694921 11.734977 11.633534 11.822281 11.715645 11.586540 11.586446 11.768936 11.633978 11.650407 11.565919 11.662164 11.626758 11.651101 11.608764 11.618932 11.698226 11.662704 11.676808 11.719489 12.091997 11.835350 12.586641 14.475383 
\ No newline at end of file
diff --git a/TbUT/options/UT/ped_mamba.dat b/TbUT/options/UT/ped_mamba.dat
new file mode 100644
index 0000000..7e91540
--- /dev/null
+++ b/TbUT/options/UT/ped_mamba.dat
@@ -0,0 +1 @@
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 253.303620 182.152255 113.621122 171.792383 120.250645 126.309957 75.423440 102.072392 114.725425 82.405370 151.940059 84.144931 71.917179 118.425014 117.137358 84.390779 75.015043 90.755132 65.461158 46.014122 64.344552 80.897262 112.127927 54.915623 45.818448 52.950238 16.700947 71.737650 14.800828 133.171107 68.749285 64.216343 -3.042604 -50.037095 -13.973598 -8.117553 22.098067 -25.182776 -7.966707 7.813575 6.690435 21.166485 -6.230388 10.299291 -0.725338 -47.185526 -15.555366 35.919805 -14.279422 -5.116494 -11.734951 -11.662071 -19.722573 43.261414 -62.580983 -7.627199 -28.002529 -8.330377 -3.950406 -28.021400 -19.728195 7.892501 -31.709001 41.948884 -124.596325 -102.222637 -87.755193 -87.414674 -89.709446 -73.812742 -80.833287 -38.950896 -74.193490 -117.918792 -75.621606 -65.111905 -63.711267 -41.983475 -17.406442 -63.364378 -64.100100 -47.427178 -32.967984 -60.556476 -18.430178 -62.281692 -60.745267 -67.925346 -41.166868 -12.956771 -46.470189 -45.835735 -55.578225 -38.468060 -57.497110 -20.651953 -67.414970 -53.458051 -63.707500 -29.066766 -15.844467 -49.081892 -61.699898 -24.109353 -4.554722 -6.583131 -2.976649 -31.208461 -12.522903 21.183791 -5.809948 1.467180 -17.374387 2.076994 20.293797 14.632401 -25.909328 4.606503 -11.754167 -14.686661 2.097853 -5.521749 -33.690440 10.447020 -15.810531 -29.106253 -27.956672 -23.200000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 143.993046 115.828224 109.673023 106.361857 115.790176 82.309432 72.677026 58.555909 104.655509 102.352075 110.826122 93.752839 28.154396 61.213051 107.529156 92.244758 63.700139 60.831653 29.173439 31.680749 40.900467 30.245755 18.732808 70.098913 8.429895 14.924629 11.211726 8.837123 -3.912452 14.362007 -8.325015 59.556553 -121.673447 -83.755947 -72.989147 -47.662903 -102.619719 -70.219704 -124.456764 -52.542638 -82.776284 -106.094290 -96.277340 -94.058599 -53.445471 -87.519127 -56.428337 -55.483802 -65.867732 -88.360121 -87.809210 -88.161892 -113.359361 -74.942836 -81.374053 -96.570768 -92.027202 -81.096345 -78.035250 -92.508416 -105.824966 -92.563379 -121.485072 9.250579 -39.369626 -90.742052 -35.971429 16.150572 -36.636056 -21.913411 -22.966341 -18.654684 -16.591379 -35.352666 -38.975838 0.388029 -25.779884 -32.410839 -24.350973 10.411679 2.537695 -28.243678 -5.281909 11.206816 -31.605753 -40.174068 -31.377332 -21.089011 -13.557339 -42.849654 -23.016646 -55.255153 -24.170208 4.896151 -69.356790 58.576026 -198.837919 -156.184179 -168.412828 -110.136174 -175.706841 -176.130134 -167.096479 -119.977369 -167.642404 -136.715376 -121.941747 -144.694214 -112.558623 -142.421387 -152.528190 -177.043934 -136.622046 -175.270575 -163.614580 -132.154191 -163.317129 -135.253817 -143.470432 -129.417464 -175.972739 -132.394553 -177.009714 -148.318405 -144.174653 -145.692359 -161.386920 -50.137176 
\ No newline at end of file
diff --git a/TbUT/options/python/.svn/all-wcprops b/TbUT/options/python/.svn/all-wcprops
new file mode 100644
index 0000000..899fac0
--- /dev/null
+++ b/TbUT/options/python/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/options/python
+END
+TbUTClusterizator.py
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/options/python/TbUTClusterizator.py
+END
+TbUTPedestalRunner.py
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/194849/Kepler/trunk/Tb/TbUT/options/python/TbUTPedestalRunner.py
+END
+Timer.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/191831/Kepler/trunk/Tb/TbUT/options/python/Timer.py
+END
diff --git a/TbUT/options/python/.svn/entries b/TbUT/options/python/.svn/entries
new file mode 100644
index 0000000..c4770b8
--- /dev/null
+++ b/TbUT/options/python/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+205728
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/options/python
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbUTClusterizator.py
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+2d1d3e58685a5ba242e96cae8d8066b4
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4828
+
+TbUTPedestalRunner.py
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+2b0baeae1a7509142f33b10085a0651f
+2015-09-10T16:19:06.475049Z
+194849
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2852
+
+Timer.py
+file
+
+
+
+
+2016-05-06T08:12:03.000000Z
+dfbebc98af7c4503a451033a4316d7f8
+2015-07-14T15:46:54.883477Z
+191831
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+326
+
diff --git a/TbUT/options/python/.svn/text-base/TbUTClusterizator.py.svn-base b/TbUT/options/python/.svn/text-base/TbUTClusterizator.py.svn-base
new file mode 100644
index 0000000..e2f41e8
--- /dev/null
+++ b/TbUT/options/python/.svn/text-base/TbUTClusterizator.py.svn-base
@@ -0,0 +1,121 @@
+__author__ = 'ja'
+
+
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataMonitor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+from Configurables import TbUT__PedestalSubtractorDataMonitorAlgorithm as pedestalMonitor
+from Configurables import TbUT__CommonModeSubtractorAlgorithm  as CMS
+from Configurables import TbUT__CommonModeSubtractorDataMonitorAlgorithm  as CMSMonitor
+from Configurables import TbUT__ClusterCreatorAlgorithm as ClusterCreator
+from Configurables import TbUT__ClusterCreatorDataMonitorAlgorithm as ClusterCreatorMonitor
+from Configurables import TbUT__NTupleCreator as nTupleCreator
+
+from Timer import timer
+
+class TbUTClusterizator:
+    def __init__(self):
+        self.isAType=True
+
+    @property
+    def eventNumberDisplay(self):
+        return self.eventNumberDisplay
+    @eventNumberDisplay.setter
+    def eventNumberDisplay(self,value):
+        self.eventNumberDisplay=value
+
+    @property
+    def pedestalInputData(self):
+        return  self.pedestalInputData
+    @pedestalInputData.setter
+    def pedestalInputData(self,value):
+        self.pedestalInputData=value
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self.isAType
+    @isAType.setter
+    def isAType(self, value):
+        self.isAType=value
+
+    @property
+    def sensorType(self):
+        return self.sensorType
+    @sensorType.setter
+    def sensorType(self, value):
+        self.sensorType=value
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @timer
+    def runClusterization(self):
+        self._prepareStandaloneClusterization()
+        config=self._runClusterization
+        appendPostConfigAction(config)
+
+
+
+    def _prepareStandaloneClusterization(self):
+        # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        outputName=self.inputData[:-4]+".root"
+        outputName=outputName[outputName.rfind("/")+1:]
+        Kepler().HistogramFile=outputName
+        outputTupleName=self.inputData[:-4]+"_Tuple.root"
+        outputTupleName=outputTupleName[outputTupleName.rfind("/")+1:]
+        Kepler().TupleFile=outputTupleName
+
+
+    def _runClusterization(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UT")
+
+        rawDataReader().inputData=self.inputData
+        rawDataReader().isAType=self.isAType
+        rawDataMonitor().displayEventNumber=self.eventNumberDisplay
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/Masks_DTypeSensor.dat"
+        pedestalSubtractor().PedestalInputFile=self.pedestalInputData
+        pedestalSubtractor().FollowingOption='file'
+        pedestalSubtractor().treningEntry=1
+        pedestalMonitor().displayEventNumber=self.eventNumberDisplay
+        CMS().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/Masks_DTypeSensor.dat"
+        CMS().NoiseOutputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        CMSMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreator().NoiseInputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        ClusterCreator().LowThreshold=2.5
+        ClusterCreator().HighThreshold=3
+        ClusterCreator().sensorType=self.sensorType
+        ClusterCreatorMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreatorMonitor().sensorType=self.sensorType
+        nTupleCreator().StoreEventNumber=900000
+        nTupleCreator().WriteRaw=False
+        nTupleCreator().WriteHeader=True
+        nTupleCreator().WritePedestal=False
+        nTupleCreator().WriteCMS=False
+        seq_UT_data_processing.Members = [rawDataReader(), rawDataMonitor() ,pedestalSubtractor(),pedestalMonitor(), CMS(),
+                                          CMSMonitor(), ClusterCreator(),ClusterCreatorMonitor(),nTupleCreator()]
+        keplerSeq.Members+=[seq_UT_data_processing]
diff --git a/TbUT/options/python/.svn/text-base/TbUTPedestalRunner.py.svn-base b/TbUT/options/python/.svn/text-base/TbUTPedestalRunner.py.svn-base
new file mode 100644
index 0000000..bbc9839
--- /dev/null
+++ b/TbUT/options/python/.svn/text-base/TbUTPedestalRunner.py.svn-base
@@ -0,0 +1,82 @@
+__author__ = 'ja'
+from Gaudi.Configuration import *
+from Configurables import ExceptionSvc
+
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataReaderMoniotor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+
+from Timer import timer
+
+class TbUTPedestalRunner:
+    def __init__(self):
+        pass
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @property
+    def pedestalOutputData(self):
+        return  self.pedestalOutputData
+    @pedestalOutputData.setter
+    def pedestalOutputData(self,value):
+        expectedDirectory ="$KEPLERROOT/../TbUT/options/UT/"
+        if not value.startswith(expectedDirectory):
+            raise AttributeError("The pedestal file have to be stored in directory: "+expectedDirectory)
+        self.pedestalOutputData=value
+
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self._isAType
+    @isAType.setter
+    def isAType(self,value):
+        self._isAType=value
+
+    @timer
+    def runPedestals(self):
+        self._preparePedestalRun()
+        config= self._runGaudi
+        appendPostConfigAction(config)
+
+
+    def _preparePedestalRun(self):
+         # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        Kepler().HistogramFile="MambaPedestal.root" # should be set more correctly
+
+    def _runGaudi(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UTPedestal")
+        rawDataReader().isAType=self.isAType
+        rawDataReader().inputData= self.inputData
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/MambaMasks.dat"
+        pedestalSubtractor().PedestalOutputFile=self.pedestalOutputData
+        pedestalSubtractor().treningEntry=15000
+
+
+        seq_UT_data_processing.Members =[rawDataReader(), rawDataReaderMoniotor() ,pedestalSubtractor()]
+        keplerSeq.Members+=[seq_UT_data_processing]
+
diff --git a/TbUT/options/python/.svn/text-base/Timer.py.svn-base b/TbUT/options/python/.svn/text-base/Timer.py.svn-base
new file mode 100644
index 0000000..d05e11e
--- /dev/null
+++ b/TbUT/options/python/.svn/text-base/Timer.py.svn-base
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+
+import time
+
+def timer(method):
+
+    def timed(*args, **kw):
+        startTime = time.time()
+        result = method(*args, **kw)
+        endTime = time.time()
+
+        print ('execution of %r  takes  %2.2f sec') % \
+              (method.__name__, endTime-startTime)
+        return result
+
+    return timed
\ No newline at end of file
diff --git a/TbUT/options/python/TbUTClusterizator.py b/TbUT/options/python/TbUTClusterizator.py
new file mode 100644
index 0000000..e2f41e8
--- /dev/null
+++ b/TbUT/options/python/TbUTClusterizator.py
@@ -0,0 +1,121 @@
+__author__ = 'ja'
+
+
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataMonitor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+from Configurables import TbUT__PedestalSubtractorDataMonitorAlgorithm as pedestalMonitor
+from Configurables import TbUT__CommonModeSubtractorAlgorithm  as CMS
+from Configurables import TbUT__CommonModeSubtractorDataMonitorAlgorithm  as CMSMonitor
+from Configurables import TbUT__ClusterCreatorAlgorithm as ClusterCreator
+from Configurables import TbUT__ClusterCreatorDataMonitorAlgorithm as ClusterCreatorMonitor
+from Configurables import TbUT__NTupleCreator as nTupleCreator
+
+from Timer import timer
+
+class TbUTClusterizator:
+    def __init__(self):
+        self.isAType=True
+
+    @property
+    def eventNumberDisplay(self):
+        return self.eventNumberDisplay
+    @eventNumberDisplay.setter
+    def eventNumberDisplay(self,value):
+        self.eventNumberDisplay=value
+
+    @property
+    def pedestalInputData(self):
+        return  self.pedestalInputData
+    @pedestalInputData.setter
+    def pedestalInputData(self,value):
+        self.pedestalInputData=value
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self.isAType
+    @isAType.setter
+    def isAType(self, value):
+        self.isAType=value
+
+    @property
+    def sensorType(self):
+        return self.sensorType
+    @sensorType.setter
+    def sensorType(self, value):
+        self.sensorType=value
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @timer
+    def runClusterization(self):
+        self._prepareStandaloneClusterization()
+        config=self._runClusterization
+        appendPostConfigAction(config)
+
+
+
+    def _prepareStandaloneClusterization(self):
+        # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        outputName=self.inputData[:-4]+".root"
+        outputName=outputName[outputName.rfind("/")+1:]
+        Kepler().HistogramFile=outputName
+        outputTupleName=self.inputData[:-4]+"_Tuple.root"
+        outputTupleName=outputTupleName[outputTupleName.rfind("/")+1:]
+        Kepler().TupleFile=outputTupleName
+
+
+    def _runClusterization(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UT")
+
+        rawDataReader().inputData=self.inputData
+        rawDataReader().isAType=self.isAType
+        rawDataMonitor().displayEventNumber=self.eventNumberDisplay
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/Masks_DTypeSensor.dat"
+        pedestalSubtractor().PedestalInputFile=self.pedestalInputData
+        pedestalSubtractor().FollowingOption='file'
+        pedestalSubtractor().treningEntry=1
+        pedestalMonitor().displayEventNumber=self.eventNumberDisplay
+        CMS().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/Masks_DTypeSensor.dat"
+        CMS().NoiseOutputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        CMSMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreator().NoiseInputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        ClusterCreator().LowThreshold=2.5
+        ClusterCreator().HighThreshold=3
+        ClusterCreator().sensorType=self.sensorType
+        ClusterCreatorMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreatorMonitor().sensorType=self.sensorType
+        nTupleCreator().StoreEventNumber=900000
+        nTupleCreator().WriteRaw=False
+        nTupleCreator().WriteHeader=True
+        nTupleCreator().WritePedestal=False
+        nTupleCreator().WriteCMS=False
+        seq_UT_data_processing.Members = [rawDataReader(), rawDataMonitor() ,pedestalSubtractor(),pedestalMonitor(), CMS(),
+                                          CMSMonitor(), ClusterCreator(),ClusterCreatorMonitor(),nTupleCreator()]
+        keplerSeq.Members+=[seq_UT_data_processing]
diff --git a/TbUT/options/python/TbUTClusterizator.pyc b/TbUT/options/python/TbUTClusterizator.pyc
new file mode 100644
index 0000000..8b1151e
--- /dev/null
+++ b/TbUT/options/python/TbUTClusterizator.pyc
Binary files differ
diff --git a/TbUT/options/python/TbUTPedestalRunner.py b/TbUT/options/python/TbUTPedestalRunner.py
new file mode 100644
index 0000000..bbc9839
--- /dev/null
+++ b/TbUT/options/python/TbUTPedestalRunner.py
@@ -0,0 +1,82 @@
+__author__ = 'ja'
+from Gaudi.Configuration import *
+from Configurables import ExceptionSvc
+
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataReaderMoniotor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+
+from Timer import timer
+
+class TbUTPedestalRunner:
+    def __init__(self):
+        pass
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @property
+    def pedestalOutputData(self):
+        return  self.pedestalOutputData
+    @pedestalOutputData.setter
+    def pedestalOutputData(self,value):
+        expectedDirectory ="$KEPLERROOT/../TbUT/options/UT/"
+        if not value.startswith(expectedDirectory):
+            raise AttributeError("The pedestal file have to be stored in directory: "+expectedDirectory)
+        self.pedestalOutputData=value
+
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self._isAType
+    @isAType.setter
+    def isAType(self,value):
+        self._isAType=value
+
+    @timer
+    def runPedestals(self):
+        self._preparePedestalRun()
+        config= self._runGaudi
+        appendPostConfigAction(config)
+
+
+    def _preparePedestalRun(self):
+         # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        Kepler().HistogramFile="MambaPedestal.root" # should be set more correctly
+
+    def _runGaudi(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UTPedestal")
+        rawDataReader().isAType=self.isAType
+        rawDataReader().inputData= self.inputData
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/MambaMasks.dat"
+        pedestalSubtractor().PedestalOutputFile=self.pedestalOutputData
+        pedestalSubtractor().treningEntry=15000
+
+
+        seq_UT_data_processing.Members =[rawDataReader(), rawDataReaderMoniotor() ,pedestalSubtractor()]
+        keplerSeq.Members+=[seq_UT_data_processing]
+
diff --git a/TbUT/options/python/TbUTPedestalRunner.pyc b/TbUT/options/python/TbUTPedestalRunner.pyc
new file mode 100644
index 0000000..8bdd99a
--- /dev/null
+++ b/TbUT/options/python/TbUTPedestalRunner.pyc
Binary files differ
diff --git a/TbUT/options/python/Timer.py b/TbUT/options/python/Timer.py
new file mode 100644
index 0000000..d05e11e
--- /dev/null
+++ b/TbUT/options/python/Timer.py
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+
+import time
+
+def timer(method):
+
+    def timed(*args, **kw):
+        startTime = time.time()
+        result = method(*args, **kw)
+        endTime = time.time()
+
+        print ('execution of %r  takes  %2.2f sec') % \
+              (method.__name__, endTime-startTime)
+        return result
+
+    return timed
\ No newline at end of file
diff --git a/TbUT/options/python/Timer.pyc b/TbUT/options/python/Timer.pyc
new file mode 100644
index 0000000..cb23d38
--- /dev/null
+++ b/TbUT/options/python/Timer.pyc
Binary files differ
diff --git "a/TbUT/options_old/\043TbUTRun.py\043" "b/TbUT/options_old/\043TbUTRun.py\043"
new file mode 100644
index 0000000..d8b30c7
--- /dev/null
+++ "b/TbUT/options_old/\043TbUTRun.py\043"
@@ -0,0 +1,25 @@
+__author__ = 'ja'
+
+
+import sys
+sys.path.append("options/python")
+from TbUTClusterizator import TbUTClusterizator
+
+app = TbUTClusterizator()
+# set parameters
+#app.inputData = "data/Run_Bias_Scan-B1-A-229-8713.dat"
+#app.inputData = "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Run_Bias_Scan-B6-A-210-8356.dat"
+#app.inputData = "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Run_Bias_Scan-B6-A-299-8431.dat"
+#app.inputData = "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Run_Bias_Scan-B6-A-293-8425.dat"
+app.inputData = "/afs/cern.ch/user/c/cbetanco/public/Custom-M1-FanIn-4-15005.dat"
+app.isAType = False
+app.sensorType = "NType"
+
+app.eventMax = 100000
+#app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/ped-BoardA4Redo.dat"
+app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/Pedestal-M1"
+app.eventNumberDisplay = 10
+
+app.runClusterization()
+
+
diff --git a/TbUT/options_old/.svn/all-wcprops b/TbUT/options_old/.svn/all-wcprops
new file mode 100644
index 0000000..99942ff
--- /dev/null
+++ b/TbUT/options_old/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/options
+END
+TbUTPedestal.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/196283/Kepler/trunk/Tb/TbUT/options/TbUTPedestal.py
+END
+TbUTRun.py
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/197306/Kepler/trunk/Tb/TbUT/options/TbUTRun.py
+END
diff --git a/TbUT/options_old/.svn/entries b/TbUT/options_old/.svn/entries
new file mode 100644
index 0000000..2173f7b
--- /dev/null
+++ b/TbUT/options_old/.svn/entries
@@ -0,0 +1,102 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/options
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+python
+dir
+
+TbUTPedestal.py
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+e48104e2beb371550c256ae91f09f55d
+2015-10-15T00:37:58.771367Z
+196283
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+534
+
+UT
+dir
+
+TbUTRun.py
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+86c6f61235856e4ed5dde32e02a7a633
+2015-11-06T18:00:55.060165Z
+197306
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+412
+
diff --git a/TbUT/options_old/.svn/text-base/TbUTPedestal.py.svn-base b/TbUT/options_old/.svn/text-base/TbUTPedestal.py.svn-base
new file mode 100644
index 0000000..f46381a
--- /dev/null
+++ b/TbUT/options_old/.svn/text-base/TbUTPedestal.py.svn-base
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+import sys
+sys.path.append( "options/python" )
+
+from TbUTPedestalRunner import TbUTPedestalRunner
+app=TbUTPedestalRunner()
+# set parameter
+app.inputData= "/afs/cern.ch/user/a/adendek/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Pedestal-B6-A-209-0.dat"  
+app.isAType=True
+# have to be more than 4k (~10k)
+app.eventMax=20000
+#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!
+app.pedestalOutputData ="$KEPLERROOT/../TbUT/options/UT/Pedestal-BoardA6.dat"
+
+app.runPedestals()
+
diff --git a/TbUT/options_old/.svn/text-base/TbUTRun.py.svn-base b/TbUT/options_old/.svn/text-base/TbUTRun.py.svn-base
new file mode 100644
index 0000000..c44359b
--- /dev/null
+++ b/TbUT/options_old/.svn/text-base/TbUTRun.py.svn-base
@@ -0,0 +1,20 @@
+__author__ = 'ja'
+
+
+import sys
+sys.path.append("options/python")
+from TbUTClusterizator import TbUTClusterizator
+
+app = TbUTClusterizator()
+# set parameters
+app.inputData = "data/Run_Bias_Scan-B1-A-229-8713.dat"
+app.isAType = True
+app.sensorType = "PType"
+
+app.eventMax = 100000
+app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/ped-BoardA4Redo.dat"
+app.eventNumberDisplay = 100
+
+app.runClusterization()
+
+
diff --git a/TbUT/options_old/TbUTPedestal.py b/TbUT/options_old/TbUTPedestal.py
new file mode 100644
index 0000000..610b105
--- /dev/null
+++ b/TbUT/options_old/TbUTPedestal.py
@@ -0,0 +1,18 @@
+__author__ = 'ja'
+import sys
+sys.path.append( "options/python" )
+
+from TbUTPedestalRunner import TbUTPedestalRunner
+app=TbUTPedestalRunner()
+# set parameter
+#app.inputData= "/afs/cern.ch/user/a/adendek/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Pedestal-B6-A-209-0.dat" 
+#app.inputData= "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Pedestal-B6-A-407-8522.dat"  
+app.inputData = "/afs/cern.ch/user/c/cbetanco/public/Pedestal-M1-FanIn-5.dat"
+app.isAType=False
+# have to be more than 4k (~10k)
+app.eventMax=100000
+#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!
+app.pedestalOutputData ="$KEPLERROOT/../TbUT/options/UT/test.dat"
+
+app.runPedestals()
+
diff --git a/TbUT/options_old/TbUTRun.py b/TbUT/options_old/TbUTRun.py
new file mode 100644
index 0000000..aeb29fa
--- /dev/null
+++ b/TbUT/options_old/TbUTRun.py
@@ -0,0 +1,25 @@
+__author__ = 'ja'
+
+
+import sys
+sys.path.append("options/python")
+from TbUTClusterizator import TbUTClusterizator
+
+app = TbUTClusterizator()
+# set parameters
+#app.inputData = "data/Run_Bias_Scan-B1-A-229-8713.dat"
+#app.inputData = "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Run_Bias_Scan-B6-A-210-8356.dat"
+#app.inputData = "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Run_Bias_Scan-B6-A-299-8431.dat"
+#app.inputData = "/afs/cern.ch/user/c/cbetanco/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/Run_Bias_Scan-B6-A-293-8425.dat"
+app.inputData = "/afs/cern.ch/user/c/cbetanco/public/Custom-M1-FanIn-4-15005.dat"
+app.isAType = False
+app.sensorType = "NType"
+
+app.eventMax = 100000
+#app.pedestalInputData = "$KEPLERROOT/../TbUT/options/UT/ped-BoardA4Redo.dat"
+app.pedestalInputData = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/options/UT/test.dat"
+app.eventNumberDisplay = 10
+
+app.runClusterization()
+
+
diff --git a/TbUT/options_old/UT/.svn/all-wcprops b/TbUT/options_old/UT/.svn/all-wcprops
new file mode 100644
index 0000000..55d8255
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/all-wcprops
@@ -0,0 +1,41 @@
+K 25
+svn:wc:ra_dav:version-url
+V 59
+/guest/lhcb/!svn/ver/196283/Kepler/trunk/Tb/TbUT/options/UT
+END
+MambaMasksSecond.dat
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/193730/Kepler/trunk/Tb/TbUT/options/UT/MambaMasksSecond.dat
+END
+noise_Mamba.dat
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/196283/Kepler/trunk/Tb/TbUT/options/UT/noise_Mamba.dat
+END
+MambaMasks.dat
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/194758/Kepler/trunk/Tb/TbUT/options/UT/MambaMasks.dat
+END
+Masks_DTypeSensor.dat
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/194560/Kepler/trunk/Tb/TbUT/options/UT/Masks_DTypeSensor.dat
+END
+ChannelMask_NO.dat
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/191831/Kepler/trunk/Tb/TbUT/options/UT/ChannelMask_NO.dat
+END
+ped_mamba.dat
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/options/UT/ped_mamba.dat
+END
diff --git a/TbUT/options_old/UT/.svn/entries b/TbUT/options_old/UT/.svn/entries
new file mode 100644
index 0000000..5f6f951
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/entries
@@ -0,0 +1,232 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/options/UT
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-15T00:37:58.771367Z
+196283
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+MambaMasksSecond.dat
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+449a6978123b92c10c42ecf940fdd65c
+2015-08-14T17:20:42.072489Z
+193730
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1024
+
+noise_Mamba.dat
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+6629373a1509abbd1874c523013acd51
+2015-10-15T00:37:58.771367Z
+196283
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4869
+
+MambaMasks.dat
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+53ed5732b232e39b0ed1c491e1f7c476
+2015-09-09T16:04:25.162348Z
+194758
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1024
+
+Masks_DTypeSensor.dat
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+e2893f41c614ee3180c78f490f30e623
+2015-09-01T19:30:54.038917Z
+194560
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1024
+
+ChannelMask_NO.dat
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+f0c836ade0a8d5c835057615fe32199e
+2015-07-14T15:46:54.883477Z
+191831
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+256
+
+ped_mamba.dat
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+d3c3769434870060dce2a00cb972bc19
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5066
+
diff --git a/TbUT/options_old/UT/.svn/text-base/ChannelMask_NO.dat.svn-base b/TbUT/options_old/UT/.svn/text-base/ChannelMask_NO.dat.svn-base
new file mode 100644
index 0000000..9e77e64
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/text-base/ChannelMask_NO.dat.svn-base
@@ -0,0 +1,128 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options_old/UT/.svn/text-base/MambaMasks.dat.svn-base b/TbUT/options_old/UT/.svn/text-base/MambaMasks.dat.svn-base
new file mode 100644
index 0000000..96c51ca
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/text-base/MambaMasks.dat.svn-base
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options_old/UT/.svn/text-base/MambaMasksSecond.dat.svn-base b/TbUT/options_old/UT/.svn/text-base/MambaMasksSecond.dat.svn-base
new file mode 100644
index 0000000..32e2c49
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/text-base/MambaMasksSecond.dat.svn-base
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options_old/UT/.svn/text-base/Masks_DTypeSensor.dat.svn-base b/TbUT/options_old/UT/.svn/text-base/Masks_DTypeSensor.dat.svn-base
new file mode 100644
index 0000000..5485528
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/text-base/Masks_DTypeSensor.dat.svn-base
@@ -0,0 +1,512 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options_old/UT/.svn/text-base/noise_Mamba.dat.svn-base b/TbUT/options_old/UT/.svn/text-base/noise_Mamba.dat.svn-base
new file mode 100644
index 0000000..02a1490
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/text-base/noise_Mamba.dat.svn-base
@@ -0,0 +1 @@
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 107.127689 25.305770 24.985735 23.880182 22.809866 23.103255 21.446864 24.188582 23.685522 22.460031 23.555169 26.122744 22.838222 25.087562 22.850856 26.304380 23.125743 23.201400 22.981947 22.458851 22.031775 75.466407 51.881567 46.426626 47.246870 50.250365 50.780563 47.397003 50.889006 44.839078 59.207575 54.965865 114.590228 52.238674 49.750998 48.155621 47.201067 49.133314 57.518032 67.569805 45.230984 46.673350 45.512254 45.617092 45.259825 45.733567 43.473456 43.722568 46.309360 48.914275 46.195759 48.450691 46.991445 52.781011 44.938163 46.455350 48.689499 45.403610 45.369944 42.134903 49.988984 49.633555 48.905178 44.971312 102.454547 43.896938 46.025610 39.809658 48.892613 43.968920 46.158579 48.159849 45.339528 42.081082 44.699937 43.227861 47.410931 41.160049 40.516874 44.124118 44.146963 46.627116 46.580809 43.070769 44.394065 42.607589 40.539213 43.251907 41.822410 45.898057 42.565037 44.062626 45.326879 44.702859 42.397044 41.252848 88.335221 41.643967 34.608467 41.525864 46.433712 48.705537 48.037901 40.895212 44.268060 42.162424 50.315707 41.441086 44.912960 43.003265 43.192740 42.952157 41.882323 44.014815 47.021833 45.965268 47.058266 45.766898 47.100425 45.208550 45.255262 49.039370 45.584677 46.038130 48.700468 45.034562 48.017172 37.116766 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 103.574529 49.603625 40.932967 44.120129 46.989088 47.289385 42.539289 39.679308 44.850751 38.851602 40.150803 39.946870 41.222906 43.960259 42.801704 37.360752 46.740100 42.473749 42.270202 43.682044 40.628559 40.139477 41.239218 39.108411 42.487292 43.201841 45.324183 40.450401 42.599853 43.263448 45.212560 44.764607 93.965153 42.923984 39.283722 39.083817 39.157311 42.328685 42.607923 38.564660 38.176196 42.152569 41.570047 39.143071 43.732281 38.429395 42.671582 38.889019 39.934366 38.649476 40.492826 39.350685 40.119143 41.312342 40.456242 42.077608 42.515644 42.268116 36.987452 37.506325 43.455469 40.407518 42.938532 42.798971 100.449464 40.856808 41.654939 42.548901 42.424191 40.898803 44.610357 44.984962 43.038145 40.748126 40.054942 41.821774 45.159960 44.908427 38.535427 40.479968 45.914416 46.386506 40.581955 40.034090 40.590609 40.195188 40.987605 58.823488 57.836143 42.323127 43.008627 42.873627 45.115518 44.816727 43.700261 40.807038 90.034575 53.500508 52.928495 52.112731 51.841441 48.424681 64.076780 55.632418 58.952640 88.941295 30.695698 25.107800 21.129922 24.741665 23.513068 23.950656 24.211989 22.534383 24.610810 24.665741 24.676102 23.380582 22.372076 25.319500 24.445932 25.051063 23.579970 23.809439 26.151015 25.114798 26.635690 26.701423 
\ No newline at end of file
diff --git a/TbUT/options_old/UT/.svn/text-base/ped_mamba.dat.svn-base b/TbUT/options_old/UT/.svn/text-base/ped_mamba.dat.svn-base
new file mode 100644
index 0000000..7e91540
--- /dev/null
+++ b/TbUT/options_old/UT/.svn/text-base/ped_mamba.dat.svn-base
@@ -0,0 +1 @@
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 253.303620 182.152255 113.621122 171.792383 120.250645 126.309957 75.423440 102.072392 114.725425 82.405370 151.940059 84.144931 71.917179 118.425014 117.137358 84.390779 75.015043 90.755132 65.461158 46.014122 64.344552 80.897262 112.127927 54.915623 45.818448 52.950238 16.700947 71.737650 14.800828 133.171107 68.749285 64.216343 -3.042604 -50.037095 -13.973598 -8.117553 22.098067 -25.182776 -7.966707 7.813575 6.690435 21.166485 -6.230388 10.299291 -0.725338 -47.185526 -15.555366 35.919805 -14.279422 -5.116494 -11.734951 -11.662071 -19.722573 43.261414 -62.580983 -7.627199 -28.002529 -8.330377 -3.950406 -28.021400 -19.728195 7.892501 -31.709001 41.948884 -124.596325 -102.222637 -87.755193 -87.414674 -89.709446 -73.812742 -80.833287 -38.950896 -74.193490 -117.918792 -75.621606 -65.111905 -63.711267 -41.983475 -17.406442 -63.364378 -64.100100 -47.427178 -32.967984 -60.556476 -18.430178 -62.281692 -60.745267 -67.925346 -41.166868 -12.956771 -46.470189 -45.835735 -55.578225 -38.468060 -57.497110 -20.651953 -67.414970 -53.458051 -63.707500 -29.066766 -15.844467 -49.081892 -61.699898 -24.109353 -4.554722 -6.583131 -2.976649 -31.208461 -12.522903 21.183791 -5.809948 1.467180 -17.374387 2.076994 20.293797 14.632401 -25.909328 4.606503 -11.754167 -14.686661 2.097853 -5.521749 -33.690440 10.447020 -15.810531 -29.106253 -27.956672 -23.200000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 143.993046 115.828224 109.673023 106.361857 115.790176 82.309432 72.677026 58.555909 104.655509 102.352075 110.826122 93.752839 28.154396 61.213051 107.529156 92.244758 63.700139 60.831653 29.173439 31.680749 40.900467 30.245755 18.732808 70.098913 8.429895 14.924629 11.211726 8.837123 -3.912452 14.362007 -8.325015 59.556553 -121.673447 -83.755947 -72.989147 -47.662903 -102.619719 -70.219704 -124.456764 -52.542638 -82.776284 -106.094290 -96.277340 -94.058599 -53.445471 -87.519127 -56.428337 -55.483802 -65.867732 -88.360121 -87.809210 -88.161892 -113.359361 -74.942836 -81.374053 -96.570768 -92.027202 -81.096345 -78.035250 -92.508416 -105.824966 -92.563379 -121.485072 9.250579 -39.369626 -90.742052 -35.971429 16.150572 -36.636056 -21.913411 -22.966341 -18.654684 -16.591379 -35.352666 -38.975838 0.388029 -25.779884 -32.410839 -24.350973 10.411679 2.537695 -28.243678 -5.281909 11.206816 -31.605753 -40.174068 -31.377332 -21.089011 -13.557339 -42.849654 -23.016646 -55.255153 -24.170208 4.896151 -69.356790 58.576026 -198.837919 -156.184179 -168.412828 -110.136174 -175.706841 -176.130134 -167.096479 -119.977369 -167.642404 -136.715376 -121.941747 -144.694214 -112.558623 -142.421387 -152.528190 -177.043934 -136.622046 -175.270575 -163.614580 -132.154191 -163.317129 -135.253817 -143.470432 -129.417464 -175.972739 -132.394553 -177.009714 -148.318405 -144.174653 -145.692359 -161.386920 -50.137176 
\ No newline at end of file
diff --git a/TbUT/options_old/UT/ChannelMask_NO.dat b/TbUT/options_old/UT/ChannelMask_NO.dat
new file mode 100644
index 0000000..9e77e64
--- /dev/null
+++ b/TbUT/options_old/UT/ChannelMask_NO.dat
@@ -0,0 +1,128 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options_old/UT/MambaMasks.dat b/TbUT/options_old/UT/MambaMasks.dat
new file mode 100644
index 0000000..5485528
--- /dev/null
+++ b/TbUT/options_old/UT/MambaMasks.dat
@@ -0,0 +1,512 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options_old/UT/MambaMasksSecond.dat b/TbUT/options_old/UT/MambaMasksSecond.dat
new file mode 100644
index 0000000..32e2c49
--- /dev/null
+++ b/TbUT/options_old/UT/MambaMasksSecond.dat
@@ -0,0 +1,512 @@
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
diff --git a/TbUT/options_old/UT/Masks_DTypeSensor.dat b/TbUT/options_old/UT/Masks_DTypeSensor.dat
new file mode 100644
index 0000000..5485528
--- /dev/null
+++ b/TbUT/options_old/UT/Masks_DTypeSensor.dat
@@ -0,0 +1,512 @@
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
+1
diff --git a/TbUT/options_old/UT/Pedestal-BoardA6.dat b/TbUT/options_old/UT/Pedestal-BoardA6.dat
new file mode 100644
index 0000000..75edf84
--- /dev/null
+++ b/TbUT/options_old/UT/Pedestal-BoardA6.dat
@@ -0,0 +1 @@
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 72 141 65 62 63 47 64 59 47 20 41 73 44 108 45 57 41 -16 19 37 37 32 39 7 25 18 0 11 3 -10 -17 -4 -92 -67 -137 -96 -127 -73 -75 -100 -35 -99 -116 -127 -109 -94 -122 -126 -137 -109 -87 -79 -147 -110 -112 -142 -71 -155 -105 -125 -85 -106 -150 -143 -151 -157 -155 -80 -137 -68 -97 -91 -118 -147 -108 -113 -121 -98 -116 -76 -166 -94 -111 -150 -135 -156 -110 -142 -136 -156 -169 -127 -174 -177 -154 -194 -261 -237 -247 -215 -280 -208 -250 -283 -270 -280 -259 -234 -274 -249 -251 -266 -258 -209 -234 -259 -254 -219 -258 -235 -237 -202 -243 -262 -265 -226 -290 -191 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 82 106 82 87 55 91 79 77 2 79 81 67 42 51 67 96 61 37 100 74 69 44 67 68 60 49 49 51 30 76 49 68 -14 8 -1 51 -25 -17 -29 22 -13 -20 -4 6 -44 -18 -26 2 -46 27 16 36 -3 -32 -1 -8 28 3 -17 -9 14 -19 -23 0 157 192 208 217 191 148 178 192 163 219 177 183 172 217 200 183 218 226 218 208 207 232 203 203 245 211 225 247 256 267 277 253 185 128 151 181 187 195 177 199 170 172 241 249 261 250 249 253 220 282 266 257 280 249 260 273 251 303 291 283 305 279 227 256 
\ No newline at end of file
diff --git a/TbUT/options_old/UT/noise_Mamba.dat b/TbUT/options_old/UT/noise_Mamba.dat
new file mode 100644
index 0000000..7254093
--- /dev/null
+++ b/TbUT/options_old/UT/noise_Mamba.dat
@@ -0,0 +1 @@
+16.443099 13.193289 12.950647 12.821843 13.166027 12.834809 12.817079 12.885629 12.907046 12.713512 12.790404 13.963880 12.982493 12.773903 12.863360 12.802765 12.882545 12.905185 12.908740 12.975181 12.830030 12.874429 12.861911 12.969083 12.961495 12.963663 12.955141 13.050247 13.051989 12.862946 13.011051 13.415043 14.483053 12.654427 12.682875 12.664466 12.720304 12.640789 12.540067 12.561181 12.661801 12.525034 12.471332 12.651835 12.624463 12.467904 12.583444 12.664664 12.665857 12.569381 12.532346 12.663693 12.636954 12.579929 12.574038 12.699557 12.664214 12.644402 12.616870 12.696810 12.698144 12.624747 12.675525 13.373671 15.072119 12.554015 12.461536 12.611592 12.544694 12.499371 12.441884 12.577233 12.477621 12.497343 12.495563 12.547332 12.538141 12.484496 12.441729 12.492193 12.543993 12.445567 12.418525 12.543367 12.674742 12.333063 12.503675 12.581786 12.645116 12.463940 12.481416 12.529399 12.752690 12.501192 12.572271 13.123135 14.514122 12.586903 12.447467 12.675817 12.406816 12.383618 12.440933 12.581525 12.450897 12.431133 12.300807 12.494803 12.290991 12.323919 12.356255 12.402751 12.377323 12.383318 12.279554 12.400002 12.358235 12.363867 12.306762 12.385325 12.415021 12.350167 12.456869 12.452115 12.833146 12.686045 13.392981 15.256822 16.608174 15.400472 15.252905 15.833716 15.333711 15.619133 15.466129 16.027050 15.355026 15.769942 15.470431 16.164993 15.269211 15.823117 15.452221 16.224807 15.289596 15.905531 15.509352 16.105216 15.440977 15.627334 14.931305 37.452919 35.263317 29.926536 29.733003 28.161070 28.968853 27.405457 27.375789 25.941408 25.874566 23.272458 23.034951 20.942954 21.304632 19.044423 18.937443 17.400644 17.978481 16.364828 16.236486 15.331526 15.659058 15.324962 15.225549 15.888165 15.165131 15.503388 15.246128 15.770901 15.018014 15.625554 14.955887 15.669243 15.089604 15.813680 15.223866 15.965795 15.178305 15.568273 15.146844 16.577064 19.957548 18.245473 18.668895 18.438014 19.696896 19.399771 20.788361 20.613980 22.869114 22.689886 24.091705 23.954872 26.328031 25.998132 27.512261 27.260141 29.853472 29.566900 30.932857 30.032534 32.955744 36.884078 35.364159 21.943743 23.376737 24.410510 23.782546 24.918588 23.308607 24.271959 23.844755 25.458372 14.931995 12.214062 12.097610 12.273424 12.058621 12.076897 12.110082 12.197866 11.974590 12.047368 11.915614 12.093908 11.962832 11.970010 11.899254 11.919361 11.909149 11.955227 11.756961 11.922979 11.928575 11.805932 11.985602 11.838587 12.005138 11.844803 11.992592 11.868767 12.230979 12.035032 12.748307 14.975670 14.926628 12.813435 12.611539 12.546126 12.675251 12.558287 12.416448 12.542910 12.599661 12.479327 12.490969 12.570800 12.507634 12.510272 12.556891 12.615025 12.567228 12.548641 12.393263 12.604307 12.504385 12.455802 12.417695 12.565925 12.540184 12.471343 12.423790 12.596315 12.531756 12.599209 12.496071 13.256789 13.857603 12.742075 12.152970 11.937777 12.266230 12.091642 12.007400 12.112897 12.206254 12.036522 11.999425 12.014673 12.089994 11.998142 11.874883 11.885265 12.015681 11.931032 12.008625 12.176415 12.048192 11.985447 11.988482 12.084985 12.042775 11.946698 12.032350 12.129353 12.043096 11.975404 12.017046 12.671563 14.361766 12.026107 11.772023 11.978632 11.880026 11.746553 11.795673 11.943794 11.919713 11.764019 11.905251 11.794778 11.865954 11.847433 11.743953 11.796961 11.811123 11.741076 11.798341 11.757666 11.864766 11.677847 11.718238 11.688892 11.806459 11.643390 11.740716 11.698465 11.879864 11.773268 11.717077 12.384588 13.974585 12.116857 12.032091 12.162355 11.902358 11.965747 11.885363 12.050611 12.047725 11.817888 11.882709 11.977875 11.959624 11.846653 11.857371 11.954973 11.833957 11.844525 11.821876 11.898875 11.883727 11.802975 11.881517 11.880532 11.888958 11.903077 11.863916 11.905809 12.069963 11.896538 12.426429 14.427074 15.668681 13.440498 13.272930 13.592451 13.294337 13.386235 13.205670 13.738804 13.164153 13.573987 13.189284 13.685009 13.198155 13.472102 13.222696 13.723976 13.037285 13.455259 13.219363 13.781073 13.070996 13.456701 12.898163 28.562760 23.600184 20.238816 20.856976 20.028909 21.037350 20.118543 20.739019 20.526563 16.835433 14.886744 14.845183 14.847684 15.297854 14.699444 14.906545 14.678621 15.030141 14.727378 15.256113 15.186889 15.132177 14.921737 15.025421 14.965638 15.005418 14.865674 14.964164 15.239263 15.216853 15.365506 15.176024 15.464087 15.919782 15.739133 15.798457 15.762958 15.895321 15.911722 15.701604 16.377460 20.156768 18.246597 20.278418 17.930410 18.615015 18.125153 18.348365 18.211582 18.622046 18.150965 18.423765 17.991298 18.587109 17.824586 17.968703 17.406766 17.968411 19.771454 18.227221 18.892258 17.276299 22.912275 29.732611 16.407796 16.885892 17.436233 17.142420 17.768061 16.972359 17.449896 17.127779 17.983003 14.095299 11.817575 11.609907 11.867619 11.689760 11.728866 11.646506 11.857059 11.676609 11.659377 11.543763 11.823550 11.634797 11.519411 11.552273 11.712009 11.627698 11.554121 11.497576 11.526783 11.531604 11.537981 11.505323 11.587578 11.633662 11.593422 11.630269 11.611219 11.938662 11.816198 12.330371 14.072595 
\ No newline at end of file
diff --git a/TbUT/options_old/UT/ped_mamba.dat b/TbUT/options_old/UT/ped_mamba.dat
new file mode 100644
index 0000000..7e91540
--- /dev/null
+++ b/TbUT/options_old/UT/ped_mamba.dat
@@ -0,0 +1 @@
+0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 253.303620 182.152255 113.621122 171.792383 120.250645 126.309957 75.423440 102.072392 114.725425 82.405370 151.940059 84.144931 71.917179 118.425014 117.137358 84.390779 75.015043 90.755132 65.461158 46.014122 64.344552 80.897262 112.127927 54.915623 45.818448 52.950238 16.700947 71.737650 14.800828 133.171107 68.749285 64.216343 -3.042604 -50.037095 -13.973598 -8.117553 22.098067 -25.182776 -7.966707 7.813575 6.690435 21.166485 -6.230388 10.299291 -0.725338 -47.185526 -15.555366 35.919805 -14.279422 -5.116494 -11.734951 -11.662071 -19.722573 43.261414 -62.580983 -7.627199 -28.002529 -8.330377 -3.950406 -28.021400 -19.728195 7.892501 -31.709001 41.948884 -124.596325 -102.222637 -87.755193 -87.414674 -89.709446 -73.812742 -80.833287 -38.950896 -74.193490 -117.918792 -75.621606 -65.111905 -63.711267 -41.983475 -17.406442 -63.364378 -64.100100 -47.427178 -32.967984 -60.556476 -18.430178 -62.281692 -60.745267 -67.925346 -41.166868 -12.956771 -46.470189 -45.835735 -55.578225 -38.468060 -57.497110 -20.651953 -67.414970 -53.458051 -63.707500 -29.066766 -15.844467 -49.081892 -61.699898 -24.109353 -4.554722 -6.583131 -2.976649 -31.208461 -12.522903 21.183791 -5.809948 1.467180 -17.374387 2.076994 20.293797 14.632401 -25.909328 4.606503 -11.754167 -14.686661 2.097853 -5.521749 -33.690440 10.447020 -15.810531 -29.106253 -27.956672 -23.200000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 143.993046 115.828224 109.673023 106.361857 115.790176 82.309432 72.677026 58.555909 104.655509 102.352075 110.826122 93.752839 28.154396 61.213051 107.529156 92.244758 63.700139 60.831653 29.173439 31.680749 40.900467 30.245755 18.732808 70.098913 8.429895 14.924629 11.211726 8.837123 -3.912452 14.362007 -8.325015 59.556553 -121.673447 -83.755947 -72.989147 -47.662903 -102.619719 -70.219704 -124.456764 -52.542638 -82.776284 -106.094290 -96.277340 -94.058599 -53.445471 -87.519127 -56.428337 -55.483802 -65.867732 -88.360121 -87.809210 -88.161892 -113.359361 -74.942836 -81.374053 -96.570768 -92.027202 -81.096345 -78.035250 -92.508416 -105.824966 -92.563379 -121.485072 9.250579 -39.369626 -90.742052 -35.971429 16.150572 -36.636056 -21.913411 -22.966341 -18.654684 -16.591379 -35.352666 -38.975838 0.388029 -25.779884 -32.410839 -24.350973 10.411679 2.537695 -28.243678 -5.281909 11.206816 -31.605753 -40.174068 -31.377332 -21.089011 -13.557339 -42.849654 -23.016646 -55.255153 -24.170208 4.896151 -69.356790 58.576026 -198.837919 -156.184179 -168.412828 -110.136174 -175.706841 -176.130134 -167.096479 -119.977369 -167.642404 -136.715376 -121.941747 -144.694214 -112.558623 -142.421387 -152.528190 -177.043934 -136.622046 -175.270575 -163.614580 -132.154191 -163.317129 -135.253817 -143.470432 -129.417464 -175.972739 -132.394553 -177.009714 -148.318405 -144.174653 -145.692359 -161.386920 -50.137176 
\ No newline at end of file
diff --git a/TbUT/options_old/UT/test.dat b/TbUT/options_old/UT/test.dat
new file mode 100644
index 0000000..b7bb230
--- /dev/null
+++ b/TbUT/options_old/UT/test.dat
@@ -0,0 +1 @@
+-142 -190 -156 -135 -117 -137 -148 -130 -163 -139 -135 -143 -144 -111 -113 -140 -130 -116 -104 -89 -124 -130 -124 -136 -98 -100 -116 -131 -122 -138 -117 -140 -52 34 33 23 16 21 3 8 48 36 -4 13 13 -2 20 18 37 16 41 40 26 20 33 16 36 73 28 17 43 -25 4 -8 -19 -3 27 1 43 9 -3 26 27 3 9 22 26 19 13 37 48 39 49 17 53 31 42 38 50 51 45 61 78 1 17 33 26 97 66 90 100 105 98 95 93 137 97 98 125 103 115 109 126 103 133 118 136 116 106 131 100 115 99 108 112 73 87 66 30 5 27 44 58 2 33 29 -2 21 38 35 17 54 27 27 18 31 45 34 64 50 56 49 53 33 27 73 1 65 54 2 -62 -63 -57 -45 -29 -73 -65 -74 -61 -78 -60 -89 -59 -61 -73 -44 -48 -72 -40 -59 -71 -52 -69 -65 -55 -34 -87 -43 -50 -80 -57 -102 -4 21 -17 10 3 19 -21 -19 4 15 1 19 9 19 30 28 15 19 15 5 13 -4 21 36 19 10 29 62 43 30 -1 12 71 137 135 137 138 162 131 120 144 129 149 156 151 130 148 104 132 171 150 158 131 151 169 144 128 131 134 158 134 153 105 112 64 84 88 95 104 82 76 93 86 87 92 63 81 118 118 117 105 115 109 86 92 59 106 54 87 71 114 87 107 90 89 83 -54 -25 -18 -31 -8 -14 -17 4 -15 -10 -16 -30 -14 -13 -30 -38 -9 -8 0 17 -7 1 15 10 -7 11 -3 17 9 16 13 -36 -53 -38 -30 -10 -11 -29 -31 -26 -27 -42 -20 -20 -23 -8 -42 -16 -16 -26 -26 -13 -29 -24 -52 -23 -39 -39 -22 -22 -23 5 -40 -56 -48 -14 8 -1 -9 -10 24 5 13 -6 -4 -3 13 -2 -3 -12 -3 -21 15 -2 6 37 18 14 20 9 24 -6 -11 11 -29 1 -23 -8 20 -23 -7 -14 -14 -9 3 6 1 -10 23 -16 -12 -30 -12 -7 35 25 25 17 -4 16 -17 23 4 -8 -2 -22 -13 7 -24 2 2 7 30 10 5 13 0 -4 29 38 17 1 22 18 17 19 56 16 20 32 11 15 8 35 12 22 26 15 17 18 -58 -26 -3 14 15 -9 8 -4 21 32 26 21 25 3 7 17 8 -16 4 7 12 14 13 -5 30 19 25 45 66 27 17 32 -36 32 5 7 17 32 16 31 35 12 9 28 33 1 18 48 32 33 38 30 27 35 28 5 37 47 52 12 36 24 23 33 
\ No newline at end of file
diff --git a/TbUT/options_old/python/.svn/all-wcprops b/TbUT/options_old/python/.svn/all-wcprops
new file mode 100644
index 0000000..899fac0
--- /dev/null
+++ b/TbUT/options_old/python/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 63
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/options/python
+END
+TbUTClusterizator.py
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/options/python/TbUTClusterizator.py
+END
+TbUTPedestalRunner.py
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/194849/Kepler/trunk/Tb/TbUT/options/python/TbUTPedestalRunner.py
+END
+Timer.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/191831/Kepler/trunk/Tb/TbUT/options/python/Timer.py
+END
diff --git a/TbUT/options_old/python/.svn/entries b/TbUT/options_old/python/.svn/entries
new file mode 100644
index 0000000..aa74bfc
--- /dev/null
+++ b/TbUT/options_old/python/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/options/python
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbUTClusterizator.py
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+2d1d3e58685a5ba242e96cae8d8066b4
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4828
+
+TbUTPedestalRunner.py
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+2b0baeae1a7509142f33b10085a0651f
+2015-09-10T16:19:06.475049Z
+194849
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2852
+
+Timer.py
+file
+
+
+
+
+2016-03-16T13:50:24.000000Z
+dfbebc98af7c4503a451033a4316d7f8
+2015-07-14T15:46:54.883477Z
+191831
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+326
+
diff --git a/TbUT/options_old/python/.svn/text-base/TbUTClusterizator.py.svn-base b/TbUT/options_old/python/.svn/text-base/TbUTClusterizator.py.svn-base
new file mode 100644
index 0000000..e2f41e8
--- /dev/null
+++ b/TbUT/options_old/python/.svn/text-base/TbUTClusterizator.py.svn-base
@@ -0,0 +1,121 @@
+__author__ = 'ja'
+
+
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataMonitor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+from Configurables import TbUT__PedestalSubtractorDataMonitorAlgorithm as pedestalMonitor
+from Configurables import TbUT__CommonModeSubtractorAlgorithm  as CMS
+from Configurables import TbUT__CommonModeSubtractorDataMonitorAlgorithm  as CMSMonitor
+from Configurables import TbUT__ClusterCreatorAlgorithm as ClusterCreator
+from Configurables import TbUT__ClusterCreatorDataMonitorAlgorithm as ClusterCreatorMonitor
+from Configurables import TbUT__NTupleCreator as nTupleCreator
+
+from Timer import timer
+
+class TbUTClusterizator:
+    def __init__(self):
+        self.isAType=True
+
+    @property
+    def eventNumberDisplay(self):
+        return self.eventNumberDisplay
+    @eventNumberDisplay.setter
+    def eventNumberDisplay(self,value):
+        self.eventNumberDisplay=value
+
+    @property
+    def pedestalInputData(self):
+        return  self.pedestalInputData
+    @pedestalInputData.setter
+    def pedestalInputData(self,value):
+        self.pedestalInputData=value
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self.isAType
+    @isAType.setter
+    def isAType(self, value):
+        self.isAType=value
+
+    @property
+    def sensorType(self):
+        return self.sensorType
+    @sensorType.setter
+    def sensorType(self, value):
+        self.sensorType=value
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @timer
+    def runClusterization(self):
+        self._prepareStandaloneClusterization()
+        config=self._runClusterization
+        appendPostConfigAction(config)
+
+
+
+    def _prepareStandaloneClusterization(self):
+        # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        outputName=self.inputData[:-4]+".root"
+        outputName=outputName[outputName.rfind("/")+1:]
+        Kepler().HistogramFile=outputName
+        outputTupleName=self.inputData[:-4]+"_Tuple.root"
+        outputTupleName=outputTupleName[outputTupleName.rfind("/")+1:]
+        Kepler().TupleFile=outputTupleName
+
+
+    def _runClusterization(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UT")
+
+        rawDataReader().inputData=self.inputData
+        rawDataReader().isAType=self.isAType
+        rawDataMonitor().displayEventNumber=self.eventNumberDisplay
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/Masks_DTypeSensor.dat"
+        pedestalSubtractor().PedestalInputFile=self.pedestalInputData
+        pedestalSubtractor().FollowingOption='file'
+        pedestalSubtractor().treningEntry=1
+        pedestalMonitor().displayEventNumber=self.eventNumberDisplay
+        CMS().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/Masks_DTypeSensor.dat"
+        CMS().NoiseOutputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        CMSMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreator().NoiseInputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        ClusterCreator().LowThreshold=2.5
+        ClusterCreator().HighThreshold=3
+        ClusterCreator().sensorType=self.sensorType
+        ClusterCreatorMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreatorMonitor().sensorType=self.sensorType
+        nTupleCreator().StoreEventNumber=900000
+        nTupleCreator().WriteRaw=False
+        nTupleCreator().WriteHeader=True
+        nTupleCreator().WritePedestal=False
+        nTupleCreator().WriteCMS=False
+        seq_UT_data_processing.Members = [rawDataReader(), rawDataMonitor() ,pedestalSubtractor(),pedestalMonitor(), CMS(),
+                                          CMSMonitor(), ClusterCreator(),ClusterCreatorMonitor(),nTupleCreator()]
+        keplerSeq.Members+=[seq_UT_data_processing]
diff --git a/TbUT/options_old/python/.svn/text-base/TbUTPedestalRunner.py.svn-base b/TbUT/options_old/python/.svn/text-base/TbUTPedestalRunner.py.svn-base
new file mode 100644
index 0000000..bbc9839
--- /dev/null
+++ b/TbUT/options_old/python/.svn/text-base/TbUTPedestalRunner.py.svn-base
@@ -0,0 +1,82 @@
+__author__ = 'ja'
+from Gaudi.Configuration import *
+from Configurables import ExceptionSvc
+
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataReaderMoniotor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+
+from Timer import timer
+
+class TbUTPedestalRunner:
+    def __init__(self):
+        pass
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @property
+    def pedestalOutputData(self):
+        return  self.pedestalOutputData
+    @pedestalOutputData.setter
+    def pedestalOutputData(self,value):
+        expectedDirectory ="$KEPLERROOT/../TbUT/options/UT/"
+        if not value.startswith(expectedDirectory):
+            raise AttributeError("The pedestal file have to be stored in directory: "+expectedDirectory)
+        self.pedestalOutputData=value
+
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self._isAType
+    @isAType.setter
+    def isAType(self,value):
+        self._isAType=value
+
+    @timer
+    def runPedestals(self):
+        self._preparePedestalRun()
+        config= self._runGaudi
+        appendPostConfigAction(config)
+
+
+    def _preparePedestalRun(self):
+         # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        Kepler().HistogramFile="MambaPedestal.root" # should be set more correctly
+
+    def _runGaudi(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UTPedestal")
+        rawDataReader().isAType=self.isAType
+        rawDataReader().inputData= self.inputData
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/MambaMasks.dat"
+        pedestalSubtractor().PedestalOutputFile=self.pedestalOutputData
+        pedestalSubtractor().treningEntry=15000
+
+
+        seq_UT_data_processing.Members =[rawDataReader(), rawDataReaderMoniotor() ,pedestalSubtractor()]
+        keplerSeq.Members+=[seq_UT_data_processing]
+
diff --git a/TbUT/options_old/python/.svn/text-base/Timer.py.svn-base b/TbUT/options_old/python/.svn/text-base/Timer.py.svn-base
new file mode 100644
index 0000000..d05e11e
--- /dev/null
+++ b/TbUT/options_old/python/.svn/text-base/Timer.py.svn-base
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+
+import time
+
+def timer(method):
+
+    def timed(*args, **kw):
+        startTime = time.time()
+        result = method(*args, **kw)
+        endTime = time.time()
+
+        print ('execution of %r  takes  %2.2f sec') % \
+              (method.__name__, endTime-startTime)
+        return result
+
+    return timed
\ No newline at end of file
diff --git a/TbUT/options_old/python/TbUTClusterizator.py b/TbUT/options_old/python/TbUTClusterizator.py
new file mode 100644
index 0000000..a4d242e
--- /dev/null
+++ b/TbUT/options_old/python/TbUTClusterizator.py
@@ -0,0 +1,121 @@
+__author__ = 'ja'
+
+
+from Gaudi.Configuration import *
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataMonitor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+from Configurables import TbUT__PedestalSubtractorDataMonitorAlgorithm as pedestalMonitor
+from Configurables import TbUT__CommonModeSubtractorAlgorithm  as CMS
+from Configurables import TbUT__CommonModeSubtractorDataMonitorAlgorithm  as CMSMonitor
+from Configurables import TbUT__ClusterCreatorAlgorithm as ClusterCreator
+from Configurables import TbUT__ClusterCreatorDataMonitorAlgorithm as ClusterCreatorMonitor
+from Configurables import TbUT__NTupleCreator as nTupleCreator
+
+from Timer import timer
+
+class TbUTClusterizator:
+    def __init__(self):
+        self.isAType=True
+
+    @property
+    def eventNumberDisplay(self):
+        return self.eventNumberDisplay
+    @eventNumberDisplay.setter
+    def eventNumberDisplay(self,value):
+        self.eventNumberDisplay=value
+
+    @property
+    def pedestalInputData(self):
+        return  self.pedestalInputData
+    @pedestalInputData.setter
+    def pedestalInputData(self,value):
+        self.pedestalInputData=value
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self.isAType
+    @isAType.setter
+    def isAType(self, value):
+        self.isAType=value
+
+    @property
+    def sensorType(self):
+        return self.sensorType
+    @sensorType.setter
+    def sensorType(self, value):
+        self.sensorType=value
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @timer
+    def runClusterization(self):
+        self._prepareStandaloneClusterization()
+        config=self._runClusterization
+        appendPostConfigAction(config)
+
+
+
+    def _prepareStandaloneClusterization(self):
+        # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        outputName=self.inputData[:-4]+".root"
+        outputName=outputName[outputName.rfind("/")+1:]
+        Kepler().HistogramFile=outputName
+        outputTupleName=self.inputData[:-4]+"_Tuple.root"
+        outputTupleName=outputTupleName[outputTupleName.rfind("/")+1:]
+        Kepler().TupleFile=outputTupleName
+
+
+    def _runClusterization(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UT")
+
+        rawDataReader().inputData=self.inputData
+        rawDataReader().isAType=self.isAType
+        rawDataMonitor().displayEventNumber=self.eventNumberDisplay
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/MambaMasks.dat"
+        pedestalSubtractor().PedestalInputFile=self.pedestalInputData
+        pedestalSubtractor().FollowingOption='file'
+        pedestalSubtractor().treningEntry=1
+        pedestalMonitor().displayEventNumber=self.eventNumberDisplay
+        CMS().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/MambaMasks.dat"
+        CMS().NoiseOutputFile="$KEPLERROOT/../TbUT/options/UT/noise_Mamba.dat"
+        CMSMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreator().NoiseInputFile="$KEPLERROOT/../TbUT/options/UT/test.dat"
+        ClusterCreator().LowThreshold=2.5
+        ClusterCreator().HighThreshold=3
+        ClusterCreator().sensorType=self.sensorType
+        ClusterCreatorMonitor().displayEventNumber=self.eventNumberDisplay
+        ClusterCreatorMonitor().sensorType=self.sensorType
+        nTupleCreator().StoreEventNumber=900000
+        nTupleCreator().WriteRaw=False
+        nTupleCreator().WriteHeader=True
+        nTupleCreator().WritePedestal=False
+        nTupleCreator().WriteCMS=False
+        seq_UT_data_processing.Members = [rawDataReader(), rawDataMonitor() ,pedestalSubtractor(),pedestalMonitor(), CMS(),
+                                          CMSMonitor(), ClusterCreator(),ClusterCreatorMonitor(),nTupleCreator()]
+        keplerSeq.Members+=[seq_UT_data_processing]
diff --git a/TbUT/options_old/python/TbUTClusterizator.pyc b/TbUT/options_old/python/TbUTClusterizator.pyc
new file mode 100644
index 0000000..0927902
--- /dev/null
+++ b/TbUT/options_old/python/TbUTClusterizator.pyc
Binary files differ
diff --git a/TbUT/options_old/python/TbUTPedestalRunner.py b/TbUT/options_old/python/TbUTPedestalRunner.py
new file mode 100644
index 0000000..bbc9839
--- /dev/null
+++ b/TbUT/options_old/python/TbUTPedestalRunner.py
@@ -0,0 +1,82 @@
+__author__ = 'ja'
+from Gaudi.Configuration import *
+from Configurables import ExceptionSvc
+
+from Configurables import Kepler
+
+from Configurables import TbUT__RawDataReaderAlgorithm as rawDataReader
+from Configurables import TbUT__RawDataMonitorAlgorithm as rawDataReaderMoniotor
+from Configurables import TbUT__PedestalSubtractorAlgorithm  as pedestalSubtractor
+
+from Timer import timer
+
+class TbUTPedestalRunner:
+    def __init__(self):
+        pass
+
+    @property
+    def inputData(self):
+        return self.inputData
+    @inputData.setter
+    def inputData(self,value):
+        self.inputData=value
+
+    @property
+    def pedestalOutputData(self):
+        return  self.pedestalOutputData
+    @pedestalOutputData.setter
+    def pedestalOutputData(self,value):
+        expectedDirectory ="$KEPLERROOT/../TbUT/options/UT/"
+        if not value.startswith(expectedDirectory):
+            raise AttributeError("The pedestal file have to be stored in directory: "+expectedDirectory)
+        self.pedestalOutputData=value
+
+    @property
+    def eventMax(self):
+        return self.eventNumber
+    @eventMax.setter
+    def eventMax(self,value):
+        self.eventMax=value
+
+    @property
+    def isAType(self):
+        return self._isAType
+    @isAType.setter
+    def isAType(self,value):
+        self._isAType=value
+
+    @timer
+    def runPedestals(self):
+        self._preparePedestalRun()
+        config= self._runGaudi
+        appendPostConfigAction(config)
+
+
+    def _preparePedestalRun(self):
+         # dummy aligment just to run Kepler
+        Kepler().PixelConfigFile = ["eos/lhcb/testbeam/velo/timepix3/July2014/RootFiles/Run1236/Conditions/PixelConfig.dat"]
+        Kepler().AlignmentFile = "eos/lhcb/testbeam/velo/timepix3/Oct2014/RootFiles/Run2176/Conditions/Alignment2176mille.dat"
+        Kepler().InputFiles =  ['eos/lhcb/testbeam/velo/timepix3/Oct2014/RawData/Run2176/']
+        Kepler().EvtMax = self.eventMax
+        Kepler().HistogramFile="MambaPedestal.root" # should be set more correctly
+
+    def _runGaudi(self):
+        keplerSeq = GaudiSequencer("KeplerSequencer")
+        seq_moni = GaudiSequencer("Monitoring")
+        seq_moni.Members = []
+        seq_out = GaudiSequencer('Output')
+        seq_moni.Members = []
+        seq_tel = GaudiSequencer("Telescope")
+        seq_tel.Members = []
+
+        seq_UT_data_processing=GaudiSequencer("UTPedestal")
+        rawDataReader().isAType=self.isAType
+        rawDataReader().inputData= self.inputData
+        pedestalSubtractor().ChannelMaskInputLocation= "$KEPLERROOT/../TbUT/options/UT/MambaMasks.dat"
+        pedestalSubtractor().PedestalOutputFile=self.pedestalOutputData
+        pedestalSubtractor().treningEntry=15000
+
+
+        seq_UT_data_processing.Members =[rawDataReader(), rawDataReaderMoniotor() ,pedestalSubtractor()]
+        keplerSeq.Members+=[seq_UT_data_processing]
+
diff --git a/TbUT/options_old/python/TbUTPedestalRunner.pyc b/TbUT/options_old/python/TbUTPedestalRunner.pyc
new file mode 100644
index 0000000..5307cab
--- /dev/null
+++ b/TbUT/options_old/python/TbUTPedestalRunner.pyc
Binary files differ
diff --git a/TbUT/options_old/python/Timer.py b/TbUT/options_old/python/Timer.py
new file mode 100644
index 0000000..d05e11e
--- /dev/null
+++ b/TbUT/options_old/python/Timer.py
@@ -0,0 +1,16 @@
+__author__ = 'ja'
+
+import time
+
+def timer(method):
+
+    def timed(*args, **kw):
+        startTime = time.time()
+        result = method(*args, **kw)
+        endTime = time.time()
+
+        print ('execution of %r  takes  %2.2f sec') % \
+              (method.__name__, endTime-startTime)
+        return result
+
+    return timed
\ No newline at end of file
diff --git a/TbUT/options_old/python/Timer.pyc b/TbUT/options_old/python/Timer.pyc
new file mode 100644
index 0000000..4863b2c
--- /dev/null
+++ b/TbUT/options_old/python/Timer.pyc
Binary files differ
diff --git a/TbUT/plots/AnalysisOutput_A6_300_6.root b/TbUT/plots/AnalysisOutput_A6_300_6.root
new file mode 100644
index 0000000..6da6623
--- /dev/null
+++ b/TbUT/plots/AnalysisOutput_A6_300_6.root
Binary files differ
diff --git a/TbUT/plots/AnalysisOutput_A6_50_3.root b/TbUT/plots/AnalysisOutput_A6_50_3.root
new file mode 100644
index 0000000..d01de0c
--- /dev/null
+++ b/TbUT/plots/AnalysisOutput_A6_50_3.root
Binary files differ
diff --git a/TbUT/plots/AnalysisOutput_M1_300_PA.root b/TbUT/plots/AnalysisOutput_M1_300_PA.root
new file mode 100644
index 0000000..72a18f2
--- /dev/null
+++ b/TbUT/plots/AnalysisOutput_M1_300_PA.root
Binary files differ
diff --git a/TbUT/plots/AnalysisOutput_M1_test_300_PA.root b/TbUT/plots/AnalysisOutput_M1_test_300_PA.root
new file mode 100644
index 0000000..9d65b7f
--- /dev/null
+++ b/TbUT/plots/AnalysisOutput_M1_test_300_PA.root
Binary files differ
diff --git a/TbUT/plots/DUTx_vs_TRKx.pdf b/TbUT/plots/DUTx_vs_TRKx.pdf
new file mode 100644
index 0000000..525cf20
--- /dev/null
+++ b/TbUT/plots/DUTx_vs_TRKx.pdf
Binary files differ
diff --git a/TbUT/plots/DUTx_vs_TRKx_color.pdf b/TbUT/plots/DUTx_vs_TRKx_color.pdf
new file mode 100644
index 0000000..bfde68d
--- /dev/null
+++ b/TbUT/plots/DUTx_vs_TRKx_color.pdf
Binary files differ
diff --git a/TbUT/plots/cluster_v_inter.pdf b/TbUT/plots/cluster_v_inter.pdf
new file mode 100644
index 0000000..265463d
--- /dev/null
+++ b/TbUT/plots/cluster_v_inter.pdf
Binary files differ
diff --git a/TbUT/plots/dut_clusters_event.pdf b/TbUT/plots/dut_clusters_event.pdf
new file mode 100644
index 0000000..7e8c01e
--- /dev/null
+++ b/TbUT/plots/dut_clusters_event.pdf
Binary files differ
diff --git a/TbUT/plots/eff_2d.pdf b/TbUT/plots/eff_2d.pdf
new file mode 100644
index 0000000..c3e99ce
--- /dev/null
+++ b/TbUT/plots/eff_2d.pdf
Binary files differ
diff --git a/TbUT/plots/eff_vs_stripPos.pdf b/TbUT/plots/eff_vs_stripPos.pdf
new file mode 100644
index 0000000..c6de186
--- /dev/null
+++ b/TbUT/plots/eff_vs_stripPos.pdf
Binary files differ
diff --git a/TbUT/plots/eff_vs_x.pdf b/TbUT/plots/eff_vs_x.pdf
new file mode 100644
index 0000000..f048569
--- /dev/null
+++ b/TbUT/plots/eff_vs_x.pdf
Binary files differ
diff --git a/TbUT/plots/eff_vs_y.pdf b/TbUT/plots/eff_vs_y.pdf
new file mode 100644
index 0000000..022d7e6
--- /dev/null
+++ b/TbUT/plots/eff_vs_y.pdf
Binary files differ
diff --git a/TbUT/plots/noise_vs_channel.pdf b/TbUT/plots/noise_vs_channel.pdf
new file mode 100644
index 0000000..dba074b
--- /dev/null
+++ b/TbUT/plots/noise_vs_channel.pdf
Binary files differ
diff --git a/TbUT/plots/residual.pdf b/TbUT/plots/residual.pdf
new file mode 100644
index 0000000..094512c
--- /dev/null
+++ b/TbUT/plots/residual.pdf
Binary files differ
diff --git a/TbUT/scripts/.svn/all-wcprops b/TbUT/scripts/.svn/all-wcprops
new file mode 100644
index 0000000..d3632a1
--- /dev/null
+++ b/TbUT/scripts/.svn/all-wcprops
@@ -0,0 +1,125 @@
+K 25
+svn:wc:ra_dav:version-url
+V 56
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts
+END
+ExampleAnalysis.C
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197014/Kepler/trunk/Tb/TbUT/scripts/ExampleAnalysis.C
+END
+ClusterAna.C
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/ClusterAna.C
+END
+ExampleAnalysis.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/196947/Kepler/trunk/Tb/TbUT/scripts/ExampleAnalysis.h
+END
+ThresholdPlotter.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/194849/Kepler/trunk/Tb/TbUT/scripts/ThresholdPlotter.cpp
+END
+ClusterAna.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/ClusterAna.h
+END
+runClusterWithTrackAna.C
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/runClusterWithTrackAna.C
+END
+fastAnalysis.py
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197407/Kepler/trunk/Tb/TbUT/scripts/fastAnalysis.py
+END
+plotADCs.C
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/196459/Kepler/trunk/Tb/TbUT/scripts/plotADCs.C
+END
+AnalysisBase.C
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/AnalysisBase.C
+END
+ClusterWithTrackAna_README
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/205202/Kepler/trunk/Tb/TbUT/scripts/ClusterWithTrackAna_README
+END
+runClusterAnaLoop.C
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/runClusterAnaLoop.C
+END
+CMS.C
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/guest/lhcb/!svn/ver/196913/Kepler/trunk/Tb/TbUT/scripts/CMS.C
+END
+ClusterWithTrackAna.C
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/ClusterWithTrackAna.C
+END
+AnalysisBase.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/AnalysisBase.h
+END
+runExampleAnalysis.C
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/196910/Kepler/trunk/Tb/TbUT/scripts/runExampleAnalysis.C
+END
+AnalysisBase_Inputs.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/AnalysisBase_Inputs.h
+END
+runClusterAna.C
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/runClusterAna.C
+END
+ClusterWithTrackAna.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/204982/Kepler/trunk/Tb/TbUT/scripts/ClusterWithTrackAna.h
+END
+CMS.h
+K 25
+svn:wc:ra_dav:version-url
+V 62
+/guest/lhcb/!svn/ver/196913/Kepler/trunk/Tb/TbUT/scripts/CMS.h
+END
+ClusterWithTrackAna_Inputs.h
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/196821/Kepler/trunk/Tb/TbUT/scripts/ClusterWithTrackAna_Inputs.h
+END
diff --git a/TbUT/scripts/.svn/entries b/TbUT/scripts/.svn/entries
new file mode 100644
index 0000000..ff36024
--- /dev/null
+++ b/TbUT/scripts/.svn/entries
@@ -0,0 +1,673 @@
+10
+
+dir
+205225
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/scripts
+http://svn.cern.ch/guest/lhcb
+
+
+
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+incomplete
+4525493e-7705-40b1-a816-d608a930855b
+
+ExampleAnalysis.C
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+3a209eff9c131e2b4067ec0269869fe6
+2015-10-29T22:00:25.723550Z
+197014
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4908
+
+ClusterAna.C
+file
+205119
+
+
+
+2016-04-19T13:00:29.000000Z
+8ea3d479cad125024af90975de945106
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5249
+
+ExampleAnalysis.h
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+226d1bd81faf34f9dfd40cae7465137d
+2015-10-28T17:40:13.089520Z
+196947
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3931
+
+AddTrigTracks
+dir
+
+ClusterAna.h
+file
+205119
+
+
+
+2016-04-19T13:00:29.000000Z
+1838cce24910abace970ae4f6d02cba0
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+18865
+
+ThresholdPlotter.cpp
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+c502ab90cdf573bcd358abda1a4d87bd
+2015-09-10T16:19:06.475049Z
+194849
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2206
+
+fastAnalysis.py
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+a165c3939e93951adeb8dc7eb59b3659
+2015-11-10T11:44:52.528559Z
+197407
+mrudolph
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+17457
+
+runClusterWithTrackAna.C
+file
+205125
+
+
+
+
+923c933ff72eb2b2a4dfbab7a9a856e9
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+plotADCs.C
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+48fcf71e3cb23e47b098145cf3230d32
+2015-10-19T14:55:18.362934Z
+196459
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10237
+
+CalibAna
+dir
+
+TbUTAutomaticAnalyzer
+dir
+
+ClusterWithTrackAna_README
+file
+
+
+
+
+2016-04-22T09:43:00.000000Z
+374d283e60ab46b69e8d92b072109756
+2016-04-21T20:15:36.367866Z
+205202
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1650
+
+AnalysisBase.C
+file
+205119
+
+
+
+2016-04-21T12:52:23.000000Z
+ac1c4315e672df2526913c408377c578
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+31901
+
+runClusterAnaLoop.C
+file
+205119
+
+
+
+2016-04-19T13:00:29.000000Z
+687b702a3d9868b8481580e226d19fe6
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1367
+
+CMS.C
+file
+205119
+
+
+
+2016-04-20T10:56:19.000000Z
+3970c7504a514024a79b57691eaf3347
+2015-10-28T10:21:30.471902Z
+196913
+sblusk
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1429
+
+ClusterWithTrackAna.C
+file
+205119
+
+
+
+2016-04-19T13:00:29.000000Z
+04de890ef0a41bd94a9a52b9c189e778
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+48132
+
+AnalysisBase.h
+file
+205119
+
+
+
+2016-04-21T12:51:34.000000Z
+a9fe5515588e62a4918b9ed2a1f1cdf4
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4724
+
+runExampleAnalysis.C
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+01d4de9f7570d92fc28736a34b9dc967
+2015-10-27T20:29:23.347992Z
+196910
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+314
+
+AnalysisBase_Inputs.h
+file
+205119
+
+
+
+
+0536605bd7ed25a64aff384c8afcf19e
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+runClusterAna.C
+file
+205119
+
+
+
+2016-04-19T13:00:29.000000Z
+5a46da45e53a73e327079edb2a6cd295
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+181
+
+ClusterWithTrackAna.h
+file
+205119
+
+
+
+2016-04-19T13:00:29.000000Z
+cebe562686c20afb48ac8d36ff5afef8
+2016-04-19T12:35:14.133839Z
+204982
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+19782
+
+CMS.h
+file
+205119
+
+
+
+2016-04-20T10:52:50.000000Z
+67189f0bcfe539b0abd8b1d387433876
+2015-10-28T10:21:30.471902Z
+196913
+sblusk
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3622
+
+ClusterWithTrackAna_Inputs.h
+file
+205119
+
+
+
+2016-03-16T13:50:22.000000Z
+4f5fccf690eb4d22b162dc5940a666a2
+2015-10-26T14:27:04.706916Z
+196821
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+747
+
diff --git a/TbUT/scripts/.svn/prop-base/CMS.C.svn-base b/TbUT/scripts/.svn/prop-base/CMS.C.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/scripts/.svn/prop-base/CMS.C.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/scripts/.svn/prop-base/CMS.h.svn-base b/TbUT/scripts/.svn/prop-base/CMS.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/scripts/.svn/prop-base/CMS.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/scripts/.svn/prop-base/fastAnalysis.py.svn-base b/TbUT/scripts/.svn/prop-base/fastAnalysis.py.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/scripts/.svn/prop-base/fastAnalysis.py.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/scripts/.svn/text-base/AnalysisBase.C.svn-base b/TbUT/scripts/.svn/text-base/AnalysisBase.C.svn-base
new file mode 100644
index 0000000..e72ed80
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/AnalysisBase.C.svn-base
@@ -0,0 +1,995 @@
+//#define AnalysisBase_cxx
+#include "AnalysisBase.h"
+
+
+AnalysisBase::AnalysisBase(TTree *tree) : fChain(0) 
+{
+
+// Notes
+// For Rz alignment, one should SUBTRACT the slope found from the deltaX vs Y plot.
+// For Z alignment, one should ADD the slope found from the deltaX vs Y plot.
+// For Ry: If slope of DX vs X is negative (positive), reduce (increase) Ry
+//
+  //these have to be able to change so we have to make sure there is only 1 copy of them, so global scope would be bad news
+
+  minDistFromHole =  m_minDistFromHole;
+  holeSector = m_board.Contains("D") && (m_sector=="1" || m_sector=="2" || m_sector == "3");
+  if(!holeSector) minDistFromHole = -9999;
+  
+  stripPitch = 0.190;
+  z_DUT 			= 370; //This needs to be set for different boards
+  Rz 				= -0.0218;
+  Ry 				= 0.00;
+  dxWin 			= 0.25;
+  
+  xGloOff 		= -9.2;
+  yGloOff 		= -7.5;
+  xOff 			= -54.78;
+  correctForZRotation = true;
+  
+  channelOffset = 0.0;
+  xLeftHole = 999;
+  xRightHole = -999;
+  stripGap[0] = 0;
+  stripGap[1] = 0;
+  stripGap[2] = 0;
+  stripGap[3] = 0;
+  nDeadRegion = 0;
+  if(  m_board.Contains("D")) {
+    stripPitch = 0.095;
+    channelOffset = 512.0;
+    //stripGap[0]=19;     
+    //stripGap[1]=39;     
+    //stripGap[2]=58;     
+    //stripGap[3]=0;     
+
+    stripGap[0]=58;     
+    stripGap[1]=39;     
+    stripGap[2]=19;     
+    stripGap[3]=0;     
+
+    if(m_board.Contains("D5")) {
+      z_DUT = 1100.0;
+      //Rz = -0.0230;  
+    }else if(m_board.Contains("D7")) {
+      z_DUT = 1123.0;
+      if(m_sector=="5") z_DUT = 1087.0;
+      if(m_sector=="1") z_DUT = 1040.0;
+      //Ry = -0.008;  
+    }
+  }
+
+
+
+  yInt1[0] = 2.8; yInt1[1] = 3.4;
+  yInt2[0] = 3.4; yInt2[1] = 4.1;
+  yInt3[0] = 1.0; yInt3[1] = 2.3;   
+
+  if(m_board.Contains("A8")){
+    z_DUT = 1100.0;
+    Rz = -0.0286;
+    yInt1[0] = 1.8; yInt1[1] = 2.0;
+    yInt2[0] = 2.0; yInt2[1] = 2.4;
+    yInt3[0] = 1.0; yInt3[1] = 2.3;
+    if(m_sector=="3" || m_sector=="6") {
+      channelOffset = -128.0*2+22;
+    }else{
+      channelOffset = -128.0;
+    }
+    if(m_scanType.Contains("Angle")){
+      if(m_angle == "10") {
+        Ry = 9.3*(TMath::Pi()/180.0);
+        z_DUT = z_DUT - 18.0;
+      } else if(m_angle == "20") {
+        Ry = 19*(TMath::Pi()/180.0);
+        z_DUT = z_DUT - 18.0;
+      }      
+     
+    }    
+  }else if( m_board.Contains("A4")){
+    z_DUT = 381.0;     
+    Rz = -0.0238;
+    if(m_sector=="3" || m_sector=="6") {
+      channelOffset = -128.0*2.0+19;
+    }else{
+      channelOffset = -128.0;
+    }
+  }else if( m_board.Contains("A6")){
+    yInt1[0] = 2.5; yInt1[1] = 3.1;
+    yInt2[0] = 3.1; yInt2[1] = 3.7;
+    yInt3[0] = 1.0; yInt3[1] = 2.3;
+    if(m_sector=="3" || m_sector=="6") {
+      channelOffset = -128.0*2+22;
+    }else{
+      channelOffset = -128.0;
+    }    
+  }else if( m_board.Contains("A2") || m_board.Contains("A1")){
+    z_DUT = 310;
+    yInt1[0] = -5.0; yInt1[1] = -2.0;
+    yInt2[0] = -2.0; yInt2[1] = 1.0;
+    yInt3[0] = 1.0; yInt3[1] = 5.0;
+  }
+
+  // Board A1 alignment is really messed up for a few runs! ADHOC here!
+  if(m_board.Contains("A1")){// && (m_bias=="300" || m_bias=="350" || m_bias=="150" || m_bias==")){  
+    dxWin = 1.0;
+    correctForZRotation = false;
+  }
+   
+  holeQuadPar[0] = 0;
+  holeQuadPar[1] = 0;
+  holeQuadPar[2] = 0;
+  removeTracksInHole = removeTracksInHoleDef;
+  // Only look to remove tacks from hole area if D-type and in sectors 1, 2, or 3.
+  if(!m_board.Contains("D") || !(m_sector=="1" || m_sector=="2" || m_sector=="3") )  removeTracksInHole = false;
+
+  polarity = 1.0;
+  if(isPType) polarity = -1;
+
+
+}
+
+AnalysisBase::~AnalysisBase()
+{
+  if (!fChain) return;
+  delete fChain->GetCurrentFile();
+}
+
+Int_t AnalysisBase::GetEntry(Long64_t entry)
+{
+  // Read contents of entry.
+  if (!fChain) return 0;
+  return fChain->GetEntry(entry);
+}
+Long64_t AnalysisBase::LoadTree(Long64_t entry)
+{
+  // Set the environment to read one entry
+  if (!fChain) return -5;
+  Long64_t centry = fChain->LoadTree(entry);
+  if (centry < 0) return centry;
+  if (fChain->GetTreeNumber() != fCurrent) {
+    fCurrent = fChain->GetTreeNumber();
+    Notify();
+  }
+  return centry;
+}
+
+void AnalysisBase::Init(TTree *tree)
+{
+  // The Init() function is called when the selector needs to initialize
+  // a new tree or chain. Typically here the branch addresses and branch
+  // pointers of the tree will be set.
+  // It is normally not necessary to make changes to the generated
+  // code, but the routine can be extended by the user if needed.
+  // Init() will be called many times when running on PROOF
+  // (once per file to be processed).
+
+  // Set object pointer
+  vec_trk_x = 0;
+  vec_trk_y = 0;
+  vec_trk_tx = 0;
+  vec_trk_ty = 0;
+  vec_trk_chi2ndf = 0;
+  // Set branch addresses and branch pointers
+  if (!tree) return;
+  fChain = tree;
+  fCurrent = -1;
+  fChain->SetMakeClass(1);
+
+  fChain->SetBranchAddress("clusterNumberPerEvent", &clusterNumberPerEvent, &b_clusterNumberPerEvent);
+  fChain->SetBranchAddress("clustersTDC", &clustersTDC, &b_clustersTDC);
+  fChain->SetBranchAddress("timestamps", &timestamps, &b_timestamps);
+  fChain->SetBranchAddress("clustersPosition", clustersPosition, &b_clustersPosition);
+  fChain->SetBranchAddress("clustersSeedPosition", clustersSeedPosition, &b_clustersSeedPosition);
+  fChain->SetBranchAddress("clustersCharge", clustersCharge, &b_clustersCharge);
+  fChain->SetBranchAddress("clustersSize", clustersSize, &b_clustersSize);
+  fChain->SetBranchAddress("clustersSeedCharge", clustersSeedCharge, &b_clustersSeedCharge);
+  fChain->SetBranchAddress("clustersCharge2StripLeft", clustersCharge2StripLeft, &b_clustersCharge2StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripLeft", clustersCharge1StripLeft, &b_clustersCharge1StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripRight", clustersCharge1StripRight, &b_clustersCharge1StripRight);
+  fChain->SetBranchAddress("clustersCharge2StripRight", clustersCharge2StripRight, &b_clustersCharge2StripRight);
+  fChain->SetBranchAddress("n_tp3_tracks", &n_tp3_tracks, &b_n_tp3_tracks);
+  fChain->SetBranchAddress("vec_trk_x", &vec_trk_x, &b_vec_trk_x);
+  fChain->SetBranchAddress("vec_trk_y", &vec_trk_y, &b_vec_trk_y);
+  fChain->SetBranchAddress("vec_trk_tx", &vec_trk_tx, &b_vec_trk_tx);
+  fChain->SetBranchAddress("vec_trk_ty", &vec_trk_ty, &b_vec_trk_ty);
+  fChain->SetBranchAddress("vec_trk_chi2ndf", &vec_trk_chi2ndf, &b_vec_trk_chi2ndf);
+  fChain->SetBranchAddress("dtime", &dtime, &b_dtime);
+
+  Notify();
+}
+
+Bool_t AnalysisBase::Notify()
+{
+  // The Notify() function is called when a new file is opened. This
+  // can be either for a new TTree in a TChain or when when a new TTree
+  // is started when using PROOF. It is normally not necessary to make changes
+  // to the generated code, but the routine can be extended by the
+  // user if needed. The return value is currently not used.
+
+  return kTRUE;
+}
+
+void AnalysisBase::Show(Long64_t entry)
+{
+  // Print contents of entry.
+  // If entry is not specified, print current entry
+  if (!fChain) return;
+  fChain->Show(entry);
+}
+/*
+Int_t AnalysisBase::Cut(Long64_t entry)
+{
+  // This function may be called from Loop.
+  // returns  1 if entry is accepted.
+  // returns -1 otherwise.
+  return 1;
+}
+*/
+void AnalysisBase::getRange(TH1 *h, float &lo, float& hi, float thresh, int nSkipMax){
+
+  int nfail = 0;
+  int iMaxBin = h->GetMaximumBin();
+  lo = iMaxBin;
+  hi = iMaxBin;
+  double maxValue = h->GetBinContent(iMaxBin);
+  // Only for debugging....
+  //h->Draw();
+  //std::cout << "maxValue = " << iMaxBin << "  " << maxValue << std::endl;
+  
+
+  for(int j=iMaxBin;j>=0;j--){
+    double v = h->GetBinContent(j);
+    double r = v / maxValue;
+    //std::cout << "r = " << r << std::endl;  // Only for debugging
+    if( r > thresh) {
+      lo = j ;
+      nfail = 0;
+    }else if( r <= thresh) {
+      nfail++;
+    }
+    if(nfail >= nSkipMax) break;
+  }
+
+  nfail = 0;
+  for(int j=iMaxBin;j<=h->GetNbinsX();j++){
+    double v = h->GetBinContent(j);
+    double r = v / maxValue;
+    //std::cout << "r = " << r << std::endl;  // Only for debugging
+    if( r > thresh) {
+      hi = j;
+      nfail = 0;
+    }else if( r <= thresh) {
+      nfail++;
+    }
+    if(nfail >= nSkipMax) break;
+  } 
+  lo = h->GetBinCenter(lo);
+  hi = h->GetBinCenter(hi);
+
+  //std::cout << "lo, hi = " << lo << " " << hi << std::endl; // only for debugging
+  
+
+  return;
+}
+
+
+void AnalysisBase::getTDCBins(TProfile* h, float& lo, float& hi){
+  getRange(h,lo,hi,0.97,1);
+  lo = lo - 1.0 + 0.5;
+  hi = hi + 0.5;
+  return;
+}
+
+
+
+void AnalysisBase::getBeamLocation(TH1F *h, float &lo, float& hi){
+  //double dif = 10;
+  for(int  j = 0; j<10; j++){
+    std::cout << "====> Finding Beam, iteration " << j+1 << std::endl;
+    getRange(h,lo,hi);
+    int dif = hi - lo + 1;
+    if(dif < 5){
+      int i1 = h->FindBin(lo);
+      int i2 = h->FindBin(hi);
+      for(int k=i1; k<=i2; k++){
+        h->SetBinContent(k,0);
+      }
+    }else{
+      break;
+    } 
+  }
+
+  //h->Draw();
+  return;
+}
+
+double AnalysisBase::getXOffset(TH1F *h1w){
+  float xlo = 0, xhi=0;
+  getRange(h1w,xlo,xhi,0.1,1);
+  
+  return (xlo+xhi)/2.0;
+
+}
+
+void AnalysisBase::getBeamLoc(){
+
+  TH1F* ha = new TH1F("ha","Strip # of cluster with track",512,0.0,512);
+  //TH1F* hb = new TH1F("hb","Strip # of cluster with track",512,0.0,512);
+  Long64_t nentries = fChain->GetEntriesFast();
+  float lo = 0, hi = 0;
+
+  Long64_t nbytes = 0, nb = 0;
+  std::cout << "======================================= " << std::endl;
+  std::cout << "getBeamLoc(): Determining Beam Position " << nentries << std::endl;
+  std::cout << "======================================= " << std::endl;
+  for (Long64_t jentry=0; jentry<max(50000,(int)nentries);jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+    //cout << clusterNumberPerEvent << endl;
+    
+    for(int j=0; j<min((int)clusterNumberPerEvent,10); j++){
+      //std::cout << clustersPosition[j] << std::endl;
+      //cout << polarity << " " << polarity*clustersCharge[j] << endl;
+      if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+      int iChan = clustersSeedPosition[j];
+      //if(j<500) cout << "iChan = " << iChan << clustersCharge[j] << " " << 5*noise[iChan] << endl;
+      if(polarity*clustersCharge[j]<4*noise[iChan]) continue;
+      if(clustersPosition[j]>0.1&&clustersSize[j]==1) ha->Fill(clustersPosition[j]);
+      if(clustersPosition[j]>0.1&&clustersSize[j]==2) ha->Fill(clustersPosition[j]);
+    }
+  }
+     
+  int num = ha->GetEntries();
+  for(int i=0; i<1000; i++){
+    if(num < 1000) continue;
+    break;
+  }
+
+  if(num < 1000){
+    std::cout << "ERROR: Something wrong here, insufficient entries in GetBeamLoc(), nEntries =  " << num << std::endl;
+    //exit(1);
+  }
+   
+  //ha->Draw();
+  getBeamLocation(ha,lo,hi);
+  iLo = lo;
+  iHi = hi;
+  std::cout << "====> Beam is between strips " << iLo << " -- " << iHi << std::endl;
+
+  //delete ha;
+  return;
+
+}
+
+void AnalysisBase::getTDC(){
+  TProfile *hb = new TProfile("hb","Cluster Charge vs TDC time",12,0,12,100,1000);
+  Long64_t nentries = fChain->GetEntriesFast();
+  float lo = 0, hi = 0;
+
+  Long64_t nbytes = 0, nb = 0;
+  std::cout << "============================================" << std::endl;
+  std::cout << "getTDC(): Determining Optimal TDC time range" << std::endl;
+  std::cout << "============================================" << std::endl;   
+  for (Long64_t jentry=0; jentry<max(50000,(int)nentries);jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+
+    for(int j=0; j<min((int)clusterNumberPerEvent,10); j++){
+      //std::cout << "j: " << ", clustersTDC: " << clustersTDC << ", clustersCharge[j]: " << clustersCharge[j] << ", clustersPosition[j]: " << clustersPosition[j] << std::endl; 
+      if(clustersPosition[j] < 0.1) continue;
+      if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+      if(clustersPosition[j]>=iLo && clustersPosition[j]<=iHi && clustersTDC>1.0 && 
+         polarity*clustersCharge[j]>150 && polarity*clustersCharge[j]<500) hb->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+    }
+  }
+
+  getTDCBins(hb,lo,hi);
+  tdcLo = lo;
+  tdcHi = hi;
+  std::cout << "====> TDC Range determined to be from " << tdcLo << " -- " << tdcHi << std::endl;
+  hb->Draw();
+  //delete hb;
+  
+
+  return;
+}
+
+void AnalysisBase::findBeamRegionAndAlign(int iPass){
+
+  cout << "==================================================================" << endl;
+  cout << "findBeamRegionAndAlign(): Determining Fiducial Region, Pass = " << iPass << endl;
+  cout << "==================================================================" << endl;
+
+  double dxWindow = dxWin;
+  if(iPass == 1) dxWindow = 1000.0;
+  if(iPass == 2) dxWindow = 1.0;
+
+  TH1F* hthx = new TH1F("hthx","#theta_{X}",1000,-5.0,5.0);
+  TH1F* hthy = new TH1F("hthy","#theta_{Y}",1000,-5.0,5.0);
+  TH1F* hx = new TH1F("hx","Y position of matched cluster",800,-40.0,40.0);
+  TH1F* hxdut = new TH1F("hxdut","Y position of matched cluster",800,-40.0,40.0);
+  TH1F* hs = new TH1F("hs","Strip number of matched cluster",512,0,512.0);
+  TH1F* hy = new TH1F("hy","Y position of matched cluster",800,-10.0,10.0);
+  TH1F* hw = new TH1F("hw","#DeltaX",20000,-100.0,100.0);
+  TH1F* hn = new TH1F("hn","#DeltaX",4000,-2.0,2.0);
+  TH1F* hnn = new TH1F("hnn","#DeltaX",400,-0.2,0.2);
+  TH2F* hxy = new TH2F("hxy","Y_{trk} vs X_{trk}, with cluster",640,-8,8.0,640,-8,8);
+  TProfile *ht = new TProfile("ht","Cluster Charge vs TDC time",12,0,12,100,1000);
+  TProfile *hzrot = new TProfile("hzrot","#DeltaX vs Y_{trk} at DUT",1600,-8,8,-1.0,1.0);
+  TH2F* hca = new TH2F("hca","Y_{trk} vs X_{trk}, with found cluster",160,-8,8.0,320,-8,8);
+  TH2F* hcf = new TH2F("hcf","Y_{trk} vs X_{trk}, with found cluster",160,-8,8.0,320,-8,8);
+  
+  hca->Sumw2();
+  hcf->Sumw2();
+  
+
+  double nomStrip=0, detStrip = 0;
+  Long64_t nbytes = 0, nb = 0;
+  Int_t nentries = fChain->GetEntriesFast();
+  for (Long64_t jentry=0; jentry<max(nentries,200000);jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    //if(jentry%1000==0) cout << "At entry = " << jentry << endl;
+    
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+    if(n_tp3_tracks > 1) continue;      
+
+    for(int k=0; k<n_tp3_tracks; k++){
+      bool goodTime = (clustersTDC >= tdcLo && clustersTDC < tdcHi);
+      goodTime = clustersTDC>1.0;
+      if(!goodTime) continue;
+      double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+      double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+
+      transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip);
+
+      double tx = 1000*vec_trk_tx->at(k);
+      double ty = 1000*vec_trk_ty->at(k);
+
+      double x_trk0 = x_trk;
+
+      for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+        if(clustersPosition[j] < 0.1) continue;
+        if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+        bool goodHit = (clustersPosition[j]>iLo && clustersPosition[j]<iHi);
+        double x_dut = getDUTHitPosition(j);
+
+        x_trk = x_trk0;
+
+        double dx = x_dut - x_trk;
+        hn->Fill(dx);
+        hnn->Fill(dx);
+
+        hca->Fill(x_trk,y_trk);
+        if(fabs(dx)<dxWindow || iPass==1) {
+          if(goodHit) {
+            hx->Fill(x_trk);
+            hxdut->Fill(x_dut);
+            hs->Fill(clustersPosition[j]);
+            hy->Fill(y_trk);
+            hthx->Fill(tx);
+            hthy->Fill(ty);
+            hw->Fill(dx);     
+            hxy->Fill(x_trk,y_trk);
+            ht->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+            hzrot->Fill(y_trk,dx);
+            hcf->Fill(x_trk,y_trk);
+          } 
+        }
+      }
+    }
+  }
+
+  //hnn->Draw();
+
+  if(iPass==4) {
+    findCutoutRegion(hcf);
+  }else {  
+
+    float xmin=0,xmax=0,ymin=0,ymax=0,txmin=0,txmax=0,tymin=0,tymax=0;
+
+    getRange(hthx,txmin,txmax,0.05,2);
+    getRange(hthy,tymin,tymax,0.05,2);
+    getRange(hx,xmin,xmax,0.05,2);
+    getRange(hy,ymin,ymax,0.2,2);
+    
+    xMin = xmin;
+    xMax = xmax;
+    yMin = ymin;
+    yMax = ymax;
+    txMin = txmin;
+    txMax = txmax;
+    tyMin = tymin;
+    tyMax = tymax;
+    
+    float xlo = 0, xhi=0;
+    if(iPass==1) getRange(hw,xlo,xhi,0.1,1);
+    if(iPass==2) getRange(hn,xlo,xhi,0.1,1);
+    if(iPass==3) getRange(hnn,xlo,xhi,0.1,1);
+    double XOFF = (xhi + xlo)/2.0;
+    xOff = xOff - XOFF;
+    double x_ave = (xMax + xMin)/2.0;
+    double y_ave = (yMax + yMin)/2.0;
+    xGloOff = xGloOff - x_ave;
+    yGloOff = yGloOff - y_ave;
+    
+    // Check/correct for z rotation
+    if(iPass==3 && correctForZRotation){
+      cout << "Checking for z-rotation" << endl;
+      TF1* p1 = new TF1("p1","[0]+[1]*x",yMin,yMax);
+      p1->SetParameters(0.0,0.0001);
+      hzrot->Fit(p1,"0R");
+      double rz = p1->GetParameter(1);
+      cout << "=======================================================================" << endl;
+      cout << "==> Updating z rotation angle from " << Rz << " to " << Rz-rz << " mrad" << endl;    
+      Rz = Rz - rz;
+      delete p1;
+    }
+    
+    
+    float lo = 0, hi = 0;
+    getTDCBins(ht,lo,hi);
+    tdcLo = lo;
+    tdcHi = hi;
+    cout << "=================================================================" << endl;
+    cout << "====> TDC Range updated to be from " << tdcLo << " -- " << tdcHi << std::endl;
+    cout << "=================================================================" << endl;
+    cout << "====> Fiducial regions, xLo, xHi (Strip numbers) = " << iLo << " " << iHi << endl;
+    cout << "====> Fiducial regions, xLo, xHi (pos in mm) = " << xMin << " " << xMax << " mm " << endl;
+    cout << "====> Fiducial regions, yLo, yHi (pos in mm) = " << yMin << " " << yMax << " mm " << endl;
+    cout << "====> Fiducial regions, thxLo, thxHi (pos in mrad) = " << txMin << " " << txMax << " mrad" << endl;
+    cout << "====> Fiducial regions, thyLo, thxHi (pos in mrad) = " << tyMin << " " << tyMax << " mrad" << endl;
+    cout << "=================================================================" << endl;   
+    cout << "====> Shifting sensor by dX = " << XOFF << " mm " << ", new xOff = " << xOff << endl;
+    cout << "====> Global X, Y shifts: " << x_ave << " " << y_ave << endl;
+    cout << "====> New global x,y = " << xGloOff << " " << yGloOff << endl;
+    
+  }
+  
+  //if(iPass==1) hw->Draw();  // for debugging   
+  //if(iPass==2) hy->Draw();
+
+  //return;
+  
+
+  delete hxdut;
+  delete hthx;
+  delete hthy;
+  delete hx;
+  delete hy;
+  delete hxy;
+  delete hw;
+  delete hn;
+  delete hnn;
+  delete hs;
+  delete ht;
+  delete hzrot;
+  delete hcf;
+  delete hca;
+  
+   
+  return;
+  
+
+}
+
+
+Double_t AnalysisBase::getCorrChannel(double ch){
+  //if(ch>=128 && ch<=255) return (ch + stripGap[0]);
+  //if(ch>=256 && ch<=383) return (ch + stripGap[1]);
+  //if(ch>=384 && ch<=512) return (ch + stripGap[2]);
+
+  if(ch<=128) return (ch - stripGap[0]);
+  if(ch>=128 && ch<=255) return (ch - stripGap[1]);
+  if(ch>=256 && ch<=383) return (ch - stripGap[2]);
+  if(ch>=384 && ch<=512) return (ch - stripGap[3]);
+
+  return ch;  
+}
+
+void AnalysisBase::findChipBoundary(){
+  // Look for holes in hit profile, due to boundary between chips
+  std::cout << "=======================================================================================" << std::endl;
+  std::cout << "findChipBoundary(): Looking for gaps due to unconnected strips in between Beetle chips " << std::endl;
+  std::cout << "=======================================================================================" << std::endl;
+   
+  TH1F* hx2 = new TH1F("hx2","X position of cluster",200,-10.0,10.0);
+
+  Long64_t nbytes = 0, nb = 0;
+  Long64_t nentries = fChain->GetEntriesFast();
+  for (Long64_t jentry=0; jentry<max((int)nentries,20000);jentry++) {
+    Long64_t ientry = LoadTree(jentry);    
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+    for(int j=0; j<min((int)clusterNumberPerEvent,10); j++){
+      if(clustersPosition[j] < 0.1) continue;
+      if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+      bool goodHit = (clustersPosition[j]>iLo && clustersPosition[j]<iHi);
+      goodHit = goodHit &&  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+      double x_dut = getDUTHitPosition(j);
+         
+      hx2->Fill(x_dut);
+    }
+  }
+  
+  //hx2->Draw(); // for debugging only
+
+  int i1 = hx2->FindBin(xMin);
+  int i2 = hx2->FindBin(xMax);
+  double ave = 0.0;
+  int ixL=i1, ixH=i2;
+  for(int i=i1; i<i2; i++){
+    ave = ave +  hx2->GetBinContent(i);
+  }
+  ave = ave / (i2 - i1 + 1);
+  for(int i=i1; i<i2; i++){
+    double v  = hx2->GetBinContent(i);
+    double xx  = hx2->GetBinCenter(i);
+    double r = v/ave;
+    if(r < ratioForHole && xx < xLeftHole) {
+      xLeftHole = xx;
+      ixL = i;
+    }
+    if(r < ratioForHole && xx > xRightHole) {
+      xRightHole = xx;
+      ixH = i;
+    }
+  }
+  // Count the number of "dead" channels in this region
+  float ndead = 0;
+  for(int i=ixL; i<=ixH; i++){
+    double v  = hx2->GetBinContent(i);
+    double r = v/ave;
+    if(r < ratioForHole) ndead = ndead + 1;
+  }
+  double frdead = ndead / (ixH - ixL + 1);
+
+  if(frdead>0.8 && ndead>4){
+    xLeftHole = xLeftHole - 0.2;
+    xRightHole = xRightHole + 0.2;
+  }else{
+    xLeftHole = 999;
+    xRightHole = -999;
+  }
+  
+  hx2->Draw();
+  
+  
+  //std::cout << "Xmin, xMax = " << xMin << " " << xMax << std::endl;
+  //std::cout << "Bin Edges: " << i1 << "  " << i2 << std::endl;
+  //std::cout << "Hole position: " << xLeftHole << "  " << xRightHole << " , fraction dead = " << ndead << " " << frdead << std::endl;
+  
+  delete hx2;
+
+}
+
+void AnalysisBase::findDeadRegions(){
+
+  cout << "=================================================" << endl;
+  cout << "findDeadRegions(): Looking for dead strip regions " << endl;
+  cout << "=================================================" << endl;
+
+  TH1F* hf = new TH1F("hf","X position of matched cluster",200,-10.0,10.0);
+  TH1F* hnf = new TH1F("hnf","X position of matched cluster",200,-10.0,10.0);
+  
+  double nomStrip = 0, detStrip = 0;
+  Long64_t nbytes = 0, nb = 0;
+  Int_t nentries = fChain->GetEntriesFast();
+  for (Long64_t jentry=0; jentry<nentries;jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+      
+    if(n_tp3_tracks > 1) continue;
+
+    // Loop over TPIX tracks in event
+    for(int k=0; k<n_tp3_tracks; k++){
+      double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+      double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+
+      transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip );
+
+      bool goodTrack = false;
+      bool inFiducial = false;
+      if(x_trk>xMin && x_trk<xMax && y_trk>yMin && y_trk<yMax) inFiducial = true;          
+      inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+      double tx = 1000*vec_trk_tx->at(k);
+      double ty = 1000*vec_trk_ty->at(k);
+      if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+      bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+      bool foundHit = false;
+      // Loop over clusters
+      for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+        if(clustersPosition[j] < 0.1) continue;
+        if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+        //bool goodHit = (clustersPosition[j]>iLo || clustersPosition[j]<iHi);
+        double x_dut = getDUTHitPosition(j);
+
+        double dx = x_dut - x_trk;
+
+        if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin) {
+          foundHit = true;
+        }   
+      }
+      if(inFiducial && goodTrack && goodTime) {
+        hf->Fill(x_trk);    
+        if(!foundHit) hnf->Fill(x_trk);          
+      }
+        
+    }
+  }
+
+  TH1F *hineff = (TH1F*)hnf->Clone("hineff");
+  hineff->Divide(hf);
+
+  // Only for debugging
+  /*
+    TCanvas *cc = new TCanvas("cc","Hits",800,800);
+    cc->Divide(2,2);
+   
+    cc->cd(1);
+    hnf->Draw();
+    cc->cd(2);
+    hf->Draw();
+    cc->cd(3);
+    hineff->Draw();
+  */
+
+
+  for(int k = 0; k<hineff->GetNbinsX()-1; k++){
+    if(nDeadRegion > 20){
+      cout << "WARNING: Exceeded 20 dead regions, exiting from loop" << endl;       
+      break;
+    }     
+    double v1 = hineff->GetBinContent(k);
+    if(v1 > k_DeadStrip){
+      deadRegionLo[nDeadRegion] = hf->GetBinLowEdge(k);
+      for(int j = k; j<hineff->GetNbinsX(); j++){
+        double v2 = hineff->GetBinContent(j);
+        if(v2 < k_DeadStrip){
+          deadRegionHi[nDeadRegion] = hf->GetBinLowEdge(j);
+          cout << "====> Found inefficiency strip region from x :    " 
+               << deadRegionLo[nDeadRegion] << " <===> " << deadRegionHi[nDeadRegion] << " mm" << endl;
+          k = j + 1;
+          nDeadRegion++;
+          break;
+        }    
+      }
+    }
+  }
+   
+  delete hf;
+  delete hnf;
+  delete hineff;
+   
+  return;
+}
+
+void AnalysisBase::transformTrackToDUTFrame(int k, double& x_trk, double& y_trk, double& elecStrip, double& detStrip){
+  y_trk = y_trk + yGloOff;
+
+  double dzs = x_trk * sin(Ry);
+  x_trk = x_trk - Rz*y_trk;
+  y_trk = y_trk + Rz*x_trk;
+  x_trk = x_trk + vec_trk_tx->at(k)*dzs;
+  x_trk = x_trk/cos(Ry);
+  double rStrip = nChan - (x_trk-xOff)/stripPitch; 
+  double corStrip = getCorrChannel(rStrip);
+  //double dx = (corStrip - rStrip)*stripPitch;
+  //x_trk = x_trk + dx;
+  detStrip = rStrip; //nChan - (x_trk-xOff)/stripPitch; 
+  elecStrip = corStrip;
+  
+  x_trk = x_trk + xGloOff;
+
+  return;
+}
+
+void AnalysisBase::PrepareDUT(){
+
+   //----------------------------
+   // Get Beam Location (Strips)
+   //----------------------------
+   getBeamLoc();
+   //return;
+   
+   
+   // ==================================
+   // Determining Optimal TDC time range
+   // ==================================
+   getTDC();
+   
+   // --------------------------------------------------------------
+   // Find beam fiducial region (slopes & Y range) & align residuals
+   // ---------------------------------------------------------------
+   findBeamRegionAndAlign(1);
+   
+   
+   findBeamRegionAndAlign(2);   
+   yMid = yMin + (yMax-yMin)/2.0;
+   yHi2 = yMax - 2.0;
+
+   findBeamRegionAndAlign(3);   
+   yMid = yMin + (yMax-yMin)/2.0;
+   yHi2 = yMax - 2.0;
+
+   //return;
+   
+   if(yInt2[1] > yMax){
+     yInt1[0] = yMax-0.8; yInt1[1] = yMax-0.4;
+     yInt2[0] = yMax-0.4; yInt2[1] = yMax;
+     yInt3[0] = yMin; yInt3[1] = yMax-0.8;
+   }
+   cout << "Y Region Definitions:" << endl;
+   cout << " ===> Region 1: " << yInt1[0] << " -- " << yInt1[1] << " mm" << endl;
+   cout << " ===> Region 2: " << yInt2[0] << " -- " << yInt2[1] << " mm" << endl;
+   cout << " ===> Region 3: " << yInt3[0] << " -- " << yInt3[1] << " mm" << endl;
+   
+   //return;
+   // Correct for gaps between Beetle chips
+   correctForStripGaps();
+
+   //findBeamRegionAndAlign(4);   
+   if(holeSector) findBeamRegionAndAlign(4);
+
+   findChipBoundary();
+   cout << "====> Hole position: " << xLeftHole << "  " << xRightHole << endl;
+   //return;
+
+   if(vetoDeadStripRegions) findDeadRegions();
+   //return;
+
+   setCrossTalkCorr();
+
+}
+
+Double_t AnalysisBase::getDUTHitPosition(int j){
+  double pos = getCorrChannel(clustersPosition[j]);
+  //double pos = clustersPosition[j];
+  double x_dut = (nChan - pos)*stripPitch + xOff;
+  x_dut = x_dut + xGloOff;  
+  return x_dut;
+  
+}
+
+void AnalysisBase::setCrossTalkCorr(){
+  float biasVal = atof(m_bias);
+  chargeCorrSlopeOdd = 0.0;
+  chargeCorrSlopeEven = 0.0;
+  cout << "Bias Value = " << m_bias <<  " " << biasVal << endl;
+  
+  if(m_board.Contains("A2") && m_sector=="1" && biasVal < 260){
+    chargeCorrSlopeOdd = 0.435;
+    chargeCorrSlopeEven = 0.400;
+  }else if(m_board.Contains("A2") && m_sector=="1" && biasVal > 320){
+    chargeCorrSlopeOdd = 0.148;
+    chargeCorrSlopeEven = 0.094;
+  }else if(m_board.Contains("A2") && m_sector=="1" && biasVal == 300){
+    chargeCorrSlopeOdd = 0.130;
+    chargeCorrSlopeEven = 0.088;
+  }else if(m_board.Contains("A2") && m_sector=="2"){
+    chargeCorrSlopeOdd = 0.120;
+    chargeCorrSlopeEven = 0.085;
+  }
+  
+}
+
+
+void AnalysisBase::findCutoutRegion(TH2F* h){
+
+  cout << "===============================================================" << endl;
+  cout << "findCutoutRegion(): Looking for cutout region in D type sensor " << endl;
+  cout << "===============================================================" << endl;
+
+
+  int ilx = h->GetXaxis()->FindBin(xMin) + 1;
+  int ihx = h->GetXaxis()->FindBin(xMax) - 1;
+  int ily = 1;//h->GetYaxis()->GetBinFindBin(yMin) - 10;
+  int ihy = h->GetYaxis()->FindBin(yMax) + 10;
+  if(ily < 0) ily = 0;
+  if(ihy > h->GetYaxis()->GetNbins()) ihy = h->GetYaxis()->GetNbins();  
+  int nb = h->GetXaxis()->GetNbins(); 
+
+  double xlow = h->GetXaxis()->GetBinLowEdge(1);
+  double xhi = h->GetXaxis()->GetBinLowEdge(nb)+h->GetXaxis()->GetBinWidth(1);
+
+  TH1F *hpr = new TH1F("hpr","Y vs X, edge",nb,xlow,xhi);
+
+  TH1D *hpy;
+  int ipeak = 0;
+  for(int i=ilx; i<ihx-1; i++){
+    hpy = h->ProjectionY("hpy",i,i);
+    double maxcon  = 0.0;
+    double maxbin  = 0.0;
+    for(int j=ily;j<ihy;j++){
+      maxcon = maxcon + hpy->GetBinContent(j);
+      if(hpy->GetBinContent(j) > maxbin) {
+        maxbin = hpy->GetBinContent(j) ;
+        ipeak = j;
+      }
+    }
+    // Find the lower "edge"
+    for(int j=ipeak; j>=ily; j--){
+      double r0 = (hpy->GetBinContent(j-1)+hpy->GetBinContent(j-2))/2.0;
+      double r1 = hpy->GetBinContent(j);
+      double r2 = (hpy->GetBinContent(j+3)+hpy->GetBinContent(j+4))/2.0;
+      if(r1<=2 && r0<=1.5 && r2>5*r1 && r2>8){
+        hpr->SetBinContent(i,hpy->GetBinCenter(j)+2*hpy->GetBinWidth(j));
+        hpr->SetBinError(i,hpy->GetBinWidth(1)/2.0);
+        //cout << "found: " << i << " " << hpy->GetEntries() << " " << hpy->GetBinCenter(j) << " " 
+        //     << hpy->GetBinContent(j) << " " << r0 << " " << r1 << " " << r2 << " " << endl;
+        break;
+      }
+    }
+    
+  }
+
+  TF1* poly2 = new TF1("poly2","[0]+[1]*x+[2]*x*x",xMin,xMax);
+  poly2->SetParameters(-1.5,-0.17,-0.15);
+  hpr->Fit(poly2,"R0");
+  hpr->SetLineColor(kRed);
+
+  holeQuadPar[0] = poly2->GetParameter(0);
+  holeQuadPar[1] = poly2->GetParameter(1);
+  holeQuadPar[2] = poly2->GetParameter(2);
+
+  //return;
+  
+
+  delete poly2;
+  delete hpr;
+  delete hpy;
+  
+  return;
+}
+
+bool AnalysisBase::isInCutoutRegion(double xtrk, double ytrk){  
+  // Some protections here..
+  if(!removeTracksInHole) return false;
+  if(holeQuadPar[0]==0 || holeQuadPar[1]==0 || holeQuadPar[2]==0) return false;
+  // Ok, looks like we mean to really remove these tracks
+  double yhole = holeQuadPar[0]+holeQuadPar[1]*xtrk+holeQuadPar[2]*xtrk*xtrk;
+  if(ytrk < yhole + minDistFromHole) return true;
+  return false;
+}
+
+double AnalysisBase::DistToCutoutRegion(double xtrk, double ytrk){  
+  // Some protections here..
+  if(holeQuadPar[0]==0 || holeQuadPar[1]==0 || holeQuadPar[2]==0) return 999.0;
+  // Ok, looks like we mean to really remove these tracks
+  double yhole = holeQuadPar[0]+holeQuadPar[1]*xtrk+holeQuadPar[2]*xtrk*xtrk;
+  double a = 2.0*holeQuadPar[2]*xtrk+holeQuadPar[1];
+  double c = yhole - a*xtrk;
+  double b = -1.0;
+  
+  double dist = fabs(a*xtrk + b*ytrk + c) / sqrt(a*a+b*b);
+  if(ytrk < yhole) dist = -1.0*dist;
+  return dist;
+}
+
+void AnalysisBase::correctForStripGaps(){   
+  cout << "================================================================================" << endl;
+  cout << "correctForStripGaps(): Correcting x fiducial range for gaps between Beetle chips" << endl;
+  cout << "================================================================================" << endl;
+
+  double x1 = getCorrChannel(iLo);
+  double x2 = getCorrChannel(iHi);
+  xMax = (nChan - x1)*stripPitch + xOff + xGloOff;
+  xMin = (nChan - x2)*stripPitch + xOff + xGloOff;
+  double xave = (xMax + xMin)/2.;
+  xGloOff = xGloOff - xave;
+  xMin = xMin - xave;
+  xMax = xMax - xave;   
+  std::cout << "====> Updating Global Offset to use Strips, *** New xMin, xMax == " << xMin << " " << xMax << endl;
+  std::cout << "====> xMin, xMax = " << xMin << " " << xMax << endl;
+  std::cout << "====> xMin, xMax = " << yMin << " " << yMax << endl;
+  return;
+  
+}
+
+
diff --git a/TbUT/scripts/.svn/text-base/AnalysisBase.h.svn-base b/TbUT/scripts/.svn/text-base/AnalysisBase.h.svn-base
new file mode 100644
index 0000000..fc58d33
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/AnalysisBase.h.svn-base
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Oct  1 20:13:36 2015 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+// found on file: /data2/pmmannin/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_tracks.root
+//////////////////////////////////////////////////////////
+
+#ifndef AnalysisBase_h
+#define AnalysisBase_h
+
+#include <TROOT.h>
+#include <iostream>
+#include <TChain.h>
+#include <TTree.h>
+#include <TMath.h>
+#include <TFile.h>
+#include <TH2.h>
+#include <TF1.h>
+#include <TProfile.h>
+#include <TString.h>
+#include <TGraph.h>
+#include <TGraphErrors.h>
+//#include "myInputs.h"
+#include "AnalysisBase_Inputs.h"
+
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+
+
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class AnalysisBase {
+ public :
+  TTree          *fChain;   //!pointer to the analyzed TTree or TChain
+  Int_t           fCurrent; //!current Tree number in a TChain
+  
+  // Declaration of leaf types
+
+  Int_t           clusterNumberPerEvent;
+  UInt_t          clustersTDC;
+  ULong64_t       timestamps;
+  Double_t        clustersPosition[10];
+  Int_t           clustersSeedPosition[10];
+  Double_t        clustersCharge[10];
+  Int_t           clustersSize[10];
+  Double_t        clustersSeedCharge[10];
+  Double_t        clustersCharge2StripLeft[10];
+  Double_t        clustersCharge1StripLeft[10];
+  Double_t        clustersCharge1StripRight[10];
+  Double_t        clustersCharge2StripRight[10];
+  Double_t        dtime;
+   
+  Int_t           n_tp3_tracks;
+  vector<double>  *vec_trk_x;
+  vector<double>  *vec_trk_y;
+  vector<double>  *vec_trk_tx;
+  vector<double>  *vec_trk_ty;
+  vector<double>  *vec_trk_chi2ndf;
+
+  // List of branches
+  TBranch        *b_clusterNumberPerEvent;   //!
+  TBranch        *b_clustersTDC;   //!
+  TBranch        *b_timestamps;   //!
+  TBranch        *b_clustersPosition;   //!
+  TBranch        *b_clustersSeedPosition;   //!
+  TBranch        *b_clustersCharge;   //!
+  TBranch        *b_clustersSize;   //!
+  TBranch        *b_clustersSeedCharge;   //!
+  TBranch        *b_clustersCharge2StripLeft;   //!
+  TBranch        *b_clustersCharge1StripLeft;   //!
+  TBranch        *b_clustersCharge1StripRight;   //!
+  TBranch        *b_clustersCharge2StripRight;   //!
+  TBranch        *b_n_tp3_tracks;   //!
+  TBranch        *b_vec_trk_x;   //!
+  TBranch        *b_vec_trk_y;   //!
+  TBranch        *b_vec_trk_tx;   //!
+  TBranch        *b_vec_trk_ty;   //!
+  TBranch        *b_vec_trk_chi2ndf;   //!
+  TBranch        *b_dtime;   //!
+
+  double stripPitch;
+  double z_DUT;
+  double Rz;
+  double Ry;
+  double dxWin;
+  double xGloOff;
+  double yGloOff;
+  double xOff;
+  
+
+  float iLo, iHi;
+  float tdcLo, tdcHi;
+  float yMin,yMax;
+  float xMin,xMax;
+  float yMid, yHi2;
+  float tyMin,tyMax;
+  float txMin,txMax;
+  Int_t skipChannel[512];
+  double xLeftHole;
+  double xRightHole;
+  
+  Int_t lowEdge, hiEdge;
+  Double_t stripGap[4];
+  Double_t deadRegionLo[20];
+  Double_t deadRegionHi[20];
+  Int_t nDeadRegion;  
+
+  double yInt1[2];
+  double yInt2[2];
+  double yInt3[2];
+
+  float polarity;
+
+  TH1F *hMeanNoise; 
+  TH1F *hWidthNoise; 
+
+  double holeQuadPar[3];
+  bool removeTracksInHole;
+  double minDistFromHole;
+  bool holeSector;
+  bool correctForZRotation;
+
+  double chargeCorrSlopeOdd;
+  double chargeCorrSlopeEven;
+  
+  double noise[512];
+
+  double channelOffset;  
+
+  AnalysisBase(TTree *tree=0);
+  virtual ~AnalysisBase();
+  //virtual Int_t    Cut(Long64_t entry);
+  virtual Int_t    GetEntry(Long64_t entry);
+  virtual Long64_t LoadTree(Long64_t entry);
+  virtual void     Init(TTree *tree);
+  virtual void     Loop()  = 0; //make it pure virtual!
+  virtual Bool_t   Notify();
+  virtual void     Show(Long64_t entry = -1);
+  virtual void     getRange(TH1 *h, float &lo, float& hi, float thresh = 0.25, int nSkipMax=5);
+  virtual void getTDCBins(TProfile* h, float& lo, float& hi);
+  virtual void getBeamLocation(TH1F *h, float &lo, float& hi);
+  virtual double getXOffset(TH1F *h1w);
+  virtual void getBeamLoc();
+  virtual void getTDC();
+  virtual void findBeamRegionAndAlign(int iPass = 1);
+  virtual Double_t getCorrChannel(double ch);
+  virtual void findChipBoundary();
+  virtual void setCrossTalkCorr();
+  
+
+  virtual void findDeadRegions();
+  virtual void transformTrackToDUTFrame(int k, double& x_trk, double& y_trk, double& nomStrip, double& detStrip);
+  virtual void PrepareDUT();
+  virtual Double_t getDUTHitPosition(int j);
+  virtual void findCutoutRegion(TH2F* h);
+  virtual bool isInCutoutRegion(double xtrk, double ytrk);
+  virtual double DistToCutoutRegion(double xtrk, double ytrk);
+  virtual void correctForStripGaps();
+
+};
+
+#endif
diff --git a/TbUT/scripts/.svn/text-base/AnalysisBase_Inputs.h.svn-base b/TbUT/scripts/.svn/text-base/AnalysisBase_Inputs.h.svn-base
new file mode 100644
index 0000000..c2f1adf
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/AnalysisBase_Inputs.h.svn-base
@@ -0,0 +1,42 @@
+//const TString m_fileIndir = "/data2/pmmannin/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/Nov2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/July2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/November2015/";
+//const TString m_board 	= "A1_Full"; 
+//const TString m_board 	= "D7_All"; 
+// Board, use: _board = "D5_All", A8_All" - October TB
+// const TString m_board 	= "D5_All"; 
+
+// =========================================================
+
+const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+const TString m_board 	= "A2"; 
+
+TString m_bias  	= "300";
+const TString m_sector	= "1"; 
+//const TString m_scanType = "Angle";
+const TString m_scanType = "Bias";
+const TString m_angle = "0";
+
+const TString m_fileOutdir = "~/lhcb/testbeam/"; 
+
+const TString plotdir 	= "plots";
+
+const double nChan 			= 512.0;
+const double stripPitch = 0.190;
+
+const bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+const double trackTriggerTimeDiffCut = 2.5;   // Default = 2.5
+
+const bool isPType = true;
+
+const int kClusterChargeMin = 150;
+const double ratioForHole 	= 0.05;
+const double ratioForDeadStrip 	= 0.6;
+const double ratioForNoisyStrip = 1.8;
+const bool vetoDeadStripRegions = false;
+const double k_DeadStrip 				= 0.12;
+
+const double m_minDistFromHole = 0.05;
+const bool removeTracksInHoleDef = false;
diff --git a/TbUT/scripts/.svn/text-base/CMS.C.svn-base b/TbUT/scripts/.svn/text-base/CMS.C.svn-base
new file mode 100644
index 0000000..5073b1e
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/CMS.C.svn-base
@@ -0,0 +1,43 @@
+#define CMS_cxx
+#include "CMS.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+
+void CMS::Loop()
+{
+//   In a ROOT session, you can do:
+//      Root > .L CMS.C
+//      Root > CMS t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+
+   Long64_t nentries = fChain->GetEntriesFast();
+
+   Long64_t nbytes = 0, nb = 0;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      // if (Cut(ientry) < 0) continue;
+   }
+}
diff --git a/TbUT/scripts/.svn/text-base/CMS.h.svn-base b/TbUT/scripts/.svn/text-base/CMS.h.svn-base
new file mode 100644
index 0000000..290a51e
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/CMS.h.svn-base
@@ -0,0 +1,130 @@
+//////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Fri Oct 16 18:02:17 2015 by ROOT version 5.34/32
+// from TTree CMS/TbUT nTuple
+// found on file: Run_Bias_Scan-B6-A-212-8358_Tuple.root
+//////////////////////////////////////////////////////////
+
+#ifndef CMS_h
+#define CMS_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+
+// Header file for the classes stored in the TTree if any.
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class CMS {
+public :
+   TTree          *fChain;   //!pointer to the analyzed TTree or TChain
+   Int_t           fCurrent; //!current Tree number in a TChain
+
+   // Declaration of leaf types
+   Double_t        cmsData[512];
+
+   // List of branches
+   TBranch        *b_cmsData;   //!
+
+   CMS(TTree *tree=0);
+   virtual ~CMS();
+   virtual Int_t    Cut(Long64_t entry);
+   virtual Int_t    GetEntry(Long64_t entry);
+   virtual Long64_t LoadTree(Long64_t entry);
+   virtual void     Init(TTree *tree);
+   virtual void     Loop();
+   virtual Bool_t   Notify();
+   virtual void     Show(Long64_t entry = -1);
+};
+
+#endif
+
+#ifdef CMS_cxx
+CMS::CMS(TTree *tree) : fChain(0) 
+{
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+   if (tree == 0) {
+      TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("Run_Bias_Scan-B6-A-212-8358_Tuple.root");
+      if (!f || !f->IsOpen()) {
+         f = new TFile("Run_Bias_Scan-B6-A-212-8358_Tuple.root");
+      }
+      TDirectory * dir = (TDirectory*)f->Get("Run_Bias_Scan-B6-A-212-8358_Tuple.root:/TbUT");
+      dir->GetObject("CMS",tree);
+
+   }
+   Init(tree);
+}
+
+CMS::~CMS()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+
+Int_t CMS::GetEntry(Long64_t entry)
+{
+// Read contents of entry.
+   if (!fChain) return 0;
+   return fChain->GetEntry(entry);
+}
+Long64_t CMS::LoadTree(Long64_t entry)
+{
+// Set the environment to read one entry
+   if (!fChain) return -5;
+   Long64_t centry = fChain->LoadTree(entry);
+   if (centry < 0) return centry;
+   if (fChain->GetTreeNumber() != fCurrent) {
+      fCurrent = fChain->GetTreeNumber();
+      Notify();
+   }
+   return centry;
+}
+
+void CMS::Init(TTree *tree)
+{
+   // The Init() function is called when the selector needs to initialize
+   // a new tree or chain. Typically here the branch addresses and branch
+   // pointers of the tree will be set.
+   // It is normally not necessary to make changes to the generated
+   // code, but the routine can be extended by the user if needed.
+   // Init() will be called many times when running on PROOF
+   // (once per file to be processed).
+
+   // Set branch addresses and branch pointers
+   if (!tree) return;
+   fChain = tree;
+   fCurrent = -1;
+   fChain->SetMakeClass(1);
+
+   fChain->SetBranchAddress("cmsData", cmsData, &b_cmsData);
+   Notify();
+}
+
+Bool_t CMS::Notify()
+{
+   // The Notify() function is called when a new file is opened. This
+   // can be either for a new TTree in a TChain or when when a new TTree
+   // is started when using PROOF. It is normally not necessary to make changes
+   // to the generated code, but the routine can be extended by the
+   // user if needed. The return value is currently not used.
+
+   return kTRUE;
+}
+
+void CMS::Show(Long64_t entry)
+{
+// Print contents of entry.
+// If entry is not specified, print current entry
+   if (!fChain) return;
+   fChain->Show(entry);
+}
+Int_t CMS::Cut(Long64_t entry)
+{
+// This function may be called from Loop.
+// returns  1 if entry is accepted.
+// returns -1 otherwise.
+   return 1;
+}
+#endif // #ifdef CMS_cxx
diff --git a/TbUT/scripts/.svn/text-base/ClusterAna.C.svn-base b/TbUT/scripts/.svn/text-base/ClusterAna.C.svn-base
new file mode 100644
index 0000000..e9f8303
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ClusterAna.C.svn-base
@@ -0,0 +1,157 @@
+#define ClusterAna_cxx
+#include "ClusterAna.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+#include <iostream>
+#include <fstream>
+
+void addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  h->SetMarkerSize(0.7);
+  h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  //float bw = h->GetBinWidth(1);
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  //h->SetMarkerSize(0.7);
+  //h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void ClusterAna::Loop()
+{
+//   In a ROOT session, you can do:
+//      Root > .L ClusterAna.C
+//      Root > ClusterAna t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+   
+   TString m_board2 = m_board;
+   m_board2 = m_board2.ReplaceAll("_All","");
+   m_board2 = m_board2.ReplaceAll("_Full","");
+   m_board2 = m_board2.ReplaceAll("_v7","");
+   Long64_t nentries = fChain->GetEntriesFast();
+   TString f_out			= m_fileOutdir + plotdir + "/AnalysisOutputCluOnly_" + m_board2 + "_" + m_bias + "_" + m_sector + ".root"; 
+
+   fout = new TFile(f_out,"RECREATE");
+   TH1F* h4 = new TH1F("h4","Strip # of cluster with track",512,0.0,512);
+   TProfile *hp = new TProfile("hp","Cluster Charge vs TDC time",12,0,12,100,1000);
+   TH1F* hcAll = new TH1F("hcAll","Cluster charge",100,0.0,1000.0);
+   TH1F *hnoiseChan = new TH1F("hnoiseChan","Noise in connected channels",200,0,200);
+   TH1F *hnoiseChan2 = new TH1F("hnoiseChan2","Noise in connected channels",200,-200,200);
+
+   PrepareDUT();
+   std::cout << iLo << " " << iHi << std::endl;
+   std::cout << tdcLo << " " << tdcHi << std::endl;
+   
+
+   //nentries = 20;
+   Long64_t nbytes = 0, nb = 0;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      
+      int nn = 0;
+      for(int j=0; j<std::min(clusterNumberPerEvent,10); j++){
+        if(clustersPosition[j]>=iLo && clustersPosition[j]<=iHi) nn++;
+      }
+      if(nn != 1) continue;
+      
+      
+      for(int j=0; j<std::min(clusterNumberPerEvent,10); j++){
+        h4->Fill(clustersPosition[j]);
+        if(clustersPosition[j] < 0.1) continue;
+        //std::cout << polarity*clustersCharge[j] << " " << clustersTDC << " " << kClusterChargeMin << endl;
+        if(clustersPosition[j]>=iLo && clustersPosition[j]<=iHi && clustersTDC>1.0 && polarity*clustersCharge[j]>kClusterChargeMin 
+           && polarity*clustersCharge[j]<800) hp->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+
+        bool beamRegion = clustersPosition[j]>=iLo && clustersPosition[j]<=iHi;
+        bool goodTDC = clustersTDC>=tdcLo && clustersTDC<=tdcHi;
+        double chr2 = clustersCharge2StripRight[j]*polarity;
+        double chl2 = clustersCharge2StripLeft[j]*polarity;                
+
+        if(beamRegion && goodTDC) {
+          hcAll->Fill(polarity*clustersCharge[j]);
+          hnoiseChan2->Fill(chl2-chr2);
+          int ichan = clustersSeedPosition[j];
+          hnoiseChan->Fill(noise[ichan]);
+        }
+        
+
+      }
+      // if (Cut(ientry) < 0) continue;
+   }
+   
+   TCanvas *c = new TCanvas("c","Mon Plots",800,600);
+   c->Divide(2,2);
+   c->cd(1);
+   h4->Draw();
+   c->cd(2);
+   hp->Draw();
+   c->cd(3);
+   hcAll->Draw();
+   c->cd(4);
+   hnoiseChan->Draw();
+   
+   fout->Write();
+   
+}
diff --git a/TbUT/scripts/.svn/text-base/ClusterAna.h.svn-base b/TbUT/scripts/.svn/text-base/ClusterAna.h.svn-base
new file mode 100644
index 0000000..13a917e
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ClusterAna.h.svn-base
@@ -0,0 +1,465 @@
+//////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Feb  4 16:48:43 2016 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+// found on file: /data2/pmmannin/FullProcessing/BoardA2/Run_Bias_Scan-B2-A-1071-14008_Tuple.root
+//////////////////////////////////////////////////////////
+
+#ifndef ClusterAna_h
+#define ClusterAna_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TProfile.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TLegend.h>
+#include <TBox.h>
+#include <TLine.h>
+
+#include "AnalysisBaseCluOnly.h"
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+#include <iostream>
+#include <algorithm>
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class ClusterAna : public AnalysisBaseCluOnly{
+public :
+  
+  ClusterAna(int biasVal);
+  virtual ~ClusterAna();
+  virtual void     Loop();
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+
+};
+
+#endif
+
+#ifdef ClusterAna_cxx
+ClusterAna::ClusterAna(int biasVal) {
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+  TString filename;
+  if(biasVal != 0) m_bias = Form("%d",biasVal);
+  TTree* tree = 0;
+  TFile *f;
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     TString scanType = "Run_Bias";
+     if(m_scanType.Contains("Angle")) scanType = "Run_Angle";
+     filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple.root"; 
+
+     f = new TFile(filename);
+     tree = (TTree*)f->Get("TbUT/Clusters");
+     std::cout << "===> Opening file: " << filename << std::endl;
+   }
+
+   
+   Init(tree);
+
+   TString filename2 = filename.ReplaceAll("_Tuple","");
+   TFile *f2 = new TFile(filename2);
+   f2->cd("TbUT");
+  TH2D *hNoise = (TH2D*)gDirectory->Get("CMSData_vs_channel");
+  TF1 *gau = new TF1("gau","gaus(0)",-120,120);
+  gau->SetParameters(10000,0.0,40.0);
+
+  TH1D *px;
+  for(int i=0;i<512;i++){
+    px = hNoise->ProjectionY(Form("px%d",i),i,i);
+    px->GetXaxis()->SetRangeUser(-200,200);
+    if(px->GetEntries() < 10){
+      noise[i] = 1000;
+      continue;
+    }
+    double p = px->GetMaximum();
+    double m = px->GetMean();
+    double e = px->GetRMS();
+    gau->SetParameters(p, m, e);
+    gau->SetRange(m-3*e,m+3*e);
+
+    px->Fit(gau,"RQ");
+    double mn = gau->GetParameter(1);
+    double wid = gau->GetParameter(2);
+    double emn = gau->GetParError(1);
+    double ewid = gau->GetParError(2);
+    noise[i] = wid;
+  }
+
+
+
+}
+
+ClusterAna::~ClusterAna()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+
+TString ClusterAna::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) {
+
+  TString tag = "";
+
+  if(board.Contains("A6")){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+      if ( bias == "250" ) tag = "B6-A-213-8359";
+      if ( bias == "200" ) tag = "B6-A-214-8361";
+      if ( bias == "150" ) tag = "B6-A-215-8362";
+      if ( bias == "100" ) tag = "B6-A-216-8363";
+      if ( bias == "75" )  tag = "B6-A-219-8365";
+      if ( bias == "50" )  tag = "B6-A-220-8366";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+      if ( bias == "250" ) tag = "B6-A-245-8392";
+      if ( bias == "200" ) tag = "B6-A-246-8393";
+      if ( bias == "150" ) tag = "B6-A-247-8394";
+      if ( bias == "100" ) tag = "B6-A-248-8395";
+      if ( bias == "75" )  tag = "B6-A-249-8396";
+      if ( bias == "50" )  tag = "B6-A-250-8397";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+      if ( bias == "250" ) tag = "B6-A-294-8426";
+      if ( bias == "200" ) tag = "B6-A-295-8427";
+      if ( bias == "150" ) tag = "B6-A-296-8428";
+      if ( bias == "100" ) tag = "B6-A-297-8429";
+      if ( bias == "75" )  tag = "B6-A-298-8430";
+      if ( bias == "50" )  tag = "B6-A-299-8431";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+      if ( bias == "250" ) tag = "B6-A-327-8453";
+      if ( bias == "200" ) tag = "B6-A-328-8454";
+      if ( bias == "150" ) tag = "B6-A-329-8455";
+      if ( bias == "100" ) tag = "B6-A-330-8456";
+      if ( bias == "75" )  tag = "B6-A-331-8457";
+      if ( bias == "50" )  tag = "B6-A-332-8458";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-378-8494";
+      if ( bias == "250" ) tag = "B6-A-381-8497";
+      if ( bias == "200" ) tag = "B6-A-382-8498";
+      if ( bias == "150" ) tag = "B6-A-383-8499";
+      if ( bias == "100" ) tag = "B6-A-384-8500";
+      if ( bias == "75" )  tag = "B6-A-385-8501";
+      if ( bias == "50" )  tag = "B6-A-386-8502";
+    } else if(sector == "6"){
+      if ( bias == "300" ) tag = "B6-A-408-8523";
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+      if ( bias == "200" ) tag = "B6-A-410-8525";
+      if ( bias == "150" ) tag = "B6-A-411-8526";
+      if ( bias == "100" ) tag = "B6-A-412-8527";
+      if ( bias == "75" )  tag = "B6-A-413-8528";
+      if ( bias == "50" )  tag = "B6-A-414-8529";
+    }
+  } else if (board.Contains("A4")) {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+      if(bias == "350" ) tag = "B4-A-211-8553";
+      if(bias == "300" ) tag = "B4-A-212-8554";
+      if(bias == "250" ) tag = "B4-A-213-8555";
+      if(bias == "200" ) tag = "B4-A-214-8556";
+      if(bias == "150" ) tag = "B4-A-215-8557";
+      if(bias == "100" ) tag = "B4-A-216-8558";
+      if(bias == "75" )  tag = "B4-A-217-8559";
+      if(bias == "50" )  tag = "B4-A-218-8560";
+    }else if(sector == "2") {
+      if(bias == "400" ) tag = "B4-A-242-8583";
+      if(bias == "350" ) tag = "B4-A-243-8584";
+      if(bias == "300" ) tag = "B4-A-246-8586";
+      if(bias == "250" ) tag = "B4-A-247-8587";
+      if(bias == "200" ) tag = "B4-A-248-8588";
+      if(bias == "150" ) tag = "B4-A-249-8589";
+      if(bias == "100" ) tag = "B4-A-250-8590";
+      if(bias == "75" )  tag = "B4-A-251-8591";
+      if(bias == "50" )  tag = "B4-A-252-8592";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+      if(bias == "350" ) tag = "B4-A-276-8616";
+      if(bias == "300" ) tag = "B4-A-277-8617";
+      if(bias == "250" ) tag = "B4-A-278-8618";
+      if(bias == "200" ) tag = "B4-A-279-8619";
+      if(bias == "150" ) tag = "B4-A-280-8620";
+      if(bias == "100" ) tag = "B4-A-281-8621";
+      if(bias == "75" )  tag = "B4-A-282-8622";
+      if(bias == "50" )  tag = "B4-A-283-8623";
+    } else if(sector == "4"){
+      if(bias == "400" ) tag = "B4-A-217-8651";
+      if(bias == "350" ) tag = "B4-A-218-8652";
+      if(bias == "300" ) tag = "B4-A-219-8653";
+      if(bias == "250" ) tag = "B4-A-220-8654";
+      if(bias == "200" ) tag = "B4-A-221-8655";
+      if(bias == "150" ) tag = "B4-A-222-8656";
+      if(bias == "100" ) tag = "B4-A-223-8657";
+      if(bias == "75" )  tag = "B4-A-224-8658";
+      if(bias == "50" )  tag = "B4-A-225-8659";
+    } else if(sector == "5"){
+      if(bias == "400" ) tag = "B4-A-246-8680";
+      if(bias == "350" ) tag = "B4-A-247-8681";
+      if(bias == "300" ) tag = "B4-A-248-8682";
+      if(bias == "250" ) tag = "B4-A-249-8683";
+      if(bias == "200" ) tag = "B4-A-250-8684";
+      if(bias == "150" ) tag = "B4-A-251-8685";
+      if(bias == "100" ) tag = "B4-A-252-8686";
+      if(bias == "75" )  tag = "B4-A-253-8687";
+      if(bias == "50" )  tag = "B4-A-254-8688";
+    } else if(sector == "6"){
+      if(bias == "400" ) tag = "B4-A-227-8711";
+      if(bias == "350" ) tag = "B4-A-228-8712";
+      if(bias == "300" ) tag = "B4-A-229-8713";
+      if(bias == "250" ) tag = "B4-A-230-8714";
+      if(bias == "200" ) tag = "B4-A-231-8715";
+      if(bias == "150" ) tag = "B4-A-232-8716";
+      if(bias == "100" ) tag = "B4-A-233-8717";
+      if(bias == "75" )  tag = "B4-A-234-8718";
+      if(bias == "50" )  tag = "B4-A-235-8719";
+      tag = tag.ReplaceAll("B4","B1");
+    }
+  } else if (board.Contains("A8")) {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+      if(bias == "400") tag = "B8-A-297-13333";
+      if(bias == "350") tag = "B8-A-298-13334";
+      if(bias == "300") tag = "B8-A-299-13335";
+      if(bias == "250") tag = "B8-A-300-13336";
+      if(bias == "200") tag = "B8-A-301-13337";
+      if(bias == "150") tag = "B8-A-302-13338";
+      if(bias == "100") tag = "B8-A-303-13339";
+      if(bias == "75")  tag = "B8-A-304-13340";
+      if(bias == "50")  tag = "B8-A-305-13341";
+      if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399";
+      if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400";
+    }else if (sector == "2"){
+      //if(bias == "500") tag = "B8-A-321-13354";
+      if(bias == "400") tag = "B8-A-324-13355";
+      if(bias == "350") tag = "B8-A-325-13356";
+      if(bias == "300") tag = "B8-A-327-13357";
+      if(bias == "250") tag = "B8-A-328-13358";
+      if(bias == "200") tag = "B8-A-329-13359";
+      if(bias == "150") tag = "B8-A-330-13360";
+      if(bias == "100") tag = "B8-A-331-13361";
+      if(bias == "75")  tag = "B8-A-332-13362";
+      if(bias == "50") tag = "B8-A-333-13363";
+    }else if (sector == "3"){
+      //if(bias == "500") tag = "B8-A-358-13385";
+      if(bias == "400") tag = "B8-A-359-13386";
+      if(bias == "350") tag = "B8-A-360-13387";
+      if(bias == "300") tag = "B8-A-361-13388";
+      if(bias == "250") tag = "B8-A-365-13389";
+      if(bias == "200") tag = "B8-A-366-13390";
+      if(bias == "150") tag = "B8-A-367-13391";
+      if(bias == "100") tag = "B8-A-368-13392";
+      if(bias == "75")  tag = "B8-A-369-13393";
+      if(bias == "50")  tag = "B8-A-370-13394";
+    }else if (sector == "4"){
+      //if(bias == "500") tag = "B8-A-309-13344";
+      if(bias == "400") tag = "B8-A-311-13345";
+      if(bias == "350") tag = "B8-A-312-13346";
+      if(bias == "300") tag = "B8-A-314-13347";
+      if(bias == "250") tag = "B8-A-315-13348";
+      if(bias == "200") tag = "B8-A-316-13349";
+      if(bias == "150") tag = "B8-A-317-13350";
+      if(bias == "100") tag = "B8-A-318-13351";
+      if(bias == "75")  tag = "B8-A-319-13352";
+      if(bias == "50")  tag = "B8-A-320-13353";
+    }else if (sector == "5"){
+      //if(bias == "500") tag = "B8-A-334-13364";
+      if(bias == "400") tag = "B8-A-337-13365";
+      if(bias == "350") tag = "B8-A-339-13367";
+      if(bias == "300") tag = "B8-A-340-13368";
+      if(bias == "250") tag = "B8-A-341-13369";
+      if(bias == "200") tag = "B8-A-342-13370";
+      if(bias == "150") tag = "B8-A-343-13371";
+      if(bias == "100") tag = "B8-A-344-13372";
+      if(bias == "75")  tag = "B8-A-345-13373";
+      if(bias == "50")  tag = "B8-A-346-13374";
+      if(bias != "400") tag = tag.ReplaceAll("B8","B1");
+    }else if (sector == "6"){
+      //if(bias == "500") tag = "B8-A-347-13375";
+      if(bias == "400") tag = "B8-A-348-13376";
+      if(bias == "350") tag = "B8-A-349-13377";
+      if(bias == "300") tag = "B8-A-350-13378";
+      if(bias == "250") tag = "B8-A-352-13379";
+      if(bias == "200") tag = "B8-A-353-13380";
+      if(bias == "150") tag = "B8-A-354-13381";
+      if(bias == "100") tag = "B8-A-355-13382";
+      if(bias == "75")  tag = "B8-A-356-13383";
+      if(bias == "50")  tag = "B8-A-357-13384";
+      tag = tag.ReplaceAll("B8","B1");
+    }
+  } else if (board.Contains("D5")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B5-D-14-13066";
+      if(bias == "75") tag = "B5-D-13-13065";
+      if(bias == "100") tag = "B5-D-12-13064";
+      if(bias == "150") tag = "B5-D-11-13063";
+      if(bias == "200") tag = "B5-D-10-13062";
+      if(bias == "250") tag = "B5-D-6-13058";
+      if(bias == "300") tag = "B5-D-19-13071";
+      if(bias == "350") tag = "B5-D-4-13056";
+      if(bias == "400") tag = "B5-D-3-13055";
+      if(bias == "500") tag = "B5-D-16-13068";
+    }else if(sector == "2"){
+      if(bias == "50")  tag = "B5-D-119-13165";
+      if(bias == "75")  tag = "B5-D-118-13164";
+      if(bias == "100") tag = "B5-D-117-13163";
+      if(bias == "150") tag = "B5-D-116-13162";
+      if(bias == "200") tag = "B5-D-115-13161";
+      if(bias == "250") tag = "B5-D-114-13160";
+      if(bias == "300") tag = "B5-D-113-13159";
+      if(bias == "350") tag = "B5-D-111-13157";
+      if(bias == "400") tag = "B5-D-110-13156";
+      if(bias == "500") tag = "B5-D-109-13155";
+    }else if(sector == "3"){
+      if(bias == "50")  tag = "B5-D-167-13209";
+      if(bias == "75")  tag = "B5-D-166-13208";
+      if(bias == "100") tag = "B5-D-165-13207";
+      if(bias == "150") tag = "B5-D-164-13206";
+      if(bias == "200") tag = "B5-D-163-13205";
+      if(bias == "250") tag = "B5-D-162-13204";
+      if(bias == "300") tag = "B5-D-159-13202";
+      if(bias == "350") tag = "B5-D-158-13201";
+      if(bias == "400") tag = "B5-D-157-13200";
+      if(bias == "500") tag = "B5-D-156-13199";
+    }else if(sector == "4"){
+      if(bias == "50")  tag = "B5-D-65-13114";
+      if(bias == "75")  tag = "B5-D-64-13113";
+      if(bias == "100") tag = "B5-D-63-13112";
+      if(bias == "150") tag = "B5-D-62-13111";
+      if(bias == "200") tag = "B5-D-61-13110";
+      if(bias == "250") tag = "B5-D-59-13108";
+      if(bias == "300") tag = "B5-D-58-13107";
+      if(bias == "350") tag = "B5-D-57-13106";
+      if(bias == "400") tag = "B5-D-56-13105";
+      if(bias == "500") tag = "B5-D-55-13104";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B5-D-218-13253";
+      if(bias == "75")  tag = "B5-D-217-13252";
+      if(bias == "100") tag = "B5-D-216-13251";
+      if(bias == "150") tag = "B5-D-215-13250";
+      if(bias == "200") tag = "B5-D-214-13249";
+      if(bias == "250") tag = "B5-D-213-13248";
+      if(bias == "300") tag = "B5-D-212-13247";
+      if(bias == "350") tag = "B5-D-211-13246";
+      if(bias == "400") tag = "B5-D-210-13245";
+      if(bias == "500") tag = "B5-D-209-13244";
+    }else if(sector == "6"){
+      if(bias == "50")  tag = "B5-D-260-13294";
+      if(bias == "75")  tag = "B5-D-259-13293";
+      if(bias == "100") tag = "B5-D-258-13292";
+      if(bias == "150") tag = "B5-D-257-13291";
+      if(bias == "200") tag = "B5-D-256-13290";
+      if(bias == "250") tag = "B5-D-255-13289";
+      if(bias == "300") tag = "B5-D-254-13288";
+      if(bias == "350") tag = "B5-D-253-13287";
+      if(bias == "400") tag = "B5-D-252-13286";
+      if(bias == "500") tag = "B5-D-251-13285";
+    }
+  } else if (board.Contains("D7")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B1-D-347-9360";
+      if(bias == "75") tag = "B1-D-346-9359";
+      if(bias == "100") tag = "B1-D-344-9356";
+      if(bias == "150") tag = "B1-D-345-9357";
+      if(bias == "200") tag = "B1-D-343-9355";
+      if(bias == "300") tag = "B1-D-343-9354";
+      if(bias == "400") tag = "B1-D-341-9353";
+      if(bias == "500") tag = "B1-D-340-9272";
+    }else if(sector == "2"){
+      if(bias == "50") tag = "B1-D-471-9659";
+      if(bias == "75") tag = "B1-D-470-9658";
+      if(bias == "100") tag = "B1-D-469-9657";
+      if(bias == "150") tag = "B1-D-468-9656";
+      if(bias == "200") tag = "B1-D-467-9655";
+      if(bias == "300") tag = "B1-D-466-9654";
+      if(bias == "400") tag = "B1-D-465-9653";
+      if(bias == "500") tag = "B1-D-464-9652";
+    }else if(sector == "3"){
+      if(bias == "50") tag = "B1-D-472-9660";
+      if(bias == "75") tag = "B1-D-473-9661";
+      if(bias == "100") tag = "B1-D-474-9662";
+      if(bias == "150") tag = "B1-D-475-9663";
+      if(bias == "200") tag = "B1-D-476-9664";
+      if(bias == "300") tag = "B1-D-477-9665";
+      if(bias == "400") tag = "B1-D-478-9666";
+      if(bias == "500") tag = "B1-D-479-9667";
+    }else if(sector == "4"){
+      if(bias == "50") tag =  "B1-D-379-9424";
+      if(bias == "75") tag =  "B1-D-378-9423";
+      if(bias == "100") tag = "B1-D-377-9422";
+      if(bias == "150") tag = "B1-D-376-9421";
+      if(bias == "200") tag = "B1-D-375-9419";
+      if(bias == "300") tag = "B1-D-374-9417";
+      if(bias == "400") tag = "B1-D-373-9415";
+      if(bias == "500") tag = "B1-D-372-9413";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B1-D-489-9763";
+      if(bias == "75")  tag = "B1-D-488-9762";
+      if(bias == "100") tag = "B1-D-487-9761";
+      if(bias == "150") tag = "B1-D-484-9674";
+      if(bias == "200") tag = "B1-D-483-9673";
+      if(bias == "300") tag = "B1-D-482-9672";
+      if(bias == "400") tag = "B1-D-481-9671";
+      if(bias == "500") tag = "B1-D-480-9670";
+    }else if(sector == "6"){
+      if(bias == "50") tag =  "B1-D-321-9252";
+      if(bias == "75") tag =  "B1-D-320-9251";
+      if(bias == "100") tag = "B1-D-319-9250";
+      if(bias == "150") tag = "B1-D-318-9249";
+      if(bias == "200") tag = "B1-D-317-9248";
+      if(bias == "300") tag = "B1-D-316-9247";
+      if(bias == "400") tag = "B1-D-315-9246";
+      if(bias == "500") tag = "B1-D-314-9245";
+    }
+  } else if (board.Contains("A1")) {
+    if(sector == "1"){    
+      if(bias == "350") tag = "B1-A-1022-13947";
+      if(bias == "300") tag = "B1-A-1021-13946";
+      if(bias == "250") tag = "B1-A-1053-13971";
+      if(bias == "200") tag = "B1-A-1052-13970";
+      if(bias == "150") tag = "B1-A-1015-13939";
+      if(bias == "100") tag = "B1-A-1014-13938";
+      if(bias == "75")  tag = "B1-A-1013-13937";
+      if(bias == "50")  tag = "B1-A-1012-13936";
+    }else if(sector == "2"){
+      if(bias == "350") tag = "B1-A-1062-13980";
+      if(bias == "300") tag = "B1-A-1061-13979";
+      if(bias == "250") tag = "B1-A-1060-13978";
+      if(bias == "200") tag = "B1-A-1059-13977";
+      if(bias == "150") tag = "B1-A-1058-13976";
+      if(bias == "100") tag = "B1-A-1057-13975";
+      if(bias == "75")  tag = "B1-A-1056-13974";
+      if(bias == "50")  tag = "B1-A-1055-13973";
+    }    
+  } else if (board.Contains("A2")) {
+    if(sector == "1"){    
+      if(bias == "340") tag = "B2-A-1095-14030";
+      if(bias == "325") tag = "B2-A-1094-14029";
+      if(bias == "300") tag = "B2-A-1084-14017";
+      if(bias == "250") tag = "B2-A-1083-14016";
+      if(bias == "200") tag = "B2-A-1082-14015";
+      if(bias == "150") tag = "B2-A-1081-14014";
+      if(bias == "100") tag = "B2-A-1078-14013";
+      if(bias == "75")  tag = "B2-A-1077-14012";
+      if(bias == "50")  tag = "B2-A-1076-14011";
+    }else if(sector == "2"){
+      if(bias == "340") tag = "B2-A-1099-14034";
+      if(bias == "325") tag = "B2-A-1098-14033";
+      if(bias == "300") tag = "B2-A-1097-14032";
+      if(bias == "250") tag = "B2-A-1100-14035";
+      if(bias == "200") tag = "B2-A-1101-14036";
+      if(bias == "150") tag = "B2-A-1102-14037";
+      if(bias == "100") tag = "B2-A-1103-14038";
+      if(bias == "75")  tag = "B2-A-1104-14039";
+      if(bias == "50")  tag = "B2-A-1105-14040";
+    }    
+  }
+
+  return tag;
+}
+
+#endif // #ifdef ClusterAna_cxx
diff --git a/TbUT/scripts/.svn/text-base/ClusterWithTrackAna.C.svn-base b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna.C.svn-base
new file mode 100644
index 0000000..d5333a6
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna.C.svn-base
@@ -0,0 +1,1162 @@
+#define ClusterWithTrackAna_cxx
+//#include "ClusterWithTrackAna_Inputs.h"
+#include "ClusterWithTrackAna.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TLatex.h>
+#include <TCanvas.h>
+#include <iostream>
+#include <fstream>
+
+void addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  h->SetMarkerSize(0.7);
+  h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  //float bw = h->GetBinWidth(1);
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  //h->SetMarkerSize(0.7);
+  //h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+
+void ClusterWithTrackAna::Loop()
+{
+//   In a ROOT session, you can do:
+//      Root > .L ClusterWithTrackAna.C
+//      Root > ClusterWithTrackAna t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+
+   Int_t nentries = fChain->GetEntriesFast();
+
+   TString m_board2 = m_board;
+   m_board2 = m_board2.ReplaceAll("_All","");
+   m_board2 = m_board2.ReplaceAll("_Full","");
+   m_board2 = m_board2.ReplaceAll("_v7","");
+   TString f_out = m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + ".root";
+   if(m_angle != "0"){
+     f_out			= m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + "_" + m_angle + ".root";
+   }
+   cout << "Will write out file: " << f_out << endl;
+   
+
+
+   fout = new TFile(f_out,"RECREATE");
+
+   TH1F* h0 = new TH1F("h0","#DeltaX between strip hit and track projection (strips)",101,-50.5,50.5);
+   TH1F* h1 = new TH1F("h1","#DeltaX",800,-2.0,2.0);
+   TH2F* h1vsx = new TH2F("h1vsx","#DeltaX vs X",50,-5,5,100,-0.2,0.2);
+   TH1F* h1mpa = new TH1F("h1mpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1mbpa = new TH1F("h1mbpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fpa = new TH1F("h1fpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fbpa = new TH1F("h1fbpa","#DeltaX",400,-20.0,20.0);
+
+   TH1F* h1mpa1 = new TH1F("h1mpa1","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa2 = new TH1F("h1mpa2","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa3 = new TH1F("h1mpa3","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa4 = new TH1F("h1mpa4","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa5 = new TH1F("h1mpa5","#DeltaX",800,-20.0,20.0);
+
+   TH1F* h1mpaL = new TH1F("h1mpaL","Strip# of Missed Hit in Lower PA region",512,0,512);
+   TH1F* h1mpaU = new TH1F("h1mpaU","Strip# of Missed Hit in Upper PA region",512,0,512);
+
+
+   TH1F* h1s = new TH1F("h1s","Seed strip of cluster",512,0.0,512.0);
+   TH1F* h1a = new TH1F("h1a","#DeltaX, 1 strip",800,-2.0,2.0);
+   TH1F* h1b = new TH1F("h1b","#DeltaX, 2 strip",800,-2.0,2.0);
+   TH1F* h1z = new TH1F("h1z","#DeltaX, low Charge",800,-2.0,2.0);
+   TH1F* h1w = new TH1F("h1w","#DeltaX",20000,-100.0,100.0);
+   TH1F* h1wY = new TH1F("h1wY","#DeltaX",20000,-100.0,100.0);
+   TH2F* h2 = new TH2F("h2","X_{DUT} vs X_{trk}",100,-8.0,8.0,100,-8,8);
+   TH2F* h3 = new TH2F("h3","Y_{trk} vs X_{trk}, with cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3a = new TH2F("h3a","Y_{trk} vs X_{trk} in fiducial",640,-8,8.0,640,-8,8);
+   TH2F* h3b = new TH2F("h3b","Y_{trk} vs X_{trk}, with missed cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3c = new TH2F("h3c","Y_{trk} vs X_{trk}, with found cluster",640,-8,8.0,640,-8,8);
+   TH1F* h4 = new TH1F("h4","Detector strip # of cluster with track",512,0.0,512);
+   TH1F* h4a = new TH1F("h4a","Electonic Strip # of cluster with track",512,0.0,512);
+   TH1F* h4b = new TH1F("h4b","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h4c = new TH1F("h4c","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h5 = new TH1F("h5","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6 = new TH1F("h6","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5c = new TH1F("h5c","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6c = new TH1F("h6c","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5a = new TH1F("h5a","X position of track",400,-10.0,10.0);
+   TH1F* h6a = new TH1F("h6a","Y position of track",400,-10.0,10.0);
+   TH1F* h5b = new TH1F("h5b","X position of matched cluster",400,-10.0,10.0);
+   TH1F* h6b = new TH1F("h6b","Y position of matched cluster",400,-10.0,10.0);
+
+   TProfile *h8 = new TProfile("h8","#DeltaX vs #theta_{trk}",100,-5,5,-1.0,1.0);
+   TProfile *h9 = new TProfile("h9","#DeltaX vs Y_{trk} at DUT",1600,-8,8,-1.0,1.0);
+   TProfile *h9a = new TProfile("h9a","#DeltaX vs X_{trk} at DUT",20,-5,5,-1.0,1.0);
+
+   TProfile *h10a = new TProfile("h10a","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10b = new TProfile("h10b","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10c = new TProfile("h10c","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10d = new TProfile("h10d","<ADC> vs Y_{trk}",100,-8,8,0.0,1000.0);
+   TProfile *h10e = new TProfile("h10e","<ADC> vs X_{trk}",100,-8,8,0.0,1000.0);
+   TH1F* h11n = new TH1F("h11n","Strip # of matched cluster",512,0.0,512);
+   TH1F* h11d = new TH1F("h11d","Strip # of track",512,0.0,512);
+   h11n->Sumw2();
+   h11d->Sumw2();
+   
+   TH1F* h12 = new TH1F("h12","Y position of matched cluster",400,-10.0,10.0); h12->Sumw2();
+   TH1F* h12c = new TH1F("h12c","X position of matched cluster",400,-10.0,10.0);h12c->Sumw2();
+   TH1F* h12a = new TH1F("h12a","Y position of track",1600,-10.0,10.0); h12a->Sumw2();
+   TH1F* h12b = new TH1F("h12b","Y position of track",1600,-10.0,10.0); h12b->Sumw2();
+
+   TH1F* h12dn = new TH1F("h12dn","X position of track",200,-10.0,10.0); h12dn->Sumw2();
+   TH1F* h12en = new TH1F("h12en","X position of track",200,-10.0,10.0);h12en->Sumw2();
+   TH1F* h12fn = new TH1F("h12fn","X position of track",200,-10.0,10.0);h12fn->Sumw2();
+   TH1F* h12gn = new TH1F("h12gn","X position of track",200,-10.0,10.0);h12gn->Sumw2();
+   TH1F* h12dd = new TH1F("h12dd","X position of track",200,-10.0,10.0);h12dd->Sumw2();
+   TH1F* h12ed = new TH1F("h12ed","X position of track",200,-10.0,10.0);h12ed->Sumw2();
+   TH1F* h12fd = new TH1F("h12fd","X position of track",200,-10.0,10.0);h12fd->Sumw2();
+   TH1F* h12gd = new TH1F("h12gd","X position of track",200,-10.0,10.0);h12gd->Sumw2();
+
+   TH1F* h12hn = new TH1F("h12hn","X position of track",50,-0.5,0.5);h12hn->Sumw2();
+   TH1F* h12in = new TH1F("h12in","X position of track",50,-0.5,0.5);h12in->Sumw2();
+   TH1F* h12jn = new TH1F("h12jn","X position of track",50,-0.5,0.5);h12jn->Sumw2();
+   TH1F* h12kn = new TH1F("h12kn","X position of track",50,-0.5,0.5);h12kn->Sumw2();
+   TH1F* h12hd = new TH1F("h12hd","X position of track",50,-0.5,0.5);h12hd->Sumw2();
+   TH1F* h12id = new TH1F("h12id","X position of track",50,-0.5,0.5);h12id->Sumw2();
+   TH1F* h12jd = new TH1F("h12jd","X position of track",50,-0.5,0.5);h12jd->Sumw2();
+   TH1F* h12kd = new TH1F("h12kd","X position of track",50,-0.5,0.5);h12kd->Sumw2();
+
+   TProfile *h12m = new TProfile("h12m","<ADC> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+   TProfile *h12n = new TProfile("h12n","<ClusterSize> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+
+   TH1F* h12on = new TH1F("h12on","dist of track to cutout",700,-2.0,5.0);h12on->Sumw2();
+   TH1F* h12od = new TH1F("h12od","dist of track to cutout",700,-2.0,5.0);h12od->Sumw2();
+
+   TH1F *h13mpa = new TH1F("h13mpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13mbpa = new TH1F("h13mbpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fpa = new TH1F("h13fpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fbpa = new TH1F("h13fbpa","#Clusters/Ev",10,-0.5,9.5);   
+
+   TH1F* h14a = new TH1F("h14a","Nom Strip, no matched cluster",512,0.0,512);
+   TH1F* h14b = new TH1F("h14b","Nom Strip, matched cluster",512,0.0,512);
+
+   TH1F *h15a = new TH1F("h15a","Chisq of tracks with matched DUT hit",200,0.0,200.0);
+   TH1F *h15b = new TH1F("h15b","TDC time with matched DUT hit",12,0.0,12.0);
+   TH1F *h15c = new TH1F("h15c","Time Between Trigger and Track",5,0.0,5.0);
+   TH1F *h15d = new TH1F("h15d","TDC time of all clusters",12,0.0,12.0);
+   TH1F *h15e = new TH1F("h15e","TDC time of good clusters",12,0.0,12.0);
+
+   TH1F *h16a = new TH1F("h16a","Chisq of tracks without matched DUT hit",200,0.0,200.0);
+   TH1F *h16b = new TH1F("h16b","TDC time without matched DUT hit",12,0.0,12.0);
+   TH1F *h16c = new TH1F("h16c","Time Between Trigger and Track",5,0.0,5.0);
+   h15c->Sumw2();
+   h16c->Sumw2();
+   
+   TH1F* h17 = new TH1F("h17","Q_{L} / (Q_{L}+Q_{R})",50,0.0,1.0);
+   TH2F* h17a = new TH2F("h17a","Q_{L} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,120,-0.1,1.1);
+   TProfile* h17b = new TProfile("h17b","Q_{R} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,-0.1,1.1);
+
+   TH1F* hcmpa = new TH1F("hcmpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcmbpa = new TH1F("hcmbpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfpa = new TH1F("hcfpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfbpa = new TH1F("hcfbpa","Cluster charge",100,0.0,1000.0);
+
+   TH1F* h18a = new TH1F("h18a","Seed/Total charge",100,0.0,2.0);
+
+   TH2F* h18b = new TH2F("h18b","#DeltaX vs Interstrip Pos (1 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18c = new TH2F("h18c","#DeltaX vs Interstrip Pos (2 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18d = new TH2F("h18d","Seed/Total charge vs Interstrip Pos",100,-0.5,0.5,100,0.0,1.1);
+
+   TH1F* hcTrkXY[16];
+   for(int i=0; i<4; i++){
+     for(int j=0; j<4; j++){
+       int iblock = 4*i+j; 
+       TString hname = Form("hcTrkXY_%d",iblock+1);     
+       TString htitle = Form("Cluster charge, block %d",iblock+1);     
+       hcTrkXY[iblock]= new TH1F(hname,htitle,100,0.0,1000.0);
+     }
+   }
+   
+   TH1F *hlandau[512];
+   for(int i=0; i<nChan; i++){
+     hlandau[i] = new TH1F(Form("hlandau_%d",i),"Cluster charge",100,0.0,1000.0);
+   }
+   
+
+
+   TH1F* hcAll = new TH1F("hcAll","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrk = new TH1F("hcTrk","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkCorr = new TH1F("hcTrkCorr","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed = new TH1F("hcTrkSeed","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed1 = new TH1F("hcTrkSeed1","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed2 = new TH1F("hcTrkSeed2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY1 = new TH1F("hcTrkY1","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY2 = new TH1F("hcTrkY2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY3 = new TH1F("hcTrkY3","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY4 = new TH1F("hcTrkY4","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkNoTop = new TH1F("hcTrkNoTop","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkLowX = new TH1F("hcTrkLowX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkHighX = new TH1F("hcTrkHighX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrka = new TH1F("hcTrka","Cluster charge, limited region",100,0.0,1000.0);
+   TH1F* hcTrk1 = new TH1F("hcTrk1","Cluster charge, Size = 1",100,0.0,1000.0);
+   TH1F* hcTrk2 = new TH1F("hcTrk2","Cluster charge, Size = 2",100,0.0,1000.0);
+   TProfile *h2p = new TProfile("h2p","Cluster Charge vs TDC time",12,0,12,100,1000);
+
+
+   TH2F* h31a = new TH2F("h31a","Y_{trk} vs X_{trk}, with cluster",64,-8,8.0,64,-8,8);
+   TH2F* h31b = new TH2F("h31b","Y_{trk} vs X_{trk}, with cluster, low ADC",64,-8,8.0,64,-8,8);
+   TH1F* h32a = new TH1F("h32a","Strip # of cluster with track",512,0.0,512);
+   TH1F* h32b = new TH1F("h32b","Strip # of cluster with track & low ADC",512,0.0,512);
+   TH1F* h33a = new TH1F("h33a","Y position of matched cluster",200,-10.0,10.0);
+   TH1F* h33b = new TH1F("h33b","X position of matched cluster",200,-10.0,10.0);
+   TH1F* h34 = new TH1F("h34","Y position of matched cluster & low ADC",200,-10.0,10.0);
+
+   TH1F *hnoise = new TH1F("hnoise","Noise in connected channels",100,-200,200);
+   TH1F *hnoiseChan = new TH1F("hnoiseChan","Noise in connected channels",200,0,200);
+   TH1F *hnoisePerChannel = new TH1F("hnoisePerChannel","Noise",512,0,512);
+
+   TH1F* h35 = new TH1F("h35","No. clusters / event",50,0.0,50.0);
+   
+   TH1F *h41[10];
+   TH1F *h42[10];
+   TH1F *h43[10];
+   TH1F *h44[10];
+   for(int i=0; i<10; i++){
+     h41[i] = new TH1F(Form("h41_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h42[i] = new TH1F(Form("h42_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h43[i] = new TH1F(Form("h43_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+     h44[i] = new TH1F(Form("h44_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+   }
+
+   for(int i=0; i<nChan; i++){
+     hnoisePerChannel->Fill(i+0.5,noise[i]);
+   }
+   
+
+
+   //------------------------------------------------------------------------------------------------------
+   
+   //-----------------------------
+   // Prepare DUT (Alignment, etc)
+   //-----------------------------
+
+   PrepareDUT();
+   //return;
+   float biasVal = atof(m_bias);
+   cout << "chargeCorrSlopeOdd, chargeCorrSlopeEven = " << chargeCorrSlopeOdd << " " << chargeCorrSlopeEven << " " 
+        << m_bias << " " << biasVal << endl;
+   
+
+   std::ofstream myfile;
+   if(writeEventsWithMissinhHitsToFile){
+     myfile.open("MissingDUTHits.dat");
+   }
+
+   int iChan = nChan;
+   double nomStrip = 0, detStrip = 0;
+   int nPrint = 0;
+   double dxh[10];
+   int njump = 10000;
+   if(nentries > 100000) njump = 50000;
+   Long64_t nbytes = 0, nb = 0;
+   cout << "Begin loop over " << nentries << " events" << endl;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      if(jentry%njump==0) cout << "====> At entry = " << jentry << endl;
+      if(n_tp3_tracks != 1) continue;
+
+      //==========================================
+      // Example here of acccessing CMS strip data
+      //==========================================
+      if(fCMS){
+        for(int k=0;k<iChan;k++){
+          if(fCMS->cmsData[k]!=0) hnoise->Fill(fCMS->cmsData[k]);
+        }      
+      }
+
+      h35->Fill(clusterNumberPerEvent);
+      if(clusterNumberPerEvent>10) continue;
+      
+      
+      // Loop over TPIX tracks in event
+      for(int k=0; k<n_tp3_tracks; k++){
+        if(dtime > trackTriggerTimeDiffCut) continue;
+        double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+        double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+        
+        transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip);
+
+        //if(isInCutoutRegion(x_trk, y_trk)) continue;
+        double distToCutout = DistToCutoutRegion(x_trk, y_trk);
+        bool awayFromCutout = distToCutout > minDistFromHole;
+
+        int closestStrip = nomStrip;
+        double fracStrip = nomStrip - closestStrip - 0.5;
+
+        double tx = 1000*vec_trk_tx->at(k);
+        double ty = 1000*vec_trk_ty->at(k);
+
+        h5->Fill(tx);
+        h6->Fill(ty);
+
+        // Test cuts here, e.g.  to reject regions
+        //if(nomStrip<422 || nomStrip>442) continue;
+        //if(y_trk>2.4) continue;
+        //if(nomStrip<420 || nomStrip>445) continue;
+        
+
+        bool goodRegion = true;
+        for(int id = 0; id<nDeadRegion; id++){
+          if(x_trk>=deadRegionLo[id]  && x_trk<=deadRegionHi[id]) goodRegion = false;  
+        }
+        if(!goodRegion) continue;
+
+        h5a->Fill(x_trk);
+        h6a->Fill(y_trk);
+        bool goodTrack = false;
+        bool inFiducialX = false;
+        bool inFiducialY = false;
+
+        if(x_trk>xMin && x_trk<xMax) inFiducialX = true;          
+        if(y_trk>yMin && y_trk<yMax) inFiducialY = true;          
+        bool inFiducial = inFiducialX && inFiducialY;
+        inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+        
+        if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+        bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+        if(goodTrack && goodTime && inFiducial) h12od->Fill(distToCutout);
+
+        if(goodTrack && goodTime && inFiducial && awayFromCutout) {
+          h3a->Fill(x_trk,y_trk);
+          h12a->Fill(y_trk);
+          h12dd->Fill(x_trk);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12ed->Fill(x_trk);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fd->Fill(x_trk);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gd->Fill(x_trk);
+          h12hd->Fill(fracStrip);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12id->Fill(fracStrip);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jd->Fill(fracStrip);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kd->Fill(fracStrip);
+        }
+        
+        bool foundHit = false;
+        bool foundHitNoFid = false;
+        double x_trk0 = x_trk;
+        for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+          dxh[j] = -999;
+          if(clustersPosition[j] < 0.1) continue;
+          if(polarity*clustersCharge[j] < 0.2*kClusterChargeMin) continue;
+          double x_dut = getDUTHitPosition(j);
+          x_trk = x_trk0;
+       
+          int iPeak = 1;
+          if(clustersSeedPosition[j]%2==0) iPeak = 0;
+          
+          h1s->Fill(clustersSeedPosition[j]);
+          if(clustersSeedPosition[j]<iLo-5 || clustersSeedPosition[j]>iHi+5) continue;
+
+          double dx = x_dut - x_trk;
+          dxh[j] = dx;
+
+          if(inFiducial && goodTime && awayFromCutout) h12->Fill(y_trk); 
+          if(goodTrack && inFiducial && fabs(dx)<dxWin && awayFromCutout) {
+            h2p->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+            h15d->Fill(clustersTDC);          
+            if(goodTime) h15e->Fill(clustersTDC);          
+          }
+          
+
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin){
+            h3->Fill(x_trk,y_trk);
+          }
+          
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin) foundHitNoFid = true;
+
+
+          if(goodTrack && inFiducial && goodTime && awayFromCutout) {
+            hcAll->Fill(polarity*clustersCharge[j]);
+            h2->Fill(x_trk, x_dut);
+            h1->Fill(dx);
+            if(clustersSize[j]==1) h1a->Fill(dx);
+            if(clustersSize[j]==2) h1b->Fill(dx);
+            h1w->Fill(dx);
+            if(y_trk>2.5) h1wY->Fill(dx);
+            if(polarity*clustersCharge[j] < 250) h1z->Fill(dx);
+            h11d->Fill(detStrip);        
+            
+            if(fabs(dx)<dxWin) {
+              int ichan = clustersSeedPosition[j];
+              h4c->Fill(clustersSeedPosition[j]);
+              if(ichan>=0 && ichan<=511){
+                hlandau[ichan]->Fill(polarity*clustersCharge[j]);
+              }
+              
+              hnoiseChan->Fill(noise[ichan]);
+              h18a->Fill(clustersSeedCharge[j]/clustersCharge[j]);
+              foundHit = true;
+              if(clustersSize[j]==1) h18b->Fill(fracStrip,dx);
+              if(clustersSize[j]==2) h18c->Fill(fracStrip,dx);
+              h18d->Fill(fracStrip,clustersSeedCharge[j]/clustersCharge[j]);
+              
+              h12m->Fill(fracStrip,polarity*clustersCharge[j]);
+              h12n->Fill(fracStrip,clustersSize[j]);
+              h1vsx->Fill(x_trk,dx);
+              if(y_trk>yMid&&y_trk<yMax) h10a->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yMin&&y_trk<yMid) h10b->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yHi2&&y_trk<yMax) h10c->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              h10d->Fill(y_trk,polarity*clustersCharge[j]);
+              h10e->Fill(x_trk,polarity*clustersCharge[j]);
+              double chleft = polarity*clustersCharge1StripLeft[j];
+              double chright = polarity*clustersCharge1StripRight[j];
+              double rc = -999;
+              if(detStrip <= clustersSeedPosition[j]) {
+                if(chleft>0) rc = (chleft/(chleft+clustersSeedCharge[j]));              
+              }else{ 
+                if(chright>0) rc = (clustersSeedCharge[j]/(chright+clustersSeedCharge[j]));
+              }
+              if( rc>=0 ) {
+                h17->Fill(rc);
+                h17a->Fill(fracStrip,rc);
+                h17b->Fill(fracStrip,rc);
+              }
+              h8->Fill(1000*vec_trk_tx->at(k),dx);    
+              h9->Fill(y_trk,dx);
+              h9a->Fill(x_trk,dx);
+              h5b->Fill(x_trk);
+              h6b->Fill(y_trk);
+              h5c->Fill(tx);
+              h6c->Fill(ty);
+
+              h11n->Fill(detStrip);
+              hcTrk->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==1) hcTrkCorr->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2 && iPeak==1) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeOdd));
+              if(clustersSize[j]==2 && iPeak==0) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeEven));
+              hcTrkSeed->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==1) hcTrkSeed1->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==2) hcTrkSeed2->Fill(polarity*clustersSeedCharge[j]);
+              if(y_trk - yMax < 5.0) hcTrkNoTop->Fill(polarity*clustersCharge[j]);
+              if(x_trk < (xMin+xMax)/2.) hcTrkLowX->Fill(polarity*clustersCharge[j]);
+              if(x_trk >= (xMin+xMax)/2.) hcTrkHighX->Fill(polarity*clustersCharge[j]);
+              int ix = 4*(x_trk - xMin - 0.001) / (xMax-xMin);
+              int iy = 4*(y_trk - yMin - 0.001) / (yMax-yMin);
+              int ihist = 4*ix + iy;
+              hcTrkXY[ihist]->Fill(polarity*clustersCharge[j]);              
+              //if(y_trk>yMin && y_trk<=(yMin+0.25*yRange)) hcTrkY1->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.25*yRange) && y_trk<(yMin+0.50*yRange)) hcTrkY2->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.50*yRange) && y_trk<(yMin+0.75*yRange)) hcTrkY3->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.75*yRange) && y_trk<(yMin+1.00*yRange)) hcTrkY4->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>yMin&&y_trk<yMid+1.0) hcTrkY2->Fill(polarity*clustersCharge[j]);
+
+              if(clustersSize[j]==1) hcTrk1->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2) hcTrk2->Fill(polarity*clustersCharge[j]);
+              if(clustersPosition[j]>170  && clustersPosition[j]<190) hcTrka->Fill(polarity*clustersCharge[j]);
+              h31a->Fill(x_trk,y_trk);
+              h32a->Fill(clustersPosition[j]);
+              h33a->Fill(y_trk);
+              h33b->Fill(x_trk);
+              if(polarity*clustersCharge[j] < 250) {
+                h31b->Fill(x_trk,y_trk);
+                h32b->Fill(clustersPosition[j]);
+                h34->Fill(y_trk);
+              }
+              double chr = clustersCharge1StripRight[j]*polarity;
+              double chl = clustersCharge1StripLeft[j]*polarity;
+              double chr2 = clustersCharge2StripRight[j]*polarity;
+              double chl2 = clustersCharge2StripLeft[j]*polarity;
+              double pch = polarity*clustersSeedCharge[j];
+              int ic = pch/50.;
+              if(ic>=0 && ic<10 && clustersSize[j]<=2 ){
+                if(iPeak==1) h41[ic]->Fill(chl-chr);
+                if(iPeak==0) h42[ic]->Fill(chl-chr);
+                if(chr2!=0 and chl2!=0){
+                  if(iPeak==1) h43[ic]->Fill(chl2-chr2);
+                  if(iPeak==0) h44[ic]->Fill(chl2-chr2);
+                }
+                
+              } 
+            }
+
+            double clstrip = getCorrChannel(clustersPosition[j]);
+            h4->Fill(clstrip);
+            h4b->Fill(clstrip + channelOffset);
+            h4a->Fill(clustersPosition[j]);
+            h0->Fill(detStrip - clstrip);
+          }
+        }
+
+        if(inFiducial && goodTrack && goodTime && foundHitNoFid) {
+          h12on->Fill(distToCutout);
+        }
+        
+        if(inFiducial && goodTrack && goodTime && awayFromCutout) {
+          h16c->Fill(dtime);
+          if(foundHit) {
+            h3c->Fill(x_trk,y_trk);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcfpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1fpa->Fill(dxh[j]);
+            }        
+            h15c->Fill(dtime);
+            h15b->Fill(clustersTDC+0.1);
+            h15a->Fill(vec_trk_chi2ndf->at(k));
+            h12b->Fill(y_trk);
+            h12dn->Fill(x_trk); 
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12en->Fill(x_trk);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fn->Fill(x_trk);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gn->Fill(x_trk);
+            h12hn->Fill(fracStrip);
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12in->Fill(fracStrip);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jn->Fill(fracStrip);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kn->Fill(fracStrip);
+            if(y_trk>yInt1[0] && y_trk < yInt2[1] && x_trk>-3.5&&x_trk<-2.0) {
+              h14b->Fill(detStrip);
+              h13fpa->Fill(clusterNumberPerEvent);
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13fbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                h1fbpa->Fill(dxh[j]);
+                hcfbpa->Fill(polarity*clustersCharge[j]);
+              }
+            }                
+          }else{     
+            h3b->Fill(x_trk,y_trk);          
+            h13mpa->Fill(clusterNumberPerEvent);
+            h16a->Fill(vec_trk_chi2ndf->at(k));
+            h16b->Fill(clustersTDC+0.1);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcmpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1mpa->Fill(dxh[j]);
+            }            
+            nPrint++;
+            if(y_trk>yInt1[0] && y_trk < yInt2[1]) {
+              h14a->Fill(detStrip);
+              if(writeEventsWithMissinhHitsToFile) 
+                myfile << jentry << " " << detStrip << " " << x_trk << " " << y_trk << endl;              
+              //if(nPrint < 100) cout << "Missed hit, event, #clu, nomStrip =  " << jentry << " " 
+              //                      << clusterNumberPerEvent << " " << nomStrip << endl;
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                if(x_trk>-3.5&&x_trk<-2.0) h1mpa1->Fill(dxh[j]);
+                if(x_trk>-2.0&&x_trk<-1.0) h1mpa2->Fill(dxh[j]);
+                if(x_trk>-1.0&&x_trk<0.0) h1mpa3->Fill(dxh[j]);
+                if(x_trk>0.0&&x_trk<1.0)  h1mpa4->Fill(dxh[j]);
+                if(x_trk>1.5&&x_trk<3.5)  h1mpa5->Fill(dxh[j]);
+                if(y_trk<yInt1[1]) h1mpaL->Fill(clustersPosition[j]);                         
+                if(y_trk>=yInt1[1]) h1mpaU->Fill(clustersPosition[j]);
+              }
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13mbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){              
+                h1mbpa->Fill(dxh[j]);
+                hcmbpa->Fill(polarity*clustersCharge[j]);
+              }    
+            }
+          }
+        } 
+      }
+   }
+   if(writeEventsWithMissinhHitsToFile) myfile.close();
+
+   int i1 = h1->FindBin(-0.3);
+   int i2 = h1->FindBin(0.3);
+   cout << "Number of track - DUT hit matchs: " << h1->Integral(i1,i2) << endl;
+   cout << "Ry = " << Ry << endl;
+   
+   
+   TString r1 = Form("%6.3f < Y < %6.3f mm",yInt1[0], yInt1[1]);
+   TString r2 = Form("%6.3f < Y < %6.3f mm ",yInt2[0], yInt2[1]);
+   TString r3 = Form("%6.3f < Y < %6.3f mm",yInt3[0], yInt3[1]);   
+
+
+   TF1 *funchole = new TF1("funchole","[0]+[1]*x+[2]*x*x",-8.0,8.0);
+   funchole->SetParameters(holeQuadPar[0],holeQuadPar[1],holeQuadPar[2]);
+   funchole->SetLineColor(4);
+   funchole->SetLineWidth(2);
+   cout << "Hole Parameters: " << holeQuadPar[0] << " " << holeQuadPar[1] << " " << holeQuadPar[2] << endl;
+   
+   gStyle->SetOptStat(1000000001);
+   gStyle->SetOptFit(0011);
+   gStyle->SetStatH(0.05);
+   gStyle->SetStatW(0.2);
+
+   addGraphics(h3b, 1, "X_{trk} [mm]", "Y_{trk} [mm] ");
+   h3b->GetXaxis()->SetRangeUser(-5,5);
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+
+   TCanvas *c = new TCanvas("c","Residuals",1500,1000);
+   c->Divide(4,3);
+   c->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h2, 1, "X_{trk} [mm]", "X_{DUT} [mm]");
+   double dM = yMax;
+   if(xMax>dM) dM = xMax;
+   h2->GetXaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->GetYaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->SetMinimum(1);
+   h2->Draw();
+
+   c->cd(2)->SetLeftMargin(0.13);;
+   addGraphics(h1, 1, "#DeltaX [mm]", "");
+   addGraphics(h1z, 2, "#DeltaX [mm]", "");
+   addGraphics(h1a, 3, "#DeltaX [mm]", "");
+   addGraphics(h1b, 6, "#DeltaX [mm]", "");
+   h1->GetXaxis()->SetRangeUser(-0.3,0.3);
+   if(m_board.Contains("A1")) h1->GetXaxis()->SetRangeUser(-1.5,1.5);
+   h1->SetMaximum(1.2*h1->GetMaximum());
+   h1->Draw();   
+   //h1z->Draw("same");
+   h1a->Draw("same");
+   h1b->Draw("same");
+   TLine *l1 = new TLine(-stripPitch/2.,0,-stripPitch/2.,0.5*h1->GetMaximum());
+   TLine *l2 = new TLine(stripPitch/2,0,stripPitch/2,0.5*h1->GetMaximum());
+   TLine *l1a = new TLine(-dxWin,0,-dxWin,0.5*h1->GetMaximum());
+   TLine *l2a = new TLine(dxWin,0,dxWin,0.5*h1->GetMaximum());
+   l1->SetLineColor(kRed); l2->SetLineColor(kRed);
+   l1a->SetLineColor(kBlue); l2a->SetLineColor(kBlue); l1a->SetLineWidth(2); l2a->SetLineWidth(2);
+   l1->Draw(); l2->Draw();
+   //l1a->Draw(); l2a->Draw();
+
+   TLegend* legend3 = new TLegend(0.15,0.70,0.40,0.89);
+   legend3->SetFillStyle(0);
+   legend3->SetBorderSize(0);
+   legend3->SetFillStyle(0);
+   legend3->SetTextSize(0.045);
+   
+   legend3->AddEntry(h1,"All","L"); 
+   //legend3->AddEntry(h1z,"ADC < 250","L"); 
+   legend3->AddEntry(h1a,"1-strip","L"); 
+   legend3->AddEntry(h1b,"2-strip","L"); 
+   legend3->Draw();
+   
+   c->cd(3)->SetLeftMargin(0.13);;
+   addGraphics(h8, 1, "#theta_{X}^{trk} [mrad]", "#DeltaX [mm]");
+   h8->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h8->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h8->Draw();
+   c->cd(4)->SetLeftMargin(0.13);;
+   addGraphics(h9, 1, "Y^{trk} [mm]", "#DeltaX [mm]");
+   h9->GetXaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h9->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9->Draw();
+   c->cd(5)->SetLeftMargin(0.13);;
+   addGraphics(h9a, 1, "X^{trk} [mm]", "#DeltaX [mm]");
+   h9a->GetXaxis()->SetRangeUser(-4,4);   
+   h9a->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9a->Draw();
+
+   c->cd(6)->SetLeftMargin(0.13);;
+   addGraphics(h3, 1, "X_{trk} [mm]", "Y_{trk} [mm]");
+   h3->GetXaxis()->SetRangeUser(xMin-1,xMax+1);   
+   h3->GetYaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h3->Draw();
+   if(holeQuadPar[0]!=0) funchole->Draw("same");
+   if(fabs(xLeftHole)<900 && fabs(xRightHole)<900){
+     TBox *b1 = new TBox(xMin,yMin,xLeftHole,yMax);
+     TBox *b2 = new TBox(xRightHole,yMin,xMax,yMax);
+     b1->SetLineColor(kBlue); b1->SetLineWidth(2);b1->SetFillStyle(0);   
+     b1->Draw();
+     b2->SetLineColor(kBlue); b2->SetLineWidth(2);b2->SetFillStyle(0);   
+     b2->Draw();
+   }else{   
+     TBox *b = new TBox(xMin,yMin,xMax,yMax);
+     b->SetLineColor(kBlue); b->SetLineWidth(2);b->SetFillStyle(0);   
+     b->Draw();
+   }
+   
+
+   c->cd(7)->SetLeftMargin(0.13);;
+   addGraphics(h5, 1, "#theta_{X}^{trk} [mrad]", "");
+   h5->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h5->Draw();
+   h5c->SetLineColor(2); h5c->Draw("same");
+   TLine *l1b = new TLine(txMin,0,txMin,h5->GetMaximum());
+   TLine *l2b = new TLine(txMax,0,txMax,h5->GetMaximum());
+   l1b->SetLineColor(kBlue); l2b->SetLineColor(kBlue); l1b->SetLineWidth(2); l2b->SetLineWidth(2);
+   l1b->Draw(); l2b->Draw();
+
+   c->cd(8)->SetLeftMargin(0.13);
+   addGraphics(h6, 1, "#theta_{Y}^{trk} [mrad]", "");
+   h6->GetXaxis()->SetRangeUser(tyMin-0.1,tyMax+0.1);   
+   h6->Draw();
+   h6c->SetLineColor(2); h6c->Draw("same");
+   TLine *l1c = new TLine(tyMin,0,tyMin,h6->GetMaximum());
+   TLine *l2c = new TLine(tyMax,0,tyMax,h6->GetMaximum());
+   l1c->SetLineColor(kBlue); l2c->SetLineColor(kBlue); l1c->SetLineWidth(2); l2c->SetLineWidth(2);   
+   l1c->Draw(); l2c->Draw();
+   
+   c->cd(9)->SetLeftMargin(0.13);;
+   addGraphics(h4, 1, "Strip # with cluster", "");
+   addGraphics(h4a, 2, "Strip # with cluster", "");
+   h4->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   h4a->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   double vmax = h4a->GetMaximum();
+   //for(int ii=iLo; ii<=iHi;ii++){
+   //  if(h4a->GetBinContent(ii)>vmax) vmax = h4a->GetBinContent(ii);
+   //}
+   h4->SetMaximum(1.25*vmax);
+   TLine *l1d = new TLine(iLo,0,iLo,0.75*h4a->GetMaximum());
+   TLine *l2d = new TLine(iHi,0,iHi,0.75*h4a->GetMaximum());
+   l1d->SetLineColor(kBlue); l2d->SetLineColor(kBlue); l1d->SetLineWidth(2); l2d->SetLineWidth(2);   
+   h4->Draw();
+   h4a->Draw("same");
+   l1d->Draw(); l2d->Draw();
+   
+   TLegend* legend4 = new TLegend(0.15,0.70,0.94,0.89);
+   legend4->SetFillStyle(0);
+   legend4->SetBorderSize(0);
+   legend4->SetFillStyle(0);
+   legend4->SetTextSize(0.045);
+   
+   legend4->AddEntry(h4,"Sensor strip ch #","L"); 
+   legend4->AddEntry(h4a,"Electr. ch #","L");
+
+   legend4->Draw();
+
+
+   c->cd(10)->SetLeftMargin(0.13);;
+   addGraphics(hcAll, 1, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk1, 3, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk2, 6, "Cluster charge [ADC]", "");
+   hcAll->SetMaximum(1.25*hcAll->GetMaximum());
+   hcAll->Draw();
+   hcTrk->SetLineColor(kBlue); hcTrk->SetLineWidth(2);
+   hcTrk->Draw("same"); 
+   hcTrk1->Draw("same"); 
+   hcTrk2->Draw("same"); 
+  
+   TLegend* legend2 = new TLegend(0.15,0.70,0.94,0.89);
+   legend2->SetFillStyle(0);
+   legend2->SetBorderSize(0);
+   legend2->SetFillStyle(0);
+   legend2->SetTextSize(0.045);
+   
+   legend2->AddEntry(hcAll,"All clusters, trk in Fid","L"); 
+   legend2->AddEntry(hcTrk,"Clusters, |#DeltaX|<200 #mum, trk in Fid.","L");
+   legend2->AddEntry(hcTrk1,"1-strip Clusters","L");
+   legend2->AddEntry(hcTrk2,"2-strip Clusters","L");
+
+   legend2->Draw();
+
+   
+
+   c->cd(11)->SetLeftMargin(0.13);;
+   addGraphics(h10a, 1, "Strip #", "<ADC>");
+   addGraphics(h10b, 2, "Strip #", "<ADC>");
+   addGraphics(h10c, 4, "Strip #", "<ADC>");
+   int ixl = iLo;
+   int ixh = iHi;
+   int yh = hcTrk->GetMean()-50;
+   h10a->GetXaxis()->SetRangeUser(ixl-2,ixh+2);   
+   h10a->GetYaxis()->SetRangeUser(yh-200,yh+300);
+   /*
+   h10a->Draw();
+   h10b->SetLineColor(2);h10b->SetMarkerColor(2);
+   h10b->Draw("same");
+   h10c->SetLineColor(4);h10c->SetMarkerColor(4);
+   h10c->Draw("same");
+
+   TLegend* legend1 = new TLegend(0.25,0.75,0.94,0.89);
+   legend1->SetFillStyle(0);
+   legend1->SetBorderSize(0);
+   legend1->SetFillStyle(0);
+   legend1->SetTextSize(0.045);
+   
+   legend1->AddEntry(h10a,"Top half in Y","LEP"); 
+   legend1->AddEntry(h10b,"Bottom half in Y","LEP"); 
+   legend1->AddEntry(h10c,"Top 2 mm in Y","LEP"); 
+   legend1->Draw();
+   */
+   addGraphics(h35, 1, "#DUT clusters", "Entries");   
+   h35->GetYaxis()->SetTitleOffset(1.2);
+   h35->Draw();
+
+   c->cd(12)->SetLeftMargin(0.13);;
+   addGraphics(h2p, 1, "TDC time / 2.5 ns", "<ADC>");
+   h2p->Draw();
+   TLine *l1e = new TLine(tdcLo,0,tdcLo,h2p->GetMaximum());
+   TLine *l2e = new TLine(tdcHi,0,tdcHi,h2p->GetMaximum());
+   l1e->SetLineColor(kBlue); l2e->SetLineColor(kBlue); l1e->SetLineWidth(2); l2e->SetLineWidth(2);   
+   l1e->Draw(); l2e->Draw();
+
+   c->Print("Plots/plot_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+   //return;
+   
+
+
+   TCanvas *c4 = new TCanvas("c4","Plot 4",800,600);
+   c4->Divide(2,2);
+   c4->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12en, 1, "X_{trk} [mm]", "");
+   addGraphics(h12fn, 1, "X_{trk} [mm]", "");
+
+   TH1F *hepa1 = (TH1F*)h12en->Clone("hepa1");
+   TH1F *hepa2 = (TH1F*)h12fn->Clone("hepa2");
+   TH1F *henpa = (TH1F*)h12gn->Clone("henpa");
+   hepa1->Divide(h12en,h12ed,1.0,1.0,"B");
+   hepa2->Divide(h12fn,h12fd,1.0,1.0,"B");
+   henpa->Divide(h12gn,h12gd,1.0,1.0,"B");
+   addGraphics(hepa1, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   addGraphics(hepa2, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+   h3b->Draw();
+
+   c4->cd(2)->SetLeftMargin(0.13);
+   hepa1->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa1->SetMinimum(0.0);
+   hepa1->SetMaximum(1.2);
+   hepa1->SetLineWidth(1);
+   hepa1->SetTitle(r1);
+   hepa1->Draw("hist");
+   c4->cd(3)->SetLeftMargin(0.13);
+   hepa2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa2->SetMinimum(0.0);
+   hepa2->SetMaximum(1.2);
+   hepa2->SetLineWidth(1);
+   hepa2->SetTitle(r2);
+   hepa2->Draw("hist");
+
+   c4->cd(4)->SetLeftMargin(0.13);
+   addGraphics(henpa, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   henpa->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   henpa->SetMinimum(0.0);
+   henpa->SetMaximum(1.2);
+   henpa->SetLineWidth(1);
+   henpa->SetTitle(r3);
+   henpa->Draw("hist");   
+
+
+   TCanvas *c5 = new TCanvas("c5","Plot 5",800,600);
+   c5->Divide(2,2);
+   c5->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12hn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12in, 1, "Rel. Strip Pos", "");
+   addGraphics(h12jn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12kn, 1, "Rel. Strip Pos", "");
+
+   TH1F *hepas1 = (TH1F*)h12hn->Clone("hepas1");
+   TH1F *hepas2 = (TH1F*)h12in->Clone("hepas2");
+   TH1F *hepas3 = (TH1F*)h12jn->Clone("hepas3");
+   TH1F *hepas4 = (TH1F*)h12kn->Clone("hepas4");
+   hepas1->Divide(h12hn,h12hd,1.0,1.0,"B");
+   hepas2->Divide(h12in,h12id,1.0,1.0,"B");
+   hepas3->Divide(h12jn,h12jd,1.0,1.0,"B");
+   hepas4->Divide(h12kn,h12kd,1.0,1.0,"B");
+   addGraphics(hepas1, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas2, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas3, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas4, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   hepas1->SetTitle("Full Beam Spot");
+   hepas1->SetMinimum(0.8);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetLineWidth(1);
+   hepas1->Draw("hist");
+   c5->cd(2)->SetLeftMargin(0.13);
+   hepas2->SetTitle(r1);
+   hepas2->SetMinimum(0.8);
+   hepas2->SetMaximum(1.2);
+   hepas2->SetLineWidth(1);
+   hepas2->Draw("hist");
+   c5->cd(3)->SetLeftMargin(0.13);
+   hepas3->SetTitle(r2);
+   hepas3->SetMinimum(0.8);
+   hepas3->SetMaximum(1.2);
+   hepas3->SetLineWidth(1);
+   hepas3->Draw("hist");
+   c5->cd(4)->SetLeftMargin(0.13);
+   hepas4->SetTitle(r3);
+   hepas4->SetMinimum(0.8);
+   hepas4->SetMaximum(1.2);
+   hepas4->SetLineWidth(1);
+   hepas4->Draw("hist");
+
+   c5->Print("Plots/plot5_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   //return;
+   
+
+   TCanvas *c1 = new TCanvas("c1","Plot 1",1600,800);
+   c1->Divide(3,2);
+
+   c1->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h10d, 2, "Y_{trk} [mm]", "<ADC>");
+   h10d->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h10d->Draw();
+
+   //c1->cd(2)->SetLeftMargin(0.13);
+   //h3b->Draw();   
+
+   c1->cd(2)->SetLeftMargin(0.13);
+   addGraphics(h12b, 2, "Y_{trk} [mm]", "");
+   addGraphics(h12a, 1, "Y_{trk} [mm]", "");
+   h12a->SetMaximum(1.2*h12a->GetMaximum());
+   h12a->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h12a->Draw("hist");
+   h12b->Draw("hist,same");
+
+   TLegend* legend0 = new TLegend(0.15,0.75,0.94,0.89);
+   legend0->SetFillStyle(0);
+   legend0->SetBorderSize(0);
+   legend0->SetFillStyle(0);
+   legend0->SetTextSize(0.045);   
+   legend0->AddEntry(h12a,"Track Y pos","LEP"); 
+   legend0->AddEntry(h12b,"Track Y pos with good cluster","LEP");
+   legend0->Draw();
+
+   c1->cd(3)->SetLeftMargin(0.13);
+   TH1F *he = (TH1F*)h12b->Clone("he");
+   he->Divide(h12b,h12a,1.0,1.0,"B");
+   float bw = 1000*h12b->GetBinWidth(1);
+   TString yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he, 1, "Y_{trk} [mm]", yt);
+   he->SetTitle("DUT Efficiency vs Y_{trk}");
+   he->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   he->SetMinimum(0.8);
+   he->SetMaximum(1.1);
+   he->Draw("e");
+
+   c1->cd(4)->SetLeftMargin(0.13);
+   addGraphics(h10e, 2, "X_{trk} [mm]", "<ADC>");
+   h10e->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h10e->Draw();
+
+   c1->cd(5)->SetLeftMargin(0.13);
+   addGraphics(h12dd, 2, "X_{trk} [mm]", "");
+   addGraphics(h12dn, 1, "X_{trk} [mm]", "");
+   h12dd->SetMaximum(1.2*h12dd->GetMaximum());
+   h12dd->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h12dd->Draw("hist");
+   h12dn->Draw("hist,same");
+
+   c1->cd(6)->SetLeftMargin(0.13);
+   TH1F *he2 = (TH1F*)h12dn->Clone("he");
+   he2->Divide(h12dn,h12dd,1.0,1.0,"B");
+   bw = 1000*h12dd->GetBinWidth(1);
+   yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he2, 1, "X_{trk} [mm]", yt);
+   he2->SetTitle("DUT Efficiency vs X_{trk}");
+   he2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   he2->SetMinimum(0.8);
+   he2->SetMaximum(1.1);
+   he2->Draw("e");
+   c1->Print("Plots/plot1_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+   TCanvas *c8 = new TCanvas("c8","Plot 8",800,400);
+   c8->Divide(2,1);
+   TH1F *he4 = (TH1F*)h15c->Clone("Eff_trigger-DUT_time");
+   he4->Divide(h15c,h16c,1.0,1.0,"B");
+   yt = "#Good DUT hit / # Track";
+   addGraphics(h16c, 1, "DUT time - Track Time (ns)", "Entries");
+   addGraphics(he4, 1, "DUT time - Track Time (ns)", "Efficiency");
+   c8->cd(1)->SetLeftMargin(0.15);;
+   c8->cd(1)->SetRightMargin(0.05);;
+   h16c->Draw();
+   c8->cd(2)->SetLeftMargin(0.13);;
+   c8->cd(2)->SetRightMargin(0.05);;
+   he4->Draw();
+   c8->Print("Plots/plot8_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");   
+
+   if(holeSector){
+     TCanvas *c7 = new TCanvas("c7","Plot 7",800,800);
+     c7->SetLeftMargin(0.13);
+     TH1F *he3 = (TH1F*)h12on->Clone("Erf()_fit");
+     he3->Divide(h12on,h12od,1.0,1.0,"B");
+     bw = 1000*h12od->GetBinWidth(1);
+     yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+     addGraphics(he3, 1, "Dist to cutout [mm]", yt);
+     he3->SetStats(kTRUE);
+     he3->SetTitle("DUT Efficiency vs Dist to Cutout");
+     he3->GetXaxis()->SetRangeUser(-0.2,2.0);
+     he3->GetYaxis()->SetRangeUser(0.0,1.3);
+     he3->Draw("e");
+     TLatex *myLatex = new TLatex();
+     myLatex->SetTextFont(42); myLatex->SetTextColor(1); 
+     myLatex->SetTextAlign(12); myLatex->SetNDC(kTRUE); myLatex->SetTextSize(0.047);
+     TString text = "Sector "+m_sector;
+     c7->cd();
+     myLatex->DrawLatex(0.18,0.8,text);
+     
+     TF1 *f4a = new TF1("f4a","0.5*[0]*(1+TMath::Erf((x-[1])/[2]))",-0.1,2.0);
+     f4a->SetParameters(0.5,0.0,0.04);
+     f4a->SetParNames("Const","Mean","Sigma");
+     he3->Fit("f4a","R");
+     TPad *inset = new TPad("inset","y vx x",0.44,0.1,0.89,0.55);
+     inset->SetLeftMargin(0.13);
+     inset->SetRightMargin(0.05);
+     h3->SetTitle("");
+     inset->Draw();
+     inset->cd();
+     h3->Draw();
+     h3b->SetMarkerSize(0.2);h3b->SetMarkerStyle(20);h3b->SetMarkerColor(kRed); 
+     h3b->Draw("same");
+     if(holeQuadPar[0]!=0) funchole->Draw("same");   
+     
+     c7->Print("Plots/plot7_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");   
+   }
+   
+   /*
+   TCanvas *c2 = new TCanvas("c2","Plot 2",1600,600);
+   c2->Divide(5,2);
+   addGraphics(h1mpa, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, No Match Clu");
+   addGraphics(h1mbpa, 4, "X_{clu}-X_{trk} [mm]", ""); h1mbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, No Match Clu");
+   addGraphics(h1fpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, Match Clu");
+   addGraphics(h1fbpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, Match Clu");
+
+   addGraphics(h1mpa1, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa1->SetTitle("2.8<Y_{trk}<4.1 mm, -3.5<X_{trk}<-2.0 mm, No Match Clu");
+   addGraphics(h1mpa2, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa2->SetTitle("2.8<Y_{trk}<4.1 mm, -2.0<X_{trk}<-1.0 mm, No Match Clu");
+   addGraphics(h1mpa3, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa3->SetTitle("2.8<Y_{trk}<4.1 mm, -1.0<X_{trk}<0.0 mm, No Match Clu");
+   addGraphics(h1mpa4, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa4->SetTitle("2.8<Y_{trk}<4.1 mm,  0.0<X_{trk}<1.0 mm, No Match Clu");
+   addGraphics(h1mpa5, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa5->SetTitle("2.8<Y_{trk}<4.1 mm,  1.5<X_{trk}<3.5 mm, No Match Clu");
+   h1mpa->SetLineWidth(1); 
+   h1mpa1->SetLineWidth(1); 
+   h1mpa2->SetLineWidth(1); 
+   h1mpa3->SetLineWidth(1); 
+   h1mpa4->SetLineWidth(1); 
+   h1mpa5->SetLineWidth(1); 
+   h1fpa->SetLineWidth(1); 
+   h1fbpa->SetLineWidth(1); 
+
+   
+   h1fpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1fbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa1->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa2->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa3->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa4->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa5->GetXaxis()->SetRangeUser(-3,9); 
+
+   c2->cd(1);
+   h3b->Draw();   
+   double xl[5] = {-3.5, -2.0, -1.0, 0.0, 1.5};
+   double xh[5] = {-2.0, -1.0,  0.0, 1.0, 3.5};
+   
+   
+   for(int i=0;i<5;i++){
+     TBox *b = new TBox(xl[i],yInt1[0],xh[i],yInt2[1]);
+     b->SetLineColor(2); b->SetFillStyle(0);b->SetLineWidth(2);
+     b->Draw();
+   }
+   TBox *b = new TBox(xl[0],yInt3[0],xh[4],yInt3[1]);
+   b->SetLineColor(4);b->SetFillStyle(0);b->SetLineWidth(2);
+   b->Draw();
+   
+
+
+   c2->cd(2);
+   h1mpa->Draw();   
+   c2->cd(3);
+   h1fpa->GetYaxis()->SetRangeUser(0,30);
+   h1fpa->Draw();   
+   c2->cd(4);
+   h1mbpa->Draw();   
+   c2->cd(5);
+   h1fbpa->GetYaxis()->SetRangeUser(0,30);
+   h1fbpa->Draw();   
+   c2->cd(6);   
+   h1mpa1->Draw();   
+   c2->cd(7);
+   h1mpa2->Draw();   
+   c2->cd(8);
+   h1mpa3->Draw();   
+   c2->cd(9);
+   h1mpa4->Draw();   
+   c2->cd(10);
+   h1mpa5->Draw();
+   c2->Print("Plots/plot2_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   /*
+   TCanvas *c3 = new TCanvas("c3","Plot 3",800,600);
+   c3->Divide(1,2);
+   c3->cd(1);
+   h1mpaU->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaU->Draw();
+   c3->cd(2);
+   h1mpaL->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaL->Draw();   
+   c3->Print("Plots/plot3_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   addGraphics(h12m,1,"Interstrip Pos","<ADC>");
+   addGraphics(h12n,1,"Interstrip Pos","<Cluster Size>");
+   TCanvas *c6 = new TCanvas("c6","Plot 6",1200,400);
+   c6->Divide(3,1);
+   c6->cd(1);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetMinimum(0.5);
+   hepas1->Draw();
+   c6->cd(2);
+   h12m->SetMinimum(0);
+   h12m->SetMaximum(1.2*h12m->GetMaximum());
+   h12m->Draw();
+   c6->cd(3);
+   h12n->SetMinimum(0.5);
+   h12n->SetMaximum(2.0);
+   h12n->Draw();
+   
+   c6->Print("Plots/plot6_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+
+   fout->Write();
+   
+
+}
diff --git a/TbUT/scripts/.svn/text-base/ClusterWithTrackAna.h.svn-base b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna.h.svn-base
new file mode 100644
index 0000000..42dfebe
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna.h.svn-base
@@ -0,0 +1,480 @@
+/////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Oct  1 20:13:36 2015 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+//////////////////////////////////////////////////////////
+
+#ifndef ClusterWithTrackAna_h
+#define ClusterWithTrackAna_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TProfile.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TLegend.h>
+#include <TBox.h>
+#include <TLine.h>
+
+#include "AnalysisBase.h"
+#include "CMS.h"
+
+//#include "ClusterWithTrackAna_Inputs.h"
+
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+#include <iostream>
+#include <algorithm>
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class ClusterWithTrackAna  : public AnalysisBase{
+public :
+   
+  CMS            *fCMS;
+
+  ClusterWithTrackAna(int biasVal);
+  //ClusterWithTrackAna(TTree *tree=0);
+   virtual ~ClusterWithTrackAna();
+   virtual void     Loop();
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+};
+
+#endif
+
+#ifdef ClusterWithTrackAna_cxx
+ClusterWithTrackAna::ClusterWithTrackAna(int biasVal){
+  //ClusterWithTrackAna::ClusterWithTrackAna(TTree *tree){
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+  TString filename;
+  if(biasVal != 0) m_bias = Form("%d",biasVal);
+  TTree* tree = 0;
+  
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     TString scanType = "Run_Bias";
+     filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root"; 
+     if(m_scanType.Contains("Angle")){
+       scanType = "Run_Angle";
+       filename = m_fileIndir+"Board"+m_board+"_Angle/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root"; 
+     }
+     
+     cout << "===> Opening file: " << filename << endl;
+     
+
+     // lxplus
+     //
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6
+     //
+
+     TFile *f = new TFile(filename);
+     tree = (TTree*)f->Get("Clusters");
+     TH1F *hn = (TH1F*)f->Get("hWidthNoise");
+     for(int i=0;i<nChan;i++){
+       noise[i] = hn->GetBinContent(i+1);
+     }
+
+     // Get mean noise and width
+     hMeanNoise 	= (TH1F*)f->Get("hMeanNoise"); 
+     hWidthNoise 	= (TH1F*)f->Get("hWidthNoise"); 
+     cout << "===> Opening file: " << filename << endl;
+
+     TString filename2 = filename.ReplaceAll("_Tracks","");
+     TFile * f2 = new TFile(filename2);
+     if(f2) {
+       TTree * tree2 = (TTree*) f2->Get("TbUT/CMS");
+       if(tree2) {
+         tree->AddFriend(tree2);
+         fCMS = new CMS(tree2);
+       }else{
+         fCMS=0;  
+       }
+     } else {
+       cout << "WARNING: Could not find CMS data file: " << filename2 << endl;
+       fCMS =0 ;
+     }
+   }
+   Init(tree);
+   
+
+
+}
+
+ClusterWithTrackAna::~ClusterWithTrackAna()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+TString ClusterWithTrackAna::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) {
+
+  TString tag = "";
+
+  if(board.Contains("A6")){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+      if ( bias == "250" ) tag = "B6-A-213-8359";
+      if ( bias == "200" ) tag = "B6-A-214-8361";
+      if ( bias == "150" ) tag = "B6-A-215-8362";
+      if ( bias == "100" ) tag = "B6-A-216-8363";
+      if ( bias == "75" )  tag = "B6-A-219-8365";
+      if ( bias == "50" )  tag = "B6-A-220-8366";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+      if ( bias == "250" ) tag = "B6-A-245-8392";
+      if ( bias == "200" ) tag = "B6-A-246-8393";
+      if ( bias == "150" ) tag = "B6-A-247-8394";
+      if ( bias == "100" ) tag = "B6-A-248-8395";
+      if ( bias == "75" )  tag = "B6-A-249-8396";
+      if ( bias == "50" )  tag = "B6-A-250-8397";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+      if ( bias == "250" ) tag = "B6-A-294-8426";
+      if ( bias == "200" ) tag = "B6-A-295-8427";
+      if ( bias == "150" ) tag = "B6-A-296-8428";
+      if ( bias == "100" ) tag = "B6-A-297-8429";
+      if ( bias == "75" )  tag = "B6-A-298-8430";
+      if ( bias == "50" )  tag = "B6-A-299-8431";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+      if ( bias == "250" ) tag = "B6-A-327-8453";
+      if ( bias == "200" ) tag = "B6-A-328-8454";
+      if ( bias == "150" ) tag = "B6-A-329-8455";
+      if ( bias == "100" ) tag = "B6-A-330-8456";
+      if ( bias == "75" )  tag = "B6-A-331-8457";
+      if ( bias == "50" )  tag = "B6-A-332-8458";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-378-8494";
+      if ( bias == "250" ) tag = "B6-A-381-8497";
+      if ( bias == "200" ) tag = "B6-A-382-8498";
+      if ( bias == "150" ) tag = "B6-A-383-8499";
+      if ( bias == "100" ) tag = "B6-A-384-8500";
+      if ( bias == "75" )  tag = "B6-A-385-8501";
+      if ( bias == "50" )  tag = "B6-A-386-8502";
+    } else if(sector == "6"){
+      if ( bias == "300" ) tag = "B6-A-408-8523";
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+      if ( bias == "200" ) tag = "B6-A-410-8525";
+      if ( bias == "150" ) tag = "B6-A-411-8526";
+      if ( bias == "100" ) tag = "B6-A-412-8527";
+      if ( bias == "75" )  tag = "B6-A-413-8528";
+      if ( bias == "50" )  tag = "B6-A-414-8529";
+    }
+  } else if (board.Contains("A4")) {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+      if(bias == "350" ) tag = "B4-A-211-8553";
+      if(bias == "300" ) tag = "B4-A-212-8554";
+      if(bias == "250" ) tag = "B4-A-213-8555";
+      if(bias == "200" ) tag = "B4-A-214-8556";
+      if(bias == "150" ) tag = "B4-A-215-8557";
+      if(bias == "100" ) tag = "B4-A-216-8558";
+      if(bias == "75" )  tag = "B4-A-217-8559";
+      if(bias == "50" )  tag = "B4-A-218-8560";
+    }else if(sector == "2") {
+      if(bias == "400" ) tag = "B4-A-242-8583";
+      if(bias == "350" ) tag = "B4-A-243-8584";
+      if(bias == "300" ) tag = "B4-A-246-8586";
+      if(bias == "250" ) tag = "B4-A-247-8587";
+      if(bias == "200" ) tag = "B4-A-248-8588";
+      if(bias == "150" ) tag = "B4-A-249-8589";
+      if(bias == "100" ) tag = "B4-A-250-8590";
+      if(bias == "75" )  tag = "B4-A-251-8591";
+      if(bias == "50" )  tag = "B4-A-252-8592";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+      if(bias == "350" ) tag = "B4-A-276-8616";
+      if(bias == "300" ) tag = "B4-A-277-8617";
+      if(bias == "250" ) tag = "B4-A-278-8618";
+      if(bias == "200" ) tag = "B4-A-279-8619";
+      if(bias == "150" ) tag = "B4-A-280-8620";
+      if(bias == "100" ) tag = "B4-A-281-8621";
+      if(bias == "75" )  tag = "B4-A-282-8622";
+      if(bias == "50" )  tag = "B4-A-283-8623";
+    } else if(sector == "4"){
+      if(bias == "400" ) tag = "B4-A-217-8651";
+      if(bias == "350" ) tag = "B4-A-218-8652";
+      if(bias == "300" ) tag = "B4-A-219-8653";
+      if(bias == "250" ) tag = "B4-A-220-8654";
+      if(bias == "200" ) tag = "B4-A-221-8655";
+      if(bias == "150" ) tag = "B4-A-222-8656";
+      if(bias == "100" ) tag = "B4-A-223-8657";
+      if(bias == "75" )  tag = "B4-A-224-8658";
+      if(bias == "50" )  tag = "B4-A-225-8659";
+    } else if(sector == "5"){
+      if(bias == "400" ) tag = "B4-A-246-8680";
+      if(bias == "350" ) tag = "B4-A-247-8681";
+      if(bias == "300" ) tag = "B4-A-248-8682";
+      if(bias == "250" ) tag = "B4-A-249-8683";
+      if(bias == "200" ) tag = "B4-A-250-8684";
+      if(bias == "150" ) tag = "B4-A-251-8685";
+      if(bias == "100" ) tag = "B4-A-252-8686";
+      if(bias == "75" )  tag = "B4-A-253-8687";
+      if(bias == "50" )  tag = "B4-A-254-8688";
+    } else if(sector == "6"){
+      if(bias == "400" ) tag = "B4-A-227-8711";
+      if(bias == "350" ) tag = "B4-A-228-8712";
+      if(bias == "300" ) tag = "B4-A-229-8713";
+      if(bias == "250" ) tag = "B4-A-230-8714";
+      if(bias == "200" ) tag = "B4-A-231-8715";
+      if(bias == "150" ) tag = "B4-A-232-8716";
+      if(bias == "100" ) tag = "B4-A-233-8717";
+      if(bias == "75" )  tag = "B4-A-234-8718";
+      if(bias == "50" )  tag = "B4-A-235-8719";
+      tag = tag.ReplaceAll("B4","B1");
+    }
+  } else if (board.Contains("A8")) {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+      if(bias == "400") tag = "B8-A-297-13333";
+      if(bias == "350") tag = "B8-A-298-13334";
+      if(bias == "300") tag = "B8-A-299-13335";
+      if(bias == "250") tag = "B8-A-300-13336";
+      if(bias == "200") tag = "B8-A-301-13337";
+      if(bias == "150") tag = "B8-A-302-13338";
+      if(bias == "100") tag = "B8-A-303-13339";
+      if(bias == "75")  tag = "B8-A-304-13340";
+      if(bias == "50")  tag = "B8-A-305-13341";
+      if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399";
+      if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400";
+    }else if (sector == "2"){
+      //if(bias == "500") tag = "B8-A-321-13354";
+      if(bias == "400") tag = "B8-A-324-13355";
+      if(bias == "350") tag = "B8-A-325-13356";
+      if(bias == "300") tag = "B8-A-327-13357";
+      if(bias == "250") tag = "B8-A-328-13358";
+      if(bias == "200") tag = "B8-A-329-13359";
+      if(bias == "150") tag = "B8-A-330-13360";
+      if(bias == "100") tag = "B8-A-331-13361";
+      if(bias == "75")  tag = "B8-A-332-13362";
+      if(bias == "50") tag = "B8-A-333-13363";
+    }else if (sector == "3"){
+      //if(bias == "500") tag = "B8-A-358-13385";
+      if(bias == "400") tag = "B8-A-359-13386";
+      if(bias == "350") tag = "B8-A-360-13387";
+      if(bias == "300") tag = "B8-A-361-13388";
+      if(bias == "250") tag = "B8-A-365-13389";
+      if(bias == "200") tag = "B8-A-366-13390";
+      if(bias == "150") tag = "B8-A-367-13391";
+      if(bias == "100") tag = "B8-A-368-13392";
+      if(bias == "75")  tag = "B8-A-369-13393";
+      if(bias == "50")  tag = "B8-A-370-13394";
+    }else if (sector == "4"){
+      //if(bias == "500") tag = "B8-A-309-13344";
+      if(bias == "400") tag = "B8-A-311-13345";
+      if(bias == "350") tag = "B8-A-312-13346";
+      if(bias == "300") tag = "B8-A-314-13347";
+      if(bias == "250") tag = "B8-A-315-13348";
+      if(bias == "200") tag = "B8-A-316-13349";
+      if(bias == "150") tag = "B8-A-317-13350";
+      if(bias == "100") tag = "B8-A-318-13351";
+      if(bias == "75")  tag = "B8-A-319-13352";
+      if(bias == "50")  tag = "B8-A-320-13353";
+    }else if (sector == "5"){
+      //if(bias == "500") tag = "B8-A-334-13364";
+      if(bias == "400") tag = "B8-A-337-13365";
+      if(bias == "350") tag = "B8-A-339-13367";
+      if(bias == "300") tag = "B8-A-340-13368";
+      if(bias == "250") tag = "B8-A-341-13369";
+      if(bias == "200") tag = "B8-A-342-13370";
+      if(bias == "150") tag = "B8-A-343-13371";
+      if(bias == "100") tag = "B8-A-344-13372";
+      if(bias == "75")  tag = "B8-A-345-13373";
+      if(bias == "50")  tag = "B8-A-346-13374";
+      if(bias != "400") tag = tag.ReplaceAll("B8","B1");
+    }else if (sector == "6"){
+      //if(bias == "500") tag = "B8-A-347-13375";
+      if(bias == "400") tag = "B8-A-348-13376";
+      if(bias == "350") tag = "B8-A-349-13377";
+      if(bias == "300") tag = "B8-A-350-13378";
+      if(bias == "250") tag = "B8-A-352-13379";
+      if(bias == "200") tag = "B8-A-353-13380";
+      if(bias == "150") tag = "B8-A-354-13381";
+      if(bias == "100") tag = "B8-A-355-13382";
+      if(bias == "75")  tag = "B8-A-356-13383";
+      if(bias == "50")  tag = "B8-A-357-13384";
+      tag = tag.ReplaceAll("B8","B1");
+    }
+  } else if (board.Contains("D5")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B5-D-14-13066";
+      if(bias == "75") tag = "B5-D-13-13065";
+      if(bias == "100") tag = "B5-D-12-13064";
+      if(bias == "150") tag = "B5-D-11-13063";
+      if(bias == "200") tag = "B5-D-10-13062";
+      if(bias == "250") tag = "B5-D-6-13058";
+      if(bias == "300") tag = "B5-D-19-13071";
+      if(bias == "350") tag = "B5-D-4-13056";
+      if(bias == "400") tag = "B5-D-3-13055";
+      if(bias == "500") tag = "B5-D-16-13068";
+    }else if(sector == "2"){
+      if(bias == "50")  tag = "B5-D-119-13165";
+      if(bias == "75")  tag = "B5-D-118-13164";
+      if(bias == "100") tag = "B5-D-117-13163";
+      if(bias == "150") tag = "B5-D-116-13162";
+      if(bias == "200") tag = "B5-D-115-13161";
+      if(bias == "250") tag = "B5-D-114-13160";
+      if(bias == "300") tag = "B5-D-113-13159";
+      if(bias == "350") tag = "B5-D-111-13157";
+      if(bias == "400") tag = "B5-D-110-13156";
+      if(bias == "500") tag = "B5-D-109-13155";
+    }else if(sector == "3"){
+      if(bias == "50")  tag = "B5-D-167-13209";
+      if(bias == "75")  tag = "B5-D-166-13208";
+      if(bias == "100") tag = "B5-D-165-13207";
+      if(bias == "150") tag = "B5-D-164-13206";
+      if(bias == "200") tag = "B5-D-163-13205";
+      if(bias == "250") tag = "B5-D-162-13204";
+      if(bias == "300") tag = "B5-D-159-13202";
+      if(bias == "350") tag = "B5-D-158-13201";
+      if(bias == "400") tag = "B5-D-157-13200";
+      if(bias == "500") tag = "B5-D-156-13199";
+    }else if(sector == "4"){
+      if(bias == "50")  tag = "B5-D-65-13114";
+      if(bias == "75")  tag = "B5-D-64-13113";
+      if(bias == "100") tag = "B5-D-63-13112";
+      if(bias == "150") tag = "B5-D-62-13111";
+      if(bias == "200") tag = "B5-D-61-13110";
+      if(bias == "250") tag = "B5-D-59-13108";
+      if(bias == "300") tag = "B5-D-58-13107";
+      if(bias == "350") tag = "B5-D-57-13106";
+      if(bias == "400") tag = "B5-D-56-13105";
+      if(bias == "500") tag = "B5-D-55-13104";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B5-D-218-13253";
+      if(bias == "75")  tag = "B5-D-217-13252";
+      if(bias == "100") tag = "B5-D-216-13251";
+      if(bias == "150") tag = "B5-D-215-13250";
+      if(bias == "200") tag = "B5-D-214-13249";
+      if(bias == "250") tag = "B5-D-213-13248";
+      if(bias == "300") tag = "B5-D-212-13247";
+      if(bias == "350") tag = "B5-D-211-13246";
+      if(bias == "400") tag = "B5-D-210-13245";
+      if(bias == "500") tag = "B5-D-209-13244";
+    }else if(sector == "6"){
+      if(bias == "50")  tag = "B5-D-260-13294";
+      if(bias == "75")  tag = "B5-D-259-13293";
+      if(bias == "100") tag = "B5-D-258-13292";
+      if(bias == "150") tag = "B5-D-257-13291";
+      if(bias == "200") tag = "B5-D-256-13290";
+      if(bias == "250") tag = "B5-D-255-13289";
+      if(bias == "300") tag = "B5-D-254-13288";
+      if(bias == "350") tag = "B5-D-253-13287";
+      if(bias == "400") tag = "B5-D-252-13286";
+      if(bias == "500") tag = "B5-D-251-13285";
+    }
+  } else if (board.Contains("D7")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B1-D-347-9360";
+      if(bias == "75") tag = "B1-D-346-9359";
+      if(bias == "100") tag = "B1-D-344-9356";
+      if(bias == "150") tag = "B1-D-345-9357";
+      if(bias == "200") tag = "B1-D-343-9355";
+      if(bias == "300") tag = "B1-D-343-9354";
+      if(bias == "400") tag = "B1-D-341-9353";
+      if(bias == "500") tag = "B1-D-340-9272";
+    }else if(sector == "2"){
+      if(bias == "50") tag = "B1-D-471-9659";
+      if(bias == "75") tag = "B1-D-470-9658";
+      if(bias == "100") tag = "B1-D-469-9657";
+      if(bias == "150") tag = "B1-D-468-9656";
+      if(bias == "200") tag = "B1-D-467-9655";
+      if(bias == "300") tag = "B1-D-466-9654";
+      if(bias == "400") tag = "B1-D-465-9653";
+      if(bias == "500") tag = "B1-D-464-9652";
+    }else if(sector == "3"){
+      if(bias == "50") tag = "B1-D-472-9660";
+      if(bias == "75") tag = "B1-D-473-9661";
+      if(bias == "100") tag = "B1-D-474-9662";
+      if(bias == "150") tag = "B1-D-475-9663";
+      if(bias == "200") tag = "B1-D-476-9664";
+      if(bias == "300") tag = "B1-D-477-9665";
+      if(bias == "400") tag = "B1-D-478-9666";
+      if(bias == "500") tag = "B1-D-479-9667";
+    }else if(sector == "4"){
+      if(bias == "50") tag =  "B1-D-379-9424";
+      if(bias == "75") tag =  "B1-D-378-9423";
+      if(bias == "100") tag = "B1-D-377-9422";
+      if(bias == "150") tag = "B1-D-376-9421";
+      if(bias == "200") tag = "B1-D-375-9419";
+      if(bias == "300") tag = "B1-D-374-9417";
+      if(bias == "400") tag = "B1-D-373-9415";
+      if(bias == "500") tag = "B1-D-372-9413";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B1-D-489-9763";
+      if(bias == "75")  tag = "B1-D-488-9762";
+      if(bias == "100") tag = "B1-D-487-9761";
+      if(bias == "150") tag = "B1-D-484-9674";
+      if(bias == "200") tag = "B1-D-483-9673";
+      if(bias == "300") tag = "B1-D-482-9672";
+      if(bias == "400") tag = "B1-D-481-9671";
+      if(bias == "500") tag = "B1-D-480-9670";
+    }else if(sector == "6"){
+      if(bias == "50") tag =  "B1-D-321-9252";
+      if(bias == "75") tag =  "B1-D-320-9251";
+      if(bias == "100") tag = "B1-D-319-9250";
+      if(bias == "150") tag = "B1-D-318-9249";
+      if(bias == "200") tag = "B1-D-317-9248";
+      if(bias == "300") tag = "B1-D-316-9247";
+      if(bias == "400") tag = "B1-D-315-9246";
+      if(bias == "500") tag = "B1-D-314-9245";
+    }
+  } else if (board.Contains("A1")) {
+    if(sector == "1"){    
+      if(bias == "350") tag = "B1-A-1022-13947";
+      if(bias == "300") tag = "B1-A-1021-13946";
+      if(bias == "250") tag = "B1-A-1053-13971";
+      if(bias == "200") tag = "B1-A-1052-13970";
+      if(bias == "150") tag = "B1-A-1015-13939";
+      if(bias == "100") tag = "B1-A-1014-13938";
+      if(bias == "75")  tag = "B1-A-1013-13937";
+      if(bias == "50")  tag = "B1-A-1012-13936";
+    }else if(sector == "2"){
+      if(bias == "350") tag = "B1-A-1062-13980";
+      if(bias == "300") tag = "B1-A-1061-13979";
+      if(bias == "250") tag = "B1-A-1060-13978";
+      if(bias == "200") tag = "B1-A-1059-13977";
+      if(bias == "150") tag = "B1-A-1058-13976";
+      if(bias == "100") tag = "B1-A-1057-13975";
+      if(bias == "75")  tag = "B1-A-1056-13974";
+      if(bias == "50")  tag = "B1-A-1055-13973";
+    }    
+  } else if (board.Contains("A2")) {
+    if(sector == "1"){    
+      if(bias == "340") tag = "B2-A-1095-14030";
+      if(bias == "325") tag = "B2-A-1094-14029";
+      if(bias == "300") tag = "B2-A-1084-14017";
+      if(bias == "250") tag = "B2-A-1083-14016";
+      if(bias == "200") tag = "B2-A-1082-14015";
+      if(bias == "150") tag = "B2-A-1081-14014";
+      if(bias == "100") tag = "B2-A-1078-14013";
+      if(bias == "75")  tag = "B2-A-1077-14012";
+      if(bias == "50")  tag = "B2-A-1076-14011";
+      if(bias == "300" && angle=="-1") tag = "B2-A-1085-14018";
+      if(bias == "300" && angle=="1") tag = "B2-A-1088-14021";
+    }else if(sector == "2"){
+      if(bias == "340") tag = "B2-A-1099-14034";
+      if(bias == "325") tag = "B2-A-1098-14033";
+      if(bias == "300") tag = "B2-A-1097-14032";
+      if(bias == "250") tag = "B2-A-1100-14035";
+      if(bias == "200") tag = "B2-A-1101-14036";
+      if(bias == "150") tag = "B2-A-1102-14037";
+      if(bias == "100") tag = "B2-A-1103-14038";
+      if(bias == "75")  tag = "B2-A-1104-14039";
+      if(bias == "50")  tag = "B2-A-1105-14040";
+    }    
+  }
+
+  return tag;
+}
+
+
+#endif // #ifdef ClusterWithTrackAna_cxx
diff --git a/TbUT/scripts/.svn/text-base/ClusterWithTrackAna_Inputs.h.svn-base b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna_Inputs.h.svn-base
new file mode 100644
index 0000000..b0b1540
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna_Inputs.h.svn-base
@@ -0,0 +1,32 @@
+double nChan = 512.0;
+double stripPitch = 0.190;
+double z_DUT = 370;
+//double Rz = -0.0218;
+double Rz = -0.0218;
+double Ry = 0.00;
+double dxWin = 0.25;
+double xGloOff = -9.2;
+double yGloOff = -7.5;
+double xOff = -54.78;
+
+int kClusterChargeMin = 120;
+
+double ratioForHole = 0.05;
+
+double ratioForDeadStrip = 0.6;
+double ratioForNoisyStrip = 1.8;
+
+bool vetoDeadStripRegions = true;
+double k_DeadStrip = 0.12;
+
+bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+double trackTriggerTimeDiffCut = 2.5;
+
+bool isPType = true;
+
+
+// Notes
+// For Rz alignment, one should SUBTRACT the slope found from the deltaX vs Y plot.
+// For Z alignment, one should ADD the slope found from the deltaX vs Y plot.
+//
diff --git a/TbUT/scripts/.svn/text-base/ClusterWithTrackAna_README.svn-base b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna_README.svn-base
new file mode 100644
index 0000000..df478ca
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ClusterWithTrackAna_README.svn-base
@@ -0,0 +1,47 @@
+//
+// S. Blusk, Oct 6, 2015
+// Updated April 21, 2016 -- S. Blusk
+
+This is a simple script to loop over a TB run that has ben processed by TbUT and has tracks added to the ntuple.
+To run interactively:
+
+< 
+
+In you home area, create your own work area:
+> mkdir TBANAL/
+> cd TBANAL
+>   mkdir Output
+>   mkdir Plots/
+
+Set up ROOT environment (ROOT 5!) - code is not fully compliant with ROOT 6.
+>
+> setenv CMTCONFIG x86_64-slc5-gcc46-opt
+> SetupProject LHCb v36r2
+> root [0] .x runClusterWithTrackAna.C
+
+
+* Right now, it is set up to run over a file in the area:
+  const TString m_fileIndir = "/afs/cern.ch/work/s/sblusk/public/TB/";
+and it picks up the file in subdirectory: "BoardA6/", set with:
+  const TString m_board   = "A6";
+
+* Only the files defined in ClusterWithTrackAna.h will run, so if you grab a different
+file, you need to check it is a good run and in the list of files. As of April 21, 2016,
+only the fgood 2015 test beam runs are included.
+
+
+[*] A set of plot should pop up after the script runs, and an output ROOT file called histOutput.root is created.
+
+[*] Until we have a more refinced processing scheme, files that you want to test should be put in by hand into 
+ClusterWithTrackAna::getFileBase (follow the examples in there).
+
+[*] Input & output files directories are included in the Analysis_Inputs.h
+
+Once we have to process many runs, we should have a way of automatically providing the input file and the output file.
+This is being worked on...
+
+
+KNOWN ISSUES
+------------
+
+* Array stripGap[4] need to be updated to depend on the particular sensor. Right now, it's assumed no gaps for Type A, and same gaps for all type D.
diff --git a/TbUT/scripts/.svn/text-base/ExampleAnalysis.C.svn-base b/TbUT/scripts/.svn/text-base/ExampleAnalysis.C.svn-base
new file mode 100644
index 0000000..24d7bc1
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ExampleAnalysis.C.svn-base
@@ -0,0 +1,142 @@
+//
+//    Example Analysis code
+//    Stripped down version to loop over tracks and clusters with alignment, etc.
+//    Date: Oct 27, 2015
+// 
+#define ExampleAnalysis_cxx
+#include "ExampleAnalysis.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+#include <iostream>
+#include <fstream>
+
+
+void ExampleAnalysis::Loop(){
+
+  if (fChain == 0) return;
+
+   Int_t nentries = fChain->GetEntriesFast();
+
+   //--------------------------------------
+   // Create output file to save histograms
+   //--------------------------------------
+   fout = new TFile(f_out,"RECREATE");
+
+   // Just add 2 histograms, as examples
+   TH1F* h1w = new TH1F("h1w","#DeltaX",20000,-100.0,100.0);
+   TH1F *hnoise = new TH1F("hnoise","Noise in connected channels",100,-200,200);
+   TH1F* h12dd = new TH1F("h12dd","X position of track",200,-10.0,10.0);h12dd->Sumw2();
+   TH1F* h12dn = new TH1F("h12dn","X position of track",200,-10.0,10.0);h12dn->Sumw2();
+   //------------------------------------------------------------------------------------------------------
+
+   //-----------------------------------------------
+   // Example for writing some information to a file
+   //-----------------------------------------------
+   std::ofstream myfile;
+   if(writeEventsWithMissinhHitsToFile){
+     myfile.open("MissingDUTHits.dat");
+   }
+
+   // Prepare DUT - Alignment, etc
+   PrepareDUT();
+   
+
+   // ----------------------
+   // Begin Analysis Loop
+   // ----------------------
+   int iChan = nChan;
+   double nomStrip = 0;
+   int njump = 10000;
+   if(nentries > 100000) njump = 50000;
+   Long64_t nbytes = 0, nb = 0;
+   cout << "Begin loop over " << nentries << " events" << endl;
+
+   // Begin loop over events
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      if(jentry%njump==0) cout << "====> At entry = " << jentry << endl;
+      if(n_tp3_tracks != 1) continue; // Require 1 and only 1 TPIX track
+
+      //==========================================
+      // Example here of acccessing CMS strip data
+      //==========================================
+      if(fCMS){
+        for(int k=0;k<iChan;k++){
+          if(fCMS->cmsData[k]!=0) hnoise->Fill(fCMS->cmsData[k]);
+        }      
+      }
+      
+      // Loop over TPIX tracks in event
+      for(int k=0; k<n_tp3_tracks; k++){
+        if(dtime > trackTriggerTimeDiffCut) continue;
+        double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+        double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+        double tx = 1000*vec_trk_tx->at(k);
+        double ty = 1000*vec_trk_ty->at(k);
+
+        transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip);
+
+        // If you want to remove tracks in region of hole, can change 'removeTracksInHoleDef = false' to not remove them.
+        if(isInCutoutRegion(x_trk, y_trk)) continue;
+       
+        bool goodRegion = true;
+        for(int id = 0; id<nDeadRegion; id++){
+          if(x_trk>=deadRegionLo[id]  && x_trk<=deadRegionHi[id]) goodRegion = false;  
+        }
+        if(!goodRegion) continue;
+
+        bool goodTrack = false;
+        bool inFiducialX = false;
+        bool inFiducialY = false;
+        if(x_trk>xMin && x_trk<xMax) inFiducialX = true;          
+        if(y_trk>yMin && y_trk<yMax) inFiducialY = true;          
+        bool inFiducial = inFiducialX && inFiducialY;
+        inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+        
+        if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+        bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+        bool foundHit = false;
+        double x_trk0 = x_trk;
+
+        // Begin loop over CLUSTERS
+        for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+          if(clustersPosition[j] < 0.1) continue;
+          x_trk = x_trk0;
+
+          double x_dut = getDUTHitPosition(j);
+          
+          double dx = x_dut - x_trk;
+
+          if(goodTrack && inFiducial && goodTime) {
+            h1w->Fill(dx);
+            if(fabs(dx)<dxWin) foundHit = true;
+          }
+        } // End Loop over Clusters
+
+        // ------------------------
+        // Efficiency studies, etc
+        // ------------------------
+        if(inFiducial && goodTrack && goodTime) {
+          h12dd->Fill(x_trk); // X pos of good tracks
+          if(foundHit) {
+            h12dn->Fill(x_trk);  // X position when a hit was found within 200 um
+          } else {   
+            // Here, you might do something else when no DUT hits are not found
+            if(writeEventsWithMissinhHitsToFile) 
+              myfile << jentry << " " << nomStrip << " " << x_trk << " " << y_trk << endl;              
+          }
+        } 
+      }// End Loop over Tracks
+   } // End Loop over Events
+
+   if(writeEventsWithMissinhHitsToFile) myfile.close();
+   
+
+   fout->Write();
+   
+
+}
diff --git a/TbUT/scripts/.svn/text-base/ExampleAnalysis.h.svn-base b/TbUT/scripts/.svn/text-base/ExampleAnalysis.h.svn-base
new file mode 100644
index 0000000..32f3165
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ExampleAnalysis.h.svn-base
@@ -0,0 +1,134 @@
+/////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Oct  1 20:13:36 2015 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+//////////////////////////////////////////////////////////
+
+#ifndef ExampleAnalysis_h
+#define ExampleAnalysis_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TProfile.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TLegend.h>
+#include <TBox.h>
+#include <TLine.h>
+
+#include "AnalysisBase.h"
+#include "CMS.h"
+
+//#include "ExampleAnalysis_Inputs.h"
+
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+#include <iostream>
+#include <algorithm>
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class ExampleAnalysis  : public AnalysisBase{
+public :
+   
+  CMS            *fCMS;
+
+   ExampleAnalysis(TTree *tree=0);
+   virtual ~ExampleAnalysis();
+   virtual void     Loop();
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+};
+
+#endif
+
+#ifdef ExampleAnalysis_cxx
+ExampleAnalysis::ExampleAnalysis(TTree *tree){
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+  TString filename;
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     filename = m_fileIndir+"Board"+m_board+"/Run_Bias_Scan-"+getFileBase("Bias",m_board, m_bias, "0",m_sector)+"_Tuple_Tracks.root"; 
+
+     // lxplus
+     //
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6
+     //
+
+     TFile *f = new TFile(filename);
+     tree = (TTree*)f->Get("Clusters");
+
+     // Get mean noise and width
+     hMeanNoise 	= (TH1F*)f->Get("hMeanNoise"); 
+     hWidthNoise 	= (TH1F*)f->Get("hWidthNoise"); 
+
+     TString filename2 = filename.ReplaceAll("_Tracks","");
+     TFile * f2 = new TFile(filename2);
+     if(f2) {
+       TTree * tree2 = (TTree*) f2->Get("TbUT/CMS");
+       if(tree2) {
+         tree->AddFriend(tree2);
+         fCMS = new CMS(tree2);
+       }else{
+         fCMS=0;  
+       }
+     } else {
+       cout << "WARNING: Could not find CMS data file: " << filename2 << endl;
+       fCMS =0 ;
+     }
+   }
+   Init(tree);
+}
+
+ExampleAnalysis::~ExampleAnalysis()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+TString ExampleAnalysis::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) {
+
+  TString tag = "";
+
+  if(board == "A6"){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-377-8494";
+    } else if(sector == "6"){
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+    }
+  } else if (board == "A4") {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+    }
+  } else if (board == "A8") {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+    }else if (sector == "2"){
+      if(bias == "400") tag = "B8-A-324-13355";
+    }else if (sector == "3"){
+      if(bias == "400") tag = "B8-A-359-13386";
+    }
+  }
+
+  return tag;
+}
+
+
+#endif // #ifdef ExampleAnalysis_cxx
diff --git a/TbUT/scripts/.svn/text-base/ThresholdPlotter.cpp.svn-base b/TbUT/scripts/.svn/text-base/ThresholdPlotter.cpp.svn-base
new file mode 100644
index 0000000..f46176d
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/ThresholdPlotter.cpp.svn-base
@@ -0,0 +1,67 @@
+#include<iostream>
+#include<vector>
+#include<string>
+#include "TH2D.h"
+
+
+using namespace std;
+
+void ThresholdPlotter()
+{
+    cout<<"start"<<endl;
+    string fileName="noise_Mamba.dat";
+    
+    ifstream l_file(fileName.c_str());
+    int channelsNumber=512;
+    std::vector<int> thresholVector(channelsNumber,0);
+
+    for(int channel=0;channel<channelsNumber;channel++)
+    {
+        double l_noiseFromFile=0;
+        l_file >> l_noiseFromFile;
+        thresholVector[channel]=l_noiseFromFile;
+        cout<<"NoiseRetreiver===> channel: "<< channel <<"noise: "<<l_noiseFromFile<<endl;
+    }
+   
+ 
+    cout<<"create histograms" <<endl;
+    TH2D* noiseHistogram= new TH2D("Noise Histogram","Noise (1#sigma)",100,-0.5,channelsNumber+0.5 , 100, 0, 200);
+    TH2D*  lowThresholdHistogram=new  TH2D("low Thresholds Histogram","low Thresholds ",100,-0.5,channelsNumber+0.5 , 100, 0, 200);
+    TH2D* highThresholdHistogram=new  TH2D("high Thresholds Histogram","high Thresholds ",100,-0.5,channelsNumber+0.5 , 100, 0, 200);
+
+    int lawThresholdMultiplicity=2.5;
+    int highThresholdMultiplicity=3;
+
+    cout<<"Fill histograms" <<endl;
+
+    for(int channel=0;channel<channelsNumber;channel++)
+    {
+        noiseHistogram->Fill(channel, thresholVector[channel]);
+        lowThresholdHistogram->Fill(channel,lawThresholdMultiplicity* thresholVector[channel]);
+        highThresholdHistogram->Fill(channel,highThresholdMultiplicity* thresholVector[channel]);
+    }
+
+    TCanvas * c1 = new TCanvas("c", "c", 600, 800);
+    
+    noiseHistogram->GetYaxis()->SetTitle("[ADC]");
+    noiseHistogram->GetXaxis()->SetTitle("channel");
+    noiseHistogram->SetMarkerStyle(2);
+    noiseHistogram->SetLineColor(kWhite);
+
+    lowThresholdHistogram->SetMarkerStyle(2);
+    lowThresholdHistogram->SetMarkerColor(kGreen);
+    lowThresholdHistogram->SetLineColor(kWhite);
+
+    highThresholdHistogram->SetMarkerStyle(2);
+    highThresholdHistogram->SetMarkerColor(kRed);
+    highThresholdHistogram->SetLineColor(kWhite);
+
+   
+    noiseHistogram->Draw();
+    lowThresholdHistogram->Draw("same");
+    highThresholdHistogram->Draw("same");
+    
+    c1->BuildLegend(0.7296238,0.8274793,0.9004702,0.8997934);
+    gStyle->SetOptStat(0);
+
+}
diff --git a/TbUT/scripts/.svn/text-base/fastAnalysis.py.svn-base b/TbUT/scripts/.svn/text-base/fastAnalysis.py.svn-base
new file mode 100644
index 0000000..2e5f034
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/fastAnalysis.py.svn-base
@@ -0,0 +1,417 @@
+#!/usr/bin/env python
+
+"""
+fastAnalysis.py for use during UT testbeam data taking
+
+To use:
+1.  Set up TbUT running environment (https://twiki.cern.ch/twiki/bin/view/LHCb/TbUT)
+2.  Edit this script to point to your current eos mount point and the data dir for current testbeam, or use the command line options
+3.  From Tb/TbUT directory, run scripts/fastAnalysis.py with the following required options:
+    -b board    : Letter+number combination, e.g. 'A8'
+    -p pednum   : run number of the pedestal run to use (UT run number)
+    -r runnum   : run number to analyze (UT run number) -- enter 0 for pedestal analysis only
+4.  These are optional arguments:
+    -n nevmax   : number of events to analyze
+    -f force    : Force overwrite of any output files existing
+    -t senstype : sensor type ('PType' or 'NType')
+    -e eosmount : eos mount point for data to use (uses as a simple path)
+    -i indir    : input path relative to eosmount point to find data
+    -o outdir   : Directory to put the monitoring in
+5.  Inside outdir it will make monitoring directories, and save the pedestal .dat, root files, and defined plots there
+6.  It will not re-run the analysis if the files exist already unless you use -f
+7.  After running it will pop open a window to view the new plots, and exit when that window is closed
+"""
+
+############################################################
+##Modify this to change defaults: 
+nevdef=100000
+eosmount='/afs/cern.ch/work/m/mrudolph/private/nov_testbeam/eos'
+indir='lhcb/testbeam/ut/OfficialData/October2015'
+outdir='.'
+############################################################
+
+
+
+
+
+
+############################################################
+##Define all the draw commands for simple monitoring plots from Cluster tuple here
+##Noise mean and width are automatically created as the first 2 plots
+##The last plot will be the ADC in the fiducial region (that gets defined based on previous draw command postprocessing)
+#Potential TODO: create a new module file with the plot configuration to make extension a bit easier
+
+class draw_command():
+    """draw command skeleton for a TTree
+    
+    Need at least command, cut, option, title for histogram to make
+    Can also bind postprocessor functions to draw more stuff or
+    to return to the list of fiducial cuts for the final plot
+    """
+    def __init__(self, command, cut, option, title, postprocessor=None):
+        self.command = command
+        self.cut = cut
+        self.option = option
+        self.title = title
+        self.postprocessor = postprocessor
+
+
+##Post processing functions for histograms defined in draw commands -- expect TPad, TTree, TH1 parameters
+##  Code below could be used for a couple things -- you have the pad so you can process the hist and draw more things,
+##    or you can return a cut string that will be used to define the fiducial region later on
+
+def post_nostat( pad, tree, hist ):
+    """Generic postprocessor to remove stat box"""
+    hist.SetStats(False)
+
+def post_clusterpos( pad, tree, hist ):
+    """Process the cluster position histogram and find beam area"""
+    post_nostat( pad, tree, hist)
+
+    maxbin = hist.GetMaximumBin()
+    maxval = hist.GetBinContent(maxbin)
+    thresh = 0.25
+    #look to the left and then to the right
+    currbin = maxbin
+    while( hist.GetBinContent(currbin) > thresh*maxval ):
+        currbin -= 1
+    left = hist.GetXaxis().GetBinLowEdge(currbin)
+    currbin = maxbin
+    while( hist.GetBinContent(currbin) > thresh*maxval ):
+        currbin += 1
+    right = hist.GetXaxis().GetBinUpEdge(currbin)
+    
+    hist.GetYaxis().SetRangeUser(0,maxval*1.1)
+    from ROOT import TLine
+    l1 = TLine( left ,0, left,maxval*1.1)
+    pad.posl1=l1
+    l1.Draw()
+    l2 = TLine( right,0,right,maxval*1.1)
+    pad.posl2=l2
+    l2.Draw()
+    pad.Update()
+    return "clustersPosition > {} && clustersPosition < {}".format(left,right)
+
+def post_tdc_prof( pad, tree, hist ):
+    """Process the charge v. TDC profile and find timing cut"""
+    ymin = hist.GetMinimum()
+    if ymin < 0:
+        ymin *= 1.2
+    else:
+        ymin *= 0.8
+    ymax = hist.GetMaximum()
+    if ymax < 0:
+        ymax *= 0.8
+    else:
+        ymax *= 1.2
+    hist.GetYaxis().SetRangeUser(ymin,ymax)
+    isneg = (ymax < 0) or ( ymin < 0 and abs(ymin) > abs(ymax) )
+    if isneg:
+        b = hist.GetMinimumBin()
+    else:
+        b = hist.GetMaximumBin()
+
+    from ROOT import TLine
+    l1 = TLine( b - 1.5 ,ymin, b - 1.5,ymax)
+    pad.tdcl1=l1
+    l1.Draw()
+    l2 = TLine( b+1.5,ymin,b+1.5,ymax)
+    pad.tdcl2=l2
+    l2.Draw()
+    return "abs(clustersTDC - {}) <= 1.5".format(b)
+
+############################################################
+##The list of draw commands to run
+##Make sure for each command if you specify anything about the histogram to draw to, give it a unique name!
+## Fiducial adc name is "fidadc", noise are called "meanNoise" and "widthNoise"
+drawcommands = [ draw_command("clusterNumberPerEvent","","","Number of clusters;N_{clusters};Events"),
+                 draw_command("clustersCharge>>charge(200,-1200,0)","clustersSize > 0","","Cluster charge;Tot. charge [ADC];Clusters"),
+                 draw_command("clustersPosition","clustersSize > 0","","Cluster position;Channel;Clusters",postprocessor=post_clusterpos),
+                 draw_command("clustersSize","clustersSize > 0", "","Cluster size;N_{strips};Clusters"),
+                 draw_command("clustersTDC>>tdc(10,0.5,10.5)","","","TDC;TDC;Events",postprocessor=post_nostat),
+                 draw_command("clustersCharge:clustersTDC>>tdcp(10,0.5,10.5)","clustersSize > 0","prof","Charge v TDC;TDC;<charge> [ADC]",postprocessor=post_tdc_prof),
+ ]
+
+##Should be possible to hook into an external file with TTree::MakeProxy using these commands as well if needed, though it hasn't been tested.
+##If you have other histograms to calculate from available inputs, there are two lists (hlist_pre and hlist_post) in the plotting loop they can be added to;
+##  see where the noise histograms are created.  Pre goes before the ttree command and post afterwards
+############################################################
+
+
+import argparse
+    
+parser = argparse.ArgumentParser(
+    description = "Fast analysis of UT testbeam data for quality monitoring",
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter,)
+parser.add_argument('-b','--board',type=str,required=True,
+                    help="Letter+number combination, e.g. 'A8'")
+parser.add_argument('-p','--pednum',type=int,required=True,
+                    help="Run number of the pedestal run to use (UT run number)")
+parser.add_argument('-r','--runnum',type=int,required=True,
+                    help="Run number to analyze (UT run number); use 0 to analyze pedestal only")
+parser.add_argument('-n','--nevmax',type=int,required=False,default=nevdef,
+                    help="Max number of events to analyze")
+parser.add_argument('-f','--force',required=False,action='store_true',
+                    help="Force overwrite of any output files existing")
+parser.add_argument('-t','--senstype',type=str,required=False,default='PType',
+                    help="Sensor type ('PType' or 'NType')")
+parser.add_argument('-e','--eosmount',type=str,required=False,default=eosmount,
+                    help="Eos mount point")
+parser.add_argument('-i','--indir',type=str,required=False,default=indir,
+                    help='Input data directory path relative to eosmount')
+parser.add_argument('-o','--outdir', type=str, required=False,default=outdir,
+                    help="Output directory for root files and plots")
+args = parser.parse_args()
+
+import sys
+import os
+import subprocess
+
+#make sure I have places for output
+pedestaldir = args.outdir + '/Pedestal-Board{}-{}'.format( args.board, args.pednum )
+monitordir = args.outdir + '/Monitoring-Board{}-{}'.format( args.board, args.runnum )
+def ensuredir(dir):
+    try: 
+        os.makedirs(dir)
+    except OSError:
+        if not os.path.isdir(dir):
+            raise
+ensuredir(pedestaldir)
+if(args.runnum!=0):
+    ensuredir(monitordir)
+
+#Run pedestal if it does not already exist
+didPedestal = False
+if(args.force or not os.path.isfile("{}/Fast-Pedestal-Board{}-{}.dat".format( pedestaldir, args.board, args.pednum ) ) ):
+    
+    print "================================================================"
+    print "==ANALYZE PEDESTAL FOR BOARD {} RUN {}=========================".format( args.board, args.pednum )
+    print "================================================================"
+
+    didPedestal = True
+
+    ##Set up the gaudi config for running the pedestal
+    pedCode = ("import sys\n"
+               "sys.path.append( 'options/python' )\n"
+               "from TbUTPedestalRunner import TbUTPedestalRunner\n"
+               "app=TbUTPedestalRunner()\n"
+               "# set parameter\n"
+               "app.inputData= '{}/{}/Board{}/RawData/Pedestal-B{}-{}-{}-.dat'\n"
+               "app.isAType={}\n"
+               "# have to be more than 4k (~10k)\n"
+               "app.eventMax={}\n"
+               "#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!\n"
+               "app.pedestalOutputData ='{}/Fast-Pedestal-Board{}-{}.dat'\n"
+               "app.runPedestals()\n").format(args.eosmount,args.indir, args.board, args.board[1:], args.board[:1],args.pednum, (args.board[:1]=='A'), args.nevmax, pedestaldir, args.board,args.pednum)
+
+
+    with open('myTempPedRun.py','w') as ftarget:
+        ftarget.write(pedCode)
+
+    ret = subprocess.call(['gaudirun.py','myTempPedRun.py'])
+
+    os.remove('myTempPedRun.py')
+
+    if(ret!=0):
+        sys.exit("Bad return code from pedestal run")
+
+#Determine if we have a data run to process
+if( args.runnum != 0):
+
+    #find the data file by run number
+    dir_to_search = "{}/{}/Board{}/RawData/".format(args.eosmount,args.indir,args.board)
+    paths = subprocess.check_output("find {} -iname '*-{}-*.dat'".format(dir_to_search,args.runnum), shell=True).splitlines()
+
+    if( len(paths)==0):
+        sys.exit("ERROR: no data file found for run number {}".format(args.runnum))
+    elif( len(paths) > 1):
+        print "WARNING: more than one file matching run number, using",paths[0]
+
+    inpath = paths[0]
+    #These are the output names used by TbUTClusterizator
+    outnames = [ os.path.basename(inpath).replace('.dat','.root'), os.path.basename(inpath).replace('.dat','_Tuple.root') ]
+
+    #Skip running if files exist unless forced
+    if( args.force or not (os.path.isfile(monitordir+'/'+outnames[0]) and os.path.isfile(monitordir+'/'+outnames[1])) ):
+
+        print "================================================================"
+        print "==ANALYZE DATA FOR BOARD {} RUN {}=============================".format( args.board, args.runnum )
+        print "================================================================"
+
+        runCode = ("import sys\n"
+                   "sys.path.append('options/python')\n"
+                   "from TbUTClusterizator import TbUTClusterizator\n"
+                   "app = TbUTClusterizator()\n"
+                   "# set parameters\n"
+                   "app.inputData = '{}'\n"
+                   "app.isAType = {}\n"
+                   "app.sensorType = '{}'\n"
+                   "app.eventMax = {}\n"
+                   "app.pedestalInputData = '{}/Fast-Pedestal-Board{}-{}.dat'\n"
+                   "app.eventNumberDisplay = 1000\n"
+                   "app.runClusterization()\n").format(inpath,(args.board[:1]=='A'),args.senstype,args.nevmax,pedestaldir,args.board,args.pednum)
+
+
+
+        with open('myTempRun.py','w') as ftarget:
+            ftarget.write(runCode)
+
+        #run twice because of noise input issue...
+        ret = subprocess.call(['gaudirun.py','myTempRun.py'])
+        ret = subprocess.call(['gaudirun.py','myTempRun.py'])
+
+        #Move them since currently can't control output location from the run
+        if( monitordir != '.' ):
+            subprocess.call(['mv',outnames[0],monitordir+'/'])
+            subprocess.call(['mv',outnames[1],monitordir+'/'])
+
+        os.remove('myTempRun.py')
+
+        if(ret!=0):
+            sys.exit("Bad return code from analysis run")
+
+
+
+
+########################################################
+##Analysis part
+########################################################
+
+
+print "================================================================"
+print "==PLOT DATA FOR BOARD {} RUN {}================================".format( args.board, args.runnum )
+print "================================================================"
+
+#Define what extensions to save plots with
+def saveall( c, outname ):
+    for ext in '.png', '.pdf', '.C':
+        c.SaveAs(outname+ext)
+
+#setup ROOT
+from ROOT import gROOT, TH1F, TCanvas, TFile, TTree, gStyle, TF1,gDirectory,gPad
+gROOT.SetBatch()
+gROOT.SetStyle("Plain")
+
+#keep track of plots we made to open at the end
+plotlist = []
+
+if( didPedestal ):
+    c = TCanvas()
+    #analyze the pedestal only
+    #dat file is space separated list of pedestals by channel number
+    peds = open("{}/Fast-Pedestal-Board{}-{}.dat".format(pedestaldir,args.board,args.pednum), "r")
+    try:
+        pedvals = [float(p) for p in peds.read().split()]
+    except:
+        sys.exit("Bad pedestal data format")
+    
+    nc = len(pedvals)
+    hped = TH1F("hped","Pedestal v. channel;Channel;Pedestal [ADC]",nc,-0.5, nc-0.5)
+    for i,v in enumerate(pedvals):
+        hped.SetBinContent(i+1, v)
+
+    hped.Draw();
+    saveall(c,"{}/pedestal".format(pedestaldir))
+    plotlist += ["{}/pedestal.png".format(pedestaldir)]
+
+#analyze the run
+if( args.runnum != 0 ):
+    fhists = TFile("{}/{}".format(monitordir,outnames[0]))
+    ftrees = TFile("{}/{}".format(monitordir,outnames[1]))
+
+    t = ftrees.Get("TbUT/Clusters")
+    
+    #make the rough noise plots -- use the range -120 to 120 ADC and ignore most of the signal contribution
+    noise2d = fhists.Get("TbUT/CMSData_vs_channel")
+    noise2d.GetYaxis().SetRangeUser(-120,120)
+    nc = noise2d.GetNbinsX()
+
+    meanNoise = TH1F("meanNoise","Mean noise;Channel;<noise> [ADC]",nc,-0.5,nc-0.5)
+    widthNoise = TH1F("widthNoise","Width noise;Channel;#sigma_{noise} [ADC]",nc,-0.5,nc-0.5)
+    meanNoise.SetStats(False)
+    widthNoise.SetStats(False)
+
+    for b in range(1, nc+1):
+        noise2d.GetXaxis().SetRange(b,b)
+        meanNoise.SetBinContent(b, noise2d.GetMean(2))
+        meanNoise.SetBinError(b, noise2d.GetMeanError(2))
+        widthNoise.SetBinContent(b, noise2d.GetStdDev(2))
+        widthNoise.SetBinError(b, noise2d.GetStdDevError(2))
+
+    #hlist_pre is a list of histograms to draw
+    hlist_pre = [meanNoise,widthNoise]
+    npre = len(hlist_pre)
+
+    #hlist_post, however, is a list of functions that create histograms; define some functions for post-draw histograms first:
+    def fiducialADC( t, fidcut ):
+        print "Use fiducial cut:", fidcut
+        t.Draw("clustersCharge>>fidcharge(200,-1200,0)", fidcut)
+        h = t.GetHistogram()
+        h.SetTitle("Fiducial cluster charge;Tot. charge [ADC];Clusters")
+        return h
+
+    #the output ntuple has empty clusters saved in every event, so always cut those out
+    fidcut = "clustersSize > 0"
+    hlist_post = [fiducialADC]
+    npost = len(hlist_post)
+
+    #create the canvases
+    #keep track of how many plots left to do
+    ntreedraw = len(drawcommands)
+    nplotall = npre + ntreedraw + npost
+
+    #9 plots per canvas max
+    ncanvas = nplotall/9
+    #if not an exact divisor we need an extra one for the leftovers:
+    if( nplotall % 9 != 0 ):
+        ncanvas += 1
+    #how many columns and rows we want for each number of plots per canvas
+    colnums = [1,2,2,2,3,3,3,3,3]
+    rownums = [1,1,2,2,2,2,3,3,3]
+    
+    clist = [TCanvas('c{}'.format(i)) for i in range(ncanvas)]
+    plotidx = 0 #count the plots
+    for c in clist:
+        #how many plots on this canvas?
+        #we'll use nplotall as a countdown
+        if( nplotall >= 9):
+            nplot=9
+            nplotall -= 9
+        else:
+            nplot=nplotall
+    
+        #setup the canvas based on number of plots to draw
+        ncols = colnums[nplot - 1]
+        nrows = rownums[nplot - 1]
+        c.SetCanvasSize( 600*ncols, 300*nrows )
+        c.Divide(ncols,nrows)
+
+        for i in range(nplot):
+            #plotidx is overall iterator, i is current canvas iterator
+            if (plotidx < npre):
+                c.cd(i+1)
+                hlist_pre[plotidx].Draw()
+            elif(plotidx < npre + ntreedraw):
+                c.cd(i+1)
+                t.Draw( drawcommands[plotidx-npre].command, drawcommands[plotidx-npre].cut, drawcommands[plotidx-npre].option )
+                h = t.GetHistogram()
+                gPad.h = h
+                h.SetTitle(drawcommands[plotidx-npre].title)
+                if(drawcommands[plotidx-npre].postprocessor):
+                    newcut = drawcommands[plotidx-npre].postprocessor( gPad, t, h )
+                    if type(newcut) == str:
+                        fidcut += " && " + newcut
+            else:
+                c.cd(i+1)
+                hlist_post[plotidx - npre - ntreedraw](t,fidcut).Draw()
+
+            plotidx+=1
+                
+        plotpath = "{}/monitoring-{}".format( monitordir, c.GetName()[1:] )
+        saveall(c, plotpath)
+        plotlist += ["{}.png".format(plotpath)]
+
+#open up an eye of gnome window to look at the plots; use the next and previous arrows to navigate between them
+if( plotlist ):
+    subprocess.call(["eog",]+plotlist) 
+
diff --git a/TbUT/scripts/.svn/text-base/plotADCs.C.svn-base b/TbUT/scripts/.svn/text-base/plotADCs.C.svn-base
new file mode 100644
index 0000000..d7c008e
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/plotADCs.C.svn-base
@@ -0,0 +1,309 @@
+///////////////////////////////////////////////////
+//
+// Macro: plotADCs.C
+// Author: S. Blusk
+// Date: Oct 19, 2015
+//
+// Purpose: To loop over events and look at the CMS ADC distribution vs channel number
+// Can also be run on selected events, liste in a file: "MissingDUTHits.dat", which can
+// be obtained by running ClusterAnaWithTrack
+// with the flag 
+//      writeEventsWithMissinhHitsToFile = true
+//
+// Note: The cursor needs to be on the event display window to advance to the next event.
+// Hit ENTER to go to next event.
+//
+///////////////////////////////////////////////////
+
+bool plotSelectedEvents = true;
+bool showEventDisplay = true;
+
+bool fillStatDistribution = true;  // Fill summary histogram
+
+int lowCh = 127; // Low Channel number of ADC distribution
+int hiCh = 256;  // High Channel number of ADC distribution
+
+int evList[20000];
+double nomStrip[20000];
+double xtrk[20000];
+double ytrk[20000];
+// Various arrays of parameters common to this macro
+double tdcTime = 0;
+double adcs[512] = {0};
+double finalSignal[512] = {0};
+
+int NCluster = 0;
+float ClusterCharge[100] = {0};
+int ClusterSize[100] ={0};
+float ClusterPosY[100] ={0};
+float seedChannel[100] ={0};
+
+int iOffSet = 0;               // Offset into tree, to get to specific events
+int printEventDisplays = 0;   // Number of event displays to print to file
+float polarity = -1.0;
+
+
+/////////////////////////////////////////////////////////////////////////////////
+
+void plotADCs(){
+  gStyle->SetNdivisions(505,"Y");
+  gStyle->SetNdivisions(505,"X");
+  gStyle->SetOptStat(0);
+  gStyle->SetOptFit(1);
+  gStyle->SetPadTickX(1);
+  gStyle->SetPadTickY(1);
+
+  //TString sigFile = getFileToOpen(runNum);
+  TString sigFile = "/data2/sblusk/TB/July2015/AnaFiles/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple.root";
+
+  
+  // Open signal file
+  TFile *fs = new TFile(sigFile);  
+  TTree* cmstree = (TTree*)fs->Get("TbUT/CMS");
+  TTree* fChain = (TTree*)fs->Get("TbUT/Clusters");
+  int nevents = cmstree->GetEntriesFast();
+
+  // Strip level data
+  Double_t        cmsData[512];
+  // List of branches
+  TBranch        *b_cmsData;   //!
+  cmstree->SetBranchAddress("cmsData", cmsData, &b_cmsData);
+
+  // Clusters
+  // Declaration of leaf types
+  Int_t           clusterNumberPerEvent;
+  UInt_t          clustersTDC;
+  ULong64_t       timestamps;
+  Double_t        clustersPosition[10];
+  Int_t           clustersSeedPosition[10];
+  Double_t        clustersCharge[10];
+  Int_t           clustersSize[10];
+  Double_t        clustersSeedCharge[10];
+  Double_t        clustersCharge2StripLeft[10];
+  Double_t        clustersCharge1StripLeft[10];
+  Double_t        clustersCharge1StripRight[10];
+  Double_t        clustersCharge2StripRight[10];
+  
+  TBranch        *b_clusterNumberPerEvent;   //!
+  TBranch        *b_clustersTDC;   //!
+  TBranch        *b_timestamps;   //!
+  TBranch        *b_clustersPosition;   //!
+  TBranch        *b_clustersSeedPosition;   //!
+  TBranch        *b_clustersCharge;   //!
+  TBranch        *b_clustersSize;   //!
+  TBranch        *b_clustersSeedCharge;   //!
+  TBranch        *b_clustersCharge2StripLeft;   //!
+  TBranch        *b_clustersCharge1StripLeft;   //!
+  TBranch        *b_clustersCharge1StripRight;   //!
+  TBranch        *b_clustersCharge2StripRight;   //!
+  
+  fChain->SetBranchAddress("clusterNumberPerEvent", &clusterNumberPerEvent, &b_clusterNumberPerEvent);
+  fChain->SetBranchAddress("clustersTDC", &clustersTDC, &b_clustersTDC);
+  fChain->SetBranchAddress("timestamps", &timestamps, &b_timestamps);
+  fChain->SetBranchAddress("clustersPosition", clustersPosition, &b_clustersPosition);
+  fChain->SetBranchAddress("clustersSeedPosition", clustersSeedPosition, &b_clustersSeedPosition);
+  fChain->SetBranchAddress("clustersCharge", clustersCharge, &b_clustersCharge);
+  fChain->SetBranchAddress("clustersSize", clustersSize, &b_clustersSize);
+  fChain->SetBranchAddress("clustersSeedCharge", clustersSeedCharge, &b_clustersSeedCharge);
+  fChain->SetBranchAddress("clustersCharge2StripLeft", clustersCharge2StripLeft, &b_clustersCharge2StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripLeft", clustersCharge1StripLeft, &b_clustersCharge1StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripRight", clustersCharge1StripRight, &b_clustersCharge1StripRight);
+  fChain->SetBranchAddress("clustersCharge2StripRight", clustersCharge2StripRight, &b_clustersCharge2StripRight);
+  
+  TH1F *h = new TH1F("h","ADC, CM + Step Subtracted",512,0.0,512);  
+  TH1F *hm1 = new TH1F("hm1","ADC of nomStrip",110,-100.0,1000);  
+  TH1F *hm = new TH1F("hm","ADC of nomStrip#pm1",110,-100.0,1000);
+  h->SetTitle("");
+  h->SetNdivisions(510,"X");
+
+  TCanvas *theCanvas;
+  int nPrint = 0;
+  
+  char input;
+  int nEvents;
+  
+  int jentry;
+  double strip, xp, yp;
+
+  std::ifstream infile;
+  if(plotSelectedEvents){
+    // Read in event list
+    TString filename = "MissingDUTHits.dat";
+    cout << "------------------------------------------------------------" << endl;
+    cout << " You've selected to view events from file: " << filename << endl;
+    cout << "------------------------------------------------------------" << endl;    
+    infile.open(filename);
+    if(!infile) { // file couldn't be opened
+      cerr << "Error: file could not be opened" << endl;
+      exit(1);
+    }
+    int il = 0;   
+    while ( !infile.eof() ) { // keep reading until end-of-file
+      infile >> jentry >> strip >> xp >> yp;
+     if(il>9999) break;
+     evList[il] = jentry;
+     nomStrip[il] = strip;
+     xtrk[il] = xp;
+     ytrk[il] = yp;
+     il++;     
+   }
+   infile.close();
+   nEvents = nevents - 1000;
+  }else{
+    cout << "How many events do you want to look at ?" << endl;
+    cin >> nEvents;
+    cout << "--------------------------------------"<<endl;
+  }
+
+  //------------------------  
+  // Begin Loop over events
+  //------------------------
+  il = 0;
+  for(int i=iOffSet; i<iOffSet+nEvents; i++){
+    //if(i%1==0) cout << "Processing Event " << i << endl;
+    if(plotSelectedEvents){
+      if(i != evList[il]) continue;
+      //if(showEventDisplay){
+      //  cout << "-------------------------------------------------------------------------------"<<endl;
+      //  cout << "Found selected event: " << i << ", NomStrip of Missing Hit = " << nomStrip[il] << endl;
+      //  cout << "-------------------------------------------------------------------------------"<<endl;
+      //} 
+    }
+
+    cmstree->GetEntry(i);
+    fChain->GetEntry(i);
+    int k=0;
+
+    //--------------
+    // Get CMS data
+    //--------------
+    for(int j=0; j<512;j++){
+      adcs[j] = cmsData[j];
+    }
+
+    //------------------
+    // Get Cluster data
+    //------------------
+    NCluster = clusterNumberPerEvent;
+    if(NCluster>=10) NCluster=10;
+    if(showEventDisplay) cout << "# Clusters = " << NCluster << endl;
+    for(int j=0; j<NCluster; j++){
+      ClusterSize[j] = clustersSize[j];
+      ClusterPosY[j] = 1.0*clustersPosition[j];
+      ClusterCharge[j] = clustersCharge[j];
+      tdcTime = clustersTDC;
+    }
+
+
+    //-------------------------
+    // Get signal distributions
+    //-------------------------
+    getSignal();      
+
+    int nstrip = 0;
+    double vstrip1 = 0, vstrip3 = 0;
+    if(plotSelectedEvents){
+      nstrip = nomStrip[il]+0.5;
+      vstrip1 = finalSignal[nstrip];
+      if(nstrip>1) vstrip3 = vstrip1 + finalSignal[nstrip-1];
+      if(nstrip<511) vstrip3 = vstrip3 + finalSignal[nstrip+1];
+      vstrip1 = -1.0*vstrip1;
+      vstrip3 = -1.0*vstrip3;
+      
+    }
+    
+    //------------------------------------------------------------
+    // Single Event displays of pedestal & noise subtracted data -
+    //------------------------------------------------------------
+    if(showEventDisplay){
+      theCanvas = plotSingleEvent(i, h, nomStrip[il]);  
+      cout << "NomStrip = " << nstrip << " .... Charge in nomStrip and nomStrip +- 1: " << vstrip1 << "  " << vstrip3 << endl;
+      printf("\n <<< ENTER / RETURN to continue >>> \n");
+      theCanvas->WaitPrimitive();
+      if(nPrint < printEventDisplays){
+        theCanvas->Print(Form("./Plots/EventDisplayCorr_%d.png",i));
+        theCanvas->Print(Form("./Plots/EventDisplayCorr_%d.pdf",i)); 
+        nPrint++;
+      }
+    }
+    
+    //----------------
+    // Fill histograms
+    //----------------
+    if(fillStatDistribution && plotSelectedEvents){
+      hm1->Fill(-1.0*vstrip1);
+      hm->Fill(-1.0*vstrip3);
+    }
+    
+    if(plotSelectedEvents) il++;    
+  }
+
+  
+  // Plot statistical distributions
+  TCanvas *c = new TCanvas("c","Plots",500,800);
+  c->Divide(1,2);
+  c->cd(1);  
+  hm1->Draw();
+  c->cd(2);  
+  hm->Draw();
+}
+
+void getSignal(){
+  // -----------------
+  // -  Final result -
+  //    - Here, one could make any "corrections", or flip polarity, etc
+  // -----------------
+  for(int k=0;k<256;k++){finalSignal[k] = adcs[k];}  
+  return;
+}
+
+
+TCanvas* plotSingleEvent(int i, TH1F *h, double xstrip)
+{
+  //-----------------
+  // Final result
+  //-----------------
+  double low = 1000;
+  double hi = -1000;
+
+  h->Reset();  
+  for(int k=0;k<512;k++) {
+    h->Fill(k,finalSignal[k]);
+    if(finalSignal[k]<low) low = finalSignal[k];
+    if(finalSignal[k]>hi) hi = finalSignal[k];
+  }
+  
+  h->SetMinimum(low-100);
+  h->SetMaximum(hi+300);
+  h->GetXaxis()->SetRangeUser(lowCh,hiCh);
+
+  TCanvas *c = new TCanvas("c","",500,0,800,800);
+  h->Draw();
+  TLine *l = new TLine(lowCh, 0, hiCh, 0);
+  TLine *l2 = new TLine(xstrip, low-100, xstrip, hi+150);
+  l2->SetLineColor(5);   l2->SetLineWidth(4); l2->Draw();
+  l->SetLineColor(3); l->SetLineStyle(2); l->SetLineWidth(2); l->Draw();  
+  h->Draw("same");
+  
+
+  TLatex *myLatex = new TLatex();
+  myLatex->SetTextFont(42); myLatex->SetTextColor(1); 
+  myLatex->SetTextAlign(12); myLatex->SetNDC(kTRUE); myLatex->SetTextSize(0.065);
+  myLatex->DrawLatex(0.14,0.85,Form("Event %d",i));
+  TString tdcs = Form("TDC time = %4.1f ns",tdcTime);
+  myLatex->SetTextSize(0.045);myLatex->DrawLatex(0.18,0.79,tdcs);  
+
+
+  float yval = 0.79;
+  myLatex->SetTextSize(0.035);
+  yval = yval - 0.05;
+  for(int k=0;k<NCluster;k++){
+    TString clString = Form("Size=%d,  Q=%3.0f,  Pos=%4.1f",ClusterSize[k],ClusterCharge[k],ClusterPosY[k]);
+    myLatex->DrawLatex(0.14,yval,clString);  
+    yval = yval - 0.05;
+  }
+
+  return c;
+}
+
+
diff --git a/TbUT/scripts/.svn/text-base/runClusterAna.C.svn-base b/TbUT/scripts/.svn/text-base/runClusterAna.C.svn-base
new file mode 100644
index 0000000..e86e022
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/runClusterAna.C.svn-base
@@ -0,0 +1,9 @@
+void runClusterAna(int bias = 350){
+
+  gROOT->ProcessLine(".L AnalysisBaseCluOnly.C+");
+  gROOT->ProcessLine(".L ClusterAna.C+");
+  
+  TTree *t;
+  ClusterAna a(bias);
+  a.Loop();
+}
diff --git a/TbUT/scripts/.svn/text-base/runClusterAnaLoop.C.svn-base b/TbUT/scripts/.svn/text-base/runClusterAnaLoop.C.svn-base
new file mode 100644
index 0000000..86f3edd
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/runClusterAnaLoop.C.svn-base
@@ -0,0 +1,44 @@
+void runClusterAnaLoop(TString board = "A1", int iSector = 1){
+
+  if(board=="A8"){
+    const int nBias = 9;  
+    int bias[nBias] = {400, 350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board=="D5"){
+    const int nBias = 10;  
+    int bias[nBias] = {500, 400, 350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board=="A2"){
+    const int nBias = 9;  
+    int bias[nBias] = {340, 325, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board=="A1"){
+    const int nBias = 8;  
+    int bias[nBias] = {350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board.Contains("D7")){
+    const int nBias = 8;  
+    int bias[nBias] = {500, 400, 300, 200, 150, 100, 75, 50};
+  }else if(board.Contains("A4")){
+    const int nBias = 9;  
+    int bias[nBias] = {400, 350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board.Contains("A6")){
+    const int nBias = 7;  
+    int bias[nBias] = {300, 250, 200, 150, 100, 75, 50};
+  }
+
+  gROOT->ProcessLine(".L AnalysisBaseCluOnly.C+");
+  gROOT->ProcessLine(".L ClusterAna.C+");
+
+  TTree *t;
+
+  for(int i=0; i<nBias;i++) {
+    int b = bias[i];
+    cout << "+++++++++++++++++++++++++++++++++++++++" << endl;
+    cout << "Processing Bias = " << b << "V " << endl;
+    cout << "+++++++++++++++++++++++++++++++++++++++" << endl;    
+    if(board=="D7" && iSector == 1 && b == 300) continue;
+    
+    
+    ClusterAna a(b);  
+    a.Loop();
+
+  }
+}  
+
diff --git a/TbUT/scripts/.svn/text-base/runClusterWithTrackAna.C.svn-base b/TbUT/scripts/.svn/text-base/runClusterWithTrackAna.C.svn-base
new file mode 100644
index 0000000..a1b98cc
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/runClusterWithTrackAna.C.svn-base
@@ -0,0 +1,16 @@
+#include <stdlib.h> 
+#include "AnalysisBase_Inputs.h"
+
+void runClusterWithTrackAna(){
+
+  int bias = atoi(m_bias);
+  
+  gROOT->ProcessLine(".L CMS.C+");
+  gROOT->ProcessLine(".L AnalysisBase.C+");
+  gROOT->ProcessLine(".L ClusterWithTrackAna.C+");
+  
+  TTree *t;
+  ClusterWithTrackAna a(bias);
+  a.Loop();
+
+}
diff --git a/TbUT/scripts/.svn/text-base/runExampleAnalysis.C.svn-base b/TbUT/scripts/.svn/text-base/runExampleAnalysis.C.svn-base
new file mode 100644
index 0000000..83451b9
--- /dev/null
+++ b/TbUT/scripts/.svn/text-base/runExampleAnalysis.C.svn-base
@@ -0,0 +1,16 @@
+{
+  //-------------------------
+  // To execute:
+  // SetupProject LHCb v36r2
+  // root[]: .x runExampleAnalysis.C
+  //
+  //-------------------------
+
+  gROOT->ProcessLine(".L CMS.C+");
+  gROOT->ProcessLine(".L AnalysisBase.C+");
+  gROOT->ProcessLine(".L ExampleAnalysis.C+");
+
+  ExampleAnalysis a;
+  a.Loop();
+
+}
diff --git a/TbUT/scripts/.svn/tmp/AnalysisBase_Inputs.h.2.tmp b/TbUT/scripts/.svn/tmp/AnalysisBase_Inputs.h.2.tmp
new file mode 100644
index 0000000..90bed34
--- /dev/null
+++ b/TbUT/scripts/.svn/tmp/AnalysisBase_Inputs.h.2.tmp
@@ -0,0 +1,62 @@
+//const TString m_fileIndir = "/data2/pmmannin/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/Nov2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/July2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/November2015/";
+//const TString m_board 	= "A1_Full"; 
+//const TString m_board 	= "D7_All"; 
+// Board, use: _board = "D5_All", A8_All" - October TB
+// const TString m_board 	= "D5_All"; 
+
+// =========================================================
+
+<<<<<<< .mine
+//<<<<<<< .mine
+/* /\* const TString m_fileIndir = "/data2/sblusk/TB/July2015/AnaFiles/";  *\/ */
+ const TString m_fileIndir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/";  
+/* //const TString m_fileOutdir = "~/lhcb/testbeam/";  */
+ const TString m_fileOutdir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/"; 
+/* const TString m_board 	= "B6";  */
+/* const TString m_bias  	= "50"; */
+/* const TString m_sector	= "3";  */
+//=======
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+=======
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+const TString m_fileIndir = "/afs/cern.ch/work/s/sblusk/public/TB/"; 
+const TString m_board 	= "A6"; 
+>>>>>>> .r205225
+
+const TString m_board 	= "A6"; 
+
+TString m_bias  	= "50";
+const TString m_sector	= "3"; 
+//const TString m_scanType = "Angle";
+const TString m_scanType = "Bias";
+const TString m_angle = "0";
+
+//const TString m_fileOutdir = "~/lhcb/testbeam/"; 
+//>>>>>>> .r204986
+
+const TString plotdir 	= "plots";
+
+
+//=======
+//>>>>>>> .r204986
+const double nChan 			= 512.0;
+const double stripPitch = 0.190;
+
+const bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+const double trackTriggerTimeDiffCut = 2.5;   // Default = 2.5
+
+const bool isPType = true;
+
+const int kClusterChargeMin = 150;
+const double ratioForHole 	= 0.05;
+const double ratioForDeadStrip 	= 0.6;
+const double ratioForNoisyStrip = 1.8;
+const bool vetoDeadStripRegions = false;
+const double k_DeadStrip 				= 0.12;
+
+const double m_minDistFromHole = 0.05;
+const bool removeTracksInHoleDef = false;
diff --git a/TbUT/scripts/.svn/tmp/AnalysisBase_Inputs.h.tmp b/TbUT/scripts/.svn/tmp/AnalysisBase_Inputs.h.tmp
new file mode 100644
index 0000000..9aba381
--- /dev/null
+++ b/TbUT/scripts/.svn/tmp/AnalysisBase_Inputs.h.tmp
@@ -0,0 +1,58 @@
+//const TString m_fileIndir = "/data2/pmmannin/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/Nov2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/July2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/November2015/";
+//const TString m_board 	= "A1_Full"; 
+//const TString m_board 	= "D7_All"; 
+// Board, use: _board = "D5_All", A8_All" - October TB
+// const TString m_board 	= "D5_All"; 
+
+// =========================================================
+
+<<<<<<< .mine
+/* const TString m_fileIndir = "/data2/sblusk/TB/July2015/AnaFiles/";  */
+const TString m_fileIndir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/"; 
+//const TString m_fileOutdir = "~/lhcb/testbeam/"; 
+const TString m_fileOutDir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/";
+const TString m_board 	= "B6"; 
+const TString m_bias  	= "300";
+const TString m_sector	= "3"; 
+=======
+const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+const TString m_board 	= "A2"; 
+
+TString m_bias  	= "300";
+const TString m_sector	= "1"; 
+//const TString m_scanType = "Angle";
+const TString m_scanType = "Bias";
+const TString m_angle = "0";
+
+const TString m_fileOutdir = "~/lhcb/testbeam/"; 
+>>>>>>> .r204986
+
+const TString plotdir 	= "plots";
+
+<<<<<<< .mine
+//const TString f_out			= m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board + "_" + m_bias + "_" + m_sector + ".root"; 
+//const TString f_out			= "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/Run_Bias_Scan-B6-A-299-8431.root"; 
+
+=======
+>>>>>>> .r204986
+const double nChan 			= 512.0;
+const double stripPitch = 0.190;
+
+const bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+const double trackTriggerTimeDiffCut = 2.5;   // Default = 2.5
+
+const bool isPType = true;
+
+const int kClusterChargeMin = 150;
+const double ratioForHole 	= 0.05;
+const double ratioForDeadStrip 	= 0.6;
+const double ratioForNoisyStrip = 1.8;
+const bool vetoDeadStripRegions = false;
+const double k_DeadStrip 				= 0.12;
+
+const double m_minDistFromHole = 0.05;
+const bool removeTracksInHoleDef = false;
diff --git a/TbUT/scripts/.svn/tmp/runClusterWithTrackAna.C.tmp b/TbUT/scripts/.svn/tmp/runClusterWithTrackAna.C.tmp
new file mode 100644
index 0000000..2099a34
--- /dev/null
+++ b/TbUT/scripts/.svn/tmp/runClusterWithTrackAna.C.tmp
@@ -0,0 +1,22 @@
+#include <stdlib.h> 
+#include "AnalysisBase_Inputs.h"
+
+void runClusterWithTrackAna(){
+
+  int bias = atoi(m_bias);
+  
+  gROOT->ProcessLine(".L CMS.C+");
+  gROOT->ProcessLine(".L AnalysisBase.C+");
+  gROOT->ProcessLine(".L ClusterWithTrackAna.C+");
+<<<<<<< .mine
+
+  //  ClusterWithTrackAna a;
+  //a.Loop();
+=======
+  
+  TTree *t;
+  ClusterWithTrackAna a(bias);
+  a.Loop();
+>>>>>>> .r204986
+
+}
diff --git a/TbUT/scripts/.svn/tmp/text-base/AnalysisBase_Inputs.h.svn-base b/TbUT/scripts/.svn/tmp/text-base/AnalysisBase_Inputs.h.svn-base
new file mode 100644
index 0000000..cce84c6
--- /dev/null
+++ b/TbUT/scripts/.svn/tmp/text-base/AnalysisBase_Inputs.h.svn-base
@@ -0,0 +1,43 @@
+//const TString m_fileIndir = "/data2/pmmannin/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/Nov2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/July2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/November2015/";
+//const TString m_board 	= "A1_Full"; 
+//const TString m_board 	= "D7_All"; 
+// Board, use: _board = "D5_All", A8_All" - October TB
+// const TString m_board 	= "D5_All"; 
+
+// =========================================================
+
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+const TString m_fileIndir = "/afs/cern.ch/work/s/sblusk/public/TB/"; 
+const TString m_board 	= "A6"; 
+
+TString m_bias  	= "300";
+const TString m_sector	= "1"; 
+//const TString m_scanType = "Angle";
+const TString m_scanType = "Bias";
+const TString m_angle = "0";
+
+const TString m_fileOutdir = "~/lhcb/testbeam/"; 
+
+const TString plotdir 	= "plots";
+
+const double nChan 			= 512.0;
+const double stripPitch = 0.190;
+
+const bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+const double trackTriggerTimeDiffCut = 2.5;   // Default = 2.5
+
+const bool isPType = true;
+
+const int kClusterChargeMin = 150;
+const double ratioForHole 	= 0.05;
+const double ratioForDeadStrip 	= 0.6;
+const double ratioForNoisyStrip = 1.8;
+const bool vetoDeadStripRegions = false;
+const double k_DeadStrip 				= 0.12;
+
+const double m_minDistFromHole = 0.05;
+const bool removeTracksInHoleDef = false;
diff --git a/TbUT/scripts/AddTrigTracks/.svn/all-wcprops b/TbUT/scripts/AddTrigTracks/.svn/all-wcprops
new file mode 100644
index 0000000..e4c18b2
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/196718/Kepler/trunk/Tb/TbUT/scripts/AddTrigTracks
+END
+combDUTwithTrack.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 91
+/guest/lhcb/!svn/ver/196718/Kepler/trunk/Tb/TbUT/scripts/AddTrigTracks/combDUTwithTrack.cpp
+END
+Makefile
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/196219/Kepler/trunk/Tb/TbUT/scripts/AddTrigTracks/Makefile
+END
diff --git a/TbUT/scripts/AddTrigTracks/.svn/entries b/TbUT/scripts/AddTrigTracks/.svn/entries
new file mode 100644
index 0000000..514fe0c
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/scripts/AddTrigTracks
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-23T18:44:23.331999Z
+196718
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+combDUTwithTrack.cpp
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+14fd7b01f4769dd5ba98718a80aff769
+2015-10-23T18:44:23.331999Z
+196718
+sblusk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+10569
+
+Makefile
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+fa391f6c5d1bd4f8f778c5addebd4acf
+2015-10-13T13:49:10.939969Z
+196219
+pmanning
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+200
+
diff --git a/TbUT/scripts/AddTrigTracks/.svn/prop-base/Makefile.svn-base b/TbUT/scripts/AddTrigTracks/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/scripts/AddTrigTracks/.svn/text-base/Makefile.svn-base b/TbUT/scripts/AddTrigTracks/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..4d38bf1
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,11 @@
+ROOTC=$(shell root-config --cflags)
+ROOTL=$(shell root-config --glibs)
+
+all: combDUTwithTrack
+
+combDUTwithTrack: combDUTwithTrack.cpp
+	g++ $(ROOTC) -o $@ $^ $(ROOTL) 
+
+
+clean:
+	rm -f combDUTwithTrack
diff --git a/TbUT/scripts/AddTrigTracks/.svn/text-base/combDUTwithTrack.cpp.svn-base b/TbUT/scripts/AddTrigTracks/.svn/text-base/combDUTwithTrack.cpp.svn-base
new file mode 100644
index 0000000..034bb2c
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/.svn/text-base/combDUTwithTrack.cpp.svn-base
@@ -0,0 +1,338 @@
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+//
+// This code will append tracking information to a ROOT tree that contains cluster information from a UT DUT 
+//
+// To compile
+//   > SetupProject LHCb
+//   > make
+//
+// Example of how to run interactively:
+// 
+// ./combDUTwithTrack -i /data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root -t /data2/sblusk/TB/July2015/TelescopeData/BoardA4/Kepler-tuple.root -o /data2/sblusk/test2.root
+//
+//
+// The Telescope data is on eos at:~/eos/lhcb/testbeam/ut/TelescopeData/July2015/RootFiles/RunXXXX/Output/Kepler-tuple.root
+// where XXXX = run number from TPIX DAQ system (Kepler run #)
+//
+// The DUT data needs to be processed through TbUT and put on eos in a standard area.
+// 
+// The easiest, although ot safest way, to get the data directly accessible from eos is to use:
+// eosmount ~/eos
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+#include <iostream>
+#include <vector>
+#include <fstream>
+
+#include "TFile.h"
+#include "TROOT.h"
+#include "TSystem.h"
+#include "TTree.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TF1.h"
+
+#ifdef __MAKECINT__
+#pragma link C++ class vector<float>+;
+#endif
+
+using namespace std;
+
+int main(int __argc, char *__argv[]){
+
+  gROOT->ProcessLine("#include <vector>");
+  const char *dut_filename  = "dut.root";
+  const char *tp3_filename = "tp3.root";
+  const char *out_filename = "outputfile.root";
+	const char *noise_filename = "noise.root"; 
+
+  int c;
+  extern char* optarg;
+  extern int optind;
+
+  int _triggerPlane(-1);
+  int _timeOffset = 0;
+
+  cout << endl;
+  
+  /*____________________________Parse Command Line___________________________*/
+  while((c = getopt(__argc,__argv,"i:t:n:o:h")) != -1){
+    switch(c){
+      case 'h': // help option
+        cout << "Example: ./combineDUTwithTrack -i dut.root -t tp3.root -o outputfile.root" << endl; 
+        return 0;
+        break;
+      case 'i':
+        dut_filename = optarg;
+        cout << "---> DUT ROOT filename: " << dut_filename << endl;
+        break;
+      case 't':
+        tp3_filename = optarg;
+        cout << "---> TimePix3 ROOT filename: " << tp3_filename << endl;
+        break;
+      case 'o':
+        out_filename = optarg;
+        cout << "---> Combined output filename: " << out_filename << endl;
+        break;
+      case 'n':
+        noise_filename = optarg;
+        cout << "---> Noise ROOT filename: " << noise_filename << endl;
+        break;
+      default: // unknown option flag
+        printf("Error!!!! Unknown option -%c\n",c);
+        cout << "Example: combineDUTwithTrack -i dut.root -t tp3.root -o outputfile.root" << endl; 
+      return 0;
+    }
+  }
+
+  cout << endl;
+  
+
+  // get info from Kepler file
+  double trk_x, trk_y, trk_tx, trk_ty, chi2ndf, trk_htime, trg_htime0;
+  ULong64_t trg_time0, trg_time0_25ns;
+  ULong64_t trk_time, trk_time_25ns, timestamps;
+  ULong64_t time_window = 1000;
+  ULong64_t diff_time;
+  ULong64_t diff_time_loc;  
+  UInt_t trg_Plane;
+  
+  TBranch        *b_timestamps;   //!
+  
+	cout << "Made it this far!" << endl; 
+ 
+  //dut_filename = "/data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root";
+  TFile *f_ut 		= new TFile(dut_filename,"READONLY");
+  TFile *f_noise 	= new TFile(noise_filename,"READONLY"); 
+	TTree* t_dut 		= (TTree*)f_ut->Get("TbUT/Clusters");
+  t_dut->SetBranchAddress("timestamps",&timestamps, &b_timestamps);
+
+	cout << "Made it a little further! " << endl; 
+  int numEvents = t_dut->GetEntriesFast();
+  cout << " ------------------------------------------------------" << endl;
+  cout << " | Number of triggers found = " << numEvents << endl;
+  cout << " ------------------------------------------------------" << endl;
+
+  //tp3_filename = "/data2/sblusk/TB/July2015/TelescopeData/BoardA4/Kepler-tuple.root";
+  TFile *f_tpix = new TFile(tp3_filename,"READONLY");
+  TTree *t_trk = (TTree*)f_tpix->Get("TbTupleWriter/Tracks");
+  t_trk->SetBranchAddress("TkTime",&trk_time);
+  t_trk->SetBranchAddress("TkHTime",&trk_htime);
+  t_trk->SetBranchAddress("TkX",&trk_x);
+  t_trk->SetBranchAddress("TkY",&trk_y);
+  t_trk->SetBranchAddress("TkTx",&trk_tx);
+  t_trk->SetBranchAddress("TkTy",&trk_ty);
+  t_trk->SetBranchAddress("TkChi2PerNdof",&chi2ndf);
+
+  int nfound=0;  
+  //out_filename = "/data2/sblusk/test.root";
+  TFile *f_out = new TFile(out_filename,"recreate");
+  TTree *t_out = (TTree*)t_dut->CloneTree(0); // grab a copy of the existing DUT tree
+
+  //TFile *fileout = new TFile("temp.root","RECREATE");
+  TH1F *h1 = new TH1F("h1","Time Diff",1000,-1000,1000);
+  TH1F *hMeanNoise = new TH1F("hMeanNoise","Mean of noise, CM subtracted",512,0,512);
+  TH1F *hWidthNoise = new TH1F("hWidthNoise","Gaussian noise, CM subtracted",512,0,512);
+  TH1D *px[512];
+
+  // add the new branches w/ track info
+  int n_tp3_tracks;
+  std::vector<double> *vec_trk_x = 0;
+  std::vector<double> *vec_trk_y = 0;
+  std::vector<double> *vec_trk_tx = 0;
+  std::vector<double> *vec_trk_ty = 0;
+  std::vector<double> *vec_trk_htime = 0; 
+  std::vector<double> *vec_trk_chi2ndf = 0;
+
+
+  t_out->Branch("n_tp3_tracks",&n_tp3_tracks);
+  t_out->Branch("vec_trk_x",&vec_trk_x);
+  t_out->Branch("vec_trk_y",&vec_trk_y);
+  t_out->Branch("vec_trk_tx",&vec_trk_tx);
+  t_out->Branch("vec_trk_ty",&vec_trk_ty);
+  t_out->Branch("vec_trk_chi2ndf",&vec_trk_chi2ndf);
+  //t_out->Branch("vec_trk_htime",&vec_trk_htime);  // don't need this one
+
+  double dtime;
+  t_out->Branch("dtime",&dtime);
+
+
+  int entries = (int)t_trk->GetEntries();
+  int curr_pos(0), j, stop_now;
+
+  // First short pass, check trigger timing
+  int iAli = 0;
+  for(int i=0;i < min(numEvents,10000); i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;    
+    //t_dut->GetEntry(i);
+    if(i%1000==0) cout << "\nprocessing " << i << " curr_pos: " << curr_pos << " " << endl;
+    trg_time0_25ns = timestamps - _timeOffset;
+
+    stop_now = 0;
+    j = curr_pos;
+    while(j < entries && stop_now == 0){
+       t_trk->GetEntry(j);
+       trk_time_25ns = (trk_time>>12);
+       
+       if(trg_time0_25ns > trk_time_25ns){
+           diff_time_loc = trg_time0_25ns - trk_time_25ns;
+       }
+       if(trk_time_25ns > trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+          if(diff_time_loc > time_window) {stop_now=1; curr_pos = j-1;}
+       }
+       if(trk_time_25ns == trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+       }
+
+       double dt = diff_time_loc * 1.0;
+       h1->Fill(dt);       
+      j++;
+    }
+
+    if(curr_pos < 0) curr_pos = 0;
+    
+  }
+
+  double _timeOffsetNew = _timeOffset;
+  int ib = h1->GetMaximumBin();
+  if(ib>0 && ib<h1->GetNbinsX()) _timeOffsetNew = _timeOffsetNew + h1->GetBinCenter(ib);
+  cout << "-----------------------------------------------" << endl;
+  cout << "Resetting time offset to " << _timeOffsetNew << endl;
+  cout << "Setting time window to 5 ns " << endl;
+  cout << "-----------------------------------------------" << endl;  
+
+  time_window = 5;
+  h1->Reset();
+
+  nfound=0;
+  iAli = 0;
+  curr_pos = 0;
+  //numEvents = 5000;
+  
+  for(int i=0;i < numEvents; i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;    
+    if(i%10000==0) cout << "\nprocessing " << i << " curr_pos: " << curr_pos << " " << endl;
+
+    trg_time0_25ns = timestamps - _timeOffsetNew; // in units of 25ns minus the offset
+    vec_trk_x->clear();
+    vec_trk_y->clear();
+    vec_trk_tx->clear();
+    vec_trk_ty->clear();
+    vec_trk_chi2ndf->clear();
+    //vec_trk_htime->clear();
+
+    stop_now = 0;
+    j = curr_pos;
+    while(j < entries && stop_now == 0){
+      int nb2 = t_trk->GetEntry(j);
+      if(nb2 <= 0) break;
+       trk_time_25ns = (trk_time>>12);
+       if(trg_time0_25ns > trk_time_25ns){
+           diff_time_loc = trg_time0_25ns - trk_time_25ns;
+       }
+       if(trk_time_25ns > trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+          if(diff_time_loc > time_window) {stop_now=1; curr_pos = j-1;}
+       }
+       if(trk_time_25ns == trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+       }
+
+       double dt = diff_time_loc * 1.0;
+       h1->Fill(dt);
+       
+
+       //if(diff_time_loc - _timeOffsetNew < time_window){
+       if(dt < time_window){
+         //vec_trk_htime->push_back((trk_htime - trg_htime0));
+         //cout << diff_time_loc - _timeOffsetNew << " " << dt << endl;
+         dtime = dt;
+         vec_trk_x->push_back(trk_x);
+         vec_trk_y->push_back(trk_y);
+         vec_trk_tx->push_back(trk_tx);
+         vec_trk_ty->push_back(trk_ty);
+         vec_trk_chi2ndf->push_back(chi2ndf);
+       }
+       
+       
+      j++;
+    }
+
+    if(curr_pos < 0) curr_pos = 0;
+    n_tp3_tracks = (int)vec_trk_x->size();
+
+    if(n_tp3_tracks > 0) nfound++;
+    if(nfound%1000==0 && nfound > 0) cout << "Found " << nfound << endl;
+    
+    t_out->Fill();
+  }
+
+  //fileout->Write();
+  //fileout->Close();  
+
+  //-------------- Do noise Plots --------------//
+  //--------------------------------------------//
+
+
+  f_noise->cd("TbUT");
+  TH2D *hNoise = (TH2D*)gDirectory->Get("CMSData_vs_channel");
+
+  f_out->cd();
+
+  TF1 *gau = new TF1("gau","gaus(0)",-120,120);
+  gau->SetParameters(10000,0.0,40.0);
+
+  int i = 128;
+  for(int i=0;i<512;i++){
+    if( i>=512 ) {
+      hMeanNoise->SetBinContent(i,-1000);
+      continue;
+    }
+    px[i] = hNoise->ProjectionY(Form("px%d",i),i,i);
+    px[i]->GetXaxis()->SetRangeUser(-200,200);
+    px[i]->SetTitle(Form("Channel %d", i));
+    px[i]->SetName(Form("Ch%d", i));
+    if(px[i]->GetEntries() < 10){
+      hMeanNoise->SetBinContent(i,-1000);
+      continue;
+    }
+    double p = px[i]->GetMaximum();
+    double m = px[i]->GetMean();
+    double e = px[i]->GetRMS();
+    gau->SetParameters(p, m, e);
+    gau->SetRange(m-3*e,m+3*e);
+
+    px[i]->Fit(gau,"RQ");
+    double mn = gau->GetParameter(1);
+    double wid = gau->GetParameter(2);
+    double emn = gau->GetParError(1);
+    double ewid = gau->GetParError(2);
+    hMeanNoise->SetBinContent(i,mn);
+    hMeanNoise->SetBinError(i,emn);
+    hWidthNoise->SetBinContent(i,wid);
+    hWidthNoise->SetBinError(i,ewid);
+  }
+
+  // Save histograms
+  hMeanNoise->Write();
+  hWidthNoise->Write();
+  for(int i=0;i<512;i++){
+   px[i]->Write();
+ }  
+  
+  t_out->AutoSave();
+  delete f_ut;
+  delete f_noise;  
+  delete f_tpix;
+  delete f_out;
+  
+  // Write and close ROOT file.
+  //f_out->Write();
+  //f_out->Close();
+
+  return 0;
+}
diff --git a/TbUT/scripts/AddTrigTracks/Makefile b/TbUT/scripts/AddTrigTracks/Makefile
new file mode 100755
index 0000000..4d38bf1
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/Makefile
@@ -0,0 +1,11 @@
+ROOTC=$(shell root-config --cflags)
+ROOTL=$(shell root-config --glibs)
+
+all: combDUTwithTrack
+
+combDUTwithTrack: combDUTwithTrack.cpp
+	g++ $(ROOTC) -o $@ $^ $(ROOTL) 
+
+
+clean:
+	rm -f combDUTwithTrack
diff --git a/TbUT/scripts/AddTrigTracks/combDUTwithTrack b/TbUT/scripts/AddTrigTracks/combDUTwithTrack
new file mode 100755
index 0000000..2cbd5ac
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/combDUTwithTrack
Binary files differ
diff --git a/TbUT/scripts/AddTrigTracks/combDUTwithTrack.cpp b/TbUT/scripts/AddTrigTracks/combDUTwithTrack.cpp
new file mode 100644
index 0000000..cfcfe9d
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/combDUTwithTrack.cpp
@@ -0,0 +1,353 @@
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+//
+// This code will append tracking information to a ROOT tree that contains cluster information from a UT DUT 
+//
+// To compile
+//   > SetupProject LHCb
+//   > make
+//
+// Example of how to run interactively:
+// 
+// ./combDUTwithTrack -i /data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root -t /data2/sblusk/TB/July2015/TelescopeData/BoardA4/Kepler-tuple.root -o /data2/sblusk/test2.root
+//
+//
+// The Telescope data is on eos at:~/eos/lhcb/testbeam/ut/TelescopeData/July2015/RootFiles/RunXXXX/Output/Kepler-tuple.root
+// where XXXX = run number from TPIX DAQ system (Kepler run #)
+//
+// The DUT data needs to be processed through TbUT and put on eos in a standard area.
+// 
+// The easiest, although ot safest way, to get the data directly accessible from eos is to use:
+// eosmount ~/eos
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+#include <iostream>
+#include <vector>
+#include <fstream>
+
+#include "TFile.h"
+#include "TROOT.h"
+#include "TSystem.h"
+#include "TTree.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TF1.h"
+
+#ifdef __MAKECINT__
+#pragma link C++ class vector<float>+;
+#endif
+
+using namespace std;
+
+int main(int __argc, char *__argv[]){
+
+  gROOT->ProcessLine("#include <vector>");
+  const char *dut_filename  = "dut.root";
+  const char *tp3_filename = "tp3.root";
+  const char *out_filename = "outputfile.root";
+	const char *noise_filename = "noise.root"; 
+
+  int c;
+  extern char* optarg;
+  extern int optind;
+
+  int _triggerPlane(-1);
+  int _timeOffset = 0;
+
+  cout << endl;
+  
+  /*____________________________Parse Command Line___________________________*/
+  while((c = getopt(__argc,__argv,"i:t:n:o:h")) != -1){
+    switch(c){
+      case 'h': // help option
+        cout << "Example: ./combineDUTwithTrack -i dut.root -t tp3.root -o outputfile.root" << endl; 
+        return 0;
+        break;
+      case 'i':
+        dut_filename = optarg;
+        cout << "---> DUT ROOT filename: " << dut_filename << endl;
+        break;
+      case 't':
+        tp3_filename = optarg;
+        cout << "---> TimePix3 ROOT filename: " << tp3_filename << endl;
+        break;
+      case 'o':
+        out_filename = optarg;
+        cout << "---> Combined output filename: " << out_filename << endl;
+        break;
+      case 'n':
+        noise_filename = optarg;
+        cout << "---> Noise ROOT filename: " << noise_filename << endl;
+        break;
+      default: // unknown option flag
+        printf("Error!!!! Unknown option -%c\n",c);
+        cout << "Example: combineDUTwithTrack -i dut.root -t tp3.root -o outputfile.root" << endl; 
+      return 0;
+    }
+  }
+
+  cout << endl;
+  
+
+  // get info from Kepler file
+  double trk_x, trk_y, trk_tx, trk_ty, chi2ndf, trk_htime, trg_htime0;
+  ULong64_t trg_time0, trg_time0_25ns;
+  ULong64_t trk_time, trk_time_25ns, timestamps;
+  ULong64_t time_window = 1000;
+  ULong64_t diff_time;
+  ULong64_t diff_time_loc;  
+  UInt_t trg_Plane;
+  
+  TBranch        *b_timestamps;   //!
+  
+	cout << "Made it this far!" << endl; 
+ 
+  //dut_filename = "/data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root";
+  TFile *f_ut 		= new TFile(dut_filename,"READONLY");
+  TFile *f_noise 	= new TFile(noise_filename,"READONLY"); 
+	TTree* t_dut 		= (TTree*)f_ut->Get("TbUT/Clusters");
+  t_dut->SetBranchAddress("timestamps",&timestamps, &b_timestamps);
+
+	cout << "Made it a little further! " << endl; 
+  int numEvents = t_dut->GetEntriesFast();
+  cout << " ------------------------------------------------------" << endl;
+  cout << " | Number of triggers found = " << numEvents << endl;
+  cout << " ------------------------------------------------------" << endl;
+
+  //tp3_filename = "/data2/sblusk/TB/July2015/TelescopeData/BoardA4/Kepler-tuple.root";
+  TFile *f_tpix = new TFile(tp3_filename,"READONLY");
+  TTree *t_trk = (TTree*)f_tpix->Get("TbTupleWriter/Tracks");
+  t_trk->SetBranchAddress("TkTime",&trk_time);
+  t_trk->SetBranchAddress("TkHTime",&trk_htime);
+  t_trk->SetBranchAddress("TkX",&trk_x);
+  t_trk->SetBranchAddress("TkY",&trk_y);
+  t_trk->SetBranchAddress("TkTx",&trk_tx);
+  t_trk->SetBranchAddress("TkTy",&trk_ty);
+  t_trk->SetBranchAddress("TkChi2PerNdof",&chi2ndf);
+
+  int nfound=0;  
+  //out_filename = "/data2/sblusk/test.root";
+  TFile *f_out = new TFile(out_filename,"recreate");
+  TTree *t_out = (TTree*)t_dut->CloneTree(0); // grab a copy of the existing DUT tree
+
+  //TFile *fileout = new TFile("temp.root","RECREATE");
+  TH1F *h1 = new TH1F("h1","Time Diff",1000,-1000,1000);
+  TH1F *hMeanNoise = new TH1F("hMeanNoise","Mean of noise, CM subtracted",512,0,512);
+  TH1F *hWidthNoise = new TH1F("hWidthNoise","Gaussian noise, CM subtracted",512,0,512);
+  TH1D *px[512];
+
+  // add the new branches w/ track info
+  int n_tp3_tracks;
+  std::vector<double> *vec_trk_x = 0;
+  std::vector<double> *vec_trk_y = 0;
+  std::vector<double> *vec_trk_tx = 0;
+  std::vector<double> *vec_trk_ty = 0;
+  std::vector<double> *vec_trk_htime = 0; 
+  std::vector<double> *vec_trk_chi2ndf = 0;
+
+
+  t_out->Branch("n_tp3_tracks",&n_tp3_tracks);
+  t_out->Branch("vec_trk_x",&vec_trk_x);
+  t_out->Branch("vec_trk_y",&vec_trk_y);
+  t_out->Branch("vec_trk_tx",&vec_trk_tx);
+  t_out->Branch("vec_trk_ty",&vec_trk_ty);
+  t_out->Branch("vec_trk_chi2ndf",&vec_trk_chi2ndf);
+  //t_out->Branch("vec_trk_htime",&vec_trk_htime);  // don't need this one
+
+  double dtime;
+  t_out->Branch("dtime",&dtime);
+
+
+  int entries = (int)t_trk->GetEntries();
+  int curr_pos(0), j, stop_now;
+
+  // First short pass, check trigger timing
+  int iAli = 0;
+  for(int i=0;i < min(numEvents,10000); i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) {
+
+      cout << "breaking" << endl;
+      break;    
+    }
+    //t_dut->GetEntry(i);
+    if(i%1000==0) cout << "\nprocessing " << i << " curr_pos: " << curr_pos << " " << endl;
+    trg_time0_25ns = timestamps - _timeOffset;
+
+    stop_now = 0;
+    j = curr_pos;
+    while(j < entries && stop_now == 0){
+       t_trk->GetEntry(j);
+       trk_time_25ns = (trk_time>>12);
+       
+       if(trg_time0_25ns > trk_time_25ns){
+           diff_time_loc = trg_time0_25ns - trk_time_25ns;
+       }
+       if(trk_time_25ns > trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+          if(diff_time_loc > time_window) {stop_now=1; curr_pos = j-1;}
+       }
+       if(trk_time_25ns == trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+       }
+
+       double dt = diff_time_loc * 1.0;
+       h1->Fill(dt);       
+      j++;
+    }
+
+    if(curr_pos < 0) curr_pos = 0;
+    
+  }
+
+  double _timeOffsetNew = _timeOffset;
+  int ib = h1->GetMaximumBin();
+  if(ib>0 && ib<h1->GetNbinsX()) _timeOffsetNew = _timeOffsetNew + h1->GetBinCenter(ib);
+  cout << "-----------------------------------------------" << endl;
+  cout << "Resetting time offset to " << _timeOffsetNew << endl;
+  cout << "Setting time window to 5 ns " << endl;
+  cout << "-----------------------------------------------" << endl;  
+
+  time_window = 5;
+  h1->Reset();
+
+  nfound=0;
+  iAli = 0;
+  curr_pos = 0;
+  //numEvents = 5000;
+  
+  for(int i=0;i < numEvents; i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;    
+    if(i%10000==0) cout << "\nprocessing " << i << " curr_pos: " << curr_pos << " " << endl;
+
+    trg_time0_25ns = timestamps - _timeOffsetNew; // in units of 25ns minus the offset
+    vec_trk_x->clear();
+    vec_trk_y->clear();
+    vec_trk_tx->clear();
+    vec_trk_ty->clear();
+    vec_trk_chi2ndf->clear();
+    //vec_trk_htime->clear();
+
+    stop_now = 0;
+    j = curr_pos;
+    while(j < entries && stop_now == 0){
+      int nb2 = t_trk->GetEntry(j);
+      if(nb2 <= 0) {
+	cout << "breaking!" << endl;
+break;
+
+      }
+       trk_time_25ns = (trk_time>>12);
+       if(trg_time0_25ns > trk_time_25ns){
+           diff_time_loc = trg_time0_25ns - trk_time_25ns;
+       }
+       if(trk_time_25ns > trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+          if(diff_time_loc > time_window) {stop_now=1; curr_pos = j-1;}
+       }
+       if(trk_time_25ns == trg_time0_25ns){
+          diff_time_loc = trk_time_25ns - trg_time0_25ns;
+       }
+
+       double dt = diff_time_loc * 1.0;
+       h1->Fill(dt);
+       
+
+       //if(diff_time_loc - _timeOffsetNew < time_window){
+       if(dt < time_window){
+         //vec_trk_htime->push_back((trk_htime - trg_htime0));
+         //cout << diff_time_loc - _timeOffsetNew << " " << dt << endl;
+         dtime = dt;
+         vec_trk_x->push_back(trk_x);
+         vec_trk_y->push_back(trk_y);
+         vec_trk_tx->push_back(trk_tx);
+         vec_trk_ty->push_back(trk_ty);
+         vec_trk_chi2ndf->push_back(chi2ndf);
+       }
+       
+       
+      j++;
+    }
+
+    if(curr_pos < 0) curr_pos = 0;
+    n_tp3_tracks = (int)vec_trk_x->size();
+
+    if(n_tp3_tracks > 0) nfound++;
+    if(nfound%1000==0 && nfound > 0) cout << "Found " << nfound << endl;
+    if(nfound == 0) {
+
+      cout << "no tracks" << endl;
+
+    }
+
+
+    t_out->Fill();
+  }
+
+  //fileout->Write();
+  //fileout->Close();  
+
+  //-------------- Do noise Plots --------------//
+  //--------------------------------------------//
+
+
+  f_noise->cd("TbUT");
+  // f_noise->cd("/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT");
+  TH2D *hNoise = (TH2D*)gDirectory->Get("CMSData_vs_channel");
+
+  f_out->cd();
+
+  TF1 *gau = new TF1("gau","gaus(0)",-120,120);
+  gau->SetParameters(10000,0.0,40.0);
+
+  int i = 128;
+  for(int i=0;i<512;i++){
+    if( i>=512 ) {
+      hMeanNoise->SetBinContent(i,-1000);
+      continue;
+    }
+    px[i] = hNoise->ProjectionY(Form("px%d",i),i,i);
+    px[i]->GetXaxis()->SetRangeUser(-200,200);
+    px[i]->SetTitle(Form("Channel %d", i));
+    px[i]->SetName(Form("Ch%d", i));
+    if(px[i]->GetEntries() < 10){
+      hMeanNoise->SetBinContent(i,-1000);
+      continue;
+    }
+    double p = px[i]->GetMaximum();
+    double m = px[i]->GetMean();
+    double e = px[i]->GetRMS();
+    gau->SetParameters(p, m, e);
+    gau->SetRange(m-3*e,m+3*e);
+
+    px[i]->Fit(gau,"RQ");
+    double mn = gau->GetParameter(1);
+    double wid = gau->GetParameter(2);
+    double emn = gau->GetParError(1);
+    double ewid = gau->GetParError(2);
+    hMeanNoise->SetBinContent(i,mn);
+    hMeanNoise->SetBinError(i,emn);
+    hWidthNoise->SetBinContent(i,wid);
+    hWidthNoise->SetBinError(i,ewid);
+  }
+
+  // Save histograms
+  hMeanNoise->Write();
+  hWidthNoise->Write();
+  for(int i=0;i<512;i++){
+   px[i]->Write();
+ }  
+  
+  t_out->AutoSave();
+  delete f_ut;
+  delete f_noise;  
+  delete f_tpix;
+  delete f_out;
+  
+  // Write and close ROOT file.
+  //f_out->Write();
+  //f_out->Close();
+
+  return 0;
+}
diff --git a/TbUT/scripts/AddTrigTracks/out.root b/TbUT/scripts/AddTrigTracks/out.root
new file mode 100644
index 0000000..de65ad6
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/out.root
Binary files differ
diff --git a/TbUT/scripts/AddTrigTracks/output.root b/TbUT/scripts/AddTrigTracks/output.root
new file mode 100644
index 0000000..de65ad6
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/output.root
Binary files differ
diff --git a/TbUT/scripts/AddTrigTracks/test.root b/TbUT/scripts/AddTrigTracks/test.root
new file mode 100644
index 0000000..18a33b7
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/test.root
Binary files differ
diff --git a/TbUT/scripts/AddTrigTracks/test2.root b/TbUT/scripts/AddTrigTracks/test2.root
new file mode 100644
index 0000000..13ea874
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/test2.root
Binary files differ
diff --git a/TbUT/scripts/AddTrigTracks/test3.root b/TbUT/scripts/AddTrigTracks/test3.root
new file mode 100644
index 0000000..32f445e
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/test3.root
Binary files differ
diff --git a/TbUT/scripts/AddTrigTracks/testing.root b/TbUT/scripts/AddTrigTracks/testing.root
new file mode 100644
index 0000000..9568e60
--- /dev/null
+++ b/TbUT/scripts/AddTrigTracks/testing.root
Binary files differ
diff --git a/TbUT/scripts/AnalysisBase.C b/TbUT/scripts/AnalysisBase.C
new file mode 100644
index 0000000..3ae6a92
--- /dev/null
+++ b/TbUT/scripts/AnalysisBase.C
@@ -0,0 +1,997 @@
+//#define AnalysisBase_cxx
+#include "AnalysisBase.h"
+
+
+AnalysisBase::AnalysisBase(TTree *tree) : fChain(0) 
+{
+
+// Notes
+// For Rz alignment, one should SUBTRACT the slope found from the deltaX vs Y plot.
+// For Z alignment, one should ADD the slope found from the deltaX vs Y plot.
+// For Ry: If slope of DX vs X is negative (positive), reduce (increase) Ry
+//
+  //these have to be able to change so we have to make sure there is only 1 copy of them, so global scope would be bad news
+
+  minDistFromHole =  m_minDistFromHole;
+  holeSector = m_board.Contains("D") && (m_sector=="1" || m_sector=="2" || m_sector == "3");
+  if(!holeSector) minDistFromHole = -9999;
+  
+  stripPitch = 0.190;
+  z_DUT 			= 370; //This needs to be set for different boards
+  Rz 				= -0.0218;
+  Ry 				= 0.00;
+  dxWin 			= 0.25;
+  
+  xGloOff 		= -9.2;
+  yGloOff 		= -7.5;
+  xOff 			= -54.78;
+  correctForZRotation = true;
+  
+  channelOffset = 0.0;
+  xLeftHole = 999;
+  xRightHole = -999;
+  stripGap[0] = 0;
+  stripGap[1] = 0;
+  stripGap[2] = 0;
+  stripGap[3] = 0;
+  nDeadRegion = 0;
+  if(  m_board.Contains("D")) {
+    stripPitch = 0.095;
+    channelOffset = 512.0;
+    //stripGap[0]=19;     
+    //stripGap[1]=39;     
+    //stripGap[2]=58;     
+    //stripGap[3]=0;     
+
+    stripGap[0]=58;     
+    stripGap[1]=39;     
+    stripGap[2]=19;     
+    stripGap[3]=0;     
+
+    if(m_board.Contains("D5")) {
+      z_DUT = 1100.0;
+      //Rz = -0.0230;  
+    }else if(m_board.Contains("D7")) {
+      z_DUT = 1123.0;
+      if(m_sector=="5") z_DUT = 1087.0;
+      if(m_sector=="1") z_DUT = 1040.0;
+      //Ry = -0.008;  
+    }
+  }
+
+
+
+  yInt1[0] = 2.8; yInt1[1] = 3.4;
+  yInt2[0] = 3.4; yInt2[1] = 4.1;
+  yInt3[0] = 1.0; yInt3[1] = 2.3;   
+
+  if(m_board.Contains("A8")){
+    z_DUT = 1100.0;
+    Rz = -0.0286;
+    yInt1[0] = 1.8; yInt1[1] = 2.0;
+    yInt2[0] = 2.0; yInt2[1] = 2.4;
+    yInt3[0] = 1.0; yInt3[1] = 2.3;
+    if(m_sector=="3" || m_sector=="6") {
+      channelOffset = -128.0*2+22;
+    }else{
+      channelOffset = -128.0;
+    }
+    if(m_scanType.Contains("Angle")){
+      if(m_angle == "10") {
+        Ry = 9.3*(TMath::Pi()/180.0);
+        z_DUT = z_DUT - 18.0;
+      } else if(m_angle == "20") {
+        Ry = 19*(TMath::Pi()/180.0);
+        z_DUT = z_DUT - 18.0;
+      }      
+     
+    }    
+  }else if( m_board.Contains("A4")){
+    z_DUT = 381.0;     
+    Rz = -0.0238;
+    if(m_sector=="3" || m_sector=="6") {
+      channelOffset = -128.0*2.0+19;
+    }else{
+      channelOffset = -128.0;
+    }
+  }else if( m_board.Contains("A6")){
+    yInt1[0] = 2.5; yInt1[1] = 3.1;
+    yInt2[0] = 3.1; yInt2[1] = 3.7;
+    yInt3[0] = 1.0; yInt3[1] = 2.3;
+    if(m_sector=="3" || m_sector=="6") {
+      channelOffset = -128.0*2+22;
+    }else{
+      channelOffset = -128.0;
+    }    
+  }else if( m_board.Contains("A2") || m_board.Contains("A1")){
+    z_DUT = 310;
+    yInt1[0] = -5.0; yInt1[1] = -2.0;
+    yInt2[0] = -2.0; yInt2[1] = 1.0;
+    yInt3[0] = 1.0; yInt3[1] = 5.0;
+  }
+
+  // Board A1 alignment is really messed up for a few runs! ADHOC here!
+  if(m_board.Contains("A1")){// && (m_bias=="300" || m_bias=="350" || m_bias=="150" || m_bias==")){  
+    dxWin = 1.0;
+    correctForZRotation = false;
+  }
+   
+  holeQuadPar[0] = 0;
+  holeQuadPar[1] = 0;
+  holeQuadPar[2] = 0;
+  removeTracksInHole = removeTracksInHoleDef;
+  // Only look to remove tacks from hole area if D-type and in sectors 1, 2, or 3.
+  if(!m_board.Contains("D") || !(m_sector=="1" || m_sector=="2" || m_sector=="3") )  removeTracksInHole = false;
+
+  polarity = 1.0;
+  if(isPType) polarity = -1;
+
+
+}
+
+AnalysisBase::~AnalysisBase()
+{
+  if (!fChain) return;
+  delete fChain->GetCurrentFile();
+}
+
+Int_t AnalysisBase::GetEntry(Long64_t entry)
+{
+  // Read contents of entry.
+  if (!fChain) return 0;
+  return fChain->GetEntry(entry);
+}
+Long64_t AnalysisBase::LoadTree(Long64_t entry)
+{
+  // Set the environment to read one entry
+  if (!fChain) return -5;
+  Long64_t centry = fChain->LoadTree(entry);
+  if (centry < 0) return centry;
+  if (fChain->GetTreeNumber() != fCurrent) {
+    fCurrent = fChain->GetTreeNumber();
+    Notify();
+  }
+  return centry;
+}
+
+void AnalysisBase::Init(TTree *tree)
+{
+  // The Init() function is called when the selector needs to initialize
+  // a new tree or chain. Typically here the branch addresses and branch
+  // pointers of the tree will be set.
+  // It is normally not necessary to make changes to the generated
+  // code, but the routine can be extended by the user if needed.
+  // Init() will be called many times when running on PROOF
+  // (once per file to be processed).
+
+  // Set object pointer
+  vec_trk_x = 0;
+  vec_trk_y = 0;
+  vec_trk_tx = 0;
+  vec_trk_ty = 0;
+  vec_trk_chi2ndf = 0;
+  // Set branch addresses and branch pointers
+  if (!tree) return;
+  fChain = tree;
+  fCurrent = -1;
+  fChain->SetMakeClass(1);
+
+  fChain->SetBranchAddress("clusterNumberPerEvent", &clusterNumberPerEvent, &b_clusterNumberPerEvent);
+  fChain->SetBranchAddress("clustersTDC", &clustersTDC, &b_clustersTDC);
+  fChain->SetBranchAddress("timestamps", &timestamps, &b_timestamps);
+  fChain->SetBranchAddress("clustersPosition", clustersPosition, &b_clustersPosition);
+  fChain->SetBranchAddress("clustersSeedPosition", clustersSeedPosition, &b_clustersSeedPosition);
+  fChain->SetBranchAddress("clustersCharge", clustersCharge, &b_clustersCharge);
+  fChain->SetBranchAddress("clustersSize", clustersSize, &b_clustersSize);
+  fChain->SetBranchAddress("clustersSeedCharge", clustersSeedCharge, &b_clustersSeedCharge);
+  fChain->SetBranchAddress("clustersCharge2StripLeft", clustersCharge2StripLeft, &b_clustersCharge2StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripLeft", clustersCharge1StripLeft, &b_clustersCharge1StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripRight", clustersCharge1StripRight, &b_clustersCharge1StripRight);
+  fChain->SetBranchAddress("clustersCharge2StripRight", clustersCharge2StripRight, &b_clustersCharge2StripRight);
+  fChain->SetBranchAddress("n_tp3_tracks", &n_tp3_tracks, &b_n_tp3_tracks);
+  fChain->SetBranchAddress("vec_trk_x", &vec_trk_x, &b_vec_trk_x);
+  fChain->SetBranchAddress("vec_trk_y", &vec_trk_y, &b_vec_trk_y);
+  fChain->SetBranchAddress("vec_trk_tx", &vec_trk_tx, &b_vec_trk_tx);
+  fChain->SetBranchAddress("vec_trk_ty", &vec_trk_ty, &b_vec_trk_ty);
+  fChain->SetBranchAddress("vec_trk_chi2ndf", &vec_trk_chi2ndf, &b_vec_trk_chi2ndf);
+  fChain->SetBranchAddress("dtime", &dtime, &b_dtime);
+
+  Notify();
+}
+
+Bool_t AnalysisBase::Notify()
+{
+  // The Notify() function is called when a new file is opened. This
+  // can be either for a new TTree in a TChain or when when a new TTree
+  // is started when using PROOF. It is normally not necessary to make changes
+  // to the generated code, but the routine can be extended by the
+  // user if needed. The return value is currently not used.
+
+  return kTRUE;
+}
+
+void AnalysisBase::Show(Long64_t entry)
+{
+  // Print contents of entry.
+  // If entry is not specified, print current entry
+  if (!fChain) return;
+  fChain->Show(entry);
+}
+/*
+Int_t AnalysisBase::Cut(Long64_t entry)
+{
+  // This function may be called from Loop.
+  // returns  1 if entry is accepted.
+  // returns -1 otherwise.
+  return 1;
+}
+*/
+void AnalysisBase::getRange(TH1 *h, float &lo, float& hi, float thresh, int nSkipMax){
+
+  int nfail = 0;
+  int iMaxBin = h->GetMaximumBin();
+  lo = iMaxBin;
+  hi = iMaxBin;
+  double maxValue = h->GetBinContent(iMaxBin);
+  // Only for debugging....
+  //h->Draw();
+  //std::cout << "maxValue = " << iMaxBin << "  " << maxValue << std::endl;
+  
+
+  for(int j=iMaxBin;j>=0;j--){
+    double v = h->GetBinContent(j);
+    double r = v / maxValue;
+    //std::cout << "r = " << r << std::endl;  // Only for debugging
+    if( r > thresh) {
+      lo = j ;
+      nfail = 0;
+    }else if( r <= thresh) {
+      nfail++;
+    }
+    if(nfail >= nSkipMax) break;
+  }
+
+  nfail = 0;
+  for(int j=iMaxBin;j<=h->GetNbinsX();j++){
+    double v = h->GetBinContent(j);
+    double r = v / maxValue;
+    //std::cout << "r = " << r << std::endl;  // Only for debugging
+    if( r > thresh) {
+      hi = j;
+      nfail = 0;
+    }else if( r <= thresh) {
+      nfail++;
+    }
+    if(nfail >= nSkipMax) break;
+  } 
+  lo = h->GetBinCenter(lo);
+  hi = h->GetBinCenter(hi);
+
+  //std::cout << "lo, hi = " << lo << " " << hi << std::endl; // only for debugging
+  
+
+  return;
+}
+
+
+void AnalysisBase::getTDCBins(TProfile* h, float& lo, float& hi){
+  getRange(h,lo,hi,0.97,1);
+  lo = lo - 1.0 + 0.5;
+  hi = hi + 0.5;
+  return;
+}
+
+
+
+void AnalysisBase::getBeamLocation(TH1F *h, float &lo, float& hi){
+  //double dif = 10;
+  for(int  j = 0; j<10; j++){
+    std::cout << "====> Finding Beam, iteration " << j+1 << std::endl;
+    getRange(h,lo,hi);
+    int dif = hi - lo + 1;
+    if(dif < 5){
+      int i1 = h->FindBin(lo);
+      int i2 = h->FindBin(hi);
+      for(int k=i1; k<=i2; k++){
+        h->SetBinContent(k,0);
+      }
+    }else{
+      break;
+    } 
+  }
+
+  //h->Draw();
+  return;
+}
+
+double AnalysisBase::getXOffset(TH1F *h1w){
+  float xlo = 0, xhi=0;
+  getRange(h1w,xlo,xhi,0.1,1);
+  
+  return (xlo+xhi)/2.0;
+
+}
+
+void AnalysisBase::getBeamLoc(){
+
+  TH1F* ha = new TH1F("ha","Strip # of cluster with track",512,0.0,512);
+  //TH1F* hb = new TH1F("hb","Strip # of cluster with track",512,0.0,512);
+  Long64_t nentries = fChain->GetEntriesFast();
+  cout << "nentries " << nentries << endl;
+  float lo = 0, hi = 0;
+
+  Long64_t nbytes = 0, nb = 0;
+  std::cout << "======================================= " << std::endl;
+  std::cout << "getBeamLoc(): Determining Beam Position " << nentries << std::endl;
+  std::cout << "======================================= " << std::endl;
+  for (Long64_t jentry=0; jentry<max(50000,(int)nentries);jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+    //cout << clusterNumberPerEvent << endl;
+    
+    for(int j=0; j<min((int)clusterNumberPerEvent,10); j++){
+      std::cout << clustersPosition[j] << std::endl;
+      cout << polarity << " " << polarity*clustersCharge[j] << endl;
+      if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+      int iChan = clustersSeedPosition[j];
+      //if(j<500) cout << "iChan = " << iChan << clustersCharge[j] << " " << 5*noise[iChan] << endl;
+      if(polarity*clustersCharge[j]<4*noise[iChan]) continue;
+      if(clustersPosition[j]>0.1&&clustersSize[j]==1) ha->Fill(clustersPosition[j]);
+      if(clustersPosition[j]>0.1&&clustersSize[j]==2) ha->Fill(clustersPosition[j]);
+    }
+  }
+     
+  int num = ha->GetEntries();
+  for(int i=0; i<1000; i++){
+    cout << "num is " << num << endl;
+    if(num < 1000) continue;
+    break;
+  }
+
+  if(num < 1000){
+    std::cout << "ERROR: Something wrong here, insufficient entries in GetBeamLoc(), nEntries =  " << num << std::endl;
+    //exit(1);
+  }
+   
+  //ha->Draw();
+  getBeamLocation(ha,lo,hi);
+  iLo = lo;
+  iHi = hi;
+  std::cout << "====> Beam is between strips " << iLo << " -- " << iHi << std::endl;
+
+  //delete ha;
+  return;
+
+}
+
+void AnalysisBase::getTDC(){
+  TProfile *hb = new TProfile("hb","Cluster Charge vs TDC time",12,0,12,100,1000);
+  Long64_t nentries = fChain->GetEntriesFast();
+  float lo = 0, hi = 0;
+
+  Long64_t nbytes = 0, nb = 0;
+  std::cout << "============================================" << std::endl;
+  std::cout << "getTDC(): Determining Optimal TDC time range" << std::endl;
+  std::cout << "============================================" << std::endl;   
+  for (Long64_t jentry=0; jentry<max(50000,(int)nentries);jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+
+    for(int j=0; j<min((int)clusterNumberPerEvent,10); j++){
+      //std::cout << "j: " << ", clustersTDC: " << clustersTDC << ", clustersCharge[j]: " << clustersCharge[j] << ", clustersPosition[j]: " << clustersPosition[j] << std::endl; 
+      if(clustersPosition[j] < 0.1) continue;
+      if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+      if(clustersPosition[j]>=iLo && clustersPosition[j]<=iHi && clustersTDC>1.0 && 
+         polarity*clustersCharge[j]>150 && polarity*clustersCharge[j]<500) hb->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+    }
+  }
+
+  getTDCBins(hb,lo,hi);
+  tdcLo = lo;
+  tdcHi = hi;
+  std::cout << "====> TDC Range determined to be from " << tdcLo << " -- " << tdcHi << std::endl;
+  hb->Draw();
+  //delete hb;
+  
+
+  return;
+}
+
+void AnalysisBase::findBeamRegionAndAlign(int iPass){
+
+  cout << "==================================================================" << endl;
+  cout << "findBeamRegionAndAlign(): Determining Fiducial Region, Pass = " << iPass << endl;
+  cout << "==================================================================" << endl;
+
+  double dxWindow = dxWin;
+  if(iPass == 1) dxWindow = 1000.0;
+  if(iPass == 2) dxWindow = 1.0;
+
+  TH1F* hthx = new TH1F("hthx","#theta_{X}",1000,-5.0,5.0);
+  TH1F* hthy = new TH1F("hthy","#theta_{Y}",1000,-5.0,5.0);
+  TH1F* hx = new TH1F("hx","Y position of matched cluster",800,-40.0,40.0);
+  TH1F* hxdut = new TH1F("hxdut","Y position of matched cluster",800,-40.0,40.0);
+  TH1F* hs = new TH1F("hs","Strip number of matched cluster",512,0,512.0);
+  TH1F* hy = new TH1F("hy","Y position of matched cluster",800,-10.0,10.0);
+  TH1F* hw = new TH1F("hw","#DeltaX",20000,-100.0,100.0);
+  TH1F* hn = new TH1F("hn","#DeltaX",4000,-2.0,2.0);
+  TH1F* hnn = new TH1F("hnn","#DeltaX",400,-0.2,0.2);
+  TH2F* hxy = new TH2F("hxy","Y_{trk} vs X_{trk}, with cluster",640,-8,8.0,640,-8,8);
+  TProfile *ht = new TProfile("ht","Cluster Charge vs TDC time",12,0,12,100,1000);
+  TProfile *hzrot = new TProfile("hzrot","#DeltaX vs Y_{trk} at DUT",1600,-8,8,-1.0,1.0);
+  TH2F* hca = new TH2F("hca","Y_{trk} vs X_{trk}, with found cluster",160,-8,8.0,320,-8,8);
+  TH2F* hcf = new TH2F("hcf","Y_{trk} vs X_{trk}, with found cluster",160,-8,8.0,320,-8,8);
+  
+  hca->Sumw2();
+  hcf->Sumw2();
+  
+
+  double nomStrip=0, detStrip = 0;
+  Long64_t nbytes = 0, nb = 0;
+  Int_t nentries = fChain->GetEntriesFast();
+  for (Long64_t jentry=0; jentry<max(nentries,200000);jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    //if(jentry%1000==0) cout << "At entry = " << jentry << endl;
+    
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+    if(n_tp3_tracks > 1) continue;      
+
+    for(int k=0; k<n_tp3_tracks; k++){
+      bool goodTime = (clustersTDC >= tdcLo && clustersTDC < tdcHi);
+      goodTime = clustersTDC>1.0;
+      if(!goodTime) continue;
+      double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+      double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+
+      transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip);
+
+      double tx = 1000*vec_trk_tx->at(k);
+      double ty = 1000*vec_trk_ty->at(k);
+
+      double x_trk0 = x_trk;
+
+      for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+        if(clustersPosition[j] < 0.1) continue;
+        if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+        bool goodHit = (clustersPosition[j]>iLo && clustersPosition[j]<iHi);
+        double x_dut = getDUTHitPosition(j);
+
+        x_trk = x_trk0;
+
+        double dx = x_dut - x_trk;
+        hn->Fill(dx);
+        hnn->Fill(dx);
+
+        hca->Fill(x_trk,y_trk);
+        if(fabs(dx)<dxWindow || iPass==1) {
+          if(goodHit) {
+            hx->Fill(x_trk);
+            hxdut->Fill(x_dut);
+            hs->Fill(clustersPosition[j]);
+            hy->Fill(y_trk);
+            hthx->Fill(tx);
+            hthy->Fill(ty);
+            hw->Fill(dx);     
+            hxy->Fill(x_trk,y_trk);
+            ht->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+            hzrot->Fill(y_trk,dx);
+            hcf->Fill(x_trk,y_trk);
+          } 
+        }
+      }
+    }
+  }
+
+  //hnn->Draw();
+
+  if(iPass==4) {
+    findCutoutRegion(hcf);
+  }else {  
+
+    float xmin=0,xmax=0,ymin=0,ymax=0,txmin=0,txmax=0,tymin=0,tymax=0;
+
+    getRange(hthx,txmin,txmax,0.05,2);
+    getRange(hthy,tymin,tymax,0.05,2);
+    getRange(hx,xmin,xmax,0.05,2);
+    getRange(hy,ymin,ymax,0.2,2);
+    
+    xMin = xmin;
+    xMax = xmax;
+    yMin = ymin;
+    yMax = ymax;
+    txMin = txmin;
+    txMax = txmax;
+    tyMin = tymin;
+    tyMax = tymax;
+    
+    float xlo = 0, xhi=0;
+    if(iPass==1) getRange(hw,xlo,xhi,0.1,1);
+    if(iPass==2) getRange(hn,xlo,xhi,0.1,1);
+    if(iPass==3) getRange(hnn,xlo,xhi,0.1,1);
+    double XOFF = (xhi + xlo)/2.0;
+    xOff = xOff - XOFF;
+    double x_ave = (xMax + xMin)/2.0;
+    double y_ave = (yMax + yMin)/2.0;
+    xGloOff = xGloOff - x_ave;
+    yGloOff = yGloOff - y_ave;
+    
+    // Check/correct for z rotation
+    if(iPass==3 && correctForZRotation){
+      cout << "Checking for z-rotation" << endl;
+      TF1* p1 = new TF1("p1","[0]+[1]*x",yMin,yMax);
+      p1->SetParameters(0.0,0.0001);
+      hzrot->Fit(p1,"0R");
+      double rz = p1->GetParameter(1);
+      cout << "=======================================================================" << endl;
+      cout << "==> Updating z rotation angle from " << Rz << " to " << Rz-rz << " mrad" << endl;    
+      Rz = Rz - rz;
+      delete p1;
+    }
+    
+    
+    float lo = 0, hi = 0;
+    getTDCBins(ht,lo,hi);
+    tdcLo = lo;
+    tdcHi = hi;
+    cout << "=================================================================" << endl;
+    cout << "====> TDC Range updated to be from " << tdcLo << " -- " << tdcHi << std::endl;
+    cout << "=================================================================" << endl;
+    cout << "====> Fiducial regions, xLo, xHi (Strip numbers) = " << iLo << " " << iHi << endl;
+    cout << "====> Fiducial regions, xLo, xHi (pos in mm) = " << xMin << " " << xMax << " mm " << endl;
+    cout << "====> Fiducial regions, yLo, yHi (pos in mm) = " << yMin << " " << yMax << " mm " << endl;
+    cout << "====> Fiducial regions, thxLo, thxHi (pos in mrad) = " << txMin << " " << txMax << " mrad" << endl;
+    cout << "====> Fiducial regions, thyLo, thxHi (pos in mrad) = " << tyMin << " " << tyMax << " mrad" << endl;
+    cout << "=================================================================" << endl;   
+    cout << "====> Shifting sensor by dX = " << XOFF << " mm " << ", new xOff = " << xOff << endl;
+    cout << "====> Global X, Y shifts: " << x_ave << " " << y_ave << endl;
+    cout << "====> New global x,y = " << xGloOff << " " << yGloOff << endl;
+    
+  }
+  
+  //if(iPass==1) hw->Draw();  // for debugging   
+  //if(iPass==2) hy->Draw();
+
+  //return;
+  
+
+  delete hxdut;
+  delete hthx;
+  delete hthy;
+  delete hx;
+  delete hy;
+  delete hxy;
+  delete hw;
+  delete hn;
+  delete hnn;
+  delete hs;
+  delete ht;
+  delete hzrot;
+  delete hcf;
+  delete hca;
+  
+   
+  return;
+  
+
+}
+
+
+Double_t AnalysisBase::getCorrChannel(double ch){
+  //if(ch>=128 && ch<=255) return (ch + stripGap[0]);
+  //if(ch>=256 && ch<=383) return (ch + stripGap[1]);
+  //if(ch>=384 && ch<=512) return (ch + stripGap[2]);
+
+  if(ch<=128) return (ch - stripGap[0]);
+  if(ch>=128 && ch<=255) return (ch - stripGap[1]);
+  if(ch>=256 && ch<=383) return (ch - stripGap[2]);
+  if(ch>=384 && ch<=512) return (ch - stripGap[3]);
+
+  return ch;  
+}
+
+void AnalysisBase::findChipBoundary(){
+  // Look for holes in hit profile, due to boundary between chips
+  std::cout << "=======================================================================================" << std::endl;
+  std::cout << "findChipBoundary(): Looking for gaps due to unconnected strips in between Beetle chips " << std::endl;
+  std::cout << "=======================================================================================" << std::endl;
+   
+  TH1F* hx2 = new TH1F("hx2","X position of cluster",200,-10.0,10.0);
+
+  Long64_t nbytes = 0, nb = 0;
+  Long64_t nentries = fChain->GetEntriesFast();
+  for (Long64_t jentry=0; jentry<max((int)nentries,20000);jentry++) {
+    Long64_t ientry = LoadTree(jentry);    
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+    for(int j=0; j<min((int)clusterNumberPerEvent,10); j++){
+      if(clustersPosition[j] < 0.1) continue;
+      if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+      bool goodHit = (clustersPosition[j]>iLo && clustersPosition[j]<iHi);
+      goodHit = goodHit &&  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+      double x_dut = getDUTHitPosition(j);
+         
+      hx2->Fill(x_dut);
+    }
+  }
+  
+  //hx2->Draw(); // for debugging only
+
+  int i1 = hx2->FindBin(xMin);
+  int i2 = hx2->FindBin(xMax);
+  double ave = 0.0;
+  int ixL=i1, ixH=i2;
+  for(int i=i1; i<i2; i++){
+    ave = ave +  hx2->GetBinContent(i);
+  }
+  ave = ave / (i2 - i1 + 1);
+  for(int i=i1; i<i2; i++){
+    double v  = hx2->GetBinContent(i);
+    double xx  = hx2->GetBinCenter(i);
+    double r = v/ave;
+    if(r < ratioForHole && xx < xLeftHole) {
+      xLeftHole = xx;
+      ixL = i;
+    }
+    if(r < ratioForHole && xx > xRightHole) {
+      xRightHole = xx;
+      ixH = i;
+    }
+  }
+  // Count the number of "dead" channels in this region
+  float ndead = 0;
+  for(int i=ixL; i<=ixH; i++){
+    double v  = hx2->GetBinContent(i);
+    double r = v/ave;
+    if(r < ratioForHole) ndead = ndead + 1;
+  }
+  double frdead = ndead / (ixH - ixL + 1);
+
+  if(frdead>0.8 && ndead>4){
+    xLeftHole = xLeftHole - 0.2;
+    xRightHole = xRightHole + 0.2;
+  }else{
+    xLeftHole = 999;
+    xRightHole = -999;
+  }
+  
+  hx2->Draw();
+  
+  
+  //std::cout << "Xmin, xMax = " << xMin << " " << xMax << std::endl;
+  //std::cout << "Bin Edges: " << i1 << "  " << i2 << std::endl;
+  //std::cout << "Hole position: " << xLeftHole << "  " << xRightHole << " , fraction dead = " << ndead << " " << frdead << std::endl;
+  
+  delete hx2;
+
+}
+
+void AnalysisBase::findDeadRegions(){
+
+  cout << "=================================================" << endl;
+  cout << "findDeadRegions(): Looking for dead strip regions " << endl;
+  cout << "=================================================" << endl;
+
+  TH1F* hf = new TH1F("hf","X position of matched cluster",200,-10.0,10.0);
+  TH1F* hnf = new TH1F("hnf","X position of matched cluster",200,-10.0,10.0);
+  
+  double nomStrip = 0, detStrip = 0;
+  Long64_t nbytes = 0, nb = 0;
+  Int_t nentries = fChain->GetEntriesFast();
+  for (Long64_t jentry=0; jentry<nentries;jentry++) {
+    Long64_t ientry = LoadTree(jentry);
+    if (ientry < 0) break;
+    nb = fChain->GetEntry(jentry);   nbytes += nb;
+      
+    if(n_tp3_tracks > 1) continue;
+
+    // Loop over TPIX tracks in event
+    for(int k=0; k<n_tp3_tracks; k++){
+      double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+      double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+
+      transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip );
+
+      bool goodTrack = false;
+      bool inFiducial = false;
+      if(x_trk>xMin && x_trk<xMax && y_trk>yMin && y_trk<yMax) inFiducial = true;          
+      inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+      double tx = 1000*vec_trk_tx->at(k);
+      double ty = 1000*vec_trk_ty->at(k);
+      if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+      bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+      bool foundHit = false;
+      // Loop over clusters
+      for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+        if(clustersPosition[j] < 0.1) continue;
+        if(polarity*clustersCharge[j] < kClusterChargeMin) continue;
+        //bool goodHit = (clustersPosition[j]>iLo || clustersPosition[j]<iHi);
+        double x_dut = getDUTHitPosition(j);
+
+        double dx = x_dut - x_trk;
+
+        if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin) {
+          foundHit = true;
+        }   
+      }
+      if(inFiducial && goodTrack && goodTime) {
+        hf->Fill(x_trk);    
+        if(!foundHit) hnf->Fill(x_trk);          
+      }
+        
+    }
+  }
+
+  TH1F *hineff = (TH1F*)hnf->Clone("hineff");
+  hineff->Divide(hf);
+
+  // Only for debugging
+  /*
+    TCanvas *cc = new TCanvas("cc","Hits",800,800);
+    cc->Divide(2,2);
+   
+    cc->cd(1);
+    hnf->Draw();
+    cc->cd(2);
+    hf->Draw();
+    cc->cd(3);
+    hineff->Draw();
+  */
+
+
+  for(int k = 0; k<hineff->GetNbinsX()-1; k++){
+    if(nDeadRegion > 20){
+      cout << "WARNING: Exceeded 20 dead regions, exiting from loop" << endl;       
+      break;
+    }     
+    double v1 = hineff->GetBinContent(k);
+    if(v1 > k_DeadStrip){
+      deadRegionLo[nDeadRegion] = hf->GetBinLowEdge(k);
+      for(int j = k; j<hineff->GetNbinsX(); j++){
+        double v2 = hineff->GetBinContent(j);
+        if(v2 < k_DeadStrip){
+          deadRegionHi[nDeadRegion] = hf->GetBinLowEdge(j);
+          cout << "====> Found inefficiency strip region from x :    " 
+               << deadRegionLo[nDeadRegion] << " <===> " << deadRegionHi[nDeadRegion] << " mm" << endl;
+          k = j + 1;
+          nDeadRegion++;
+          break;
+        }    
+      }
+    }
+  }
+   
+  delete hf;
+  delete hnf;
+  delete hineff;
+   
+  return;
+}
+
+void AnalysisBase::transformTrackToDUTFrame(int k, double& x_trk, double& y_trk, double& elecStrip, double& detStrip){
+  y_trk = y_trk + yGloOff;
+
+  double dzs = x_trk * sin(Ry);
+  x_trk = x_trk - Rz*y_trk;
+  y_trk = y_trk + Rz*x_trk;
+  x_trk = x_trk + vec_trk_tx->at(k)*dzs;
+  x_trk = x_trk/cos(Ry);
+  double rStrip = nChan - (x_trk-xOff)/stripPitch; 
+  double corStrip = getCorrChannel(rStrip);
+  //double dx = (corStrip - rStrip)*stripPitch;
+  //x_trk = x_trk + dx;
+  detStrip = rStrip; //nChan - (x_trk-xOff)/stripPitch; 
+  elecStrip = corStrip;
+  
+  x_trk = x_trk + xGloOff;
+
+  return;
+}
+
+void AnalysisBase::PrepareDUT(){
+
+   //----------------------------
+   // Get Beam Location (Strips)
+   //----------------------------
+   getBeamLoc();
+   //return;
+   
+   
+   // ==================================
+   // Determining Optimal TDC time range
+   // ==================================
+   getTDC();
+   
+   // --------------------------------------------------------------
+   // Find beam fiducial region (slopes & Y range) & align residuals
+   // ---------------------------------------------------------------
+   findBeamRegionAndAlign(1);
+   
+   
+   findBeamRegionAndAlign(2);   
+   yMid = yMin + (yMax-yMin)/2.0;
+   yHi2 = yMax - 2.0;
+
+   findBeamRegionAndAlign(3);   
+   yMid = yMin + (yMax-yMin)/2.0;
+   yHi2 = yMax - 2.0;
+
+   //return;
+   
+   if(yInt2[1] > yMax){
+     yInt1[0] = yMax-0.8; yInt1[1] = yMax-0.4;
+     yInt2[0] = yMax-0.4; yInt2[1] = yMax;
+     yInt3[0] = yMin; yInt3[1] = yMax-0.8;
+   }
+   cout << "Y Region Definitions:" << endl;
+   cout << " ===> Region 1: " << yInt1[0] << " -- " << yInt1[1] << " mm" << endl;
+   cout << " ===> Region 2: " << yInt2[0] << " -- " << yInt2[1] << " mm" << endl;
+   cout << " ===> Region 3: " << yInt3[0] << " -- " << yInt3[1] << " mm" << endl;
+   
+   //return;
+   // Correct for gaps between Beetle chips
+   correctForStripGaps();
+
+   //findBeamRegionAndAlign(4);   
+   if(holeSector) findBeamRegionAndAlign(4);
+
+   findChipBoundary();
+   cout << "====> Hole position: " << xLeftHole << "  " << xRightHole << endl;
+   //return;
+
+   if(vetoDeadStripRegions) findDeadRegions();
+   //return;
+
+   setCrossTalkCorr();
+
+}
+
+Double_t AnalysisBase::getDUTHitPosition(int j){
+  double pos = getCorrChannel(clustersPosition[j]);
+  //double pos = clustersPosition[j];
+  double x_dut = (nChan - pos)*stripPitch + xOff;
+  x_dut = x_dut + xGloOff;  
+  return x_dut;
+  
+}
+
+void AnalysisBase::setCrossTalkCorr(){
+  float biasVal = atof(m_bias);
+  chargeCorrSlopeOdd = 0.0;
+  chargeCorrSlopeEven = 0.0;
+  cout << "Bias Value = " << m_bias <<  " " << biasVal << endl;
+  
+  if(m_board.Contains("A2") && m_sector=="1" && biasVal < 260){
+    chargeCorrSlopeOdd = 0.435;
+    chargeCorrSlopeEven = 0.400;
+  }else if(m_board.Contains("A2") && m_sector=="1" && biasVal > 320){
+    chargeCorrSlopeOdd = 0.148;
+    chargeCorrSlopeEven = 0.094;
+  }else if(m_board.Contains("A2") && m_sector=="1" && biasVal == 300){
+    chargeCorrSlopeOdd = 0.130;
+    chargeCorrSlopeEven = 0.088;
+  }else if(m_board.Contains("A2") && m_sector=="2"){
+    chargeCorrSlopeOdd = 0.120;
+    chargeCorrSlopeEven = 0.085;
+  }
+  
+}
+
+
+void AnalysisBase::findCutoutRegion(TH2F* h){
+
+  cout << "===============================================================" << endl;
+  cout << "findCutoutRegion(): Looking for cutout region in D type sensor " << endl;
+  cout << "===============================================================" << endl;
+
+
+  int ilx = h->GetXaxis()->FindBin(xMin) + 1;
+  int ihx = h->GetXaxis()->FindBin(xMax) - 1;
+  int ily = 1;//h->GetYaxis()->GetBinFindBin(yMin) - 10;
+  int ihy = h->GetYaxis()->FindBin(yMax) + 10;
+  if(ily < 0) ily = 0;
+  if(ihy > h->GetYaxis()->GetNbins()) ihy = h->GetYaxis()->GetNbins();  
+  int nb = h->GetXaxis()->GetNbins(); 
+
+  double xlow = h->GetXaxis()->GetBinLowEdge(1);
+  double xhi = h->GetXaxis()->GetBinLowEdge(nb)+h->GetXaxis()->GetBinWidth(1);
+
+  TH1F *hpr = new TH1F("hpr","Y vs X, edge",nb,xlow,xhi);
+
+  TH1D *hpy;
+  int ipeak = 0;
+  for(int i=ilx; i<ihx-1; i++){
+    hpy = h->ProjectionY("hpy",i,i);
+    double maxcon  = 0.0;
+    double maxbin  = 0.0;
+    for(int j=ily;j<ihy;j++){
+      maxcon = maxcon + hpy->GetBinContent(j);
+      if(hpy->GetBinContent(j) > maxbin) {
+        maxbin = hpy->GetBinContent(j) ;
+        ipeak = j;
+      }
+    }
+    // Find the lower "edge"
+    for(int j=ipeak; j>=ily; j--){
+      double r0 = (hpy->GetBinContent(j-1)+hpy->GetBinContent(j-2))/2.0;
+      double r1 = hpy->GetBinContent(j);
+      double r2 = (hpy->GetBinContent(j+3)+hpy->GetBinContent(j+4))/2.0;
+      if(r1<=2 && r0<=1.5 && r2>5*r1 && r2>8){
+        hpr->SetBinContent(i,hpy->GetBinCenter(j)+2*hpy->GetBinWidth(j));
+        hpr->SetBinError(i,hpy->GetBinWidth(1)/2.0);
+        //cout << "found: " << i << " " << hpy->GetEntries() << " " << hpy->GetBinCenter(j) << " " 
+        //     << hpy->GetBinContent(j) << " " << r0 << " " << r1 << " " << r2 << " " << endl;
+        break;
+      }
+    }
+    
+  }
+
+  TF1* poly2 = new TF1("poly2","[0]+[1]*x+[2]*x*x",xMin,xMax);
+  poly2->SetParameters(-1.5,-0.17,-0.15);
+  hpr->Fit(poly2,"R0");
+  hpr->SetLineColor(kRed);
+
+  holeQuadPar[0] = poly2->GetParameter(0);
+  holeQuadPar[1] = poly2->GetParameter(1);
+  holeQuadPar[2] = poly2->GetParameter(2);
+
+  //return;
+  
+
+  delete poly2;
+  delete hpr;
+  delete hpy;
+  
+  return;
+}
+
+bool AnalysisBase::isInCutoutRegion(double xtrk, double ytrk){  
+  // Some protections here..
+  if(!removeTracksInHole) return false;
+  if(holeQuadPar[0]==0 || holeQuadPar[1]==0 || holeQuadPar[2]==0) return false;
+  // Ok, looks like we mean to really remove these tracks
+  double yhole = holeQuadPar[0]+holeQuadPar[1]*xtrk+holeQuadPar[2]*xtrk*xtrk;
+  if(ytrk < yhole + minDistFromHole) return true;
+  return false;
+}
+
+double AnalysisBase::DistToCutoutRegion(double xtrk, double ytrk){  
+  // Some protections here..
+  if(holeQuadPar[0]==0 || holeQuadPar[1]==0 || holeQuadPar[2]==0) return 999.0;
+  // Ok, looks like we mean to really remove these tracks
+  double yhole = holeQuadPar[0]+holeQuadPar[1]*xtrk+holeQuadPar[2]*xtrk*xtrk;
+  double a = 2.0*holeQuadPar[2]*xtrk+holeQuadPar[1];
+  double c = yhole - a*xtrk;
+  double b = -1.0;
+  
+  double dist = fabs(a*xtrk + b*ytrk + c) / sqrt(a*a+b*b);
+  if(ytrk < yhole) dist = -1.0*dist;
+  return dist;
+}
+
+void AnalysisBase::correctForStripGaps(){   
+  cout << "================================================================================" << endl;
+  cout << "correctForStripGaps(): Correcting x fiducial range for gaps between Beetle chips" << endl;
+  cout << "================================================================================" << endl;
+
+  double x1 = getCorrChannel(iLo);
+  double x2 = getCorrChannel(iHi);
+  xMax = (nChan - x1)*stripPitch + xOff + xGloOff;
+  xMin = (nChan - x2)*stripPitch + xOff + xGloOff;
+  double xave = (xMax + xMin)/2.;
+  xGloOff = xGloOff - xave;
+  xMin = xMin - xave;
+  xMax = xMax - xave;   
+  std::cout << "====> Updating Global Offset to use Strips, *** New xMin, xMax == " << xMin << " " << xMax << endl;
+  std::cout << "====> xMin, xMax = " << xMin << " " << xMax << endl;
+  std::cout << "====> xMin, xMax = " << yMin << " " << yMax << endl;
+  return;
+  
+}
+
+
diff --git a/TbUT/scripts/AnalysisBase.h b/TbUT/scripts/AnalysisBase.h
new file mode 100644
index 0000000..fc58d33
--- /dev/null
+++ b/TbUT/scripts/AnalysisBase.h
@@ -0,0 +1,163 @@
+//////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Oct  1 20:13:36 2015 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+// found on file: /data2/pmmannin/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_tracks.root
+//////////////////////////////////////////////////////////
+
+#ifndef AnalysisBase_h
+#define AnalysisBase_h
+
+#include <TROOT.h>
+#include <iostream>
+#include <TChain.h>
+#include <TTree.h>
+#include <TMath.h>
+#include <TFile.h>
+#include <TH2.h>
+#include <TF1.h>
+#include <TProfile.h>
+#include <TString.h>
+#include <TGraph.h>
+#include <TGraphErrors.h>
+//#include "myInputs.h"
+#include "AnalysisBase_Inputs.h"
+
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+
+
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class AnalysisBase {
+ public :
+  TTree          *fChain;   //!pointer to the analyzed TTree or TChain
+  Int_t           fCurrent; //!current Tree number in a TChain
+  
+  // Declaration of leaf types
+
+  Int_t           clusterNumberPerEvent;
+  UInt_t          clustersTDC;
+  ULong64_t       timestamps;
+  Double_t        clustersPosition[10];
+  Int_t           clustersSeedPosition[10];
+  Double_t        clustersCharge[10];
+  Int_t           clustersSize[10];
+  Double_t        clustersSeedCharge[10];
+  Double_t        clustersCharge2StripLeft[10];
+  Double_t        clustersCharge1StripLeft[10];
+  Double_t        clustersCharge1StripRight[10];
+  Double_t        clustersCharge2StripRight[10];
+  Double_t        dtime;
+   
+  Int_t           n_tp3_tracks;
+  vector<double>  *vec_trk_x;
+  vector<double>  *vec_trk_y;
+  vector<double>  *vec_trk_tx;
+  vector<double>  *vec_trk_ty;
+  vector<double>  *vec_trk_chi2ndf;
+
+  // List of branches
+  TBranch        *b_clusterNumberPerEvent;   //!
+  TBranch        *b_clustersTDC;   //!
+  TBranch        *b_timestamps;   //!
+  TBranch        *b_clustersPosition;   //!
+  TBranch        *b_clustersSeedPosition;   //!
+  TBranch        *b_clustersCharge;   //!
+  TBranch        *b_clustersSize;   //!
+  TBranch        *b_clustersSeedCharge;   //!
+  TBranch        *b_clustersCharge2StripLeft;   //!
+  TBranch        *b_clustersCharge1StripLeft;   //!
+  TBranch        *b_clustersCharge1StripRight;   //!
+  TBranch        *b_clustersCharge2StripRight;   //!
+  TBranch        *b_n_tp3_tracks;   //!
+  TBranch        *b_vec_trk_x;   //!
+  TBranch        *b_vec_trk_y;   //!
+  TBranch        *b_vec_trk_tx;   //!
+  TBranch        *b_vec_trk_ty;   //!
+  TBranch        *b_vec_trk_chi2ndf;   //!
+  TBranch        *b_dtime;   //!
+
+  double stripPitch;
+  double z_DUT;
+  double Rz;
+  double Ry;
+  double dxWin;
+  double xGloOff;
+  double yGloOff;
+  double xOff;
+  
+
+  float iLo, iHi;
+  float tdcLo, tdcHi;
+  float yMin,yMax;
+  float xMin,xMax;
+  float yMid, yHi2;
+  float tyMin,tyMax;
+  float txMin,txMax;
+  Int_t skipChannel[512];
+  double xLeftHole;
+  double xRightHole;
+  
+  Int_t lowEdge, hiEdge;
+  Double_t stripGap[4];
+  Double_t deadRegionLo[20];
+  Double_t deadRegionHi[20];
+  Int_t nDeadRegion;  
+
+  double yInt1[2];
+  double yInt2[2];
+  double yInt3[2];
+
+  float polarity;
+
+  TH1F *hMeanNoise; 
+  TH1F *hWidthNoise; 
+
+  double holeQuadPar[3];
+  bool removeTracksInHole;
+  double minDistFromHole;
+  bool holeSector;
+  bool correctForZRotation;
+
+  double chargeCorrSlopeOdd;
+  double chargeCorrSlopeEven;
+  
+  double noise[512];
+
+  double channelOffset;  
+
+  AnalysisBase(TTree *tree=0);
+  virtual ~AnalysisBase();
+  //virtual Int_t    Cut(Long64_t entry);
+  virtual Int_t    GetEntry(Long64_t entry);
+  virtual Long64_t LoadTree(Long64_t entry);
+  virtual void     Init(TTree *tree);
+  virtual void     Loop()  = 0; //make it pure virtual!
+  virtual Bool_t   Notify();
+  virtual void     Show(Long64_t entry = -1);
+  virtual void     getRange(TH1 *h, float &lo, float& hi, float thresh = 0.25, int nSkipMax=5);
+  virtual void getTDCBins(TProfile* h, float& lo, float& hi);
+  virtual void getBeamLocation(TH1F *h, float &lo, float& hi);
+  virtual double getXOffset(TH1F *h1w);
+  virtual void getBeamLoc();
+  virtual void getTDC();
+  virtual void findBeamRegionAndAlign(int iPass = 1);
+  virtual Double_t getCorrChannel(double ch);
+  virtual void findChipBoundary();
+  virtual void setCrossTalkCorr();
+  
+
+  virtual void findDeadRegions();
+  virtual void transformTrackToDUTFrame(int k, double& x_trk, double& y_trk, double& nomStrip, double& detStrip);
+  virtual void PrepareDUT();
+  virtual Double_t getDUTHitPosition(int j);
+  virtual void findCutoutRegion(TH2F* h);
+  virtual bool isInCutoutRegion(double xtrk, double ytrk);
+  virtual double DistToCutoutRegion(double xtrk, double ytrk);
+  virtual void correctForStripGaps();
+
+};
+
+#endif
diff --git a/TbUT/scripts/AnalysisBase_C.d b/TbUT/scripts/AnalysisBase_C.d
new file mode 100644
index 0000000..6b48a99
--- /dev/null
+++ b/TbUT/scripts/AnalysisBase_C.d
@@ -0,0 +1,75 @@
+
+# DO NOT DELETE
+
+./AnalysisBase_C.so: AnalysisBase.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TROOT.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectory.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TNamed.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObject.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypes.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RConfig.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/DllImport.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypeinfo.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/snprintf.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/strlcpy.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGenericClassInfo.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSchemaHelper.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStorage.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVersionCheck.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Riosfwd.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBuffer.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TString.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMathBase.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TList.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSeqCollection.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCollection.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TIterator.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDatime.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUUID.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TChain.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TTree.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBranch.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjArray.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttFill.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDataType.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDictionary.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Property.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttLine.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttMarker.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayD.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArray.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayI.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TClass.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjString.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualTreePlayer.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMath.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TError.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFile.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectoryFile.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMap.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/THashTable.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUrl.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH2.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH1.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAxis.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttAxis.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayC.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayS.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayF.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Foption.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorFfwd.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorDfwd.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFitResultPtr.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixFBasefwd.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixDBasefwd.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TF1.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFormula.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBits.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Math/ParamFunctor.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TProfile.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGraph.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGraphErrors.h
+./AnalysisBase_C.so: AnalysisBase_Inputs.h
+./AnalysisBase_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/cintdictversion.h /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+AnalysisBase_C__ROOTBUILDVERSION= 5.34/10
diff --git a/TbUT/scripts/AnalysisBase_C.so b/TbUT/scripts/AnalysisBase_C.so
new file mode 100755
index 0000000..e96fdb6
--- /dev/null
+++ b/TbUT/scripts/AnalysisBase_C.so
Binary files differ
diff --git a/TbUT/scripts/AnalysisBase_C_ACLiC_dict_rdict.pcm b/TbUT/scripts/AnalysisBase_C_ACLiC_dict_rdict.pcm
new file mode 100644
index 0000000..4547b86
--- /dev/null
+++ b/TbUT/scripts/AnalysisBase_C_ACLiC_dict_rdict.pcm
Binary files differ
diff --git a/TbUT/scripts/AnalysisBase_Inputs.h b/TbUT/scripts/AnalysisBase_Inputs.h
new file mode 100644
index 0000000..24603d5
--- /dev/null
+++ b/TbUT/scripts/AnalysisBase_Inputs.h
@@ -0,0 +1,74 @@
+//const TString m_fileIndir = "/data2/pmmannin/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/Nov2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/July2015/"; 
+//const TString m_fileIndir = "/data2/pmmannin/November2015/";
+//const TString m_board 	= "A1_Full"; 
+//const TString m_board 	= "D7_All"; 
+// Board, use: _board = "D5_All", A8_All" - October TB
+// const TString m_board 	= "D5_All"; 
+
+// =========================================================
+
+//<<<<<<< .mine
+/* /\* const TString m_fileIndir = "/data2/sblusk/TB/July2015/AnaFiles/";  *\/ */
+// const TString m_fileIndir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/";  
+/* //const TString m_fileOutdir = "~/lhcb/testbeam/";  */
+// const TString m_fileOutdir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/"; 
+/* const TString m_board 	= "B6";  */
+/* const TString m_bias  	= "50"; */
+/* const TString m_sector	= "3";  */
+//=======
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+
+//const TString m_board 	= "M1_test"; 
+
+
+#include <sstream>
+
+const TString iarotest = TString(getenv("KEPLERROOT"))+"  test";
+
+const TString m_fileIndir = TString(getenv("KEPLERROOT"))+"/../../output/";
+const TString m_board   = TString(getenv("BOARD"));
+
+const TString m_runNumb = "defRUN";
+//--------------------------------------------------------------------------------------
+const TString runplace = TString(getenv("RUNPLACE"));
+const TString consR = TString(getenv("RUNNUMBER"));
+//
+
+
+//-----------------------------------------------------------------------------------------
+TString m_bias  	= "300";
+const TString m_sector	= "PA"; 
+//const TString m_scanType = "Angle";
+const TString m_scanType = "Bias";
+const TString m_angle = "0";
+
+const TString m_fileOutdir = ""; 
+//>>>>>>> .r204986
+
+const TString plotdir 	= "Plots";
+
+
+
+
+//=======
+//>>>>>>> .r204986
+const double nChan 			= 512.0;
+const double stripPitch = 0.190;
+
+const bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+const double trackTriggerTimeDiffCut = 2.5;   // Default = 2.5
+
+const bool isPType = false;
+
+const int kClusterChargeMin = 150;
+const double ratioForHole 	= 0.05;
+const double ratioForDeadStrip 	= 0.6;
+const double ratioForNoisyStrip = 1.8;
+const bool vetoDeadStripRegions = false;
+const double k_DeadStrip 				= 0.12;
+
+const double m_minDistFromHole = 0.05;
+const bool removeTracksInHoleDef = false;
diff --git a/TbUT/scripts/CMS.C b/TbUT/scripts/CMS.C
new file mode 100755
index 0000000..5073b1e
--- /dev/null
+++ b/TbUT/scripts/CMS.C
@@ -0,0 +1,43 @@
+#define CMS_cxx
+#include "CMS.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+
+void CMS::Loop()
+{
+//   In a ROOT session, you can do:
+//      Root > .L CMS.C
+//      Root > CMS t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+
+   Long64_t nentries = fChain->GetEntriesFast();
+
+   Long64_t nbytes = 0, nb = 0;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      // if (Cut(ientry) < 0) continue;
+   }
+}
diff --git a/TbUT/scripts/CMS.h b/TbUT/scripts/CMS.h
new file mode 100755
index 0000000..290a51e
--- /dev/null
+++ b/TbUT/scripts/CMS.h
@@ -0,0 +1,130 @@
+//////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Fri Oct 16 18:02:17 2015 by ROOT version 5.34/32
+// from TTree CMS/TbUT nTuple
+// found on file: Run_Bias_Scan-B6-A-212-8358_Tuple.root
+//////////////////////////////////////////////////////////
+
+#ifndef CMS_h
+#define CMS_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+
+// Header file for the classes stored in the TTree if any.
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class CMS {
+public :
+   TTree          *fChain;   //!pointer to the analyzed TTree or TChain
+   Int_t           fCurrent; //!current Tree number in a TChain
+
+   // Declaration of leaf types
+   Double_t        cmsData[512];
+
+   // List of branches
+   TBranch        *b_cmsData;   //!
+
+   CMS(TTree *tree=0);
+   virtual ~CMS();
+   virtual Int_t    Cut(Long64_t entry);
+   virtual Int_t    GetEntry(Long64_t entry);
+   virtual Long64_t LoadTree(Long64_t entry);
+   virtual void     Init(TTree *tree);
+   virtual void     Loop();
+   virtual Bool_t   Notify();
+   virtual void     Show(Long64_t entry = -1);
+};
+
+#endif
+
+#ifdef CMS_cxx
+CMS::CMS(TTree *tree) : fChain(0) 
+{
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+   if (tree == 0) {
+      TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("Run_Bias_Scan-B6-A-212-8358_Tuple.root");
+      if (!f || !f->IsOpen()) {
+         f = new TFile("Run_Bias_Scan-B6-A-212-8358_Tuple.root");
+      }
+      TDirectory * dir = (TDirectory*)f->Get("Run_Bias_Scan-B6-A-212-8358_Tuple.root:/TbUT");
+      dir->GetObject("CMS",tree);
+
+   }
+   Init(tree);
+}
+
+CMS::~CMS()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+
+Int_t CMS::GetEntry(Long64_t entry)
+{
+// Read contents of entry.
+   if (!fChain) return 0;
+   return fChain->GetEntry(entry);
+}
+Long64_t CMS::LoadTree(Long64_t entry)
+{
+// Set the environment to read one entry
+   if (!fChain) return -5;
+   Long64_t centry = fChain->LoadTree(entry);
+   if (centry < 0) return centry;
+   if (fChain->GetTreeNumber() != fCurrent) {
+      fCurrent = fChain->GetTreeNumber();
+      Notify();
+   }
+   return centry;
+}
+
+void CMS::Init(TTree *tree)
+{
+   // The Init() function is called when the selector needs to initialize
+   // a new tree or chain. Typically here the branch addresses and branch
+   // pointers of the tree will be set.
+   // It is normally not necessary to make changes to the generated
+   // code, but the routine can be extended by the user if needed.
+   // Init() will be called many times when running on PROOF
+   // (once per file to be processed).
+
+   // Set branch addresses and branch pointers
+   if (!tree) return;
+   fChain = tree;
+   fCurrent = -1;
+   fChain->SetMakeClass(1);
+
+   fChain->SetBranchAddress("cmsData", cmsData, &b_cmsData);
+   Notify();
+}
+
+Bool_t CMS::Notify()
+{
+   // The Notify() function is called when a new file is opened. This
+   // can be either for a new TTree in a TChain or when when a new TTree
+   // is started when using PROOF. It is normally not necessary to make changes
+   // to the generated code, but the routine can be extended by the
+   // user if needed. The return value is currently not used.
+
+   return kTRUE;
+}
+
+void CMS::Show(Long64_t entry)
+{
+// Print contents of entry.
+// If entry is not specified, print current entry
+   if (!fChain) return;
+   fChain->Show(entry);
+}
+Int_t CMS::Cut(Long64_t entry)
+{
+// This function may be called from Loop.
+// returns  1 if entry is accepted.
+// returns -1 otherwise.
+   return 1;
+}
+#endif // #ifdef CMS_cxx
diff --git a/TbUT/scripts/CMS_C.d b/TbUT/scripts/CMS_C.d
new file mode 100644
index 0000000..131fa8a
--- /dev/null
+++ b/TbUT/scripts/CMS_C.d
@@ -0,0 +1,77 @@
+
+# DO NOT DELETE
+
+./CMS_C.so: CMS.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TROOT.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectory.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TNamed.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObject.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypes.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RConfig.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/DllImport.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypeinfo.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/snprintf.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/strlcpy.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGenericClassInfo.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSchemaHelper.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStorage.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVersionCheck.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Riosfwd.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBuffer.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TString.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMathBase.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TList.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSeqCollection.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCollection.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TIterator.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDatime.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUUID.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TChain.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TTree.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBranch.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjArray.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttFill.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDataType.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDictionary.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Property.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttLine.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttMarker.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayD.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArray.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayI.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TClass.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjString.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualTreePlayer.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFile.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectoryFile.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMap.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/THashTable.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUrl.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH2.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH1.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAxis.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttAxis.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayC.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayS.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayF.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Foption.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorFfwd.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorDfwd.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFitResultPtr.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixFBasefwd.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixDBasefwd.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStyle.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttText.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCanvas.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TPad.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualPad.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttPad.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualX.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/GuiTypes.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Buttons.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TQObject.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttCanvas.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCanvasImp.h
+./CMS_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/cintdictversion.h /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+CMS_C__ROOTBUILDVERSION= 5.34/10
diff --git a/TbUT/scripts/CMS_C.so b/TbUT/scripts/CMS_C.so
new file mode 100755
index 0000000..8e6d60c
--- /dev/null
+++ b/TbUT/scripts/CMS_C.so
Binary files differ
diff --git a/TbUT/scripts/CMS_C_ACLiC_dict_rdict.pcm b/TbUT/scripts/CMS_C_ACLiC_dict_rdict.pcm
new file mode 100644
index 0000000..9ea5e5b
--- /dev/null
+++ b/TbUT/scripts/CMS_C_ACLiC_dict_rdict.pcm
Binary files differ
diff --git a/TbUT/scripts/CalibAna/.svn/all-wcprops b/TbUT/scripts/CalibAna/.svn/all-wcprops
new file mode 100644
index 0000000..032deae
--- /dev/null
+++ b/TbUT/scripts/CalibAna/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/197530/Kepler/trunk/Tb/TbUT/scripts/CalibAna
+END
+analyzeCalib.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/197530/Kepler/trunk/Tb/TbUT/scripts/CalibAna/analyzeCalib.cpp
+END
+Makefile
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197530/Kepler/trunk/Tb/TbUT/scripts/CalibAna/Makefile
+END
+README
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197530/Kepler/trunk/Tb/TbUT/scripts/CalibAna/README
+END
diff --git a/TbUT/scripts/CalibAna/.svn/entries b/TbUT/scripts/CalibAna/.svn/entries
new file mode 100644
index 0000000..2d2291d
--- /dev/null
+++ b/TbUT/scripts/CalibAna/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/scripts/CalibAna
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-12T19:43:55.833845Z
+197530
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+analyzeCalib.cpp
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+048bae79a74a0e777df5a73df2ff6654
+2015-11-12T19:43:55.833845Z
+197530
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+9797
+
+Makefile
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+b704dd03e9a4e13a6bc686cb74329422
+2015-11-12T19:43:55.833845Z
+197530
+pmanning
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+184
+
+README
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+32d599f89beff256ffa289a19cc6fbd2
+2015-11-12T19:43:55.833845Z
+197530
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+869
+
diff --git a/TbUT/scripts/CalibAna/.svn/prop-base/Makefile.svn-base b/TbUT/scripts/CalibAna/.svn/prop-base/Makefile.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/scripts/CalibAna/.svn/prop-base/Makefile.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/scripts/CalibAna/.svn/text-base/Makefile.svn-base b/TbUT/scripts/CalibAna/.svn/text-base/Makefile.svn-base
new file mode 100644
index 0000000..81185f1
--- /dev/null
+++ b/TbUT/scripts/CalibAna/.svn/text-base/Makefile.svn-base
@@ -0,0 +1,11 @@
+ROOTC=$(shell root-config --cflags)
+ROOTL=$(shell root-config --glibs)
+
+all: analyzeCalib
+
+analyzeCalib: analyzeCalib.cpp
+	g++ $(ROOTC) -o $@ $^ $(ROOTL) 
+
+
+clean:
+	rm -f analyzeCalib
diff --git a/TbUT/scripts/CalibAna/.svn/text-base/README.svn-base b/TbUT/scripts/CalibAna/.svn/text-base/README.svn-base
new file mode 100644
index 0000000..ca67864
--- /dev/null
+++ b/TbUT/scripts/CalibAna/.svn/text-base/README.svn-base
@@ -0,0 +1,13 @@
+This is a quick program to run over a single calibration run. It produces an output ntuple with 4 plots as well as a PNG file with all 4 plots, being, the cluster charge distribution, the charge(channel-1), the charge(channel+1), and charge(channel+1)-charge(channel-1). If the detector is A-type, the program takes the channel number and adds 128, since only Beetle 2 and 4 are connected. For the D-type, the channel number is taken directly. 
+
+
+To compile, in the CalibAna directory: 
+
+> make
+
+To run: 
+
+> ./analyzeCalib -i calib_36.root -o outputfile_36.root -n 36 -t 0 -p -15
+
+Where calib_36.root is the Calibration*_Tuple.root that is produced after running the TbUT software, outputfile_36.root is the output file, 36 is the channel number of the calibration run, 0 is the detector type (0=A, 1=D, 2=Micron mini, 3=Ham mini), and -15 is the phase being tested. 
+
diff --git a/TbUT/scripts/CalibAna/.svn/text-base/analyzeCalib.cpp.svn-base b/TbUT/scripts/CalibAna/.svn/text-base/analyzeCalib.cpp.svn-base
new file mode 100644
index 0000000..98b87f1
--- /dev/null
+++ b/TbUT/scripts/CalibAna/.svn/text-base/analyzeCalib.cpp.svn-base
@@ -0,0 +1,270 @@
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+//
+// This code will append tracking information to a ROOT tree that contains cluster information from a UT DUT 
+//
+// To compile
+//   > SetupProject LHCb
+//   > make
+//
+// Example of how to run interactively:
+// 
+// ./combDUTwithTrack -i /data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root -t /data2/sblusk/TB/July2015/TelescopeData/BoardA4/Kepler-tuple.root -o /data2/sblusk/test2.root
+//
+//
+// The Telescope data is on eos at:~/eos/lhcb/testbeam/ut/TelescopeData/July2015/RootFiles/RunXXXX/Output/Kepler-tuple.root
+// where XXXX = run number from TPIX DAQ system (Kepler run #)
+//
+// The DUT data needs to be processed through TbUT and put on eos in a standard area.
+// 
+// The easiest, although ot safest way, to get the data directly accessible from eos is to use:
+// eosmount ~/eos
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+#include <iostream>
+#include <vector>
+#include <fstream>
+#include <math.h>
+#include <stdlib.h>
+#include "TFile.h"
+#include "TROOT.h"
+#include "TSystem.h"
+#include "TTree.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TF1.h"
+#include "TCanvas.h"
+
+#ifdef __MAKECINT__
+#pragma link C++ class vector<float>+;
+#endif
+
+using namespace std;
+
+
+
+int main(int __argc, char *__argv[]){
+
+  gROOT->ProcessLine("#include <vector>");
+  const char *calib_filename  = "calib.root";
+  const char *out_filename    = "outputfile.root";
+
+  int c;
+  extern char* optarg;
+  extern int optind;
+
+  int channel; 
+  int type; 
+  cout << endl;
+ 
+
+  cout << "number of arguments: " << __argc << endl;  
+  for(int i=0; i < __argc; i++) {
+
+    cout << __argv[i] << endl; 
+  }
+  /*____________________________Parse Command Line___________________________*/
+  while((c = getopt(__argc,__argv,"i:o:n:t:p")) != -1){
+    switch(c){
+      case 'h': // help option
+        cout << "Example: ./analyzeCalib -i calib.root -o outputfile.root -n channel -t type" << endl; 
+        return 0;
+        break;
+      case 'i':
+        calib_filename = optarg;
+        cout << "---> Calibration ROOT filename: " << calib_filename << endl;
+        break;
+      case 'o':
+        out_filename = optarg;
+        cout << "--->  Output filename: " << out_filename << endl;
+        break;
+      case 'n':
+        channel = atoi(optarg); 
+        cout << "Channel: " << channel << endl; 
+        break; 
+      case 't':
+        type = atoi(optarg); 
+        cout << "Type: " << type << endl; 
+        break; 
+      default: // unknown option flag
+        printf("Error!!!! Unknown option -%c\n",c);
+        cout << "Example: analyzeCalib -i calib.root -o outputfile.root -n channel -t type" << endl; 
+      return 0;
+    }
+  }
+
+  cout << endl;
+
+   Int_t           clusterNumberPerEvent;
+   UInt_t          clustersTDC;
+   ULong64_t       timestamps;
+   Double_t        clustersPosition[10];
+   Int_t           clustersSeedPosition[10];
+   Double_t        clustersCharge[10];
+   Int_t           clustersSize[10];
+   Double_t        clustersSeedCharge[10];
+   Double_t        clustersCharge2StripLeft[10];
+   Double_t        clustersCharge1StripLeft[10];
+   Double_t        clustersCharge1StripRight[10];
+   Double_t        clustersCharge2StripRight[10];
+
+   // List of branches
+   TBranch        *b_clusterNumberPerEvent;   //!
+   TBranch        *b_clustersTDC;   //!
+   TBranch        *b_timestamps;   //!
+   TBranch        *b_clustersPosition;   //!
+   TBranch        *b_clustersSeedPosition;   //!
+   TBranch        *b_clustersCharge;   //!
+   TBranch        *b_clustersSize;   //!
+   TBranch        *b_clustersSeedCharge;   //!
+   TBranch        *b_clustersCharge2StripLeft;   //!
+   TBranch        *b_clustersCharge1StripLeft;   //!
+   TBranch        *b_clustersCharge1StripRight;   //!
+   TBranch        *b_clustersCharge2StripRight;   //!
+
+ 
+  //dut_filename = "/data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root";
+  TFile *f_calib 		= new TFile(calib_filename,"READONLY");
+	TTree* t_dut 		= (TTree*)f_calib->Get("TbUT/Clusters");
+
+  t_dut->SetBranchAddress("clusterNumberPerEvent", &clusterNumberPerEvent, &b_clusterNumberPerEvent);
+  t_dut->SetBranchAddress("clustersTDC", &clustersTDC, &b_clustersTDC);
+  t_dut->SetBranchAddress("timestamps", &timestamps, &b_timestamps);
+  t_dut->SetBranchAddress("clustersPosition", clustersPosition, &b_clustersPosition);
+  t_dut->SetBranchAddress("clustersSeedPosition", clustersSeedPosition, &b_clustersSeedPosition);
+  t_dut->SetBranchAddress("clustersCharge", clustersCharge, &b_clustersCharge);
+  t_dut->SetBranchAddress("clustersSize", clustersSize, &b_clustersSize);
+  t_dut->SetBranchAddress("clustersSeedCharge", clustersSeedCharge, &b_clustersSeedCharge);
+  t_dut->SetBranchAddress("clustersCharge2StripLeft", clustersCharge2StripLeft, &b_clustersCharge2StripLeft);
+  t_dut->SetBranchAddress("clustersCharge1StripLeft", clustersCharge1StripLeft, &b_clustersCharge1StripLeft);
+  t_dut->SetBranchAddress("clustersCharge1StripRight", clustersCharge1StripRight, &b_clustersCharge1StripRight);
+  t_dut->SetBranchAddress("clustersCharge2StripRight", clustersCharge2StripRight, &b_clustersCharge2StripRight);
+
+  int numEvents = t_dut->GetEntriesFast();
+  cout << " ------------------------------------------------------" << endl;
+  cout << " | Number of events found = " << numEvents << endl;
+  cout << " ------------------------------------------------------" << endl;
+
+  vector<int> maxStrips;
+
+  int nfound=0;  
+  //out_filename = "/data2/sblusk/test.root";
+  TFile *f_out = new TFile(out_filename,"recreate");
+
+  //TFile *fileout = new TFile("temp.root","RECREATE");
+  TH1F *h_chg       = new TH1F("h_chg","Cluster Charge",200,-2000,2000);
+  TH1F *h_chgLeft   = new TH1F("h_chgLeft","Charge Charge (ch-1)",200,-2000,2000);
+  TH1F *h_chgLeft2   = new TH1F("h_chgLeft2","Charge Charge (ch-2)",200,-2000,2000);
+  TH1F *h_chgRight   = new TH1F("h_chgRight","Charge Charge (ch+1)",200,-2000,2000);
+  TH1F *h_chgRight2  = new TH1F("h_chgRight2","Charge Charge (ch+2)",200,-2000,2000);
+  TH1F *h_chgDiff   = new TH1F("h_chgDiff","Charge_{left}-Charge_{right}",200,-2000,2000);
+  TH1F *h_chgDiff2   = new TH1F("h_chgDiff2","Charge_{s-2}-Charge_{s+2}",200,-2000,2000);
+  TH1F *h_seed      = new TH1F("h_seed","Seed Strip",513,-0.5,512.5); 
+  TH1F *h_pos       = new TH1F("h_pos","Strip",513,-0.5,512.5);
+
+ int strip; 
+ int left; 
+ int right;  
+
+  for(int i=0;i < numEvents; i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;
+    for(int j=0; j < min(clusterNumberPerEvent,10);j++) {
+      h_pos->Fill(clustersPosition[j]); 
+    } 
+  }
+
+
+  /*
+  for(int i=1; i < 511; i++) {
+    if(h_pos->GetBinContent(i) > 2500) {
+      maxStrips.push_back((int)h_pos->GetBinCenter(i));
+      cout << (int)h_pos->GetBinCenter(i) << endl;
+    }
+  }
+
+  for(int i=0; i < maxStrips.size(); i++) {
+    cout << "Max Strip " << i << ": " << maxStrips.at(i) << endl;
+  }
+  */
+
+
+  if(type == 0) strip = channel+128;
+  else if(type == 1) strip = channel; 
+  else { cout << "Please enter a valid type: 0 for A, 1 for D, 2 for Micron Mini, 3 for Ham Mini" << endl; return 0; }
+
+  left  = strip-1; 
+  right = strip+1; 
+
+  for(int i=0;i < numEvents; i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;
+    double chgLeft  = 0.0; 
+    double chgRight = 0.0; 
+    for(int j=0; j < min(clusterNumberPerEvent,10);j++) {
+      if(fabs( clustersPosition[j]-strip) < 0.5 ) {
+        h_chg->Fill(clustersCharge[j]);
+        h_seed->Fill(clustersSeedPosition[j]); 
+        h_chgLeft->Fill(clustersCharge1StripLeft[j]);
+        h_chgRight->Fill(clustersCharge1StripRight[j]);
+        h_chgLeft2->Fill(clustersCharge2StripLeft[j]);
+        h_chgRight2->Fill(clustersCharge2StripRight[j]);
+        h_chgDiff->Fill(clustersCharge1StripLeft[j]-clustersCharge1StripRight[j]); 
+        h_chgDiff2->Fill(clustersCharge2StripLeft[j]-clustersCharge2StripRight[j]); 
+      }
+    }
+  }
+
+  TCanvas *c1 = new TCanvas("c","c",1200,800);
+
+  c1->Divide(3,3);
+  c1->cd(1)->SetLeftMargin(0.13);
+  h_chg->SetTitle(TString(Form("Seed Channel %d (strip %d)",channel,strip)));
+  h_chg->GetXaxis()->SetTitle("Cluster Charge");
+  h_chg->Draw();
+
+  c1->cd(2)->SetLeftMargin(0.13);
+  h_chgLeft->SetTitle(TString(Form("Left Channel: %d (strip %d)",channel-1,left)));
+  h_chgLeft->GetXaxis()->SetTitle("Cluster Charge, N-1");
+  h_chgLeft->Draw();
+  
+  c1->cd(3)->SetLeftMargin(0.13);
+  h_chgRight->SetTitle(TString(Form("Right Channel: %d (strip %d)",channel+1,right)));
+  h_chgRight->GetXaxis()->SetTitle("Cluster Charge, N+1");
+  h_chgRight->Draw();
+
+  c1->cd(4)->SetLeftMargin(0.13);
+  h_chgLeft2->SetTitle(TString(Form("2^{nd} Left Channel: %d (strip %d)",channel-2,left-1)));
+  h_chgLeft2->GetXaxis()->SetTitle("Cluster Charge, N-2");
+  h_chgLeft2->Draw();
+  
+  c1->cd(5)->SetLeftMargin(0.13);
+  h_chgRight2->SetTitle(TString(Form("2^{nd} Right Channel: %d (strip %d)",channel+2,right+1)));
+  h_chgRight2->GetXaxis()->SetTitle("Cluster Charge, N+2");
+  h_chgRight2->Draw();
+
+
+  c1->cd(6)->SetLeftMargin(0.13);
+  h_chgDiff->GetXaxis()->SetTitle("Cluster Charge Difference (s-1,s+1)");
+  h_chgDiff->Draw();
+  
+  c1->cd(7)->SetLeftMargin(0.13);
+  h_chgDiff2->GetXaxis()->SetTitle("Cluster Charge Difference (s-2,s+2)");
+  h_chgDiff2->Draw();
+  
+  c1->cd(8)->SetLeftMargin(0.13);
+  h_seed->GetXaxis()->SetTitle("Seed Cluster Position");
+  h_seed->GetXaxis()->SetRangeUser(h_seed->GetMaximumBin()-10,h_seed->GetMaximumBin()+10); 
+  h_seed->Draw();
+
+  
+
+
+  c1->SaveAs(TString(Form("Calibration_Type%d_Channel%d.png",type,channel)));
+
+  // Write and close ROOT file.
+  f_out->Write();
+  f_out->Close();
+
+  return 0;
+}
diff --git a/TbUT/scripts/CalibAna/Makefile b/TbUT/scripts/CalibAna/Makefile
new file mode 100755
index 0000000..81185f1
--- /dev/null
+++ b/TbUT/scripts/CalibAna/Makefile
@@ -0,0 +1,11 @@
+ROOTC=$(shell root-config --cflags)
+ROOTL=$(shell root-config --glibs)
+
+all: analyzeCalib
+
+analyzeCalib: analyzeCalib.cpp
+	g++ $(ROOTC) -o $@ $^ $(ROOTL) 
+
+
+clean:
+	rm -f analyzeCalib
diff --git a/TbUT/scripts/CalibAna/README b/TbUT/scripts/CalibAna/README
new file mode 100644
index 0000000..ca67864
--- /dev/null
+++ b/TbUT/scripts/CalibAna/README
@@ -0,0 +1,13 @@
+This is a quick program to run over a single calibration run. It produces an output ntuple with 4 plots as well as a PNG file with all 4 plots, being, the cluster charge distribution, the charge(channel-1), the charge(channel+1), and charge(channel+1)-charge(channel-1). If the detector is A-type, the program takes the channel number and adds 128, since only Beetle 2 and 4 are connected. For the D-type, the channel number is taken directly. 
+
+
+To compile, in the CalibAna directory: 
+
+> make
+
+To run: 
+
+> ./analyzeCalib -i calib_36.root -o outputfile_36.root -n 36 -t 0 -p -15
+
+Where calib_36.root is the Calibration*_Tuple.root that is produced after running the TbUT software, outputfile_36.root is the output file, 36 is the channel number of the calibration run, 0 is the detector type (0=A, 1=D, 2=Micron mini, 3=Ham mini), and -15 is the phase being tested. 
+
diff --git a/TbUT/scripts/CalibAna/analyzeCalib.cpp b/TbUT/scripts/CalibAna/analyzeCalib.cpp
new file mode 100644
index 0000000..98b87f1
--- /dev/null
+++ b/TbUT/scripts/CalibAna/analyzeCalib.cpp
@@ -0,0 +1,270 @@
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+//
+// This code will append tracking information to a ROOT tree that contains cluster information from a UT DUT 
+//
+// To compile
+//   > SetupProject LHCb
+//   > make
+//
+// Example of how to run interactively:
+// 
+// ./combDUTwithTrack -i /data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root -t /data2/sblusk/TB/July2015/TelescopeData/BoardA4/Kepler-tuple.root -o /data2/sblusk/test2.root
+//
+//
+// The Telescope data is on eos at:~/eos/lhcb/testbeam/ut/TelescopeData/July2015/RootFiles/RunXXXX/Output/Kepler-tuple.root
+// where XXXX = run number from TPIX DAQ system (Kepler run #)
+//
+// The DUT data needs to be processed through TbUT and put on eos in a standard area.
+// 
+// The easiest, although ot safest way, to get the data directly accessible from eos is to use:
+// eosmount ~/eos
+//--------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+#include <iostream>
+#include <vector>
+#include <fstream>
+#include <math.h>
+#include <stdlib.h>
+#include "TFile.h"
+#include "TROOT.h"
+#include "TSystem.h"
+#include "TTree.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TF1.h"
+#include "TCanvas.h"
+
+#ifdef __MAKECINT__
+#pragma link C++ class vector<float>+;
+#endif
+
+using namespace std;
+
+
+
+int main(int __argc, char *__argv[]){
+
+  gROOT->ProcessLine("#include <vector>");
+  const char *calib_filename  = "calib.root";
+  const char *out_filename    = "outputfile.root";
+
+  int c;
+  extern char* optarg;
+  extern int optind;
+
+  int channel; 
+  int type; 
+  cout << endl;
+ 
+
+  cout << "number of arguments: " << __argc << endl;  
+  for(int i=0; i < __argc; i++) {
+
+    cout << __argv[i] << endl; 
+  }
+  /*____________________________Parse Command Line___________________________*/
+  while((c = getopt(__argc,__argv,"i:o:n:t:p")) != -1){
+    switch(c){
+      case 'h': // help option
+        cout << "Example: ./analyzeCalib -i calib.root -o outputfile.root -n channel -t type" << endl; 
+        return 0;
+        break;
+      case 'i':
+        calib_filename = optarg;
+        cout << "---> Calibration ROOT filename: " << calib_filename << endl;
+        break;
+      case 'o':
+        out_filename = optarg;
+        cout << "--->  Output filename: " << out_filename << endl;
+        break;
+      case 'n':
+        channel = atoi(optarg); 
+        cout << "Channel: " << channel << endl; 
+        break; 
+      case 't':
+        type = atoi(optarg); 
+        cout << "Type: " << type << endl; 
+        break; 
+      default: // unknown option flag
+        printf("Error!!!! Unknown option -%c\n",c);
+        cout << "Example: analyzeCalib -i calib.root -o outputfile.root -n channel -t type" << endl; 
+      return 0;
+    }
+  }
+
+  cout << endl;
+
+   Int_t           clusterNumberPerEvent;
+   UInt_t          clustersTDC;
+   ULong64_t       timestamps;
+   Double_t        clustersPosition[10];
+   Int_t           clustersSeedPosition[10];
+   Double_t        clustersCharge[10];
+   Int_t           clustersSize[10];
+   Double_t        clustersSeedCharge[10];
+   Double_t        clustersCharge2StripLeft[10];
+   Double_t        clustersCharge1StripLeft[10];
+   Double_t        clustersCharge1StripRight[10];
+   Double_t        clustersCharge2StripRight[10];
+
+   // List of branches
+   TBranch        *b_clusterNumberPerEvent;   //!
+   TBranch        *b_clustersTDC;   //!
+   TBranch        *b_timestamps;   //!
+   TBranch        *b_clustersPosition;   //!
+   TBranch        *b_clustersSeedPosition;   //!
+   TBranch        *b_clustersCharge;   //!
+   TBranch        *b_clustersSize;   //!
+   TBranch        *b_clustersSeedCharge;   //!
+   TBranch        *b_clustersCharge2StripLeft;   //!
+   TBranch        *b_clustersCharge1StripLeft;   //!
+   TBranch        *b_clustersCharge1StripRight;   //!
+   TBranch        *b_clustersCharge2StripRight;   //!
+
+ 
+  //dut_filename = "/data2/pmmannin/BoardA4_redo_v2/Run_Bias_Scan-B1-A-227-8711_Tuple.root";
+  TFile *f_calib 		= new TFile(calib_filename,"READONLY");
+	TTree* t_dut 		= (TTree*)f_calib->Get("TbUT/Clusters");
+
+  t_dut->SetBranchAddress("clusterNumberPerEvent", &clusterNumberPerEvent, &b_clusterNumberPerEvent);
+  t_dut->SetBranchAddress("clustersTDC", &clustersTDC, &b_clustersTDC);
+  t_dut->SetBranchAddress("timestamps", &timestamps, &b_timestamps);
+  t_dut->SetBranchAddress("clustersPosition", clustersPosition, &b_clustersPosition);
+  t_dut->SetBranchAddress("clustersSeedPosition", clustersSeedPosition, &b_clustersSeedPosition);
+  t_dut->SetBranchAddress("clustersCharge", clustersCharge, &b_clustersCharge);
+  t_dut->SetBranchAddress("clustersSize", clustersSize, &b_clustersSize);
+  t_dut->SetBranchAddress("clustersSeedCharge", clustersSeedCharge, &b_clustersSeedCharge);
+  t_dut->SetBranchAddress("clustersCharge2StripLeft", clustersCharge2StripLeft, &b_clustersCharge2StripLeft);
+  t_dut->SetBranchAddress("clustersCharge1StripLeft", clustersCharge1StripLeft, &b_clustersCharge1StripLeft);
+  t_dut->SetBranchAddress("clustersCharge1StripRight", clustersCharge1StripRight, &b_clustersCharge1StripRight);
+  t_dut->SetBranchAddress("clustersCharge2StripRight", clustersCharge2StripRight, &b_clustersCharge2StripRight);
+
+  int numEvents = t_dut->GetEntriesFast();
+  cout << " ------------------------------------------------------" << endl;
+  cout << " | Number of events found = " << numEvents << endl;
+  cout << " ------------------------------------------------------" << endl;
+
+  vector<int> maxStrips;
+
+  int nfound=0;  
+  //out_filename = "/data2/sblusk/test.root";
+  TFile *f_out = new TFile(out_filename,"recreate");
+
+  //TFile *fileout = new TFile("temp.root","RECREATE");
+  TH1F *h_chg       = new TH1F("h_chg","Cluster Charge",200,-2000,2000);
+  TH1F *h_chgLeft   = new TH1F("h_chgLeft","Charge Charge (ch-1)",200,-2000,2000);
+  TH1F *h_chgLeft2   = new TH1F("h_chgLeft2","Charge Charge (ch-2)",200,-2000,2000);
+  TH1F *h_chgRight   = new TH1F("h_chgRight","Charge Charge (ch+1)",200,-2000,2000);
+  TH1F *h_chgRight2  = new TH1F("h_chgRight2","Charge Charge (ch+2)",200,-2000,2000);
+  TH1F *h_chgDiff   = new TH1F("h_chgDiff","Charge_{left}-Charge_{right}",200,-2000,2000);
+  TH1F *h_chgDiff2   = new TH1F("h_chgDiff2","Charge_{s-2}-Charge_{s+2}",200,-2000,2000);
+  TH1F *h_seed      = new TH1F("h_seed","Seed Strip",513,-0.5,512.5); 
+  TH1F *h_pos       = new TH1F("h_pos","Strip",513,-0.5,512.5);
+
+ int strip; 
+ int left; 
+ int right;  
+
+  for(int i=0;i < numEvents; i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;
+    for(int j=0; j < min(clusterNumberPerEvent,10);j++) {
+      h_pos->Fill(clustersPosition[j]); 
+    } 
+  }
+
+
+  /*
+  for(int i=1; i < 511; i++) {
+    if(h_pos->GetBinContent(i) > 2500) {
+      maxStrips.push_back((int)h_pos->GetBinCenter(i));
+      cout << (int)h_pos->GetBinCenter(i) << endl;
+    }
+  }
+
+  for(int i=0; i < maxStrips.size(); i++) {
+    cout << "Max Strip " << i << ": " << maxStrips.at(i) << endl;
+  }
+  */
+
+
+  if(type == 0) strip = channel+128;
+  else if(type == 1) strip = channel; 
+  else { cout << "Please enter a valid type: 0 for A, 1 for D, 2 for Micron Mini, 3 for Ham Mini" << endl; return 0; }
+
+  left  = strip-1; 
+  right = strip+1; 
+
+  for(int i=0;i < numEvents; i++){
+    int nb = t_dut->GetEntry(i);
+    if(nb <= 0) break;
+    double chgLeft  = 0.0; 
+    double chgRight = 0.0; 
+    for(int j=0; j < min(clusterNumberPerEvent,10);j++) {
+      if(fabs( clustersPosition[j]-strip) < 0.5 ) {
+        h_chg->Fill(clustersCharge[j]);
+        h_seed->Fill(clustersSeedPosition[j]); 
+        h_chgLeft->Fill(clustersCharge1StripLeft[j]);
+        h_chgRight->Fill(clustersCharge1StripRight[j]);
+        h_chgLeft2->Fill(clustersCharge2StripLeft[j]);
+        h_chgRight2->Fill(clustersCharge2StripRight[j]);
+        h_chgDiff->Fill(clustersCharge1StripLeft[j]-clustersCharge1StripRight[j]); 
+        h_chgDiff2->Fill(clustersCharge2StripLeft[j]-clustersCharge2StripRight[j]); 
+      }
+    }
+  }
+
+  TCanvas *c1 = new TCanvas("c","c",1200,800);
+
+  c1->Divide(3,3);
+  c1->cd(1)->SetLeftMargin(0.13);
+  h_chg->SetTitle(TString(Form("Seed Channel %d (strip %d)",channel,strip)));
+  h_chg->GetXaxis()->SetTitle("Cluster Charge");
+  h_chg->Draw();
+
+  c1->cd(2)->SetLeftMargin(0.13);
+  h_chgLeft->SetTitle(TString(Form("Left Channel: %d (strip %d)",channel-1,left)));
+  h_chgLeft->GetXaxis()->SetTitle("Cluster Charge, N-1");
+  h_chgLeft->Draw();
+  
+  c1->cd(3)->SetLeftMargin(0.13);
+  h_chgRight->SetTitle(TString(Form("Right Channel: %d (strip %d)",channel+1,right)));
+  h_chgRight->GetXaxis()->SetTitle("Cluster Charge, N+1");
+  h_chgRight->Draw();
+
+  c1->cd(4)->SetLeftMargin(0.13);
+  h_chgLeft2->SetTitle(TString(Form("2^{nd} Left Channel: %d (strip %d)",channel-2,left-1)));
+  h_chgLeft2->GetXaxis()->SetTitle("Cluster Charge, N-2");
+  h_chgLeft2->Draw();
+  
+  c1->cd(5)->SetLeftMargin(0.13);
+  h_chgRight2->SetTitle(TString(Form("2^{nd} Right Channel: %d (strip %d)",channel+2,right+1)));
+  h_chgRight2->GetXaxis()->SetTitle("Cluster Charge, N+2");
+  h_chgRight2->Draw();
+
+
+  c1->cd(6)->SetLeftMargin(0.13);
+  h_chgDiff->GetXaxis()->SetTitle("Cluster Charge Difference (s-1,s+1)");
+  h_chgDiff->Draw();
+  
+  c1->cd(7)->SetLeftMargin(0.13);
+  h_chgDiff2->GetXaxis()->SetTitle("Cluster Charge Difference (s-2,s+2)");
+  h_chgDiff2->Draw();
+  
+  c1->cd(8)->SetLeftMargin(0.13);
+  h_seed->GetXaxis()->SetTitle("Seed Cluster Position");
+  h_seed->GetXaxis()->SetRangeUser(h_seed->GetMaximumBin()-10,h_seed->GetMaximumBin()+10); 
+  h_seed->Draw();
+
+  
+
+
+  c1->SaveAs(TString(Form("Calibration_Type%d_Channel%d.png",type,channel)));
+
+  // Write and close ROOT file.
+  f_out->Write();
+  f_out->Close();
+
+  return 0;
+}
diff --git a/TbUT/scripts/ClusterAna.C b/TbUT/scripts/ClusterAna.C
new file mode 100644
index 0000000..e9f8303
--- /dev/null
+++ b/TbUT/scripts/ClusterAna.C
@@ -0,0 +1,157 @@
+#define ClusterAna_cxx
+#include "ClusterAna.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+#include <iostream>
+#include <fstream>
+
+void addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  h->SetMarkerSize(0.7);
+  h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  //float bw = h->GetBinWidth(1);
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  //h->SetMarkerSize(0.7);
+  //h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void ClusterAna::Loop()
+{
+//   In a ROOT session, you can do:
+//      Root > .L ClusterAna.C
+//      Root > ClusterAna t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+   
+   TString m_board2 = m_board;
+   m_board2 = m_board2.ReplaceAll("_All","");
+   m_board2 = m_board2.ReplaceAll("_Full","");
+   m_board2 = m_board2.ReplaceAll("_v7","");
+   Long64_t nentries = fChain->GetEntriesFast();
+   TString f_out			= m_fileOutdir + plotdir + "/AnalysisOutputCluOnly_" + m_board2 + "_" + m_bias + "_" + m_sector + ".root"; 
+
+   fout = new TFile(f_out,"RECREATE");
+   TH1F* h4 = new TH1F("h4","Strip # of cluster with track",512,0.0,512);
+   TProfile *hp = new TProfile("hp","Cluster Charge vs TDC time",12,0,12,100,1000);
+   TH1F* hcAll = new TH1F("hcAll","Cluster charge",100,0.0,1000.0);
+   TH1F *hnoiseChan = new TH1F("hnoiseChan","Noise in connected channels",200,0,200);
+   TH1F *hnoiseChan2 = new TH1F("hnoiseChan2","Noise in connected channels",200,-200,200);
+
+   PrepareDUT();
+   std::cout << iLo << " " << iHi << std::endl;
+   std::cout << tdcLo << " " << tdcHi << std::endl;
+   
+
+   //nentries = 20;
+   Long64_t nbytes = 0, nb = 0;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      
+      int nn = 0;
+      for(int j=0; j<std::min(clusterNumberPerEvent,10); j++){
+        if(clustersPosition[j]>=iLo && clustersPosition[j]<=iHi) nn++;
+      }
+      if(nn != 1) continue;
+      
+      
+      for(int j=0; j<std::min(clusterNumberPerEvent,10); j++){
+        h4->Fill(clustersPosition[j]);
+        if(clustersPosition[j] < 0.1) continue;
+        //std::cout << polarity*clustersCharge[j] << " " << clustersTDC << " " << kClusterChargeMin << endl;
+        if(clustersPosition[j]>=iLo && clustersPosition[j]<=iHi && clustersTDC>1.0 && polarity*clustersCharge[j]>kClusterChargeMin 
+           && polarity*clustersCharge[j]<800) hp->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+
+        bool beamRegion = clustersPosition[j]>=iLo && clustersPosition[j]<=iHi;
+        bool goodTDC = clustersTDC>=tdcLo && clustersTDC<=tdcHi;
+        double chr2 = clustersCharge2StripRight[j]*polarity;
+        double chl2 = clustersCharge2StripLeft[j]*polarity;                
+
+        if(beamRegion && goodTDC) {
+          hcAll->Fill(polarity*clustersCharge[j]);
+          hnoiseChan2->Fill(chl2-chr2);
+          int ichan = clustersSeedPosition[j];
+          hnoiseChan->Fill(noise[ichan]);
+        }
+        
+
+      }
+      // if (Cut(ientry) < 0) continue;
+   }
+   
+   TCanvas *c = new TCanvas("c","Mon Plots",800,600);
+   c->Divide(2,2);
+   c->cd(1);
+   h4->Draw();
+   c->cd(2);
+   hp->Draw();
+   c->cd(3);
+   hcAll->Draw();
+   c->cd(4);
+   hnoiseChan->Draw();
+   
+   fout->Write();
+   
+}
diff --git a/TbUT/scripts/ClusterAna.h b/TbUT/scripts/ClusterAna.h
new file mode 100644
index 0000000..13a917e
--- /dev/null
+++ b/TbUT/scripts/ClusterAna.h
@@ -0,0 +1,465 @@
+//////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Feb  4 16:48:43 2016 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+// found on file: /data2/pmmannin/FullProcessing/BoardA2/Run_Bias_Scan-B2-A-1071-14008_Tuple.root
+//////////////////////////////////////////////////////////
+
+#ifndef ClusterAna_h
+#define ClusterAna_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TProfile.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TLegend.h>
+#include <TBox.h>
+#include <TLine.h>
+
+#include "AnalysisBaseCluOnly.h"
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+#include <iostream>
+#include <algorithm>
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class ClusterAna : public AnalysisBaseCluOnly{
+public :
+  
+  ClusterAna(int biasVal);
+  virtual ~ClusterAna();
+  virtual void     Loop();
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+
+};
+
+#endif
+
+#ifdef ClusterAna_cxx
+ClusterAna::ClusterAna(int biasVal) {
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+  TString filename;
+  if(biasVal != 0) m_bias = Form("%d",biasVal);
+  TTree* tree = 0;
+  TFile *f;
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     TString scanType = "Run_Bias";
+     if(m_scanType.Contains("Angle")) scanType = "Run_Angle";
+     filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple.root"; 
+
+     f = new TFile(filename);
+     tree = (TTree*)f->Get("TbUT/Clusters");
+     std::cout << "===> Opening file: " << filename << std::endl;
+   }
+
+   
+   Init(tree);
+
+   TString filename2 = filename.ReplaceAll("_Tuple","");
+   TFile *f2 = new TFile(filename2);
+   f2->cd("TbUT");
+  TH2D *hNoise = (TH2D*)gDirectory->Get("CMSData_vs_channel");
+  TF1 *gau = new TF1("gau","gaus(0)",-120,120);
+  gau->SetParameters(10000,0.0,40.0);
+
+  TH1D *px;
+  for(int i=0;i<512;i++){
+    px = hNoise->ProjectionY(Form("px%d",i),i,i);
+    px->GetXaxis()->SetRangeUser(-200,200);
+    if(px->GetEntries() < 10){
+      noise[i] = 1000;
+      continue;
+    }
+    double p = px->GetMaximum();
+    double m = px->GetMean();
+    double e = px->GetRMS();
+    gau->SetParameters(p, m, e);
+    gau->SetRange(m-3*e,m+3*e);
+
+    px->Fit(gau,"RQ");
+    double mn = gau->GetParameter(1);
+    double wid = gau->GetParameter(2);
+    double emn = gau->GetParError(1);
+    double ewid = gau->GetParError(2);
+    noise[i] = wid;
+  }
+
+
+
+}
+
+ClusterAna::~ClusterAna()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+
+TString ClusterAna::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) {
+
+  TString tag = "";
+
+  if(board.Contains("A6")){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+      if ( bias == "250" ) tag = "B6-A-213-8359";
+      if ( bias == "200" ) tag = "B6-A-214-8361";
+      if ( bias == "150" ) tag = "B6-A-215-8362";
+      if ( bias == "100" ) tag = "B6-A-216-8363";
+      if ( bias == "75" )  tag = "B6-A-219-8365";
+      if ( bias == "50" )  tag = "B6-A-220-8366";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+      if ( bias == "250" ) tag = "B6-A-245-8392";
+      if ( bias == "200" ) tag = "B6-A-246-8393";
+      if ( bias == "150" ) tag = "B6-A-247-8394";
+      if ( bias == "100" ) tag = "B6-A-248-8395";
+      if ( bias == "75" )  tag = "B6-A-249-8396";
+      if ( bias == "50" )  tag = "B6-A-250-8397";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+      if ( bias == "250" ) tag = "B6-A-294-8426";
+      if ( bias == "200" ) tag = "B6-A-295-8427";
+      if ( bias == "150" ) tag = "B6-A-296-8428";
+      if ( bias == "100" ) tag = "B6-A-297-8429";
+      if ( bias == "75" )  tag = "B6-A-298-8430";
+      if ( bias == "50" )  tag = "B6-A-299-8431";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+      if ( bias == "250" ) tag = "B6-A-327-8453";
+      if ( bias == "200" ) tag = "B6-A-328-8454";
+      if ( bias == "150" ) tag = "B6-A-329-8455";
+      if ( bias == "100" ) tag = "B6-A-330-8456";
+      if ( bias == "75" )  tag = "B6-A-331-8457";
+      if ( bias == "50" )  tag = "B6-A-332-8458";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-378-8494";
+      if ( bias == "250" ) tag = "B6-A-381-8497";
+      if ( bias == "200" ) tag = "B6-A-382-8498";
+      if ( bias == "150" ) tag = "B6-A-383-8499";
+      if ( bias == "100" ) tag = "B6-A-384-8500";
+      if ( bias == "75" )  tag = "B6-A-385-8501";
+      if ( bias == "50" )  tag = "B6-A-386-8502";
+    } else if(sector == "6"){
+      if ( bias == "300" ) tag = "B6-A-408-8523";
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+      if ( bias == "200" ) tag = "B6-A-410-8525";
+      if ( bias == "150" ) tag = "B6-A-411-8526";
+      if ( bias == "100" ) tag = "B6-A-412-8527";
+      if ( bias == "75" )  tag = "B6-A-413-8528";
+      if ( bias == "50" )  tag = "B6-A-414-8529";
+    }
+  } else if (board.Contains("A4")) {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+      if(bias == "350" ) tag = "B4-A-211-8553";
+      if(bias == "300" ) tag = "B4-A-212-8554";
+      if(bias == "250" ) tag = "B4-A-213-8555";
+      if(bias == "200" ) tag = "B4-A-214-8556";
+      if(bias == "150" ) tag = "B4-A-215-8557";
+      if(bias == "100" ) tag = "B4-A-216-8558";
+      if(bias == "75" )  tag = "B4-A-217-8559";
+      if(bias == "50" )  tag = "B4-A-218-8560";
+    }else if(sector == "2") {
+      if(bias == "400" ) tag = "B4-A-242-8583";
+      if(bias == "350" ) tag = "B4-A-243-8584";
+      if(bias == "300" ) tag = "B4-A-246-8586";
+      if(bias == "250" ) tag = "B4-A-247-8587";
+      if(bias == "200" ) tag = "B4-A-248-8588";
+      if(bias == "150" ) tag = "B4-A-249-8589";
+      if(bias == "100" ) tag = "B4-A-250-8590";
+      if(bias == "75" )  tag = "B4-A-251-8591";
+      if(bias == "50" )  tag = "B4-A-252-8592";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+      if(bias == "350" ) tag = "B4-A-276-8616";
+      if(bias == "300" ) tag = "B4-A-277-8617";
+      if(bias == "250" ) tag = "B4-A-278-8618";
+      if(bias == "200" ) tag = "B4-A-279-8619";
+      if(bias == "150" ) tag = "B4-A-280-8620";
+      if(bias == "100" ) tag = "B4-A-281-8621";
+      if(bias == "75" )  tag = "B4-A-282-8622";
+      if(bias == "50" )  tag = "B4-A-283-8623";
+    } else if(sector == "4"){
+      if(bias == "400" ) tag = "B4-A-217-8651";
+      if(bias == "350" ) tag = "B4-A-218-8652";
+      if(bias == "300" ) tag = "B4-A-219-8653";
+      if(bias == "250" ) tag = "B4-A-220-8654";
+      if(bias == "200" ) tag = "B4-A-221-8655";
+      if(bias == "150" ) tag = "B4-A-222-8656";
+      if(bias == "100" ) tag = "B4-A-223-8657";
+      if(bias == "75" )  tag = "B4-A-224-8658";
+      if(bias == "50" )  tag = "B4-A-225-8659";
+    } else if(sector == "5"){
+      if(bias == "400" ) tag = "B4-A-246-8680";
+      if(bias == "350" ) tag = "B4-A-247-8681";
+      if(bias == "300" ) tag = "B4-A-248-8682";
+      if(bias == "250" ) tag = "B4-A-249-8683";
+      if(bias == "200" ) tag = "B4-A-250-8684";
+      if(bias == "150" ) tag = "B4-A-251-8685";
+      if(bias == "100" ) tag = "B4-A-252-8686";
+      if(bias == "75" )  tag = "B4-A-253-8687";
+      if(bias == "50" )  tag = "B4-A-254-8688";
+    } else if(sector == "6"){
+      if(bias == "400" ) tag = "B4-A-227-8711";
+      if(bias == "350" ) tag = "B4-A-228-8712";
+      if(bias == "300" ) tag = "B4-A-229-8713";
+      if(bias == "250" ) tag = "B4-A-230-8714";
+      if(bias == "200" ) tag = "B4-A-231-8715";
+      if(bias == "150" ) tag = "B4-A-232-8716";
+      if(bias == "100" ) tag = "B4-A-233-8717";
+      if(bias == "75" )  tag = "B4-A-234-8718";
+      if(bias == "50" )  tag = "B4-A-235-8719";
+      tag = tag.ReplaceAll("B4","B1");
+    }
+  } else if (board.Contains("A8")) {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+      if(bias == "400") tag = "B8-A-297-13333";
+      if(bias == "350") tag = "B8-A-298-13334";
+      if(bias == "300") tag = "B8-A-299-13335";
+      if(bias == "250") tag = "B8-A-300-13336";
+      if(bias == "200") tag = "B8-A-301-13337";
+      if(bias == "150") tag = "B8-A-302-13338";
+      if(bias == "100") tag = "B8-A-303-13339";
+      if(bias == "75")  tag = "B8-A-304-13340";
+      if(bias == "50")  tag = "B8-A-305-13341";
+      if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399";
+      if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400";
+    }else if (sector == "2"){
+      //if(bias == "500") tag = "B8-A-321-13354";
+      if(bias == "400") tag = "B8-A-324-13355";
+      if(bias == "350") tag = "B8-A-325-13356";
+      if(bias == "300") tag = "B8-A-327-13357";
+      if(bias == "250") tag = "B8-A-328-13358";
+      if(bias == "200") tag = "B8-A-329-13359";
+      if(bias == "150") tag = "B8-A-330-13360";
+      if(bias == "100") tag = "B8-A-331-13361";
+      if(bias == "75")  tag = "B8-A-332-13362";
+      if(bias == "50") tag = "B8-A-333-13363";
+    }else if (sector == "3"){
+      //if(bias == "500") tag = "B8-A-358-13385";
+      if(bias == "400") tag = "B8-A-359-13386";
+      if(bias == "350") tag = "B8-A-360-13387";
+      if(bias == "300") tag = "B8-A-361-13388";
+      if(bias == "250") tag = "B8-A-365-13389";
+      if(bias == "200") tag = "B8-A-366-13390";
+      if(bias == "150") tag = "B8-A-367-13391";
+      if(bias == "100") tag = "B8-A-368-13392";
+      if(bias == "75")  tag = "B8-A-369-13393";
+      if(bias == "50")  tag = "B8-A-370-13394";
+    }else if (sector == "4"){
+      //if(bias == "500") tag = "B8-A-309-13344";
+      if(bias == "400") tag = "B8-A-311-13345";
+      if(bias == "350") tag = "B8-A-312-13346";
+      if(bias == "300") tag = "B8-A-314-13347";
+      if(bias == "250") tag = "B8-A-315-13348";
+      if(bias == "200") tag = "B8-A-316-13349";
+      if(bias == "150") tag = "B8-A-317-13350";
+      if(bias == "100") tag = "B8-A-318-13351";
+      if(bias == "75")  tag = "B8-A-319-13352";
+      if(bias == "50")  tag = "B8-A-320-13353";
+    }else if (sector == "5"){
+      //if(bias == "500") tag = "B8-A-334-13364";
+      if(bias == "400") tag = "B8-A-337-13365";
+      if(bias == "350") tag = "B8-A-339-13367";
+      if(bias == "300") tag = "B8-A-340-13368";
+      if(bias == "250") tag = "B8-A-341-13369";
+      if(bias == "200") tag = "B8-A-342-13370";
+      if(bias == "150") tag = "B8-A-343-13371";
+      if(bias == "100") tag = "B8-A-344-13372";
+      if(bias == "75")  tag = "B8-A-345-13373";
+      if(bias == "50")  tag = "B8-A-346-13374";
+      if(bias != "400") tag = tag.ReplaceAll("B8","B1");
+    }else if (sector == "6"){
+      //if(bias == "500") tag = "B8-A-347-13375";
+      if(bias == "400") tag = "B8-A-348-13376";
+      if(bias == "350") tag = "B8-A-349-13377";
+      if(bias == "300") tag = "B8-A-350-13378";
+      if(bias == "250") tag = "B8-A-352-13379";
+      if(bias == "200") tag = "B8-A-353-13380";
+      if(bias == "150") tag = "B8-A-354-13381";
+      if(bias == "100") tag = "B8-A-355-13382";
+      if(bias == "75")  tag = "B8-A-356-13383";
+      if(bias == "50")  tag = "B8-A-357-13384";
+      tag = tag.ReplaceAll("B8","B1");
+    }
+  } else if (board.Contains("D5")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B5-D-14-13066";
+      if(bias == "75") tag = "B5-D-13-13065";
+      if(bias == "100") tag = "B5-D-12-13064";
+      if(bias == "150") tag = "B5-D-11-13063";
+      if(bias == "200") tag = "B5-D-10-13062";
+      if(bias == "250") tag = "B5-D-6-13058";
+      if(bias == "300") tag = "B5-D-19-13071";
+      if(bias == "350") tag = "B5-D-4-13056";
+      if(bias == "400") tag = "B5-D-3-13055";
+      if(bias == "500") tag = "B5-D-16-13068";
+    }else if(sector == "2"){
+      if(bias == "50")  tag = "B5-D-119-13165";
+      if(bias == "75")  tag = "B5-D-118-13164";
+      if(bias == "100") tag = "B5-D-117-13163";
+      if(bias == "150") tag = "B5-D-116-13162";
+      if(bias == "200") tag = "B5-D-115-13161";
+      if(bias == "250") tag = "B5-D-114-13160";
+      if(bias == "300") tag = "B5-D-113-13159";
+      if(bias == "350") tag = "B5-D-111-13157";
+      if(bias == "400") tag = "B5-D-110-13156";
+      if(bias == "500") tag = "B5-D-109-13155";
+    }else if(sector == "3"){
+      if(bias == "50")  tag = "B5-D-167-13209";
+      if(bias == "75")  tag = "B5-D-166-13208";
+      if(bias == "100") tag = "B5-D-165-13207";
+      if(bias == "150") tag = "B5-D-164-13206";
+      if(bias == "200") tag = "B5-D-163-13205";
+      if(bias == "250") tag = "B5-D-162-13204";
+      if(bias == "300") tag = "B5-D-159-13202";
+      if(bias == "350") tag = "B5-D-158-13201";
+      if(bias == "400") tag = "B5-D-157-13200";
+      if(bias == "500") tag = "B5-D-156-13199";
+    }else if(sector == "4"){
+      if(bias == "50")  tag = "B5-D-65-13114";
+      if(bias == "75")  tag = "B5-D-64-13113";
+      if(bias == "100") tag = "B5-D-63-13112";
+      if(bias == "150") tag = "B5-D-62-13111";
+      if(bias == "200") tag = "B5-D-61-13110";
+      if(bias == "250") tag = "B5-D-59-13108";
+      if(bias == "300") tag = "B5-D-58-13107";
+      if(bias == "350") tag = "B5-D-57-13106";
+      if(bias == "400") tag = "B5-D-56-13105";
+      if(bias == "500") tag = "B5-D-55-13104";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B5-D-218-13253";
+      if(bias == "75")  tag = "B5-D-217-13252";
+      if(bias == "100") tag = "B5-D-216-13251";
+      if(bias == "150") tag = "B5-D-215-13250";
+      if(bias == "200") tag = "B5-D-214-13249";
+      if(bias == "250") tag = "B5-D-213-13248";
+      if(bias == "300") tag = "B5-D-212-13247";
+      if(bias == "350") tag = "B5-D-211-13246";
+      if(bias == "400") tag = "B5-D-210-13245";
+      if(bias == "500") tag = "B5-D-209-13244";
+    }else if(sector == "6"){
+      if(bias == "50")  tag = "B5-D-260-13294";
+      if(bias == "75")  tag = "B5-D-259-13293";
+      if(bias == "100") tag = "B5-D-258-13292";
+      if(bias == "150") tag = "B5-D-257-13291";
+      if(bias == "200") tag = "B5-D-256-13290";
+      if(bias == "250") tag = "B5-D-255-13289";
+      if(bias == "300") tag = "B5-D-254-13288";
+      if(bias == "350") tag = "B5-D-253-13287";
+      if(bias == "400") tag = "B5-D-252-13286";
+      if(bias == "500") tag = "B5-D-251-13285";
+    }
+  } else if (board.Contains("D7")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B1-D-347-9360";
+      if(bias == "75") tag = "B1-D-346-9359";
+      if(bias == "100") tag = "B1-D-344-9356";
+      if(bias == "150") tag = "B1-D-345-9357";
+      if(bias == "200") tag = "B1-D-343-9355";
+      if(bias == "300") tag = "B1-D-343-9354";
+      if(bias == "400") tag = "B1-D-341-9353";
+      if(bias == "500") tag = "B1-D-340-9272";
+    }else if(sector == "2"){
+      if(bias == "50") tag = "B1-D-471-9659";
+      if(bias == "75") tag = "B1-D-470-9658";
+      if(bias == "100") tag = "B1-D-469-9657";
+      if(bias == "150") tag = "B1-D-468-9656";
+      if(bias == "200") tag = "B1-D-467-9655";
+      if(bias == "300") tag = "B1-D-466-9654";
+      if(bias == "400") tag = "B1-D-465-9653";
+      if(bias == "500") tag = "B1-D-464-9652";
+    }else if(sector == "3"){
+      if(bias == "50") tag = "B1-D-472-9660";
+      if(bias == "75") tag = "B1-D-473-9661";
+      if(bias == "100") tag = "B1-D-474-9662";
+      if(bias == "150") tag = "B1-D-475-9663";
+      if(bias == "200") tag = "B1-D-476-9664";
+      if(bias == "300") tag = "B1-D-477-9665";
+      if(bias == "400") tag = "B1-D-478-9666";
+      if(bias == "500") tag = "B1-D-479-9667";
+    }else if(sector == "4"){
+      if(bias == "50") tag =  "B1-D-379-9424";
+      if(bias == "75") tag =  "B1-D-378-9423";
+      if(bias == "100") tag = "B1-D-377-9422";
+      if(bias == "150") tag = "B1-D-376-9421";
+      if(bias == "200") tag = "B1-D-375-9419";
+      if(bias == "300") tag = "B1-D-374-9417";
+      if(bias == "400") tag = "B1-D-373-9415";
+      if(bias == "500") tag = "B1-D-372-9413";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B1-D-489-9763";
+      if(bias == "75")  tag = "B1-D-488-9762";
+      if(bias == "100") tag = "B1-D-487-9761";
+      if(bias == "150") tag = "B1-D-484-9674";
+      if(bias == "200") tag = "B1-D-483-9673";
+      if(bias == "300") tag = "B1-D-482-9672";
+      if(bias == "400") tag = "B1-D-481-9671";
+      if(bias == "500") tag = "B1-D-480-9670";
+    }else if(sector == "6"){
+      if(bias == "50") tag =  "B1-D-321-9252";
+      if(bias == "75") tag =  "B1-D-320-9251";
+      if(bias == "100") tag = "B1-D-319-9250";
+      if(bias == "150") tag = "B1-D-318-9249";
+      if(bias == "200") tag = "B1-D-317-9248";
+      if(bias == "300") tag = "B1-D-316-9247";
+      if(bias == "400") tag = "B1-D-315-9246";
+      if(bias == "500") tag = "B1-D-314-9245";
+    }
+  } else if (board.Contains("A1")) {
+    if(sector == "1"){    
+      if(bias == "350") tag = "B1-A-1022-13947";
+      if(bias == "300") tag = "B1-A-1021-13946";
+      if(bias == "250") tag = "B1-A-1053-13971";
+      if(bias == "200") tag = "B1-A-1052-13970";
+      if(bias == "150") tag = "B1-A-1015-13939";
+      if(bias == "100") tag = "B1-A-1014-13938";
+      if(bias == "75")  tag = "B1-A-1013-13937";
+      if(bias == "50")  tag = "B1-A-1012-13936";
+    }else if(sector == "2"){
+      if(bias == "350") tag = "B1-A-1062-13980";
+      if(bias == "300") tag = "B1-A-1061-13979";
+      if(bias == "250") tag = "B1-A-1060-13978";
+      if(bias == "200") tag = "B1-A-1059-13977";
+      if(bias == "150") tag = "B1-A-1058-13976";
+      if(bias == "100") tag = "B1-A-1057-13975";
+      if(bias == "75")  tag = "B1-A-1056-13974";
+      if(bias == "50")  tag = "B1-A-1055-13973";
+    }    
+  } else if (board.Contains("A2")) {
+    if(sector == "1"){    
+      if(bias == "340") tag = "B2-A-1095-14030";
+      if(bias == "325") tag = "B2-A-1094-14029";
+      if(bias == "300") tag = "B2-A-1084-14017";
+      if(bias == "250") tag = "B2-A-1083-14016";
+      if(bias == "200") tag = "B2-A-1082-14015";
+      if(bias == "150") tag = "B2-A-1081-14014";
+      if(bias == "100") tag = "B2-A-1078-14013";
+      if(bias == "75")  tag = "B2-A-1077-14012";
+      if(bias == "50")  tag = "B2-A-1076-14011";
+    }else if(sector == "2"){
+      if(bias == "340") tag = "B2-A-1099-14034";
+      if(bias == "325") tag = "B2-A-1098-14033";
+      if(bias == "300") tag = "B2-A-1097-14032";
+      if(bias == "250") tag = "B2-A-1100-14035";
+      if(bias == "200") tag = "B2-A-1101-14036";
+      if(bias == "150") tag = "B2-A-1102-14037";
+      if(bias == "100") tag = "B2-A-1103-14038";
+      if(bias == "75")  tag = "B2-A-1104-14039";
+      if(bias == "50")  tag = "B2-A-1105-14040";
+    }    
+  }
+
+  return tag;
+}
+
+#endif // #ifdef ClusterAna_cxx
diff --git a/TbUT/scripts/ClusterAna_C.d b/TbUT/scripts/ClusterAna_C.d
new file mode 100644
index 0000000..7951cd9
--- /dev/null
+++ b/TbUT/scripts/ClusterAna_C.d
@@ -0,0 +1,84 @@
+
+# DO NOT DELETE
+
+./ClusterAna_C.so: ClusterAna.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TROOT.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectory.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TNamed.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObject.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypes.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RConfig.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/DllImport.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypeinfo.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/snprintf.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/strlcpy.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGenericClassInfo.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSchemaHelper.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStorage.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVersionCheck.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Riosfwd.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBuffer.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TString.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMathBase.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TList.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSeqCollection.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCollection.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TIterator.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDatime.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUUID.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TChain.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TTree.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBranch.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjArray.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttFill.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDataType.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDictionary.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Property.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttLine.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttMarker.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayD.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArray.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayI.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TClass.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjString.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualTreePlayer.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFile.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectoryFile.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMap.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/THashTable.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUrl.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TProfile.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH1.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAxis.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttAxis.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayC.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayS.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayF.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Foption.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorFfwd.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorDfwd.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFitResultPtr.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH1F.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH2F.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH2.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixFBasefwd.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixDBasefwd.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TLegend.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TPave.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBox.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttText.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TLine.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStyle.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCanvas.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TPad.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualPad.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttPad.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualX.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/GuiTypes.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Buttons.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TQObject.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttCanvas.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCanvasImp.h
+./ClusterAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/cintdictversion.h /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+ClusterAna_C__ROOTBUILDVERSION= 5.34/10
diff --git a/TbUT/scripts/ClusterTrackAnalysis.C b/TbUT/scripts/ClusterTrackAnalysis.C
new file mode 100644
index 0000000..da83732
--- /dev/null
+++ b/TbUT/scripts/ClusterTrackAnalysis.C
@@ -0,0 +1,1585 @@
+#include "ClusterTrackAnalysis.h"
+
+ClusterTrackAnalysis::ClusterTrackAnalysis() :
+
+  test(0)
+
+{
+  cout << "starting ClusterTrackAnalysis" << endl;
+}
+
+ClusterTrackAnalysis::~ClusterTrackAnalysis() {
+  //  if (!fChain) return;
+  // delete fChain->GetCurrentFile();
+}
+
+ClusterTrackAnalysis::ClusterTrackAnalysis(int biasVal) {
+
+ TString filename;
+ //  if(biasVal != 0) m_bias = Form("%d",biasVal);
+  TTree* tree = 0;
+  
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     TString scanType = "Run_Bias";
+     filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root"; 
+     if(m_scanType.Contains("Angle")){
+       scanType = "Run_Angle";
+       filename = m_fileIndir+"Board"+m_board+"_Angle/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root"; 
+     }
+     
+     cout << "===> Opening file: " << filename << endl;
+     
+
+     // lxplus
+     //
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6
+     //
+
+     TFile *f = new TFile(filename);
+     tree = (TTree*)f->Get("Clusters");
+     TH1F *hn = (TH1F*)f->Get("hWidthNoise");
+     for(int i=0;i<nChan;i++){
+       noise[i] = hn->GetBinContent(i+1);
+     }
+
+     // Get mean noise and width
+     hMeanNoise 	= (TH1F*)f->Get("hMeanNoise"); 
+     hWidthNoise 	= (TH1F*)f->Get("hWidthNoise"); 
+     cout << "===> Opening file: " << filename << endl;
+
+     TString filename2 = filename.ReplaceAll("_Tracks","");
+     TFile * f2 = new TFile(filename2);
+     if(f2) {
+       TTree * tree2 = (TTree*) f2->Get("TbUT/CMS");
+       if(tree2) {
+         tree->AddFriend(tree2);
+         fCMS = new CMS(tree2);
+       }else{
+         fCMS=0;  
+       }
+     } else {
+       cout << "WARNING: Could not find CMS data file: " << filename2 << endl;
+       fCMS =0 ;
+     }
+   }
+   Init(tree);
+
+}
+
+void ClusterTrackAnalysis::Loop(){
+//   In a ROOT session, you can do:
+//      Root > .L ClusterWithTrackAna.C
+//      Root > ClusterWithTrackAna t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+
+   Int_t nentries = fChain->GetEntriesFast();
+
+   TString m_board2 = m_board;
+   m_board2 = m_board2.ReplaceAll("_All","");
+   m_board2 = m_board2.ReplaceAll("_Full","");
+   m_board2 = m_board2.ReplaceAll("_v7","");
+   TString f_out = m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + ".root";
+   if(m_angle != "0"){
+     f_out			= m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + "_" + m_angle + ".root";
+   }
+   cout << "Will write out file: " << f_out << endl;
+   
+
+
+   fout = new TFile(f_out,"RECREATE");
+
+   TH1F* h0 = new TH1F("h0","#DeltaX between strip hit and track projection (strips)",101,-50.5,50.5);
+   TH1F* h1 = new TH1F("h1","#DeltaX",800,-2.0,2.0);
+   TH2F* h1vsx = new TH2F("h1vsx","#DeltaX vs X",50,-5,5,100,-0.2,0.2);
+   TH1F* h1mpa = new TH1F("h1mpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1mbpa = new TH1F("h1mbpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fpa = new TH1F("h1fpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fbpa = new TH1F("h1fbpa","#DeltaX",400,-20.0,20.0);
+
+   TH1F* h1mpa1 = new TH1F("h1mpa1","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa2 = new TH1F("h1mpa2","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa3 = new TH1F("h1mpa3","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa4 = new TH1F("h1mpa4","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa5 = new TH1F("h1mpa5","#DeltaX",800,-20.0,20.0);
+
+   TH1F* h1mpaL = new TH1F("h1mpaL","Strip# of Missed Hit in Lower PA region",512,0,512);
+   TH1F* h1mpaU = new TH1F("h1mpaU","Strip# of Missed Hit in Upper PA region",512,0,512);
+
+
+   TH1F* h1s = new TH1F("h1s","Seed strip of cluster",512,0.0,512.0);
+   TH1F* h1a = new TH1F("h1a","#DeltaX, 1 strip",800,-2.0,2.0);
+   TH1F* h1b = new TH1F("h1b","#DeltaX, 2 strip",800,-2.0,2.0);
+   TH1F* h1z = new TH1F("h1z","#DeltaX, low Charge",800,-2.0,2.0);
+   TH1F* h1w = new TH1F("h1w","#DeltaX",20000,-100.0,100.0);
+   TH1F* h1wY = new TH1F("h1wY","#DeltaX",20000,-100.0,100.0);
+   TH2F* h2 = new TH2F("h2","X_{DUT} vs X_{trk}",100,-8.0,8.0,100,-8,8);
+   TH2F* h3 = new TH2F("h3","Y_{trk} vs X_{trk}, with cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3a = new TH2F("h3a","Y_{trk} vs X_{trk} in fiducial",640,-8,8.0,640,-8,8);
+   TH2F* h3b = new TH2F("h3b","Y_{trk} vs X_{trk}, with missed cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3c = new TH2F("h3c","Y_{trk} vs X_{trk}, with found cluster",640,-8,8.0,640,-8,8);
+   TH1F* h4 = new TH1F("h4","Detector strip # of cluster with track",512,0.0,512);
+   TH1F* h4a = new TH1F("h4a","Electonic Strip # of cluster with track",512,0.0,512);
+   TH1F* h4b = new TH1F("h4b","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h4c = new TH1F("h4c","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h5 = new TH1F("h5","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6 = new TH1F("h6","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5c = new TH1F("h5c","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6c = new TH1F("h6c","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5a = new TH1F("h5a","X position of track",400,-10.0,10.0);
+   TH1F* h6a = new TH1F("h6a","Y position of track",400,-10.0,10.0);
+   TH1F* h5b = new TH1F("h5b","X position of matched cluster",400,-10.0,10.0);
+   TH1F* h6b = new TH1F("h6b","Y position of matched cluster",400,-10.0,10.0);
+
+   TProfile *h8 = new TProfile("h8","#DeltaX vs #theta_{trk}",100,-5,5,-1.0,1.0);
+   TProfile *h9 = new TProfile("h9","#DeltaX vs Y_{trk} at DUT",1600,-8,8,-1.0,1.0);
+   TProfile *h9a = new TProfile("h9a","#DeltaX vs X_{trk} at DUT",20,-5,5,-1.0,1.0);
+
+   TProfile *h10a = new TProfile("h10a","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10b = new TProfile("h10b","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10c = new TProfile("h10c","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10d = new TProfile("h10d","<ADC> vs Y_{trk}",100,-8,8,0.0,1000.0);
+   TProfile *h10e = new TProfile("h10e","<ADC> vs X_{trk}",100,-8,8,0.0,1000.0);
+   TH1F* h11n = new TH1F("h11n","Strip # of matched cluster",512,0.0,512);
+   TH1F* h11d = new TH1F("h11d","Strip # of track",512,0.0,512);
+   h11n->Sumw2();
+   h11d->Sumw2();
+   
+   TH1F* h12 = new TH1F("h12","Y position of matched cluster",400,-10.0,10.0); h12->Sumw2();
+   TH1F* h12c = new TH1F("h12c","X position of matched cluster",400,-10.0,10.0);h12c->Sumw2();
+   TH1F* h12a = new TH1F("h12a","Y position of track",1600,-10.0,10.0); h12a->Sumw2();
+   TH1F* h12b = new TH1F("h12b","Y position of track",1600,-10.0,10.0); h12b->Sumw2();
+
+   TH1F* h12dn = new TH1F("h12dn","X position of track",200,-10.0,10.0); h12dn->Sumw2();
+   TH1F* h12en = new TH1F("h12en","X position of track",200,-10.0,10.0);h12en->Sumw2();
+   TH1F* h12fn = new TH1F("h12fn","X position of track",200,-10.0,10.0);h12fn->Sumw2();
+   TH1F* h12gn = new TH1F("h12gn","X position of track",200,-10.0,10.0);h12gn->Sumw2();
+   TH1F* h12dd = new TH1F("h12dd","X position of track",200,-10.0,10.0);h12dd->Sumw2();
+   TH1F* h12ed = new TH1F("h12ed","X position of track",200,-10.0,10.0);h12ed->Sumw2();
+   TH1F* h12fd = new TH1F("h12fd","X position of track",200,-10.0,10.0);h12fd->Sumw2();
+   TH1F* h12gd = new TH1F("h12gd","X position of track",200,-10.0,10.0);h12gd->Sumw2();
+
+   TH1F* h12hn = new TH1F("h12hn","X position of track",50,-0.5,0.5);h12hn->Sumw2();
+   TH1F* h12in = new TH1F("h12in","X position of track",50,-0.5,0.5);h12in->Sumw2();
+   TH1F* h12jn = new TH1F("h12jn","X position of track",50,-0.5,0.5);h12jn->Sumw2();
+   TH1F* h12kn = new TH1F("h12kn","X position of track",50,-0.5,0.5);h12kn->Sumw2();
+   TH1F* h12hd = new TH1F("h12hd","X position of track",50,-0.5,0.5);h12hd->Sumw2();
+   TH1F* h12id = new TH1F("h12id","X position of track",50,-0.5,0.5);h12id->Sumw2();
+   TH1F* h12jd = new TH1F("h12jd","X position of track",50,-0.5,0.5);h12jd->Sumw2();
+   TH1F* h12kd = new TH1F("h12kd","X position of track",50,-0.5,0.5);h12kd->Sumw2();
+
+   TProfile *h12m = new TProfile("h12m","<ADC> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+   TProfile *h12n = new TProfile("h12n","<ClusterSize> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+
+   TH1F* h12on = new TH1F("h12on","dist of track to cutout",700,-2.0,5.0);h12on->Sumw2();
+   TH1F* h12od = new TH1F("h12od","dist of track to cutout",700,-2.0,5.0);h12od->Sumw2();
+
+   TH1F *h13mpa = new TH1F("h13mpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13mbpa = new TH1F("h13mbpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fpa = new TH1F("h13fpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fbpa = new TH1F("h13fbpa","#Clusters/Ev",10,-0.5,9.5);   
+
+   TH1F* h14a = new TH1F("h14a","Nom Strip, no matched cluster",512,0.0,512);
+   TH1F* h14b = new TH1F("h14b","Nom Strip, matched cluster",512,0.0,512);
+
+   TH1F *h15a = new TH1F("h15a","Chisq of tracks with matched DUT hit",200,0.0,200.0);
+   TH1F *h15b = new TH1F("h15b","TDC time with matched DUT hit",12,0.0,12.0);
+   TH1F *h15c = new TH1F("h15c","Time Between Trigger and Track",5,0.0,5.0);
+   TH1F *h15d = new TH1F("h15d","TDC time of all clusters",12,0.0,12.0);
+   TH1F *h15e = new TH1F("h15e","TDC time of good clusters",12,0.0,12.0);
+
+   TH1F *h16a = new TH1F("h16a","Chisq of tracks without matched DUT hit",200,0.0,200.0);
+   TH1F *h16b = new TH1F("h16b","TDC time without matched DUT hit",12,0.0,12.0);
+   TH1F *h16c = new TH1F("h16c","Time Between Trigger and Track",5,0.0,5.0);
+   h15c->Sumw2();
+   h16c->Sumw2();
+   
+   TH1F* h17 = new TH1F("h17","Q_{L} / (Q_{L}+Q_{R})",50,0.0,1.0);
+   TH2F* h17a = new TH2F("h17a","Q_{L} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,120,-0.1,1.1);
+   TProfile* h17b = new TProfile("h17b","Q_{R} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,-0.1,1.1);
+
+   TH1F* hcmpa = new TH1F("hcmpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcmbpa = new TH1F("hcmbpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfpa = new TH1F("hcfpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfbpa = new TH1F("hcfbpa","Cluster charge",100,0.0,1000.0);
+
+   TH1F* h18a = new TH1F("h18a","Seed/Total charge",100,0.0,2.0);
+
+   TH2F* h18b = new TH2F("h18b","#DeltaX vs Interstrip Pos (1 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18c = new TH2F("h18c","#DeltaX vs Interstrip Pos (2 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18d = new TH2F("h18d","Seed/Total charge vs Interstrip Pos",100,-0.5,0.5,100,0.0,1.1);
+
+   TH1F* hcTrkXY[16];
+   for(int i=0; i<4; i++){
+     for(int j=0; j<4; j++){
+       int iblock = 4*i+j; 
+       TString hname = Form("hcTrkXY_%d",iblock+1);     
+       TString htitle = Form("Cluster charge, block %d",iblock+1);     
+       hcTrkXY[iblock]= new TH1F(hname,htitle,100,0.0,1000.0);
+     }
+   }
+   
+   TH1F *hlandau[512];
+   for(int i=0; i<nChan; i++){
+     hlandau[i] = new TH1F(Form("hlandau_%d",i),"Cluster charge",100,0.0,1000.0);
+   }
+   
+
+
+   TH1F* hcAll = new TH1F("hcAll","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrk = new TH1F("hcTrk","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkCorr = new TH1F("hcTrkCorr","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed = new TH1F("hcTrkSeed","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed1 = new TH1F("hcTrkSeed1","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed2 = new TH1F("hcTrkSeed2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY1 = new TH1F("hcTrkY1","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY2 = new TH1F("hcTrkY2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY3 = new TH1F("hcTrkY3","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY4 = new TH1F("hcTrkY4","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkNoTop = new TH1F("hcTrkNoTop","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkLowX = new TH1F("hcTrkLowX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkHighX = new TH1F("hcTrkHighX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrka = new TH1F("hcTrka","Cluster charge, limited region",100,0.0,1000.0);
+   TH1F* hcTrk1 = new TH1F("hcTrk1","Cluster charge, Size = 1",100,0.0,1000.0);
+   TH1F* hcTrk2 = new TH1F("hcTrk2","Cluster charge, Size = 2",100,0.0,1000.0);
+   TProfile *h2p = new TProfile("h2p","Cluster Charge vs TDC time",12,0,12,100,1000);
+
+
+   TH2F* h31a = new TH2F("h31a","Y_{trk} vs X_{trk}, with cluster",64,-8,8.0,64,-8,8);
+   TH2F* h31b = new TH2F("h31b","Y_{trk} vs X_{trk}, with cluster, low ADC",64,-8,8.0,64,-8,8);
+   TH1F* h32a = new TH1F("h32a","Strip # of cluster with track",512,0.0,512);
+   TH1F* h32b = new TH1F("h32b","Strip # of cluster with track & low ADC",512,0.0,512);
+   TH1F* h33a = new TH1F("h33a","Y position of matched cluster",200,-10.0,10.0);
+   TH1F* h33b = new TH1F("h33b","X position of matched cluster",200,-10.0,10.0);
+   TH1F* h34 = new TH1F("h34","Y position of matched cluster & low ADC",200,-10.0,10.0);
+
+   TH1F *hnoise = new TH1F("hnoise","Noise in connected channels",100,-200,200);
+   TH1F *hnoiseChan = new TH1F("hnoiseChan","Noise in connected channels",200,0,200);
+   TH1F *hnoisePerChannel = new TH1F("hnoisePerChannel","Noise",512,0,512);
+
+   TH1F* h35 = new TH1F("h35","No. clusters / event",50,0.0,50.0);
+   
+   TH1F *h41[10];
+   TH1F *h42[10];
+   TH1F *h43[10];
+   TH1F *h44[10];
+   for(int i=0; i<10; i++){
+     h41[i] = new TH1F(Form("h41_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h42[i] = new TH1F(Form("h42_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h43[i] = new TH1F(Form("h43_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+     h44[i] = new TH1F(Form("h44_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+   }
+
+   for(int i=0; i<nChan; i++){
+     hnoisePerChannel->Fill(i+0.5,noise[i]);
+   }
+   
+
+
+   //------------------------------------------------------------------------------------------------------
+   
+   //-----------------------------
+   // Prepare DUT (Alignment, etc)
+   //-----------------------------
+
+   PrepareDUT();
+   //return;
+   float biasVal = atof(m_bias);
+   cout << "chargeCorrSlopeOdd, chargeCorrSlopeEven = " << chargeCorrSlopeOdd << " " << chargeCorrSlopeEven << " " 
+        << m_bias << " " << biasVal << endl;
+   
+
+   std::ofstream myfile;
+   if(writeEventsWithMissinhHitsToFile){
+     myfile.open("MissingDUTHits.dat");
+   }
+
+   int iChan = nChan;
+   double nomStrip = 0, detStrip = 0;
+   int nPrint = 0;
+   double dxh[10];
+   int njump = 10000;
+   if(nentries > 100000) njump = 50000;
+   Long64_t nbytes = 0, nb = 0;
+   cout << "Begin loop over " << nentries << " events" << endl;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      if(jentry%njump==0) cout << "====> At entry = " << jentry << endl;
+      if(n_tp3_tracks != 1) continue;
+
+      //==========================================
+      // Example here of acccessing CMS strip data
+      //==========================================
+      if(fCMS){
+        for(int k=0;k<iChan;k++){
+          if(fCMS->cmsData[k]!=0) hnoise->Fill(fCMS->cmsData[k]);
+        }      
+      }
+
+      h35->Fill(clusterNumberPerEvent);
+      if(clusterNumberPerEvent>10) continue;
+      
+      
+      // Loop over TPIX tracks in event
+      for(int k=0; k<n_tp3_tracks; k++){
+        if(dtime > trackTriggerTimeDiffCut) continue;
+        double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+        double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+        
+        transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip);
+
+        //if(isInCutoutRegion(x_trk, y_trk)) continue;
+        double distToCutout = DistToCutoutRegion(x_trk, y_trk);
+        bool awayFromCutout = distToCutout > minDistFromHole;
+
+        int closestStrip = nomStrip;
+        double fracStrip = nomStrip - closestStrip - 0.5;
+
+        double tx = 1000*vec_trk_tx->at(k);
+        double ty = 1000*vec_trk_ty->at(k);
+
+        h5->Fill(tx);
+        h6->Fill(ty);
+
+        // Test cuts here, e.g.  to reject regions
+        //if(nomStrip<422 || nomStrip>442) continue;
+        //if(y_trk>2.4) continue;
+        //if(nomStrip<420 || nomStrip>445) continue;
+        
+
+        bool goodRegion = true;
+        for(int id = 0; id<nDeadRegion; id++){
+          if(x_trk>=deadRegionLo[id]  && x_trk<=deadRegionHi[id]) goodRegion = false;  
+        }
+        if(!goodRegion) continue;
+
+        h5a->Fill(x_trk);
+        h6a->Fill(y_trk);
+        bool goodTrack = false;
+        bool inFiducialX = false;
+        bool inFiducialY = false;
+
+        if(x_trk>xMin && x_trk<xMax) inFiducialX = true;          
+        if(y_trk>yMin && y_trk<yMax) inFiducialY = true;          
+        bool inFiducial = inFiducialX && inFiducialY;
+        inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+        
+        if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+        bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+        if(goodTrack && goodTime && inFiducial) h12od->Fill(distToCutout);
+
+        if(goodTrack && goodTime && inFiducial && awayFromCutout) {
+          h3a->Fill(x_trk,y_trk);
+          h12a->Fill(y_trk);
+          h12dd->Fill(x_trk);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12ed->Fill(x_trk);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fd->Fill(x_trk);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gd->Fill(x_trk);
+          h12hd->Fill(fracStrip);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12id->Fill(fracStrip);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jd->Fill(fracStrip);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kd->Fill(fracStrip);
+        }
+        
+        bool foundHit = false;
+        bool foundHitNoFid = false;
+        double x_trk0 = x_trk;
+        for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+          dxh[j] = -999;
+          if(clustersPosition[j] < 0.1) continue;
+          if(polarity*clustersCharge[j] < 0.2*kClusterChargeMin) continue;
+          double x_dut = getDUTHitPosition(j);
+          x_trk = x_trk0;
+       
+          int iPeak = 1;
+          if(clustersSeedPosition[j]%2==0) iPeak = 0;
+          
+          h1s->Fill(clustersSeedPosition[j]);
+          if(clustersSeedPosition[j]<iLo-5 || clustersSeedPosition[j]>iHi+5) continue;
+
+          double dx = x_dut - x_trk;
+          dxh[j] = dx;
+
+          if(inFiducial && goodTime && awayFromCutout) h12->Fill(y_trk); 
+          if(goodTrack && inFiducial && fabs(dx)<dxWin && awayFromCutout) {
+            h2p->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+            h15d->Fill(clustersTDC);          
+            if(goodTime) h15e->Fill(clustersTDC);          
+          }
+          
+
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin){
+            h3->Fill(x_trk,y_trk);
+          }
+          
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin) foundHitNoFid = true;
+
+
+          if(goodTrack && inFiducial && goodTime && awayFromCutout) {
+            hcAll->Fill(polarity*clustersCharge[j]);
+            h2->Fill(x_trk, x_dut);
+            h1->Fill(dx);
+            if(clustersSize[j]==1) h1a->Fill(dx);
+            if(clustersSize[j]==2) h1b->Fill(dx);
+            h1w->Fill(dx);
+            if(y_trk>2.5) h1wY->Fill(dx);
+            if(polarity*clustersCharge[j] < 250) h1z->Fill(dx);
+            h11d->Fill(detStrip);        
+            
+            if(fabs(dx)<dxWin) {
+              int ichan = clustersSeedPosition[j];
+              h4c->Fill(clustersSeedPosition[j]);
+              if(ichan>=0 && ichan<=511){
+                hlandau[ichan]->Fill(polarity*clustersCharge[j]);
+              }
+              
+              hnoiseChan->Fill(noise[ichan]);
+              h18a->Fill(clustersSeedCharge[j]/clustersCharge[j]);
+              foundHit = true;
+              if(clustersSize[j]==1) h18b->Fill(fracStrip,dx);
+              if(clustersSize[j]==2) h18c->Fill(fracStrip,dx);
+              h18d->Fill(fracStrip,clustersSeedCharge[j]/clustersCharge[j]);
+              
+              h12m->Fill(fracStrip,polarity*clustersCharge[j]);
+              h12n->Fill(fracStrip,clustersSize[j]);
+              h1vsx->Fill(x_trk,dx);
+              if(y_trk>yMid&&y_trk<yMax) h10a->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yMin&&y_trk<yMid) h10b->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yHi2&&y_trk<yMax) h10c->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              h10d->Fill(y_trk,polarity*clustersCharge[j]);
+              h10e->Fill(x_trk,polarity*clustersCharge[j]);
+              double chleft = polarity*clustersCharge1StripLeft[j];
+              double chright = polarity*clustersCharge1StripRight[j];
+              double rc = -999;
+              if(detStrip <= clustersSeedPosition[j]) {
+                if(chleft>0) rc = (chleft/(chleft+clustersSeedCharge[j]));              
+              }else{ 
+                if(chright>0) rc = (clustersSeedCharge[j]/(chright+clustersSeedCharge[j]));
+              }
+              if( rc>=0 ) {
+                h17->Fill(rc);
+                h17a->Fill(fracStrip,rc);
+                h17b->Fill(fracStrip,rc);
+              }
+              h8->Fill(1000*vec_trk_tx->at(k),dx);    
+              h9->Fill(y_trk,dx);
+              h9a->Fill(x_trk,dx);
+              h5b->Fill(x_trk);
+              h6b->Fill(y_trk);
+              h5c->Fill(tx);
+              h6c->Fill(ty);
+
+              h11n->Fill(detStrip);
+              hcTrk->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==1) hcTrkCorr->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2 && iPeak==1) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeOdd));
+              if(clustersSize[j]==2 && iPeak==0) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeEven));
+              hcTrkSeed->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==1) hcTrkSeed1->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==2) hcTrkSeed2->Fill(polarity*clustersSeedCharge[j]);
+              if(y_trk - yMax < 5.0) hcTrkNoTop->Fill(polarity*clustersCharge[j]);
+              if(x_trk < (xMin+xMax)/2.) hcTrkLowX->Fill(polarity*clustersCharge[j]);
+              if(x_trk >= (xMin+xMax)/2.) hcTrkHighX->Fill(polarity*clustersCharge[j]);
+              int ix = 4*(x_trk - xMin - 0.001) / (xMax-xMin);
+              int iy = 4*(y_trk - yMin - 0.001) / (yMax-yMin);
+              int ihist = 4*ix + iy;
+              hcTrkXY[ihist]->Fill(polarity*clustersCharge[j]);              
+              //if(y_trk>yMin && y_trk<=(yMin+0.25*yRange)) hcTrkY1->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.25*yRange) && y_trk<(yMin+0.50*yRange)) hcTrkY2->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.50*yRange) && y_trk<(yMin+0.75*yRange)) hcTrkY3->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.75*yRange) && y_trk<(yMin+1.00*yRange)) hcTrkY4->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>yMin&&y_trk<yMid+1.0) hcTrkY2->Fill(polarity*clustersCharge[j]);
+
+              if(clustersSize[j]==1) hcTrk1->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2) hcTrk2->Fill(polarity*clustersCharge[j]);
+              if(clustersPosition[j]>170  && clustersPosition[j]<190) hcTrka->Fill(polarity*clustersCharge[j]);
+              h31a->Fill(x_trk,y_trk);
+              h32a->Fill(clustersPosition[j]);
+              h33a->Fill(y_trk);
+              h33b->Fill(x_trk);
+              if(polarity*clustersCharge[j] < 250) {
+                h31b->Fill(x_trk,y_trk);
+                h32b->Fill(clustersPosition[j]);
+                h34->Fill(y_trk);
+              }
+              double chr = clustersCharge1StripRight[j]*polarity;
+              double chl = clustersCharge1StripLeft[j]*polarity;
+              double chr2 = clustersCharge2StripRight[j]*polarity;
+              double chl2 = clustersCharge2StripLeft[j]*polarity;
+              double pch = polarity*clustersSeedCharge[j];
+              int ic = pch/50.;
+              if(ic>=0 && ic<10 && clustersSize[j]<=2 ){
+                if(iPeak==1) h41[ic]->Fill(chl-chr);
+                if(iPeak==0) h42[ic]->Fill(chl-chr);
+                if(chr2!=0 and chl2!=0){
+                  if(iPeak==1) h43[ic]->Fill(chl2-chr2);
+                  if(iPeak==0) h44[ic]->Fill(chl2-chr2);
+                }
+                
+              } 
+            }
+
+            double clstrip = getCorrChannel(clustersPosition[j]);
+            h4->Fill(clstrip);
+            h4b->Fill(clstrip + channelOffset);
+            h4a->Fill(clustersPosition[j]);
+            h0->Fill(detStrip - clstrip);
+          }
+        }
+
+        if(inFiducial && goodTrack && goodTime && foundHitNoFid) {
+          h12on->Fill(distToCutout);
+        }
+        
+        if(inFiducial && goodTrack && goodTime && awayFromCutout) {
+          h16c->Fill(dtime);
+          if(foundHit) {
+            h3c->Fill(x_trk,y_trk);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcfpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1fpa->Fill(dxh[j]);
+            }        
+            h15c->Fill(dtime);
+            h15b->Fill(clustersTDC+0.1);
+            h15a->Fill(vec_trk_chi2ndf->at(k));
+            h12b->Fill(y_trk);
+            h12dn->Fill(x_trk); 
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12en->Fill(x_trk);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fn->Fill(x_trk);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gn->Fill(x_trk);
+            h12hn->Fill(fracStrip);
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12in->Fill(fracStrip);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jn->Fill(fracStrip);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kn->Fill(fracStrip);
+            if(y_trk>yInt1[0] && y_trk < yInt2[1] && x_trk>-3.5&&x_trk<-2.0) {
+              h14b->Fill(detStrip);
+              h13fpa->Fill(clusterNumberPerEvent);
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13fbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                h1fbpa->Fill(dxh[j]);
+                hcfbpa->Fill(polarity*clustersCharge[j]);
+              }
+            }                
+          }else{     
+            h3b->Fill(x_trk,y_trk);          
+            h13mpa->Fill(clusterNumberPerEvent);
+            h16a->Fill(vec_trk_chi2ndf->at(k));
+            h16b->Fill(clustersTDC+0.1);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcmpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1mpa->Fill(dxh[j]);
+            }            
+            nPrint++;
+            if(y_trk>yInt1[0] && y_trk < yInt2[1]) {
+              h14a->Fill(detStrip);
+              if(writeEventsWithMissinhHitsToFile) 
+                myfile << jentry << " " << detStrip << " " << x_trk << " " << y_trk << endl;              
+              //if(nPrint < 100) cout << "Missed hit, event, #clu, nomStrip =  " << jentry << " " 
+              //                      << clusterNumberPerEvent << " " << nomStrip << endl;
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                if(x_trk>-3.5&&x_trk<-2.0) h1mpa1->Fill(dxh[j]);
+                if(x_trk>-2.0&&x_trk<-1.0) h1mpa2->Fill(dxh[j]);
+                if(x_trk>-1.0&&x_trk<0.0) h1mpa3->Fill(dxh[j]);
+                if(x_trk>0.0&&x_trk<1.0)  h1mpa4->Fill(dxh[j]);
+                if(x_trk>1.5&&x_trk<3.5)  h1mpa5->Fill(dxh[j]);
+                if(y_trk<yInt1[1]) h1mpaL->Fill(clustersPosition[j]);                         
+                if(y_trk>=yInt1[1]) h1mpaU->Fill(clustersPosition[j]);
+              }
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13mbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){              
+                h1mbpa->Fill(dxh[j]);
+                hcmbpa->Fill(polarity*clustersCharge[j]);
+              }    
+            }
+          }
+        } 
+      }
+   }
+   if(writeEventsWithMissinhHitsToFile) myfile.close();
+
+   int i1 = h1->FindBin(-0.3);
+   int i2 = h1->FindBin(0.3);
+   cout << "Number of track - DUT hit matchs: " << h1->Integral(i1,i2) << endl;
+   cout << "Ry = " << Ry << endl;
+   
+   
+   TString r1 = Form("%6.3f < Y < %6.3f mm",yInt1[0], yInt1[1]);
+   TString r2 = Form("%6.3f < Y < %6.3f mm ",yInt2[0], yInt2[1]);
+   TString r3 = Form("%6.3f < Y < %6.3f mm",yInt3[0], yInt3[1]);   
+
+
+   TF1 *funchole = new TF1("funchole","[0]+[1]*x+[2]*x*x",-8.0,8.0);
+   funchole->SetParameters(holeQuadPar[0],holeQuadPar[1],holeQuadPar[2]);
+   funchole->SetLineColor(4);
+   funchole->SetLineWidth(2);
+   cout << "Hole Parameters: " << holeQuadPar[0] << " " << holeQuadPar[1] << " " << holeQuadPar[2] << endl;
+   
+   gStyle->SetOptStat(1000000001);
+   gStyle->SetOptFit(0011);
+   gStyle->SetStatH(0.05);
+   gStyle->SetStatW(0.2);
+
+   addGraphics(h3b, 1, "X_{trk} [mm]", "Y_{trk} [mm] ");
+   h3b->GetXaxis()->SetRangeUser(-5,5);
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+
+   TCanvas *c = new TCanvas("c","Residuals",1500,1000);
+   c->Divide(4,3);
+   c->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h2, 1, "X_{trk} [mm]", "X_{DUT} [mm]");
+   double dM = yMax;
+   if(xMax>dM) dM = xMax;
+   h2->GetXaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->GetYaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->SetMinimum(1);
+   h2->Draw();
+
+   c->cd(2)->SetLeftMargin(0.13);;
+   addGraphics(h1, 1, "#DeltaX [mm]", "");
+   addGraphics(h1z, 2, "#DeltaX [mm]", "");
+   addGraphics(h1a, 3, "#DeltaX [mm]", "");
+   addGraphics(h1b, 6, "#DeltaX [mm]", "");
+   h1->GetXaxis()->SetRangeUser(-0.3,0.3);
+   if(m_board.Contains("A1")) h1->GetXaxis()->SetRangeUser(-1.5,1.5);
+   h1->SetMaximum(1.2*h1->GetMaximum());
+   h1->Draw();   
+   //h1z->Draw("same");
+   h1a->Draw("same");
+   h1b->Draw("same");
+   TLine *l1 = new TLine(-stripPitch/2.,0,-stripPitch/2.,0.5*h1->GetMaximum());
+   TLine *l2 = new TLine(stripPitch/2,0,stripPitch/2,0.5*h1->GetMaximum());
+   TLine *l1a = new TLine(-dxWin,0,-dxWin,0.5*h1->GetMaximum());
+   TLine *l2a = new TLine(dxWin,0,dxWin,0.5*h1->GetMaximum());
+   l1->SetLineColor(kRed); l2->SetLineColor(kRed);
+   l1a->SetLineColor(kBlue); l2a->SetLineColor(kBlue); l1a->SetLineWidth(2); l2a->SetLineWidth(2);
+   l1->Draw(); l2->Draw();
+   //l1a->Draw(); l2a->Draw();
+
+   TLegend* legend3 = new TLegend(0.15,0.70,0.40,0.89);
+   legend3->SetFillStyle(0);
+   legend3->SetBorderSize(0);
+   legend3->SetFillStyle(0);
+   legend3->SetTextSize(0.045);
+   
+   legend3->AddEntry(h1,"All","L"); 
+   //legend3->AddEntry(h1z,"ADC < 250","L"); 
+   legend3->AddEntry(h1a,"1-strip","L"); 
+   legend3->AddEntry(h1b,"2-strip","L"); 
+   legend3->Draw();
+   
+   c->cd(3)->SetLeftMargin(0.13);;
+   addGraphics(h8, 1, "#theta_{X}^{trk} [mrad]", "#DeltaX [mm]");
+   h8->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h8->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h8->Draw();
+   c->cd(4)->SetLeftMargin(0.13);;
+   addGraphics(h9, 1, "Y^{trk} [mm]", "#DeltaX [mm]");
+   h9->GetXaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h9->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9->Draw();
+   c->cd(5)->SetLeftMargin(0.13);;
+   addGraphics(h9a, 1, "X^{trk} [mm]", "#DeltaX [mm]");
+   h9a->GetXaxis()->SetRangeUser(-4,4);   
+   h9a->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9a->Draw();
+
+   c->cd(6)->SetLeftMargin(0.13);;
+   addGraphics(h3, 1, "X_{trk} [mm]", "Y_{trk} [mm]");
+   h3->GetXaxis()->SetRangeUser(xMin-1,xMax+1);   
+   h3->GetYaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h3->Draw();
+   if(holeQuadPar[0]!=0) funchole->Draw("same");
+   if(fabs(xLeftHole)<900 && fabs(xRightHole)<900){
+     TBox *b1 = new TBox(xMin,yMin,xLeftHole,yMax);
+     TBox *b2 = new TBox(xRightHole,yMin,xMax,yMax);
+     b1->SetLineColor(kBlue); b1->SetLineWidth(2);b1->SetFillStyle(0);   
+     b1->Draw();
+     b2->SetLineColor(kBlue); b2->SetLineWidth(2);b2->SetFillStyle(0);   
+     b2->Draw();
+   }else{   
+     TBox *b = new TBox(xMin,yMin,xMax,yMax);
+     b->SetLineColor(kBlue); b->SetLineWidth(2);b->SetFillStyle(0);   
+     b->Draw();
+   }
+   
+
+   c->cd(7)->SetLeftMargin(0.13);;
+   addGraphics(h5, 1, "#theta_{X}^{trk} [mrad]", "");
+   h5->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h5->Draw();
+   h5c->SetLineColor(2); h5c->Draw("same");
+   TLine *l1b = new TLine(txMin,0,txMin,h5->GetMaximum());
+   TLine *l2b = new TLine(txMax,0,txMax,h5->GetMaximum());
+   l1b->SetLineColor(kBlue); l2b->SetLineColor(kBlue); l1b->SetLineWidth(2); l2b->SetLineWidth(2);
+   l1b->Draw(); l2b->Draw();
+
+   c->cd(8)->SetLeftMargin(0.13);
+   addGraphics(h6, 1, "#theta_{Y}^{trk} [mrad]", "");
+   h6->GetXaxis()->SetRangeUser(tyMin-0.1,tyMax+0.1);   
+   h6->Draw();
+   h6c->SetLineColor(2); h6c->Draw("same");
+   TLine *l1c = new TLine(tyMin,0,tyMin,h6->GetMaximum());
+   TLine *l2c = new TLine(tyMax,0,tyMax,h6->GetMaximum());
+   l1c->SetLineColor(kBlue); l2c->SetLineColor(kBlue); l1c->SetLineWidth(2); l2c->SetLineWidth(2);   
+   l1c->Draw(); l2c->Draw();
+   
+   c->cd(9)->SetLeftMargin(0.13);;
+   addGraphics(h4, 1, "Strip # with cluster", "");
+   addGraphics(h4a, 2, "Strip # with cluster", "");
+   h4->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   h4a->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   double vmax = h4a->GetMaximum();
+   //for(int ii=iLo; ii<=iHi;ii++){
+   //  if(h4a->GetBinContent(ii)>vmax) vmax = h4a->GetBinContent(ii);
+   //}
+   h4->SetMaximum(1.25*vmax);
+   TLine *l1d = new TLine(iLo,0,iLo,0.75*h4a->GetMaximum());
+   TLine *l2d = new TLine(iHi,0,iHi,0.75*h4a->GetMaximum());
+   l1d->SetLineColor(kBlue); l2d->SetLineColor(kBlue); l1d->SetLineWidth(2); l2d->SetLineWidth(2);   
+   h4->Draw();
+   h4a->Draw("same");
+   l1d->Draw(); l2d->Draw();
+   
+   TLegend* legend4 = new TLegend(0.15,0.70,0.94,0.89);
+   legend4->SetFillStyle(0);
+   legend4->SetBorderSize(0);
+   legend4->SetFillStyle(0);
+   legend4->SetTextSize(0.045);
+   
+   legend4->AddEntry(h4,"Sensor strip ch #","L"); 
+   legend4->AddEntry(h4a,"Electr. ch #","L");
+
+   legend4->Draw();
+
+
+   c->cd(10)->SetLeftMargin(0.13);;
+   addGraphics(hcAll, 1, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk1, 3, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk2, 6, "Cluster charge [ADC]", "");
+   hcAll->SetMaximum(1.25*hcAll->GetMaximum());
+   hcAll->Draw();
+   hcTrk->SetLineColor(kBlue); hcTrk->SetLineWidth(2);
+   hcTrk->Draw("same"); 
+   hcTrk1->Draw("same"); 
+   hcTrk2->Draw("same"); 
+  
+   TLegend* legend2 = new TLegend(0.15,0.70,0.94,0.89);
+   legend2->SetFillStyle(0);
+   legend2->SetBorderSize(0);
+   legend2->SetFillStyle(0);
+   legend2->SetTextSize(0.045);
+   
+   legend2->AddEntry(hcAll,"All clusters, trk in Fid","L"); 
+   legend2->AddEntry(hcTrk,"Clusters, |#DeltaX|<200 #mum, trk in Fid.","L");
+   legend2->AddEntry(hcTrk1,"1-strip Clusters","L");
+   legend2->AddEntry(hcTrk2,"2-strip Clusters","L");
+
+   legend2->Draw();
+
+   
+
+   c->cd(11)->SetLeftMargin(0.13);;
+   addGraphics(h10a, 1, "Strip #", "<ADC>");
+   addGraphics(h10b, 2, "Strip #", "<ADC>");
+   addGraphics(h10c, 4, "Strip #", "<ADC>");
+   int ixl = iLo;
+   int ixh = iHi;
+   int yh = hcTrk->GetMean()-50;
+   h10a->GetXaxis()->SetRangeUser(ixl-2,ixh+2);   
+   h10a->GetYaxis()->SetRangeUser(yh-200,yh+300);
+   /*
+   h10a->Draw();
+   h10b->SetLineColor(2);h10b->SetMarkerColor(2);
+   h10b->Draw("same");
+   h10c->SetLineColor(4);h10c->SetMarkerColor(4);
+   h10c->Draw("same");
+
+   TLegend* legend1 = new TLegend(0.25,0.75,0.94,0.89);
+   legend1->SetFillStyle(0);
+   legend1->SetBorderSize(0);
+   legend1->SetFillStyle(0);
+   legend1->SetTextSize(0.045);
+   
+   legend1->AddEntry(h10a,"Top half in Y","LEP"); 
+   legend1->AddEntry(h10b,"Bottom half in Y","LEP"); 
+   legend1->AddEntry(h10c,"Top 2 mm in Y","LEP"); 
+   legend1->Draw();
+   */
+   addGraphics(h35, 1, "#DUT clusters", "Entries");   
+   h35->GetYaxis()->SetTitleOffset(1.2);
+   h35->Draw();
+
+   c->cd(12)->SetLeftMargin(0.13);;
+   addGraphics(h2p, 1, "TDC time / 2.5 ns", "<ADC>");
+   h2p->Draw();
+   TLine *l1e = new TLine(tdcLo,0,tdcLo,h2p->GetMaximum());
+   TLine *l2e = new TLine(tdcHi,0,tdcHi,h2p->GetMaximum());
+   l1e->SetLineColor(kBlue); l2e->SetLineColor(kBlue); l1e->SetLineWidth(2); l2e->SetLineWidth(2);   
+   l1e->Draw(); l2e->Draw();
+
+   c->Print("Plots/plot_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+   //return;
+   
+
+
+   TCanvas *c4 = new TCanvas("c4","Plot 4",800,600);
+   c4->Divide(2,2);
+   c4->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12en, 1, "X_{trk} [mm]", "");
+   addGraphics(h12fn, 1, "X_{trk} [mm]", "");
+
+   TH1F *hepa1 = (TH1F*)h12en->Clone("hepa1");
+   TH1F *hepa2 = (TH1F*)h12fn->Clone("hepa2");
+   TH1F *henpa = (TH1F*)h12gn->Clone("henpa");
+   hepa1->Divide(h12en,h12ed,1.0,1.0,"B");
+   hepa2->Divide(h12fn,h12fd,1.0,1.0,"B");
+   henpa->Divide(h12gn,h12gd,1.0,1.0,"B");
+   addGraphics(hepa1, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   addGraphics(hepa2, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+   h3b->Draw();
+
+   c4->cd(2)->SetLeftMargin(0.13);
+   hepa1->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa1->SetMinimum(0.0);
+   hepa1->SetMaximum(1.2);
+   hepa1->SetLineWidth(1);
+   hepa1->SetTitle(r1);
+   hepa1->Draw("hist");
+   c4->cd(3)->SetLeftMargin(0.13);
+   hepa2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa2->SetMinimum(0.0);
+   hepa2->SetMaximum(1.2);
+   hepa2->SetLineWidth(1);
+   hepa2->SetTitle(r2);
+   hepa2->Draw("hist");
+
+   c4->cd(4)->SetLeftMargin(0.13);
+   addGraphics(henpa, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   henpa->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   henpa->SetMinimum(0.0);
+   henpa->SetMaximum(1.2);
+   henpa->SetLineWidth(1);
+   henpa->SetTitle(r3);
+   henpa->Draw("hist");   
+
+
+   TCanvas *c5 = new TCanvas("c5","Plot 5",800,600);
+   c5->Divide(2,2);
+   c5->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12hn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12in, 1, "Rel. Strip Pos", "");
+   addGraphics(h12jn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12kn, 1, "Rel. Strip Pos", "");
+
+   TH1F *hepas1 = (TH1F*)h12hn->Clone("hepas1");
+   TH1F *hepas2 = (TH1F*)h12in->Clone("hepas2");
+   TH1F *hepas3 = (TH1F*)h12jn->Clone("hepas3");
+   TH1F *hepas4 = (TH1F*)h12kn->Clone("hepas4");
+   hepas1->Divide(h12hn,h12hd,1.0,1.0,"B");
+   hepas2->Divide(h12in,h12id,1.0,1.0,"B");
+   hepas3->Divide(h12jn,h12jd,1.0,1.0,"B");
+   hepas4->Divide(h12kn,h12kd,1.0,1.0,"B");
+   addGraphics(hepas1, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas2, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas3, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas4, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   hepas1->SetTitle("Full Beam Spot");
+   hepas1->SetMinimum(0.8);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetLineWidth(1);
+   hepas1->Draw("hist");
+   c5->cd(2)->SetLeftMargin(0.13);
+   hepas2->SetTitle(r1);
+   hepas2->SetMinimum(0.8);
+   hepas2->SetMaximum(1.2);
+   hepas2->SetLineWidth(1);
+   hepas2->Draw("hist");
+   c5->cd(3)->SetLeftMargin(0.13);
+   hepas3->SetTitle(r2);
+   hepas3->SetMinimum(0.8);
+   hepas3->SetMaximum(1.2);
+   hepas3->SetLineWidth(1);
+   hepas3->Draw("hist");
+   c5->cd(4)->SetLeftMargin(0.13);
+   hepas4->SetTitle(r3);
+   hepas4->SetMinimum(0.8);
+   hepas4->SetMaximum(1.2);
+   hepas4->SetLineWidth(1);
+   hepas4->Draw("hist");
+
+   c5->Print("Plots/plot5_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   //return;
+   
+
+   TCanvas *c1 = new TCanvas("c1","Plot 1",1600,800);
+   c1->Divide(3,2);
+
+   c1->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h10d, 2, "Y_{trk} [mm]", "<ADC>");
+   h10d->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h10d->Draw();
+
+   //c1->cd(2)->SetLeftMargin(0.13);
+   //h3b->Draw();   
+
+   c1->cd(2)->SetLeftMargin(0.13);
+   addGraphics(h12b, 2, "Y_{trk} [mm]", "");
+   addGraphics(h12a, 1, "Y_{trk} [mm]", "");
+   h12a->SetMaximum(1.2*h12a->GetMaximum());
+   h12a->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h12a->Draw("hist");
+   h12b->Draw("hist,same");
+
+   TLegend* legend0 = new TLegend(0.15,0.75,0.94,0.89);
+   legend0->SetFillStyle(0);
+   legend0->SetBorderSize(0);
+   legend0->SetFillStyle(0);
+   legend0->SetTextSize(0.045);   
+   legend0->AddEntry(h12a,"Track Y pos","LEP"); 
+   legend0->AddEntry(h12b,"Track Y pos with good cluster","LEP");
+   legend0->Draw();
+
+   c1->cd(3)->SetLeftMargin(0.13);
+   TH1F *he = (TH1F*)h12b->Clone("he");
+   he->Divide(h12b,h12a,1.0,1.0,"B");
+   float bw = 1000*h12b->GetBinWidth(1);
+   TString yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he, 1, "Y_{trk} [mm]", yt);
+   he->SetTitle("DUT Efficiency vs Y_{trk}");
+   he->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   he->SetMinimum(0.8);
+   he->SetMaximum(1.1);
+   he->Draw("e");
+
+   c1->cd(4)->SetLeftMargin(0.13);
+   addGraphics(h10e, 2, "X_{trk} [mm]", "<ADC>");
+   h10e->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h10e->Draw();
+
+   c1->cd(5)->SetLeftMargin(0.13);
+   addGraphics(h12dd, 2, "X_{trk} [mm]", "");
+   addGraphics(h12dn, 1, "X_{trk} [mm]", "");
+   h12dd->SetMaximum(1.2*h12dd->GetMaximum());
+   h12dd->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h12dd->Draw("hist");
+   h12dn->Draw("hist,same");
+
+   c1->cd(6)->SetLeftMargin(0.13);
+   TH1F *he2 = (TH1F*)h12dn->Clone("he");
+   he2->Divide(h12dn,h12dd,1.0,1.0,"B");
+   bw = 1000*h12dd->GetBinWidth(1);
+   yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he2, 1, "X_{trk} [mm]", yt);
+   he2->SetTitle("DUT Efficiency vs X_{trk}");
+   he2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   he2->SetMinimum(0.8);
+   he2->SetMaximum(1.1);
+   he2->Draw("e");
+   c1->Print("Plots/plot1_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+   TCanvas *c8 = new TCanvas("c8","Plot 8",800,400);
+   c8->Divide(2,1);
+   TH1F *he4 = (TH1F*)h15c->Clone("Eff_trigger-DUT_time");
+   he4->Divide(h15c,h16c,1.0,1.0,"B");
+   yt = "#Good DUT hit / # Track";
+   addGraphics(h16c, 1, "DUT time - Track Time (ns)", "Entries");
+   addGraphics(he4, 1, "DUT time - Track Time (ns)", "Efficiency");
+   c8->cd(1)->SetLeftMargin(0.15);;
+   c8->cd(1)->SetRightMargin(0.05);;
+   h16c->Draw();
+   c8->cd(2)->SetLeftMargin(0.13);;
+   c8->cd(2)->SetRightMargin(0.05);;
+   he4->Draw();
+   c8->Print("Plots/plot8_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");   
+
+   if(holeSector){
+     TCanvas *c7 = new TCanvas("c7","Plot 7",800,800);
+     c7->SetLeftMargin(0.13);
+     TH1F *he3 = (TH1F*)h12on->Clone("Erf()_fit");
+     he3->Divide(h12on,h12od,1.0,1.0,"B");
+     bw = 1000*h12od->GetBinWidth(1);
+     yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+     addGraphics(he3, 1, "Dist to cutout [mm]", yt);
+     he3->SetStats(kTRUE);
+     he3->SetTitle("DUT Efficiency vs Dist to Cutout");
+     he3->GetXaxis()->SetRangeUser(-0.2,2.0);
+     he3->GetYaxis()->SetRangeUser(0.0,1.3);
+     he3->Draw("e");
+     TLatex *myLatex = new TLatex();
+     myLatex->SetTextFont(42); myLatex->SetTextColor(1); 
+     myLatex->SetTextAlign(12); myLatex->SetNDC(kTRUE); myLatex->SetTextSize(0.047);
+     TString text = "Sector "+m_sector;
+     c7->cd();
+     myLatex->DrawLatex(0.18,0.8,text);
+     
+     TF1 *f4a = new TF1("f4a","0.5*[0]*(1+TMath::Erf((x-[1])/[2]))",-0.1,2.0);
+     f4a->SetParameters(0.5,0.0,0.04);
+     f4a->SetParNames("Const","Mean","Sigma");
+     he3->Fit("f4a","R");
+     TPad *inset = new TPad("inset","y vx x",0.44,0.1,0.89,0.55);
+     inset->SetLeftMargin(0.13);
+     inset->SetRightMargin(0.05);
+     h3->SetTitle("");
+     inset->Draw();
+     inset->cd();
+     h3->Draw();
+     h3b->SetMarkerSize(0.2);h3b->SetMarkerStyle(20);h3b->SetMarkerColor(kRed); 
+     h3b->Draw("same");
+     if(holeQuadPar[0]!=0) funchole->Draw("same");   
+     
+     c7->Print("Plots/plot7_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");   
+   }
+   
+   /*
+   TCanvas *c2 = new TCanvas("c2","Plot 2",1600,600);
+   c2->Divide(5,2);
+   addGraphics(h1mpa, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, No Match Clu");
+   addGraphics(h1mbpa, 4, "X_{clu}-X_{trk} [mm]", ""); h1mbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, No Match Clu");
+   addGraphics(h1fpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, Match Clu");
+   addGraphics(h1fbpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, Match Clu");
+
+   addGraphics(h1mpa1, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa1->SetTitle("2.8<Y_{trk}<4.1 mm, -3.5<X_{trk}<-2.0 mm, No Match Clu");
+   addGraphics(h1mpa2, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa2->SetTitle("2.8<Y_{trk}<4.1 mm, -2.0<X_{trk}<-1.0 mm, No Match Clu");
+   addGraphics(h1mpa3, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa3->SetTitle("2.8<Y_{trk}<4.1 mm, -1.0<X_{trk}<0.0 mm, No Match Clu");
+   addGraphics(h1mpa4, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa4->SetTitle("2.8<Y_{trk}<4.1 mm,  0.0<X_{trk}<1.0 mm, No Match Clu");
+   addGraphics(h1mpa5, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa5->SetTitle("2.8<Y_{trk}<4.1 mm,  1.5<X_{trk}<3.5 mm, No Match Clu");
+   h1mpa->SetLineWidth(1); 
+   h1mpa1->SetLineWidth(1); 
+   h1mpa2->SetLineWidth(1); 
+   h1mpa3->SetLineWidth(1); 
+   h1mpa4->SetLineWidth(1); 
+   h1mpa5->SetLineWidth(1); 
+   h1fpa->SetLineWidth(1); 
+   h1fbpa->SetLineWidth(1); 
+
+   
+   h1fpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1fbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa1->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa2->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa3->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa4->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa5->GetXaxis()->SetRangeUser(-3,9); 
+
+   c2->cd(1);
+   h3b->Draw();   
+   double xl[5] = {-3.5, -2.0, -1.0, 0.0, 1.5};
+   double xh[5] = {-2.0, -1.0,  0.0, 1.0, 3.5};
+   
+   
+   for(int i=0;i<5;i++){
+     TBox *b = new TBox(xl[i],yInt1[0],xh[i],yInt2[1]);
+     b->SetLineColor(2); b->SetFillStyle(0);b->SetLineWidth(2);
+     b->Draw();
+   }
+   TBox *b = new TBox(xl[0],yInt3[0],xh[4],yInt3[1]);
+   b->SetLineColor(4);b->SetFillStyle(0);b->SetLineWidth(2);
+   b->Draw();
+   
+
+
+   c2->cd(2);
+   h1mpa->Draw();   
+   c2->cd(3);
+   h1fpa->GetYaxis()->SetRangeUser(0,30);
+   h1fpa->Draw();   
+   c2->cd(4);
+   h1mbpa->Draw();   
+   c2->cd(5);
+   h1fbpa->GetYaxis()->SetRangeUser(0,30);
+   h1fbpa->Draw();   
+   c2->cd(6);   
+   h1mpa1->Draw();   
+   c2->cd(7);
+   h1mpa2->Draw();   
+   c2->cd(8);
+   h1mpa3->Draw();   
+   c2->cd(9);
+   h1mpa4->Draw();   
+   c2->cd(10);
+   h1mpa5->Draw();
+   c2->Print("Plots/plot2_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   /*
+   TCanvas *c3 = new TCanvas("c3","Plot 3",800,600);
+   c3->Divide(1,2);
+   c3->cd(1);
+   h1mpaU->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaU->Draw();
+   c3->cd(2);
+   h1mpaL->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaL->Draw();   
+   c3->Print("Plots/plot3_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   addGraphics(h12m,1,"Interstrip Pos","<ADC>");
+   addGraphics(h12n,1,"Interstrip Pos","<Cluster Size>");
+   TCanvas *c6 = new TCanvas("c6","Plot 6",1200,400);
+   c6->Divide(3,1);
+   c6->cd(1);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetMinimum(0.5);
+   hepas1->Draw();
+   c6->cd(2);
+   h12m->SetMinimum(0);
+   h12m->SetMaximum(1.2*h12m->GetMaximum());
+   h12m->Draw();
+   c6->cd(3);
+   h12n->SetMinimum(0.5);
+   h12n->SetMaximum(2.0);
+   h12n->Draw();
+   
+   c6->Print("Plots/plot6_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+
+   fout->Write();
+  
+}
+
+void ClusterTrackAnalysis::addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  h->SetMarkerSize(0.7);
+  h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void ClusterTrackAnalysis::addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  //float bw = h->GetBinWidth(1);
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  //h->SetMarkerSize(0.7);
+  //h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+TString ClusterTrackAnalysis::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector){
+
+  TString tag = "";
+
+  if(board.Contains("A6")){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+      if ( bias == "250" ) tag = "B6-A-213-8359";
+      if ( bias == "200" ) tag = "B6-A-214-8361";
+      if ( bias == "150" ) tag = "B6-A-215-8362";
+      if ( bias == "100" ) tag = "B6-A-216-8363";
+      if ( bias == "75" )  tag = "B6-A-219-8365";
+      if ( bias == "50" )  tag = "B6-A-220-8366";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+      if ( bias == "250" ) tag = "B6-A-245-8392";
+      if ( bias == "200" ) tag = "B6-A-246-8393";
+      if ( bias == "150" ) tag = "B6-A-247-8394";
+      if ( bias == "100" ) tag = "B6-A-248-8395";
+      if ( bias == "75" )  tag = "B6-A-249-8396";
+      if ( bias == "50" )  tag = "B6-A-250-8397";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+      if ( bias == "250" ) tag = "B6-A-294-8426";
+      if ( bias == "200" ) tag = "B6-A-295-8427";
+      if ( bias == "150" ) tag = "B6-A-296-8428";
+      if ( bias == "100" ) tag = "B6-A-297-8429";
+      if ( bias == "75" )  tag = "B6-A-298-8430";
+      if ( bias == "50" )  tag = "B6-A-299-8431";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+      if ( bias == "250" ) tag = "B6-A-327-8453";
+      if ( bias == "200" ) tag = "B6-A-328-8454";
+      if ( bias == "150" ) tag = "B6-A-329-8455";
+      if ( bias == "100" ) tag = "B6-A-330-8456";
+      if ( bias == "75" )  tag = "B6-A-331-8457";
+      if ( bias == "50" )  tag = "B6-A-332-8458";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-378-8494";
+      if ( bias == "250" ) tag = "B6-A-381-8497";
+      if ( bias == "200" ) tag = "B6-A-382-8498";
+      if ( bias == "150" ) tag = "B6-A-383-8499";
+      if ( bias == "100" ) tag = "B6-A-384-8500";
+      if ( bias == "75" )  tag = "B6-A-385-8501";
+      if ( bias == "50" )  tag = "B6-A-386-8502";
+    } else if(sector == "6"){
+      if ( bias == "300" ) tag = "B6-A-408-8523";
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+      if ( bias == "200" ) tag = "B6-A-410-8525";
+      if ( bias == "150" ) tag = "B6-A-411-8526";
+      if ( bias == "100" ) tag = "B6-A-412-8527";
+      if ( bias == "75" )  tag = "B6-A-413-8528";
+      if ( bias == "50" )  tag = "B6-A-414-8529";
+    }
+  } else if (board.Contains("A4")) {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+      if(bias == "350" ) tag = "B4-A-211-8553";
+      if(bias == "300" ) tag = "B4-A-212-8554";
+      if(bias == "250" ) tag = "B4-A-213-8555";
+      if(bias == "200" ) tag = "B4-A-214-8556";
+      if(bias == "150" ) tag = "B4-A-215-8557";
+      if(bias == "100" ) tag = "B4-A-216-8558";
+      if(bias == "75" )  tag = "B4-A-217-8559";
+      if(bias == "50" )  tag = "B4-A-218-8560";
+    }else if(sector == "2") {
+      if(bias == "400" ) tag = "B4-A-242-8583";
+      if(bias == "350" ) tag = "B4-A-243-8584";
+      if(bias == "300" ) tag = "B4-A-246-8586";
+      if(bias == "250" ) tag = "B4-A-247-8587";
+      if(bias == "200" ) tag = "B4-A-248-8588";
+      if(bias == "150" ) tag = "B4-A-249-8589";
+      if(bias == "100" ) tag = "B4-A-250-8590";
+      if(bias == "75" )  tag = "B4-A-251-8591";
+      if(bias == "50" )  tag = "B4-A-252-8592";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+      if(bias == "350" ) tag = "B4-A-276-8616";
+      if(bias == "300" ) tag = "B4-A-277-8617";
+      if(bias == "250" ) tag = "B4-A-278-8618";
+      if(bias == "200" ) tag = "B4-A-279-8619";
+      if(bias == "150" ) tag = "B4-A-280-8620";
+      if(bias == "100" ) tag = "B4-A-281-8621";
+      if(bias == "75" )  tag = "B4-A-282-8622";
+      if(bias == "50" )  tag = "B4-A-283-8623";
+    } else if(sector == "4"){
+      if(bias == "400" ) tag = "B4-A-217-8651";
+      if(bias == "350" ) tag = "B4-A-218-8652";
+      if(bias == "300" ) tag = "B4-A-219-8653";
+      if(bias == "250" ) tag = "B4-A-220-8654";
+      if(bias == "200" ) tag = "B4-A-221-8655";
+      if(bias == "150" ) tag = "B4-A-222-8656";
+      if(bias == "100" ) tag = "B4-A-223-8657";
+      if(bias == "75" )  tag = "B4-A-224-8658";
+      if(bias == "50" )  tag = "B4-A-225-8659";
+    } else if(sector == "5"){
+      if(bias == "400" ) tag = "B4-A-246-8680";
+      if(bias == "350" ) tag = "B4-A-247-8681";
+      if(bias == "300" ) tag = "B4-A-248-8682";
+      if(bias == "250" ) tag = "B4-A-249-8683";
+      if(bias == "200" ) tag = "B4-A-250-8684";
+      if(bias == "150" ) tag = "B4-A-251-8685";
+      if(bias == "100" ) tag = "B4-A-252-8686";
+      if(bias == "75" )  tag = "B4-A-253-8687";
+      if(bias == "50" )  tag = "B4-A-254-8688";
+    } else if(sector == "6"){
+      if(bias == "400" ) tag = "B4-A-227-8711";
+      if(bias == "350" ) tag = "B4-A-228-8712";
+      if(bias == "300" ) tag = "B4-A-229-8713";
+      if(bias == "250" ) tag = "B4-A-230-8714";
+      if(bias == "200" ) tag = "B4-A-231-8715";
+      if(bias == "150" ) tag = "B4-A-232-8716";
+      if(bias == "100" ) tag = "B4-A-233-8717";
+      if(bias == "75" )  tag = "B4-A-234-8718";
+      if(bias == "50" )  tag = "B4-A-235-8719";
+      tag = tag.ReplaceAll("B4","B1");
+    }
+  } else if (board.Contains("A8")) {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+      if(bias == "400") tag = "B8-A-297-13333";
+      if(bias == "350") tag = "B8-A-298-13334";
+      if(bias == "300") tag = "B8-A-299-13335";
+      if(bias == "250") tag = "B8-A-300-13336";
+      if(bias == "200") tag = "B8-A-301-13337";
+      if(bias == "150") tag = "B8-A-302-13338";
+      if(bias == "100") tag = "B8-A-303-13339";
+      if(bias == "75")  tag = "B8-A-304-13340";
+      if(bias == "50")  tag = "B8-A-305-13341";
+      if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399";
+      if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400";
+    }else if (sector == "2"){
+      //if(bias == "500") tag = "B8-A-321-13354";
+      if(bias == "400") tag = "B8-A-324-13355";
+      if(bias == "350") tag = "B8-A-325-13356";
+      if(bias == "300") tag = "B8-A-327-13357";
+      if(bias == "250") tag = "B8-A-328-13358";
+      if(bias == "200") tag = "B8-A-329-13359";
+      if(bias == "150") tag = "B8-A-330-13360";
+      if(bias == "100") tag = "B8-A-331-13361";
+      if(bias == "75")  tag = "B8-A-332-13362";
+      if(bias == "50") tag = "B8-A-333-13363";
+    }else if (sector == "3"){
+      //if(bias == "500") tag = "B8-A-358-13385";
+      if(bias == "400") tag = "B8-A-359-13386";
+      if(bias == "350") tag = "B8-A-360-13387";
+      if(bias == "300") tag = "B8-A-361-13388";
+      if(bias == "250") tag = "B8-A-365-13389";
+      if(bias == "200") tag = "B8-A-366-13390";
+      if(bias == "150") tag = "B8-A-367-13391";
+      if(bias == "100") tag = "B8-A-368-13392";
+      if(bias == "75")  tag = "B8-A-369-13393";
+      if(bias == "50")  tag = "B8-A-370-13394";
+    }else if (sector == "4"){
+      //if(bias == "500") tag = "B8-A-309-13344";
+      if(bias == "400") tag = "B8-A-311-13345";
+      if(bias == "350") tag = "B8-A-312-13346";
+      if(bias == "300") tag = "B8-A-314-13347";
+      if(bias == "250") tag = "B8-A-315-13348";
+      if(bias == "200") tag = "B8-A-316-13349";
+      if(bias == "150") tag = "B8-A-317-13350";
+      if(bias == "100") tag = "B8-A-318-13351";
+      if(bias == "75")  tag = "B8-A-319-13352";
+      if(bias == "50")  tag = "B8-A-320-13353";
+    }else if (sector == "5"){
+      //if(bias == "500") tag = "B8-A-334-13364";
+      if(bias == "400") tag = "B8-A-337-13365";
+      if(bias == "350") tag = "B8-A-339-13367";
+      if(bias == "300") tag = "B8-A-340-13368";
+      if(bias == "250") tag = "B8-A-341-13369";
+      if(bias == "200") tag = "B8-A-342-13370";
+      if(bias == "150") tag = "B8-A-343-13371";
+      if(bias == "100") tag = "B8-A-344-13372";
+      if(bias == "75")  tag = "B8-A-345-13373";
+      if(bias == "50")  tag = "B8-A-346-13374";
+      if(bias != "400") tag = tag.ReplaceAll("B8","B1");
+    }else if (sector == "6"){
+      //if(bias == "500") tag = "B8-A-347-13375";
+      if(bias == "400") tag = "B8-A-348-13376";
+      if(bias == "350") tag = "B8-A-349-13377";
+      if(bias == "300") tag = "B8-A-350-13378";
+      if(bias == "250") tag = "B8-A-352-13379";
+      if(bias == "200") tag = "B8-A-353-13380";
+      if(bias == "150") tag = "B8-A-354-13381";
+      if(bias == "100") tag = "B8-A-355-13382";
+      if(bias == "75")  tag = "B8-A-356-13383";
+      if(bias == "50")  tag = "B8-A-357-13384";
+      tag = tag.ReplaceAll("B8","B1");
+    }
+  } else if (board.Contains("D5")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B5-D-14-13066";
+      if(bias == "75") tag = "B5-D-13-13065";
+      if(bias == "100") tag = "B5-D-12-13064";
+      if(bias == "150") tag = "B5-D-11-13063";
+      if(bias == "200") tag = "B5-D-10-13062";
+      if(bias == "250") tag = "B5-D-6-13058";
+      if(bias == "300") tag = "B5-D-19-13071";
+      if(bias == "350") tag = "B5-D-4-13056";
+      if(bias == "400") tag = "B5-D-3-13055";
+      if(bias == "500") tag = "B5-D-16-13068";
+    }else if(sector == "2"){
+      if(bias == "50")  tag = "B5-D-119-13165";
+      if(bias == "75")  tag = "B5-D-118-13164";
+      if(bias == "100") tag = "B5-D-117-13163";
+      if(bias == "150") tag = "B5-D-116-13162";
+      if(bias == "200") tag = "B5-D-115-13161";
+      if(bias == "250") tag = "B5-D-114-13160";
+      if(bias == "300") tag = "B5-D-113-13159";
+      if(bias == "350") tag = "B5-D-111-13157";
+      if(bias == "400") tag = "B5-D-110-13156";
+      if(bias == "500") tag = "B5-D-109-13155";
+    }else if(sector == "3"){
+      if(bias == "50")  tag = "B5-D-167-13209";
+      if(bias == "75")  tag = "B5-D-166-13208";
+      if(bias == "100") tag = "B5-D-165-13207";
+      if(bias == "150") tag = "B5-D-164-13206";
+      if(bias == "200") tag = "B5-D-163-13205";
+      if(bias == "250") tag = "B5-D-162-13204";
+      if(bias == "300") tag = "B5-D-159-13202";
+      if(bias == "350") tag = "B5-D-158-13201";
+      if(bias == "400") tag = "B5-D-157-13200";
+      if(bias == "500") tag = "B5-D-156-13199";
+    }else if(sector == "4"){
+      if(bias == "50")  tag = "B5-D-65-13114";
+      if(bias == "75")  tag = "B5-D-64-13113";
+      if(bias == "100") tag = "B5-D-63-13112";
+      if(bias == "150") tag = "B5-D-62-13111";
+      if(bias == "200") tag = "B5-D-61-13110";
+      if(bias == "250") tag = "B5-D-59-13108";
+      if(bias == "300") tag = "B5-D-58-13107";
+      if(bias == "350") tag = "B5-D-57-13106";
+      if(bias == "400") tag = "B5-D-56-13105";
+      if(bias == "500") tag = "B5-D-55-13104";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B5-D-218-13253";
+      if(bias == "75")  tag = "B5-D-217-13252";
+      if(bias == "100") tag = "B5-D-216-13251";
+      if(bias == "150") tag = "B5-D-215-13250";
+      if(bias == "200") tag = "B5-D-214-13249";
+      if(bias == "250") tag = "B5-D-213-13248";
+      if(bias == "300") tag = "B5-D-212-13247";
+      if(bias == "350") tag = "B5-D-211-13246";
+      if(bias == "400") tag = "B5-D-210-13245";
+      if(bias == "500") tag = "B5-D-209-13244";
+    }else if(sector == "6"){
+      if(bias == "50")  tag = "B5-D-260-13294";
+      if(bias == "75")  tag = "B5-D-259-13293";
+      if(bias == "100") tag = "B5-D-258-13292";
+      if(bias == "150") tag = "B5-D-257-13291";
+      if(bias == "200") tag = "B5-D-256-13290";
+      if(bias == "250") tag = "B5-D-255-13289";
+      if(bias == "300") tag = "B5-D-254-13288";
+      if(bias == "350") tag = "B5-D-253-13287";
+      if(bias == "400") tag = "B5-D-252-13286";
+      if(bias == "500") tag = "B5-D-251-13285";
+    }
+  } else if (board.Contains("D7")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B1-D-347-9360";
+      if(bias == "75") tag = "B1-D-346-9359";
+      if(bias == "100") tag = "B1-D-344-9356";
+      if(bias == "150") tag = "B1-D-345-9357";
+      if(bias == "200") tag = "B1-D-343-9355";
+      if(bias == "300") tag = "B1-D-343-9354";
+      if(bias == "400") tag = "B1-D-341-9353";
+      if(bias == "500") tag = "B1-D-340-9272";
+    }else if(sector == "2"){
+      if(bias == "50") tag = "B1-D-471-9659";
+      if(bias == "75") tag = "B1-D-470-9658";
+      if(bias == "100") tag = "B1-D-469-9657";
+      if(bias == "150") tag = "B1-D-468-9656";
+      if(bias == "200") tag = "B1-D-467-9655";
+      if(bias == "300") tag = "B1-D-466-9654";
+      if(bias == "400") tag = "B1-D-465-9653";
+      if(bias == "500") tag = "B1-D-464-9652";
+    }else if(sector == "3"){
+      if(bias == "50") tag = "B1-D-472-9660";
+      if(bias == "75") tag = "B1-D-473-9661";
+      if(bias == "100") tag = "B1-D-474-9662";
+      if(bias == "150") tag = "B1-D-475-9663";
+      if(bias == "200") tag = "B1-D-476-9664";
+      if(bias == "300") tag = "B1-D-477-9665";
+      if(bias == "400") tag = "B1-D-478-9666";
+      if(bias == "500") tag = "B1-D-479-9667";
+    }else if(sector == "4"){
+      if(bias == "50") tag =  "B1-D-379-9424";
+      if(bias == "75") tag =  "B1-D-378-9423";
+      if(bias == "100") tag = "B1-D-377-9422";
+      if(bias == "150") tag = "B1-D-376-9421";
+      if(bias == "200") tag = "B1-D-375-9419";
+      if(bias == "300") tag = "B1-D-374-9417";
+      if(bias == "400") tag = "B1-D-373-9415";
+      if(bias == "500") tag = "B1-D-372-9413";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B1-D-489-9763";
+      if(bias == "75")  tag = "B1-D-488-9762";
+      if(bias == "100") tag = "B1-D-487-9761";
+      if(bias == "150") tag = "B1-D-484-9674";
+      if(bias == "200") tag = "B1-D-483-9673";
+      if(bias == "300") tag = "B1-D-482-9672";
+      if(bias == "400") tag = "B1-D-481-9671";
+      if(bias == "500") tag = "B1-D-480-9670";
+    }else if(sector == "6"){
+      if(bias == "50") tag =  "B1-D-321-9252";
+      if(bias == "75") tag =  "B1-D-320-9251";
+      if(bias == "100") tag = "B1-D-319-9250";
+      if(bias == "150") tag = "B1-D-318-9249";
+      if(bias == "200") tag = "B1-D-317-9248";
+      if(bias == "300") tag = "B1-D-316-9247";
+      if(bias == "400") tag = "B1-D-315-9246";
+      if(bias == "500") tag = "B1-D-314-9245";
+    }
+  } else if (board.Contains("A1")) {
+    if(sector == "1"){    
+      if(bias == "350") tag = "B1-A-1022-13947";
+      if(bias == "300") tag = "B1-A-1021-13946";
+      if(bias == "250") tag = "B1-A-1053-13971";
+      if(bias == "200") tag = "B1-A-1052-13970";
+      if(bias == "150") tag = "B1-A-1015-13939";
+      if(bias == "100") tag = "B1-A-1014-13938";
+      if(bias == "75")  tag = "B1-A-1013-13937";
+      if(bias == "50")  tag = "B1-A-1012-13936";
+    }else if(sector == "2"){
+      if(bias == "350") tag = "B1-A-1062-13980";
+      if(bias == "300") tag = "B1-A-1061-13979";
+      if(bias == "250") tag = "B1-A-1060-13978";
+      if(bias == "200") tag = "B1-A-1059-13977";
+      if(bias == "150") tag = "B1-A-1058-13976";
+      if(bias == "100") tag = "B1-A-1057-13975";
+      if(bias == "75")  tag = "B1-A-1056-13974";
+      if(bias == "50")  tag = "B1-A-1055-13973";
+    }    
+  } else if (board.Contains("A2")) {
+    if(sector == "1"){    
+      if(bias == "340") tag = "B2-A-1095-14030";
+      if(bias == "325") tag = "B2-A-1094-14029";
+      if(bias == "300") tag = "B2-A-1084-14017";
+      if(bias == "250") tag = "B2-A-1083-14016";
+      if(bias == "200") tag = "B2-A-1082-14015";
+      if(bias == "150") tag = "B2-A-1081-14014";
+      if(bias == "100") tag = "B2-A-1078-14013";
+      if(bias == "75")  tag = "B2-A-1077-14012";
+      if(bias == "50")  tag = "B2-A-1076-14011";
+      if(bias == "300" && angle=="-1") tag = "B2-A-1085-14018";
+      if(bias == "300" && angle=="1") tag = "B2-A-1088-14021";
+    }else if(sector == "2"){
+      if(bias == "340") tag = "B2-A-1099-14034";
+      if(bias == "325") tag = "B2-A-1098-14033";
+      if(bias == "300") tag = "B2-A-1097-14032";
+      if(bias == "250") tag = "B2-A-1100-14035";
+      if(bias == "200") tag = "B2-A-1101-14036";
+      if(bias == "150") tag = "B2-A-1102-14037";
+      if(bias == "100") tag = "B2-A-1103-14038";
+      if(bias == "75")  tag = "B2-A-1104-14039";
+      if(bias == "50")  tag = "B2-A-1105-14040";
+    }    
+  }
+
+  return tag;
+}
diff --git a/TbUT/scripts/ClusterTrackAnalysis.C~ b/TbUT/scripts/ClusterTrackAnalysis.C~
new file mode 100644
index 0000000..097fe89
--- /dev/null
+++ b/TbUT/scripts/ClusterTrackAnalysis.C~
@@ -0,0 +1,1585 @@
+#include "ClusterTrackAnalysis.h"
+
+ClusterTrackAnalysis::CusterTrackAnalysis() :
+
+  test(0)
+
+{
+  cout << "starting ClusterTrackAnalysis" << endl;
+}
+
+ClusterTrackAnalysis::~ClusterTrackAnalysis() {
+  if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+
+ClusterTrackAnalysis::ClusterTrackAnalysis(int biasVal) {
+
+ TString filename;
+  if(biasVal != 0) m_bias = Form("%d",biasVal);
+  TTree* tree = 0;
+  
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     TString scanType = "Run_Bias";
+     filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root"; 
+     if(m_scanType.Contains("Angle")){
+       scanType = "Run_Angle";
+       filename = m_fileIndir+"Board"+m_board+"_Angle/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root"; 
+     }
+     
+     cout << "===> Opening file: " << filename << endl;
+     
+
+     // lxplus
+     //
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6
+     //
+
+     TFile *f = new TFile(filename);
+     tree = (TTree*)f->Get("Clusters");
+     TH1F *hn = (TH1F*)f->Get("hWidthNoise");
+     for(int i=0;i<nChan;i++){
+       noise[i] = hn->GetBinContent(i+1);
+     }
+
+     // Get mean noise and width
+     hMeanNoise 	= (TH1F*)f->Get("hMeanNoise"); 
+     hWidthNoise 	= (TH1F*)f->Get("hWidthNoise"); 
+     cout << "===> Opening file: " << filename << endl;
+
+     TString filename2 = filename.ReplaceAll("_Tracks","");
+     TFile * f2 = new TFile(filename2);
+     if(f2) {
+       TTree * tree2 = (TTree*) f2->Get("TbUT/CMS");
+       if(tree2) {
+         tree->AddFriend(tree2);
+         fCMS = new CMS(tree2);
+       }else{
+         fCMS=0;  
+       }
+     } else {
+       cout << "WARNING: Could not find CMS data file: " << filename2 << endl;
+       fCMS =0 ;
+     }
+   }
+   Init(tree);
+
+}
+
+void ClusterTrackAnalysis::Loop(){
+//   In a ROOT session, you can do:
+//      Root > .L ClusterWithTrackAna.C
+//      Root > ClusterWithTrackAna t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+
+   Int_t nentries = fChain->GetEntriesFast();
+
+   TString m_board2 = m_board;
+   m_board2 = m_board2.ReplaceAll("_All","");
+   m_board2 = m_board2.ReplaceAll("_Full","");
+   m_board2 = m_board2.ReplaceAll("_v7","");
+   TString f_out = m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + ".root";
+   if(m_angle != "0"){
+     f_out			= m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + "_" + m_angle + ".root";
+   }
+   cout << "Will write out file: " << f_out << endl;
+   
+
+
+   fout = new TFile(f_out,"RECREATE");
+
+   TH1F* h0 = new TH1F("h0","#DeltaX between strip hit and track projection (strips)",101,-50.5,50.5);
+   TH1F* h1 = new TH1F("h1","#DeltaX",800,-2.0,2.0);
+   TH2F* h1vsx = new TH2F("h1vsx","#DeltaX vs X",50,-5,5,100,-0.2,0.2);
+   TH1F* h1mpa = new TH1F("h1mpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1mbpa = new TH1F("h1mbpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fpa = new TH1F("h1fpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fbpa = new TH1F("h1fbpa","#DeltaX",400,-20.0,20.0);
+
+   TH1F* h1mpa1 = new TH1F("h1mpa1","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa2 = new TH1F("h1mpa2","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa3 = new TH1F("h1mpa3","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa4 = new TH1F("h1mpa4","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa5 = new TH1F("h1mpa5","#DeltaX",800,-20.0,20.0);
+
+   TH1F* h1mpaL = new TH1F("h1mpaL","Strip# of Missed Hit in Lower PA region",512,0,512);
+   TH1F* h1mpaU = new TH1F("h1mpaU","Strip# of Missed Hit in Upper PA region",512,0,512);
+
+
+   TH1F* h1s = new TH1F("h1s","Seed strip of cluster",512,0.0,512.0);
+   TH1F* h1a = new TH1F("h1a","#DeltaX, 1 strip",800,-2.0,2.0);
+   TH1F* h1b = new TH1F("h1b","#DeltaX, 2 strip",800,-2.0,2.0);
+   TH1F* h1z = new TH1F("h1z","#DeltaX, low Charge",800,-2.0,2.0);
+   TH1F* h1w = new TH1F("h1w","#DeltaX",20000,-100.0,100.0);
+   TH1F* h1wY = new TH1F("h1wY","#DeltaX",20000,-100.0,100.0);
+   TH2F* h2 = new TH2F("h2","X_{DUT} vs X_{trk}",100,-8.0,8.0,100,-8,8);
+   TH2F* h3 = new TH2F("h3","Y_{trk} vs X_{trk}, with cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3a = new TH2F("h3a","Y_{trk} vs X_{trk} in fiducial",640,-8,8.0,640,-8,8);
+   TH2F* h3b = new TH2F("h3b","Y_{trk} vs X_{trk}, with missed cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3c = new TH2F("h3c","Y_{trk} vs X_{trk}, with found cluster",640,-8,8.0,640,-8,8);
+   TH1F* h4 = new TH1F("h4","Detector strip # of cluster with track",512,0.0,512);
+   TH1F* h4a = new TH1F("h4a","Electonic Strip # of cluster with track",512,0.0,512);
+   TH1F* h4b = new TH1F("h4b","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h4c = new TH1F("h4c","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h5 = new TH1F("h5","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6 = new TH1F("h6","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5c = new TH1F("h5c","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6c = new TH1F("h6c","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5a = new TH1F("h5a","X position of track",400,-10.0,10.0);
+   TH1F* h6a = new TH1F("h6a","Y position of track",400,-10.0,10.0);
+   TH1F* h5b = new TH1F("h5b","X position of matched cluster",400,-10.0,10.0);
+   TH1F* h6b = new TH1F("h6b","Y position of matched cluster",400,-10.0,10.0);
+
+   TProfile *h8 = new TProfile("h8","#DeltaX vs #theta_{trk}",100,-5,5,-1.0,1.0);
+   TProfile *h9 = new TProfile("h9","#DeltaX vs Y_{trk} at DUT",1600,-8,8,-1.0,1.0);
+   TProfile *h9a = new TProfile("h9a","#DeltaX vs X_{trk} at DUT",20,-5,5,-1.0,1.0);
+
+   TProfile *h10a = new TProfile("h10a","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10b = new TProfile("h10b","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10c = new TProfile("h10c","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10d = new TProfile("h10d","<ADC> vs Y_{trk}",100,-8,8,0.0,1000.0);
+   TProfile *h10e = new TProfile("h10e","<ADC> vs X_{trk}",100,-8,8,0.0,1000.0);
+   TH1F* h11n = new TH1F("h11n","Strip # of matched cluster",512,0.0,512);
+   TH1F* h11d = new TH1F("h11d","Strip # of track",512,0.0,512);
+   h11n->Sumw2();
+   h11d->Sumw2();
+   
+   TH1F* h12 = new TH1F("h12","Y position of matched cluster",400,-10.0,10.0); h12->Sumw2();
+   TH1F* h12c = new TH1F("h12c","X position of matched cluster",400,-10.0,10.0);h12c->Sumw2();
+   TH1F* h12a = new TH1F("h12a","Y position of track",1600,-10.0,10.0); h12a->Sumw2();
+   TH1F* h12b = new TH1F("h12b","Y position of track",1600,-10.0,10.0); h12b->Sumw2();
+
+   TH1F* h12dn = new TH1F("h12dn","X position of track",200,-10.0,10.0); h12dn->Sumw2();
+   TH1F* h12en = new TH1F("h12en","X position of track",200,-10.0,10.0);h12en->Sumw2();
+   TH1F* h12fn = new TH1F("h12fn","X position of track",200,-10.0,10.0);h12fn->Sumw2();
+   TH1F* h12gn = new TH1F("h12gn","X position of track",200,-10.0,10.0);h12gn->Sumw2();
+   TH1F* h12dd = new TH1F("h12dd","X position of track",200,-10.0,10.0);h12dd->Sumw2();
+   TH1F* h12ed = new TH1F("h12ed","X position of track",200,-10.0,10.0);h12ed->Sumw2();
+   TH1F* h12fd = new TH1F("h12fd","X position of track",200,-10.0,10.0);h12fd->Sumw2();
+   TH1F* h12gd = new TH1F("h12gd","X position of track",200,-10.0,10.0);h12gd->Sumw2();
+
+   TH1F* h12hn = new TH1F("h12hn","X position of track",50,-0.5,0.5);h12hn->Sumw2();
+   TH1F* h12in = new TH1F("h12in","X position of track",50,-0.5,0.5);h12in->Sumw2();
+   TH1F* h12jn = new TH1F("h12jn","X position of track",50,-0.5,0.5);h12jn->Sumw2();
+   TH1F* h12kn = new TH1F("h12kn","X position of track",50,-0.5,0.5);h12kn->Sumw2();
+   TH1F* h12hd = new TH1F("h12hd","X position of track",50,-0.5,0.5);h12hd->Sumw2();
+   TH1F* h12id = new TH1F("h12id","X position of track",50,-0.5,0.5);h12id->Sumw2();
+   TH1F* h12jd = new TH1F("h12jd","X position of track",50,-0.5,0.5);h12jd->Sumw2();
+   TH1F* h12kd = new TH1F("h12kd","X position of track",50,-0.5,0.5);h12kd->Sumw2();
+
+   TProfile *h12m = new TProfile("h12m","<ADC> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+   TProfile *h12n = new TProfile("h12n","<ClusterSize> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+
+   TH1F* h12on = new TH1F("h12on","dist of track to cutout",700,-2.0,5.0);h12on->Sumw2();
+   TH1F* h12od = new TH1F("h12od","dist of track to cutout",700,-2.0,5.0);h12od->Sumw2();
+
+   TH1F *h13mpa = new TH1F("h13mpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13mbpa = new TH1F("h13mbpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fpa = new TH1F("h13fpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fbpa = new TH1F("h13fbpa","#Clusters/Ev",10,-0.5,9.5);   
+
+   TH1F* h14a = new TH1F("h14a","Nom Strip, no matched cluster",512,0.0,512);
+   TH1F* h14b = new TH1F("h14b","Nom Strip, matched cluster",512,0.0,512);
+
+   TH1F *h15a = new TH1F("h15a","Chisq of tracks with matched DUT hit",200,0.0,200.0);
+   TH1F *h15b = new TH1F("h15b","TDC time with matched DUT hit",12,0.0,12.0);
+   TH1F *h15c = new TH1F("h15c","Time Between Trigger and Track",5,0.0,5.0);
+   TH1F *h15d = new TH1F("h15d","TDC time of all clusters",12,0.0,12.0);
+   TH1F *h15e = new TH1F("h15e","TDC time of good clusters",12,0.0,12.0);
+
+   TH1F *h16a = new TH1F("h16a","Chisq of tracks without matched DUT hit",200,0.0,200.0);
+   TH1F *h16b = new TH1F("h16b","TDC time without matched DUT hit",12,0.0,12.0);
+   TH1F *h16c = new TH1F("h16c","Time Between Trigger and Track",5,0.0,5.0);
+   h15c->Sumw2();
+   h16c->Sumw2();
+   
+   TH1F* h17 = new TH1F("h17","Q_{L} / (Q_{L}+Q_{R})",50,0.0,1.0);
+   TH2F* h17a = new TH2F("h17a","Q_{L} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,120,-0.1,1.1);
+   TProfile* h17b = new TProfile("h17b","Q_{R} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,-0.1,1.1);
+
+   TH1F* hcmpa = new TH1F("hcmpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcmbpa = new TH1F("hcmbpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfpa = new TH1F("hcfpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfbpa = new TH1F("hcfbpa","Cluster charge",100,0.0,1000.0);
+
+   TH1F* h18a = new TH1F("h18a","Seed/Total charge",100,0.0,2.0);
+
+   TH2F* h18b = new TH2F("h18b","#DeltaX vs Interstrip Pos (1 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18c = new TH2F("h18c","#DeltaX vs Interstrip Pos (2 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18d = new TH2F("h18d","Seed/Total charge vs Interstrip Pos",100,-0.5,0.5,100,0.0,1.1);
+
+   TH1F* hcTrkXY[16];
+   for(int i=0; i<4; i++){
+     for(int j=0; j<4; j++){
+       int iblock = 4*i+j; 
+       TString hname = Form("hcTrkXY_%d",iblock+1);     
+       TString htitle = Form("Cluster charge, block %d",iblock+1);     
+       hcTrkXY[iblock]= new TH1F(hname,htitle,100,0.0,1000.0);
+     }
+   }
+   
+   TH1F *hlandau[512];
+   for(int i=0; i<nChan; i++){
+     hlandau[i] = new TH1F(Form("hlandau_%d",i),"Cluster charge",100,0.0,1000.0);
+   }
+   
+
+
+   TH1F* hcAll = new TH1F("hcAll","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrk = new TH1F("hcTrk","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkCorr = new TH1F("hcTrkCorr","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed = new TH1F("hcTrkSeed","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed1 = new TH1F("hcTrkSeed1","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed2 = new TH1F("hcTrkSeed2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY1 = new TH1F("hcTrkY1","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY2 = new TH1F("hcTrkY2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY3 = new TH1F("hcTrkY3","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY4 = new TH1F("hcTrkY4","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkNoTop = new TH1F("hcTrkNoTop","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkLowX = new TH1F("hcTrkLowX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkHighX = new TH1F("hcTrkHighX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrka = new TH1F("hcTrka","Cluster charge, limited region",100,0.0,1000.0);
+   TH1F* hcTrk1 = new TH1F("hcTrk1","Cluster charge, Size = 1",100,0.0,1000.0);
+   TH1F* hcTrk2 = new TH1F("hcTrk2","Cluster charge, Size = 2",100,0.0,1000.0);
+   TProfile *h2p = new TProfile("h2p","Cluster Charge vs TDC time",12,0,12,100,1000);
+
+
+   TH2F* h31a = new TH2F("h31a","Y_{trk} vs X_{trk}, with cluster",64,-8,8.0,64,-8,8);
+   TH2F* h31b = new TH2F("h31b","Y_{trk} vs X_{trk}, with cluster, low ADC",64,-8,8.0,64,-8,8);
+   TH1F* h32a = new TH1F("h32a","Strip # of cluster with track",512,0.0,512);
+   TH1F* h32b = new TH1F("h32b","Strip # of cluster with track & low ADC",512,0.0,512);
+   TH1F* h33a = new TH1F("h33a","Y position of matched cluster",200,-10.0,10.0);
+   TH1F* h33b = new TH1F("h33b","X position of matched cluster",200,-10.0,10.0);
+   TH1F* h34 = new TH1F("h34","Y position of matched cluster & low ADC",200,-10.0,10.0);
+
+   TH1F *hnoise = new TH1F("hnoise","Noise in connected channels",100,-200,200);
+   TH1F *hnoiseChan = new TH1F("hnoiseChan","Noise in connected channels",200,0,200);
+   TH1F *hnoisePerChannel = new TH1F("hnoisePerChannel","Noise",512,0,512);
+
+   TH1F* h35 = new TH1F("h35","No. clusters / event",50,0.0,50.0);
+   
+   TH1F *h41[10];
+   TH1F *h42[10];
+   TH1F *h43[10];
+   TH1F *h44[10];
+   for(int i=0; i<10; i++){
+     h41[i] = new TH1F(Form("h41_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h42[i] = new TH1F(Form("h42_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h43[i] = new TH1F(Form("h43_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+     h44[i] = new TH1F(Form("h44_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+   }
+
+   for(int i=0; i<nChan; i++){
+     hnoisePerChannel->Fill(i+0.5,noise[i]);
+   }
+   
+
+
+   //------------------------------------------------------------------------------------------------------
+   
+   //-----------------------------
+   // Prepare DUT (Alignment, etc)
+   //-----------------------------
+
+   PrepareDUT();
+   //return;
+   float biasVal = atof(m_bias);
+   cout << "chargeCorrSlopeOdd, chargeCorrSlopeEven = " << chargeCorrSlopeOdd << " " << chargeCorrSlopeEven << " " 
+        << m_bias << " " << biasVal << endl;
+   
+
+   std::ofstream myfile;
+   if(writeEventsWithMissinhHitsToFile){
+     myfile.open("MissingDUTHits.dat");
+   }
+
+   int iChan = nChan;
+   double nomStrip = 0, detStrip = 0;
+   int nPrint = 0;
+   double dxh[10];
+   int njump = 10000;
+   if(nentries > 100000) njump = 50000;
+   Long64_t nbytes = 0, nb = 0;
+   cout << "Begin loop over " << nentries << " events" << endl;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      if(jentry%njump==0) cout << "====> At entry = " << jentry << endl;
+      if(n_tp3_tracks != 1) continue;
+
+      //==========================================
+      // Example here of acccessing CMS strip data
+      //==========================================
+      if(fCMS){
+        for(int k=0;k<iChan;k++){
+          if(fCMS->cmsData[k]!=0) hnoise->Fill(fCMS->cmsData[k]);
+        }      
+      }
+
+      h35->Fill(clusterNumberPerEvent);
+      if(clusterNumberPerEvent>10) continue;
+      
+      
+      // Loop over TPIX tracks in event
+      for(int k=0; k<n_tp3_tracks; k++){
+        if(dtime > trackTriggerTimeDiffCut) continue;
+        double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+        double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+        
+        transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip);
+
+        //if(isInCutoutRegion(x_trk, y_trk)) continue;
+        double distToCutout = DistToCutoutRegion(x_trk, y_trk);
+        bool awayFromCutout = distToCutout > minDistFromHole;
+
+        int closestStrip = nomStrip;
+        double fracStrip = nomStrip - closestStrip - 0.5;
+
+        double tx = 1000*vec_trk_tx->at(k);
+        double ty = 1000*vec_trk_ty->at(k);
+
+        h5->Fill(tx);
+        h6->Fill(ty);
+
+        // Test cuts here, e.g.  to reject regions
+        //if(nomStrip<422 || nomStrip>442) continue;
+        //if(y_trk>2.4) continue;
+        //if(nomStrip<420 || nomStrip>445) continue;
+        
+
+        bool goodRegion = true;
+        for(int id = 0; id<nDeadRegion; id++){
+          if(x_trk>=deadRegionLo[id]  && x_trk<=deadRegionHi[id]) goodRegion = false;  
+        }
+        if(!goodRegion) continue;
+
+        h5a->Fill(x_trk);
+        h6a->Fill(y_trk);
+        bool goodTrack = false;
+        bool inFiducialX = false;
+        bool inFiducialY = false;
+
+        if(x_trk>xMin && x_trk<xMax) inFiducialX = true;          
+        if(y_trk>yMin && y_trk<yMax) inFiducialY = true;          
+        bool inFiducial = inFiducialX && inFiducialY;
+        inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+        
+        if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+        bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+        if(goodTrack && goodTime && inFiducial) h12od->Fill(distToCutout);
+
+        if(goodTrack && goodTime && inFiducial && awayFromCutout) {
+          h3a->Fill(x_trk,y_trk);
+          h12a->Fill(y_trk);
+          h12dd->Fill(x_trk);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12ed->Fill(x_trk);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fd->Fill(x_trk);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gd->Fill(x_trk);
+          h12hd->Fill(fracStrip);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12id->Fill(fracStrip);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jd->Fill(fracStrip);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kd->Fill(fracStrip);
+        }
+        
+        bool foundHit = false;
+        bool foundHitNoFid = false;
+        double x_trk0 = x_trk;
+        for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+          dxh[j] = -999;
+          if(clustersPosition[j] < 0.1) continue;
+          if(polarity*clustersCharge[j] < 0.2*kClusterChargeMin) continue;
+          double x_dut = getDUTHitPosition(j);
+          x_trk = x_trk0;
+       
+          int iPeak = 1;
+          if(clustersSeedPosition[j]%2==0) iPeak = 0;
+          
+          h1s->Fill(clustersSeedPosition[j]);
+          if(clustersSeedPosition[j]<iLo-5 || clustersSeedPosition[j]>iHi+5) continue;
+
+          double dx = x_dut - x_trk;
+          dxh[j] = dx;
+
+          if(inFiducial && goodTime && awayFromCutout) h12->Fill(y_trk); 
+          if(goodTrack && inFiducial && fabs(dx)<dxWin && awayFromCutout) {
+            h2p->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+            h15d->Fill(clustersTDC);          
+            if(goodTime) h15e->Fill(clustersTDC);          
+          }
+          
+
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin){
+            h3->Fill(x_trk,y_trk);
+          }
+          
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin) foundHitNoFid = true;
+
+
+          if(goodTrack && inFiducial && goodTime && awayFromCutout) {
+            hcAll->Fill(polarity*clustersCharge[j]);
+            h2->Fill(x_trk, x_dut);
+            h1->Fill(dx);
+            if(clustersSize[j]==1) h1a->Fill(dx);
+            if(clustersSize[j]==2) h1b->Fill(dx);
+            h1w->Fill(dx);
+            if(y_trk>2.5) h1wY->Fill(dx);
+            if(polarity*clustersCharge[j] < 250) h1z->Fill(dx);
+            h11d->Fill(detStrip);        
+            
+            if(fabs(dx)<dxWin) {
+              int ichan = clustersSeedPosition[j];
+              h4c->Fill(clustersSeedPosition[j]);
+              if(ichan>=0 && ichan<=511){
+                hlandau[ichan]->Fill(polarity*clustersCharge[j]);
+              }
+              
+              hnoiseChan->Fill(noise[ichan]);
+              h18a->Fill(clustersSeedCharge[j]/clustersCharge[j]);
+              foundHit = true;
+              if(clustersSize[j]==1) h18b->Fill(fracStrip,dx);
+              if(clustersSize[j]==2) h18c->Fill(fracStrip,dx);
+              h18d->Fill(fracStrip,clustersSeedCharge[j]/clustersCharge[j]);
+              
+              h12m->Fill(fracStrip,polarity*clustersCharge[j]);
+              h12n->Fill(fracStrip,clustersSize[j]);
+              h1vsx->Fill(x_trk,dx);
+              if(y_trk>yMid&&y_trk<yMax) h10a->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yMin&&y_trk<yMid) h10b->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yHi2&&y_trk<yMax) h10c->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              h10d->Fill(y_trk,polarity*clustersCharge[j]);
+              h10e->Fill(x_trk,polarity*clustersCharge[j]);
+              double chleft = polarity*clustersCharge1StripLeft[j];
+              double chright = polarity*clustersCharge1StripRight[j];
+              double rc = -999;
+              if(detStrip <= clustersSeedPosition[j]) {
+                if(chleft>0) rc = (chleft/(chleft+clustersSeedCharge[j]));              
+              }else{ 
+                if(chright>0) rc = (clustersSeedCharge[j]/(chright+clustersSeedCharge[j]));
+              }
+              if( rc>=0 ) {
+                h17->Fill(rc);
+                h17a->Fill(fracStrip,rc);
+                h17b->Fill(fracStrip,rc);
+              }
+              h8->Fill(1000*vec_trk_tx->at(k),dx);    
+              h9->Fill(y_trk,dx);
+              h9a->Fill(x_trk,dx);
+              h5b->Fill(x_trk);
+              h6b->Fill(y_trk);
+              h5c->Fill(tx);
+              h6c->Fill(ty);
+
+              h11n->Fill(detStrip);
+              hcTrk->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==1) hcTrkCorr->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2 && iPeak==1) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeOdd));
+              if(clustersSize[j]==2 && iPeak==0) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeEven));
+              hcTrkSeed->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==1) hcTrkSeed1->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==2) hcTrkSeed2->Fill(polarity*clustersSeedCharge[j]);
+              if(y_trk - yMax < 5.0) hcTrkNoTop->Fill(polarity*clustersCharge[j]);
+              if(x_trk < (xMin+xMax)/2.) hcTrkLowX->Fill(polarity*clustersCharge[j]);
+              if(x_trk >= (xMin+xMax)/2.) hcTrkHighX->Fill(polarity*clustersCharge[j]);
+              int ix = 4*(x_trk - xMin - 0.001) / (xMax-xMin);
+              int iy = 4*(y_trk - yMin - 0.001) / (yMax-yMin);
+              int ihist = 4*ix + iy;
+              hcTrkXY[ihist]->Fill(polarity*clustersCharge[j]);              
+              //if(y_trk>yMin && y_trk<=(yMin+0.25*yRange)) hcTrkY1->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.25*yRange) && y_trk<(yMin+0.50*yRange)) hcTrkY2->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.50*yRange) && y_trk<(yMin+0.75*yRange)) hcTrkY3->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.75*yRange) && y_trk<(yMin+1.00*yRange)) hcTrkY4->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>yMin&&y_trk<yMid+1.0) hcTrkY2->Fill(polarity*clustersCharge[j]);
+
+              if(clustersSize[j]==1) hcTrk1->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2) hcTrk2->Fill(polarity*clustersCharge[j]);
+              if(clustersPosition[j]>170  && clustersPosition[j]<190) hcTrka->Fill(polarity*clustersCharge[j]);
+              h31a->Fill(x_trk,y_trk);
+              h32a->Fill(clustersPosition[j]);
+              h33a->Fill(y_trk);
+              h33b->Fill(x_trk);
+              if(polarity*clustersCharge[j] < 250) {
+                h31b->Fill(x_trk,y_trk);
+                h32b->Fill(clustersPosition[j]);
+                h34->Fill(y_trk);
+              }
+              double chr = clustersCharge1StripRight[j]*polarity;
+              double chl = clustersCharge1StripLeft[j]*polarity;
+              double chr2 = clustersCharge2StripRight[j]*polarity;
+              double chl2 = clustersCharge2StripLeft[j]*polarity;
+              double pch = polarity*clustersSeedCharge[j];
+              int ic = pch/50.;
+              if(ic>=0 && ic<10 && clustersSize[j]<=2 ){
+                if(iPeak==1) h41[ic]->Fill(chl-chr);
+                if(iPeak==0) h42[ic]->Fill(chl-chr);
+                if(chr2!=0 and chl2!=0){
+                  if(iPeak==1) h43[ic]->Fill(chl2-chr2);
+                  if(iPeak==0) h44[ic]->Fill(chl2-chr2);
+                }
+                
+              } 
+            }
+
+            double clstrip = getCorrChannel(clustersPosition[j]);
+            h4->Fill(clstrip);
+            h4b->Fill(clstrip + channelOffset);
+            h4a->Fill(clustersPosition[j]);
+            h0->Fill(detStrip - clstrip);
+          }
+        }
+
+        if(inFiducial && goodTrack && goodTime && foundHitNoFid) {
+          h12on->Fill(distToCutout);
+        }
+        
+        if(inFiducial && goodTrack && goodTime && awayFromCutout) {
+          h16c->Fill(dtime);
+          if(foundHit) {
+            h3c->Fill(x_trk,y_trk);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcfpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1fpa->Fill(dxh[j]);
+            }        
+            h15c->Fill(dtime);
+            h15b->Fill(clustersTDC+0.1);
+            h15a->Fill(vec_trk_chi2ndf->at(k));
+            h12b->Fill(y_trk);
+            h12dn->Fill(x_trk); 
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12en->Fill(x_trk);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fn->Fill(x_trk);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gn->Fill(x_trk);
+            h12hn->Fill(fracStrip);
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12in->Fill(fracStrip);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jn->Fill(fracStrip);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kn->Fill(fracStrip);
+            if(y_trk>yInt1[0] && y_trk < yInt2[1] && x_trk>-3.5&&x_trk<-2.0) {
+              h14b->Fill(detStrip);
+              h13fpa->Fill(clusterNumberPerEvent);
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13fbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                h1fbpa->Fill(dxh[j]);
+                hcfbpa->Fill(polarity*clustersCharge[j]);
+              }
+            }                
+          }else{     
+            h3b->Fill(x_trk,y_trk);          
+            h13mpa->Fill(clusterNumberPerEvent);
+            h16a->Fill(vec_trk_chi2ndf->at(k));
+            h16b->Fill(clustersTDC+0.1);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcmpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1mpa->Fill(dxh[j]);
+            }            
+            nPrint++;
+            if(y_trk>yInt1[0] && y_trk < yInt2[1]) {
+              h14a->Fill(detStrip);
+              if(writeEventsWithMissinhHitsToFile) 
+                myfile << jentry << " " << detStrip << " " << x_trk << " " << y_trk << endl;              
+              //if(nPrint < 100) cout << "Missed hit, event, #clu, nomStrip =  " << jentry << " " 
+              //                      << clusterNumberPerEvent << " " << nomStrip << endl;
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                if(x_trk>-3.5&&x_trk<-2.0) h1mpa1->Fill(dxh[j]);
+                if(x_trk>-2.0&&x_trk<-1.0) h1mpa2->Fill(dxh[j]);
+                if(x_trk>-1.0&&x_trk<0.0) h1mpa3->Fill(dxh[j]);
+                if(x_trk>0.0&&x_trk<1.0)  h1mpa4->Fill(dxh[j]);
+                if(x_trk>1.5&&x_trk<3.5)  h1mpa5->Fill(dxh[j]);
+                if(y_trk<yInt1[1]) h1mpaL->Fill(clustersPosition[j]);                         
+                if(y_trk>=yInt1[1]) h1mpaU->Fill(clustersPosition[j]);
+              }
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13mbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){              
+                h1mbpa->Fill(dxh[j]);
+                hcmbpa->Fill(polarity*clustersCharge[j]);
+              }    
+            }
+          }
+        } 
+      }
+   }
+   if(writeEventsWithMissinhHitsToFile) myfile.close();
+
+   int i1 = h1->FindBin(-0.3);
+   int i2 = h1->FindBin(0.3);
+   cout << "Number of track - DUT hit matchs: " << h1->Integral(i1,i2) << endl;
+   cout << "Ry = " << Ry << endl;
+   
+   
+   TString r1 = Form("%6.3f < Y < %6.3f mm",yInt1[0], yInt1[1]);
+   TString r2 = Form("%6.3f < Y < %6.3f mm ",yInt2[0], yInt2[1]);
+   TString r3 = Form("%6.3f < Y < %6.3f mm",yInt3[0], yInt3[1]);   
+
+
+   TF1 *funchole = new TF1("funchole","[0]+[1]*x+[2]*x*x",-8.0,8.0);
+   funchole->SetParameters(holeQuadPar[0],holeQuadPar[1],holeQuadPar[2]);
+   funchole->SetLineColor(4);
+   funchole->SetLineWidth(2);
+   cout << "Hole Parameters: " << holeQuadPar[0] << " " << holeQuadPar[1] << " " << holeQuadPar[2] << endl;
+   
+   gStyle->SetOptStat(1000000001);
+   gStyle->SetOptFit(0011);
+   gStyle->SetStatH(0.05);
+   gStyle->SetStatW(0.2);
+
+   addGraphics(h3b, 1, "X_{trk} [mm]", "Y_{trk} [mm] ");
+   h3b->GetXaxis()->SetRangeUser(-5,5);
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+
+   TCanvas *c = new TCanvas("c","Residuals",1500,1000);
+   c->Divide(4,3);
+   c->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h2, 1, "X_{trk} [mm]", "X_{DUT} [mm]");
+   double dM = yMax;
+   if(xMax>dM) dM = xMax;
+   h2->GetXaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->GetYaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->SetMinimum(1);
+   h2->Draw();
+
+   c->cd(2)->SetLeftMargin(0.13);;
+   addGraphics(h1, 1, "#DeltaX [mm]", "");
+   addGraphics(h1z, 2, "#DeltaX [mm]", "");
+   addGraphics(h1a, 3, "#DeltaX [mm]", "");
+   addGraphics(h1b, 6, "#DeltaX [mm]", "");
+   h1->GetXaxis()->SetRangeUser(-0.3,0.3);
+   if(m_board.Contains("A1")) h1->GetXaxis()->SetRangeUser(-1.5,1.5);
+   h1->SetMaximum(1.2*h1->GetMaximum());
+   h1->Draw();   
+   //h1z->Draw("same");
+   h1a->Draw("same");
+   h1b->Draw("same");
+   TLine *l1 = new TLine(-stripPitch/2.,0,-stripPitch/2.,0.5*h1->GetMaximum());
+   TLine *l2 = new TLine(stripPitch/2,0,stripPitch/2,0.5*h1->GetMaximum());
+   TLine *l1a = new TLine(-dxWin,0,-dxWin,0.5*h1->GetMaximum());
+   TLine *l2a = new TLine(dxWin,0,dxWin,0.5*h1->GetMaximum());
+   l1->SetLineColor(kRed); l2->SetLineColor(kRed);
+   l1a->SetLineColor(kBlue); l2a->SetLineColor(kBlue); l1a->SetLineWidth(2); l2a->SetLineWidth(2);
+   l1->Draw(); l2->Draw();
+   //l1a->Draw(); l2a->Draw();
+
+   TLegend* legend3 = new TLegend(0.15,0.70,0.40,0.89);
+   legend3->SetFillStyle(0);
+   legend3->SetBorderSize(0);
+   legend3->SetFillStyle(0);
+   legend3->SetTextSize(0.045);
+   
+   legend3->AddEntry(h1,"All","L"); 
+   //legend3->AddEntry(h1z,"ADC < 250","L"); 
+   legend3->AddEntry(h1a,"1-strip","L"); 
+   legend3->AddEntry(h1b,"2-strip","L"); 
+   legend3->Draw();
+   
+   c->cd(3)->SetLeftMargin(0.13);;
+   addGraphics(h8, 1, "#theta_{X}^{trk} [mrad]", "#DeltaX [mm]");
+   h8->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h8->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h8->Draw();
+   c->cd(4)->SetLeftMargin(0.13);;
+   addGraphics(h9, 1, "Y^{trk} [mm]", "#DeltaX [mm]");
+   h9->GetXaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h9->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9->Draw();
+   c->cd(5)->SetLeftMargin(0.13);;
+   addGraphics(h9a, 1, "X^{trk} [mm]", "#DeltaX [mm]");
+   h9a->GetXaxis()->SetRangeUser(-4,4);   
+   h9a->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9a->Draw();
+
+   c->cd(6)->SetLeftMargin(0.13);;
+   addGraphics(h3, 1, "X_{trk} [mm]", "Y_{trk} [mm]");
+   h3->GetXaxis()->SetRangeUser(xMin-1,xMax+1);   
+   h3->GetYaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h3->Draw();
+   if(holeQuadPar[0]!=0) funchole->Draw("same");
+   if(fabs(xLeftHole)<900 && fabs(xRightHole)<900){
+     TBox *b1 = new TBox(xMin,yMin,xLeftHole,yMax);
+     TBox *b2 = new TBox(xRightHole,yMin,xMax,yMax);
+     b1->SetLineColor(kBlue); b1->SetLineWidth(2);b1->SetFillStyle(0);   
+     b1->Draw();
+     b2->SetLineColor(kBlue); b2->SetLineWidth(2);b2->SetFillStyle(0);   
+     b2->Draw();
+   }else{   
+     TBox *b = new TBox(xMin,yMin,xMax,yMax);
+     b->SetLineColor(kBlue); b->SetLineWidth(2);b->SetFillStyle(0);   
+     b->Draw();
+   }
+   
+
+   c->cd(7)->SetLeftMargin(0.13);;
+   addGraphics(h5, 1, "#theta_{X}^{trk} [mrad]", "");
+   h5->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h5->Draw();
+   h5c->SetLineColor(2); h5c->Draw("same");
+   TLine *l1b = new TLine(txMin,0,txMin,h5->GetMaximum());
+   TLine *l2b = new TLine(txMax,0,txMax,h5->GetMaximum());
+   l1b->SetLineColor(kBlue); l2b->SetLineColor(kBlue); l1b->SetLineWidth(2); l2b->SetLineWidth(2);
+   l1b->Draw(); l2b->Draw();
+
+   c->cd(8)->SetLeftMargin(0.13);
+   addGraphics(h6, 1, "#theta_{Y}^{trk} [mrad]", "");
+   h6->GetXaxis()->SetRangeUser(tyMin-0.1,tyMax+0.1);   
+   h6->Draw();
+   h6c->SetLineColor(2); h6c->Draw("same");
+   TLine *l1c = new TLine(tyMin,0,tyMin,h6->GetMaximum());
+   TLine *l2c = new TLine(tyMax,0,tyMax,h6->GetMaximum());
+   l1c->SetLineColor(kBlue); l2c->SetLineColor(kBlue); l1c->SetLineWidth(2); l2c->SetLineWidth(2);   
+   l1c->Draw(); l2c->Draw();
+   
+   c->cd(9)->SetLeftMargin(0.13);;
+   addGraphics(h4, 1, "Strip # with cluster", "");
+   addGraphics(h4a, 2, "Strip # with cluster", "");
+   h4->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   h4a->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   double vmax = h4a->GetMaximum();
+   //for(int ii=iLo; ii<=iHi;ii++){
+   //  if(h4a->GetBinContent(ii)>vmax) vmax = h4a->GetBinContent(ii);
+   //}
+   h4->SetMaximum(1.25*vmax);
+   TLine *l1d = new TLine(iLo,0,iLo,0.75*h4a->GetMaximum());
+   TLine *l2d = new TLine(iHi,0,iHi,0.75*h4a->GetMaximum());
+   l1d->SetLineColor(kBlue); l2d->SetLineColor(kBlue); l1d->SetLineWidth(2); l2d->SetLineWidth(2);   
+   h4->Draw();
+   h4a->Draw("same");
+   l1d->Draw(); l2d->Draw();
+   
+   TLegend* legend4 = new TLegend(0.15,0.70,0.94,0.89);
+   legend4->SetFillStyle(0);
+   legend4->SetBorderSize(0);
+   legend4->SetFillStyle(0);
+   legend4->SetTextSize(0.045);
+   
+   legend4->AddEntry(h4,"Sensor strip ch #","L"); 
+   legend4->AddEntry(h4a,"Electr. ch #","L");
+
+   legend4->Draw();
+
+
+   c->cd(10)->SetLeftMargin(0.13);;
+   addGraphics(hcAll, 1, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk1, 3, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk2, 6, "Cluster charge [ADC]", "");
+   hcAll->SetMaximum(1.25*hcAll->GetMaximum());
+   hcAll->Draw();
+   hcTrk->SetLineColor(kBlue); hcTrk->SetLineWidth(2);
+   hcTrk->Draw("same"); 
+   hcTrk1->Draw("same"); 
+   hcTrk2->Draw("same"); 
+  
+   TLegend* legend2 = new TLegend(0.15,0.70,0.94,0.89);
+   legend2->SetFillStyle(0);
+   legend2->SetBorderSize(0);
+   legend2->SetFillStyle(0);
+   legend2->SetTextSize(0.045);
+   
+   legend2->AddEntry(hcAll,"All clusters, trk in Fid","L"); 
+   legend2->AddEntry(hcTrk,"Clusters, |#DeltaX|<200 #mum, trk in Fid.","L");
+   legend2->AddEntry(hcTrk1,"1-strip Clusters","L");
+   legend2->AddEntry(hcTrk2,"2-strip Clusters","L");
+
+   legend2->Draw();
+
+   
+
+   c->cd(11)->SetLeftMargin(0.13);;
+   addGraphics(h10a, 1, "Strip #", "<ADC>");
+   addGraphics(h10b, 2, "Strip #", "<ADC>");
+   addGraphics(h10c, 4, "Strip #", "<ADC>");
+   int ixl = iLo;
+   int ixh = iHi;
+   int yh = hcTrk->GetMean()-50;
+   h10a->GetXaxis()->SetRangeUser(ixl-2,ixh+2);   
+   h10a->GetYaxis()->SetRangeUser(yh-200,yh+300);
+   /*
+   h10a->Draw();
+   h10b->SetLineColor(2);h10b->SetMarkerColor(2);
+   h10b->Draw("same");
+   h10c->SetLineColor(4);h10c->SetMarkerColor(4);
+   h10c->Draw("same");
+
+   TLegend* legend1 = new TLegend(0.25,0.75,0.94,0.89);
+   legend1->SetFillStyle(0);
+   legend1->SetBorderSize(0);
+   legend1->SetFillStyle(0);
+   legend1->SetTextSize(0.045);
+   
+   legend1->AddEntry(h10a,"Top half in Y","LEP"); 
+   legend1->AddEntry(h10b,"Bottom half in Y","LEP"); 
+   legend1->AddEntry(h10c,"Top 2 mm in Y","LEP"); 
+   legend1->Draw();
+   */
+   addGraphics(h35, 1, "#DUT clusters", "Entries");   
+   h35->GetYaxis()->SetTitleOffset(1.2);
+   h35->Draw();
+
+   c->cd(12)->SetLeftMargin(0.13);;
+   addGraphics(h2p, 1, "TDC time / 2.5 ns", "<ADC>");
+   h2p->Draw();
+   TLine *l1e = new TLine(tdcLo,0,tdcLo,h2p->GetMaximum());
+   TLine *l2e = new TLine(tdcHi,0,tdcHi,h2p->GetMaximum());
+   l1e->SetLineColor(kBlue); l2e->SetLineColor(kBlue); l1e->SetLineWidth(2); l2e->SetLineWidth(2);   
+   l1e->Draw(); l2e->Draw();
+
+   c->Print("Plots/plot_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+   //return;
+   
+
+
+   TCanvas *c4 = new TCanvas("c4","Plot 4",800,600);
+   c4->Divide(2,2);
+   c4->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12en, 1, "X_{trk} [mm]", "");
+   addGraphics(h12fn, 1, "X_{trk} [mm]", "");
+
+   TH1F *hepa1 = (TH1F*)h12en->Clone("hepa1");
+   TH1F *hepa2 = (TH1F*)h12fn->Clone("hepa2");
+   TH1F *henpa = (TH1F*)h12gn->Clone("henpa");
+   hepa1->Divide(h12en,h12ed,1.0,1.0,"B");
+   hepa2->Divide(h12fn,h12fd,1.0,1.0,"B");
+   henpa->Divide(h12gn,h12gd,1.0,1.0,"B");
+   addGraphics(hepa1, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   addGraphics(hepa2, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+   h3b->Draw();
+
+   c4->cd(2)->SetLeftMargin(0.13);
+   hepa1->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa1->SetMinimum(0.0);
+   hepa1->SetMaximum(1.2);
+   hepa1->SetLineWidth(1);
+   hepa1->SetTitle(r1);
+   hepa1->Draw("hist");
+   c4->cd(3)->SetLeftMargin(0.13);
+   hepa2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa2->SetMinimum(0.0);
+   hepa2->SetMaximum(1.2);
+   hepa2->SetLineWidth(1);
+   hepa2->SetTitle(r2);
+   hepa2->Draw("hist");
+
+   c4->cd(4)->SetLeftMargin(0.13);
+   addGraphics(henpa, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   henpa->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   henpa->SetMinimum(0.0);
+   henpa->SetMaximum(1.2);
+   henpa->SetLineWidth(1);
+   henpa->SetTitle(r3);
+   henpa->Draw("hist");   
+
+
+   TCanvas *c5 = new TCanvas("c5","Plot 5",800,600);
+   c5->Divide(2,2);
+   c5->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12hn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12in, 1, "Rel. Strip Pos", "");
+   addGraphics(h12jn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12kn, 1, "Rel. Strip Pos", "");
+
+   TH1F *hepas1 = (TH1F*)h12hn->Clone("hepas1");
+   TH1F *hepas2 = (TH1F*)h12in->Clone("hepas2");
+   TH1F *hepas3 = (TH1F*)h12jn->Clone("hepas3");
+   TH1F *hepas4 = (TH1F*)h12kn->Clone("hepas4");
+   hepas1->Divide(h12hn,h12hd,1.0,1.0,"B");
+   hepas2->Divide(h12in,h12id,1.0,1.0,"B");
+   hepas3->Divide(h12jn,h12jd,1.0,1.0,"B");
+   hepas4->Divide(h12kn,h12kd,1.0,1.0,"B");
+   addGraphics(hepas1, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas2, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas3, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas4, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   hepas1->SetTitle("Full Beam Spot");
+   hepas1->SetMinimum(0.8);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetLineWidth(1);
+   hepas1->Draw("hist");
+   c5->cd(2)->SetLeftMargin(0.13);
+   hepas2->SetTitle(r1);
+   hepas2->SetMinimum(0.8);
+   hepas2->SetMaximum(1.2);
+   hepas2->SetLineWidth(1);
+   hepas2->Draw("hist");
+   c5->cd(3)->SetLeftMargin(0.13);
+   hepas3->SetTitle(r2);
+   hepas3->SetMinimum(0.8);
+   hepas3->SetMaximum(1.2);
+   hepas3->SetLineWidth(1);
+   hepas3->Draw("hist");
+   c5->cd(4)->SetLeftMargin(0.13);
+   hepas4->SetTitle(r3);
+   hepas4->SetMinimum(0.8);
+   hepas4->SetMaximum(1.2);
+   hepas4->SetLineWidth(1);
+   hepas4->Draw("hist");
+
+   c5->Print("Plots/plot5_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   //return;
+   
+
+   TCanvas *c1 = new TCanvas("c1","Plot 1",1600,800);
+   c1->Divide(3,2);
+
+   c1->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h10d, 2, "Y_{trk} [mm]", "<ADC>");
+   h10d->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h10d->Draw();
+
+   //c1->cd(2)->SetLeftMargin(0.13);
+   //h3b->Draw();   
+
+   c1->cd(2)->SetLeftMargin(0.13);
+   addGraphics(h12b, 2, "Y_{trk} [mm]", "");
+   addGraphics(h12a, 1, "Y_{trk} [mm]", "");
+   h12a->SetMaximum(1.2*h12a->GetMaximum());
+   h12a->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h12a->Draw("hist");
+   h12b->Draw("hist,same");
+
+   TLegend* legend0 = new TLegend(0.15,0.75,0.94,0.89);
+   legend0->SetFillStyle(0);
+   legend0->SetBorderSize(0);
+   legend0->SetFillStyle(0);
+   legend0->SetTextSize(0.045);   
+   legend0->AddEntry(h12a,"Track Y pos","LEP"); 
+   legend0->AddEntry(h12b,"Track Y pos with good cluster","LEP");
+   legend0->Draw();
+
+   c1->cd(3)->SetLeftMargin(0.13);
+   TH1F *he = (TH1F*)h12b->Clone("he");
+   he->Divide(h12b,h12a,1.0,1.0,"B");
+   float bw = 1000*h12b->GetBinWidth(1);
+   TString yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he, 1, "Y_{trk} [mm]", yt);
+   he->SetTitle("DUT Efficiency vs Y_{trk}");
+   he->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   he->SetMinimum(0.8);
+   he->SetMaximum(1.1);
+   he->Draw("e");
+
+   c1->cd(4)->SetLeftMargin(0.13);
+   addGraphics(h10e, 2, "X_{trk} [mm]", "<ADC>");
+   h10e->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h10e->Draw();
+
+   c1->cd(5)->SetLeftMargin(0.13);
+   addGraphics(h12dd, 2, "X_{trk} [mm]", "");
+   addGraphics(h12dn, 1, "X_{trk} [mm]", "");
+   h12dd->SetMaximum(1.2*h12dd->GetMaximum());
+   h12dd->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h12dd->Draw("hist");
+   h12dn->Draw("hist,same");
+
+   c1->cd(6)->SetLeftMargin(0.13);
+   TH1F *he2 = (TH1F*)h12dn->Clone("he");
+   he2->Divide(h12dn,h12dd,1.0,1.0,"B");
+   bw = 1000*h12dd->GetBinWidth(1);
+   yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he2, 1, "X_{trk} [mm]", yt);
+   he2->SetTitle("DUT Efficiency vs X_{trk}");
+   he2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   he2->SetMinimum(0.8);
+   he2->SetMaximum(1.1);
+   he2->Draw("e");
+   c1->Print("Plots/plot1_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+   TCanvas *c8 = new TCanvas("c8","Plot 8",800,400);
+   c8->Divide(2,1);
+   TH1F *he4 = (TH1F*)h15c->Clone("Eff_trigger-DUT_time");
+   he4->Divide(h15c,h16c,1.0,1.0,"B");
+   yt = "#Good DUT hit / # Track";
+   addGraphics(h16c, 1, "DUT time - Track Time (ns)", "Entries");
+   addGraphics(he4, 1, "DUT time - Track Time (ns)", "Efficiency");
+   c8->cd(1)->SetLeftMargin(0.15);;
+   c8->cd(1)->SetRightMargin(0.05);;
+   h16c->Draw();
+   c8->cd(2)->SetLeftMargin(0.13);;
+   c8->cd(2)->SetRightMargin(0.05);;
+   he4->Draw();
+   c8->Print("Plots/plot8_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");   
+
+   if(holeSector){
+     TCanvas *c7 = new TCanvas("c7","Plot 7",800,800);
+     c7->SetLeftMargin(0.13);
+     TH1F *he3 = (TH1F*)h12on->Clone("Erf()_fit");
+     he3->Divide(h12on,h12od,1.0,1.0,"B");
+     bw = 1000*h12od->GetBinWidth(1);
+     yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+     addGraphics(he3, 1, "Dist to cutout [mm]", yt);
+     he3->SetStats(kTRUE);
+     he3->SetTitle("DUT Efficiency vs Dist to Cutout");
+     he3->GetXaxis()->SetRangeUser(-0.2,2.0);
+     he3->GetYaxis()->SetRangeUser(0.0,1.3);
+     he3->Draw("e");
+     TLatex *myLatex = new TLatex();
+     myLatex->SetTextFont(42); myLatex->SetTextColor(1); 
+     myLatex->SetTextAlign(12); myLatex->SetNDC(kTRUE); myLatex->SetTextSize(0.047);
+     TString text = "Sector "+m_sector;
+     c7->cd();
+     myLatex->DrawLatex(0.18,0.8,text);
+     
+     TF1 *f4a = new TF1("f4a","0.5*[0]*(1+TMath::Erf((x-[1])/[2]))",-0.1,2.0);
+     f4a->SetParameters(0.5,0.0,0.04);
+     f4a->SetParNames("Const","Mean","Sigma");
+     he3->Fit("f4a","R");
+     TPad *inset = new TPad("inset","y vx x",0.44,0.1,0.89,0.55);
+     inset->SetLeftMargin(0.13);
+     inset->SetRightMargin(0.05);
+     h3->SetTitle("");
+     inset->Draw();
+     inset->cd();
+     h3->Draw();
+     h3b->SetMarkerSize(0.2);h3b->SetMarkerStyle(20);h3b->SetMarkerColor(kRed); 
+     h3b->Draw("same");
+     if(holeQuadPar[0]!=0) funchole->Draw("same");   
+     
+     c7->Print("Plots/plot7_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");   
+   }
+   
+   /*
+   TCanvas *c2 = new TCanvas("c2","Plot 2",1600,600);
+   c2->Divide(5,2);
+   addGraphics(h1mpa, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, No Match Clu");
+   addGraphics(h1mbpa, 4, "X_{clu}-X_{trk} [mm]", ""); h1mbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, No Match Clu");
+   addGraphics(h1fpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, Match Clu");
+   addGraphics(h1fbpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, Match Clu");
+
+   addGraphics(h1mpa1, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa1->SetTitle("2.8<Y_{trk}<4.1 mm, -3.5<X_{trk}<-2.0 mm, No Match Clu");
+   addGraphics(h1mpa2, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa2->SetTitle("2.8<Y_{trk}<4.1 mm, -2.0<X_{trk}<-1.0 mm, No Match Clu");
+   addGraphics(h1mpa3, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa3->SetTitle("2.8<Y_{trk}<4.1 mm, -1.0<X_{trk}<0.0 mm, No Match Clu");
+   addGraphics(h1mpa4, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa4->SetTitle("2.8<Y_{trk}<4.1 mm,  0.0<X_{trk}<1.0 mm, No Match Clu");
+   addGraphics(h1mpa5, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa5->SetTitle("2.8<Y_{trk}<4.1 mm,  1.5<X_{trk}<3.5 mm, No Match Clu");
+   h1mpa->SetLineWidth(1); 
+   h1mpa1->SetLineWidth(1); 
+   h1mpa2->SetLineWidth(1); 
+   h1mpa3->SetLineWidth(1); 
+   h1mpa4->SetLineWidth(1); 
+   h1mpa5->SetLineWidth(1); 
+   h1fpa->SetLineWidth(1); 
+   h1fbpa->SetLineWidth(1); 
+
+   
+   h1fpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1fbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa1->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa2->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa3->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa4->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa5->GetXaxis()->SetRangeUser(-3,9); 
+
+   c2->cd(1);
+   h3b->Draw();   
+   double xl[5] = {-3.5, -2.0, -1.0, 0.0, 1.5};
+   double xh[5] = {-2.0, -1.0,  0.0, 1.0, 3.5};
+   
+   
+   for(int i=0;i<5;i++){
+     TBox *b = new TBox(xl[i],yInt1[0],xh[i],yInt2[1]);
+     b->SetLineColor(2); b->SetFillStyle(0);b->SetLineWidth(2);
+     b->Draw();
+   }
+   TBox *b = new TBox(xl[0],yInt3[0],xh[4],yInt3[1]);
+   b->SetLineColor(4);b->SetFillStyle(0);b->SetLineWidth(2);
+   b->Draw();
+   
+
+
+   c2->cd(2);
+   h1mpa->Draw();   
+   c2->cd(3);
+   h1fpa->GetYaxis()->SetRangeUser(0,30);
+   h1fpa->Draw();   
+   c2->cd(4);
+   h1mbpa->Draw();   
+   c2->cd(5);
+   h1fbpa->GetYaxis()->SetRangeUser(0,30);
+   h1fbpa->Draw();   
+   c2->cd(6);   
+   h1mpa1->Draw();   
+   c2->cd(7);
+   h1mpa2->Draw();   
+   c2->cd(8);
+   h1mpa3->Draw();   
+   c2->cd(9);
+   h1mpa4->Draw();   
+   c2->cd(10);
+   h1mpa5->Draw();
+   c2->Print("Plots/plot2_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   /*
+   TCanvas *c3 = new TCanvas("c3","Plot 3",800,600);
+   c3->Divide(1,2);
+   c3->cd(1);
+   h1mpaU->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaU->Draw();
+   c3->cd(2);
+   h1mpaL->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaL->Draw();   
+   c3->Print("Plots/plot3_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   addGraphics(h12m,1,"Interstrip Pos","<ADC>");
+   addGraphics(h12n,1,"Interstrip Pos","<Cluster Size>");
+   TCanvas *c6 = new TCanvas("c6","Plot 6",1200,400);
+   c6->Divide(3,1);
+   c6->cd(1);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetMinimum(0.5);
+   hepas1->Draw();
+   c6->cd(2);
+   h12m->SetMinimum(0);
+   h12m->SetMaximum(1.2*h12m->GetMaximum());
+   h12m->Draw();
+   c6->cd(3);
+   h12n->SetMinimum(0.5);
+   h12n->SetMaximum(2.0);
+   h12n->Draw();
+   
+   c6->Print("Plots/plot6_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+
+
+   fout->Write();
+  
+}
+
+void ClusterTrackAnalysis::addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  h->SetMarkerSize(0.7);
+  h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void ClusterTrackAnalysis::addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  //float bw = h->GetBinWidth(1);
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  //h->SetMarkerSize(0.7);
+  //h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+TString ClusterTrackAnalysis::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector){
+
+  TString tag = "";
+
+  if(board.Contains("A6")){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+      if ( bias == "250" ) tag = "B6-A-213-8359";
+      if ( bias == "200" ) tag = "B6-A-214-8361";
+      if ( bias == "150" ) tag = "B6-A-215-8362";
+      if ( bias == "100" ) tag = "B6-A-216-8363";
+      if ( bias == "75" )  tag = "B6-A-219-8365";
+      if ( bias == "50" )  tag = "B6-A-220-8366";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+      if ( bias == "250" ) tag = "B6-A-245-8392";
+      if ( bias == "200" ) tag = "B6-A-246-8393";
+      if ( bias == "150" ) tag = "B6-A-247-8394";
+      if ( bias == "100" ) tag = "B6-A-248-8395";
+      if ( bias == "75" )  tag = "B6-A-249-8396";
+      if ( bias == "50" )  tag = "B6-A-250-8397";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+      if ( bias == "250" ) tag = "B6-A-294-8426";
+      if ( bias == "200" ) tag = "B6-A-295-8427";
+      if ( bias == "150" ) tag = "B6-A-296-8428";
+      if ( bias == "100" ) tag = "B6-A-297-8429";
+      if ( bias == "75" )  tag = "B6-A-298-8430";
+      if ( bias == "50" )  tag = "B6-A-299-8431";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+      if ( bias == "250" ) tag = "B6-A-327-8453";
+      if ( bias == "200" ) tag = "B6-A-328-8454";
+      if ( bias == "150" ) tag = "B6-A-329-8455";
+      if ( bias == "100" ) tag = "B6-A-330-8456";
+      if ( bias == "75" )  tag = "B6-A-331-8457";
+      if ( bias == "50" )  tag = "B6-A-332-8458";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-378-8494";
+      if ( bias == "250" ) tag = "B6-A-381-8497";
+      if ( bias == "200" ) tag = "B6-A-382-8498";
+      if ( bias == "150" ) tag = "B6-A-383-8499";
+      if ( bias == "100" ) tag = "B6-A-384-8500";
+      if ( bias == "75" )  tag = "B6-A-385-8501";
+      if ( bias == "50" )  tag = "B6-A-386-8502";
+    } else if(sector == "6"){
+      if ( bias == "300" ) tag = "B6-A-408-8523";
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+      if ( bias == "200" ) tag = "B6-A-410-8525";
+      if ( bias == "150" ) tag = "B6-A-411-8526";
+      if ( bias == "100" ) tag = "B6-A-412-8527";
+      if ( bias == "75" )  tag = "B6-A-413-8528";
+      if ( bias == "50" )  tag = "B6-A-414-8529";
+    }
+  } else if (board.Contains("A4")) {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+      if(bias == "350" ) tag = "B4-A-211-8553";
+      if(bias == "300" ) tag = "B4-A-212-8554";
+      if(bias == "250" ) tag = "B4-A-213-8555";
+      if(bias == "200" ) tag = "B4-A-214-8556";
+      if(bias == "150" ) tag = "B4-A-215-8557";
+      if(bias == "100" ) tag = "B4-A-216-8558";
+      if(bias == "75" )  tag = "B4-A-217-8559";
+      if(bias == "50" )  tag = "B4-A-218-8560";
+    }else if(sector == "2") {
+      if(bias == "400" ) tag = "B4-A-242-8583";
+      if(bias == "350" ) tag = "B4-A-243-8584";
+      if(bias == "300" ) tag = "B4-A-246-8586";
+      if(bias == "250" ) tag = "B4-A-247-8587";
+      if(bias == "200" ) tag = "B4-A-248-8588";
+      if(bias == "150" ) tag = "B4-A-249-8589";
+      if(bias == "100" ) tag = "B4-A-250-8590";
+      if(bias == "75" )  tag = "B4-A-251-8591";
+      if(bias == "50" )  tag = "B4-A-252-8592";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+      if(bias == "350" ) tag = "B4-A-276-8616";
+      if(bias == "300" ) tag = "B4-A-277-8617";
+      if(bias == "250" ) tag = "B4-A-278-8618";
+      if(bias == "200" ) tag = "B4-A-279-8619";
+      if(bias == "150" ) tag = "B4-A-280-8620";
+      if(bias == "100" ) tag = "B4-A-281-8621";
+      if(bias == "75" )  tag = "B4-A-282-8622";
+      if(bias == "50" )  tag = "B4-A-283-8623";
+    } else if(sector == "4"){
+      if(bias == "400" ) tag = "B4-A-217-8651";
+      if(bias == "350" ) tag = "B4-A-218-8652";
+      if(bias == "300" ) tag = "B4-A-219-8653";
+      if(bias == "250" ) tag = "B4-A-220-8654";
+      if(bias == "200" ) tag = "B4-A-221-8655";
+      if(bias == "150" ) tag = "B4-A-222-8656";
+      if(bias == "100" ) tag = "B4-A-223-8657";
+      if(bias == "75" )  tag = "B4-A-224-8658";
+      if(bias == "50" )  tag = "B4-A-225-8659";
+    } else if(sector == "5"){
+      if(bias == "400" ) tag = "B4-A-246-8680";
+      if(bias == "350" ) tag = "B4-A-247-8681";
+      if(bias == "300" ) tag = "B4-A-248-8682";
+      if(bias == "250" ) tag = "B4-A-249-8683";
+      if(bias == "200" ) tag = "B4-A-250-8684";
+      if(bias == "150" ) tag = "B4-A-251-8685";
+      if(bias == "100" ) tag = "B4-A-252-8686";
+      if(bias == "75" )  tag = "B4-A-253-8687";
+      if(bias == "50" )  tag = "B4-A-254-8688";
+    } else if(sector == "6"){
+      if(bias == "400" ) tag = "B4-A-227-8711";
+      if(bias == "350" ) tag = "B4-A-228-8712";
+      if(bias == "300" ) tag = "B4-A-229-8713";
+      if(bias == "250" ) tag = "B4-A-230-8714";
+      if(bias == "200" ) tag = "B4-A-231-8715";
+      if(bias == "150" ) tag = "B4-A-232-8716";
+      if(bias == "100" ) tag = "B4-A-233-8717";
+      if(bias == "75" )  tag = "B4-A-234-8718";
+      if(bias == "50" )  tag = "B4-A-235-8719";
+      tag = tag.ReplaceAll("B4","B1");
+    }
+  } else if (board.Contains("A8")) {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+      if(bias == "400") tag = "B8-A-297-13333";
+      if(bias == "350") tag = "B8-A-298-13334";
+      if(bias == "300") tag = "B8-A-299-13335";
+      if(bias == "250") tag = "B8-A-300-13336";
+      if(bias == "200") tag = "B8-A-301-13337";
+      if(bias == "150") tag = "B8-A-302-13338";
+      if(bias == "100") tag = "B8-A-303-13339";
+      if(bias == "75")  tag = "B8-A-304-13340";
+      if(bias == "50")  tag = "B8-A-305-13341";
+      if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399";
+      if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400";
+    }else if (sector == "2"){
+      //if(bias == "500") tag = "B8-A-321-13354";
+      if(bias == "400") tag = "B8-A-324-13355";
+      if(bias == "350") tag = "B8-A-325-13356";
+      if(bias == "300") tag = "B8-A-327-13357";
+      if(bias == "250") tag = "B8-A-328-13358";
+      if(bias == "200") tag = "B8-A-329-13359";
+      if(bias == "150") tag = "B8-A-330-13360";
+      if(bias == "100") tag = "B8-A-331-13361";
+      if(bias == "75")  tag = "B8-A-332-13362";
+      if(bias == "50") tag = "B8-A-333-13363";
+    }else if (sector == "3"){
+      //if(bias == "500") tag = "B8-A-358-13385";
+      if(bias == "400") tag = "B8-A-359-13386";
+      if(bias == "350") tag = "B8-A-360-13387";
+      if(bias == "300") tag = "B8-A-361-13388";
+      if(bias == "250") tag = "B8-A-365-13389";
+      if(bias == "200") tag = "B8-A-366-13390";
+      if(bias == "150") tag = "B8-A-367-13391";
+      if(bias == "100") tag = "B8-A-368-13392";
+      if(bias == "75")  tag = "B8-A-369-13393";
+      if(bias == "50")  tag = "B8-A-370-13394";
+    }else if (sector == "4"){
+      //if(bias == "500") tag = "B8-A-309-13344";
+      if(bias == "400") tag = "B8-A-311-13345";
+      if(bias == "350") tag = "B8-A-312-13346";
+      if(bias == "300") tag = "B8-A-314-13347";
+      if(bias == "250") tag = "B8-A-315-13348";
+      if(bias == "200") tag = "B8-A-316-13349";
+      if(bias == "150") tag = "B8-A-317-13350";
+      if(bias == "100") tag = "B8-A-318-13351";
+      if(bias == "75")  tag = "B8-A-319-13352";
+      if(bias == "50")  tag = "B8-A-320-13353";
+    }else if (sector == "5"){
+      //if(bias == "500") tag = "B8-A-334-13364";
+      if(bias == "400") tag = "B8-A-337-13365";
+      if(bias == "350") tag = "B8-A-339-13367";
+      if(bias == "300") tag = "B8-A-340-13368";
+      if(bias == "250") tag = "B8-A-341-13369";
+      if(bias == "200") tag = "B8-A-342-13370";
+      if(bias == "150") tag = "B8-A-343-13371";
+      if(bias == "100") tag = "B8-A-344-13372";
+      if(bias == "75")  tag = "B8-A-345-13373";
+      if(bias == "50")  tag = "B8-A-346-13374";
+      if(bias != "400") tag = tag.ReplaceAll("B8","B1");
+    }else if (sector == "6"){
+      //if(bias == "500") tag = "B8-A-347-13375";
+      if(bias == "400") tag = "B8-A-348-13376";
+      if(bias == "350") tag = "B8-A-349-13377";
+      if(bias == "300") tag = "B8-A-350-13378";
+      if(bias == "250") tag = "B8-A-352-13379";
+      if(bias == "200") tag = "B8-A-353-13380";
+      if(bias == "150") tag = "B8-A-354-13381";
+      if(bias == "100") tag = "B8-A-355-13382";
+      if(bias == "75")  tag = "B8-A-356-13383";
+      if(bias == "50")  tag = "B8-A-357-13384";
+      tag = tag.ReplaceAll("B8","B1");
+    }
+  } else if (board.Contains("D5")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B5-D-14-13066";
+      if(bias == "75") tag = "B5-D-13-13065";
+      if(bias == "100") tag = "B5-D-12-13064";
+      if(bias == "150") tag = "B5-D-11-13063";
+      if(bias == "200") tag = "B5-D-10-13062";
+      if(bias == "250") tag = "B5-D-6-13058";
+      if(bias == "300") tag = "B5-D-19-13071";
+      if(bias == "350") tag = "B5-D-4-13056";
+      if(bias == "400") tag = "B5-D-3-13055";
+      if(bias == "500") tag = "B5-D-16-13068";
+    }else if(sector == "2"){
+      if(bias == "50")  tag = "B5-D-119-13165";
+      if(bias == "75")  tag = "B5-D-118-13164";
+      if(bias == "100") tag = "B5-D-117-13163";
+      if(bias == "150") tag = "B5-D-116-13162";
+      if(bias == "200") tag = "B5-D-115-13161";
+      if(bias == "250") tag = "B5-D-114-13160";
+      if(bias == "300") tag = "B5-D-113-13159";
+      if(bias == "350") tag = "B5-D-111-13157";
+      if(bias == "400") tag = "B5-D-110-13156";
+      if(bias == "500") tag = "B5-D-109-13155";
+    }else if(sector == "3"){
+      if(bias == "50")  tag = "B5-D-167-13209";
+      if(bias == "75")  tag = "B5-D-166-13208";
+      if(bias == "100") tag = "B5-D-165-13207";
+      if(bias == "150") tag = "B5-D-164-13206";
+      if(bias == "200") tag = "B5-D-163-13205";
+      if(bias == "250") tag = "B5-D-162-13204";
+      if(bias == "300") tag = "B5-D-159-13202";
+      if(bias == "350") tag = "B5-D-158-13201";
+      if(bias == "400") tag = "B5-D-157-13200";
+      if(bias == "500") tag = "B5-D-156-13199";
+    }else if(sector == "4"){
+      if(bias == "50")  tag = "B5-D-65-13114";
+      if(bias == "75")  tag = "B5-D-64-13113";
+      if(bias == "100") tag = "B5-D-63-13112";
+      if(bias == "150") tag = "B5-D-62-13111";
+      if(bias == "200") tag = "B5-D-61-13110";
+      if(bias == "250") tag = "B5-D-59-13108";
+      if(bias == "300") tag = "B5-D-58-13107";
+      if(bias == "350") tag = "B5-D-57-13106";
+      if(bias == "400") tag = "B5-D-56-13105";
+      if(bias == "500") tag = "B5-D-55-13104";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B5-D-218-13253";
+      if(bias == "75")  tag = "B5-D-217-13252";
+      if(bias == "100") tag = "B5-D-216-13251";
+      if(bias == "150") tag = "B5-D-215-13250";
+      if(bias == "200") tag = "B5-D-214-13249";
+      if(bias == "250") tag = "B5-D-213-13248";
+      if(bias == "300") tag = "B5-D-212-13247";
+      if(bias == "350") tag = "B5-D-211-13246";
+      if(bias == "400") tag = "B5-D-210-13245";
+      if(bias == "500") tag = "B5-D-209-13244";
+    }else if(sector == "6"){
+      if(bias == "50")  tag = "B5-D-260-13294";
+      if(bias == "75")  tag = "B5-D-259-13293";
+      if(bias == "100") tag = "B5-D-258-13292";
+      if(bias == "150") tag = "B5-D-257-13291";
+      if(bias == "200") tag = "B5-D-256-13290";
+      if(bias == "250") tag = "B5-D-255-13289";
+      if(bias == "300") tag = "B5-D-254-13288";
+      if(bias == "350") tag = "B5-D-253-13287";
+      if(bias == "400") tag = "B5-D-252-13286";
+      if(bias == "500") tag = "B5-D-251-13285";
+    }
+  } else if (board.Contains("D7")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B1-D-347-9360";
+      if(bias == "75") tag = "B1-D-346-9359";
+      if(bias == "100") tag = "B1-D-344-9356";
+      if(bias == "150") tag = "B1-D-345-9357";
+      if(bias == "200") tag = "B1-D-343-9355";
+      if(bias == "300") tag = "B1-D-343-9354";
+      if(bias == "400") tag = "B1-D-341-9353";
+      if(bias == "500") tag = "B1-D-340-9272";
+    }else if(sector == "2"){
+      if(bias == "50") tag = "B1-D-471-9659";
+      if(bias == "75") tag = "B1-D-470-9658";
+      if(bias == "100") tag = "B1-D-469-9657";
+      if(bias == "150") tag = "B1-D-468-9656";
+      if(bias == "200") tag = "B1-D-467-9655";
+      if(bias == "300") tag = "B1-D-466-9654";
+      if(bias == "400") tag = "B1-D-465-9653";
+      if(bias == "500") tag = "B1-D-464-9652";
+    }else if(sector == "3"){
+      if(bias == "50") tag = "B1-D-472-9660";
+      if(bias == "75") tag = "B1-D-473-9661";
+      if(bias == "100") tag = "B1-D-474-9662";
+      if(bias == "150") tag = "B1-D-475-9663";
+      if(bias == "200") tag = "B1-D-476-9664";
+      if(bias == "300") tag = "B1-D-477-9665";
+      if(bias == "400") tag = "B1-D-478-9666";
+      if(bias == "500") tag = "B1-D-479-9667";
+    }else if(sector == "4"){
+      if(bias == "50") tag =  "B1-D-379-9424";
+      if(bias == "75") tag =  "B1-D-378-9423";
+      if(bias == "100") tag = "B1-D-377-9422";
+      if(bias == "150") tag = "B1-D-376-9421";
+      if(bias == "200") tag = "B1-D-375-9419";
+      if(bias == "300") tag = "B1-D-374-9417";
+      if(bias == "400") tag = "B1-D-373-9415";
+      if(bias == "500") tag = "B1-D-372-9413";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B1-D-489-9763";
+      if(bias == "75")  tag = "B1-D-488-9762";
+      if(bias == "100") tag = "B1-D-487-9761";
+      if(bias == "150") tag = "B1-D-484-9674";
+      if(bias == "200") tag = "B1-D-483-9673";
+      if(bias == "300") tag = "B1-D-482-9672";
+      if(bias == "400") tag = "B1-D-481-9671";
+      if(bias == "500") tag = "B1-D-480-9670";
+    }else if(sector == "6"){
+      if(bias == "50") tag =  "B1-D-321-9252";
+      if(bias == "75") tag =  "B1-D-320-9251";
+      if(bias == "100") tag = "B1-D-319-9250";
+      if(bias == "150") tag = "B1-D-318-9249";
+      if(bias == "200") tag = "B1-D-317-9248";
+      if(bias == "300") tag = "B1-D-316-9247";
+      if(bias == "400") tag = "B1-D-315-9246";
+      if(bias == "500") tag = "B1-D-314-9245";
+    }
+  } else if (board.Contains("A1")) {
+    if(sector == "1"){    
+      if(bias == "350") tag = "B1-A-1022-13947";
+      if(bias == "300") tag = "B1-A-1021-13946";
+      if(bias == "250") tag = "B1-A-1053-13971";
+      if(bias == "200") tag = "B1-A-1052-13970";
+      if(bias == "150") tag = "B1-A-1015-13939";
+      if(bias == "100") tag = "B1-A-1014-13938";
+      if(bias == "75")  tag = "B1-A-1013-13937";
+      if(bias == "50")  tag = "B1-A-1012-13936";
+    }else if(sector == "2"){
+      if(bias == "350") tag = "B1-A-1062-13980";
+      if(bias == "300") tag = "B1-A-1061-13979";
+      if(bias == "250") tag = "B1-A-1060-13978";
+      if(bias == "200") tag = "B1-A-1059-13977";
+      if(bias == "150") tag = "B1-A-1058-13976";
+      if(bias == "100") tag = "B1-A-1057-13975";
+      if(bias == "75")  tag = "B1-A-1056-13974";
+      if(bias == "50")  tag = "B1-A-1055-13973";
+    }    
+  } else if (board.Contains("A2")) {
+    if(sector == "1"){    
+      if(bias == "340") tag = "B2-A-1095-14030";
+      if(bias == "325") tag = "B2-A-1094-14029";
+      if(bias == "300") tag = "B2-A-1084-14017";
+      if(bias == "250") tag = "B2-A-1083-14016";
+      if(bias == "200") tag = "B2-A-1082-14015";
+      if(bias == "150") tag = "B2-A-1081-14014";
+      if(bias == "100") tag = "B2-A-1078-14013";
+      if(bias == "75")  tag = "B2-A-1077-14012";
+      if(bias == "50")  tag = "B2-A-1076-14011";
+      if(bias == "300" && angle=="-1") tag = "B2-A-1085-14018";
+      if(bias == "300" && angle=="1") tag = "B2-A-1088-14021";
+    }else if(sector == "2"){
+      if(bias == "340") tag = "B2-A-1099-14034";
+      if(bias == "325") tag = "B2-A-1098-14033";
+      if(bias == "300") tag = "B2-A-1097-14032";
+      if(bias == "250") tag = "B2-A-1100-14035";
+      if(bias == "200") tag = "B2-A-1101-14036";
+      if(bias == "150") tag = "B2-A-1102-14037";
+      if(bias == "100") tag = "B2-A-1103-14038";
+      if(bias == "75")  tag = "B2-A-1104-14039";
+      if(bias == "50")  tag = "B2-A-1105-14040";
+    }    
+  }
+
+  return tag;
+}
diff --git a/TbUT/scripts/ClusterTrackAnalysis.h b/TbUT/scripts/ClusterTrackAnalysis.h
new file mode 100644
index 0000000..80b4377
--- /dev/null
+++ b/TbUT/scripts/ClusterTrackAnalysis.h
@@ -0,0 +1,187 @@
+#include <string>
+//#include <TMath.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "TChain.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TFile.h"
+#include <TStyle.h>
+#include <TLine.h>
+#include <TLatex.h>
+#include <TF1.h>
+#include <vector>
+#include <map>
+#include <TLegend.h>
+#include <ctime>
+#include <cstdlib>
+#include <TString.h>
+#include <TCanvas.h>
+#include <CMS.h>
+using namespace std;
+
+class ClusterTrackAnalysis {
+
+ public:
+
+  ClusterTrackAnalysis();
+  ~ClusterTrackAnalysis();
+  ClusterTrackAnalysis(int biasVal);
+
+  // functions
+  // void Run();
+  void Loop();
+  void addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="");
+  void addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="");
+
+  
+  // just for testing
+  vector<int> test;
+
+  CMS *fCMS;
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+
+  //
+  const TString m_fileIndir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/"; 
+const TString m_fileOutDir = "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/";
+const TString m_board 	= "B6"; 
+const TString m_bias  	= "300";
+const TString m_sector	= "3"; 
+//=======
+//const TString m_fileIndir = "/data2/pmmannin/FullProcessing/"; 
+//const TString m_board 	= "A2"; 
+
+//TString m_bias  	= "300";
+//const TString m_sector	= "1"; 
+//const TString m_scanType = "Angle";
+const TString m_scanType = "Bias";
+const TString m_angle = "0";
+
+const TString m_fileOutdir = "~/lhcb/testbeam/"; 
+//>>>>>>> .r204986
+
+const TString plotdir 	= "plots";
+
+//<<<<<<< .mine
+//const TString f_out			= m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board + "_" + m_bias + "_" + m_sector + ".root"; 
+//const TString f_out			= "/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/Run_Bias_Scan-B6-A-299-8431.root"; 
+
+//=======
+//>>>>>>> .r204986
+const double nChan 			= 512.0;
+const double stripPitch = 0.190;
+
+const bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+const double trackTriggerTimeDiffCut = 2.5;   // Default = 2.5
+
+const bool isPType = true;
+
+const int kClusterChargeMin = 150;
+const double ratioForHole 	= 0.05;
+const double ratioForDeadStrip 	= 0.6;
+const double ratioForNoisyStrip = 1.8;
+const bool vetoDeadStripRegions = false;
+const double k_DeadStrip 				= 0.12;
+
+const double m_minDistFromHole = 0.05;
+const bool removeTracksInHoleDef = false;
+
+ Int_t           clusterNumberPerEvent;
+  UInt_t          clustersTDC;
+  ULong64_t       timestamps;
+  Double_t        clustersPosition[10];
+  Int_t           clustersSeedPosition[10];
+  Double_t        clustersCharge[10];
+  Int_t           clustersSize[10];
+  Double_t        clustersSeedCharge[10];
+  Double_t        clustersCharge2StripLeft[10];
+  Double_t        clustersCharge1StripLeft[10];
+  Double_t        clustersCharge1StripRight[10];
+  Double_t        clustersCharge2StripRight[10];
+  Double_t        dtime;
+   
+  Int_t           n_tp3_tracks;
+  vector<double>  *vec_trk_x;
+  vector<double>  *vec_trk_y;
+  vector<double>  *vec_trk_tx;
+  vector<double>  *vec_trk_ty;
+  vector<double>  *vec_trk_chi2ndf;
+
+  // List of branches
+  TBranch        *b_clusterNumberPerEvent;   //!
+  TBranch        *b_clustersTDC;   //!
+  TBranch        *b_timestamps;   //!
+  TBranch        *b_clustersPosition;   //!
+  TBranch        *b_clustersSeedPosition;   //!
+  TBranch        *b_clustersCharge;   //!
+  TBranch        *b_clustersSize;   //!
+  TBranch        *b_clustersSeedCharge;   //!
+  TBranch        *b_clustersCharge2StripLeft;   //!
+  TBranch        *b_clustersCharge1StripLeft;   //!
+  TBranch        *b_clustersCharge1StripRight;   //!
+  TBranch        *b_clustersCharge2StripRight;   //!
+  TBranch        *b_n_tp3_tracks;   //!
+  TBranch        *b_vec_trk_x;   //!
+  TBranch        *b_vec_trk_y;   //!
+  TBranch        *b_vec_trk_tx;   //!
+  TBranch        *b_vec_trk_ty;   //!
+  TBranch        *b_vec_trk_chi2ndf;   //!
+  TBranch        *b_dtime;   //!
+
+  //double stripPitch;
+  double z_DUT;
+  double Rz;
+  double Ry;
+  double dxWin;
+  double xGloOff;
+  double yGloOff;
+  double xOff;
+  
+
+  float iLo, iHi;
+  float tdcLo, tdcHi;
+  float yMin,yMax;
+  float xMin,xMax;
+  float yMid, yHi2;
+  float tyMin,tyMax;
+  float txMin,txMax;
+  Int_t skipChannel[512];
+  double xLeftHole;
+  double xRightHole;
+  
+  Int_t lowEdge, hiEdge;
+  Double_t stripGap[4];
+  Double_t deadRegionLo[20];
+  Double_t deadRegionHi[20];
+  Int_t nDeadRegion;  
+
+  double yInt1[2];
+  double yInt2[2];
+  double yInt3[2];
+
+  float polarity;
+
+  TH1F *hMeanNoise; 
+  TH1F *hWidthNoise; 
+
+  double holeQuadPar[3];
+  bool removeTracksInHole;
+  double minDistFromHole;
+  bool holeSector;
+  bool correctForZRotation;
+
+  double chargeCorrSlopeOdd;
+  double chargeCorrSlopeEven;
+  
+  double noise[512];
+
+  double channelOffset;  
+
+
+};
+
diff --git a/TbUT/scripts/ClusterTrackAnalysis.h~ b/TbUT/scripts/ClusterTrackAnalysis.h~
new file mode 100644
index 0000000..1f9f341
--- /dev/null
+++ b/TbUT/scripts/ClusterTrackAnalysis.h~
@@ -0,0 +1,474 @@
+#include <string>
+//#include <TMath.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include "TChain.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TFile.h"
+#include <TStyle.h>
+#include <TLine.h>
+#include <TLatex.h>
+#include <TF1.h>
+#include <vector>
+#include <map>
+#include <TLegend.h>
+#include <ctime>
+#include <cstdlib>
+#include <TString.h>
+#include <TCanvas.h>
+using namespace std;
+
+class ClusterTrackAnalysis {
+
+ public:
+
+  ClusterTrackAnalysis();
+  ~ClusterTrackAnalysis();
+  ClusterTrackAnalysis(int biasVal);
+
+  // functions
+  // void Run();
+  void Loop();
+  void addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="");
+  void addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="");
+
+  
+  // just for testing
+  vector<int> test;
+
+  CMS *fCMS;
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+
+
+};
+
+/* ClusterTrackAnalysis::ClusterTrackAnalysis(int biasVal) { */
+
+/*  TString filename; */
+/*   if(biasVal != 0) m_bias = Form("%d",biasVal); */
+/*   TTree* tree = 0; */
+  
+/*    if (tree == 0) { */
+/*      // */
+/*      // lhcb-dev */
+/*      // */
+/*      TString scanType = "Run_Bias"; */
+/*      filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root";  */
+/*      if(m_scanType.Contains("Angle")){ */
+/*        scanType = "Run_Angle"; */
+/*        filename = m_fileIndir+"Board"+m_board+"_Angle/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root";  */
+/*      } */
+     
+/*      cout << "===> Opening file: " << filename << endl; */
+     
+
+/*      // lxplus */
+/*      // */
+/*      //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1 */
+/*      //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2 */
+/*      //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3 */
+/*      //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6 */
+/*      // */
+
+/*      TFile *f = new TFile(filename); */
+/*      tree = (TTree*)f->Get("Clusters"); */
+/*      TH1F *hn = (TH1F*)f->Get("hWidthNoise"); */
+/*      for(int i=0;i<nChan;i++){ */
+/*        noise[i] = hn->GetBinContent(i+1); */
+/*      } */
+
+/*      // Get mean noise and width */
+/*      hMeanNoise 	= (TH1F*)f->Get("hMeanNoise");  */
+/*      hWidthNoise 	= (TH1F*)f->Get("hWidthNoise");  */
+/*      cout << "===> Opening file: " << filename << endl; */
+
+/*      TString filename2 = filename.ReplaceAll("_Tracks",""); */
+/*      TFile * f2 = new TFile(filename2); */
+/*      if(f2) { */
+/*        TTree * tree2 = (TTree*) f2->Get("TbUT/CMS"); */
+/*        if(tree2) { */
+/*          tree->AddFriend(tree2); */
+/*          fCMS = new CMS(tree2); */
+/*        }else{ */
+/*          fCMS=0;   */
+/*        } */
+/*      } else { */
+/*        cout << "WARNING: Could not find CMS data file: " << filename2 << endl; */
+/*        fCMS =0 ; */
+/*      } */
+/*    } */
+/*    Init(tree); */
+
+/* } */
+
+//ClusterTrackAnalysis::~ClusterTrackAnalysis()
+//{
+//  if (!fChain) return;
+//  delete fChain->GetCurrentFile();
+//}
+/* TString ClusterTrackAnalysis::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) { */
+
+/*   TString tag = ""; */
+
+/*   if(board.Contains("A6")){ */
+/*     if(sector == "1") { */
+/*       if ( bias == "300" ) tag = "B6-A-212-8358"; */
+/*       if ( bias == "250" ) tag = "B6-A-213-8359"; */
+/*       if ( bias == "200" ) tag = "B6-A-214-8361"; */
+/*       if ( bias == "150" ) tag = "B6-A-215-8362"; */
+/*       if ( bias == "100" ) tag = "B6-A-216-8363"; */
+/*       if ( bias == "75" )  tag = "B6-A-219-8365"; */
+/*       if ( bias == "50" )  tag = "B6-A-220-8366"; */
+/*     } else if(sector == "2"){ */
+/*       if ( bias == "300" ) tag = "B6-A-242-8389"; */
+/*       if ( bias == "250" ) tag = "B6-A-245-8392"; */
+/*       if ( bias == "200" ) tag = "B6-A-246-8393"; */
+/*       if ( bias == "150" ) tag = "B6-A-247-8394"; */
+/*       if ( bias == "100" ) tag = "B6-A-248-8395"; */
+/*       if ( bias == "75" )  tag = "B6-A-249-8396"; */
+/*       if ( bias == "50" )  tag = "B6-A-250-8397"; */
+/*     } else if(sector == "3"){ */
+/*       if ( bias == "300" ) tag = "B6-A-293-8425"; */
+/*       if ( bias == "250" ) tag = "B6-A-294-8426"; */
+/*       if ( bias == "200" ) tag = "B6-A-295-8427"; */
+/*       if ( bias == "150" ) tag = "B6-A-296-8428"; */
+/*       if ( bias == "100" ) tag = "B6-A-297-8429"; */
+/*       if ( bias == "75" )  tag = "B6-A-298-8430"; */
+/*       if ( bias == "50" )  tag = "B6-A-299-8431"; */
+/*     } else if(sector == "4"){ */
+/*       if ( bias == "300" ) tag = "B6-A-326-8452"; */
+/*       if ( bias == "250" ) tag = "B6-A-327-8453"; */
+/*       if ( bias == "200" ) tag = "B6-A-328-8454"; */
+/*       if ( bias == "150" ) tag = "B6-A-329-8455"; */
+/*       if ( bias == "100" ) tag = "B6-A-330-8456"; */
+/*       if ( bias == "75" )  tag = "B6-A-331-8457"; */
+/*       if ( bias == "50" )  tag = "B6-A-332-8458"; */
+/*     } else if(sector == "5"){ */
+/*       if ( bias == "300" ) tag = "B6-A-378-8494"; */
+/*       if ( bias == "250" ) tag = "B6-A-381-8497"; */
+/*       if ( bias == "200" ) tag = "B6-A-382-8498"; */
+/*       if ( bias == "150" ) tag = "B6-A-383-8499"; */
+/*       if ( bias == "100" ) tag = "B6-A-384-8500"; */
+/*       if ( bias == "75" )  tag = "B6-A-385-8501"; */
+/*       if ( bias == "50" )  tag = "B6-A-386-8502"; */
+/*     } else if(sector == "6"){ */
+/*       if ( bias == "300" ) tag = "B6-A-408-8523"; */
+/*       if ( bias == "250" ) tag = "B6-A-409-8524"; */
+/*       if ( bias == "200" ) tag = "B6-A-410-8525"; */
+/*       if ( bias == "150" ) tag = "B6-A-411-8526"; */
+/*       if ( bias == "100" ) tag = "B6-A-412-8527"; */
+/*       if ( bias == "75" )  tag = "B6-A-413-8528"; */
+/*       if ( bias == "50" )  tag = "B6-A-414-8529"; */
+/*     } */
+/*   } else if (board.Contains("A4")) { */
+/*     if(sector == "1") { */
+/*       if(bias == "400" ) tag = "B4-A-210-8552"; */
+/*       if(bias == "350" ) tag = "B4-A-211-8553"; */
+/*       if(bias == "300" ) tag = "B4-A-212-8554"; */
+/*       if(bias == "250" ) tag = "B4-A-213-8555"; */
+/*       if(bias == "200" ) tag = "B4-A-214-8556"; */
+/*       if(bias == "150" ) tag = "B4-A-215-8557"; */
+/*       if(bias == "100" ) tag = "B4-A-216-8558"; */
+/*       if(bias == "75" )  tag = "B4-A-217-8559"; */
+/*       if(bias == "50" )  tag = "B4-A-218-8560"; */
+/*     }else if(sector == "2") { */
+/*       if(bias == "400" ) tag = "B4-A-242-8583"; */
+/*       if(bias == "350" ) tag = "B4-A-243-8584"; */
+/*       if(bias == "300" ) tag = "B4-A-246-8586"; */
+/*       if(bias == "250" ) tag = "B4-A-247-8587"; */
+/*       if(bias == "200" ) tag = "B4-A-248-8588"; */
+/*       if(bias == "150" ) tag = "B4-A-249-8589"; */
+/*       if(bias == "100" ) tag = "B4-A-250-8590"; */
+/*       if(bias == "75" )  tag = "B4-A-251-8591"; */
+/*       if(bias == "50" )  tag = "B4-A-252-8592"; */
+/*     } else if(sector == "3"){ */
+/*       if(bias == "400" ) tag = "B4-A-275-8615"; */
+/*       if(bias == "350" ) tag = "B4-A-276-8616"; */
+/*       if(bias == "300" ) tag = "B4-A-277-8617"; */
+/*       if(bias == "250" ) tag = "B4-A-278-8618"; */
+/*       if(bias == "200" ) tag = "B4-A-279-8619"; */
+/*       if(bias == "150" ) tag = "B4-A-280-8620"; */
+/*       if(bias == "100" ) tag = "B4-A-281-8621"; */
+/*       if(bias == "75" )  tag = "B4-A-282-8622"; */
+/*       if(bias == "50" )  tag = "B4-A-283-8623"; */
+/*     } else if(sector == "4"){ */
+/*       if(bias == "400" ) tag = "B4-A-217-8651"; */
+/*       if(bias == "350" ) tag = "B4-A-218-8652"; */
+/*       if(bias == "300" ) tag = "B4-A-219-8653"; */
+/*       if(bias == "250" ) tag = "B4-A-220-8654"; */
+/*       if(bias == "200" ) tag = "B4-A-221-8655"; */
+/*       if(bias == "150" ) tag = "B4-A-222-8656"; */
+/*       if(bias == "100" ) tag = "B4-A-223-8657"; */
+/*       if(bias == "75" )  tag = "B4-A-224-8658"; */
+/*       if(bias == "50" )  tag = "B4-A-225-8659"; */
+/*     } else if(sector == "5"){ */
+/*       if(bias == "400" ) tag = "B4-A-246-8680"; */
+/*       if(bias == "350" ) tag = "B4-A-247-8681"; */
+/*       if(bias == "300" ) tag = "B4-A-248-8682"; */
+/*       if(bias == "250" ) tag = "B4-A-249-8683"; */
+/*       if(bias == "200" ) tag = "B4-A-250-8684"; */
+/*       if(bias == "150" ) tag = "B4-A-251-8685"; */
+/*       if(bias == "100" ) tag = "B4-A-252-8686"; */
+/*       if(bias == "75" )  tag = "B4-A-253-8687"; */
+/*       if(bias == "50" )  tag = "B4-A-254-8688"; */
+/*     } else if(sector == "6"){ */
+/*       if(bias == "400" ) tag = "B4-A-227-8711"; */
+/*       if(bias == "350" ) tag = "B4-A-228-8712"; */
+/*       if(bias == "300" ) tag = "B4-A-229-8713"; */
+/*       if(bias == "250" ) tag = "B4-A-230-8714"; */
+/*       if(bias == "200" ) tag = "B4-A-231-8715"; */
+/*       if(bias == "150" ) tag = "B4-A-232-8716"; */
+/*       if(bias == "100" ) tag = "B4-A-233-8717"; */
+/*       if(bias == "75" )  tag = "B4-A-234-8718"; */
+/*       if(bias == "50" )  tag = "B4-A-235-8719"; */
+/*       tag = tag.ReplaceAll("B4","B1"); */
+/*     } */
+/*   } else if (board.Contains("A8")) { */
+/*     if(sector == "1"){ */
+/*       if(bias == "500") tag = "B8-A-296-13332"; */
+/*       if(bias == "400") tag = "B8-A-297-13333"; */
+/*       if(bias == "350") tag = "B8-A-298-13334"; */
+/*       if(bias == "300") tag = "B8-A-299-13335"; */
+/*       if(bias == "250") tag = "B8-A-300-13336"; */
+/*       if(bias == "200") tag = "B8-A-301-13337"; */
+/*       if(bias == "150") tag = "B8-A-302-13338"; */
+/*       if(bias == "100") tag = "B8-A-303-13339"; */
+/*       if(bias == "75")  tag = "B8-A-304-13340"; */
+/*       if(bias == "50")  tag = "B8-A-305-13341"; */
+/*       if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399"; */
+/*       if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400"; */
+/*     }else if (sector == "2"){ */
+/*       //if(bias == "500") tag = "B8-A-321-13354"; */
+/*       if(bias == "400") tag = "B8-A-324-13355"; */
+/*       if(bias == "350") tag = "B8-A-325-13356"; */
+/*       if(bias == "300") tag = "B8-A-327-13357"; */
+/*       if(bias == "250") tag = "B8-A-328-13358"; */
+/*       if(bias == "200") tag = "B8-A-329-13359"; */
+/*       if(bias == "150") tag = "B8-A-330-13360"; */
+/*       if(bias == "100") tag = "B8-A-331-13361"; */
+/*       if(bias == "75")  tag = "B8-A-332-13362"; */
+/*       if(bias == "50") tag = "B8-A-333-13363"; */
+/*     }else if (sector == "3"){ */
+/*       //if(bias == "500") tag = "B8-A-358-13385"; */
+/*       if(bias == "400") tag = "B8-A-359-13386"; */
+/*       if(bias == "350") tag = "B8-A-360-13387"; */
+/*       if(bias == "300") tag = "B8-A-361-13388"; */
+/*       if(bias == "250") tag = "B8-A-365-13389"; */
+/*       if(bias == "200") tag = "B8-A-366-13390"; */
+/*       if(bias == "150") tag = "B8-A-367-13391"; */
+/*       if(bias == "100") tag = "B8-A-368-13392"; */
+/*       if(bias == "75")  tag = "B8-A-369-13393"; */
+/*       if(bias == "50")  tag = "B8-A-370-13394"; */
+/*     }else if (sector == "4"){ */
+/*       //if(bias == "500") tag = "B8-A-309-13344"; */
+/*       if(bias == "400") tag = "B8-A-311-13345"; */
+/*       if(bias == "350") tag = "B8-A-312-13346"; */
+/*       if(bias == "300") tag = "B8-A-314-13347"; */
+/*       if(bias == "250") tag = "B8-A-315-13348"; */
+/*       if(bias == "200") tag = "B8-A-316-13349"; */
+/*       if(bias == "150") tag = "B8-A-317-13350"; */
+/*       if(bias == "100") tag = "B8-A-318-13351"; */
+/*       if(bias == "75")  tag = "B8-A-319-13352"; */
+/*       if(bias == "50")  tag = "B8-A-320-13353"; */
+/*     }else if (sector == "5"){ */
+/*       //if(bias == "500") tag = "B8-A-334-13364"; */
+/*       if(bias == "400") tag = "B8-A-337-13365"; */
+/*       if(bias == "350") tag = "B8-A-339-13367"; */
+/*       if(bias == "300") tag = "B8-A-340-13368"; */
+/*       if(bias == "250") tag = "B8-A-341-13369"; */
+/*       if(bias == "200") tag = "B8-A-342-13370"; */
+/*       if(bias == "150") tag = "B8-A-343-13371"; */
+/*       if(bias == "100") tag = "B8-A-344-13372"; */
+/*       if(bias == "75")  tag = "B8-A-345-13373"; */
+/*       if(bias == "50")  tag = "B8-A-346-13374"; */
+/*       if(bias != "400") tag = tag.ReplaceAll("B8","B1"); */
+/*     }else if (sector == "6"){ */
+/*       //if(bias == "500") tag = "B8-A-347-13375"; */
+/*       if(bias == "400") tag = "B8-A-348-13376"; */
+/*       if(bias == "350") tag = "B8-A-349-13377"; */
+/*       if(bias == "300") tag = "B8-A-350-13378"; */
+/*       if(bias == "250") tag = "B8-A-352-13379"; */
+/*       if(bias == "200") tag = "B8-A-353-13380"; */
+/*       if(bias == "150") tag = "B8-A-354-13381"; */
+/*       if(bias == "100") tag = "B8-A-355-13382"; */
+/*       if(bias == "75")  tag = "B8-A-356-13383"; */
+/*       if(bias == "50")  tag = "B8-A-357-13384"; */
+/*       tag = tag.ReplaceAll("B8","B1"); */
+/*     } */
+/*   } else if (board.Contains("D5")) { */
+/*     if(sector == "1"){ */
+/*       if(bias == "50") tag = "B5-D-14-13066"; */
+/*       if(bias == "75") tag = "B5-D-13-13065"; */
+/*       if(bias == "100") tag = "B5-D-12-13064"; */
+/*       if(bias == "150") tag = "B5-D-11-13063"; */
+/*       if(bias == "200") tag = "B5-D-10-13062"; */
+/*       if(bias == "250") tag = "B5-D-6-13058"; */
+/*       if(bias == "300") tag = "B5-D-19-13071"; */
+/*       if(bias == "350") tag = "B5-D-4-13056"; */
+/*       if(bias == "400") tag = "B5-D-3-13055"; */
+/*       if(bias == "500") tag = "B5-D-16-13068"; */
+/*     }else if(sector == "2"){ */
+/*       if(bias == "50")  tag = "B5-D-119-13165"; */
+/*       if(bias == "75")  tag = "B5-D-118-13164"; */
+/*       if(bias == "100") tag = "B5-D-117-13163"; */
+/*       if(bias == "150") tag = "B5-D-116-13162"; */
+/*       if(bias == "200") tag = "B5-D-115-13161"; */
+/*       if(bias == "250") tag = "B5-D-114-13160"; */
+/*       if(bias == "300") tag = "B5-D-113-13159"; */
+/*       if(bias == "350") tag = "B5-D-111-13157"; */
+/*       if(bias == "400") tag = "B5-D-110-13156"; */
+/*       if(bias == "500") tag = "B5-D-109-13155"; */
+/*     }else if(sector == "3"){ */
+/*       if(bias == "50")  tag = "B5-D-167-13209"; */
+/*       if(bias == "75")  tag = "B5-D-166-13208"; */
+/*       if(bias == "100") tag = "B5-D-165-13207"; */
+/*       if(bias == "150") tag = "B5-D-164-13206"; */
+/*       if(bias == "200") tag = "B5-D-163-13205"; */
+/*       if(bias == "250") tag = "B5-D-162-13204"; */
+/*       if(bias == "300") tag = "B5-D-159-13202"; */
+/*       if(bias == "350") tag = "B5-D-158-13201"; */
+/*       if(bias == "400") tag = "B5-D-157-13200"; */
+/*       if(bias == "500") tag = "B5-D-156-13199"; */
+/*     }else if(sector == "4"){ */
+/*       if(bias == "50")  tag = "B5-D-65-13114"; */
+/*       if(bias == "75")  tag = "B5-D-64-13113"; */
+/*       if(bias == "100") tag = "B5-D-63-13112"; */
+/*       if(bias == "150") tag = "B5-D-62-13111"; */
+/*       if(bias == "200") tag = "B5-D-61-13110"; */
+/*       if(bias == "250") tag = "B5-D-59-13108"; */
+/*       if(bias == "300") tag = "B5-D-58-13107"; */
+/*       if(bias == "350") tag = "B5-D-57-13106"; */
+/*       if(bias == "400") tag = "B5-D-56-13105"; */
+/*       if(bias == "500") tag = "B5-D-55-13104"; */
+/*     }else if(sector == "5"){ */
+/*       if(bias == "50")  tag = "B5-D-218-13253"; */
+/*       if(bias == "75")  tag = "B5-D-217-13252"; */
+/*       if(bias == "100") tag = "B5-D-216-13251"; */
+/*       if(bias == "150") tag = "B5-D-215-13250"; */
+/*       if(bias == "200") tag = "B5-D-214-13249"; */
+/*       if(bias == "250") tag = "B5-D-213-13248"; */
+/*       if(bias == "300") tag = "B5-D-212-13247"; */
+/*       if(bias == "350") tag = "B5-D-211-13246"; */
+/*       if(bias == "400") tag = "B5-D-210-13245"; */
+/*       if(bias == "500") tag = "B5-D-209-13244"; */
+/*     }else if(sector == "6"){ */
+/*       if(bias == "50")  tag = "B5-D-260-13294"; */
+/*       if(bias == "75")  tag = "B5-D-259-13293"; */
+/*       if(bias == "100") tag = "B5-D-258-13292"; */
+/*       if(bias == "150") tag = "B5-D-257-13291"; */
+/*       if(bias == "200") tag = "B5-D-256-13290"; */
+/*       if(bias == "250") tag = "B5-D-255-13289"; */
+/*       if(bias == "300") tag = "B5-D-254-13288"; */
+/*       if(bias == "350") tag = "B5-D-253-13287"; */
+/*       if(bias == "400") tag = "B5-D-252-13286"; */
+/*       if(bias == "500") tag = "B5-D-251-13285"; */
+/*     } */
+/*   } else if (board.Contains("D7")) { */
+/*     if(sector == "1"){ */
+/*       if(bias == "50") tag = "B1-D-347-9360"; */
+/*       if(bias == "75") tag = "B1-D-346-9359"; */
+/*       if(bias == "100") tag = "B1-D-344-9356"; */
+/*       if(bias == "150") tag = "B1-D-345-9357"; */
+/*       if(bias == "200") tag = "B1-D-343-9355"; */
+/*       if(bias == "300") tag = "B1-D-343-9354"; */
+/*       if(bias == "400") tag = "B1-D-341-9353"; */
+/*       if(bias == "500") tag = "B1-D-340-9272"; */
+/*     }else if(sector == "2"){ */
+/*       if(bias == "50") tag = "B1-D-471-9659"; */
+/*       if(bias == "75") tag = "B1-D-470-9658"; */
+/*       if(bias == "100") tag = "B1-D-469-9657"; */
+/*       if(bias == "150") tag = "B1-D-468-9656"; */
+/*       if(bias == "200") tag = "B1-D-467-9655"; */
+/*       if(bias == "300") tag = "B1-D-466-9654"; */
+/*       if(bias == "400") tag = "B1-D-465-9653"; */
+/*       if(bias == "500") tag = "B1-D-464-9652"; */
+/*     }else if(sector == "3"){ */
+/*       if(bias == "50") tag = "B1-D-472-9660"; */
+/*       if(bias == "75") tag = "B1-D-473-9661"; */
+/*       if(bias == "100") tag = "B1-D-474-9662"; */
+/*       if(bias == "150") tag = "B1-D-475-9663"; */
+/*       if(bias == "200") tag = "B1-D-476-9664"; */
+/*       if(bias == "300") tag = "B1-D-477-9665"; */
+/*       if(bias == "400") tag = "B1-D-478-9666"; */
+/*       if(bias == "500") tag = "B1-D-479-9667"; */
+/*     }else if(sector == "4"){ */
+/*       if(bias == "50") tag =  "B1-D-379-9424"; */
+/*       if(bias == "75") tag =  "B1-D-378-9423"; */
+/*       if(bias == "100") tag = "B1-D-377-9422"; */
+/*       if(bias == "150") tag = "B1-D-376-9421"; */
+/*       if(bias == "200") tag = "B1-D-375-9419"; */
+/*       if(bias == "300") tag = "B1-D-374-9417"; */
+/*       if(bias == "400") tag = "B1-D-373-9415"; */
+/*       if(bias == "500") tag = "B1-D-372-9413"; */
+/*     }else if(sector == "5"){ */
+/*       if(bias == "50")  tag = "B1-D-489-9763"; */
+/*       if(bias == "75")  tag = "B1-D-488-9762"; */
+/*       if(bias == "100") tag = "B1-D-487-9761"; */
+/*       if(bias == "150") tag = "B1-D-484-9674"; */
+/*       if(bias == "200") tag = "B1-D-483-9673"; */
+/*       if(bias == "300") tag = "B1-D-482-9672"; */
+/*       if(bias == "400") tag = "B1-D-481-9671"; */
+/*       if(bias == "500") tag = "B1-D-480-9670"; */
+/*     }else if(sector == "6"){ */
+/*       if(bias == "50") tag =  "B1-D-321-9252"; */
+/*       if(bias == "75") tag =  "B1-D-320-9251"; */
+/*       if(bias == "100") tag = "B1-D-319-9250"; */
+/*       if(bias == "150") tag = "B1-D-318-9249"; */
+/*       if(bias == "200") tag = "B1-D-317-9248"; */
+/*       if(bias == "300") tag = "B1-D-316-9247"; */
+/*       if(bias == "400") tag = "B1-D-315-9246"; */
+/*       if(bias == "500") tag = "B1-D-314-9245"; */
+/*     } */
+/*   } else if (board.Contains("A1")) { */
+/*     if(sector == "1"){     */
+/*       if(bias == "350") tag = "B1-A-1022-13947"; */
+/*       if(bias == "300") tag = "B1-A-1021-13946"; */
+/*       if(bias == "250") tag = "B1-A-1053-13971"; */
+/*       if(bias == "200") tag = "B1-A-1052-13970"; */
+/*       if(bias == "150") tag = "B1-A-1015-13939"; */
+/*       if(bias == "100") tag = "B1-A-1014-13938"; */
+/*       if(bias == "75")  tag = "B1-A-1013-13937"; */
+/*       if(bias == "50")  tag = "B1-A-1012-13936"; */
+/*     }else if(sector == "2"){ */
+/*       if(bias == "350") tag = "B1-A-1062-13980"; */
+/*       if(bias == "300") tag = "B1-A-1061-13979"; */
+/*       if(bias == "250") tag = "B1-A-1060-13978"; */
+/*       if(bias == "200") tag = "B1-A-1059-13977"; */
+/*       if(bias == "150") tag = "B1-A-1058-13976"; */
+/*       if(bias == "100") tag = "B1-A-1057-13975"; */
+/*       if(bias == "75")  tag = "B1-A-1056-13974"; */
+/*       if(bias == "50")  tag = "B1-A-1055-13973"; */
+/*     }     */
+/*   } else if (board.Contains("A2")) { */
+/*     if(sector == "1"){     */
+/*       if(bias == "340") tag = "B2-A-1095-14030"; */
+/*       if(bias == "325") tag = "B2-A-1094-14029"; */
+/*       if(bias == "300") tag = "B2-A-1084-14017"; */
+/*       if(bias == "250") tag = "B2-A-1083-14016"; */
+/*       if(bias == "200") tag = "B2-A-1082-14015"; */
+/*       if(bias == "150") tag = "B2-A-1081-14014"; */
+/*       if(bias == "100") tag = "B2-A-1078-14013"; */
+/*       if(bias == "75")  tag = "B2-A-1077-14012"; */
+/*       if(bias == "50")  tag = "B2-A-1076-14011"; */
+/*       if(bias == "300" && angle=="-1") tag = "B2-A-1085-14018"; */
+/*       if(bias == "300" && angle=="1") tag = "B2-A-1088-14021"; */
+/*     }else if(sector == "2"){ */
+/*       if(bias == "340") tag = "B2-A-1099-14034"; */
+/*       if(bias == "325") tag = "B2-A-1098-14033"; */
+/*       if(bias == "300") tag = "B2-A-1097-14032"; */
+/*       if(bias == "250") tag = "B2-A-1100-14035"; */
+/*       if(bias == "200") tag = "B2-A-1101-14036"; */
+/*       if(bias == "150") tag = "B2-A-1102-14037"; */
+/*       if(bias == "100") tag = "B2-A-1103-14038"; */
+/*       if(bias == "75")  tag = "B2-A-1104-14039"; */
+/*       if(bias == "50")  tag = "B2-A-1105-14040"; */
+/*     }     */
+/*   } */
+
+/*   return tag; */
+/* } */
diff --git a/TbUT/scripts/ClusterTrackAnalysis_C.d b/TbUT/scripts/ClusterTrackAnalysis_C.d
new file mode 100644
index 0000000..a76647f
--- /dev/null
+++ b/TbUT/scripts/ClusterTrackAnalysis_C.d
@@ -0,0 +1,198 @@
+
+# DO NOT DELETE
+
+./ClusterTrackAnalysis_C.so: ClusterTrackAnalysis.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/string
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++config.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/os_defines.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/cpu_defines.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stringfwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/memoryfwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/char_traits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_algobase.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/functexcept.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/exception_defines.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/cpp_type_traits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/type_traits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/numeric_traits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_pair.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/move.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/concept_check.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_iterator_base_types.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_iterator_base_funcs.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/debug/debug.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_iterator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ptr_traits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/predefined_ops.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/postypes.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cwchar
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/allocator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++allocator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/new_allocator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/new
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/exception
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/atomic_lockfree_defines.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/localefwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++locale.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/clocale
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iosfwd
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cctype
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ostream_insert.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/cxxabi_forced.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_function.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/backward/binders.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/range_access.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_string.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/atomicity.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/gthr.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/gthr-default.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/atomic_word.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_string.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/sstream
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/istream
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ios
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ios_base.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_classes.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_classes.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/streambuf
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/streambuf.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_ios.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_facets.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cwctype
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/ctype_base.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/streambuf_iterator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/ctype_inline.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_facets.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_ios.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ostream
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ostream.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/istream.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/sstream.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iostream
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/fstream
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/codecvt.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cstdio
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/basic_file.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++io.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/fstream.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iomanip
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TChain.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TTree.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBranch.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TNamed.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TObject.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Rtypes.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RtypesCore.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RConfig.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RVersion.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/DllImport.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Rtypeinfo.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/typeinfo
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/snprintf.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/strlcpy.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/atomic
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/c++0x_warning.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/atomic_base.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TGenericClassInfo.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/vector
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_construct.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/alloc_traits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_uninitialized.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_vector.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_bvector.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/vector.tcc
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TSchemaHelper.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TStorage.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVersionCheck.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Riosfwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBuffer.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TString.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMathBase.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cstdlib
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cmath
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TObjArray.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TSeqCollection.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCollection.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TIterator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iterator
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stream_iterator.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttFill.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDataType.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDictionary.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/ESTLType.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttLine.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttMarker.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayD.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArray.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayI.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TClass.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TObjString.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/map
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_tree.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_map.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_multimap.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/set
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_set.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_multiset.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/unordered_set
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/ThreadLocalStorage.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RConfigure.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualTreePlayer.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TH1.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAxis.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttAxis.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayC.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayS.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayF.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Foption.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVectorFfwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVectorDfwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFitResultPtr.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TH2.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMatrixFBasefwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMatrixDBasefwd.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFile.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDirectoryFile.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDirectory.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TList.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDatime.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TUUID.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMap.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/THashTable.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TUrl.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TStyle.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttText.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TLine.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttBBox2D.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/GuiTypes.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TPoint.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TLatex.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TText.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TF1.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFormula.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBits.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Math/ParamFunctor.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TLegend.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TPave.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBox.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ctime
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCanvas.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TPad.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualPad.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttPad.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualX.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/utility
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_relops.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Buttons.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TQObject.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TQObjectEmitVA.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TQConnection.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Varargs.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TInterpreter.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualMutex.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttCanvas.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCanvasImp.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/work/c/cbetanco/LHCb/KeplerDev_v3r0/Tb/TbUT/scripts/CMS.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TROOT.h
+./ClusterTrackAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RVersion.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RConfig.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TClass.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDictAttributeMap.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TInterpreter.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TROOT.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBuffer.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMemberInspector.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TError.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RtypesImp.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TIsAProxy.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFileMergeInfo.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCollectionProxyInfo.h
+ClusterTrackAnalysis_C__ROOTBUILDVERSION= 6.02/05
diff --git a/TbUT/scripts/ClusterWithTrackAna.C b/TbUT/scripts/ClusterWithTrackAna.C
new file mode 100644
index 0000000..0c24254
--- /dev/null
+++ b/TbUT/scripts/ClusterWithTrackAna.C
@@ -0,0 +1,1217 @@
+#define ClusterWithTrackAna_cxx
+//#include "ClusterWithTrackAna_Inputs.h"
+#include "ClusterWithTrackAna.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TLatex.h>
+#include <TCanvas.h>
+#include <iostream>
+#include <fstream>
+
+
+
+void addGraphics(TH1 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  h->SetMarkerSize(0.7);
+  h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+void addGraphics(TH2 *h, int iCol = 1, TString XTitle="", TString YTitle="")
+{
+  //float bw = h->GetBinWidth(1);
+  h->SetXTitle(XTitle);
+  h->SetYTitle(YTitle);
+  h->SetStats(kFALSE);
+  h->SetLineColor(iCol);
+  h->SetMarkerColor(iCol);
+  h->SetMinimum(0.0);
+  h->SetMaximum(1.2*h->GetMaximum());
+  h->SetTitleSize(0.1);
+  
+  //h->SetLineColor(kBlack);
+  //h->SetMarkerSize(0.7);
+  //h->SetMarkerStyle(20);
+  h->GetXaxis()->SetTitleOffset(1.0);  
+  h->GetYaxis()->SetTitleOffset(1.2);
+  h->GetXaxis()->SetTitleSize(0.045);  
+  h->GetYaxis()->SetTitleSize(0.045);
+  h->GetXaxis()->SetLabelSize(0.04);  
+  h->GetYaxis()->SetLabelSize(0.04);  
+  h->SetNdivisions(505,"X");
+  h->SetNdivisions(505,"Y");
+  h->SetLineWidth(2);
+}
+
+
+void ClusterWithTrackAna::Loop()
+{
+//   In a ROOT session, you can do:
+//      Root > .L ClusterWithTrackAna.C
+//      Root > ClusterWithTrackAna t
+//      Root > t.GetEntry(12); // Fill t data members with entry number 12
+//      Root > t.Show();       // Show values of entry 12
+//      Root > t.Show(16);     // Read and show values of entry 16
+//      Root > t.Loop();       // Loop on all entries
+//
+
+//     This is the loop skeleton where:
+//    jentry is the global entry number in the chain
+//    ientry is the entry number in the current Tree
+//  Note that the argument to GetEntry must be:
+//    jentry for TChain::GetEntry
+//    ientry for TTree::GetEntry and TBranch::GetEntry
+//
+//       To read only selected branches, Insert statements like:
+// METHOD1:
+//    fChain->SetBranchStatus("*",0);  // disable all branches
+//    fChain->SetBranchStatus("branchname",1);  // activate branchname
+// METHOD2: replace line
+//    fChain->GetEntry(jentry);       //read all branches
+//by  b_branchname->GetEntry(ientry); //read only this branch
+   if (fChain == 0) return;
+
+   Int_t nentries = fChain->GetEntriesFast();
+
+   TString m_board2 = m_board;
+   m_board2 = m_board2.ReplaceAll("_All","");
+   m_board2 = m_board2.ReplaceAll("_Full","");
+   m_board2 = m_board2.ReplaceAll("_v7","");
+   TString f_out = m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + runplace + "_" + consR +"_"+m_runNumb+".root";
+
+   //TString f_out = m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + ".root";
+   if(m_angle != "0"){
+     f_out			= m_fileOutdir + plotdir + "/AnalysisOutput_" + m_board2 + "_" + m_bias + "_" + m_sector + "_" + m_angle + ".root";
+   }
+   cout << "Will write out file: " << f_out << endl;
+   
+
+
+   fout = new TFile(f_out,"RECREATE");
+
+   // cluster charge vs. channel
+   // TH2F* h_clst_chan = new TH2F("h_clst_chan","Cluster charge vs. seed channel",
+
+   // eff vs. x and y
+   //   TH2F* h_eff_xy = new TH2F("h_eff_xy","Efficiency vs. position",100,-8,8,100,-8,8);
+
+   TH1F* h0 = new TH1F("h0","#DeltaX between strip hit and track projection (strips)",101,-50.5,50.5);
+   TH1F* h1 = new TH1F("h1","#DeltaX",800,-2.0,2.0);
+   TH2F* h1vsx = new TH2F("h1vsx","#DeltaX vs X",50,-5,5,100,-0.2,0.2);
+   TH1F* h1mpa = new TH1F("h1mpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1mbpa = new TH1F("h1mbpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fpa = new TH1F("h1fpa","#DeltaX",400,-20.0,20.0);
+   TH1F* h1fbpa = new TH1F("h1fbpa","#DeltaX",400,-20.0,20.0);
+
+   TH1F* h1mpa1 = new TH1F("h1mpa1","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa2 = new TH1F("h1mpa2","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa3 = new TH1F("h1mpa3","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa4 = new TH1F("h1mpa4","#DeltaX",800,-20.0,20.0);
+   TH1F* h1mpa5 = new TH1F("h1mpa5","#DeltaX",800,-20.0,20.0);
+
+   TH1F* h1mpaL = new TH1F("h1mpaL","Strip# of Missed Hit in Lower PA region",512,0,512);
+   TH1F* h1mpaU = new TH1F("h1mpaU","Strip# of Missed Hit in Upper PA region",512,0,512);
+
+
+   TH1F* h1s = new TH1F("h1s","Seed strip of cluster",512,0.0,512.0);
+   TH1F* h1a = new TH1F("h1a","#DeltaX, 1 strip",800,-2.0,2.0);
+   TH1F* h1b = new TH1F("h1b","#DeltaX, 2 strip",800,-2.0,2.0);
+   TH1F* h1z = new TH1F("h1z","#DeltaX, low Charge",800,-2.0,2.0);
+   TH1F* h1w = new TH1F("h1w","#DeltaX",20000,-100.0,100.0);
+   TH1F* h1wY = new TH1F("h1wY","#DeltaX",20000,-100.0,100.0);
+   TH2F* h2 = new TH2F("h2","X_{DUT} vs X_{trk}",100,-8.0,8.0,100,-8,8);
+   TH2F* h3 = new TH2F("h3","Y_{trk} vs X_{trk}, with cluster",640,-8,8.0,640,-8,8);
+   TH2F* h311 = new TH2F("h311","Y_{trk} vs X_{trk}",32,-8,8.0,32,-8,8);
+   TH2F* h311a = new TH2F("h311a","Y_{trk} vs X_{trk}, with cluster",32,-8,8.0,32,-8,8);
+   // TH2F* h3a = new TH2F("h3a","Y_{trk} vs X_{trk} in fiducial",640,-8,8.0,640,-8,8);
+   // TH2F* h3b = new TH2F("h3b","Y_{trk} vs X_{trk}, with missed cluster",640,-8,8.0,640,-8,8);
+   // TH2F* h3c = new TH2F("h3c","Y_{trk} vs X_{trk}, with found cluster",640,-8,8.0,640,-8,8);
+   TH2F* h3a = new TH2F("h3a","Y_{trk} vs X_{trk} in fiducial",32,-3.6,3.6,32,-4,4);
+   TH2F* h3b = new TH2F("h3b","Y_{trk} vs X_{trk}, with missed cluster",160,-4,4.0,160,-4,4);
+   TH2F* h3c = new TH2F("h3c","Y_{trk} vs X_{trk}, with found cluster",32,-3.6,3.6,32,-4,4);
+   TH1F* h4 = new TH1F("h4","Detector strip # of cluster with track",512,0.0,512);
+   TH1F* h4a = new TH1F("h4a","Electonic Strip # of cluster with track",512,0.0,512);
+   TH1F* h4b = new TH1F("h4b","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h4c = new TH1F("h4c","Strip # of cluster with track",1024,0.0,1024);
+   TH1F* h5 = new TH1F("h5","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6 = new TH1F("h6","#theta_{Y}",25,-5.0,5.0);
+   TH1F* h5c = new TH1F("h5c","#theta_{X}",500,-5.0,5.0);
+   TH1F* h6c = new TH1F("h6c","#theta_{Y}",500,-5.0,5.0);
+   TH1F* h5a = new TH1F("h5a","X position of track",400,-10.0,10.0);
+   TH1F* h6a = new TH1F("h6a","Y position of track",25,-5.0,5.0);
+   TH1F* h5b = new TH1F("h5b","X position of matched cluster",400,-10.0,10.0);
+   TH1F* h6b = new TH1F("h6b","Y position of matched cluster",400,-10.0,10.0);
+   TH1F* h6d = new TH1F("h6d","Y position of matched cluster",400,-10.0,10.0);
+
+   TProfile *h8 = new TProfile("h8","#DeltaX vs #theta_{trk}",100,-5,5,-1.0,1.0);
+   TProfile *h9 = new TProfile("h9","#DeltaX vs Y_{trk} at DUT",1600,-8,8,-1.0,1.0);
+   TProfile *h9a = new TProfile("h9a","#DeltaX vs X_{trk} at DUT",20,-5,5,-1.0,1.0);
+
+   TProfile *h10a = new TProfile("h10a","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10b = new TProfile("h10b","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10c = new TProfile("h10c","<ADC> vs strip",512,0,512,0.0,1000.0);
+   TProfile *h10d = new TProfile("h10d","<ADC> vs Y_{trk}",100,-8,8,0.0,1000.0);
+   TProfile *h10e = new TProfile("h10e","<ADC> vs X_{trk}",100,-8,8,0.0,1000.0);
+   TH1F* h11n = new TH1F("h11n","Strip # of matched cluster",512,0.0,512);
+   TH1F* h11d = new TH1F("h11d","Strip # of track",512,0.0,512);
+   h11n->Sumw2();
+   h11d->Sumw2();
+   
+   TH1F* h12 = new TH1F("h12","Y position of matched cluster",400,-10.0,10.0); h12->Sumw2();
+   TH1F* h122 = new TH1F("h122","Y position of matched cluster",15,-7.0,7.0); h12->Sumw2();
+   TH1F* h123 = new TH1F("h123","y position of matched cluster",15,-7.0,7.0); h12->Sumw2();
+   TH1F* h12c = new TH1F("h12c","X position of matched cluster",400,-10.0,10.0);h12c->Sumw2();
+   TH1F* h12a = new TH1F("h12a","Y position of track",25,-5.0,5.0); h12a->Sumw2();
+   TH1F* h12b = new TH1F("h12b","Y position of track",1600,-10.0,10.0); h12b->Sumw2();
+
+   TH1F* h12dn = new TH1F("h12dn","X position of track",200,-10.0,10.0); h12dn->Sumw2();
+   TH1F* h12en = new TH1F("h12en","X position of track",200,-10.0,10.0);h12en->Sumw2();
+   TH1F* h12fn = new TH1F("h12fn","X position of track",200,-10.0,10.0);h12fn->Sumw2();
+   TH1F* h12gn = new TH1F("h12gn","X position of track",200,-10.0,10.0);h12gn->Sumw2();
+   TH1F* h12dd = new TH1F("h12dd","X position of track",200,-10.0,10.0);h12dd->Sumw2();
+   TH1F* h12ed = new TH1F("h12ed","X position of track",200,-10.0,10.0);h12ed->Sumw2();
+   TH1F* h12fd = new TH1F("h12fd","X position of track",200,-10.0,10.0);h12fd->Sumw2();
+   TH1F* h12gd = new TH1F("h12gd","X position of track",200,-10.0,10.0);h12gd->Sumw2();
+
+   TH1F* h12hn = new TH1F("h12hn","X position of track",50,-0.5,0.5);h12hn->Sumw2();
+   TH1F* h12in = new TH1F("h12in","X position of track",50,-0.5,0.5);h12in->Sumw2();
+   TH1F* h12jn = new TH1F("h12jn","X position of track",50,-0.5,0.5);h12jn->Sumw2();
+   TH1F* h12kn = new TH1F("h12kn","X position of track",50,-0.5,0.5);h12kn->Sumw2();
+   TH1F* h12hd = new TH1F("h12hd","X position of track",50,-0.5,0.5);h12hd->Sumw2();
+   TH1F* h12id = new TH1F("h12id","X position of track",50,-0.5,0.5);h12id->Sumw2();
+   TH1F* h12jd = new TH1F("h12jd","X position of track",50,-0.5,0.5);h12jd->Sumw2();
+   TH1F* h12kd = new TH1F("h12kd","X position of track",50,-0.5,0.5);h12kd->Sumw2();
+
+   TProfile *h12m = new TProfile("h12m","<ADC> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+   TProfile *h12n = new TProfile("h12n","<ClusterSize> vs interstrip pos",50,-0.5,0.5,0.0,1000.0);
+
+   TH1F* h12on = new TH1F("h12on","dist of track to cutout",700,-2.0,5.0);h12on->Sumw2();
+   TH1F* h12od = new TH1F("h12od","dist of track to cutout",700,-2.0,5.0);h12od->Sumw2();
+
+   TH1F *h13mpa = new TH1F("h13mpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13mbpa = new TH1F("h13mbpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fpa = new TH1F("h13fpa","#Clusters/Ev",10,-0.5,9.5);
+   TH1F *h13fbpa = new TH1F("h13fbpa","#Clusters/Ev",10,-0.5,9.5);   
+
+   TH1F* h14a = new TH1F("h14a","Nom Strip, no matched cluster",512,0.0,512);
+   TH1F* h14b = new TH1F("h14b","Nom Strip, matched cluster",512,0.0,512);
+
+   TH1F *h15a = new TH1F("h15a","Chisq of tracks with matched DUT hit",200,0.0,200.0);
+   TH1F *h15b = new TH1F("h15b","TDC time with matched DUT hit",12,0.0,12.0);
+   TH1F *h15c = new TH1F("h15c","Time Between Trigger and Track",5,0.0,5.0);
+   TH1F *h15d = new TH1F("h15d","TDC time of all clusters",12,0.0,12.0);
+   TH1F *h15e = new TH1F("h15e","TDC time of good clusters",12,0.0,12.0);
+
+   TH1F *h16a = new TH1F("h16a","Chisq of tracks without matched DUT hit",200,0.0,200.0);
+   TH1F *h16b = new TH1F("h16b","TDC time without matched DUT hit",12,0.0,12.0);
+   TH1F *h16c = new TH1F("h16c","Time Between Trigger and Track",5,0.0,5.0);
+   h15c->Sumw2();
+   h16c->Sumw2();
+   
+   TH1F* h17 = new TH1F("h17","Q_{L} / (Q_{L}+Q_{R})",50,0.0,1.0);
+   TH2F* h17a = new TH2F("h17a","Q_{L} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,120,-0.1,1.1);
+   TProfile* h17b = new TProfile("h17b","Q_{R} / (Q_{L}+Q_{R}) vs Interstrip Pos",20,-0.5,0.5,-0.1,1.1);
+
+   TH1F* hcmpa = new TH1F("hcmpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcmbpa = new TH1F("hcmbpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfpa = new TH1F("hcfpa","Cluster charge",100,0.0,1000.0);
+   TH1F* hcfbpa = new TH1F("hcfbpa","Cluster charge",100,0.0,1000.0);
+
+   TH1F* h18a = new TH1F("h18a","Seed/Total charge",100,0.0,2.0);
+
+   TH2F* h18b = new TH2F("h18b","#DeltaX vs Interstrip Pos (1 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18c = new TH2F("h18c","#DeltaX vs Interstrip Pos (2 strip Clu)",100,-0.5,0.5,100,-0.2,0.2);
+   TH2F* h18d = new TH2F("h18d","Seed/Total charge vs Interstrip Pos",100,-0.5,0.5,100,0.0,1.1);
+
+   TH1F* hcTrkXY[16];
+   for(int i=0; i<4; i++){
+     for(int j=0; j<4; j++){
+       int iblock = 4*i+j; 
+       TString hname = Form("hcTrkXY_%d",iblock+1);     
+       TString htitle = Form("Cluster charge, block %d",iblock+1);     
+       hcTrkXY[iblock]= new TH1F(hname,htitle,100,0.0,1000.0);
+     }
+   }
+   
+   TH1F *hlandau[512];
+   for(int i=0; i<nChan; i++){
+     hlandau[i] = new TH1F(Form("hlandau_%d",i),"Cluster charge",100,0.0,1000.0);
+   }
+   
+
+
+   TH1F* hcAll = new TH1F("hcAll","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrk = new TH1F("hcTrk","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkCorr = new TH1F("hcTrkCorr","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed = new TH1F("hcTrkSeed","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed1 = new TH1F("hcTrkSeed1","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkSeed2 = new TH1F("hcTrkSeed2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY1 = new TH1F("hcTrkY1","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY2 = new TH1F("hcTrkY2","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY3 = new TH1F("hcTrkY3","Cluster charge",100,0.0,1000.0);
+   //TH1F* hcTrkY4 = new TH1F("hcTrkY4","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkNoTop = new TH1F("hcTrkNoTop","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkLowX = new TH1F("hcTrkLowX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrkHighX = new TH1F("hcTrkHighX","Cluster charge",100,0.0,1000.0);
+   TH1F* hcTrka = new TH1F("hcTrka","Cluster charge, limited region",100,0.0,1000.0);
+   TH1F* hcTrk1 = new TH1F("hcTrk1","Cluster charge, Size = 1",100,0.0,1000.0);
+   TH1F* hcTrk2 = new TH1F("hcTrk2","Cluster charge, Size = 2",100,0.0,1000.0);
+   TProfile *h2p = new TProfile("h2p","Cluster Charge vs TDC time",12,0,12,100,1000);
+
+
+   TH2F* h31a = new TH2F("h31a","Y_{trk} vs X_{trk}, with cluster",64,-8,8.0,64,-8,8);
+   TH2F* h31b = new TH2F("h31b","Y_{trk} vs X_{trk}, with cluster, low ADC",64,-8,8.0,64,-8,8);
+   TH1F* h32a = new TH1F("h32a","Strip # of cluster with track",512,0.0,512);
+   TH1F* h32b = new TH1F("h32b","Strip # of cluster with track & low ADC",512,0.0,512);
+   TH1F* h33a = new TH1F("h33a","Y position of matched cluster",200,-10.0,10.0);
+   TH1F* h33b = new TH1F("h33b","X position of matched cluster",200,-10.0,10.0);
+   TH1F* h34 = new TH1F("h34","Y position of matched cluster & low ADC",200,-10.0,10.0);
+
+   TH1F *hnoise = new TH1F("hnoise","Noise in connected channels",100,-200,200);
+   TH1F *hnoiseChan = new TH1F("hnoiseChan","Noise in connected channels",200,0,200);
+   TH1F *hnoisePerChannel = new TH1F("hnoisePerChannel","Noise",512,0,512);
+
+   TH1F* h35 = new TH1F("h35","No. clusters / event",50,0.0,50.0);
+   
+   TH1F *h41[10];
+   TH1F *h42[10];
+   TH1F *h43[10];
+   TH1F *h44[10];
+   for(int i=0; i<10; i++){
+     h41[i] = new TH1F(Form("h41_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h42[i] = new TH1F(Form("h42_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),80,-400,400);
+     h43[i] = new TH1F(Form("h43_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+     h44[i] = new TH1F(Form("h44_%d",i),Form("ADC_{L}-ADC_{R}, Bin %d, Odd Ch",i),160,-400,400);
+   }
+
+   for(int i=0; i<nChan; i++){
+     hnoisePerChannel->Fill(i+0.5,noise[i]);
+   }
+   
+
+
+   //------------------------------------------------------------------------------------------------------
+   
+   //-----------------------------
+   // Prepare DUT (Alignment, etc)
+   //-----------------------------
+
+   PrepareDUT();
+   //return;
+   float biasVal = atof(m_bias);
+   cout << "chargeCorrSlopeOdd, chargeCorrSlopeEven = " << chargeCorrSlopeOdd << " " << chargeCorrSlopeEven << " " 
+        << m_bias << " " << biasVal << endl;
+   
+
+   std::ofstream myfile;
+   if(writeEventsWithMissinhHitsToFile){
+     myfile.open("MissingDUTHits.dat");
+   }
+
+   int iChan = nChan;
+   double nomStrip = 0, detStrip = 0;
+   int nPrint = 0;
+   double dxh[10];
+   int njump = 10000;
+   if(nentries > 100000) njump = 50000;
+   Long64_t nbytes = 0, nb = 0;
+   cout << "Begin loop over " << nentries << " events" << endl;
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      if(jentry%njump==0) cout << "====> At entry = " << jentry << endl;
+      if(n_tp3_tracks != 1) continue;
+
+      //==========================================
+      // Example here of acccessing CMS strip data
+      //==========================================
+      if(fCMS){
+        for(int k=0;k<iChan;k++){
+          if(fCMS->cmsData[k]!=0) hnoise->Fill(fCMS->cmsData[k]);
+        }      
+      }
+
+      h35->Fill(clusterNumberPerEvent);
+      if(clusterNumberPerEvent>10) continue;
+      
+      
+      // Loop over TPIX tracks in event
+      for(int k=0; k<n_tp3_tracks; k++){
+        if(dtime > trackTriggerTimeDiffCut) continue;
+        double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+        double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+        
+        transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip, detStrip);
+
+        //if(isInCutoutRegion(x_trk, y_trk)) continue;
+        double distToCutout = DistToCutoutRegion(x_trk, y_trk);
+        bool awayFromCutout = distToCutout > minDistFromHole;
+
+        int closestStrip = nomStrip;
+        double fracStrip = nomStrip - closestStrip - 0.5;
+
+        double tx = 1000*vec_trk_tx->at(k);
+        double ty = 1000*vec_trk_ty->at(k);
+
+        h5->Fill(tx);
+        h6->Fill(ty);
+
+        // Test cuts here, e.g.  to reject regions
+        //if(nomStrip<422 || nomStrip>442) continue;
+        //if(y_trk>2.4) continue;
+        //if(nomStrip<420 || nomStrip>445) continue;
+        
+
+        bool goodRegion = true;
+        for(int id = 0; id<nDeadRegion; id++){
+          if(x_trk>=deadRegionLo[id]  && x_trk<=deadRegionHi[id]) goodRegion = false;  
+        }
+        if(!goodRegion) continue;
+
+        h5a->Fill(x_trk);
+        h6a->Fill(y_trk);
+        bool goodTrack = false;
+        bool inFiducialX = false;
+        bool inFiducialY = false;
+
+        if(x_trk>xMin && x_trk<xMax) inFiducialX = true;          
+        if(y_trk>yMin && y_trk<yMax) inFiducialY = true;          
+        bool inFiducial = inFiducialX && inFiducialY;
+        inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+        
+        if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+        bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+        if(goodTrack && goodTime && inFiducial) h12od->Fill(distToCutout);
+
+        if(goodTrack && goodTime && inFiducial && awayFromCutout) {
+          h3a->Fill(x_trk,y_trk);
+          //h12a->Fill(y_trk);
+          h12dd->Fill(x_trk);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12ed->Fill(x_trk);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fd->Fill(x_trk);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gd->Fill(x_trk);
+          h12hd->Fill(fracStrip);
+          if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12id->Fill(fracStrip);
+          if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jd->Fill(fracStrip);
+          if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kd->Fill(fracStrip);
+        }
+        
+        bool foundHit = false;
+        bool foundHitNoFid = false;
+        double x_trk0 = x_trk;
+        for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+          dxh[j] = -999;
+          if(clustersPosition[j] < 0.1) continue;
+          if(polarity*clustersCharge[j] < 0.2*kClusterChargeMin) continue;
+          double x_dut = getDUTHitPosition(j);
+          x_trk = x_trk0;
+       
+          int iPeak = 1;
+          if(clustersSeedPosition[j]%2==0) iPeak = 0;
+          
+          h1s->Fill(clustersSeedPosition[j]);
+          if(clustersSeedPosition[j]<iLo-5 || clustersSeedPosition[j]>iHi+5) continue;
+
+          double dx = x_dut - x_trk;
+          dxh[j] = dx;
+
+	  //if(dx<0.2 && )
+	  // h122->Fill(y_trk);
+	  h123->Fill(y_trk);
+          if(inFiducial && goodTime && awayFromCutout) h12->Fill(y_trk); 
+          if(goodTrack && inFiducial && fabs(dx)<dxWin && awayFromCutout) {
+            h2p->Fill(clustersTDC+0.1,polarity*clustersCharge[j]);
+            h15d->Fill(clustersTDC);          
+            if(goodTime) h15e->Fill(clustersTDC);          
+          }
+          
+	  h311->Fill(x_trk,y_trk);
+
+	  if(fabs(dx)<0.2){
+            h311a->Fill(x_trk,y_trk);
+	    h122->Fill(y_trk);
+          }
+
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin){
+            h3->Fill(x_trk,y_trk);
+          }
+          
+          if(goodTrack && inFiducial && goodTime && fabs(dx)<dxWin) foundHitNoFid = true;
+
+
+          if(goodTrack && inFiducial && goodTime && awayFromCutout) {
+            hcAll->Fill(polarity*clustersCharge[j]);
+            h2->Fill(x_trk, x_dut);
+            h1->Fill(dx);
+            if(clustersSize[j]==1) h1a->Fill(dx);
+            if(clustersSize[j]==2) h1b->Fill(dx);
+            h1w->Fill(dx);
+            if(y_trk>2.5) h1wY->Fill(dx);
+            if(polarity*clustersCharge[j] < 250) h1z->Fill(dx);
+            h11d->Fill(detStrip);        
+            
+            if(fabs(dx)<dxWin) {
+              int ichan = clustersSeedPosition[j];
+              h4c->Fill(clustersSeedPosition[j]);
+              if(ichan>=0 && ichan<=511){
+                hlandau[ichan]->Fill(polarity*clustersCharge[j]);
+              }
+              
+              hnoiseChan->Fill(noise[ichan]);
+              h18a->Fill(clustersSeedCharge[j]/clustersCharge[j]);
+              foundHit = true;
+              if(clustersSize[j]==1) h18b->Fill(fracStrip,dx);
+              if(clustersSize[j]==2) h18c->Fill(fracStrip,dx);
+              h18d->Fill(fracStrip,clustersSeedCharge[j]/clustersCharge[j]);
+              
+              h12m->Fill(fracStrip,polarity*clustersCharge[j]);
+              h12n->Fill(fracStrip,clustersSize[j]);
+              h1vsx->Fill(x_trk,dx);
+              if(y_trk>yMid&&y_trk<yMax) h10a->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yMin&&y_trk<yMid) h10b->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              if(y_trk>yHi2&&y_trk<yMax) h10c->Fill(clustersPosition[j],polarity*clustersCharge[j]);
+              h10d->Fill(y_trk,polarity*clustersCharge[j]);
+              h10e->Fill(x_trk,polarity*clustersCharge[j]);
+              double chleft = polarity*clustersCharge1StripLeft[j];
+              double chright = polarity*clustersCharge1StripRight[j];
+              double rc = -999;
+              if(detStrip <= clustersSeedPosition[j]) {
+                if(chleft>0) rc = (chleft/(chleft+clustersSeedCharge[j]));              
+              }else{ 
+                if(chright>0) rc = (clustersSeedCharge[j]/(chright+clustersSeedCharge[j]));
+              }
+              if( rc>=0 ) {
+                h17->Fill(rc);
+                h17a->Fill(fracStrip,rc);
+                h17b->Fill(fracStrip,rc);
+              }
+              h8->Fill(1000*vec_trk_tx->at(k),dx);    
+              h9->Fill(y_trk,dx);
+              h9a->Fill(x_trk,dx);
+              h5b->Fill(x_trk);
+              h6b->Fill(y_trk);
+              h5c->Fill(tx);
+              h6c->Fill(ty);
+	      if(abs(dx<0.2)) h6d->Fill(y_trk);
+
+              h11n->Fill(detStrip);
+              hcTrk->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==1) hcTrkCorr->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2 && iPeak==1) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeOdd));
+              if(clustersSize[j]==2 && iPeak==0) hcTrkCorr->Fill(polarity*clustersCharge[j]*(1.0-chargeCorrSlopeEven));
+              hcTrkSeed->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==1) hcTrkSeed1->Fill(polarity*clustersSeedCharge[j]);
+              if(clustersSize[j]==2) hcTrkSeed2->Fill(polarity*clustersSeedCharge[j]);
+              if(y_trk - yMax < 5.0) hcTrkNoTop->Fill(polarity*clustersCharge[j]);
+              if(x_trk < (xMin+xMax)/2.) hcTrkLowX->Fill(polarity*clustersCharge[j]);
+              if(x_trk >= (xMin+xMax)/2.) hcTrkHighX->Fill(polarity*clustersCharge[j]);
+              int ix = 4*(x_trk - xMin - 0.001) / (xMax-xMin);
+              int iy = 4*(y_trk - yMin - 0.001) / (yMax-yMin);
+              int ihist = 4*ix + iy;
+              hcTrkXY[ihist]->Fill(polarity*clustersCharge[j]);              
+              //if(y_trk>yMin && y_trk<=(yMin+0.25*yRange)) hcTrkY1->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.25*yRange) && y_trk<(yMin+0.50*yRange)) hcTrkY2->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.50*yRange) && y_trk<(yMin+0.75*yRange)) hcTrkY3->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>(yMin+0.75*yRange) && y_trk<(yMin+1.00*yRange)) hcTrkY4->Fill(polarity*clustersCharge[j]);
+              //if(y_trk>yMin&&y_trk<yMid+1.0) hcTrkY2->Fill(polarity*clustersCharge[j]);
+
+              if(clustersSize[j]==1) hcTrk1->Fill(polarity*clustersCharge[j]);
+              if(clustersSize[j]==2) hcTrk2->Fill(polarity*clustersCharge[j]);
+              if(clustersPosition[j]>170  && clustersPosition[j]<190) hcTrka->Fill(polarity*clustersCharge[j]);
+              h31a->Fill(x_trk,y_trk);
+              h32a->Fill(clustersPosition[j]);
+              h33a->Fill(y_trk);
+              h33b->Fill(x_trk);
+              if(polarity*clustersCharge[j] < 250) {
+                h31b->Fill(x_trk,y_trk);
+                h32b->Fill(clustersPosition[j]);
+                h34->Fill(y_trk);
+              }
+              double chr = clustersCharge1StripRight[j]*polarity;
+              double chl = clustersCharge1StripLeft[j]*polarity;
+              double chr2 = clustersCharge2StripRight[j]*polarity;
+              double chl2 = clustersCharge2StripLeft[j]*polarity;
+              double pch = polarity*clustersSeedCharge[j];
+              int ic = pch/50.;
+              if(ic>=0 && ic<10 && clustersSize[j]<=2 ){
+                if(iPeak==1) h41[ic]->Fill(chl-chr);
+                if(iPeak==0) h42[ic]->Fill(chl-chr);
+                if(chr2!=0 and chl2!=0){
+                  if(iPeak==1) h43[ic]->Fill(chl2-chr2);
+                  if(iPeak==0) h44[ic]->Fill(chl2-chr2);
+                }
+                
+              } 
+            }
+
+            double clstrip = getCorrChannel(clustersPosition[j]);
+            h4->Fill(clstrip);
+            h4b->Fill(clstrip + channelOffset);
+            h4a->Fill(clustersPosition[j]);
+            h0->Fill(detStrip - clstrip);
+          }
+        }
+
+        if(inFiducial && goodTrack && goodTime && foundHitNoFid) {
+          h12on->Fill(distToCutout);
+        }
+        
+        if(inFiducial && goodTrack && goodTime && awayFromCutout) {
+          h16c->Fill(dtime);
+          if(foundHit) {
+            h3c->Fill(x_trk,y_trk);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcfpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1fpa->Fill(dxh[j]);
+            }        
+            h15c->Fill(dtime);
+            h15b->Fill(clustersTDC+0.1);
+            h15a->Fill(vec_trk_chi2ndf->at(k));
+            h12b->Fill(y_trk);
+            h12dn->Fill(x_trk); 
+	    //h_eff_xy->Fill(x_trk,y_trk);
+
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1]) h12en->Fill(x_trk);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1]) h12fn->Fill(x_trk);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1]) h12gn->Fill(x_trk);
+            h12hn->Fill(fracStrip);
+            if(y_trk>yInt1[0]&&y_trk<yInt1[1] && x_trk>-3.5&&x_trk<2.5) h12in->Fill(fracStrip);
+            if(y_trk>yInt2[0]&&y_trk<yInt2[1] && x_trk>-3.5&&x_trk<2.5) h12jn->Fill(fracStrip);
+            if(y_trk>yInt3[0]&&y_trk<yInt3[1] && x_trk>-3.5&&x_trk<2.5) h12kn->Fill(fracStrip);
+            if(y_trk>yInt1[0] && y_trk < yInt2[1] && x_trk>-3.5&&x_trk<-2.0) {
+              h14b->Fill(detStrip);
+              h13fpa->Fill(clusterNumberPerEvent);
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13fbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                h1fbpa->Fill(dxh[j]);
+                hcfbpa->Fill(polarity*clustersCharge[j]);
+              }
+            }                
+          }else{     
+            h3b->Fill(x_trk,y_trk);          
+            h13mpa->Fill(clusterNumberPerEvent);
+            h16a->Fill(vec_trk_chi2ndf->at(k));
+            h16b->Fill(clustersTDC+0.1);
+            for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+              hcmpa->Fill(polarity*clustersCharge[j]);
+              if(polarity*clustersCharge[j]>120) h1mpa->Fill(dxh[j]);
+            }            
+            nPrint++;
+            if(y_trk>yInt1[0] && y_trk < yInt2[1]) {
+              h14a->Fill(detStrip);
+              if(writeEventsWithMissinhHitsToFile) 
+                myfile << jentry << " " << detStrip << " " << x_trk << " " << y_trk << endl;              
+              //if(nPrint < 100) cout << "Missed hit, event, #clu, nomStrip =  " << jentry << " " 
+              //                      << clusterNumberPerEvent << " " << nomStrip << endl;
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+                if(x_trk>-3.5&&x_trk<-2.0) h1mpa1->Fill(dxh[j]);
+                if(x_trk>-2.0&&x_trk<-1.0) h1mpa2->Fill(dxh[j]);
+                if(x_trk>-1.0&&x_trk<0.0) h1mpa3->Fill(dxh[j]);
+                if(x_trk>0.0&&x_trk<1.0)  h1mpa4->Fill(dxh[j]);
+                if(x_trk>1.5&&x_trk<3.5)  h1mpa5->Fill(dxh[j]);
+                if(y_trk<yInt1[1]) h1mpaL->Fill(clustersPosition[j]);                         
+                if(y_trk>=yInt1[1]) h1mpaU->Fill(clustersPosition[j]);
+              }
+            }else if(y_trk>yInt3[0] && y_trk < yInt3[1]) {
+              h13mbpa->Fill(clusterNumberPerEvent);
+              for(int j=0; j<min(clusterNumberPerEvent,10); j++){              
+                h1mbpa->Fill(dxh[j]);
+                hcmbpa->Fill(polarity*clustersCharge[j]);
+              }    
+            }
+          }
+        } 
+      }
+   }
+   if(writeEventsWithMissinhHitsToFile) myfile.close();
+
+   int i1 = h1->FindBin(-0.3);
+   int i2 = h1->FindBin(0.3);
+   cout << "Number of track - DUT hit matchs: " << h1->Integral(i1,i2) << endl;
+   cout << "Ry = " << Ry << endl;
+   
+   
+   TString r1 = Form("%6.3f < Y < %6.3f mm",yInt1[0], yInt1[1]);
+   TString r2 = Form("%6.3f < Y < %6.3f mm ",yInt2[0], yInt2[1]);
+   TString r3 = Form("%6.3f < Y < %6.3f mm",yInt3[0], yInt3[1]);   
+
+
+   TF1 *funchole = new TF1("funchole","[0]+[1]*x+[2]*x*x",-8.0,8.0);
+   funchole->SetParameters(holeQuadPar[0],holeQuadPar[1],holeQuadPar[2]);
+   funchole->SetLineColor(4);
+   funchole->SetLineWidth(2);
+   cout << "Hole Parameters: " << holeQuadPar[0] << " " << holeQuadPar[1] << " " << holeQuadPar[2] << endl;
+   
+   gStyle->SetOptStat(1000000001);
+   gStyle->SetOptFit(0011);
+   gStyle->SetStatH(0.05);
+   gStyle->SetStatW(0.2);
+
+   addGraphics(h3b, 1, "X_{trk} [mm]", "Y_{trk} [mm] ");
+   h3b->GetXaxis()->SetRangeUser(-5,5);
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+
+   TCanvas *c = new TCanvas("c","Residuals",1500,1000);
+   c->Divide(4,3);
+   c->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h2, 1, "X_{trk} [mm]", "X_{DUT} [mm]");
+   double dM = yMax;
+   if(xMax>dM) dM = xMax;
+   h2->GetXaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->GetYaxis()->SetRangeUser(-1.0*dM-1,dM+1);
+   h2->SetMinimum(1);
+   h2->Draw("colz");
+
+   c->cd(2)->SetLeftMargin(0.13);;
+   addGraphics(h1, 1, "#DeltaX [mm]", "");
+   addGraphics(h1z, 2, "#DeltaX [mm]", "");
+   addGraphics(h1a, 3, "#DeltaX [mm]", "");
+   addGraphics(h1b, 6, "#DeltaX [mm]", "");
+   h1->GetXaxis()->SetRangeUser(-0.3,0.3);
+   if(m_board.Contains("A1")) h1->GetXaxis()->SetRangeUser(-1.5,1.5);
+   h1->SetMaximum(1.2*h1->GetMaximum());
+   h1->Draw();   
+   //h1z->Draw("same");
+   h1a->Draw("same");
+   h1b->Draw("same");
+   TLine *l1 = new TLine(-stripPitch/2.,0,-stripPitch/2.,0.5*h1->GetMaximum());
+   TLine *l2 = new TLine(stripPitch/2,0,stripPitch/2,0.5*h1->GetMaximum());
+   TLine *l1a = new TLine(-dxWin,0,-dxWin,0.5*h1->GetMaximum());
+   TLine *l2a = new TLine(dxWin,0,dxWin,0.5*h1->GetMaximum());
+   l1->SetLineColor(kRed); l2->SetLineColor(kRed);
+   l1a->SetLineColor(kBlue); l2a->SetLineColor(kBlue); l1a->SetLineWidth(2); l2a->SetLineWidth(2);
+   l1->Draw(); l2->Draw();
+   //l1a->Draw(); l2a->Draw();
+
+   TLegend* legend3 = new TLegend(0.15,0.70,0.40,0.89);
+   legend3->SetFillStyle(0);
+   legend3->SetBorderSize(0);
+   legend3->SetFillStyle(0);
+   legend3->SetTextSize(0.045);
+   
+   legend3->AddEntry(h1,"All","L"); 
+   //legend3->AddEntry(h1z,"ADC < 250","L"); 
+   legend3->AddEntry(h1a,"1-strip","L"); 
+   legend3->AddEntry(h1b,"2-strip","L"); 
+   legend3->Draw();
+   
+   c->cd(3)->SetLeftMargin(0.13);;
+   addGraphics(h8, 1, "#theta_{X}^{trk} [mrad]", "#DeltaX [mm]");
+   h8->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h8->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h8->Draw();
+   c->cd(4)->SetLeftMargin(0.13);;
+   addGraphics(h9, 1, "Y^{trk} [mm]", "#DeltaX [mm]");
+   h9->GetXaxis()->SetRangeUser(yMin-1,yMax+1);   
+   h9->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9->Draw();
+   c->cd(5)->SetLeftMargin(0.13);;
+   addGraphics(h9a, 1, "X^{trk} [mm]", "#DeltaX [mm]");
+   h9a->GetXaxis()->SetRangeUser(-4,4);   
+   h9a->GetYaxis()->SetRangeUser(-0.1,0.1);   
+   h9a->Draw();
+
+   c->cd(6)->SetLeftMargin(0.13);;
+   h3c->Divide(h3a);
+   h122->Divide(h123);
+   //h311a->Divide(h311);
+   addGraphics(h3c, 1, "X_{trk} [mm]", "Y_{trk} [mm]");
+   h3c->GetXaxis()->SetRangeUser(xMin-1,xMax+1);   
+   h3c->GetYaxis()->SetRangeUser(yMin-1,yMax+1);
+   h3c->GetZaxis()->SetRangeUser(0,1);
+   h3c->SetTitle("trk");   
+   h3c->Draw("colz");
+
+   //h3c->GetXaxis()->SetRangeUser(xMin-1,xMax+1);   
+   //h3c->GetYaxis()->SetRangeUser(yMin-1,yMax+1);
+   //h3c->GetZaxis()->SetRangeUser(0,1);
+   //h3c->SetTitle("Efficiency");   
+   //h3c->Draw("colz");
+   if(holeQuadPar[0]!=0) funchole->Draw("same");
+   if(fabs(xLeftHole)<900 && fabs(xRightHole)<900){
+     TBox *b1 = new TBox(xMin,yMin,xLeftHole,yMax);
+     TBox *b2 = new TBox(xRightHole,yMin,xMax,yMax);
+     b1->SetLineColor(kBlue); b1->SetLineWidth(2);b1->SetFillStyle(0);   
+     b1->Draw();
+     b2->SetLineColor(kBlue); b2->SetLineWidth(2);b2->SetFillStyle(0);   
+     b2->Draw();
+   }else{   
+     TBox *b = new TBox(xMin,yMin,xMax,yMax);
+     b->SetLineColor(kBlue); b->SetLineWidth(2);b->SetFillStyle(0);   
+     b->Draw();
+   }
+   
+
+   c->cd(7)->SetLeftMargin(0.13);;
+   addGraphics(h5, 1, "#theta_{X}^{trk} [mrad]", "");
+   h5->GetXaxis()->SetRangeUser(txMin-0.1,txMax+0.1);   
+   h5->Draw();
+   h5c->SetLineColor(2); h5c->Draw("same");
+   TLine *l1b = new TLine(txMin,0,txMin,h5->GetMaximum());
+   TLine *l2b = new TLine(txMax,0,txMax,h5->GetMaximum());
+   l1b->SetLineColor(kBlue); l2b->SetLineColor(kBlue); l1b->SetLineWidth(2); l2b->SetLineWidth(2);
+   l1b->Draw(); l2b->Draw();
+
+   c->cd(8)->SetLeftMargin(0.13);
+   addGraphics(h6, 1, "#theta_{Y}^{trk} [mrad]", "");
+   h6->GetXaxis()->SetRangeUser(tyMin-0.1,tyMax+0.1);   
+   h6->Draw();
+   h6c->SetLineColor(2); h6c->Draw("same");
+   TLine *l1c = new TLine(tyMin,0,tyMin,h6->GetMaximum());
+   TLine *l2c = new TLine(tyMax,0,tyMax,h6->GetMaximum());
+   l1c->SetLineColor(kBlue); l2c->SetLineColor(kBlue); l1c->SetLineWidth(2); l2c->SetLineWidth(2);   
+   l1c->Draw(); l2c->Draw();
+   
+   c->cd(9)->SetLeftMargin(0.13);;
+   addGraphics(h4, 1, "Strip # with cluster", "");
+   addGraphics(h4a, 2, "Strip # with cluster", "");
+   h4->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   h4a->GetXaxis()->SetRangeUser(max(iLo-60.0,1.0),min(iHi+60.0,512.0));
+   double vmax = h4a->GetMaximum();
+   //for(int ii=iLo; ii<=iHi;ii++){
+   //  if(h4a->GetBinContent(ii)>vmax) vmax = h4a->GetBinContent(ii);
+   //}
+   h4->SetMaximum(1.25*vmax);
+   TLine *l1d = new TLine(iLo,0,iLo,0.75*h4a->GetMaximum());
+   TLine *l2d = new TLine(iHi,0,iHi,0.75*h4a->GetMaximum());
+   l1d->SetLineColor(kBlue); l2d->SetLineColor(kBlue); l1d->SetLineWidth(2); l2d->SetLineWidth(2);   
+   h4->Draw();
+   h4a->Draw("same");
+   l1d->Draw(); l2d->Draw();
+   
+   TLegend* legend4 = new TLegend(0.15,0.70,0.94,0.89);
+   legend4->SetFillStyle(0);
+   legend4->SetBorderSize(0);
+   legend4->SetFillStyle(0);
+   legend4->SetTextSize(0.045);
+   
+   legend4->AddEntry(h4,"Sensor strip ch #","L"); 
+   legend4->AddEntry(h4a,"Electr. ch #","L");
+
+   legend4->Draw();
+
+
+   c->cd(10)->SetLeftMargin(0.13);;
+   addGraphics(hcAll, 1, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk1, 3, "Cluster charge [ADC]", "");
+   addGraphics(hcTrk2, 6, "Cluster charge [ADC]", "");
+   hcAll->SetMaximum(1.25*hcAll->GetMaximum());
+   hcAll->Draw();
+   hcTrk->SetLineColor(kBlue); hcTrk->SetLineWidth(2);
+   hcTrk->Draw("same"); 
+   hcTrk1->Draw("same"); 
+   hcTrk2->Draw("same"); 
+  
+   TLegend* legend2 = new TLegend(0.15,0.70,0.94,0.89);
+   legend2->SetFillStyle(0);
+   legend2->SetBorderSize(0);
+   legend2->SetFillStyle(0);
+   legend2->SetTextSize(0.045);
+   
+   legend2->AddEntry(hcAll,"All clusters, trk in Fid","L"); 
+   legend2->AddEntry(hcTrk,"Clusters, |#DeltaX|<200 #mum, trk in Fid.","L");
+   legend2->AddEntry(hcTrk1,"1-strip Clusters","L");
+   legend2->AddEntry(hcTrk2,"2-strip Clusters","L");
+
+   legend2->Draw();
+
+   
+
+   c->cd(11)->SetLeftMargin(0.13);;
+   addGraphics(h10a, 1, "Strip #", "<ADC>");
+   addGraphics(h10b, 2, "Strip #", "<ADC>");
+   addGraphics(h10c, 4, "Strip #", "<ADC>");
+   int ixl = iLo;
+   int ixh = iHi;
+   int yh = hcTrk->GetMean()-50;
+   h10a->GetXaxis()->SetRangeUser(ixl-2,ixh+2);   
+   h10a->GetYaxis()->SetRangeUser(yh-200,yh+300);
+   /*
+   h10a->Draw();
+   h10b->SetLineColor(2);h10b->SetMarkerColor(2);
+   h10b->Draw("same");
+   h10c->SetLineColor(4);h10c->SetMarkerColor(4);
+   h10c->Draw("same");
+
+   TLegend* legend1 = new TLegend(0.25,0.75,0.94,0.89);
+   legend1->SetFillStyle(0);
+   legend1->SetBorderSize(0);
+   legend1->SetFillStyle(0);
+   legend1->SetTextSize(0.045);
+   
+   legend1->AddEntry(h10a,"Top half in Y","LEP"); 
+   legend1->AddEntry(h10b,"Bottom half in Y","LEP"); 
+   legend1->AddEntry(h10c,"Top 2 mm in Y","LEP"); 
+   legend1->Draw();
+   */
+   addGraphics(h35, 1, "#DUT clusters", "Entries");   
+   h35->GetYaxis()->SetTitleOffset(1.2);
+   h35->Draw();
+
+   c->cd(12)->SetLeftMargin(0.13);;
+   addGraphics(h2p, 1, "TDC time / 2.5 ns", "<ADC>");
+   h2p->Draw();
+   TLine *l1e = new TLine(tdcLo,0,tdcLo,h2p->GetMaximum());
+   TLine *l2e = new TLine(tdcHi,0,tdcHi,h2p->GetMaximum());
+   l1e->SetLineColor(kBlue); l2e->SetLineColor(kBlue); l1e->SetLineWidth(2); l2e->SetLineWidth(2);   
+   l1e->Draw(); l2e->Draw();
+   // c->cd(12)->Print("testing.root");
+
+   c->Print("Plots/plot_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   c->Print("Plots/plot_"+m_board+"_s"+m_sector+"_vb"+m_bias+".root");
+
+   //return;
+ TCanvas *c44 = new TCanvas("c44","Plot 4",800,600);
+   addGraphics(h2p, 1, "TDC time / 2.5 ns", "<ADC>");
+   h2p->Draw();
+   TLine *l1e2 = new TLine(tdcLo,0,tdcLo,h2p->GetMaximum());
+   TLine *l2e2 = new TLine(tdcHi,0,tdcHi,h2p->GetMaximum());
+   l1e2->SetLineColor(kBlue); l2e2->SetLineColor(kBlue); l1e2->SetLineWidth(2); l2e2->SetLineWidth(2);   
+   l1e2->Draw("same"); l2e2->Draw("same");
+   c44->SaveAs("testing.root");
+
+   TCanvas *c4 = new TCanvas("c4","Plot 4",800,600);
+   c4->Divide(2,2);
+   c4->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12en, 1, "X_{trk} [mm]", "");
+   addGraphics(h12fn, 1, "X_{trk} [mm]", "");
+
+   TH1F *hepa1 = (TH1F*)h12en->Clone("hepa1");
+   TH1F *hepa2 = (TH1F*)h12fn->Clone("hepa2");
+   TH1F *henpa = (TH1F*)h12gn->Clone("henpa");
+   hepa1->Divide(h12en,h12ed,1.0,1.0,"B");
+   hepa2->Divide(h12fn,h12fd,1.0,1.0,"B");
+   henpa->Divide(h12gn,h12gd,1.0,1.0,"B");
+   addGraphics(hepa1, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   addGraphics(hepa2, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   h3b->GetYaxis()->SetRangeUser(-5,5);
+   h3b->Draw();
+
+   c4->cd(2)->SetLeftMargin(0.13);
+   hepa1->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa1->SetMinimum(0.0);
+   hepa1->SetMaximum(1.2);
+   hepa1->SetLineWidth(1);
+   hepa1->SetTitle(r1);
+   hepa1->Draw("hist");
+   c4->cd(3)->SetLeftMargin(0.13);
+   hepa2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   hepa2->SetMinimum(0.0);
+   hepa2->SetMaximum(1.2);
+   hepa2->SetLineWidth(1);
+   hepa2->SetTitle(r2);
+   hepa2->Draw("hist");
+
+   c4->cd(4)->SetLeftMargin(0.13);
+   addGraphics(henpa, 1, "X_{trk} [mm]", "#Good DUT hit / # Track ");
+   henpa->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   henpa->SetMinimum(0.0);
+   henpa->SetMaximum(1.2);
+   henpa->SetLineWidth(1);
+   henpa->SetTitle(r3);
+   henpa->Draw("hist");   
+
+
+   TCanvas *c5 = new TCanvas("c5","Plot 5",800,600);
+   c5->Divide(2,2);
+   c5->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h12hn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12in, 1, "Rel. Strip Pos", "");
+   addGraphics(h12jn, 1, "Rel. Strip Pos", "");
+   addGraphics(h12kn, 1, "Rel. Strip Pos", "");
+
+   TH1F *hepas1 = (TH1F*)h12hn->Clone("hepas1");
+   TH1F *hepas2 = (TH1F*)h12in->Clone("hepas2");
+   TH1F *hepas3 = (TH1F*)h12jn->Clone("hepas3");
+   TH1F *hepas4 = (TH1F*)h12kn->Clone("hepas4");
+   hepas1->Divide(h12hn,h12hd,1.0,1.0,"B");
+   hepas2->Divide(h12in,h12id,1.0,1.0,"B");
+   hepas3->Divide(h12jn,h12jd,1.0,1.0,"B");
+   hepas4->Divide(h12kn,h12kd,1.0,1.0,"B");
+   addGraphics(hepas1, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas2, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas3, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   addGraphics(hepas4, 1, "Rel. Strip Pos.", "#Good DUT hit / # Track ");
+   hepas1->SetTitle("Full Beam Spot");
+   hepas1->SetMinimum(0.8);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetLineWidth(1);
+   hepas1->Draw("hist");
+   c5->cd(2)->SetLeftMargin(0.13);
+   hepas2->SetTitle(r1);
+   hepas2->SetMinimum(0.8);
+   hepas2->SetMaximum(1.2);
+   hepas2->SetLineWidth(1);
+   hepas2->Draw("hist");
+   c5->cd(3)->SetLeftMargin(0.13);
+   hepas3->SetTitle(r2);
+   hepas3->SetMinimum(0.8);
+   hepas3->SetMaximum(1.2);
+   hepas3->SetLineWidth(1);
+   hepas3->Draw("hist");
+   c5->cd(4)->SetLeftMargin(0.13);
+   hepas4->SetTitle(r3);
+   hepas4->SetMinimum(0.8);
+   hepas4->SetMaximum(1.2);
+   hepas4->SetLineWidth(1);
+   hepas4->Draw("hist");
+
+   c5->Print("Plots/plot5_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   c5->Print("Plots/plot5_"+m_board+"_s"+m_sector+"_vb"+m_bias+".root");
+   //return;
+   
+
+   TCanvas *c1 = new TCanvas("c1","Plot 1",1600,800);
+   c1->Divide(3,2);
+
+   c1->cd(1)->SetLeftMargin(0.13);
+   addGraphics(h10d, 2, "Y_{trk} [mm]", "<ADC>");
+   h10d->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h10d->Draw();
+
+   //c1->cd(2)->SetLeftMargin(0.13);
+   //h3b->Draw();   
+
+   c1->cd(2)->SetLeftMargin(0.13);
+   addGraphics(h12b, 2, "Y_{trk} [mm]", "");
+   addGraphics(h12a, 1, "Y_{trk} [mm]", "");
+   h12a->SetMaximum(1.2*h12a->GetMaximum());
+   h12a->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   h12a->Draw("hist");
+   h12b->Draw("hist,same");
+
+   TLegend* legend0 = new TLegend(0.15,0.75,0.94,0.89);
+   legend0->SetFillStyle(0);
+   legend0->SetBorderSize(0);
+   legend0->SetFillStyle(0);
+   legend0->SetTextSize(0.045);   
+   legend0->AddEntry(h12a,"Track Y pos","LEP"); 
+   legend0->AddEntry(h12b,"Track Y pos with good cluster","LEP");
+   legend0->Draw();
+
+   c1->cd(3)->SetLeftMargin(0.13);
+   TH1F *he = (TH1F*)h12b->Clone("he");
+   he->Divide(h12b,h12a,1.0,1.0,"B");
+   float bw = 1000*h12b->GetBinWidth(1);
+   TString yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he, 1, "Y_{trk} [mm]", yt);
+   he->SetTitle("DUT Efficiency vs Y_{trk}");
+   he->GetXaxis()->SetRangeUser(yMin-0.5,yMax+0.5);
+   he->SetMinimum(0.8);
+   he->SetMaximum(1.1);
+   he->Draw("e");
+
+   c1->cd(4)->SetLeftMargin(0.13);
+   addGraphics(h10e, 2, "X_{trk} [mm]", "<ADC>");
+   h10e->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h10e->Draw();
+
+   c1->cd(5)->SetLeftMargin(0.13);
+   addGraphics(h12dd, 2, "X_{trk} [mm]", "");
+   addGraphics(h12dn, 1, "X_{trk} [mm]", "");
+   h12dd->SetMaximum(1.2*h12dd->GetMaximum());
+   h12dd->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   h12dd->Draw("hist");
+   h12dn->Draw("hist,same");
+
+   c1->cd(6)->SetLeftMargin(0.13);
+   TH1F *he2 = (TH1F*)h12dn->Clone("he");
+   he2->SetName("he2");
+   he2->Divide(h12dn,h12dd,1.0,1.0,"B");
+   bw = 1000*h12dd->GetBinWidth(1);
+   yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+   addGraphics(he2, 1, "X_{trk} [mm]", yt);
+   he2->SetTitle("DUT Efficiency vs X_{trk}");
+   he2->GetXaxis()->SetRangeUser(xMin-0.5,xMax+0.5);
+   he2->SetMinimum(0.8);
+   he2->SetMaximum(1.1);
+   he2->Draw("e");
+   c1->Print("Plots/plot1_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   c1->Print("Plots/plot1_"+m_board+"_s"+m_sector+"_vb"+m_bias+".root");
+
+   TCanvas *c8 = new TCanvas("c8","Plot 8",800,400);
+   c8->Divide(2,1);
+   TH1F *he4 = (TH1F*)h15c->Clone("Eff_trigger-DUT_time");
+   he4->Divide(h15c,h16c,1.0,1.0,"B");
+   yt = "#Good DUT hit / # Track";
+   addGraphics(h16c, 1, "DUT time - Track Time (ns)", "Entries");
+   addGraphics(he4, 1, "DUT time - Track Time (ns)", "Efficiency");
+   c8->cd(1)->SetLeftMargin(0.15);;
+   c8->cd(1)->SetRightMargin(0.05);;
+   h16c->Draw();
+   c8->cd(2)->SetLeftMargin(0.13);;
+   c8->cd(2)->SetRightMargin(0.05);;
+   he4->Draw();
+   c8->Print("Plots/plot8_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   c8->Print("Plots/plot8_"+m_board+"_s"+m_sector+"_vb"+m_bias+".root");   
+
+   if(holeSector){
+     TCanvas *c7 = new TCanvas("c7","Plot 7",800,800);
+     c7->SetLeftMargin(0.13);
+     TH1F *he3 = (TH1F*)h12on->Clone("Erf()_fit");
+     he3->Divide(h12on,h12od,1.0,1.0,"B");
+     bw = 1000*h12od->GetBinWidth(1);
+     yt = Form("(#Good DUT hit / # Track) / %3.0f #mum",bw);
+     addGraphics(he3, 1, "Dist to cutout [mm]", yt);
+     he3->SetStats(kTRUE);
+     he3->SetTitle("DUT Efficiency vs Dist to Cutout");
+     he3->GetXaxis()->SetRangeUser(-0.2,2.0);
+     he3->GetYaxis()->SetRangeUser(0.0,1.3);
+     he3->Draw("e");
+     TLatex *myLatex = new TLatex();
+     myLatex->SetTextFont(42); myLatex->SetTextColor(1); 
+     myLatex->SetTextAlign(12); myLatex->SetNDC(kTRUE); myLatex->SetTextSize(0.047);
+     TString text = "Sector "+m_sector;
+     c7->cd();
+     myLatex->DrawLatex(0.18,0.8,text);
+     
+     TF1 *f4a = new TF1("f4a","0.5*[0]*(1+TMath::Erf((x-[1])/[2]))",-0.1,2.0);
+     f4a->SetParameters(0.5,0.0,0.04);
+     f4a->SetParNames("Const","Mean","Sigma");
+     he3->Fit("f4a","R");
+     TPad *inset = new TPad("inset","y vx x",0.44,0.1,0.89,0.55);
+     inset->SetLeftMargin(0.13);
+     inset->SetRightMargin(0.05);
+     h3->SetTitle("");
+     inset->Draw();
+     inset->cd();
+     h3->Draw();
+     h3b->SetMarkerSize(0.2);h3b->SetMarkerStyle(20);h3b->SetMarkerColor(kRed); 
+     h3b->Draw("same");
+     if(holeQuadPar[0]!=0) funchole->Draw("same");   
+     
+     c7->Print("Plots/plot7_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+     c7->Print("Plots/plot7_"+m_board+"_s"+m_sector+"_vb"+m_bias+".root");   
+   }
+   
+   /*
+   TCanvas *c2 = new TCanvas("c2","Plot 2",1600,600);
+   c2->Divide(5,2);
+   addGraphics(h1mpa, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, No Match Clu");
+   addGraphics(h1mbpa, 4, "X_{clu}-X_{trk} [mm]", ""); h1mbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, No Match Clu");
+   addGraphics(h1fpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fpa->SetTitle("2.8<Y_{trk}<4.1 mm, All X, Match Clu");
+   addGraphics(h1fbpa, 1, "X_{clu}-X_{trk} [mm]", ""); h1fbpa->SetTitle("1.0<Y_{trk}<2.3 mm, All X, Match Clu");
+
+   addGraphics(h1mpa1, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa1->SetTitle("2.8<Y_{trk}<4.1 mm, -3.5<X_{trk}<-2.0 mm, No Match Clu");
+   addGraphics(h1mpa2, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa2->SetTitle("2.8<Y_{trk}<4.1 mm, -2.0<X_{trk}<-1.0 mm, No Match Clu");
+   addGraphics(h1mpa3, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa3->SetTitle("2.8<Y_{trk}<4.1 mm, -1.0<X_{trk}<0.0 mm, No Match Clu");
+   addGraphics(h1mpa4, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa4->SetTitle("2.8<Y_{trk}<4.1 mm,  0.0<X_{trk}<1.0 mm, No Match Clu");
+   addGraphics(h1mpa5, 2, "X_{clu}-X_{trk} [mm]", ""); h1mpa5->SetTitle("2.8<Y_{trk}<4.1 mm,  1.5<X_{trk}<3.5 mm, No Match Clu");
+   h1mpa->SetLineWidth(1); 
+   h1mpa1->SetLineWidth(1); 
+   h1mpa2->SetLineWidth(1); 
+   h1mpa3->SetLineWidth(1); 
+   h1mpa4->SetLineWidth(1); 
+   h1mpa5->SetLineWidth(1); 
+   h1fpa->SetLineWidth(1); 
+   h1fbpa->SetLineWidth(1); 
+
+   
+   h1fpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1fbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mbpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa1->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa2->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa3->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa4->GetXaxis()->SetRangeUser(-3,9); 
+   h1mpa5->GetXaxis()->SetRangeUser(-3,9); 
+
+   c2->cd(1);
+   h3b->Draw();   
+   double xl[5] = {-3.5, -2.0, -1.0, 0.0, 1.5};
+   double xh[5] = {-2.0, -1.0,  0.0, 1.0, 3.5};
+   
+   
+   for(int i=0;i<5;i++){
+     TBox *b = new TBox(xl[i],yInt1[0],xh[i],yInt2[1]);
+     b->SetLineColor(2); b->SetFillStyle(0);b->SetLineWidth(2);
+     b->Draw();
+   }
+   TBox *b = new TBox(xl[0],yInt3[0],xh[4],yInt3[1]);
+   b->SetLineColor(4);b->SetFillStyle(0);b->SetLineWidth(2);
+   b->Draw();
+   
+
+
+   c2->cd(2);
+   h1mpa->Draw();   
+   c2->cd(3);
+   h1fpa->GetYaxis()->SetRangeUser(0,30);
+   h1fpa->Draw();   
+   c2->cd(4);
+   h1mbpa->Draw();   
+   c2->cd(5);
+   h1fbpa->GetYaxis()->SetRangeUser(0,30);
+   h1fbpa->Draw();   
+   c2->cd(6);   
+   h1mpa1->Draw();   
+   c2->cd(7);
+   h1mpa2->Draw();   
+   c2->cd(8);
+   h1mpa3->Draw();   
+   c2->cd(9);
+   h1mpa4->Draw();   
+   c2->cd(10);
+   h1mpa5->Draw();
+   c2->Print("Plots/plot2_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   /*
+   TCanvas *c3 = new TCanvas("c3","Plot 3",800,600);
+   c3->Divide(1,2);
+   c3->cd(1);
+   h1mpaU->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaU->Draw();
+   c3->cd(2);
+   h1mpaL->GetXaxis()->SetRangeUser(iLo-10,iHi+10);
+   h1mpaL->Draw();   
+   c3->Print("Plots/plot3_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+   */
+
+   addGraphics(h12m,1,"Interstrip Pos","<ADC>");
+   addGraphics(h12n,1,"Interstrip Pos","<Cluster Size>");
+   TCanvas *c6 = new TCanvas("c6","Plot 6",1200,400);
+   c6->Divide(3,1);
+   c6->cd(1);
+   hepas1->SetMaximum(1.2);
+   hepas1->SetMinimum(0.5);
+   hepas1->Draw();
+   c6->cd(2);
+   h12m->SetMinimum(0);
+   h12m->SetMaximum(1.2*h12m->GetMaximum());
+   h12m->Draw();
+   c6->cd(3);
+   h12n->SetMinimum(0.5);
+   h12n->SetMaximum(2.0);
+   h12n->Draw();
+   
+   c6->Print("Plots/plot6_"+m_board+"_s"+m_sector+"_vb"+m_bias+".png");
+c6->Print("Plots/plot6_"+m_board+"_s"+m_sector+"_vb"+m_bias+".root");
+
+
+   fout->Write();
+   
+
+}
diff --git a/TbUT/scripts/ClusterWithTrackAna.h b/TbUT/scripts/ClusterWithTrackAna.h
new file mode 100644
index 0000000..a1e86da
--- /dev/null
+++ b/TbUT/scripts/ClusterWithTrackAna.h
@@ -0,0 +1,485 @@
+/////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Oct  1 20:13:36 2015 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+//////////////////////////////////////////////////////////
+
+#ifndef ClusterWithTrackAna_h
+#define ClusterWithTrackAna_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TProfile.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TLegend.h>
+#include <TBox.h>
+#include <TLine.h>
+
+#include "CMS.h"
+#include "AnalysisBase.h"
+
+//#include "ClusterWithTrackAna_Inputs.h"
+
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+#include <iostream>
+#include <algorithm>
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class ClusterWithTrackAna  : public AnalysisBase{
+public :
+   
+  CMS *fCMS;
+
+  ClusterWithTrackAna(int biasVal);
+  //ClusterWithTrackAna(TTree *tree=0);
+   virtual ~ClusterWithTrackAna();
+   virtual void     Loop();
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+};
+
+#endif
+
+#ifdef ClusterWithTrackAna_cxx
+ClusterWithTrackAna::ClusterWithTrackAna(int biasVal){
+  //ClusterWithTrackAna::ClusterWithTrackAna(TTree *tree){
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+  TString filename;
+  if(biasVal != 0) m_bias = Form("%d",biasVal);
+  TTree* tree = 0;
+  
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     TString scanType = "Run_Bias";
+     //   filename = m_fileIndir+"Board"+m_board+"/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root";  
+     cout << "defining file" << endl;
+     //filename = "$KEPLERROOT/../TbUT/scripts/AddTrigTracks/out.root";
+
+filename = m_fileIndir+scanType+"_Scan-"+m_board+"-"+runplace+"-"+consR+"-"+m_runNumb+"_Tracks.root";
+
+       if(m_scanType.Contains("Angle")){ 
+       scanType = "Run_Angle"; 
+       filename = m_fileIndir+"Board"+m_board+"_Angle/"+scanType+"_Scan-"+getFileBase("Bias",m_board, m_bias, m_angle,m_sector)+"_Tuple_Tracks.root";  
+      } 
+     
+     cout << "===> Opening file: " << filename << endl;
+     
+
+     // lxplus
+     //
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6
+     //
+
+     TFile *f = new TFile(filename);
+     tree = (TTree*)f->Get("Clusters");
+     TH1F *hn = (TH1F*)f->Get("hWidthNoise");
+     for(int i=0;i<nChan;i++){
+       noise[i] = hn->GetBinContent(i+1);
+     }
+
+     // Get mean noise and width
+     hMeanNoise 	= (TH1F*)f->Get("hMeanNoise"); 
+     hWidthNoise 	= (TH1F*)f->Get("hWidthNoise"); 
+     cout << "===> Opening file: " << filename << endl;
+
+     TString filename2 = filename.ReplaceAll("_Tracks","");
+     TFile * f2 = new TFile(filename2);
+     if(f2) {
+       TTree * tree2 = (TTree*) f2->Get("TbUT/CMS");
+       if(tree2) {
+         tree->AddFriend(tree2);
+         fCMS = new CMS(tree2);
+       }else{
+         fCMS=0;  
+       }
+     } else {
+       cout << "WARNING: Could not find CMS data file: " << filename2 << endl;
+       fCMS =0 ;
+     }
+   }
+   Init(tree);
+   
+
+
+}
+
+ClusterWithTrackAna::~ClusterWithTrackAna()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+TString ClusterWithTrackAna::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) {
+
+  TString tag = "";
+
+  if(board.Contains("A6")){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+      if ( bias == "250" ) tag = "B6-A-213-8359";
+      if ( bias == "200" ) tag = "B6-A-214-8361";
+      if ( bias == "150" ) tag = "B6-A-215-8362";
+      if ( bias == "100" ) tag = "B6-A-216-8363";
+      if ( bias == "75" )  tag = "B6-A-219-8365";
+      if ( bias == "50" )  tag = "B6-A-220-8366";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+      if ( bias == "250" ) tag = "B6-A-245-8392";
+      if ( bias == "200" ) tag = "B6-A-246-8393";
+      if ( bias == "150" ) tag = "B6-A-247-8394";
+      if ( bias == "100" ) tag = "B6-A-248-8395";
+      if ( bias == "75" )  tag = "B6-A-249-8396";
+      if ( bias == "50" )  tag = "B6-A-250-8397";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+      if ( bias == "250" ) tag = "B6-A-294-8426";
+      if ( bias == "200" ) tag = "B6-A-295-8427";
+      if ( bias == "150" ) tag = "B6-A-296-8428";
+      if ( bias == "100" ) tag = "B6-A-297-8429";
+      if ( bias == "75" )  tag = "B6-A-298-8430";
+      if ( bias == "50" )  tag = "B6-A-299-8431";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+      if ( bias == "250" ) tag = "B6-A-327-8453";
+      if ( bias == "200" ) tag = "B6-A-328-8454";
+      if ( bias == "150" ) tag = "B6-A-329-8455";
+      if ( bias == "100" ) tag = "B6-A-330-8456";
+      if ( bias == "75" )  tag = "B6-A-331-8457";
+      if ( bias == "50" )  tag = "B6-A-332-8458";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-378-8494";
+      if ( bias == "250" ) tag = "B6-A-381-8497";
+      if ( bias == "200" ) tag = "B6-A-382-8498";
+      if ( bias == "150" ) tag = "B6-A-383-8499";
+      if ( bias == "100" ) tag = "B6-A-384-8500";
+      if ( bias == "75" )  tag = "B6-A-385-8501";
+      if ( bias == "50" )  tag = "B6-A-386-8502";
+    } else if(sector == "6"){
+      if ( bias == "300" ) tag = "B6-A-408-8523";
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+      if ( bias == "200" ) tag = "B6-A-410-8525";
+      if ( bias == "150" ) tag = "B6-A-411-8526";
+      if ( bias == "100" ) tag = "B6-A-412-8527";
+      if ( bias == "75" )  tag = "B6-A-413-8528";
+      if ( bias == "50" )  tag = "B6-A-414-8529";
+    }
+  } else if (board.Contains("A4")) {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+      if(bias == "350" ) tag = "B4-A-211-8553";
+      if(bias == "300" ) tag = "B4-A-212-8554";
+      if(bias == "250" ) tag = "B4-A-213-8555";
+      if(bias == "200" ) tag = "B4-A-214-8556";
+      if(bias == "150" ) tag = "B4-A-215-8557";
+      if(bias == "100" ) tag = "B4-A-216-8558";
+      if(bias == "75" )  tag = "B4-A-217-8559";
+      if(bias == "50" )  tag = "B4-A-218-8560";
+    }else if(sector == "2") {
+      if(bias == "400" ) tag = "B4-A-242-8583";
+      if(bias == "350" ) tag = "B4-A-243-8584";
+      if(bias == "300" ) tag = "B4-A-246-8586";
+      if(bias == "250" ) tag = "B4-A-247-8587";
+      if(bias == "200" ) tag = "B4-A-248-8588";
+      if(bias == "150" ) tag = "B4-A-249-8589";
+      if(bias == "100" ) tag = "B4-A-250-8590";
+      if(bias == "75" )  tag = "B4-A-251-8591";
+      if(bias == "50" )  tag = "B4-A-252-8592";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+      if(bias == "350" ) tag = "B4-A-276-8616";
+      if(bias == "300" ) tag = "B4-A-277-8617";
+      if(bias == "250" ) tag = "B4-A-278-8618";
+      if(bias == "200" ) tag = "B4-A-279-8619";
+      if(bias == "150" ) tag = "B4-A-280-8620";
+      if(bias == "100" ) tag = "B4-A-281-8621";
+      if(bias == "75" )  tag = "B4-A-282-8622";
+      if(bias == "50" )  tag = "B4-A-283-8623";
+    } else if(sector == "4"){
+      if(bias == "400" ) tag = "B4-A-217-8651";
+      if(bias == "350" ) tag = "B4-A-218-8652";
+      if(bias == "300" ) tag = "B4-A-219-8653";
+      if(bias == "250" ) tag = "B4-A-220-8654";
+      if(bias == "200" ) tag = "B4-A-221-8655";
+      if(bias == "150" ) tag = "B4-A-222-8656";
+      if(bias == "100" ) tag = "B4-A-223-8657";
+      if(bias == "75" )  tag = "B4-A-224-8658";
+      if(bias == "50" )  tag = "B4-A-225-8659";
+    } else if(sector == "5"){
+      if(bias == "400" ) tag = "B4-A-246-8680";
+      if(bias == "350" ) tag = "B4-A-247-8681";
+      if(bias == "300" ) tag = "B4-A-248-8682";
+      if(bias == "250" ) tag = "B4-A-249-8683";
+      if(bias == "200" ) tag = "B4-A-250-8684";
+      if(bias == "150" ) tag = "B4-A-251-8685";
+      if(bias == "100" ) tag = "B4-A-252-8686";
+      if(bias == "75" )  tag = "B4-A-253-8687";
+      if(bias == "50" )  tag = "B4-A-254-8688";
+    } else if(sector == "6"){
+      if(bias == "400" ) tag = "B4-A-227-8711";
+      if(bias == "350" ) tag = "B4-A-228-8712";
+      if(bias == "300" ) tag = "B4-A-229-8713";
+      if(bias == "250" ) tag = "B4-A-230-8714";
+      if(bias == "200" ) tag = "B4-A-231-8715";
+      if(bias == "150" ) tag = "B4-A-232-8716";
+      if(bias == "100" ) tag = "B4-A-233-8717";
+      if(bias == "75" )  tag = "B4-A-234-8718";
+      if(bias == "50" )  tag = "B4-A-235-8719";
+      tag = tag.ReplaceAll("B4","B1");
+    }
+  } else if (board.Contains("A8")) {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+      if(bias == "400") tag = "B8-A-297-13333";
+      if(bias == "350") tag = "B8-A-298-13334";
+      if(bias == "300") tag = "B8-A-299-13335";
+      if(bias == "250") tag = "B8-A-300-13336";
+      if(bias == "200") tag = "B8-A-301-13337";
+      if(bias == "150") tag = "B8-A-302-13338";
+      if(bias == "100") tag = "B8-A-303-13339";
+      if(bias == "75")  tag = "B8-A-304-13340";
+      if(bias == "50")  tag = "B8-A-305-13341";
+      if(m_scanType=="Angle" && angle=="10" && bias == "300") tag = "B8-A-378-13399";
+      if(m_scanType=="Angle" && angle=="20" && bias == "300") tag = "B8-A-379-13400";
+    }else if (sector == "2"){
+      //if(bias == "500") tag = "B8-A-321-13354";
+      if(bias == "400") tag = "B8-A-324-13355";
+      if(bias == "350") tag = "B8-A-325-13356";
+      if(bias == "300") tag = "B8-A-327-13357";
+      if(bias == "250") tag = "B8-A-328-13358";
+      if(bias == "200") tag = "B8-A-329-13359";
+      if(bias == "150") tag = "B8-A-330-13360";
+      if(bias == "100") tag = "B8-A-331-13361";
+      if(bias == "75")  tag = "B8-A-332-13362";
+      if(bias == "50") tag = "B8-A-333-13363";
+    }else if (sector == "3"){
+      //if(bias == "500") tag = "B8-A-358-13385";
+      if(bias == "400") tag = "B8-A-359-13386";
+      if(bias == "350") tag = "B8-A-360-13387";
+      if(bias == "300") tag = "B8-A-361-13388";
+      if(bias == "250") tag = "B8-A-365-13389";
+      if(bias == "200") tag = "B8-A-366-13390";
+      if(bias == "150") tag = "B8-A-367-13391";
+      if(bias == "100") tag = "B8-A-368-13392";
+      if(bias == "75")  tag = "B8-A-369-13393";
+      if(bias == "50")  tag = "B8-A-370-13394";
+    }else if (sector == "4"){
+      //if(bias == "500") tag = "B8-A-309-13344";
+      if(bias == "400") tag = "B8-A-311-13345";
+      if(bias == "350") tag = "B8-A-312-13346";
+      if(bias == "300") tag = "B8-A-314-13347";
+      if(bias == "250") tag = "B8-A-315-13348";
+      if(bias == "200") tag = "B8-A-316-13349";
+      if(bias == "150") tag = "B8-A-317-13350";
+      if(bias == "100") tag = "B8-A-318-13351";
+      if(bias == "75")  tag = "B8-A-319-13352";
+      if(bias == "50")  tag = "B8-A-320-13353";
+    }else if (sector == "5"){
+      //if(bias == "500") tag = "B8-A-334-13364";
+      if(bias == "400") tag = "B8-A-337-13365";
+      if(bias == "350") tag = "B8-A-339-13367";
+      if(bias == "300") tag = "B8-A-340-13368";
+      if(bias == "250") tag = "B8-A-341-13369";
+      if(bias == "200") tag = "B8-A-342-13370";
+      if(bias == "150") tag = "B8-A-343-13371";
+      if(bias == "100") tag = "B8-A-344-13372";
+      if(bias == "75")  tag = "B8-A-345-13373";
+      if(bias == "50")  tag = "B8-A-346-13374";
+      if(bias != "400") tag = tag.ReplaceAll("B8","B1");
+    }else if (sector == "6"){
+      //if(bias == "500") tag = "B8-A-347-13375";
+      if(bias == "400") tag = "B8-A-348-13376";
+      if(bias == "350") tag = "B8-A-349-13377";
+      if(bias == "300") tag = "B8-A-350-13378";
+      if(bias == "250") tag = "B8-A-352-13379";
+      if(bias == "200") tag = "B8-A-353-13380";
+      if(bias == "150") tag = "B8-A-354-13381";
+      if(bias == "100") tag = "B8-A-355-13382";
+      if(bias == "75")  tag = "B8-A-356-13383";
+      if(bias == "50")  tag = "B8-A-357-13384";
+      tag = tag.ReplaceAll("B8","B1");
+    }
+  } else if (board.Contains("D5")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B5-D-14-13066";
+      if(bias == "75") tag = "B5-D-13-13065";
+      if(bias == "100") tag = "B5-D-12-13064";
+      if(bias == "150") tag = "B5-D-11-13063";
+      if(bias == "200") tag = "B5-D-10-13062";
+      if(bias == "250") tag = "B5-D-6-13058";
+      if(bias == "300") tag = "B5-D-19-13071";
+      if(bias == "350") tag = "B5-D-4-13056";
+      if(bias == "400") tag = "B5-D-3-13055";
+      if(bias == "500") tag = "B5-D-16-13068";
+    }else if(sector == "2"){
+      if(bias == "50")  tag = "B5-D-119-13165";
+      if(bias == "75")  tag = "B5-D-118-13164";
+      if(bias == "100") tag = "B5-D-117-13163";
+      if(bias == "150") tag = "B5-D-116-13162";
+      if(bias == "200") tag = "B5-D-115-13161";
+      if(bias == "250") tag = "B5-D-114-13160";
+      if(bias == "300") tag = "B5-D-113-13159";
+      if(bias == "350") tag = "B5-D-111-13157";
+      if(bias == "400") tag = "B5-D-110-13156";
+      if(bias == "500") tag = "B5-D-109-13155";
+    }else if(sector == "3"){
+      if(bias == "50")  tag = "B5-D-167-13209";
+      if(bias == "75")  tag = "B5-D-166-13208";
+      if(bias == "100") tag = "B5-D-165-13207";
+      if(bias == "150") tag = "B5-D-164-13206";
+      if(bias == "200") tag = "B5-D-163-13205";
+      if(bias == "250") tag = "B5-D-162-13204";
+      if(bias == "300") tag = "B5-D-159-13202";
+      if(bias == "350") tag = "B5-D-158-13201";
+      if(bias == "400") tag = "B5-D-157-13200";
+      if(bias == "500") tag = "B5-D-156-13199";
+    }else if(sector == "4"){
+      if(bias == "50")  tag = "B5-D-65-13114";
+      if(bias == "75")  tag = "B5-D-64-13113";
+      if(bias == "100") tag = "B5-D-63-13112";
+      if(bias == "150") tag = "B5-D-62-13111";
+      if(bias == "200") tag = "B5-D-61-13110";
+      if(bias == "250") tag = "B5-D-59-13108";
+      if(bias == "300") tag = "B5-D-58-13107";
+      if(bias == "350") tag = "B5-D-57-13106";
+      if(bias == "400") tag = "B5-D-56-13105";
+      if(bias == "500") tag = "B5-D-55-13104";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B5-D-218-13253";
+      if(bias == "75")  tag = "B5-D-217-13252";
+      if(bias == "100") tag = "B5-D-216-13251";
+      if(bias == "150") tag = "B5-D-215-13250";
+      if(bias == "200") tag = "B5-D-214-13249";
+      if(bias == "250") tag = "B5-D-213-13248";
+      if(bias == "300") tag = "B5-D-212-13247";
+      if(bias == "350") tag = "B5-D-211-13246";
+      if(bias == "400") tag = "B5-D-210-13245";
+      if(bias == "500") tag = "B5-D-209-13244";
+    }else if(sector == "6"){
+      if(bias == "50")  tag = "B5-D-260-13294";
+      if(bias == "75")  tag = "B5-D-259-13293";
+      if(bias == "100") tag = "B5-D-258-13292";
+      if(bias == "150") tag = "B5-D-257-13291";
+      if(bias == "200") tag = "B5-D-256-13290";
+      if(bias == "250") tag = "B5-D-255-13289";
+      if(bias == "300") tag = "B5-D-254-13288";
+      if(bias == "350") tag = "B5-D-253-13287";
+      if(bias == "400") tag = "B5-D-252-13286";
+      if(bias == "500") tag = "B5-D-251-13285";
+    }
+  } else if (board.Contains("D7")) {
+    if(sector == "1"){
+      if(bias == "50") tag = "B1-D-347-9360";
+      if(bias == "75") tag = "B1-D-346-9359";
+      if(bias == "100") tag = "B1-D-344-9356";
+      if(bias == "150") tag = "B1-D-345-9357";
+      if(bias == "200") tag = "B1-D-343-9355";
+      if(bias == "300") tag = "B1-D-343-9354";
+      if(bias == "400") tag = "B1-D-341-9353";
+      if(bias == "500") tag = "B1-D-340-9272";
+    }else if(sector == "2"){
+      if(bias == "50") tag = "B1-D-471-9659";
+      if(bias == "75") tag = "B1-D-470-9658";
+      if(bias == "100") tag = "B1-D-469-9657";
+      if(bias == "150") tag = "B1-D-468-9656";
+      if(bias == "200") tag = "B1-D-467-9655";
+      if(bias == "300") tag = "B1-D-466-9654";
+      if(bias == "400") tag = "B1-D-465-9653";
+      if(bias == "500") tag = "B1-D-464-9652";
+    }else if(sector == "3"){
+      if(bias == "50") tag = "B1-D-472-9660";
+      if(bias == "75") tag = "B1-D-473-9661";
+      if(bias == "100") tag = "B1-D-474-9662";
+      if(bias == "150") tag = "B1-D-475-9663";
+      if(bias == "200") tag = "B1-D-476-9664";
+      if(bias == "300") tag = "B1-D-477-9665";
+      if(bias == "400") tag = "B1-D-478-9666";
+      if(bias == "500") tag = "B1-D-479-9667";
+    }else if(sector == "4"){
+      if(bias == "50") tag =  "B1-D-379-9424";
+      if(bias == "75") tag =  "B1-D-378-9423";
+      if(bias == "100") tag = "B1-D-377-9422";
+      if(bias == "150") tag = "B1-D-376-9421";
+      if(bias == "200") tag = "B1-D-375-9419";
+      if(bias == "300") tag = "B1-D-374-9417";
+      if(bias == "400") tag = "B1-D-373-9415";
+      if(bias == "500") tag = "B1-D-372-9413";
+    }else if(sector == "5"){
+      if(bias == "50")  tag = "B1-D-489-9763";
+      if(bias == "75")  tag = "B1-D-488-9762";
+      if(bias == "100") tag = "B1-D-487-9761";
+      if(bias == "150") tag = "B1-D-484-9674";
+      if(bias == "200") tag = "B1-D-483-9673";
+      if(bias == "300") tag = "B1-D-482-9672";
+      if(bias == "400") tag = "B1-D-481-9671";
+      if(bias == "500") tag = "B1-D-480-9670";
+    }else if(sector == "6"){
+      if(bias == "50") tag =  "B1-D-321-9252";
+      if(bias == "75") tag =  "B1-D-320-9251";
+      if(bias == "100") tag = "B1-D-319-9250";
+      if(bias == "150") tag = "B1-D-318-9249";
+      if(bias == "200") tag = "B1-D-317-9248";
+      if(bias == "300") tag = "B1-D-316-9247";
+      if(bias == "400") tag = "B1-D-315-9246";
+      if(bias == "500") tag = "B1-D-314-9245";
+    }
+  } else if (board.Contains("A1")) {
+    if(sector == "1"){    
+      if(bias == "350") tag = "B1-A-1022-13947";
+      if(bias == "300") tag = "B1-A-1021-13946";
+      if(bias == "250") tag = "B1-A-1053-13971";
+      if(bias == "200") tag = "B1-A-1052-13970";
+      if(bias == "150") tag = "B1-A-1015-13939";
+      if(bias == "100") tag = "B1-A-1014-13938";
+      if(bias == "75")  tag = "B1-A-1013-13937";
+      if(bias == "50")  tag = "B1-A-1012-13936";
+    }else if(sector == "2"){
+      if(bias == "350") tag = "B1-A-1062-13980";
+      if(bias == "300") tag = "B1-A-1061-13979";
+      if(bias == "250") tag = "B1-A-1060-13978";
+      if(bias == "200") tag = "B1-A-1059-13977";
+      if(bias == "150") tag = "B1-A-1058-13976";
+      if(bias == "100") tag = "B1-A-1057-13975";
+      if(bias == "75")  tag = "B1-A-1056-13974";
+      if(bias == "50")  tag = "B1-A-1055-13973";
+    }    
+  } else if (board.Contains("A2")) {
+    if(sector == "1"){    
+      if(bias == "340") tag = "B2-A-1095-14030";
+      if(bias == "325") tag = "B2-A-1094-14029";
+      if(bias == "300") tag = "B2-A-1084-14017";
+      if(bias == "250") tag = "B2-A-1083-14016";
+      if(bias == "200") tag = "B2-A-1082-14015";
+      if(bias == "150") tag = "B2-A-1081-14014";
+      if(bias == "100") tag = "B2-A-1078-14013";
+      if(bias == "75")  tag = "B2-A-1077-14012";
+      if(bias == "50")  tag = "B2-A-1076-14011";
+      if(bias == "300" && angle=="-1") tag = "B2-A-1085-14018";
+      if(bias == "300" && angle=="1") tag = "B2-A-1088-14021";
+    }else if(sector == "2"){
+      if(bias == "340") tag = "B2-A-1099-14034";
+      if(bias == "325") tag = "B2-A-1098-14033";
+      if(bias == "300") tag = "B2-A-1097-14032";
+      if(bias == "250") tag = "B2-A-1100-14035";
+      if(bias == "200") tag = "B2-A-1101-14036";
+      if(bias == "150") tag = "B2-A-1102-14037";
+      if(bias == "100") tag = "B2-A-1103-14038";
+      if(bias == "75")  tag = "B2-A-1104-14039";
+      if(bias == "50")  tag = "B2-A-1105-14040";
+    }    
+  }
+
+  return tag;
+}
+
+
+#endif // #ifdef ClusterWithTrackAna_cxx
diff --git a/TbUT/scripts/ClusterWithTrackAna_C.d b/TbUT/scripts/ClusterWithTrackAna_C.d
new file mode 100644
index 0000000..f96ae71
--- /dev/null
+++ b/TbUT/scripts/ClusterWithTrackAna_C.d
@@ -0,0 +1,97 @@
+
+# DO NOT DELETE
+
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/output/./../Tb/TbUT/scripts/ClusterWithTrackAna.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TROOT.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectory.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TNamed.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObject.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypes.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RConfig.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/DllImport.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Rtypeinfo.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/snprintf.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/strlcpy.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGenericClassInfo.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSchemaHelper.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStorage.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVersionCheck.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Riosfwd.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBuffer.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TString.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMathBase.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TList.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TSeqCollection.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCollection.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TIterator.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDatime.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUUID.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TChain.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TTree.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBranch.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjArray.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttFill.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDataType.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDictionary.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Property.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttLine.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttMarker.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayD.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArray.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayI.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TClass.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TObjString.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualTreePlayer.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFile.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TDirectoryFile.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMap.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/THashTable.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TUrl.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TProfile.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH1.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAxis.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttAxis.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayC.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayS.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TArrayF.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Foption.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorFfwd.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVectorDfwd.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFitResultPtr.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH1F.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH2F.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TH2.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixFBasefwd.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMatrixDBasefwd.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TLegend.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TPave.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBox.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttText.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TLine.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/output/./../Tb/TbUT/scripts/CMS.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/output/./../Tb/TbUT/scripts/AnalysisBase.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TMath.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TError.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TF1.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TFormula.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TBits.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Math/ParamFunctor.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGraph.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TGraphErrors.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/work/i/ibezshyi/public/TESTBEAM/ChrisSoft/KeplerDev_v3r0/output/./../Tb/TbUT/scripts/AnalysisBase_Inputs.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TStyle.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TLatex.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TText.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCanvas.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TPad.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualPad.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttPad.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TVirtualX.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/GuiTypes.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/Buttons.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TQObject.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TAttCanvas.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/TCanvasImp.h
+./../Tb/TbUT/scripts/ClusterWithTrackAna_C.so: /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/cintdictversion.h /afs/cern.ch/sw/lcg/app/releases/ROOT/5.34.10/x86_64-slc6-gcc48-opt/root/include/RVersion.h
+ClusterWithTrackAna_C__ROOTBUILDVERSION= 5.34/10
diff --git a/TbUT/scripts/ClusterWithTrackAna_C.so b/TbUT/scripts/ClusterWithTrackAna_C.so
new file mode 100755
index 0000000..10415fd
--- /dev/null
+++ b/TbUT/scripts/ClusterWithTrackAna_C.so
Binary files differ
diff --git a/TbUT/scripts/ClusterWithTrackAna_Inputs.h b/TbUT/scripts/ClusterWithTrackAna_Inputs.h
new file mode 100644
index 0000000..b0b1540
--- /dev/null
+++ b/TbUT/scripts/ClusterWithTrackAna_Inputs.h
@@ -0,0 +1,32 @@
+double nChan = 512.0;
+double stripPitch = 0.190;
+double z_DUT = 370;
+//double Rz = -0.0218;
+double Rz = -0.0218;
+double Ry = 0.00;
+double dxWin = 0.25;
+double xGloOff = -9.2;
+double yGloOff = -7.5;
+double xOff = -54.78;
+
+int kClusterChargeMin = 120;
+
+double ratioForHole = 0.05;
+
+double ratioForDeadStrip = 0.6;
+double ratioForNoisyStrip = 1.8;
+
+bool vetoDeadStripRegions = true;
+double k_DeadStrip = 0.12;
+
+bool writeEventsWithMissinhHitsToFile = false;   // flag to write events to file with missing DUT hit
+
+double trackTriggerTimeDiffCut = 2.5;
+
+bool isPType = true;
+
+
+// Notes
+// For Rz alignment, one should SUBTRACT the slope found from the deltaX vs Y plot.
+// For Z alignment, one should ADD the slope found from the deltaX vs Y plot.
+//
diff --git a/TbUT/scripts/ClusterWithTrackAna_README b/TbUT/scripts/ClusterWithTrackAna_README
new file mode 100644
index 0000000..55eb6c0
--- /dev/null
+++ b/TbUT/scripts/ClusterWithTrackAna_README
@@ -0,0 +1,51 @@
+//
+// S. Blusk, Oct 6, 2015
+// Updated April 21, 2016 -- S. Blusk
+
+This is a simple script to loop over a TB run that has ben processed by TbUT and has tracks added to the ntuple.
+To run interactively:
+
+< 
+
+In you home area, create your own work area:
+> mkdir TBANAL/
+> cd TBANAL
+>   mkdir Output
+>   mkdir Plots/
+
+Set up ROOT environment (ROOT 5!) - code is not fully compliant with ROOT 6.
+>
+//> setenv CMTCONFIG x86_64-slc5-gcc46-opt
+
+
+
+LbLogin -c x86_64-slc6-gcc48-opt
+> SetupProject LHCb v36r2
+> root [0] .x runClusterWithTrackAna.C
+
+
+* Right now, it is set up to run over a file in the area:
+  const TString m_fileIndir = "/afs/cern.ch/work/s/sblusk/public/TB/";
+and it picks up the file in subdirectory: "BoardA6/", set with:
+  const TString m_board   = "A6";
+
+* Only the files defined in ClusterWithTrackAna.h will run, so if you grab a different
+file, you need to check it is a good run and in the list of files. As of April 21, 2016,
+only the fgood 2015 test beam runs are included.
+
+
+[*] A set of plot should pop up after the script runs, and an output ROOT file called histOutput.root is created.
+
+[*] Until we have a more refinced processing scheme, files that you want to test should be put in by hand into 
+ClusterWithTrackAna::getFileBase (follow the examples in there).
+
+[*] Input & output files directories are included in the Analysis_Inputs.h
+
+Once we have to process many runs, we should have a way of automatically providing the input file and the output file.
+This is being worked on...
+
+
+KNOWN ISSUES
+------------
+
+* Array stripGap[4] need to be updated to depend on the particular sensor. Right now, it's assumed no gaps for Type A, and same gaps for all type D.
diff --git a/TbUT/scripts/ExampleAnalysis.C b/TbUT/scripts/ExampleAnalysis.C
new file mode 100644
index 0000000..24d7bc1
--- /dev/null
+++ b/TbUT/scripts/ExampleAnalysis.C
@@ -0,0 +1,142 @@
+//
+//    Example Analysis code
+//    Stripped down version to loop over tracks and clusters with alignment, etc.
+//    Date: Oct 27, 2015
+// 
+#define ExampleAnalysis_cxx
+#include "ExampleAnalysis.h"
+#include <TH2.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+#include <iostream>
+#include <fstream>
+
+
+void ExampleAnalysis::Loop(){
+
+  if (fChain == 0) return;
+
+   Int_t nentries = fChain->GetEntriesFast();
+
+   //--------------------------------------
+   // Create output file to save histograms
+   //--------------------------------------
+   fout = new TFile(f_out,"RECREATE");
+
+   // Just add 2 histograms, as examples
+   TH1F* h1w = new TH1F("h1w","#DeltaX",20000,-100.0,100.0);
+   TH1F *hnoise = new TH1F("hnoise","Noise in connected channels",100,-200,200);
+   TH1F* h12dd = new TH1F("h12dd","X position of track",200,-10.0,10.0);h12dd->Sumw2();
+   TH1F* h12dn = new TH1F("h12dn","X position of track",200,-10.0,10.0);h12dn->Sumw2();
+   //------------------------------------------------------------------------------------------------------
+
+   //-----------------------------------------------
+   // Example for writing some information to a file
+   //-----------------------------------------------
+   std::ofstream myfile;
+   if(writeEventsWithMissinhHitsToFile){
+     myfile.open("MissingDUTHits.dat");
+   }
+
+   // Prepare DUT - Alignment, etc
+   PrepareDUT();
+   
+
+   // ----------------------
+   // Begin Analysis Loop
+   // ----------------------
+   int iChan = nChan;
+   double nomStrip = 0;
+   int njump = 10000;
+   if(nentries > 100000) njump = 50000;
+   Long64_t nbytes = 0, nb = 0;
+   cout << "Begin loop over " << nentries << " events" << endl;
+
+   // Begin loop over events
+   for (Long64_t jentry=0; jentry<nentries;jentry++) {
+      Long64_t ientry = LoadTree(jentry);
+      if (ientry < 0) break;
+      nb = fChain->GetEntry(jentry);   nbytes += nb;
+      if(jentry%njump==0) cout << "====> At entry = " << jentry << endl;
+      if(n_tp3_tracks != 1) continue; // Require 1 and only 1 TPIX track
+
+      //==========================================
+      // Example here of acccessing CMS strip data
+      //==========================================
+      if(fCMS){
+        for(int k=0;k<iChan;k++){
+          if(fCMS->cmsData[k]!=0) hnoise->Fill(fCMS->cmsData[k]);
+        }      
+      }
+      
+      // Loop over TPIX tracks in event
+      for(int k=0; k<n_tp3_tracks; k++){
+        if(dtime > trackTriggerTimeDiffCut) continue;
+        double x_trk = vec_trk_tx->at(k)*z_DUT+vec_trk_x->at(k);
+        double y_trk = vec_trk_ty->at(k)*z_DUT+vec_trk_y->at(k);
+        double tx = 1000*vec_trk_tx->at(k);
+        double ty = 1000*vec_trk_ty->at(k);
+
+        transformTrackToDUTFrame(k, x_trk, y_trk, nomStrip);
+
+        // If you want to remove tracks in region of hole, can change 'removeTracksInHoleDef = false' to not remove them.
+        if(isInCutoutRegion(x_trk, y_trk)) continue;
+       
+        bool goodRegion = true;
+        for(int id = 0; id<nDeadRegion; id++){
+          if(x_trk>=deadRegionLo[id]  && x_trk<=deadRegionHi[id]) goodRegion = false;  
+        }
+        if(!goodRegion) continue;
+
+        bool goodTrack = false;
+        bool inFiducialX = false;
+        bool inFiducialY = false;
+        if(x_trk>xMin && x_trk<xMax) inFiducialX = true;          
+        if(y_trk>yMin && y_trk<yMax) inFiducialY = true;          
+        bool inFiducial = inFiducialX && inFiducialY;
+        inFiducial = inFiducial && (x_trk<xLeftHole || x_trk>xRightHole);
+        
+        if(tx>txMin && tx<txMax && ty>tyMin && ty<tyMax) goodTrack = true;        
+        bool goodTime =  (clustersTDC >= tdcLo && clustersTDC <= tdcHi);
+
+        bool foundHit = false;
+        double x_trk0 = x_trk;
+
+        // Begin loop over CLUSTERS
+        for(int j=0; j<min(clusterNumberPerEvent,10); j++){
+          if(clustersPosition[j] < 0.1) continue;
+          x_trk = x_trk0;
+
+          double x_dut = getDUTHitPosition(j);
+          
+          double dx = x_dut - x_trk;
+
+          if(goodTrack && inFiducial && goodTime) {
+            h1w->Fill(dx);
+            if(fabs(dx)<dxWin) foundHit = true;
+          }
+        } // End Loop over Clusters
+
+        // ------------------------
+        // Efficiency studies, etc
+        // ------------------------
+        if(inFiducial && goodTrack && goodTime) {
+          h12dd->Fill(x_trk); // X pos of good tracks
+          if(foundHit) {
+            h12dn->Fill(x_trk);  // X position when a hit was found within 200 um
+          } else {   
+            // Here, you might do something else when no DUT hits are not found
+            if(writeEventsWithMissinhHitsToFile) 
+              myfile << jentry << " " << nomStrip << " " << x_trk << " " << y_trk << endl;              
+          }
+        } 
+      }// End Loop over Tracks
+   } // End Loop over Events
+
+   if(writeEventsWithMissinhHitsToFile) myfile.close();
+   
+
+   fout->Write();
+   
+
+}
diff --git a/TbUT/scripts/ExampleAnalysis.h b/TbUT/scripts/ExampleAnalysis.h
new file mode 100644
index 0000000..32f3165
--- /dev/null
+++ b/TbUT/scripts/ExampleAnalysis.h
@@ -0,0 +1,134 @@
+/////////////////////////////////////////////////////////
+// This class has been automatically generated on
+// Thu Oct  1 20:13:36 2015 by ROOT version 5.34/10
+// from TTree Clusters/TbUT nTuple
+//////////////////////////////////////////////////////////
+
+#ifndef ExampleAnalysis_h
+#define ExampleAnalysis_h
+
+#include <TROOT.h>
+#include <TChain.h>
+#include <TFile.h>
+#include <TProfile.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TLegend.h>
+#include <TBox.h>
+#include <TLine.h>
+
+#include "AnalysisBase.h"
+#include "CMS.h"
+
+//#include "ExampleAnalysis_Inputs.h"
+
+// Header file for the classes stored in the TTree if any.
+#include <vector>
+#include <iostream>
+#include <algorithm>
+
+// Fixed size dimensions of array or collections stored in the TTree if any.
+
+class ExampleAnalysis  : public AnalysisBase{
+public :
+   
+  CMS            *fCMS;
+
+   ExampleAnalysis(TTree *tree=0);
+   virtual ~ExampleAnalysis();
+   virtual void     Loop();
+  virtual TString getFileBase(TString scan="Bias", TString board="", TString bias="", TString angle="0", TString sector="1");  
+
+  TFile *fout;
+};
+
+#endif
+
+#ifdef ExampleAnalysis_cxx
+ExampleAnalysis::ExampleAnalysis(TTree *tree){
+// if parameter tree is not specified (or zero), connect the file
+// used to generate this class and read the Tree.
+  TString filename;
+   if (tree == 0) {
+     //
+     // lhcb-dev
+     //
+     filename = m_fileIndir+"Board"+m_board+"/Run_Bias_Scan-"+getFileBase("Bias",m_board, m_bias, "0",m_sector)+"_Tuple_Tracks.root"; 
+
+     // lxplus
+     //
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-296-13332_Tuple_Tracks.root"; // A8 - s1
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-324-13355_Tuple_Tracks.root"; // A8 - s2
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA8/Run_Bias_Scan-B8-A-359-13386_Tuple_Tracks.root";  // A8 - s3
+     //filename = "/afs/cern.ch/work/s/sblusk/public/TB/2015/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple_Tracks.root";   // A6
+     //
+
+     TFile *f = new TFile(filename);
+     tree = (TTree*)f->Get("Clusters");
+
+     // Get mean noise and width
+     hMeanNoise 	= (TH1F*)f->Get("hMeanNoise"); 
+     hWidthNoise 	= (TH1F*)f->Get("hWidthNoise"); 
+
+     TString filename2 = filename.ReplaceAll("_Tracks","");
+     TFile * f2 = new TFile(filename2);
+     if(f2) {
+       TTree * tree2 = (TTree*) f2->Get("TbUT/CMS");
+       if(tree2) {
+         tree->AddFriend(tree2);
+         fCMS = new CMS(tree2);
+       }else{
+         fCMS=0;  
+       }
+     } else {
+       cout << "WARNING: Could not find CMS data file: " << filename2 << endl;
+       fCMS =0 ;
+     }
+   }
+   Init(tree);
+}
+
+ExampleAnalysis::~ExampleAnalysis()
+{
+   if (!fChain) return;
+   delete fChain->GetCurrentFile();
+}
+TString ExampleAnalysis::getFileBase(TString scan, TString board, TString bias, TString angle, TString sector) {
+
+  TString tag = "";
+
+  if(board == "A6"){
+    if(sector == "1") {
+      if ( bias == "300" ) tag = "B6-A-212-8358";
+    } else if(sector == "2"){
+      if ( bias == "300" ) tag = "B6-A-242-8389";
+    } else if(sector == "3"){
+      if ( bias == "300" ) tag = "B6-A-293-8425";
+    } else if(sector == "4"){
+      if ( bias == "300" ) tag = "B6-A-326-8452";
+    } else if(sector == "5"){
+      if ( bias == "300" ) tag = "B6-A-377-8494";
+    } else if(sector == "6"){
+      if ( bias == "250" ) tag = "B6-A-409-8524";
+    }
+  } else if (board == "A4") {
+    if(sector == "1") {
+      if(bias == "400" ) tag = "B4-A-210-8552";
+    } else if(sector == "3"){
+      if(bias == "400" ) tag = "B4-A-275-8615";
+    }
+  } else if (board == "A8") {
+    if(sector == "1"){
+      if(bias == "500") tag = "B8-A-296-13332";
+    }else if (sector == "2"){
+      if(bias == "400") tag = "B8-A-324-13355";
+    }else if (sector == "3"){
+      if(bias == "400") tag = "B8-A-359-13386";
+    }
+  }
+
+  return tag;
+}
+
+
+#endif // #ifdef ExampleAnalysis_cxx
diff --git a/TbUT/scripts/ExampleAnalysis_C.d b/TbUT/scripts/ExampleAnalysis_C.d
new file mode 100644
index 0000000..a58f959
--- /dev/null
+++ b/TbUT/scripts/ExampleAnalysis_C.d
@@ -0,0 +1,206 @@
+
+# DO NOT DELETE
+
+./ExampleAnalysis_C.so: ExampleAnalysis.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TROOT.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDirectory.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TNamed.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TObject.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Rtypes.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RtypesCore.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RConfig.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RVersion.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/DllImport.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Rtypeinfo.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/typeinfo
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/exception
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++config.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/os_defines.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/cpu_defines.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/atomic_lockfree_defines.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/snprintf.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/strlcpy.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/atomic
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/c++0x_warning.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/atomic_base.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TGenericClassInfo.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/vector
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_algobase.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/functexcept.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/exception_defines.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/cpp_type_traits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/type_traits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/numeric_traits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_pair.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/move.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/concept_check.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_iterator_base_types.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_iterator_base_funcs.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/debug/debug.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_iterator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ptr_traits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/predefined_ops.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/allocator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++allocator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/new_allocator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/new
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/memoryfwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_construct.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/alloc_traits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_uninitialized.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_vector.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_bvector.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/range_access.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/vector.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TSchemaHelper.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/string
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stringfwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/char_traits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/postypes.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cwchar
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/localefwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++locale.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/clocale
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iosfwd
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cctype
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ostream_insert.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/cxxabi_forced.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_function.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/backward/binders.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_string.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ext/atomicity.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/gthr.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/gthr-default.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/atomic_word.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_string.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TStorage.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVersionCheck.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Riosfwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBuffer.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TString.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMathBase.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cstdlib
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cmath
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TList.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TSeqCollection.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCollection.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TIterator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iterator
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ostream
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/ios
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ios_base.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_classes.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_classes.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/streambuf
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/streambuf.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_ios.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_facets.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cwctype
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/ctype_base.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/streambuf_iterator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/ctype_inline.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/locale_facets.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/basic_ios.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/ostream.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/istream
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/istream.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stream_iterator.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDatime.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TUUID.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RConfigure.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TChain.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TTree.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBranch.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TObjArray.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttFill.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDataType.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDictionary.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/ESTLType.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttLine.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttMarker.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayD.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArray.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayI.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TClass.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TObjString.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/map
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_tree.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_map.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_multimap.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/set
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_set.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_multiset.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/unordered_set
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/ThreadLocalStorage.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualTreePlayer.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFile.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDirectoryFile.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMap.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/THashTable.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TUrl.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TProfile.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TH1.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAxis.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttAxis.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayC.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayS.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TArrayF.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Foption.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVectorFfwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVectorDfwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFitResultPtr.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TH1F.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TH2F.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TH2.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMatrixFBasefwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMatrixDBasefwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TLegend.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TPave.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBox.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttBBox2D.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/GuiTypes.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TPoint.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttText.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TLine.h
+./ExampleAnalysis_C.so: AnalysisBase.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/iostream
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMath.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TError.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/algorithm
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/utility
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_relops.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_algo.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/algorithmfwd.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_heap.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/stl_tempbuf.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/limits
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TF1.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFormula.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBits.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Math/ParamFunctor.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TGraph.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TGraphErrors.h
+./ExampleAnalysis_C.so: AnalysisBase_Inputs.h CMS.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TStyle.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCanvas.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TPad.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualPad.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttPad.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualX.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Buttons.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TQObject.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TQObjectEmitVA.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TQConnection.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/Varargs.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TInterpreter.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TVirtualMutex.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TAttCanvas.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCanvasImp.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/fstream
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/codecvt.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/cstdio
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/basic_file.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/x86_64-unknown-linux-gnu/bits/c++io.h
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/gcc/4.9.1/x86_64-slc6/include/c++/4.9.1/bits/fstream.tcc
+./ExampleAnalysis_C.so: /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RVersion.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RConfig.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TClass.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TDictAttributeMap.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TInterpreter.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TROOT.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TBuffer.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TMemberInspector.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TError.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/RtypesImp.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TIsAProxy.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TFileMergeInfo.h /afs/cern.ch/sw/lcg/releases/ROOT/6.02.05-9ad88/x86_64-slc6-gcc49-opt/include/TCollectionProxyInfo.h
+ExampleAnalysis_C__ROOTBUILDVERSION= 6.02/05
diff --git a/TbUT/scripts/Plots/cluster.pdf b/TbUT/scripts/Plots/cluster.pdf
new file mode 100644
index 0000000..608bbe2
--- /dev/null
+++ b/TbUT/scripts/Plots/cluster.pdf
Binary files differ
diff --git a/TbUT/scripts/Plots/cluster_charge b/TbUT/scripts/Plots/cluster_charge
new file mode 100644
index 0000000..b49ef79
--- /dev/null
+++ b/TbUT/scripts/Plots/cluster_charge
@@ -0,0 +1,4 @@
+{
+//========= Macro generated from object: TFrame/Pad graphics frame
+//========= by ROOT version5.34/07
+}
diff --git a/TbUT/scripts/Plots/cluster_charge.pdf b/TbUT/scripts/Plots/cluster_charge.pdf
new file mode 100644
index 0000000..b49ef79
--- /dev/null
+++ b/TbUT/scripts/Plots/cluster_charge.pdf
@@ -0,0 +1,4 @@
+{
+//========= Macro generated from object: TFrame/Pad graphics frame
+//========= by ROOT version5.34/07
+}
diff --git a/TbUT/scripts/Plots/cluster_charge.root b/TbUT/scripts/Plots/cluster_charge.root
new file mode 100644
index 0000000..a8ef46b
--- /dev/null
+++ b/TbUT/scripts/Plots/cluster_charge.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_A6_s3_vb50.png b/TbUT/scripts/Plots/plot1_A6_s3_vb50.png
new file mode 100644
index 0000000..d6c1353
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_A6_s3_vb50.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_A6_s6_vb300.png b/TbUT/scripts/Plots/plot1_A6_s6_vb300.png
new file mode 100644
index 0000000..d6c1353
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_A6_s6_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_A6_s6_vb300.root b/TbUT/scripts/Plots/plot1_A6_s6_vb300.root
new file mode 100644
index 0000000..a055694
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_A6_s6_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_M1_sPA_vb300.png b/TbUT/scripts/Plots/plot1_M1_sPA_vb300.png
new file mode 100644
index 0000000..d6c1353
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_M1_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_M1_sPA_vb300.root b/TbUT/scripts/Plots/plot1_M1_sPA_vb300.root
new file mode 100644
index 0000000..3f3fc4f
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_M1_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_M1_test_sPA_vb300.png b/TbUT/scripts/Plots/plot1_M1_test_sPA_vb300.png
new file mode 100644
index 0000000..7412de2
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_M1_test_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot1_M1_test_sPA_vb300.root b/TbUT/scripts/Plots/plot1_M1_test_sPA_vb300.root
new file mode 100644
index 0000000..d3d9eea
--- /dev/null
+++ b/TbUT/scripts/Plots/plot1_M1_test_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_A6_s3_vb50.png b/TbUT/scripts/Plots/plot5_A6_s3_vb50.png
new file mode 100644
index 0000000..7df0ba9
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_A6_s3_vb50.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_A6_s6_vb300.png b/TbUT/scripts/Plots/plot5_A6_s6_vb300.png
new file mode 100644
index 0000000..7df0ba9
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_A6_s6_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_A6_s6_vb300.root b/TbUT/scripts/Plots/plot5_A6_s6_vb300.root
new file mode 100644
index 0000000..14cf845
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_A6_s6_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_M1_sPA_vb300.png b/TbUT/scripts/Plots/plot5_M1_sPA_vb300.png
new file mode 100644
index 0000000..00e1a4e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_M1_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_M1_sPA_vb300.root b/TbUT/scripts/Plots/plot5_M1_sPA_vb300.root
new file mode 100644
index 0000000..54f193f
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_M1_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_M1_test_sPA_vb300.png b/TbUT/scripts/Plots/plot5_M1_test_sPA_vb300.png
new file mode 100644
index 0000000..f9d7181
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_M1_test_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot5_M1_test_sPA_vb300.root b/TbUT/scripts/Plots/plot5_M1_test_sPA_vb300.root
new file mode 100644
index 0000000..6559373
--- /dev/null
+++ b/TbUT/scripts/Plots/plot5_M1_test_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_A6_s3_vb50.png b/TbUT/scripts/Plots/plot6_A6_s3_vb50.png
new file mode 100644
index 0000000..b3b0a7e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_A6_s3_vb50.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_A6_s6_vb300.png b/TbUT/scripts/Plots/plot6_A6_s6_vb300.png
new file mode 100644
index 0000000..b3b0a7e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_A6_s6_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_A6_s6_vb300.root b/TbUT/scripts/Plots/plot6_A6_s6_vb300.root
new file mode 100644
index 0000000..5ed2b14
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_A6_s6_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_M1_sPA_vb300.png b/TbUT/scripts/Plots/plot6_M1_sPA_vb300.png
new file mode 100644
index 0000000..b3b0a7e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_M1_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_M1_sPA_vb300.root b/TbUT/scripts/Plots/plot6_M1_sPA_vb300.root
new file mode 100644
index 0000000..ff509d5
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_M1_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_M1_test_sPA_vb300.png b/TbUT/scripts/Plots/plot6_M1_test_sPA_vb300.png
new file mode 100644
index 0000000..84a7de4
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_M1_test_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot6_M1_test_sPA_vb300.root b/TbUT/scripts/Plots/plot6_M1_test_sPA_vb300.root
new file mode 100644
index 0000000..1c61795
--- /dev/null
+++ b/TbUT/scripts/Plots/plot6_M1_test_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_A6_s3_vb50.png b/TbUT/scripts/Plots/plot8_A6_s3_vb50.png
new file mode 100644
index 0000000..f175a7e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_A6_s3_vb50.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_A6_s6_vb300.png b/TbUT/scripts/Plots/plot8_A6_s6_vb300.png
new file mode 100644
index 0000000..f175a7e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_A6_s6_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_A6_s6_vb300.root b/TbUT/scripts/Plots/plot8_A6_s6_vb300.root
new file mode 100644
index 0000000..3b9753d
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_A6_s6_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_M1_sPA_vb300.png b/TbUT/scripts/Plots/plot8_M1_sPA_vb300.png
new file mode 100644
index 0000000..f175a7e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_M1_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_M1_sPA_vb300.root b/TbUT/scripts/Plots/plot8_M1_sPA_vb300.root
new file mode 100644
index 0000000..6ce08c1
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_M1_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_M1_test_sPA_vb300.png b/TbUT/scripts/Plots/plot8_M1_test_sPA_vb300.png
new file mode 100644
index 0000000..53ff1b4
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_M1_test_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot8_M1_test_sPA_vb300.root b/TbUT/scripts/Plots/plot8_M1_test_sPA_vb300.root
new file mode 100644
index 0000000..406bd9d
--- /dev/null
+++ b/TbUT/scripts/Plots/plot8_M1_test_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_A6_s3_vb50.png b/TbUT/scripts/Plots/plot_A6_s3_vb50.png
new file mode 100644
index 0000000..e4f3f30
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_A6_s3_vb50.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_A6_s3_vb50.root b/TbUT/scripts/Plots/plot_A6_s3_vb50.root
new file mode 100644
index 0000000..2af6e8a
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_A6_s3_vb50.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_A6_s6_vb300.png b/TbUT/scripts/Plots/plot_A6_s6_vb300.png
new file mode 100644
index 0000000..2ec19c2
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_A6_s6_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_A6_s6_vb300.root b/TbUT/scripts/Plots/plot_A6_s6_vb300.root
new file mode 100644
index 0000000..45a7e72
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_A6_s6_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_M1_sPA_vb300.png b/TbUT/scripts/Plots/plot_M1_sPA_vb300.png
new file mode 100644
index 0000000..2ec19c2
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_M1_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_M1_sPA_vb300.root b/TbUT/scripts/Plots/plot_M1_sPA_vb300.root
new file mode 100644
index 0000000..a78311f
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_M1_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_M1_test_sPA_vb300.png b/TbUT/scripts/Plots/plot_M1_test_sPA_vb300.png
new file mode 100644
index 0000000..d8b4fcd
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_M1_test_sPA_vb300.png
Binary files differ
diff --git a/TbUT/scripts/Plots/plot_M1_test_sPA_vb300.root b/TbUT/scripts/Plots/plot_M1_test_sPA_vb300.root
new file mode 100644
index 0000000..6a4e54e
--- /dev/null
+++ b/TbUT/scripts/Plots/plot_M1_test_sPA_vb300.root
Binary files differ
diff --git a/TbUT/scripts/Plots/test.root b/TbUT/scripts/Plots/test.root
new file mode 100644
index 0000000..b578667
--- /dev/null
+++ b/TbUT/scripts/Plots/test.root
Binary files differ
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/all-wcprops b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/all-wcprops
new file mode 100644
index 0000000..8885e9c
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/all-wcprops
@@ -0,0 +1,23 @@
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/195785/Kepler/trunk/Tb/TbUT/scripts/TbUTAutomaticAnalyzer
+END
+July2015Database.xml
+K 25
+svn:wc:ra_dav:version-url
+V 99
+/guest/lhcb/!svn/ver/195785/Kepler/trunk/Tb/TbUT/scripts/TbUTAutomaticAnalyzer/July2015Database.xml
+END
+TbUTAnalyzer.py
+K 25
+svn:wc:ra_dav:version-url
+V 94
+/guest/lhcb/!svn/ver/195785/Kepler/trunk/Tb/TbUT/scripts/TbUTAutomaticAnalyzer/TbUTAnalyzer.py
+END
+XmlGenerator.py
+K 25
+svn:wc:ra_dav:version-url
+V 94
+/guest/lhcb/!svn/ver/195785/Kepler/trunk/Tb/TbUT/scripts/TbUTAutomaticAnalyzer/XmlGenerator.py
+END
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/entries b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/entries
new file mode 100644
index 0000000..6b079f2
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/entries
@@ -0,0 +1,130 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/scripts/TbUTAutomaticAnalyzer
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-10-08T18:06:50.323206Z
+195785
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+July2015Database.xml
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+bb4a6f4958298c3c48e95054ffc971ee
+2015-10-08T18:06:50.323206Z
+195785
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+49946
+
+TbUTAnalyzer.py
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+56e17719fb4c621a215bee681c7bd35d
+2015-10-08T18:06:50.323206Z
+195785
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2763
+
+XmlGenerator.py
+file
+
+
+
+
+2016-03-16T13:50:21.000000Z
+6da5708b0d099cc618107582a18519e9
+2015-10-08T18:06:50.323206Z
+195785
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1278
+
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/July2015Database.xml.svn-base b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/July2015Database.xml.svn-base
new file mode 100644
index 0000000..dc7ea1b
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/July2015Database.xml.svn-base
@@ -0,0 +1 @@
+<root><directory name="BoardA4"><Pedestal><file>Pedestal-B1-A-193-8195.dat</file><file>Pedestal-B1-A-201-8328.dat</file><file>Pedestal-B1-A-202-8329.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B4-A-130-0.dat</file><file>Run_Bias_Scan-B4-A-131-8136.dat</file><file>Run_Bias_Scan-B4-A-132-8137.dat</file><file>Run_Bias_Scan-B4-A-136-8139.dat</file><file>Run_Bias_Scan-B4-A-137-8140.dat</file><file>Run_Bias_Scan-B4-A-138-8141.dat</file><file>Run_Bias_Scan-B4-A-139-8142.dat</file><file>Run_Bias_Scan-B4-A-140-8143.dat</file><file>Run_Bias_Scan-B4-A-141-8144.dat</file><file>Run_Bias_Scan-B4-A-142-8145.dat</file><file>Run_Bias_Scan-B4-A-143-8146.dat</file><file>Run_Bias_Scan-B4-A-144-8147.dat</file><file>Run_Bias_Scan-B4-A-171-8175.dat</file><file>Run_Bias_Scan-B4-A-172-8176.dat</file><file>Run_Bias_Scan-B4-A-173-8177.dat</file><file>Run_Bias_Scan-B4-A-174-8178.dat</file><file>Run_Bias_Scan-B4-A-175-8179.dat</file><file>Run_Bias_Scan-B4-A-176-8180.dat</file><file>Run_Bias_Scan-B4-A-177-8181.dat</file><file>Run_Bias_Scan-B4-A-178-8181.dat</file><file>Run_Bias_Scan-B4-A-179-8183.dat</file><file>Run_Bias_Scan-B4-A-180-8184.dat</file><file>Run_Bias_Scan-B4-A-181-8185.dat</file><file>Run_Bias_Scan-B4-A-182-8186.dat</file><file>Run_Bias_Scan-B4-A-210-8210.dat</file><file>Run_Bias_Scan-B4-A-211-8210.dat</file><file>Run_Bias_Scan-B4-A-220-8213.dat</file><file>Run_Bias_Scan-B4-A-221-8214.dat</file><file>Run_Bias_Scan-B4-A-222-8215.dat</file><file>Run_Bias_Scan-B4-A-223-8216.dat</file><file>Run_Bias_Scan-B4-A-224-8217.dat</file><file>Run_Bias_Scan-B4-A-225-8218.dat</file><file>Run_Bias_Scan-B4-A-226-8219.dat</file><file>Run_Bias_Scan-B4-A-227-8220.dat</file><file>Run_Bias_Scan-B4-A-228-8221.dat</file><file>Run_Bias_Scan-B4-A-229-8222.dat</file><file>Run_Bias_Scan-B4-A-254-8246.dat</file><file>Run_Bias_Scan-B4-A-255-8247.dat</file><file>Run_Bias_Scan-B4-A-256-8248.dat</file><file>Run_Bias_Scan-B4-A-257-8249.dat</file><file>Run_Bias_Scan-B4-A-258-8250.dat</file><file>Run_Bias_Scan-B4-A-259-8251.dat</file><file>Run_Bias_Scan-B4-A-260-8252.dat</file><file>Run_Bias_Scan-B4-A-261-8253.dat</file><file>Run_Bias_Scan-B4-A-262-8254.dat</file><file>Run_Bias_Scan-B4-A-263-8255.dat</file><file>Run_Bias_Scan-B4-A-291-8279.dat</file><file>Run_Bias_Scan-B4-A-292-8280.dat</file><file>Run_Bias_Scan-B4-A-293-8281.dat</file><file>Run_Bias_Scan-B4-A-294-8282.dat</file><file>Run_Bias_Scan-B4-A-295-8283.dat</file><file>Run_Bias_Scan-B4-A-296-8284.dat</file><file>Run_Bias_Scan-B4-A-297-8285.dat</file><file>Run_Bias_Scan-B4-A-298-8286.dat</file><file>Run_Bias_Scan-B4-A-299-8287.dat</file><file>Run_Bias_Scan-B4-A-300-8288.dat</file><file>Run_Bias_Scan-B4-A-327-8311.dat</file><file>Run_Bias_Scan-B4-A-328-8312.dat</file><file>Run_Bias_Scan-B4-A-329-8313.dat</file><file>Run_Bias_Scan-B4-A-330-8314.dat</file><file>Run_Bias_Scan-B4-A-331-8315.dat</file><file>Run_Bias_Scan-B4-A-332-8316.dat</file><file>Run_Bias_Scan-B4-A-333-8317.dat</file><file>Run_Bias_Scan-B4-A-334-8317.dat</file><file>Run_Bias_Scan-B4-A-335-8317.dat</file><file>Run_Bias_Scan-B4-A-338-8319.dat</file><file>Run_Bias_Scan-B4-A-339-8320.dat</file><file>Run_Bias_Scan-B4-A-340-8321.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-203-8330.dat</file><file>Run_Angle_Scan-B1-A-206-8331.dat</file><file>Run_Angle_Scan-B1-A-208-8331.dat</file><file>Run_Angle_Scan-B1-A-209-8333.dat</file><file>Run_Angle_Scan-B1-A-212-8335.dat</file><file>Run_Angle_Scan-B1-A-214-8335.dat</file><file>Run_Angle_Scan-B1-A-216-8337.dat</file><file>Run_Angle_Scan-B1-A-217-8339.dat</file><file>Run_Angle_Scan-B1-A-218-8340.dat</file><file>Run_Angle_Scan-B1-A-219-8341.dat</file><file>Run_Angle_Scan-B1-A-220-8342.dat</file><file>Run_Angle_Scan-B1-A-222-8343.dat</file><file>Run_Angle_Scan-B4-A-145-8148.dat</file><file>Run_Angle_Scan-B4-A-146-8149.dat</file><file>Run_Angle_Scan-B4-A-147-8150.dat</file><file>Run_Angle_Scan-B4-A-148-8151.dat</file><file>Run_Angle_Scan-B4-A-149-8152.dat</file><file>Run_Angle_Scan-B4-A-150-8154.dat</file><file>Run_Angle_Scan-B4-A-151-8155.dat</file><file>Run_Angle_Scan-B4-A-152-8156.dat</file><file>Run_Angle_Scan-B4-A-153-8157.dat</file><file>Run_Angle_Scan-B4-A-154-8158.dat</file><file>Run_Angle_Scan-B4-A-155-8159.dat</file><file>Run_Angle_Scan-B4-A-156-8160.dat</file><file>Run_Angle_Scan-B4-A-157-8161.dat</file><file>Run_Angle_Scan-B4-A-158-8162.dat</file><file>Run_Angle_Scan-B4-A-159-8163.dat</file><file>Run_Angle_Scan-B4-A-160-8164.dat</file><file>Run_Angle_Scan-B4-A-161-8165.dat</file><file>Run_Angle_Scan-B4-A-162-8166.dat</file><file>Run_Angle_Scan-B4-A-163-8167.dat</file><file>Run_Angle_Scan-B4-A-164-8168.dat</file><file>Run_Angle_Scan-B4-A-165-8169.dat</file><file>Run_Angle_Scan-B4-A-166-8170.dat</file><file>Run_Angle_Scan-B4-A-167-8171.dat</file><file>Run_Angle_Scan-B4-A-168-8172.dat</file><file>Run_Angle_Scan-B4-A-169-8173.dat</file><file>Run_Angle_Scan-B4-A-170-8174.dat</file><file>Run_Angle_Scan-B4-A-183-8187.dat</file><file>Run_Angle_Scan-B4-A-184-8188.dat</file><file>Run_Angle_Scan-B4-A-185-8189.dat</file><file>Run_Angle_Scan-B4-A-186-8190.dat</file><file>Run_Angle_Scan-B4-A-187-8191.dat</file><file>Run_Angle_Scan-B4-A-188-8192.dat</file><file>Run_Angle_Scan-B4-A-189-8193.dat</file><file>Run_Angle_Scan-B4-A-190-8194.dat</file><file>Run_Angle_Scan-B4-A-194-8195.dat</file><file>Run_Angle_Scan-B4-A-195-8196.dat</file><file>Run_Angle_Scan-B4-A-196-8197.dat</file><file>Run_Angle_Scan-B4-A-197-8198.dat</file><file>Run_Angle_Scan-B4-A-198-8199.dat</file><file>Run_Angle_Scan-B4-A-199-8200.dat</file><file>Run_Angle_Scan-B4-A-200-8201.dat</file><file>Run_Angle_Scan-B4-A-203-8203.dat</file><file>Run_Angle_Scan-B4-A-204-8204.dat</file><file>Run_Angle_Scan-B4-A-205-8205.dat</file><file>Run_Angle_Scan-B4-A-206-8206.dat</file><file>Run_Angle_Scan-B4-A-207-8207.dat</file><file>Run_Angle_Scan-B4-A-208-8208.dat</file><file>Run_Angle_Scan-B4-A-209-8209.dat</file><file>Run_Angle_Scan-B4-A-223-8344.dat</file><file>Run_Angle_Scan-B4-A-224-8345.dat</file><file>Run_Angle_Scan-B4-A-225-8346.dat</file><file>Run_Angle_Scan-B4-A-226-8347.dat</file><file>Run_Angle_Scan-B4-A-227-8348.dat</file><file>Run_Angle_Scan-B4-A-228-8349.dat</file><file>Run_Angle_Scan-B4-A-229-8350.dat</file><file>Run_Angle_Scan-B4-A-230-8223.dat</file><file>Run_Angle_Scan-B4-A-230-8351.dat</file><file>Run_Angle_Scan-B4-A-231-8224.dat</file><file>Run_Angle_Scan-B4-A-231-8352.dat</file><file>Run_Angle_Scan-B4-A-232-8353.dat</file><file>Run_Angle_Scan-B4-A-233-8225.dat</file><file>Run_Angle_Scan-B4-A-234-8226.dat</file><file>Run_Angle_Scan-B4-A-235-8227.dat</file><file>Run_Angle_Scan-B4-A-236-8229.dat</file><file>Run_Angle_Scan-B4-A-237-8230.dat</file><file>Run_Angle_Scan-B4-A-238-8231.dat</file><file>Run_Angle_Scan-B4-A-239-8232.dat</file><file>Run_Angle_Scan-B4-A-240-8233.dat</file><file>Run_Angle_Scan-B4-A-241-8234.dat</file><file>Run_Angle_Scan-B4-A-242-8235.dat</file><file>Run_Angle_Scan-B4-A-243-8236.dat</file><file>Run_Angle_Scan-B4-A-244-8237.dat</file><file>Run_Angle_Scan-B4-A-245-8238.dat</file><file>Run_Angle_Scan-B4-A-246-8239.dat</file><file>Run_Angle_Scan-B4-A-247-8240.dat</file><file>Run_Angle_Scan-B4-A-248-8241.dat</file><file>Run_Angle_Scan-B4-A-249-8242.dat</file><file>Run_Angle_Scan-B4-A-250-8243.dat</file><file>Run_Angle_Scan-B4-A-251-8243.dat</file><file>Run_Angle_Scan-B4-A-252-8244.dat</file><file>Run_Angle_Scan-B4-A-253-8245.dat</file><file>Run_Angle_Scan-B4-A-264-8256.dat</file><file>Run_Angle_Scan-B4-A-265-8257.dat</file><file>Run_Angle_Scan-B4-A-266-8258.dat</file><file>Run_Angle_Scan-B4-A-267-8259.dat</file><file>Run_Angle_Scan-B4-A-268-8260.dat</file><file>Run_Angle_Scan-B4-A-269-8261.dat</file><file>Run_Angle_Scan-B4-A-271-8262.dat</file><file>Run_Angle_Scan-B4-A-272-8263.dat</file><file>Run_Angle_Scan-B4-A-273-8264.dat</file><file>Run_Angle_Scan-B4-A-274-8265.dat</file><file>Run_Angle_Scan-B4-A-275-8266.dat</file><file>Run_Angle_Scan-B4-A-276-8267.dat</file><file>Run_Angle_Scan-B4-A-277-8268.dat</file><file>Run_Angle_Scan-B4-A-278-8269.dat</file><file>Run_Angle_Scan-B4-A-279-8270.dat</file><file>Run_Angle_Scan-B4-A-280-8271.dat</file><file>Run_Angle_Scan-B4-A-281-8272.dat</file><file>Run_Angle_Scan-B4-A-282-8273.dat</file><file>Run_Angle_Scan-B4-A-286-8274.dat</file><file>Run_Angle_Scan-B4-A-287-8275.dat</file><file>Run_Angle_Scan-B4-A-288-8276.dat</file><file>Run_Angle_Scan-B4-A-289-8277.dat</file><file>Run_Angle_Scan-B4-A-290-8278.dat</file><file>Run_Angle_Scan-B4-A-301-8289.dat</file><file>Run_Angle_Scan-B4-A-302-8290.dat</file><file>Run_Angle_Scan-B4-A-303-8291.dat</file><file>Run_Angle_Scan-B4-A-304-8292.dat</file><file>Run_Angle_Scan-B4-A-305-8293.dat</file><file>Run_Angle_Scan-B4-A-306-8294.dat</file><file>Run_Angle_Scan-B4-A-307-8295.dat</file><file>Run_Angle_Scan-B4-A-308-8296.dat</file><file>Run_Angle_Scan-B4-A-309-8297.dat</file><file>Run_Angle_Scan-B4-A-310-8298.dat</file><file>Run_Angle_Scan-B4-A-311-8299.dat</file><file>Run_Angle_Scan-B4-A-312-8300.dat</file><file>Run_Angle_Scan-B4-A-313-8301.dat</file><file>Run_Angle_Scan-B4-A-314-8302.dat</file><file>Run_Angle_Scan-B4-A-315-8303.dat</file><file>Run_Angle_Scan-B4-A-316-8304.dat</file><file>Run_Angle_Scan-B4-A-317-8304.dat</file><file>Run_Angle_Scan-B4-A-320-8305.dat</file><file>Run_Angle_Scan-B4-A-321-8305.dat</file><file>Run_Angle_Scan-B4-A-322-8307.dat</file><file>Run_Angle_Scan-B4-A-324-8308.dat</file><file>Run_Angle_Scan-B4-A-325-8309.dat</file><file>Run_Angle_Scan-B4-A-326-8310.dat</file><file>Run_Angle_Scan-B4-A-341-8322.dat</file><file>Run_Angle_Scan-B4-A-342-8323.dat</file></AngleScan></directory><directory name="BoardA4_redo"><Pedestal><file>Pedestal-B4-A-209-0.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B1-A-227-8711.dat</file><file>Run_Bias_Scan-B1-A-228-8712.dat</file><file>Run_Bias_Scan-B1-A-229-8713.dat</file><file>Run_Bias_Scan-B1-A-230-8714.dat</file><file>Run_Bias_Scan-B1-A-231-8715.dat</file><file>Run_Bias_Scan-B1-A-232-8716.dat</file><file>Run_Bias_Scan-B1-A-233-8717.dat</file><file>Run_Bias_Scan-B1-A-234-8718.dat</file><file>Run_Bias_Scan-B1-A-235-8719.dat</file><file>Run_Bias_Scan-B4-A-210-8552.dat</file><file>Run_Bias_Scan-B4-A-211-8553.dat</file><file>Run_Bias_Scan-B4-A-212-8554.dat</file><file>Run_Bias_Scan-B4-A-213-8555.dat</file><file>Run_Bias_Scan-B4-A-214-8556.dat</file><file>Run_Bias_Scan-B4-A-215-8557.dat</file><file>Run_Bias_Scan-B4-A-216-8558.dat</file><file>Run_Bias_Scan-B4-A-217-8559.dat</file><file>Run_Bias_Scan-B4-A-217-8651.dat</file><file>Run_Bias_Scan-B4-A-218-8560.dat</file><file>Run_Bias_Scan-B4-A-218-8652.dat</file><file>Run_Bias_Scan-B4-A-219-8653.dat</file><file>Run_Bias_Scan-B4-A-220-8654.dat</file><file>Run_Bias_Scan-B4-A-221-8655.dat</file><file>Run_Bias_Scan-B4-A-222-8656.dat</file><file>Run_Bias_Scan-B4-A-223-8657.dat</file><file>Run_Bias_Scan-B4-A-224-8658.dat</file><file>Run_Bias_Scan-B4-A-225-8659.dat</file><file>Run_Bias_Scan-B4-A-242-8583.dat</file><file>Run_Bias_Scan-B4-A-243-8584.dat</file><file>Run_Bias_Scan-B4-A-246-8586.dat</file><file>Run_Bias_Scan-B4-A-246-8680.dat</file><file>Run_Bias_Scan-B4-A-247-8587.dat</file><file>Run_Bias_Scan-B4-A-247-8681.dat</file><file>Run_Bias_Scan-B4-A-248-8588.dat</file><file>Run_Bias_Scan-B4-A-248-8682.dat</file><file>Run_Bias_Scan-B4-A-249-8589.dat</file><file>Run_Bias_Scan-B4-A-249-8683.dat</file><file>Run_Bias_Scan-B4-A-250-8590.dat</file><file>Run_Bias_Scan-B4-A-250-8684.dat</file><file>Run_Bias_Scan-B4-A-251-8591.dat</file><file>Run_Bias_Scan-B4-A-251-8685.dat</file><file>Run_Bias_Scan-B4-A-252-8592.dat</file><file>Run_Bias_Scan-B4-A-252-8686.dat</file><file>Run_Bias_Scan-B4-A-253-8687.dat</file><file>Run_Bias_Scan-B4-A-254-8688.dat</file><file>Run_Bias_Scan-B4-A-273-8613.dat</file><file>Run_Bias_Scan-B4-A-275-8615.dat</file><file>Run_Bias_Scan-B4-A-276-8616.dat</file><file>Run_Bias_Scan-B4-A-277-8617.dat</file><file>Run_Bias_Scan-B4-A-278-8618.dat</file><file>Run_Bias_Scan-B4-A-279-8619.dat</file><file>Run_Bias_Scan-B4-A-280-8620.dat</file><file>Run_Bias_Scan-B4-A-281-8621.dat</file><file>Run_Bias_Scan-B4-A-282-8622.dat</file><file>Run_Bias_Scan-B4-A-283-8623.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-213-8697.dat</file><file>Run_Angle_Scan-B1-A-214-8698.dat</file><file>Run_Angle_Scan-B1-A-215-8699.dat</file><file>Run_Angle_Scan-B1-A-216-8700.dat</file><file>Run_Angle_Scan-B1-A-217-8701.dat</file><file>Run_Angle_Scan-B1-A-218-8702.dat</file><file>Run_Angle_Scan-B1-A-219-8703.dat</file><file>Run_Angle_Scan-B1-A-220-8704.dat</file><file>Run_Angle_Scan-B1-A-221-8705.dat</file><file>Run_Angle_Scan-B1-A-222-8706.dat</file><file>Run_Angle_Scan-B1-A-223-8707.dat</file><file>Run_Angle_Scan-B1-A-224-8708.dat</file><file>Run_Angle_Scan-B1-A-225-8709.dat</file><file>Run_Angle_Scan-B1-A-226-8710.dat</file><file>Run_Angle_Scan-B1-A-236-8720.dat</file><file>Run_Angle_Scan-B1-A-237-8721.dat</file><file>Run_Angle_Scan-B1-A-238-8722.dat</file><file>Run_Angle_Scan-B1-A-239-8723.dat</file><file>Run_Angle_Scan-B1-A-240-8724.dat</file><file>Run_Angle_Scan-B1-A-241-8725.dat</file><file>Run_Angle_Scan-B1-A-242-8726.dat</file><file>Run_Angle_Scan-B1-A-243-8727.dat</file><file>Run_Angle_Scan-B1-A-244-8728.dat</file><file>Run_Angle_Scan-B1-A-245-8729.dat</file><file>Run_Angle_Scan-B1-A-246-8730.dat</file><file>Run_Angle_Scan-B1-A-247-8731.dat</file><file>Run_Angle_Scan-B1-A-248-8732.dat</file><file>Run_Angle_Scan-B1-A-249-8733.dat</file><file>Run_Angle_Scan-B1-A-250-8734.dat</file><file>Run_Angle_Scan-B1-A-251-8735.dat</file><file>Run_Angle_Scan-B1-A-252-8736.dat</file><file>Run_Angle_Scan-B1-A-253-8737.dat</file><file>Run_Angle_Scan-B1-A-254-8738.dat</file><file>Run_Angle_Scan-B1-A-255-8739.dat</file><file>Run_Angle_Scan-B4-A-209-8643.dat</file><file>Run_Angle_Scan-B4-A-209-8694.dat</file><file>Run_Angle_Scan-B4-A-210-8644.dat</file><file>Run_Angle_Scan-B4-A-210-8695.dat</file><file>Run_Angle_Scan-B4-A-211-8645.dat</file><file>Run_Angle_Scan-B4-A-211-8696.dat</file><file>Run_Angle_Scan-B4-A-212-8646.dat</file><file>Run_Angle_Scan-B4-A-213-8647.dat</file><file>Run_Angle_Scan-B4-A-214-8648.dat</file><file>Run_Angle_Scan-B4-A-215-8649.dat</file><file>Run_Angle_Scan-B4-A-216-8650.dat</file><file>Run_Angle_Scan-B4-A-219-8561.dat</file><file>Run_Angle_Scan-B4-A-220-8562.dat</file><file>Run_Angle_Scan-B4-A-221-8563.dat</file><file>Run_Angle_Scan-B4-A-222-8564.dat</file><file>Run_Angle_Scan-B4-A-223-8565.dat</file><file>Run_Angle_Scan-B4-A-224-8566.dat</file><file>Run_Angle_Scan-B4-A-225-8567.dat</file><file>Run_Angle_Scan-B4-A-226-8568.dat</file><file>Run_Angle_Scan-B4-A-226-8660.dat</file><file>Run_Angle_Scan-B4-A-227-8569.dat</file><file>Run_Angle_Scan-B4-A-227-8661.dat</file><file>Run_Angle_Scan-B4-A-228-8570.dat</file><file>Run_Angle_Scan-B4-A-228-8662.dat</file><file>Run_Angle_Scan-B4-A-229-8571.dat</file><file>Run_Angle_Scan-B4-A-229-8663.dat</file><file>Run_Angle_Scan-B4-A-230-8572.dat</file><file>Run_Angle_Scan-B4-A-230-8664.dat</file><file>Run_Angle_Scan-B4-A-231-8573.dat</file><file>Run_Angle_Scan-B4-A-231-8665.dat</file><file>Run_Angle_Scan-B4-A-232-8574.dat</file><file>Run_Angle_Scan-B4-A-232-8666.dat</file><file>Run_Angle_Scan-B4-A-233-8575.dat</file><file>Run_Angle_Scan-B4-A-233-8667.dat</file><file>Run_Angle_Scan-B4-A-234-8576.dat</file><file>Run_Angle_Scan-B4-A-234-8668.dat</file><file>Run_Angle_Scan-B4-A-235-8669.dat</file><file>Run_Angle_Scan-B4-A-236-8670.dat</file><file>Run_Angle_Scan-B4-A-237-8578.dat</file><file>Run_Angle_Scan-B4-A-237-8671.dat</file><file>Run_Angle_Scan-B4-A-238-8579.dat</file><file>Run_Angle_Scan-B4-A-238-8672.dat</file><file>Run_Angle_Scan-B4-A-239-8580.dat</file><file>Run_Angle_Scan-B4-A-239-8673.dat</file><file>Run_Angle_Scan-B4-A-240-8581.dat</file><file>Run_Angle_Scan-B4-A-240-8674.dat</file><file>Run_Angle_Scan-B4-A-241-8582.dat</file><file>Run_Angle_Scan-B4-A-241-8675.dat</file><file>Run_Angle_Scan-B4-A-242-8676.dat</file><file>Run_Angle_Scan-B4-A-243-8677.dat</file><file>Run_Angle_Scan-B4-A-244-8678.dat</file><file>Run_Angle_Scan-B4-A-245-8679.dat</file><file>Run_Angle_Scan-B4-A-253-8593.dat</file><file>Run_Angle_Scan-B4-A-254-8594.dat</file><file>Run_Angle_Scan-B4-A-255-8595.dat</file><file>Run_Angle_Scan-B4-A-255-8689.dat</file><file>Run_Angle_Scan-B4-A-256-8596.dat</file><file>Run_Angle_Scan-B4-A-256-8690.dat</file><file>Run_Angle_Scan-B4-A-257-8597.dat</file><file>Run_Angle_Scan-B4-A-257-8691.dat</file><file>Run_Angle_Scan-B4-A-258-8598.dat</file><file>Run_Angle_Scan-B4-A-258-8692.dat</file><file>Run_Angle_Scan-B4-A-259-8599.dat</file><file>Run_Angle_Scan-B4-A-259-8693.dat</file><file>Run_Angle_Scan-B4-A-260-8600.dat</file><file>Run_Angle_Scan-B4-A-261-8601.dat</file><file>Run_Angle_Scan-B4-A-262-8602.dat</file><file>Run_Angle_Scan-B4-A-263-8603.dat</file><file>Run_Angle_Scan-B4-A-264-8604.dat</file><file>Run_Angle_Scan-B4-A-265-8605.dat</file><file>Run_Angle_Scan-B4-A-266-8606.dat</file><file>Run_Angle_Scan-B4-A-267-8607.dat</file><file>Run_Angle_Scan-B4-A-268-8608.dat</file><file>Run_Angle_Scan-B4-A-269-8609.dat</file><file>Run_Angle_Scan-B4-A-270-8610.dat</file><file>Run_Angle_Scan-B4-A-271-8611.dat</file><file>Run_Angle_Scan-B4-A-272-8612.dat</file><file>Run_Angle_Scan-B4-A-284-8624.dat</file><file>Run_Angle_Scan-B4-A-285-8625.dat</file><file>Run_Angle_Scan-B4-A-286-8626.dat</file><file>Run_Angle_Scan-B4-A-287-8627.dat</file><file>Run_Angle_Scan-B4-A-288-8628.dat</file><file>Run_Angle_Scan-B4-A-289-8629.dat</file><file>Run_Angle_Scan-B4-A-290-8630.dat</file><file>Run_Angle_Scan-B4-A-291-8631.dat</file><file>Run_Angle_Scan-B4-A-292-8632.dat</file><file>Run_Angle_Scan-B4-A-293-8633.dat</file><file>Run_Angle_Scan-B4-A-294-8634.dat</file><file>Run_Angle_Scan-B4-A-295-8635.dat</file><file>Run_Angle_Scan-B4-A-296-8636.dat</file><file>Run_Angle_Scan-B4-A-297-8637.dat</file><file>Run_Angle_Scan-B4-A-298-8638.dat</file><file>Run_Angle_Scan-B4-A-299-8639.dat</file><file>Run_Angle_Scan-B4-A-300-8640.dat</file><file>Run_Angle_Scan-B4-A-301-8641.dat</file><file>Run_Angle_Scan-B4-A-302-8642.dat</file></AngleScan></directory><directory name="BoardA6"><Pedestal><file>Pedestal-B6-A-209-0.dat</file><file>Pedestal-B6-A-263-0.dat</file><file>Pedestal-B6-A-264-1.dat</file><file>Pedestal-B6-A-285-8419.dat</file><file>Pedestal-B6-A-300-8431.dat</file><file>Pedestal-B6-A-319-8445.dat</file><file>Pedestal-B6-A-354-8472.dat</file><file>Pedestal-B6-A-392-8507.dat</file><file>Pedestal-B6-A-393-8508.dat</file><file>Pedestal-B6-A-394-8509.dat</file><file>Pedestal-B6-A-395-8510.dat</file><file>Pedestal-B6-A-396-8511.dat</file><file>Pedestal-B6-A-397-8512.dat</file><file>Pedestal-B6-A-398-8512.dat</file><file>Pedestal-B6-A-399-8514.dat</file><file>Pedestal-B6-A-400-8515.dat</file><file>Pedestal-B6-A-401-8516.dat</file><file>Pedestal-B6-A-402-8517.dat</file><file>Pedestal-B6-A-403-8518.dat</file><file>Pedestal-B6-A-404-8519.dat</file><file>Pedestal-B6-A-405-8520.dat</file><file>Pedestal-B6-A-406-8521.dat</file><file>Pedestal-B6-A-407-8522.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B6-A-210-8356.dat</file><file>Run_Bias_Scan-B6-A-211-8357.dat</file><file>Run_Bias_Scan-B6-A-212-8358.dat</file><file>Run_Bias_Scan-B6-A-213-8359.dat</file><file>Run_Bias_Scan-B6-A-214-8361.dat</file><file>Run_Bias_Scan-B6-A-215-8362.dat</file><file>Run_Bias_Scan-B6-A-216-8363.dat</file><file>Run_Bias_Scan-B6-A-217-8364.dat</file><file>Run_Bias_Scan-B6-A-218-8364.dat</file><file>Run_Bias_Scan-B6-A-219-8365.dat</file><file>Run_Bias_Scan-B6-A-220-8366.dat</file><file>Run_Bias_Scan-B6-A-221-8368.dat</file><file>Run_Bias_Scan-B6-A-242-8389.dat</file><file>Run_Bias_Scan-B6-A-245-8392.dat</file><file>Run_Bias_Scan-B6-A-246-8393.dat</file><file>Run_Bias_Scan-B6-A-247-8394.dat</file><file>Run_Bias_Scan-B6-A-248-8395.dat</file><file>Run_Bias_Scan-B6-A-249-8396.dat</file><file>Run_Bias_Scan-B6-A-250-8397.dat</file><file>Run_Bias_Scan-B6-A-267-8409.dat</file><file>Run_Bias_Scan-B6-A-272-8410.dat</file><file>Run_Bias_Scan-B6-A-292-8424.dat</file><file>Run_Bias_Scan-B6-A-293-8425.dat</file><file>Run_Bias_Scan-B6-A-294-8426.dat</file><file>Run_Bias_Scan-B6-A-295-8427.dat</file><file>Run_Bias_Scan-B6-A-296-8428.dat</file><file>Run_Bias_Scan-B6-A-297-8429.dat</file><file>Run_Bias_Scan-B6-A-298-8430.dat</file><file>Run_Bias_Scan-B6-A-299-8431.dat</file><file>Run_Bias_Scan-B6-A-326-8452.dat</file><file>Run_Bias_Scan-B6-A-327-8453.dat</file><file>Run_Bias_Scan-B6-A-328-8454.dat</file><file>Run_Bias_Scan-B6-A-329-8455.dat</file><file>Run_Bias_Scan-B6-A-330-8456.dat</file><file>Run_Bias_Scan-B6-A-331-8457.dat</file><file>Run_Bias_Scan-B6-A-332-8458.dat</file><file>Run_Bias_Scan-B6-A-364-8482.dat</file><file>Run_Bias_Scan-B6-A-378-8494.dat</file><file>Run_Bias_Scan-B6-A-379-8496.dat</file><file>Run_Bias_Scan-B6-A-381-8497.dat</file><file>Run_Bias_Scan-B6-A-382-8498.dat</file><file>Run_Bias_Scan-B6-A-383-8499.dat</file><file>Run_Bias_Scan-B6-A-384-8500.dat</file><file>Run_Bias_Scan-B6-A-385-8501.dat</file><file>Run_Bias_Scan-B6-A-386-8502.dat</file><file>Run_Bias_Scan-B6-A-408-8523.dat</file><file>Run_Bias_Scan-B6-A-409-8524.dat</file><file>Run_Bias_Scan-B6-A-410-8525.dat</file><file>Run_Bias_Scan-B6-A-411-8526.dat</file><file>Run_Bias_Scan-B6-A-412-8527.dat</file><file>Run_Bias_Scan-B6-A-413-8528.dat</file><file>Run_Bias_Scan-B6-A-414-8529.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B6-A-222-8369.dat</file><file>Run_Angle_Scan-B6-A-223-8370.dat</file><file>Run_Angle_Scan-B6-A-224-8371.dat</file><file>Run_Angle_Scan-B6-A-225-8372.dat</file><file>Run_Angle_Scan-B6-A-226-8373.dat</file><file>Run_Angle_Scan-B6-A-227-8374.dat</file><file>Run_Angle_Scan-B6-A-228-8375.dat</file><file>Run_Angle_Scan-B6-A-229-8376.dat</file><file>Run_Angle_Scan-B6-A-230-8377.dat</file><file>Run_Angle_Scan-B6-A-231-8378.dat</file><file>Run_Angle_Scan-B6-A-232-8379.dat</file><file>Run_Angle_Scan-B6-A-233-8380.dat</file><file>Run_Angle_Scan-B6-A-234-8381.dat</file><file>Run_Angle_Scan-B6-A-235-8382.dat</file><file>Run_Angle_Scan-B6-A-236-8383.dat</file><file>Run_Angle_Scan-B6-A-237-8384.dat</file><file>Run_Angle_Scan-B6-A-238-8385.dat</file><file>Run_Angle_Scan-B6-A-239-8386.dat</file><file>Run_Angle_Scan-B6-A-240-8387.dat</file><file>Run_Angle_Scan-B6-A-241-8388.dat</file><file>Run_Angle_Scan-B6-A-251-8398.dat</file><file>Run_Angle_Scan-B6-A-252-8399.dat</file><file>Run_Angle_Scan-B6-A-253-8400.dat</file><file>Run_Angle_Scan-B6-A-256-8402.dat</file><file>Run_Angle_Scan-B6-A-257-8403.dat</file><file>Run_Angle_Scan-B6-A-258-8404.dat</file><file>Run_Angle_Scan-B6-A-259-8405.dat</file><file>Run_Angle_Scan-B6-A-260-8406.dat</file><file>Run_Angle_Scan-B6-A-261-8407.dat</file><file>Run_Angle_Scan-B6-A-262-8408.dat</file><file>Run_Angle_Scan-B6-A-273-8410.dat</file><file>Run_Angle_Scan-B6-A-275-8412.dat</file><file>Run_Angle_Scan-B6-A-276-8413.dat</file><file>Run_Angle_Scan-B6-A-279-8415.dat</file><file>Run_Angle_Scan-B6-A-280-8416.dat</file><file>Run_Angle_Scan-B6-A-281-8417.dat</file><file>Run_Angle_Scan-B6-A-284-8419.dat</file><file>Run_Angle_Scan-B6-A-286-8420.dat</file><file>Run_Angle_Scan-B6-A-288-8420.dat</file><file>Run_Angle_Scan-B6-A-289-8421.dat</file><file>Run_Angle_Scan-B6-A-290-8422.dat</file><file>Run_Angle_Scan-B6-A-291-8423.dat</file><file>Run_Angle_Scan-B6-A-301-8432.dat</file><file>Run_Angle_Scan-B6-A-302-8433.dat</file><file>Run_Angle_Scan-B6-A-303-8434.dat</file><file>Run_Angle_Scan-B6-A-306-8435.dat</file><file>Run_Angle_Scan-B6-A-307-8436.dat</file><file>Run_Angle_Scan-B6-A-308-8437.dat</file><file>Run_Angle_Scan-B6-A-309-8438.dat</file><file>Run_Angle_Scan-B6-A-310-8439.dat</file><file>Run_Angle_Scan-B6-A-311-8440.dat</file><file>Run_Angle_Scan-B6-A-312-8441.dat</file><file>Run_Angle_Scan-B6-A-313-8441.dat</file><file>Run_Angle_Scan-B6-A-316-8443.dat</file><file>Run_Angle_Scan-B6-A-317-8444.dat</file><file>Run_Angle_Scan-B6-A-318-8445.dat</file><file>Run_Angle_Scan-B6-A-320-8446.dat</file><file>Run_Angle_Scan-B6-A-321-8447.dat</file><file>Run_Angle_Scan-B6-A-322-8448.dat</file><file>Run_Angle_Scan-B6-A-323-8449.dat</file><file>Run_Angle_Scan-B6-A-324-8450.dat</file><file>Run_Angle_Scan-B6-A-325-8451.dat</file><file>Run_Angle_Scan-B6-A-333-8459.dat</file><file>Run_Angle_Scan-B6-A-336-8461.dat</file><file>Run_Angle_Scan-B6-A-337-8462.dat</file><file>Run_Angle_Scan-B6-A-338-8463.dat</file><file>Run_Angle_Scan-B6-A-339-8464.dat</file><file>Run_Angle_Scan-B6-A-342-8466.dat</file><file>Run_Angle_Scan-B6-A-343-8467.dat</file><file>Run_Angle_Scan-B6-A-344-8468.dat</file><file>Run_Angle_Scan-B6-A-345-8469.dat</file><file>Run_Angle_Scan-B6-A-352-8471.dat</file><file>Run_Angle_Scan-B6-A-353-8472.dat</file><file>Run_Angle_Scan-B6-A-355-8473.dat</file><file>Run_Angle_Scan-B6-A-356-8474.dat</file><file>Run_Angle_Scan-B6-A-357-8475.dat</file><file>Run_Angle_Scan-B6-A-358-8476.dat</file><file>Run_Angle_Scan-B6-A-359-8477.dat</file><file>Run_Angle_Scan-B6-A-360-8478.dat</file><file>Run_Angle_Scan-B6-A-361-8479.dat</file><file>Run_Angle_Scan-B6-A-362-8480.dat</file><file>Run_Angle_Scan-B6-A-363-8481.dat</file><file>Run_Angle_Scan-B6-A-367-8484.dat</file><file>Run_Angle_Scan-B6-A-368-8485.dat</file><file>Run_Angle_Scan-B6-A-369-8486.dat</file><file>Run_Angle_Scan-B6-A-370-8487.dat</file><file>Run_Angle_Scan-B6-A-371-8488.dat</file><file>Run_Angle_Scan-B6-A-372-8489.dat</file><file>Run_Angle_Scan-B6-A-373-8490.dat</file><file>Run_Angle_Scan-B6-A-374-8491.dat</file><file>Run_Angle_Scan-B6-A-375-8492.dat</file><file>Run_Angle_Scan-B6-A-376-8493.dat</file><file>Run_Angle_Scan-B6-A-377-8494.dat</file><file>Run_Angle_Scan-B6-A-387-8503.dat</file><file>Run_Angle_Scan-B6-A-388-8504.dat</file><file>Run_Angle_Scan-B6-A-389-8505.dat</file><file>Run_Angle_Scan-B6-A-390-8506.dat</file><file>Run_Angle_Scan-B6-A-391-8507.dat</file><file>Run_Angle_Scan-B6-A-415-8530.dat</file><file>Run_Angle_Scan-B6-A-416-8531.dat</file><file>Run_Angle_Scan-B6-A-417-8532.dat</file><file>Run_Angle_Scan-B6-A-418-8533.dat</file><file>Run_Angle_Scan-B6-A-419-8534.dat</file><file>Run_Angle_Scan-B6-A-422-8535.dat</file><file>Run_Angle_Scan-B6-A-423-8536.dat</file><file>Run_Angle_Scan-B6-A-424-8537.dat</file><file>Run_Angle_Scan-B6-A-425-8538.dat</file><file>Run_Angle_Scan-B6-A-426-8539.dat</file><file>Run_Angle_Scan-B6-A-427-8540.dat</file><file>Run_Angle_Scan-B6-A-428-8541.dat</file><file>Run_Angle_Scan-B6-A-429-8542.dat</file><file>Run_Angle_Scan-B6-A-430-8543.dat</file><file>Run_Angle_Scan-B6-A-431-8544.dat</file><file>Run_Angle_Scan-B6-A-432-8545.dat</file><file>Run_Angle_Scan-B6-A-433-8546.dat</file><file>Run_Angle_Scan-B6-A-434-8547.dat</file><file>Run_Angle_Scan-B6-A-435-8548.dat</file><file>Run_Angle_Scan-B6-A-436-8549.dat</file><file>Run_Angle_Scan-B6-A-437-8550.dat</file></AngleScan></directory><directory name="BoardA9"><Pedestal /><BiasScan><file>Run_Bias_Scan-B4-A-1-8016.dat</file><file>Run_Bias_Scan-B4-A-10-8023.dat</file><file>Run_Bias_Scan-B4-A-105-8113.dat</file><file>Run_Bias_Scan-B4-A-106-8114.dat</file><file>Run_Bias_Scan-B4-A-107-8115.dat</file><file>Run_Bias_Scan-B4-A-108-8116.dat</file><file>Run_Bias_Scan-B4-A-109-8117.dat</file><file>Run_Bias_Scan-B4-A-110-8118.dat</file><file>Run_Bias_Scan-B4-A-111-8119.dat</file><file>Run_Bias_Scan-B4-A-112-8120.dat</file><file>Run_Bias_Scan-B4-A-19-8032.dat</file><file>Run_Bias_Scan-B4-A-2-8017.dat</file><file>Run_Bias_Scan-B4-A-20-8033_BAD.dat</file><file>Run_Bias_Scan-B4-A-22-8033_BAD.dat</file><file>Run_Bias_Scan-B4-A-26-8034.dat</file><file>Run_Bias_Scan-B4-A-27-8035.dat</file><file>Run_Bias_Scan-B4-A-28-8036.dat</file><file>Run_Bias_Scan-B4-A-29-8037.dat</file><file>Run_Bias_Scan-B4-A-3-8018.dat</file><file>Run_Bias_Scan-B4-A-30-8038.dat</file><file>Run_Bias_Scan-B4-A-31-8039.dat</file><file>Run_Bias_Scan-B4-A-32-8040.dat</file><file>Run_Bias_Scan-B4-A-4-8019.dat</file><file>Run_Bias_Scan-B4-A-41-8049.dat</file><file>Run_Bias_Scan-B4-A-42-8050.dat</file><file>Run_Bias_Scan-B4-A-43-8051.dat</file><file>Run_Bias_Scan-B4-A-44-8052.dat</file><file>Run_Bias_Scan-B4-A-47-8055.dat</file><file>Run_Bias_Scan-B4-A-48-8056.dat</file><file>Run_Bias_Scan-B4-A-49-8057.dat</file><file>Run_Bias_Scan-B4-A-5-8020.dat</file><file>Run_Bias_Scan-B4-A-50-8058.dat</file><file>Run_Bias_Scan-B4-A-51-8059.dat</file><file>Run_Bias_Scan-B4-A-53-8060.dat</file><file>Run_Bias_Scan-B4-A-56-8061.dat</file><file>Run_Bias_Scan-B4-A-57-8062.dat</file><file>Run_Bias_Scan-B4-A-58-8063.dat</file><file>Run_Bias_Scan-B4-A-6-8021.dat</file><file>Run_Bias_Scan-B4-A-69-8076.dat</file><file>Run_Bias_Scan-B4-A-70-8077.dat</file><file>Run_Bias_Scan-B4-A-73-8081.dat</file><file>Run_Bias_Scan-B4-A-74-8082.dat</file><file>Run_Bias_Scan-B4-A-75-8083.dat</file><file>Run_Bias_Scan-B4-A-76-8084.dat</file><file>Run_Bias_Scan-B4-A-77-8085.dat</file><file>Run_Bias_Scan-B4-A-78-8086.dat</file><file>Run_Bias_Scan-B4-A-79-8087.dat</file><file>Run_Bias_Scan-B4-A-8-8021.dat</file><file>Run_Bias_Scan-B4-A-80-8088.dat</file><file>Run_Bias_Scan-B4-A-89-8097.dat</file><file>Run_Bias_Scan-B4-A-9-8022.dat</file><file>Run_Bias_Scan-B4-A-90-8098.dat</file><file>Run_Bias_Scan-B4-A-91-8099.dat</file><file>Run_Bias_Scan-B4-A-92-8100.dat</file><file>Run_Bias_Scan-B4-A-93-8101.dat</file><file>Run_Bias_Scan-B4-A-94-8102.dat</file><file>Run_Bias_Scan-B4-A-95-8103.dat</file><file>Run_Bias_Scan-B4-A-96-8104.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-121-8130.dat</file><file>Run_Angle_Scan-B1-A-122-8131.dat</file><file>Run_Angle_Scan-B4-A-100-8108.dat</file><file>Run_Angle_Scan-B4-A-101-8109.dat</file><file>Run_Angle_Scan-B4-A-102-8110.dat</file><file>Run_Angle_Scan-B4-A-103-8111.dat</file><file>Run_Angle_Scan-B4-A-104-8112.dat</file><file>Run_Angle_Scan-B4-A-11-8024.dat</file><file>Run_Angle_Scan-B4-A-113-8121.dat</file><file>Run_Angle_Scan-B4-A-114-8122.dat</file><file>Run_Angle_Scan-B4-A-115-8123.dat</file><file>Run_Angle_Scan-B4-A-116-8124.dat</file><file>Run_Angle_Scan-B4-A-117-8125.dat</file><file>Run_Angle_Scan-B4-A-118-8126.dat</file><file>Run_Angle_Scan-B4-A-119-8127.dat</file><file>Run_Angle_Scan-B4-A-12-8025.dat</file><file>Run_Angle_Scan-B4-A-120-8128.dat</file><file>Run_Angle_Scan-B4-A-13-8026.dat</file><file>Run_Angle_Scan-B4-A-14-8027.dat</file><file>Run_Angle_Scan-B4-A-15-8028.dat</file><file>Run_Angle_Scan-B4-A-16-8029.dat</file><file>Run_Angle_Scan-B4-A-17-8030.dat</file><file>Run_Angle_Scan-B4-A-18-8031.dat</file><file>Run_Angle_Scan-B4-A-33-8041.dat</file><file>Run_Angle_Scan-B4-A-34-8042.dat</file><file>Run_Angle_Scan-B4-A-35-8043.dat</file><file>Run_Angle_Scan-B4-A-36-8044.dat</file><file>Run_Angle_Scan-B4-A-37-8045.dat</file><file>Run_Angle_Scan-B4-A-38-8046.dat</file><file>Run_Angle_Scan-B4-A-39-8047.dat</file><file>Run_Angle_Scan-B4-A-40-8048.dat</file><file>Run_Angle_Scan-B4-A-59-8064.dat</file><file>Run_Angle_Scan-B4-A-60-8065.dat</file><file>Run_Angle_Scan-B4-A-61-8066.dat</file><file>Run_Angle_Scan-B4-A-62-8067.dat</file><file>Run_Angle_Scan-B4-A-63-8068.dat</file><file>Run_Angle_Scan-B4-A-64-8069.dat</file><file>Run_Angle_Scan-B4-A-65-8070.dat</file><file>Run_Angle_Scan-B4-A-66-8071.dat</file><file>Run_Angle_Scan-B4-A-67-8073.dat</file><file>Run_Angle_Scan-B4-A-68-8075.dat</file><file>Run_Angle_Scan-B4-A-81-8089.dat</file><file>Run_Angle_Scan-B4-A-82-8090.dat</file><file>Run_Angle_Scan-B4-A-83-8091.dat</file><file>Run_Angle_Scan-B4-A-84-8092.dat</file><file>Run_Angle_Scan-B4-A-85-8093.dat</file><file>Run_Angle_Scan-B4-A-86-8094.dat</file><file>Run_Angle_Scan-B4-A-87-8095.dat</file><file>Run_Angle_Scan-B4-A-88-8096.dat</file><file>Run_Angle_Scan-B4-A-97-8105.dat</file><file>Run_Angle_Scan-B4-A-98-8106.dat</file><file>Run_Angle_Scan-B4-A-99-8107.dat</file></AngleScan></directory><directory name="BoardD-irradiated"><Pedestal /><BiasScan /><AngleScan /></directory><directory name="BoardD-irradiated-behind-telescope"><Pedestal><file>Pedestal-B1-A-282-None.dat</file><file>Pedestal-B1-A-291-9113.dat</file><file>Pedestal-B1-A-296-9117.dat</file><file>Pedestal-B1-A-304-9122.dat</file><file>Pedestal-B1-A-305-9123.dat</file><file>Pedestal-B1-A-306-9124.dat</file><file>Pedestal-B1-A-307-9125.dat</file><file>Pedestal-B1-A-308-9126.dat</file><file>Pedestal-B1-A-309-none.dat</file><file>Pedestal-B1-D-356-9370.dat</file><file>Pedestal-B1-D-363-9383.dat</file><file>Pedestal-B1-D-370-9390.dat</file><file>Pedestal-B1-D-386-9431.dat</file><file>Pedestal-B1-D-387-9432.dat</file><file>Pedestal-B1-D-395-9440.dat</file><file>Pedestal-B1-D-553-xxxx.dat</file><file>Pedestal-B1-D-554-xxxx.dat</file><file>Pedestal-B1-D-555-xxxx.dat</file><file>Pedestal-B1-D-556-xxxx.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B1-A-273-9095.dat</file><file>Run_Bias_Scan-B1-A-274-9095.dat</file><file>Run_Bias_Scan-B1-A-275-9095.dat</file><file>Run_Bias_Scan-B1-A-276-9097.dat</file><file>Run_Bias_Scan-B1-A-277-9098.dat</file><file>Run_Bias_Scan-B1-A-278-9099.dat</file><file>Run_Bias_Scan-B1-A-279-9100.dat</file><file>Run_Bias_Scan-B1-A-280-9101.dat</file><file>Run_Bias_Scan-B1-A-281-9105.dat</file><file>Run_Bias_Scan-B1-D-310-9242.dat</file><file>Run_Bias_Scan-B1-D-312-9244.dat</file><file>Run_Bias_Scan-B1-D-314-9245.dat</file><file>Run_Bias_Scan-B1-D-315-9246.dat</file><file>Run_Bias_Scan-B1-D-316-9247.dat</file><file>Run_Bias_Scan-B1-D-317-9248.dat</file><file>Run_Bias_Scan-B1-D-318-9249.dat</file><file>Run_Bias_Scan-B1-D-319-9250.dat</file><file>Run_Bias_Scan-B1-D-320-9251.dat</file><file>Run_Bias_Scan-B1-D-321-9252.dat</file><file>Run_Bias_Scan-B1-D-340-9272.dat</file><file>Run_Bias_Scan-B1-D-341-9353.dat</file><file>Run_Bias_Scan-B1-D-342-9354.dat</file><file>Run_Bias_Scan-B1-D-343-9354.dat</file><file>Run_Bias_Scan-B1-D-344-9356.dat</file><file>Run_Bias_Scan-B1-D-345-9357.dat</file><file>Run_Bias_Scan-B1-D-346-9359.dat</file><file>Run_Bias_Scan-B1-D-347-9360.dat</file><file>Run_Bias_Scan-B1-D-348-9362.dat</file><file>Run_Bias_Scan-B1-D-371-9413.dat</file><file>Run_Bias_Scan-B1-D-372-9413.dat</file><file>Run_Bias_Scan-B1-D-373-9415.dat</file><file>Run_Bias_Scan-B1-D-374-9417.dat</file><file>Run_Bias_Scan-B1-D-375-9419.dat</file><file>Run_Bias_Scan-B1-D-376-9421.dat</file><file>Run_Bias_Scan-B1-D-377-9422.dat</file><file>Run_Bias_Scan-B1-D-378-9423.dat</file><file>Run_Bias_Scan-B1-D-379-9424.dat</file><file>Run_Bias_Scan-B1-D-453-9635.dat</file><file>Run_Bias_Scan-B1-D-454-9636.dat</file><file>Run_Bias_Scan-B1-D-455-9637.dat</file><file>Run_Bias_Scan-B1-D-456-9638.dat</file><file>Run_Bias_Scan-B1-D-457-9639.dat</file><file>Run_Bias_Scan-B1-D-458-9640.dat</file><file>Run_Bias_Scan-B1-D-459-9641.dat</file><file>Run_Bias_Scan-B1-D-460-9652.dat</file><file>Run_Bias_Scan-B1-D-461-9645.dat</file><file>Run_Bias_Scan-B1-D-462-9646.dat</file><file>Run_Bias_Scan-B1-D-464-9652.dat</file><file>Run_Bias_Scan-B1-D-465-9653.dat</file><file>Run_Bias_Scan-B1-D-466-9654.dat</file><file>Run_Bias_Scan-B1-D-467-9655.dat</file><file>Run_Bias_Scan-B1-D-468-9656.dat</file><file>Run_Bias_Scan-B1-D-469-9657.dat</file><file>Run_Bias_Scan-B1-D-470-9658.dat</file><file>Run_Bias_Scan-B1-D-471-9659.dat</file><file>Run_Bias_Scan-B1-D-472-9660.dat</file><file>Run_Bias_Scan-B1-D-473-9661.dat</file><file>Run_Bias_Scan-B1-D-474-9662.dat</file><file>Run_Bias_Scan-B1-D-475-9663.dat</file><file>Run_Bias_Scan-B1-D-476-9664.dat</file><file>Run_Bias_Scan-B1-D-477-9665.dat</file><file>Run_Bias_Scan-B1-D-478-9666.dat</file><file>Run_Bias_Scan-B1-D-479-9667.dat</file><file>Run_Bias_Scan-B1-D-480-9670.dat</file><file>Run_Bias_Scan-B1-D-481-9671.dat</file><file>Run_Bias_Scan-B1-D-482-9672.dat</file><file>Run_Bias_Scan-B1-D-483-9673.dat</file><file>Run_Bias_Scan-B1-D-484-9674.dat</file><file>Run_Bias_Scan-B1-D-487-9761.dat</file><file>Run_Bias_Scan-B1-D-488-9762.dat</file><file>Run_Bias_Scan-B1-D-489-9763.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-283-9106.dat</file><file>Run_Angle_Scan-B1-A-286-9108.dat</file><file>Run_Angle_Scan-B1-A-287-9109.dat</file><file>Run_Angle_Scan-B1-A-288-9110.dat</file><file>Run_Angle_Scan-B1-A-289-9111.dat</file><file>Run_Angle_Scan-B1-A-290-9112.dat</file><file>Run_Angle_Scan-B1-A-292-9113.dat</file><file>Run_Angle_Scan-B1-A-293-9114.dat</file><file>Run_Angle_Scan-B1-A-294-9115.dat</file><file>Run_Angle_Scan-B1-A-295-9116.dat</file><file>Run_Angle_Scan-B1-A-297-9117.dat</file><file>Run_Angle_Scan-B1-A-298-9117.dat</file><file>Run_Angle_Scan-B1-A-299-9118.dat</file><file>Run_Angle_Scan-B1-A-300-9119.dat</file><file>Run_Angle_Scan-B1-A-301-9120.dat</file><file>Run_Angle_Scan-B1-A-302-9121.dat</file><file>Run_Angle_Scan-B1-A-303-9122.dat</file><file>Run_Angle_Scan-B1-D-322-9253.dat</file><file>Run_Angle_Scan-B1-D-323-9254.dat</file><file>Run_Angle_Scan-B1-D-324-9255.dat</file><file>Run_Angle_Scan-B1-D-325-9256.dat</file><file>Run_Angle_Scan-B1-D-326-9257.dat</file><file>Run_Angle_Scan-B1-D-327-9258.dat</file><file>Run_Angle_Scan-B1-D-328-9259.dat</file><file>Run_Angle_Scan-B1-D-329-9260.dat</file><file>Run_Angle_Scan-B1-D-330-9261.dat</file><file>Run_Angle_Scan-B1-D-331-9262.dat</file><file>Run_Angle_Scan-B1-D-332-9263.dat</file><file>Run_Angle_Scan-B1-D-333-9264.dat</file><file>Run_Angle_Scan-B1-D-334-9265.dat</file><file>Run_Angle_Scan-B1-D-335-9266.dat</file><file>Run_Angle_Scan-B1-D-336-9267.dat</file><file>Run_Angle_Scan-B1-D-337-9268.dat</file><file>Run_Angle_Scan-B1-D-338-9269.dat</file><file>Run_Angle_Scan-B1-D-339-9270.dat</file><file>Run_Angle_Scan-B1-D-350-9363.dat</file><file>Run_Angle_Scan-B1-D-351-9364.dat</file><file>Run_Angle_Scan-B1-D-352-9366.dat</file><file>Run_Angle_Scan-B1-D-353-9367.dat</file><file>Run_Angle_Scan-B1-D-354-9368.dat</file><file>Run_Angle_Scan-B1-D-355-9369.dat</file><file>Run_Angle_Scan-B1-D-357-9377.dat</file><file>Run_Angle_Scan-B1-D-358-9378.dat</file><file>Run_Angle_Scan-B1-D-359-9379.dat</file><file>Run_Angle_Scan-B1-D-360-9380.dat</file><file>Run_Angle_Scan-B1-D-361-9381.dat</file><file>Run_Angle_Scan-B1-D-362-9382.dat</file><file>Run_Angle_Scan-B1-D-364-9384.dat</file><file>Run_Angle_Scan-B1-D-365-9385.dat</file><file>Run_Angle_Scan-B1-D-366-9386.dat</file><file>Run_Angle_Scan-B1-D-367-9387.dat</file><file>Run_Angle_Scan-B1-D-368-9388.dat</file><file>Run_Angle_Scan-B1-D-369-9389.dat</file><file>Run_Angle_Scan-B1-D-380-9425.dat</file><file>Run_Angle_Scan-B1-D-381-9426.dat</file><file>Run_Angle_Scan-B1-D-382-9427.dat</file><file>Run_Angle_Scan-B1-D-383-9428.dat</file><file>Run_Angle_Scan-B1-D-384-9429.dat</file><file>Run_Angle_Scan-B1-D-385-9430.dat</file><file>Run_Angle_Scan-B1-D-388-9433.dat</file><file>Run_Angle_Scan-B1-D-389-9434.dat</file><file>Run_Angle_Scan-B1-D-390-9435.dat</file><file>Run_Angle_Scan-B1-D-391-9436.dat</file><file>Run_Angle_Scan-B1-D-392-9437.dat</file><file>Run_Angle_Scan-B1-D-393-9438.dat</file><file>Run_Angle_Scan-B1-D-394-9439.dat</file><file>Run_Angle_Scan-B1-D-398-9442.dat</file><file>Run_Angle_Scan-B1-D-401-9444.dat</file><file>Run_Angle_Scan-B1-D-402-9444.dat</file><file>Run_Angle_Scan-B1-D-403-9446.dat</file><file>Run_Angle_Scan-B1-D-404-9447.dat</file><file>Run_Angle_Scan-B1-D-405-9448.dat</file><file>Run_Angle_Scan-B1-D-406-9449.dat</file><file>Run_Angle_Scan-B1-D-407-9450.dat</file><file>Run_Angle_Scan-B1-D-408-9451.dat</file><file>Run_Angle_Scan-B1-D-409-9452.dat</file><file>Run_Angle_Scan-B1-D-490-9764.dat</file><file>Run_Angle_Scan-B1-D-491-9765.dat</file><file>Run_Angle_Scan-B1-D-492-9766.dat</file><file>Run_Angle_Scan-B1-D-493-9767.dat</file><file>Run_Angle_Scan-B1-D-494-9768.dat</file><file>Run_Angle_Scan-B1-D-495-9769.dat</file><file>Run_Angle_Scan-B1-D-496-9770.dat</file><file>Run_Angle_Scan-B1-D-497-9771.dat</file><file>Run_Angle_Scan-B1-D-498-9772.dat</file><file>Run_Angle_Scan-B1-D-499-9773.dat</file><file>Run_Angle_Scan-B1-D-500-9774.dat</file><file>Run_Angle_Scan-B1-D-501-9775.dat</file><file>Run_Angle_Scan-B1-D-502-9777.dat</file><file>Run_Angle_Scan-B1-D-503-9778.dat</file><file>Run_Angle_Scan-B1-D-504-9779.dat</file><file>Run_Angle_Scan-B1-D-505-9780.dat</file><file>Run_Angle_Scan-B1-D-506-9781.dat</file><file>Run_Angle_Scan-B1-D-507-9782.dat</file><file>Run_Angle_Scan-B1-D-508-9784.dat</file><file>Run_Angle_Scan-B1-D-509-9785.dat</file><file>Run_Angle_Scan-B1-D-510-9786.dat</file><file>Run_Angle_Scan-B1-D-511-9787.dat</file><file>Run_Angle_Scan-B1-D-512-9788.dat</file><file>Run_Angle_Scan-B1-D-513-9789.dat</file><file>Run_Angle_Scan-B1-D-514-9791.dat</file><file>Run_Angle_Scan-B1-D-515-9792.dat</file><file>Run_Angle_Scan-B1-D-516-9793.dat</file><file>Run_Angle_Scan-B1-D-517-9794.dat</file><file>Run_Angle_Scan-B1-D-518-9795.dat</file><file>Run_Angle_Scan-B1-D-519-9796.dat</file><file>Run_Angle_Scan-B1-D-520-9797.dat</file><file>Run_Angle_Scan-B1-D-521-9798.dat</file><file>Run_Angle_Scan-B1-D-522-9799.dat</file><file>Run_Angle_Scan-B1-D-523-9800.dat</file><file>Run_Angle_Scan-B1-D-524-9801.dat</file><file>Run_Angle_Scan-B1-D-525-9802.dat</file><file>Run_Angle_Scan-B1-D-526-9803.dat</file><file>Run_Angle_Scan-B1-D-528-9804.dat</file><file>Run_Angle_Scan-B1-D-529-9807.dat</file><file>Run_Angle_Scan-B1-D-530-9808.dat</file><file>Run_Angle_Scan-B1-D-531-9809.dat</file><file>Run_Angle_Scan-B1-D-532-9810.dat</file><file>Run_Angle_Scan-B1-D-533-9811.dat</file><file>Run_Angle_Scan-B1-D-534-9812.dat</file><file>Run_Angle_Scan-B1-D-535-9813.dat</file><file>Run_Angle_Scan-B1-D-536-9814.dat</file><file>Run_Angle_Scan-B1-D-537-9815.dat</file><file>Run_Angle_Scan-B1-D-538-9816.dat</file><file>Run_Angle_Scan-B1-D-539-9817.dat</file><file>Run_Angle_Scan-B1-D-540-9818.dat</file><file>Run_Angle_Scan-B1-D-541-9818.dat</file><file>Run_Angle_Scan-B1-D-545-9821.dat</file><file>Run_Angle_Scan-B1-D-546-9822.dat</file><file>Run_Angle_Scan-B1-D-547-9823.dat</file><file>Run_Angle_Scan-B1-D-548-9825.dat</file><file>Run_Angle_Scan-B1-D-549-9826.dat</file><file>Run_Angle_Scan-B1-D-550-9827.dat</file></AngleScan></directory><directory name="BoardD9"><Pedestal><file>Pedestal-B9-D-264-.dat</file><file>Pedestal-B9-D-271-.dat</file><file>Pedestal-B9-D-279-.dat</file><file>Pedestal-B9-D-286-.dat</file><file>Pedestal-B9-D-293-.dat</file><file>Pedestal-B9-D-297-.dat</file><file>Pedestal-B9-D-300-.dat</file><file>Pedestal-B9-D-312-.dat</file><file>Pedestal-B9-D-315-.dat</file><file>Pedestal-B9-D-319-.dat</file><file>Pedestal-B9-D-326-.dat</file><file>Pedestal-B9-D-327-0.dat</file><file>Pedestal-B9-D-329-.dat</file><file>Pedestal-B9-D-334-0.dat</file><file>Pedestal-B9-D-350-.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B9-D-262-8746.dat</file><file>Run_Bias_Scan-B9-D-263-8747.dat</file><file>Run_Bias_Scan-B9-D-264-8748.dat</file><file>Run_Bias_Scan-B9-D-265-8749.dat</file><file>Run_Bias_Scan-B9-D-266-8750.dat</file><file>Run_Bias_Scan-B9-D-267-8751.dat</file><file>Run_Bias_Scan-B9-D-268-8752.dat</file><file>Run_Bias_Scan-B9-D-269-8753.dat</file><file>Run_Bias_Scan-B9-D-272-8837.dat</file><file>Run_Bias_Scan-B9-D-273-8838.dat</file><file>Run_Bias_Scan-B9-D-274-8839.dat</file><file>Run_Bias_Scan-B9-D-275-8840.dat</file><file>Run_Bias_Scan-B9-D-276-8841.dat</file><file>Run_Bias_Scan-B9-D-277-8842.dat</file><file>Run_Bias_Scan-B9-D-278-8843.dat</file><file>Run_Bias_Scan-B9-D-279-8844.dat</file><file>Run_Bias_Scan-B9-D-298-8774.dat</file><file>Run_Bias_Scan-B9-D-299-8775.dat</file><file>Run_Bias_Scan-B9-D-300-8776.dat</file><file>Run_Bias_Scan-B9-D-301-8777.dat</file><file>Run_Bias_Scan-B9-D-301-8863.dat</file><file>Run_Bias_Scan-B9-D-302-8778.dat</file><file>Run_Bias_Scan-B9-D-302-8864.dat</file><file>Run_Bias_Scan-B9-D-303-8779.dat</file><file>Run_Bias_Scan-B9-D-303-8865.dat</file><file>Run_Bias_Scan-B9-D-304-8780.dat</file><file>Run_Bias_Scan-B9-D-304-8866.dat</file><file>Run_Bias_Scan-B9-D-305-8781.dat</file><file>Run_Bias_Scan-B9-D-305-8867.dat</file><file>Run_Bias_Scan-B9-D-306-8868.dat</file><file>Run_Bias_Scan-B9-D-307-8869.dat</file><file>Run_Bias_Scan-B9-D-308-8870.dat</file><file>Run_Bias_Scan-B9-D-330-8802.dat</file><file>Run_Bias_Scan-B9-D-331-8803.dat</file><file>Run_Bias_Scan-B9-D-332-8804.dat</file><file>Run_Bias_Scan-B9-D-333-8805.dat</file><file>Run_Bias_Scan-B9-D-334-8806.dat</file><file>Run_Bias_Scan-B9-D-335-8807.dat</file><file>Run_Bias_Scan-B9-D-335-8891.dat</file><file>Run_Bias_Scan-B9-D-336-8808.dat</file><file>Run_Bias_Scan-B9-D-336-8892.dat</file><file>Run_Bias_Scan-B9-D-337-8809.dat</file><file>Run_Bias_Scan-B9-D-337-8893.dat</file><file>Run_Bias_Scan-B9-D-338-8894.dat</file><file>Run_Bias_Scan-B9-D-339-8895.dat</file><file>Run_Bias_Scan-B9-D-340-8896.dat</file><file>Run_Bias_Scan-B9-D-341-8897.dat</file><file>Run_Bias_Scan-B9-D-342-8898.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B9-D-256-8825.dat</file><file>Run_Angle_Scan-B9-D-257-8826.dat</file><file>Run_Angle_Scan-B9-D-257-8903.dat</file><file>Run_Angle_Scan-B9-D-258-8827.dat</file><file>Run_Angle_Scan-B9-D-258-8904.dat</file><file>Run_Angle_Scan-B9-D-259-8828.dat</file><file>Run_Angle_Scan-B9-D-259-8905.dat</file><file>Run_Angle_Scan-B9-D-260-8906.dat</file><file>Run_Angle_Scan-B9-D-261-8829.dat</file><file>Run_Angle_Scan-B9-D-261-8907.dat</file><file>Run_Angle_Scan-B9-D-262-8908.dat</file><file>Run_Angle_Scan-B9-D-263-8830.dat</file><file>Run_Angle_Scan-B9-D-263-8909.dat</file><file>Run_Angle_Scan-B9-D-264-8910.dat</file><file>Run_Angle_Scan-B9-D-265-8831.dat</file><file>Run_Angle_Scan-B9-D-265-8911.dat</file><file>Run_Angle_Scan-B9-D-266-8832.dat</file><file>Run_Angle_Scan-B9-D-266-8912.dat</file><file>Run_Angle_Scan-B9-D-267-8833.dat</file><file>Run_Angle_Scan-B9-D-267-8913.dat</file><file>Run_Angle_Scan-B9-D-268-8834.dat</file><file>Run_Angle_Scan-B9-D-268-8914.dat</file><file>Run_Angle_Scan-B9-D-269-8835.dat</file><file>Run_Angle_Scan-B9-D-269-8915.dat</file><file>Run_Angle_Scan-B9-D-270-8754.dat</file><file>Run_Angle_Scan-B9-D-270-8836.dat</file><file>Run_Angle_Scan-B9-D-270-8916.dat</file><file>Run_Angle_Scan-B9-D-271-8755.dat</file><file>Run_Angle_Scan-B9-D-271-8917.dat</file><file>Run_Angle_Scan-B9-D-272-8756.dat</file><file>Run_Angle_Scan-B9-D-272-8918.dat</file><file>Run_Angle_Scan-B9-D-273-8757.dat</file><file>Run_Angle_Scan-B9-D-274-8758.dat</file><file>Run_Angle_Scan-B9-D-275-8759.dat</file><file>Run_Angle_Scan-B9-D-276-8761.dat</file><file>Run_Angle_Scan-B9-D-280-8762.dat</file><file>Run_Angle_Scan-B9-D-280-8845.dat</file><file>Run_Angle_Scan-B9-D-281-8763.dat</file><file>Run_Angle_Scan-B9-D-281-8846.dat</file><file>Run_Angle_Scan-B9-D-282-8764.dat</file><file>Run_Angle_Scan-B9-D-282-8847.dat</file><file>Run_Angle_Scan-B9-D-283-8765.dat</file><file>Run_Angle_Scan-B9-D-283-8848.dat</file><file>Run_Angle_Scan-B9-D-284-8766.dat</file><file>Run_Angle_Scan-B9-D-284-8849.dat</file><file>Run_Angle_Scan-B9-D-285-8767.dat</file><file>Run_Angle_Scan-B9-D-285-8850.dat</file><file>Run_Angle_Scan-B9-D-287-8768.dat</file><file>Run_Angle_Scan-B9-D-287-8851.dat</file><file>Run_Angle_Scan-B9-D-288-8768.dat</file><file>Run_Angle_Scan-B9-D-288-8852.dat</file><file>Run_Angle_Scan-B9-D-289-8768.dat</file><file>Run_Angle_Scan-B9-D-289-8853.dat</file><file>Run_Angle_Scan-B9-D-290-8854.dat</file><file>Run_Angle_Scan-B9-D-291-8855.dat</file><file>Run_Angle_Scan-B9-D-292-8769.dat</file><file>Run_Angle_Scan-B9-D-292-8856.dat</file><file>Run_Angle_Scan-B9-D-293-8770.dat</file><file>Run_Angle_Scan-B9-D-294-8771.dat</file><file>Run_Angle_Scan-B9-D-294-8857.dat</file><file>Run_Angle_Scan-B9-D-295-8772.dat</file><file>Run_Angle_Scan-B9-D-295-8858.dat</file><file>Run_Angle_Scan-B9-D-296-8773.dat</file><file>Run_Angle_Scan-B9-D-296-8859.dat</file><file>Run_Angle_Scan-B9-D-297-8860.dat</file><file>Run_Angle_Scan-B9-D-298-8861.dat</file><file>Run_Angle_Scan-B9-D-299-8862.dat</file><file>Run_Angle_Scan-B9-D-306-8782.dat</file><file>Run_Angle_Scan-B9-D-307-8783.dat</file><file>Run_Angle_Scan-B9-D-308-8784.dat</file><file>Run_Angle_Scan-B9-D-309-8785.dat</file><file>Run_Angle_Scan-B9-D-309-8871.dat</file><file>Run_Angle_Scan-B9-D-310-8786.dat</file><file>Run_Angle_Scan-B9-D-310-8872.dat</file><file>Run_Angle_Scan-B9-D-311-8787.dat</file><file>Run_Angle_Scan-B9-D-311-8873.dat</file><file>Run_Angle_Scan-B9-D-312-8874.dat</file><file>Run_Angle_Scan-B9-D-313-8788.dat</file><file>Run_Angle_Scan-B9-D-313-8875.dat</file><file>Run_Angle_Scan-B9-D-314-8789.dat</file><file>Run_Angle_Scan-B9-D-314-8876.dat</file><file>Run_Angle_Scan-B9-D-315-8790.dat</file><file>Run_Angle_Scan-B9-D-316-8791.dat</file><file>Run_Angle_Scan-B9-D-317-8792.dat</file><file>Run_Angle_Scan-B9-D-318-8793.dat</file><file>Run_Angle_Scan-B9-D-318-8877.dat</file><file>Run_Angle_Scan-B9-D-320-8784.dat</file><file>Run_Angle_Scan-B9-D-320-8878.dat</file><file>Run_Angle_Scan-B9-D-321-8785.dat</file><file>Run_Angle_Scan-B9-D-321-8879.dat</file><file>Run_Angle_Scan-B9-D-322-8880.dat</file><file>Run_Angle_Scan-B9-D-323-8796.dat</file><file>Run_Angle_Scan-B9-D-323-8881.dat</file><file>Run_Angle_Scan-B9-D-324-8797.dat</file><file>Run_Angle_Scan-B9-D-324-8882.dat</file><file>Run_Angle_Scan-B9-D-325-8798.dat</file><file>Run_Angle_Scan-B9-D-325-8883.dat</file><file>Run_Angle_Scan-B9-D-326-8799.dat</file><file>Run_Angle_Scan-B9-D-327-8800.dat</file><file>Run_Angle_Scan-B9-D-328-8801.dat</file><file>Run_Angle_Scan-B9-D-328-8885.dat</file><file>Run_Angle_Scan-B9-D-329-8886.dat</file><file>Run_Angle_Scan-B9-D-330-8887.dat</file><file>Run_Angle_Scan-B9-D-331-8888.dat</file><file>Run_Angle_Scan-B9-D-332-8889.dat</file><file>Run_Angle_Scan-B9-D-333-8890.dat</file><file>Run_Angle_Scan-B9-D-338-8810.dat</file><file>Run_Angle_Scan-B9-D-339-8811.dat</file><file>Run_Angle_Scan-B9-D-340-8812.dat</file><file>Run_Angle_Scan-B9-D-341-8813.dat</file><file>Run_Angle_Scan-B9-D-342-8814.dat</file><file>Run_Angle_Scan-B9-D-343-8899.dat</file><file>Run_Angle_Scan-B9-D-344-8815.dat</file><file>Run_Angle_Scan-B9-D-344-8900.dat</file><file>Run_Angle_Scan-B9-D-345-8816.dat</file><file>Run_Angle_Scan-B9-D-345-8901.dat</file><file>Run_Angle_Scan-B9-D-346-8817.dat</file><file>Run_Angle_Scan-B9-D-347-8818.dat</file><file>Run_Angle_Scan-B9-D-348-8819.dat</file><file>Run_Angle_Scan-B9-D-349-8820.dat</file><file>Run_Angle_Scan-B9-D-351-8821.dat</file><file>Run_Angle_Scan-B9-D-353-8821.dat</file><file>Run_Angle_Scan-B9-D-354-8822.dat</file><file>Run_Angle_Scan-B9-D-356-8823.dat</file><file>Run_Angle_Scan-B9-D-357-8824.dat</file></AngleScan></directory></root>
\ No newline at end of file
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/TbUTAnalyzer.py.svn-base b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/TbUTAnalyzer.py.svn-base
new file mode 100644
index 0000000..a13bb62
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/TbUTAnalyzer.py.svn-base
@@ -0,0 +1,73 @@
+__author__ = 'ja'
+from xml.dom.minidom import parse
+import xml.dom.minidom
+import os
+from tempfile import mkstemp
+from shutil import move
+from os import remove, close
+
+class TbUTAnalyzer():
+
+    def __init__(self):
+        self.dirToAnalyse="BoardA4"
+        self.pathToDataInEos="/afs/cern.ch/user/a/adendek/eos/lhcb/testbeam/ut/OfficialData/July2015/"
+        self.scanType='BiasScan'  # one of 'AngleScan' 'BiasScan'
+        self.TbUTPath=os.path.expandvars("$KEPLERROOT")+"/../TbUT/"
+
+    def _performAnalysis(self, inputFilename):
+        print( "work on: " +inputFilename)
+        self.__changeOptionFile(inputFilename)
+        os.chdir(self.TbUTPath)
+        os.system("gaudirun.py options/TbUTRun.py")
+        os.system("gaudirun.py options/TbUTRun.py")
+        self._moveOutputRootFilesIntoDirectory(inputFilename)
+        ###
+        # add your stuffs here!
+        ###
+
+
+    def runAnalysis(self):
+        self._createOutputDir()
+        xmlRoot = xml.dom.minidom.parse('July2015Database.xml')
+        for directory in xmlRoot.getElementsByTagName('directory'):
+            if (directory.getAttribute("name")) in self.dirToAnalyse:
+                biasScan=directory.getElementsByTagName(self.scanType)
+                for run in biasScan[0].getElementsByTagName("file"):
+                    dataPath=self.pathToDataInEos+ self.dirToAnalyse+"/RawData/"+run.firstChild.nodeValue
+                    self._performAnalysis(dataPath)
+
+
+    def _createOutputDir(self):
+        self.outDirName=self.TbUTPath+"study_"+self.dirToAnalyse+"_"+self.scanType
+        if not os.path.exists(self.outDirName):
+            os.mkdir(self.outDirName)
+
+    def __changeOptionFile(self,inputFileName):
+        optionFilePath=self.TbUTPath+"options/TbUTRun.py"
+        fh, abs_path = mkstemp()
+        with open(abs_path,'w') as new_file:
+            with open(optionFilePath) as old_file:
+                for line in old_file:
+                    if not  "app.inputData" in line:
+                        new_file.write(line)
+                    else:
+                        new_file.write("app.inputData='"+inputFileName+"'\n")
+        close(fh)
+        #Remove original file
+        remove(optionFilePath)
+        #Move new file
+        move(abs_path, optionFilePath)
+
+    def _moveOutputRootFilesIntoDirectory(self, inputFilename):
+        outputName=inputFilename[:-4]+".root"
+        outputName=outputName[outputName.rfind("/")+1:]
+        move(outputName,self.outDirName+"/"+outputName)
+
+        outputTupleName=inputFilename[:-4]+"_Tuple.root"
+        outputTupleName=outputTupleName[outputTupleName.rfind("/")+1:]
+        move(outputTupleName,self.outDirName+"/"+outputTupleName)
+
+
+if __name__=='__main__':
+    analyzer = TbUTAnalyzer()
+    analyzer.runAnalysis()
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/XmlGenerator.py.svn-base b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/XmlGenerator.py.svn-base
new file mode 100644
index 0000000..065d30e
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/.svn/text-base/XmlGenerator.py.svn-base
@@ -0,0 +1,36 @@
+__author__ = 'ja'
+
+import xml.etree.cElementTree as ET
+from optparse import OptionParser
+import os
+
+parser = OptionParser()
+parser.add_option("-p", "--path", dest="path",
+                  help="path to eos", metavar="FILE")
+
+(options, args) = parser.parse_args()
+
+root = ET.Element("root")
+
+for dirname, dirnames, filenames in os.walk(options.path):
+    if '.git' in dirnames:
+        # don't go into any .git directories.
+        dirnames.remove('.git')
+    for subdirname in dirnames:
+        if "RawData" in subdirname:
+            boardName=dirname[dirname.rfind("/")+1:]
+            directory = ET.SubElement(root, "directory", name=boardName)
+            Pedestal=ET.SubElement(directory, "Pedestal",)
+            Bias=ET.SubElement(directory, "BiasScan",)
+            Angle=ET.SubElement(directory, "AngleScan",)
+
+    for filename in filenames:
+        if "Bias" in filename and ".xml" not in filename:
+            ET.SubElement(Bias, "file", ).text = filename
+        elif "Angle" in filename and ".xml" not in filename:
+            ET.SubElement(Angle, "file", ).text = filename
+        elif "Pedestal" in filename and ".xml" not in filename:
+            ET.SubElement(Pedestal, "file", ).text = filename
+
+tree = ET.ElementTree(root)
+tree.write("July2015Database.xml")
\ No newline at end of file
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/July2015Database.xml b/TbUT/scripts/TbUTAutomaticAnalyzer/July2015Database.xml
new file mode 100644
index 0000000..dc7ea1b
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/July2015Database.xml
@@ -0,0 +1 @@
+<root><directory name="BoardA4"><Pedestal><file>Pedestal-B1-A-193-8195.dat</file><file>Pedestal-B1-A-201-8328.dat</file><file>Pedestal-B1-A-202-8329.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B4-A-130-0.dat</file><file>Run_Bias_Scan-B4-A-131-8136.dat</file><file>Run_Bias_Scan-B4-A-132-8137.dat</file><file>Run_Bias_Scan-B4-A-136-8139.dat</file><file>Run_Bias_Scan-B4-A-137-8140.dat</file><file>Run_Bias_Scan-B4-A-138-8141.dat</file><file>Run_Bias_Scan-B4-A-139-8142.dat</file><file>Run_Bias_Scan-B4-A-140-8143.dat</file><file>Run_Bias_Scan-B4-A-141-8144.dat</file><file>Run_Bias_Scan-B4-A-142-8145.dat</file><file>Run_Bias_Scan-B4-A-143-8146.dat</file><file>Run_Bias_Scan-B4-A-144-8147.dat</file><file>Run_Bias_Scan-B4-A-171-8175.dat</file><file>Run_Bias_Scan-B4-A-172-8176.dat</file><file>Run_Bias_Scan-B4-A-173-8177.dat</file><file>Run_Bias_Scan-B4-A-174-8178.dat</file><file>Run_Bias_Scan-B4-A-175-8179.dat</file><file>Run_Bias_Scan-B4-A-176-8180.dat</file><file>Run_Bias_Scan-B4-A-177-8181.dat</file><file>Run_Bias_Scan-B4-A-178-8181.dat</file><file>Run_Bias_Scan-B4-A-179-8183.dat</file><file>Run_Bias_Scan-B4-A-180-8184.dat</file><file>Run_Bias_Scan-B4-A-181-8185.dat</file><file>Run_Bias_Scan-B4-A-182-8186.dat</file><file>Run_Bias_Scan-B4-A-210-8210.dat</file><file>Run_Bias_Scan-B4-A-211-8210.dat</file><file>Run_Bias_Scan-B4-A-220-8213.dat</file><file>Run_Bias_Scan-B4-A-221-8214.dat</file><file>Run_Bias_Scan-B4-A-222-8215.dat</file><file>Run_Bias_Scan-B4-A-223-8216.dat</file><file>Run_Bias_Scan-B4-A-224-8217.dat</file><file>Run_Bias_Scan-B4-A-225-8218.dat</file><file>Run_Bias_Scan-B4-A-226-8219.dat</file><file>Run_Bias_Scan-B4-A-227-8220.dat</file><file>Run_Bias_Scan-B4-A-228-8221.dat</file><file>Run_Bias_Scan-B4-A-229-8222.dat</file><file>Run_Bias_Scan-B4-A-254-8246.dat</file><file>Run_Bias_Scan-B4-A-255-8247.dat</file><file>Run_Bias_Scan-B4-A-256-8248.dat</file><file>Run_Bias_Scan-B4-A-257-8249.dat</file><file>Run_Bias_Scan-B4-A-258-8250.dat</file><file>Run_Bias_Scan-B4-A-259-8251.dat</file><file>Run_Bias_Scan-B4-A-260-8252.dat</file><file>Run_Bias_Scan-B4-A-261-8253.dat</file><file>Run_Bias_Scan-B4-A-262-8254.dat</file><file>Run_Bias_Scan-B4-A-263-8255.dat</file><file>Run_Bias_Scan-B4-A-291-8279.dat</file><file>Run_Bias_Scan-B4-A-292-8280.dat</file><file>Run_Bias_Scan-B4-A-293-8281.dat</file><file>Run_Bias_Scan-B4-A-294-8282.dat</file><file>Run_Bias_Scan-B4-A-295-8283.dat</file><file>Run_Bias_Scan-B4-A-296-8284.dat</file><file>Run_Bias_Scan-B4-A-297-8285.dat</file><file>Run_Bias_Scan-B4-A-298-8286.dat</file><file>Run_Bias_Scan-B4-A-299-8287.dat</file><file>Run_Bias_Scan-B4-A-300-8288.dat</file><file>Run_Bias_Scan-B4-A-327-8311.dat</file><file>Run_Bias_Scan-B4-A-328-8312.dat</file><file>Run_Bias_Scan-B4-A-329-8313.dat</file><file>Run_Bias_Scan-B4-A-330-8314.dat</file><file>Run_Bias_Scan-B4-A-331-8315.dat</file><file>Run_Bias_Scan-B4-A-332-8316.dat</file><file>Run_Bias_Scan-B4-A-333-8317.dat</file><file>Run_Bias_Scan-B4-A-334-8317.dat</file><file>Run_Bias_Scan-B4-A-335-8317.dat</file><file>Run_Bias_Scan-B4-A-338-8319.dat</file><file>Run_Bias_Scan-B4-A-339-8320.dat</file><file>Run_Bias_Scan-B4-A-340-8321.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-203-8330.dat</file><file>Run_Angle_Scan-B1-A-206-8331.dat</file><file>Run_Angle_Scan-B1-A-208-8331.dat</file><file>Run_Angle_Scan-B1-A-209-8333.dat</file><file>Run_Angle_Scan-B1-A-212-8335.dat</file><file>Run_Angle_Scan-B1-A-214-8335.dat</file><file>Run_Angle_Scan-B1-A-216-8337.dat</file><file>Run_Angle_Scan-B1-A-217-8339.dat</file><file>Run_Angle_Scan-B1-A-218-8340.dat</file><file>Run_Angle_Scan-B1-A-219-8341.dat</file><file>Run_Angle_Scan-B1-A-220-8342.dat</file><file>Run_Angle_Scan-B1-A-222-8343.dat</file><file>Run_Angle_Scan-B4-A-145-8148.dat</file><file>Run_Angle_Scan-B4-A-146-8149.dat</file><file>Run_Angle_Scan-B4-A-147-8150.dat</file><file>Run_Angle_Scan-B4-A-148-8151.dat</file><file>Run_Angle_Scan-B4-A-149-8152.dat</file><file>Run_Angle_Scan-B4-A-150-8154.dat</file><file>Run_Angle_Scan-B4-A-151-8155.dat</file><file>Run_Angle_Scan-B4-A-152-8156.dat</file><file>Run_Angle_Scan-B4-A-153-8157.dat</file><file>Run_Angle_Scan-B4-A-154-8158.dat</file><file>Run_Angle_Scan-B4-A-155-8159.dat</file><file>Run_Angle_Scan-B4-A-156-8160.dat</file><file>Run_Angle_Scan-B4-A-157-8161.dat</file><file>Run_Angle_Scan-B4-A-158-8162.dat</file><file>Run_Angle_Scan-B4-A-159-8163.dat</file><file>Run_Angle_Scan-B4-A-160-8164.dat</file><file>Run_Angle_Scan-B4-A-161-8165.dat</file><file>Run_Angle_Scan-B4-A-162-8166.dat</file><file>Run_Angle_Scan-B4-A-163-8167.dat</file><file>Run_Angle_Scan-B4-A-164-8168.dat</file><file>Run_Angle_Scan-B4-A-165-8169.dat</file><file>Run_Angle_Scan-B4-A-166-8170.dat</file><file>Run_Angle_Scan-B4-A-167-8171.dat</file><file>Run_Angle_Scan-B4-A-168-8172.dat</file><file>Run_Angle_Scan-B4-A-169-8173.dat</file><file>Run_Angle_Scan-B4-A-170-8174.dat</file><file>Run_Angle_Scan-B4-A-183-8187.dat</file><file>Run_Angle_Scan-B4-A-184-8188.dat</file><file>Run_Angle_Scan-B4-A-185-8189.dat</file><file>Run_Angle_Scan-B4-A-186-8190.dat</file><file>Run_Angle_Scan-B4-A-187-8191.dat</file><file>Run_Angle_Scan-B4-A-188-8192.dat</file><file>Run_Angle_Scan-B4-A-189-8193.dat</file><file>Run_Angle_Scan-B4-A-190-8194.dat</file><file>Run_Angle_Scan-B4-A-194-8195.dat</file><file>Run_Angle_Scan-B4-A-195-8196.dat</file><file>Run_Angle_Scan-B4-A-196-8197.dat</file><file>Run_Angle_Scan-B4-A-197-8198.dat</file><file>Run_Angle_Scan-B4-A-198-8199.dat</file><file>Run_Angle_Scan-B4-A-199-8200.dat</file><file>Run_Angle_Scan-B4-A-200-8201.dat</file><file>Run_Angle_Scan-B4-A-203-8203.dat</file><file>Run_Angle_Scan-B4-A-204-8204.dat</file><file>Run_Angle_Scan-B4-A-205-8205.dat</file><file>Run_Angle_Scan-B4-A-206-8206.dat</file><file>Run_Angle_Scan-B4-A-207-8207.dat</file><file>Run_Angle_Scan-B4-A-208-8208.dat</file><file>Run_Angle_Scan-B4-A-209-8209.dat</file><file>Run_Angle_Scan-B4-A-223-8344.dat</file><file>Run_Angle_Scan-B4-A-224-8345.dat</file><file>Run_Angle_Scan-B4-A-225-8346.dat</file><file>Run_Angle_Scan-B4-A-226-8347.dat</file><file>Run_Angle_Scan-B4-A-227-8348.dat</file><file>Run_Angle_Scan-B4-A-228-8349.dat</file><file>Run_Angle_Scan-B4-A-229-8350.dat</file><file>Run_Angle_Scan-B4-A-230-8223.dat</file><file>Run_Angle_Scan-B4-A-230-8351.dat</file><file>Run_Angle_Scan-B4-A-231-8224.dat</file><file>Run_Angle_Scan-B4-A-231-8352.dat</file><file>Run_Angle_Scan-B4-A-232-8353.dat</file><file>Run_Angle_Scan-B4-A-233-8225.dat</file><file>Run_Angle_Scan-B4-A-234-8226.dat</file><file>Run_Angle_Scan-B4-A-235-8227.dat</file><file>Run_Angle_Scan-B4-A-236-8229.dat</file><file>Run_Angle_Scan-B4-A-237-8230.dat</file><file>Run_Angle_Scan-B4-A-238-8231.dat</file><file>Run_Angle_Scan-B4-A-239-8232.dat</file><file>Run_Angle_Scan-B4-A-240-8233.dat</file><file>Run_Angle_Scan-B4-A-241-8234.dat</file><file>Run_Angle_Scan-B4-A-242-8235.dat</file><file>Run_Angle_Scan-B4-A-243-8236.dat</file><file>Run_Angle_Scan-B4-A-244-8237.dat</file><file>Run_Angle_Scan-B4-A-245-8238.dat</file><file>Run_Angle_Scan-B4-A-246-8239.dat</file><file>Run_Angle_Scan-B4-A-247-8240.dat</file><file>Run_Angle_Scan-B4-A-248-8241.dat</file><file>Run_Angle_Scan-B4-A-249-8242.dat</file><file>Run_Angle_Scan-B4-A-250-8243.dat</file><file>Run_Angle_Scan-B4-A-251-8243.dat</file><file>Run_Angle_Scan-B4-A-252-8244.dat</file><file>Run_Angle_Scan-B4-A-253-8245.dat</file><file>Run_Angle_Scan-B4-A-264-8256.dat</file><file>Run_Angle_Scan-B4-A-265-8257.dat</file><file>Run_Angle_Scan-B4-A-266-8258.dat</file><file>Run_Angle_Scan-B4-A-267-8259.dat</file><file>Run_Angle_Scan-B4-A-268-8260.dat</file><file>Run_Angle_Scan-B4-A-269-8261.dat</file><file>Run_Angle_Scan-B4-A-271-8262.dat</file><file>Run_Angle_Scan-B4-A-272-8263.dat</file><file>Run_Angle_Scan-B4-A-273-8264.dat</file><file>Run_Angle_Scan-B4-A-274-8265.dat</file><file>Run_Angle_Scan-B4-A-275-8266.dat</file><file>Run_Angle_Scan-B4-A-276-8267.dat</file><file>Run_Angle_Scan-B4-A-277-8268.dat</file><file>Run_Angle_Scan-B4-A-278-8269.dat</file><file>Run_Angle_Scan-B4-A-279-8270.dat</file><file>Run_Angle_Scan-B4-A-280-8271.dat</file><file>Run_Angle_Scan-B4-A-281-8272.dat</file><file>Run_Angle_Scan-B4-A-282-8273.dat</file><file>Run_Angle_Scan-B4-A-286-8274.dat</file><file>Run_Angle_Scan-B4-A-287-8275.dat</file><file>Run_Angle_Scan-B4-A-288-8276.dat</file><file>Run_Angle_Scan-B4-A-289-8277.dat</file><file>Run_Angle_Scan-B4-A-290-8278.dat</file><file>Run_Angle_Scan-B4-A-301-8289.dat</file><file>Run_Angle_Scan-B4-A-302-8290.dat</file><file>Run_Angle_Scan-B4-A-303-8291.dat</file><file>Run_Angle_Scan-B4-A-304-8292.dat</file><file>Run_Angle_Scan-B4-A-305-8293.dat</file><file>Run_Angle_Scan-B4-A-306-8294.dat</file><file>Run_Angle_Scan-B4-A-307-8295.dat</file><file>Run_Angle_Scan-B4-A-308-8296.dat</file><file>Run_Angle_Scan-B4-A-309-8297.dat</file><file>Run_Angle_Scan-B4-A-310-8298.dat</file><file>Run_Angle_Scan-B4-A-311-8299.dat</file><file>Run_Angle_Scan-B4-A-312-8300.dat</file><file>Run_Angle_Scan-B4-A-313-8301.dat</file><file>Run_Angle_Scan-B4-A-314-8302.dat</file><file>Run_Angle_Scan-B4-A-315-8303.dat</file><file>Run_Angle_Scan-B4-A-316-8304.dat</file><file>Run_Angle_Scan-B4-A-317-8304.dat</file><file>Run_Angle_Scan-B4-A-320-8305.dat</file><file>Run_Angle_Scan-B4-A-321-8305.dat</file><file>Run_Angle_Scan-B4-A-322-8307.dat</file><file>Run_Angle_Scan-B4-A-324-8308.dat</file><file>Run_Angle_Scan-B4-A-325-8309.dat</file><file>Run_Angle_Scan-B4-A-326-8310.dat</file><file>Run_Angle_Scan-B4-A-341-8322.dat</file><file>Run_Angle_Scan-B4-A-342-8323.dat</file></AngleScan></directory><directory name="BoardA4_redo"><Pedestal><file>Pedestal-B4-A-209-0.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B1-A-227-8711.dat</file><file>Run_Bias_Scan-B1-A-228-8712.dat</file><file>Run_Bias_Scan-B1-A-229-8713.dat</file><file>Run_Bias_Scan-B1-A-230-8714.dat</file><file>Run_Bias_Scan-B1-A-231-8715.dat</file><file>Run_Bias_Scan-B1-A-232-8716.dat</file><file>Run_Bias_Scan-B1-A-233-8717.dat</file><file>Run_Bias_Scan-B1-A-234-8718.dat</file><file>Run_Bias_Scan-B1-A-235-8719.dat</file><file>Run_Bias_Scan-B4-A-210-8552.dat</file><file>Run_Bias_Scan-B4-A-211-8553.dat</file><file>Run_Bias_Scan-B4-A-212-8554.dat</file><file>Run_Bias_Scan-B4-A-213-8555.dat</file><file>Run_Bias_Scan-B4-A-214-8556.dat</file><file>Run_Bias_Scan-B4-A-215-8557.dat</file><file>Run_Bias_Scan-B4-A-216-8558.dat</file><file>Run_Bias_Scan-B4-A-217-8559.dat</file><file>Run_Bias_Scan-B4-A-217-8651.dat</file><file>Run_Bias_Scan-B4-A-218-8560.dat</file><file>Run_Bias_Scan-B4-A-218-8652.dat</file><file>Run_Bias_Scan-B4-A-219-8653.dat</file><file>Run_Bias_Scan-B4-A-220-8654.dat</file><file>Run_Bias_Scan-B4-A-221-8655.dat</file><file>Run_Bias_Scan-B4-A-222-8656.dat</file><file>Run_Bias_Scan-B4-A-223-8657.dat</file><file>Run_Bias_Scan-B4-A-224-8658.dat</file><file>Run_Bias_Scan-B4-A-225-8659.dat</file><file>Run_Bias_Scan-B4-A-242-8583.dat</file><file>Run_Bias_Scan-B4-A-243-8584.dat</file><file>Run_Bias_Scan-B4-A-246-8586.dat</file><file>Run_Bias_Scan-B4-A-246-8680.dat</file><file>Run_Bias_Scan-B4-A-247-8587.dat</file><file>Run_Bias_Scan-B4-A-247-8681.dat</file><file>Run_Bias_Scan-B4-A-248-8588.dat</file><file>Run_Bias_Scan-B4-A-248-8682.dat</file><file>Run_Bias_Scan-B4-A-249-8589.dat</file><file>Run_Bias_Scan-B4-A-249-8683.dat</file><file>Run_Bias_Scan-B4-A-250-8590.dat</file><file>Run_Bias_Scan-B4-A-250-8684.dat</file><file>Run_Bias_Scan-B4-A-251-8591.dat</file><file>Run_Bias_Scan-B4-A-251-8685.dat</file><file>Run_Bias_Scan-B4-A-252-8592.dat</file><file>Run_Bias_Scan-B4-A-252-8686.dat</file><file>Run_Bias_Scan-B4-A-253-8687.dat</file><file>Run_Bias_Scan-B4-A-254-8688.dat</file><file>Run_Bias_Scan-B4-A-273-8613.dat</file><file>Run_Bias_Scan-B4-A-275-8615.dat</file><file>Run_Bias_Scan-B4-A-276-8616.dat</file><file>Run_Bias_Scan-B4-A-277-8617.dat</file><file>Run_Bias_Scan-B4-A-278-8618.dat</file><file>Run_Bias_Scan-B4-A-279-8619.dat</file><file>Run_Bias_Scan-B4-A-280-8620.dat</file><file>Run_Bias_Scan-B4-A-281-8621.dat</file><file>Run_Bias_Scan-B4-A-282-8622.dat</file><file>Run_Bias_Scan-B4-A-283-8623.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-213-8697.dat</file><file>Run_Angle_Scan-B1-A-214-8698.dat</file><file>Run_Angle_Scan-B1-A-215-8699.dat</file><file>Run_Angle_Scan-B1-A-216-8700.dat</file><file>Run_Angle_Scan-B1-A-217-8701.dat</file><file>Run_Angle_Scan-B1-A-218-8702.dat</file><file>Run_Angle_Scan-B1-A-219-8703.dat</file><file>Run_Angle_Scan-B1-A-220-8704.dat</file><file>Run_Angle_Scan-B1-A-221-8705.dat</file><file>Run_Angle_Scan-B1-A-222-8706.dat</file><file>Run_Angle_Scan-B1-A-223-8707.dat</file><file>Run_Angle_Scan-B1-A-224-8708.dat</file><file>Run_Angle_Scan-B1-A-225-8709.dat</file><file>Run_Angle_Scan-B1-A-226-8710.dat</file><file>Run_Angle_Scan-B1-A-236-8720.dat</file><file>Run_Angle_Scan-B1-A-237-8721.dat</file><file>Run_Angle_Scan-B1-A-238-8722.dat</file><file>Run_Angle_Scan-B1-A-239-8723.dat</file><file>Run_Angle_Scan-B1-A-240-8724.dat</file><file>Run_Angle_Scan-B1-A-241-8725.dat</file><file>Run_Angle_Scan-B1-A-242-8726.dat</file><file>Run_Angle_Scan-B1-A-243-8727.dat</file><file>Run_Angle_Scan-B1-A-244-8728.dat</file><file>Run_Angle_Scan-B1-A-245-8729.dat</file><file>Run_Angle_Scan-B1-A-246-8730.dat</file><file>Run_Angle_Scan-B1-A-247-8731.dat</file><file>Run_Angle_Scan-B1-A-248-8732.dat</file><file>Run_Angle_Scan-B1-A-249-8733.dat</file><file>Run_Angle_Scan-B1-A-250-8734.dat</file><file>Run_Angle_Scan-B1-A-251-8735.dat</file><file>Run_Angle_Scan-B1-A-252-8736.dat</file><file>Run_Angle_Scan-B1-A-253-8737.dat</file><file>Run_Angle_Scan-B1-A-254-8738.dat</file><file>Run_Angle_Scan-B1-A-255-8739.dat</file><file>Run_Angle_Scan-B4-A-209-8643.dat</file><file>Run_Angle_Scan-B4-A-209-8694.dat</file><file>Run_Angle_Scan-B4-A-210-8644.dat</file><file>Run_Angle_Scan-B4-A-210-8695.dat</file><file>Run_Angle_Scan-B4-A-211-8645.dat</file><file>Run_Angle_Scan-B4-A-211-8696.dat</file><file>Run_Angle_Scan-B4-A-212-8646.dat</file><file>Run_Angle_Scan-B4-A-213-8647.dat</file><file>Run_Angle_Scan-B4-A-214-8648.dat</file><file>Run_Angle_Scan-B4-A-215-8649.dat</file><file>Run_Angle_Scan-B4-A-216-8650.dat</file><file>Run_Angle_Scan-B4-A-219-8561.dat</file><file>Run_Angle_Scan-B4-A-220-8562.dat</file><file>Run_Angle_Scan-B4-A-221-8563.dat</file><file>Run_Angle_Scan-B4-A-222-8564.dat</file><file>Run_Angle_Scan-B4-A-223-8565.dat</file><file>Run_Angle_Scan-B4-A-224-8566.dat</file><file>Run_Angle_Scan-B4-A-225-8567.dat</file><file>Run_Angle_Scan-B4-A-226-8568.dat</file><file>Run_Angle_Scan-B4-A-226-8660.dat</file><file>Run_Angle_Scan-B4-A-227-8569.dat</file><file>Run_Angle_Scan-B4-A-227-8661.dat</file><file>Run_Angle_Scan-B4-A-228-8570.dat</file><file>Run_Angle_Scan-B4-A-228-8662.dat</file><file>Run_Angle_Scan-B4-A-229-8571.dat</file><file>Run_Angle_Scan-B4-A-229-8663.dat</file><file>Run_Angle_Scan-B4-A-230-8572.dat</file><file>Run_Angle_Scan-B4-A-230-8664.dat</file><file>Run_Angle_Scan-B4-A-231-8573.dat</file><file>Run_Angle_Scan-B4-A-231-8665.dat</file><file>Run_Angle_Scan-B4-A-232-8574.dat</file><file>Run_Angle_Scan-B4-A-232-8666.dat</file><file>Run_Angle_Scan-B4-A-233-8575.dat</file><file>Run_Angle_Scan-B4-A-233-8667.dat</file><file>Run_Angle_Scan-B4-A-234-8576.dat</file><file>Run_Angle_Scan-B4-A-234-8668.dat</file><file>Run_Angle_Scan-B4-A-235-8669.dat</file><file>Run_Angle_Scan-B4-A-236-8670.dat</file><file>Run_Angle_Scan-B4-A-237-8578.dat</file><file>Run_Angle_Scan-B4-A-237-8671.dat</file><file>Run_Angle_Scan-B4-A-238-8579.dat</file><file>Run_Angle_Scan-B4-A-238-8672.dat</file><file>Run_Angle_Scan-B4-A-239-8580.dat</file><file>Run_Angle_Scan-B4-A-239-8673.dat</file><file>Run_Angle_Scan-B4-A-240-8581.dat</file><file>Run_Angle_Scan-B4-A-240-8674.dat</file><file>Run_Angle_Scan-B4-A-241-8582.dat</file><file>Run_Angle_Scan-B4-A-241-8675.dat</file><file>Run_Angle_Scan-B4-A-242-8676.dat</file><file>Run_Angle_Scan-B4-A-243-8677.dat</file><file>Run_Angle_Scan-B4-A-244-8678.dat</file><file>Run_Angle_Scan-B4-A-245-8679.dat</file><file>Run_Angle_Scan-B4-A-253-8593.dat</file><file>Run_Angle_Scan-B4-A-254-8594.dat</file><file>Run_Angle_Scan-B4-A-255-8595.dat</file><file>Run_Angle_Scan-B4-A-255-8689.dat</file><file>Run_Angle_Scan-B4-A-256-8596.dat</file><file>Run_Angle_Scan-B4-A-256-8690.dat</file><file>Run_Angle_Scan-B4-A-257-8597.dat</file><file>Run_Angle_Scan-B4-A-257-8691.dat</file><file>Run_Angle_Scan-B4-A-258-8598.dat</file><file>Run_Angle_Scan-B4-A-258-8692.dat</file><file>Run_Angle_Scan-B4-A-259-8599.dat</file><file>Run_Angle_Scan-B4-A-259-8693.dat</file><file>Run_Angle_Scan-B4-A-260-8600.dat</file><file>Run_Angle_Scan-B4-A-261-8601.dat</file><file>Run_Angle_Scan-B4-A-262-8602.dat</file><file>Run_Angle_Scan-B4-A-263-8603.dat</file><file>Run_Angle_Scan-B4-A-264-8604.dat</file><file>Run_Angle_Scan-B4-A-265-8605.dat</file><file>Run_Angle_Scan-B4-A-266-8606.dat</file><file>Run_Angle_Scan-B4-A-267-8607.dat</file><file>Run_Angle_Scan-B4-A-268-8608.dat</file><file>Run_Angle_Scan-B4-A-269-8609.dat</file><file>Run_Angle_Scan-B4-A-270-8610.dat</file><file>Run_Angle_Scan-B4-A-271-8611.dat</file><file>Run_Angle_Scan-B4-A-272-8612.dat</file><file>Run_Angle_Scan-B4-A-284-8624.dat</file><file>Run_Angle_Scan-B4-A-285-8625.dat</file><file>Run_Angle_Scan-B4-A-286-8626.dat</file><file>Run_Angle_Scan-B4-A-287-8627.dat</file><file>Run_Angle_Scan-B4-A-288-8628.dat</file><file>Run_Angle_Scan-B4-A-289-8629.dat</file><file>Run_Angle_Scan-B4-A-290-8630.dat</file><file>Run_Angle_Scan-B4-A-291-8631.dat</file><file>Run_Angle_Scan-B4-A-292-8632.dat</file><file>Run_Angle_Scan-B4-A-293-8633.dat</file><file>Run_Angle_Scan-B4-A-294-8634.dat</file><file>Run_Angle_Scan-B4-A-295-8635.dat</file><file>Run_Angle_Scan-B4-A-296-8636.dat</file><file>Run_Angle_Scan-B4-A-297-8637.dat</file><file>Run_Angle_Scan-B4-A-298-8638.dat</file><file>Run_Angle_Scan-B4-A-299-8639.dat</file><file>Run_Angle_Scan-B4-A-300-8640.dat</file><file>Run_Angle_Scan-B4-A-301-8641.dat</file><file>Run_Angle_Scan-B4-A-302-8642.dat</file></AngleScan></directory><directory name="BoardA6"><Pedestal><file>Pedestal-B6-A-209-0.dat</file><file>Pedestal-B6-A-263-0.dat</file><file>Pedestal-B6-A-264-1.dat</file><file>Pedestal-B6-A-285-8419.dat</file><file>Pedestal-B6-A-300-8431.dat</file><file>Pedestal-B6-A-319-8445.dat</file><file>Pedestal-B6-A-354-8472.dat</file><file>Pedestal-B6-A-392-8507.dat</file><file>Pedestal-B6-A-393-8508.dat</file><file>Pedestal-B6-A-394-8509.dat</file><file>Pedestal-B6-A-395-8510.dat</file><file>Pedestal-B6-A-396-8511.dat</file><file>Pedestal-B6-A-397-8512.dat</file><file>Pedestal-B6-A-398-8512.dat</file><file>Pedestal-B6-A-399-8514.dat</file><file>Pedestal-B6-A-400-8515.dat</file><file>Pedestal-B6-A-401-8516.dat</file><file>Pedestal-B6-A-402-8517.dat</file><file>Pedestal-B6-A-403-8518.dat</file><file>Pedestal-B6-A-404-8519.dat</file><file>Pedestal-B6-A-405-8520.dat</file><file>Pedestal-B6-A-406-8521.dat</file><file>Pedestal-B6-A-407-8522.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B6-A-210-8356.dat</file><file>Run_Bias_Scan-B6-A-211-8357.dat</file><file>Run_Bias_Scan-B6-A-212-8358.dat</file><file>Run_Bias_Scan-B6-A-213-8359.dat</file><file>Run_Bias_Scan-B6-A-214-8361.dat</file><file>Run_Bias_Scan-B6-A-215-8362.dat</file><file>Run_Bias_Scan-B6-A-216-8363.dat</file><file>Run_Bias_Scan-B6-A-217-8364.dat</file><file>Run_Bias_Scan-B6-A-218-8364.dat</file><file>Run_Bias_Scan-B6-A-219-8365.dat</file><file>Run_Bias_Scan-B6-A-220-8366.dat</file><file>Run_Bias_Scan-B6-A-221-8368.dat</file><file>Run_Bias_Scan-B6-A-242-8389.dat</file><file>Run_Bias_Scan-B6-A-245-8392.dat</file><file>Run_Bias_Scan-B6-A-246-8393.dat</file><file>Run_Bias_Scan-B6-A-247-8394.dat</file><file>Run_Bias_Scan-B6-A-248-8395.dat</file><file>Run_Bias_Scan-B6-A-249-8396.dat</file><file>Run_Bias_Scan-B6-A-250-8397.dat</file><file>Run_Bias_Scan-B6-A-267-8409.dat</file><file>Run_Bias_Scan-B6-A-272-8410.dat</file><file>Run_Bias_Scan-B6-A-292-8424.dat</file><file>Run_Bias_Scan-B6-A-293-8425.dat</file><file>Run_Bias_Scan-B6-A-294-8426.dat</file><file>Run_Bias_Scan-B6-A-295-8427.dat</file><file>Run_Bias_Scan-B6-A-296-8428.dat</file><file>Run_Bias_Scan-B6-A-297-8429.dat</file><file>Run_Bias_Scan-B6-A-298-8430.dat</file><file>Run_Bias_Scan-B6-A-299-8431.dat</file><file>Run_Bias_Scan-B6-A-326-8452.dat</file><file>Run_Bias_Scan-B6-A-327-8453.dat</file><file>Run_Bias_Scan-B6-A-328-8454.dat</file><file>Run_Bias_Scan-B6-A-329-8455.dat</file><file>Run_Bias_Scan-B6-A-330-8456.dat</file><file>Run_Bias_Scan-B6-A-331-8457.dat</file><file>Run_Bias_Scan-B6-A-332-8458.dat</file><file>Run_Bias_Scan-B6-A-364-8482.dat</file><file>Run_Bias_Scan-B6-A-378-8494.dat</file><file>Run_Bias_Scan-B6-A-379-8496.dat</file><file>Run_Bias_Scan-B6-A-381-8497.dat</file><file>Run_Bias_Scan-B6-A-382-8498.dat</file><file>Run_Bias_Scan-B6-A-383-8499.dat</file><file>Run_Bias_Scan-B6-A-384-8500.dat</file><file>Run_Bias_Scan-B6-A-385-8501.dat</file><file>Run_Bias_Scan-B6-A-386-8502.dat</file><file>Run_Bias_Scan-B6-A-408-8523.dat</file><file>Run_Bias_Scan-B6-A-409-8524.dat</file><file>Run_Bias_Scan-B6-A-410-8525.dat</file><file>Run_Bias_Scan-B6-A-411-8526.dat</file><file>Run_Bias_Scan-B6-A-412-8527.dat</file><file>Run_Bias_Scan-B6-A-413-8528.dat</file><file>Run_Bias_Scan-B6-A-414-8529.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B6-A-222-8369.dat</file><file>Run_Angle_Scan-B6-A-223-8370.dat</file><file>Run_Angle_Scan-B6-A-224-8371.dat</file><file>Run_Angle_Scan-B6-A-225-8372.dat</file><file>Run_Angle_Scan-B6-A-226-8373.dat</file><file>Run_Angle_Scan-B6-A-227-8374.dat</file><file>Run_Angle_Scan-B6-A-228-8375.dat</file><file>Run_Angle_Scan-B6-A-229-8376.dat</file><file>Run_Angle_Scan-B6-A-230-8377.dat</file><file>Run_Angle_Scan-B6-A-231-8378.dat</file><file>Run_Angle_Scan-B6-A-232-8379.dat</file><file>Run_Angle_Scan-B6-A-233-8380.dat</file><file>Run_Angle_Scan-B6-A-234-8381.dat</file><file>Run_Angle_Scan-B6-A-235-8382.dat</file><file>Run_Angle_Scan-B6-A-236-8383.dat</file><file>Run_Angle_Scan-B6-A-237-8384.dat</file><file>Run_Angle_Scan-B6-A-238-8385.dat</file><file>Run_Angle_Scan-B6-A-239-8386.dat</file><file>Run_Angle_Scan-B6-A-240-8387.dat</file><file>Run_Angle_Scan-B6-A-241-8388.dat</file><file>Run_Angle_Scan-B6-A-251-8398.dat</file><file>Run_Angle_Scan-B6-A-252-8399.dat</file><file>Run_Angle_Scan-B6-A-253-8400.dat</file><file>Run_Angle_Scan-B6-A-256-8402.dat</file><file>Run_Angle_Scan-B6-A-257-8403.dat</file><file>Run_Angle_Scan-B6-A-258-8404.dat</file><file>Run_Angle_Scan-B6-A-259-8405.dat</file><file>Run_Angle_Scan-B6-A-260-8406.dat</file><file>Run_Angle_Scan-B6-A-261-8407.dat</file><file>Run_Angle_Scan-B6-A-262-8408.dat</file><file>Run_Angle_Scan-B6-A-273-8410.dat</file><file>Run_Angle_Scan-B6-A-275-8412.dat</file><file>Run_Angle_Scan-B6-A-276-8413.dat</file><file>Run_Angle_Scan-B6-A-279-8415.dat</file><file>Run_Angle_Scan-B6-A-280-8416.dat</file><file>Run_Angle_Scan-B6-A-281-8417.dat</file><file>Run_Angle_Scan-B6-A-284-8419.dat</file><file>Run_Angle_Scan-B6-A-286-8420.dat</file><file>Run_Angle_Scan-B6-A-288-8420.dat</file><file>Run_Angle_Scan-B6-A-289-8421.dat</file><file>Run_Angle_Scan-B6-A-290-8422.dat</file><file>Run_Angle_Scan-B6-A-291-8423.dat</file><file>Run_Angle_Scan-B6-A-301-8432.dat</file><file>Run_Angle_Scan-B6-A-302-8433.dat</file><file>Run_Angle_Scan-B6-A-303-8434.dat</file><file>Run_Angle_Scan-B6-A-306-8435.dat</file><file>Run_Angle_Scan-B6-A-307-8436.dat</file><file>Run_Angle_Scan-B6-A-308-8437.dat</file><file>Run_Angle_Scan-B6-A-309-8438.dat</file><file>Run_Angle_Scan-B6-A-310-8439.dat</file><file>Run_Angle_Scan-B6-A-311-8440.dat</file><file>Run_Angle_Scan-B6-A-312-8441.dat</file><file>Run_Angle_Scan-B6-A-313-8441.dat</file><file>Run_Angle_Scan-B6-A-316-8443.dat</file><file>Run_Angle_Scan-B6-A-317-8444.dat</file><file>Run_Angle_Scan-B6-A-318-8445.dat</file><file>Run_Angle_Scan-B6-A-320-8446.dat</file><file>Run_Angle_Scan-B6-A-321-8447.dat</file><file>Run_Angle_Scan-B6-A-322-8448.dat</file><file>Run_Angle_Scan-B6-A-323-8449.dat</file><file>Run_Angle_Scan-B6-A-324-8450.dat</file><file>Run_Angle_Scan-B6-A-325-8451.dat</file><file>Run_Angle_Scan-B6-A-333-8459.dat</file><file>Run_Angle_Scan-B6-A-336-8461.dat</file><file>Run_Angle_Scan-B6-A-337-8462.dat</file><file>Run_Angle_Scan-B6-A-338-8463.dat</file><file>Run_Angle_Scan-B6-A-339-8464.dat</file><file>Run_Angle_Scan-B6-A-342-8466.dat</file><file>Run_Angle_Scan-B6-A-343-8467.dat</file><file>Run_Angle_Scan-B6-A-344-8468.dat</file><file>Run_Angle_Scan-B6-A-345-8469.dat</file><file>Run_Angle_Scan-B6-A-352-8471.dat</file><file>Run_Angle_Scan-B6-A-353-8472.dat</file><file>Run_Angle_Scan-B6-A-355-8473.dat</file><file>Run_Angle_Scan-B6-A-356-8474.dat</file><file>Run_Angle_Scan-B6-A-357-8475.dat</file><file>Run_Angle_Scan-B6-A-358-8476.dat</file><file>Run_Angle_Scan-B6-A-359-8477.dat</file><file>Run_Angle_Scan-B6-A-360-8478.dat</file><file>Run_Angle_Scan-B6-A-361-8479.dat</file><file>Run_Angle_Scan-B6-A-362-8480.dat</file><file>Run_Angle_Scan-B6-A-363-8481.dat</file><file>Run_Angle_Scan-B6-A-367-8484.dat</file><file>Run_Angle_Scan-B6-A-368-8485.dat</file><file>Run_Angle_Scan-B6-A-369-8486.dat</file><file>Run_Angle_Scan-B6-A-370-8487.dat</file><file>Run_Angle_Scan-B6-A-371-8488.dat</file><file>Run_Angle_Scan-B6-A-372-8489.dat</file><file>Run_Angle_Scan-B6-A-373-8490.dat</file><file>Run_Angle_Scan-B6-A-374-8491.dat</file><file>Run_Angle_Scan-B6-A-375-8492.dat</file><file>Run_Angle_Scan-B6-A-376-8493.dat</file><file>Run_Angle_Scan-B6-A-377-8494.dat</file><file>Run_Angle_Scan-B6-A-387-8503.dat</file><file>Run_Angle_Scan-B6-A-388-8504.dat</file><file>Run_Angle_Scan-B6-A-389-8505.dat</file><file>Run_Angle_Scan-B6-A-390-8506.dat</file><file>Run_Angle_Scan-B6-A-391-8507.dat</file><file>Run_Angle_Scan-B6-A-415-8530.dat</file><file>Run_Angle_Scan-B6-A-416-8531.dat</file><file>Run_Angle_Scan-B6-A-417-8532.dat</file><file>Run_Angle_Scan-B6-A-418-8533.dat</file><file>Run_Angle_Scan-B6-A-419-8534.dat</file><file>Run_Angle_Scan-B6-A-422-8535.dat</file><file>Run_Angle_Scan-B6-A-423-8536.dat</file><file>Run_Angle_Scan-B6-A-424-8537.dat</file><file>Run_Angle_Scan-B6-A-425-8538.dat</file><file>Run_Angle_Scan-B6-A-426-8539.dat</file><file>Run_Angle_Scan-B6-A-427-8540.dat</file><file>Run_Angle_Scan-B6-A-428-8541.dat</file><file>Run_Angle_Scan-B6-A-429-8542.dat</file><file>Run_Angle_Scan-B6-A-430-8543.dat</file><file>Run_Angle_Scan-B6-A-431-8544.dat</file><file>Run_Angle_Scan-B6-A-432-8545.dat</file><file>Run_Angle_Scan-B6-A-433-8546.dat</file><file>Run_Angle_Scan-B6-A-434-8547.dat</file><file>Run_Angle_Scan-B6-A-435-8548.dat</file><file>Run_Angle_Scan-B6-A-436-8549.dat</file><file>Run_Angle_Scan-B6-A-437-8550.dat</file></AngleScan></directory><directory name="BoardA9"><Pedestal /><BiasScan><file>Run_Bias_Scan-B4-A-1-8016.dat</file><file>Run_Bias_Scan-B4-A-10-8023.dat</file><file>Run_Bias_Scan-B4-A-105-8113.dat</file><file>Run_Bias_Scan-B4-A-106-8114.dat</file><file>Run_Bias_Scan-B4-A-107-8115.dat</file><file>Run_Bias_Scan-B4-A-108-8116.dat</file><file>Run_Bias_Scan-B4-A-109-8117.dat</file><file>Run_Bias_Scan-B4-A-110-8118.dat</file><file>Run_Bias_Scan-B4-A-111-8119.dat</file><file>Run_Bias_Scan-B4-A-112-8120.dat</file><file>Run_Bias_Scan-B4-A-19-8032.dat</file><file>Run_Bias_Scan-B4-A-2-8017.dat</file><file>Run_Bias_Scan-B4-A-20-8033_BAD.dat</file><file>Run_Bias_Scan-B4-A-22-8033_BAD.dat</file><file>Run_Bias_Scan-B4-A-26-8034.dat</file><file>Run_Bias_Scan-B4-A-27-8035.dat</file><file>Run_Bias_Scan-B4-A-28-8036.dat</file><file>Run_Bias_Scan-B4-A-29-8037.dat</file><file>Run_Bias_Scan-B4-A-3-8018.dat</file><file>Run_Bias_Scan-B4-A-30-8038.dat</file><file>Run_Bias_Scan-B4-A-31-8039.dat</file><file>Run_Bias_Scan-B4-A-32-8040.dat</file><file>Run_Bias_Scan-B4-A-4-8019.dat</file><file>Run_Bias_Scan-B4-A-41-8049.dat</file><file>Run_Bias_Scan-B4-A-42-8050.dat</file><file>Run_Bias_Scan-B4-A-43-8051.dat</file><file>Run_Bias_Scan-B4-A-44-8052.dat</file><file>Run_Bias_Scan-B4-A-47-8055.dat</file><file>Run_Bias_Scan-B4-A-48-8056.dat</file><file>Run_Bias_Scan-B4-A-49-8057.dat</file><file>Run_Bias_Scan-B4-A-5-8020.dat</file><file>Run_Bias_Scan-B4-A-50-8058.dat</file><file>Run_Bias_Scan-B4-A-51-8059.dat</file><file>Run_Bias_Scan-B4-A-53-8060.dat</file><file>Run_Bias_Scan-B4-A-56-8061.dat</file><file>Run_Bias_Scan-B4-A-57-8062.dat</file><file>Run_Bias_Scan-B4-A-58-8063.dat</file><file>Run_Bias_Scan-B4-A-6-8021.dat</file><file>Run_Bias_Scan-B4-A-69-8076.dat</file><file>Run_Bias_Scan-B4-A-70-8077.dat</file><file>Run_Bias_Scan-B4-A-73-8081.dat</file><file>Run_Bias_Scan-B4-A-74-8082.dat</file><file>Run_Bias_Scan-B4-A-75-8083.dat</file><file>Run_Bias_Scan-B4-A-76-8084.dat</file><file>Run_Bias_Scan-B4-A-77-8085.dat</file><file>Run_Bias_Scan-B4-A-78-8086.dat</file><file>Run_Bias_Scan-B4-A-79-8087.dat</file><file>Run_Bias_Scan-B4-A-8-8021.dat</file><file>Run_Bias_Scan-B4-A-80-8088.dat</file><file>Run_Bias_Scan-B4-A-89-8097.dat</file><file>Run_Bias_Scan-B4-A-9-8022.dat</file><file>Run_Bias_Scan-B4-A-90-8098.dat</file><file>Run_Bias_Scan-B4-A-91-8099.dat</file><file>Run_Bias_Scan-B4-A-92-8100.dat</file><file>Run_Bias_Scan-B4-A-93-8101.dat</file><file>Run_Bias_Scan-B4-A-94-8102.dat</file><file>Run_Bias_Scan-B4-A-95-8103.dat</file><file>Run_Bias_Scan-B4-A-96-8104.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-121-8130.dat</file><file>Run_Angle_Scan-B1-A-122-8131.dat</file><file>Run_Angle_Scan-B4-A-100-8108.dat</file><file>Run_Angle_Scan-B4-A-101-8109.dat</file><file>Run_Angle_Scan-B4-A-102-8110.dat</file><file>Run_Angle_Scan-B4-A-103-8111.dat</file><file>Run_Angle_Scan-B4-A-104-8112.dat</file><file>Run_Angle_Scan-B4-A-11-8024.dat</file><file>Run_Angle_Scan-B4-A-113-8121.dat</file><file>Run_Angle_Scan-B4-A-114-8122.dat</file><file>Run_Angle_Scan-B4-A-115-8123.dat</file><file>Run_Angle_Scan-B4-A-116-8124.dat</file><file>Run_Angle_Scan-B4-A-117-8125.dat</file><file>Run_Angle_Scan-B4-A-118-8126.dat</file><file>Run_Angle_Scan-B4-A-119-8127.dat</file><file>Run_Angle_Scan-B4-A-12-8025.dat</file><file>Run_Angle_Scan-B4-A-120-8128.dat</file><file>Run_Angle_Scan-B4-A-13-8026.dat</file><file>Run_Angle_Scan-B4-A-14-8027.dat</file><file>Run_Angle_Scan-B4-A-15-8028.dat</file><file>Run_Angle_Scan-B4-A-16-8029.dat</file><file>Run_Angle_Scan-B4-A-17-8030.dat</file><file>Run_Angle_Scan-B4-A-18-8031.dat</file><file>Run_Angle_Scan-B4-A-33-8041.dat</file><file>Run_Angle_Scan-B4-A-34-8042.dat</file><file>Run_Angle_Scan-B4-A-35-8043.dat</file><file>Run_Angle_Scan-B4-A-36-8044.dat</file><file>Run_Angle_Scan-B4-A-37-8045.dat</file><file>Run_Angle_Scan-B4-A-38-8046.dat</file><file>Run_Angle_Scan-B4-A-39-8047.dat</file><file>Run_Angle_Scan-B4-A-40-8048.dat</file><file>Run_Angle_Scan-B4-A-59-8064.dat</file><file>Run_Angle_Scan-B4-A-60-8065.dat</file><file>Run_Angle_Scan-B4-A-61-8066.dat</file><file>Run_Angle_Scan-B4-A-62-8067.dat</file><file>Run_Angle_Scan-B4-A-63-8068.dat</file><file>Run_Angle_Scan-B4-A-64-8069.dat</file><file>Run_Angle_Scan-B4-A-65-8070.dat</file><file>Run_Angle_Scan-B4-A-66-8071.dat</file><file>Run_Angle_Scan-B4-A-67-8073.dat</file><file>Run_Angle_Scan-B4-A-68-8075.dat</file><file>Run_Angle_Scan-B4-A-81-8089.dat</file><file>Run_Angle_Scan-B4-A-82-8090.dat</file><file>Run_Angle_Scan-B4-A-83-8091.dat</file><file>Run_Angle_Scan-B4-A-84-8092.dat</file><file>Run_Angle_Scan-B4-A-85-8093.dat</file><file>Run_Angle_Scan-B4-A-86-8094.dat</file><file>Run_Angle_Scan-B4-A-87-8095.dat</file><file>Run_Angle_Scan-B4-A-88-8096.dat</file><file>Run_Angle_Scan-B4-A-97-8105.dat</file><file>Run_Angle_Scan-B4-A-98-8106.dat</file><file>Run_Angle_Scan-B4-A-99-8107.dat</file></AngleScan></directory><directory name="BoardD-irradiated"><Pedestal /><BiasScan /><AngleScan /></directory><directory name="BoardD-irradiated-behind-telescope"><Pedestal><file>Pedestal-B1-A-282-None.dat</file><file>Pedestal-B1-A-291-9113.dat</file><file>Pedestal-B1-A-296-9117.dat</file><file>Pedestal-B1-A-304-9122.dat</file><file>Pedestal-B1-A-305-9123.dat</file><file>Pedestal-B1-A-306-9124.dat</file><file>Pedestal-B1-A-307-9125.dat</file><file>Pedestal-B1-A-308-9126.dat</file><file>Pedestal-B1-A-309-none.dat</file><file>Pedestal-B1-D-356-9370.dat</file><file>Pedestal-B1-D-363-9383.dat</file><file>Pedestal-B1-D-370-9390.dat</file><file>Pedestal-B1-D-386-9431.dat</file><file>Pedestal-B1-D-387-9432.dat</file><file>Pedestal-B1-D-395-9440.dat</file><file>Pedestal-B1-D-553-xxxx.dat</file><file>Pedestal-B1-D-554-xxxx.dat</file><file>Pedestal-B1-D-555-xxxx.dat</file><file>Pedestal-B1-D-556-xxxx.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B1-A-273-9095.dat</file><file>Run_Bias_Scan-B1-A-274-9095.dat</file><file>Run_Bias_Scan-B1-A-275-9095.dat</file><file>Run_Bias_Scan-B1-A-276-9097.dat</file><file>Run_Bias_Scan-B1-A-277-9098.dat</file><file>Run_Bias_Scan-B1-A-278-9099.dat</file><file>Run_Bias_Scan-B1-A-279-9100.dat</file><file>Run_Bias_Scan-B1-A-280-9101.dat</file><file>Run_Bias_Scan-B1-A-281-9105.dat</file><file>Run_Bias_Scan-B1-D-310-9242.dat</file><file>Run_Bias_Scan-B1-D-312-9244.dat</file><file>Run_Bias_Scan-B1-D-314-9245.dat</file><file>Run_Bias_Scan-B1-D-315-9246.dat</file><file>Run_Bias_Scan-B1-D-316-9247.dat</file><file>Run_Bias_Scan-B1-D-317-9248.dat</file><file>Run_Bias_Scan-B1-D-318-9249.dat</file><file>Run_Bias_Scan-B1-D-319-9250.dat</file><file>Run_Bias_Scan-B1-D-320-9251.dat</file><file>Run_Bias_Scan-B1-D-321-9252.dat</file><file>Run_Bias_Scan-B1-D-340-9272.dat</file><file>Run_Bias_Scan-B1-D-341-9353.dat</file><file>Run_Bias_Scan-B1-D-342-9354.dat</file><file>Run_Bias_Scan-B1-D-343-9354.dat</file><file>Run_Bias_Scan-B1-D-344-9356.dat</file><file>Run_Bias_Scan-B1-D-345-9357.dat</file><file>Run_Bias_Scan-B1-D-346-9359.dat</file><file>Run_Bias_Scan-B1-D-347-9360.dat</file><file>Run_Bias_Scan-B1-D-348-9362.dat</file><file>Run_Bias_Scan-B1-D-371-9413.dat</file><file>Run_Bias_Scan-B1-D-372-9413.dat</file><file>Run_Bias_Scan-B1-D-373-9415.dat</file><file>Run_Bias_Scan-B1-D-374-9417.dat</file><file>Run_Bias_Scan-B1-D-375-9419.dat</file><file>Run_Bias_Scan-B1-D-376-9421.dat</file><file>Run_Bias_Scan-B1-D-377-9422.dat</file><file>Run_Bias_Scan-B1-D-378-9423.dat</file><file>Run_Bias_Scan-B1-D-379-9424.dat</file><file>Run_Bias_Scan-B1-D-453-9635.dat</file><file>Run_Bias_Scan-B1-D-454-9636.dat</file><file>Run_Bias_Scan-B1-D-455-9637.dat</file><file>Run_Bias_Scan-B1-D-456-9638.dat</file><file>Run_Bias_Scan-B1-D-457-9639.dat</file><file>Run_Bias_Scan-B1-D-458-9640.dat</file><file>Run_Bias_Scan-B1-D-459-9641.dat</file><file>Run_Bias_Scan-B1-D-460-9652.dat</file><file>Run_Bias_Scan-B1-D-461-9645.dat</file><file>Run_Bias_Scan-B1-D-462-9646.dat</file><file>Run_Bias_Scan-B1-D-464-9652.dat</file><file>Run_Bias_Scan-B1-D-465-9653.dat</file><file>Run_Bias_Scan-B1-D-466-9654.dat</file><file>Run_Bias_Scan-B1-D-467-9655.dat</file><file>Run_Bias_Scan-B1-D-468-9656.dat</file><file>Run_Bias_Scan-B1-D-469-9657.dat</file><file>Run_Bias_Scan-B1-D-470-9658.dat</file><file>Run_Bias_Scan-B1-D-471-9659.dat</file><file>Run_Bias_Scan-B1-D-472-9660.dat</file><file>Run_Bias_Scan-B1-D-473-9661.dat</file><file>Run_Bias_Scan-B1-D-474-9662.dat</file><file>Run_Bias_Scan-B1-D-475-9663.dat</file><file>Run_Bias_Scan-B1-D-476-9664.dat</file><file>Run_Bias_Scan-B1-D-477-9665.dat</file><file>Run_Bias_Scan-B1-D-478-9666.dat</file><file>Run_Bias_Scan-B1-D-479-9667.dat</file><file>Run_Bias_Scan-B1-D-480-9670.dat</file><file>Run_Bias_Scan-B1-D-481-9671.dat</file><file>Run_Bias_Scan-B1-D-482-9672.dat</file><file>Run_Bias_Scan-B1-D-483-9673.dat</file><file>Run_Bias_Scan-B1-D-484-9674.dat</file><file>Run_Bias_Scan-B1-D-487-9761.dat</file><file>Run_Bias_Scan-B1-D-488-9762.dat</file><file>Run_Bias_Scan-B1-D-489-9763.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B1-A-283-9106.dat</file><file>Run_Angle_Scan-B1-A-286-9108.dat</file><file>Run_Angle_Scan-B1-A-287-9109.dat</file><file>Run_Angle_Scan-B1-A-288-9110.dat</file><file>Run_Angle_Scan-B1-A-289-9111.dat</file><file>Run_Angle_Scan-B1-A-290-9112.dat</file><file>Run_Angle_Scan-B1-A-292-9113.dat</file><file>Run_Angle_Scan-B1-A-293-9114.dat</file><file>Run_Angle_Scan-B1-A-294-9115.dat</file><file>Run_Angle_Scan-B1-A-295-9116.dat</file><file>Run_Angle_Scan-B1-A-297-9117.dat</file><file>Run_Angle_Scan-B1-A-298-9117.dat</file><file>Run_Angle_Scan-B1-A-299-9118.dat</file><file>Run_Angle_Scan-B1-A-300-9119.dat</file><file>Run_Angle_Scan-B1-A-301-9120.dat</file><file>Run_Angle_Scan-B1-A-302-9121.dat</file><file>Run_Angle_Scan-B1-A-303-9122.dat</file><file>Run_Angle_Scan-B1-D-322-9253.dat</file><file>Run_Angle_Scan-B1-D-323-9254.dat</file><file>Run_Angle_Scan-B1-D-324-9255.dat</file><file>Run_Angle_Scan-B1-D-325-9256.dat</file><file>Run_Angle_Scan-B1-D-326-9257.dat</file><file>Run_Angle_Scan-B1-D-327-9258.dat</file><file>Run_Angle_Scan-B1-D-328-9259.dat</file><file>Run_Angle_Scan-B1-D-329-9260.dat</file><file>Run_Angle_Scan-B1-D-330-9261.dat</file><file>Run_Angle_Scan-B1-D-331-9262.dat</file><file>Run_Angle_Scan-B1-D-332-9263.dat</file><file>Run_Angle_Scan-B1-D-333-9264.dat</file><file>Run_Angle_Scan-B1-D-334-9265.dat</file><file>Run_Angle_Scan-B1-D-335-9266.dat</file><file>Run_Angle_Scan-B1-D-336-9267.dat</file><file>Run_Angle_Scan-B1-D-337-9268.dat</file><file>Run_Angle_Scan-B1-D-338-9269.dat</file><file>Run_Angle_Scan-B1-D-339-9270.dat</file><file>Run_Angle_Scan-B1-D-350-9363.dat</file><file>Run_Angle_Scan-B1-D-351-9364.dat</file><file>Run_Angle_Scan-B1-D-352-9366.dat</file><file>Run_Angle_Scan-B1-D-353-9367.dat</file><file>Run_Angle_Scan-B1-D-354-9368.dat</file><file>Run_Angle_Scan-B1-D-355-9369.dat</file><file>Run_Angle_Scan-B1-D-357-9377.dat</file><file>Run_Angle_Scan-B1-D-358-9378.dat</file><file>Run_Angle_Scan-B1-D-359-9379.dat</file><file>Run_Angle_Scan-B1-D-360-9380.dat</file><file>Run_Angle_Scan-B1-D-361-9381.dat</file><file>Run_Angle_Scan-B1-D-362-9382.dat</file><file>Run_Angle_Scan-B1-D-364-9384.dat</file><file>Run_Angle_Scan-B1-D-365-9385.dat</file><file>Run_Angle_Scan-B1-D-366-9386.dat</file><file>Run_Angle_Scan-B1-D-367-9387.dat</file><file>Run_Angle_Scan-B1-D-368-9388.dat</file><file>Run_Angle_Scan-B1-D-369-9389.dat</file><file>Run_Angle_Scan-B1-D-380-9425.dat</file><file>Run_Angle_Scan-B1-D-381-9426.dat</file><file>Run_Angle_Scan-B1-D-382-9427.dat</file><file>Run_Angle_Scan-B1-D-383-9428.dat</file><file>Run_Angle_Scan-B1-D-384-9429.dat</file><file>Run_Angle_Scan-B1-D-385-9430.dat</file><file>Run_Angle_Scan-B1-D-388-9433.dat</file><file>Run_Angle_Scan-B1-D-389-9434.dat</file><file>Run_Angle_Scan-B1-D-390-9435.dat</file><file>Run_Angle_Scan-B1-D-391-9436.dat</file><file>Run_Angle_Scan-B1-D-392-9437.dat</file><file>Run_Angle_Scan-B1-D-393-9438.dat</file><file>Run_Angle_Scan-B1-D-394-9439.dat</file><file>Run_Angle_Scan-B1-D-398-9442.dat</file><file>Run_Angle_Scan-B1-D-401-9444.dat</file><file>Run_Angle_Scan-B1-D-402-9444.dat</file><file>Run_Angle_Scan-B1-D-403-9446.dat</file><file>Run_Angle_Scan-B1-D-404-9447.dat</file><file>Run_Angle_Scan-B1-D-405-9448.dat</file><file>Run_Angle_Scan-B1-D-406-9449.dat</file><file>Run_Angle_Scan-B1-D-407-9450.dat</file><file>Run_Angle_Scan-B1-D-408-9451.dat</file><file>Run_Angle_Scan-B1-D-409-9452.dat</file><file>Run_Angle_Scan-B1-D-490-9764.dat</file><file>Run_Angle_Scan-B1-D-491-9765.dat</file><file>Run_Angle_Scan-B1-D-492-9766.dat</file><file>Run_Angle_Scan-B1-D-493-9767.dat</file><file>Run_Angle_Scan-B1-D-494-9768.dat</file><file>Run_Angle_Scan-B1-D-495-9769.dat</file><file>Run_Angle_Scan-B1-D-496-9770.dat</file><file>Run_Angle_Scan-B1-D-497-9771.dat</file><file>Run_Angle_Scan-B1-D-498-9772.dat</file><file>Run_Angle_Scan-B1-D-499-9773.dat</file><file>Run_Angle_Scan-B1-D-500-9774.dat</file><file>Run_Angle_Scan-B1-D-501-9775.dat</file><file>Run_Angle_Scan-B1-D-502-9777.dat</file><file>Run_Angle_Scan-B1-D-503-9778.dat</file><file>Run_Angle_Scan-B1-D-504-9779.dat</file><file>Run_Angle_Scan-B1-D-505-9780.dat</file><file>Run_Angle_Scan-B1-D-506-9781.dat</file><file>Run_Angle_Scan-B1-D-507-9782.dat</file><file>Run_Angle_Scan-B1-D-508-9784.dat</file><file>Run_Angle_Scan-B1-D-509-9785.dat</file><file>Run_Angle_Scan-B1-D-510-9786.dat</file><file>Run_Angle_Scan-B1-D-511-9787.dat</file><file>Run_Angle_Scan-B1-D-512-9788.dat</file><file>Run_Angle_Scan-B1-D-513-9789.dat</file><file>Run_Angle_Scan-B1-D-514-9791.dat</file><file>Run_Angle_Scan-B1-D-515-9792.dat</file><file>Run_Angle_Scan-B1-D-516-9793.dat</file><file>Run_Angle_Scan-B1-D-517-9794.dat</file><file>Run_Angle_Scan-B1-D-518-9795.dat</file><file>Run_Angle_Scan-B1-D-519-9796.dat</file><file>Run_Angle_Scan-B1-D-520-9797.dat</file><file>Run_Angle_Scan-B1-D-521-9798.dat</file><file>Run_Angle_Scan-B1-D-522-9799.dat</file><file>Run_Angle_Scan-B1-D-523-9800.dat</file><file>Run_Angle_Scan-B1-D-524-9801.dat</file><file>Run_Angle_Scan-B1-D-525-9802.dat</file><file>Run_Angle_Scan-B1-D-526-9803.dat</file><file>Run_Angle_Scan-B1-D-528-9804.dat</file><file>Run_Angle_Scan-B1-D-529-9807.dat</file><file>Run_Angle_Scan-B1-D-530-9808.dat</file><file>Run_Angle_Scan-B1-D-531-9809.dat</file><file>Run_Angle_Scan-B1-D-532-9810.dat</file><file>Run_Angle_Scan-B1-D-533-9811.dat</file><file>Run_Angle_Scan-B1-D-534-9812.dat</file><file>Run_Angle_Scan-B1-D-535-9813.dat</file><file>Run_Angle_Scan-B1-D-536-9814.dat</file><file>Run_Angle_Scan-B1-D-537-9815.dat</file><file>Run_Angle_Scan-B1-D-538-9816.dat</file><file>Run_Angle_Scan-B1-D-539-9817.dat</file><file>Run_Angle_Scan-B1-D-540-9818.dat</file><file>Run_Angle_Scan-B1-D-541-9818.dat</file><file>Run_Angle_Scan-B1-D-545-9821.dat</file><file>Run_Angle_Scan-B1-D-546-9822.dat</file><file>Run_Angle_Scan-B1-D-547-9823.dat</file><file>Run_Angle_Scan-B1-D-548-9825.dat</file><file>Run_Angle_Scan-B1-D-549-9826.dat</file><file>Run_Angle_Scan-B1-D-550-9827.dat</file></AngleScan></directory><directory name="BoardD9"><Pedestal><file>Pedestal-B9-D-264-.dat</file><file>Pedestal-B9-D-271-.dat</file><file>Pedestal-B9-D-279-.dat</file><file>Pedestal-B9-D-286-.dat</file><file>Pedestal-B9-D-293-.dat</file><file>Pedestal-B9-D-297-.dat</file><file>Pedestal-B9-D-300-.dat</file><file>Pedestal-B9-D-312-.dat</file><file>Pedestal-B9-D-315-.dat</file><file>Pedestal-B9-D-319-.dat</file><file>Pedestal-B9-D-326-.dat</file><file>Pedestal-B9-D-327-0.dat</file><file>Pedestal-B9-D-329-.dat</file><file>Pedestal-B9-D-334-0.dat</file><file>Pedestal-B9-D-350-.dat</file></Pedestal><BiasScan><file>Run_Bias_Scan-B9-D-262-8746.dat</file><file>Run_Bias_Scan-B9-D-263-8747.dat</file><file>Run_Bias_Scan-B9-D-264-8748.dat</file><file>Run_Bias_Scan-B9-D-265-8749.dat</file><file>Run_Bias_Scan-B9-D-266-8750.dat</file><file>Run_Bias_Scan-B9-D-267-8751.dat</file><file>Run_Bias_Scan-B9-D-268-8752.dat</file><file>Run_Bias_Scan-B9-D-269-8753.dat</file><file>Run_Bias_Scan-B9-D-272-8837.dat</file><file>Run_Bias_Scan-B9-D-273-8838.dat</file><file>Run_Bias_Scan-B9-D-274-8839.dat</file><file>Run_Bias_Scan-B9-D-275-8840.dat</file><file>Run_Bias_Scan-B9-D-276-8841.dat</file><file>Run_Bias_Scan-B9-D-277-8842.dat</file><file>Run_Bias_Scan-B9-D-278-8843.dat</file><file>Run_Bias_Scan-B9-D-279-8844.dat</file><file>Run_Bias_Scan-B9-D-298-8774.dat</file><file>Run_Bias_Scan-B9-D-299-8775.dat</file><file>Run_Bias_Scan-B9-D-300-8776.dat</file><file>Run_Bias_Scan-B9-D-301-8777.dat</file><file>Run_Bias_Scan-B9-D-301-8863.dat</file><file>Run_Bias_Scan-B9-D-302-8778.dat</file><file>Run_Bias_Scan-B9-D-302-8864.dat</file><file>Run_Bias_Scan-B9-D-303-8779.dat</file><file>Run_Bias_Scan-B9-D-303-8865.dat</file><file>Run_Bias_Scan-B9-D-304-8780.dat</file><file>Run_Bias_Scan-B9-D-304-8866.dat</file><file>Run_Bias_Scan-B9-D-305-8781.dat</file><file>Run_Bias_Scan-B9-D-305-8867.dat</file><file>Run_Bias_Scan-B9-D-306-8868.dat</file><file>Run_Bias_Scan-B9-D-307-8869.dat</file><file>Run_Bias_Scan-B9-D-308-8870.dat</file><file>Run_Bias_Scan-B9-D-330-8802.dat</file><file>Run_Bias_Scan-B9-D-331-8803.dat</file><file>Run_Bias_Scan-B9-D-332-8804.dat</file><file>Run_Bias_Scan-B9-D-333-8805.dat</file><file>Run_Bias_Scan-B9-D-334-8806.dat</file><file>Run_Bias_Scan-B9-D-335-8807.dat</file><file>Run_Bias_Scan-B9-D-335-8891.dat</file><file>Run_Bias_Scan-B9-D-336-8808.dat</file><file>Run_Bias_Scan-B9-D-336-8892.dat</file><file>Run_Bias_Scan-B9-D-337-8809.dat</file><file>Run_Bias_Scan-B9-D-337-8893.dat</file><file>Run_Bias_Scan-B9-D-338-8894.dat</file><file>Run_Bias_Scan-B9-D-339-8895.dat</file><file>Run_Bias_Scan-B9-D-340-8896.dat</file><file>Run_Bias_Scan-B9-D-341-8897.dat</file><file>Run_Bias_Scan-B9-D-342-8898.dat</file></BiasScan><AngleScan><file>Run_Angle_Scan-B9-D-256-8825.dat</file><file>Run_Angle_Scan-B9-D-257-8826.dat</file><file>Run_Angle_Scan-B9-D-257-8903.dat</file><file>Run_Angle_Scan-B9-D-258-8827.dat</file><file>Run_Angle_Scan-B9-D-258-8904.dat</file><file>Run_Angle_Scan-B9-D-259-8828.dat</file><file>Run_Angle_Scan-B9-D-259-8905.dat</file><file>Run_Angle_Scan-B9-D-260-8906.dat</file><file>Run_Angle_Scan-B9-D-261-8829.dat</file><file>Run_Angle_Scan-B9-D-261-8907.dat</file><file>Run_Angle_Scan-B9-D-262-8908.dat</file><file>Run_Angle_Scan-B9-D-263-8830.dat</file><file>Run_Angle_Scan-B9-D-263-8909.dat</file><file>Run_Angle_Scan-B9-D-264-8910.dat</file><file>Run_Angle_Scan-B9-D-265-8831.dat</file><file>Run_Angle_Scan-B9-D-265-8911.dat</file><file>Run_Angle_Scan-B9-D-266-8832.dat</file><file>Run_Angle_Scan-B9-D-266-8912.dat</file><file>Run_Angle_Scan-B9-D-267-8833.dat</file><file>Run_Angle_Scan-B9-D-267-8913.dat</file><file>Run_Angle_Scan-B9-D-268-8834.dat</file><file>Run_Angle_Scan-B9-D-268-8914.dat</file><file>Run_Angle_Scan-B9-D-269-8835.dat</file><file>Run_Angle_Scan-B9-D-269-8915.dat</file><file>Run_Angle_Scan-B9-D-270-8754.dat</file><file>Run_Angle_Scan-B9-D-270-8836.dat</file><file>Run_Angle_Scan-B9-D-270-8916.dat</file><file>Run_Angle_Scan-B9-D-271-8755.dat</file><file>Run_Angle_Scan-B9-D-271-8917.dat</file><file>Run_Angle_Scan-B9-D-272-8756.dat</file><file>Run_Angle_Scan-B9-D-272-8918.dat</file><file>Run_Angle_Scan-B9-D-273-8757.dat</file><file>Run_Angle_Scan-B9-D-274-8758.dat</file><file>Run_Angle_Scan-B9-D-275-8759.dat</file><file>Run_Angle_Scan-B9-D-276-8761.dat</file><file>Run_Angle_Scan-B9-D-280-8762.dat</file><file>Run_Angle_Scan-B9-D-280-8845.dat</file><file>Run_Angle_Scan-B9-D-281-8763.dat</file><file>Run_Angle_Scan-B9-D-281-8846.dat</file><file>Run_Angle_Scan-B9-D-282-8764.dat</file><file>Run_Angle_Scan-B9-D-282-8847.dat</file><file>Run_Angle_Scan-B9-D-283-8765.dat</file><file>Run_Angle_Scan-B9-D-283-8848.dat</file><file>Run_Angle_Scan-B9-D-284-8766.dat</file><file>Run_Angle_Scan-B9-D-284-8849.dat</file><file>Run_Angle_Scan-B9-D-285-8767.dat</file><file>Run_Angle_Scan-B9-D-285-8850.dat</file><file>Run_Angle_Scan-B9-D-287-8768.dat</file><file>Run_Angle_Scan-B9-D-287-8851.dat</file><file>Run_Angle_Scan-B9-D-288-8768.dat</file><file>Run_Angle_Scan-B9-D-288-8852.dat</file><file>Run_Angle_Scan-B9-D-289-8768.dat</file><file>Run_Angle_Scan-B9-D-289-8853.dat</file><file>Run_Angle_Scan-B9-D-290-8854.dat</file><file>Run_Angle_Scan-B9-D-291-8855.dat</file><file>Run_Angle_Scan-B9-D-292-8769.dat</file><file>Run_Angle_Scan-B9-D-292-8856.dat</file><file>Run_Angle_Scan-B9-D-293-8770.dat</file><file>Run_Angle_Scan-B9-D-294-8771.dat</file><file>Run_Angle_Scan-B9-D-294-8857.dat</file><file>Run_Angle_Scan-B9-D-295-8772.dat</file><file>Run_Angle_Scan-B9-D-295-8858.dat</file><file>Run_Angle_Scan-B9-D-296-8773.dat</file><file>Run_Angle_Scan-B9-D-296-8859.dat</file><file>Run_Angle_Scan-B9-D-297-8860.dat</file><file>Run_Angle_Scan-B9-D-298-8861.dat</file><file>Run_Angle_Scan-B9-D-299-8862.dat</file><file>Run_Angle_Scan-B9-D-306-8782.dat</file><file>Run_Angle_Scan-B9-D-307-8783.dat</file><file>Run_Angle_Scan-B9-D-308-8784.dat</file><file>Run_Angle_Scan-B9-D-309-8785.dat</file><file>Run_Angle_Scan-B9-D-309-8871.dat</file><file>Run_Angle_Scan-B9-D-310-8786.dat</file><file>Run_Angle_Scan-B9-D-310-8872.dat</file><file>Run_Angle_Scan-B9-D-311-8787.dat</file><file>Run_Angle_Scan-B9-D-311-8873.dat</file><file>Run_Angle_Scan-B9-D-312-8874.dat</file><file>Run_Angle_Scan-B9-D-313-8788.dat</file><file>Run_Angle_Scan-B9-D-313-8875.dat</file><file>Run_Angle_Scan-B9-D-314-8789.dat</file><file>Run_Angle_Scan-B9-D-314-8876.dat</file><file>Run_Angle_Scan-B9-D-315-8790.dat</file><file>Run_Angle_Scan-B9-D-316-8791.dat</file><file>Run_Angle_Scan-B9-D-317-8792.dat</file><file>Run_Angle_Scan-B9-D-318-8793.dat</file><file>Run_Angle_Scan-B9-D-318-8877.dat</file><file>Run_Angle_Scan-B9-D-320-8784.dat</file><file>Run_Angle_Scan-B9-D-320-8878.dat</file><file>Run_Angle_Scan-B9-D-321-8785.dat</file><file>Run_Angle_Scan-B9-D-321-8879.dat</file><file>Run_Angle_Scan-B9-D-322-8880.dat</file><file>Run_Angle_Scan-B9-D-323-8796.dat</file><file>Run_Angle_Scan-B9-D-323-8881.dat</file><file>Run_Angle_Scan-B9-D-324-8797.dat</file><file>Run_Angle_Scan-B9-D-324-8882.dat</file><file>Run_Angle_Scan-B9-D-325-8798.dat</file><file>Run_Angle_Scan-B9-D-325-8883.dat</file><file>Run_Angle_Scan-B9-D-326-8799.dat</file><file>Run_Angle_Scan-B9-D-327-8800.dat</file><file>Run_Angle_Scan-B9-D-328-8801.dat</file><file>Run_Angle_Scan-B9-D-328-8885.dat</file><file>Run_Angle_Scan-B9-D-329-8886.dat</file><file>Run_Angle_Scan-B9-D-330-8887.dat</file><file>Run_Angle_Scan-B9-D-331-8888.dat</file><file>Run_Angle_Scan-B9-D-332-8889.dat</file><file>Run_Angle_Scan-B9-D-333-8890.dat</file><file>Run_Angle_Scan-B9-D-338-8810.dat</file><file>Run_Angle_Scan-B9-D-339-8811.dat</file><file>Run_Angle_Scan-B9-D-340-8812.dat</file><file>Run_Angle_Scan-B9-D-341-8813.dat</file><file>Run_Angle_Scan-B9-D-342-8814.dat</file><file>Run_Angle_Scan-B9-D-343-8899.dat</file><file>Run_Angle_Scan-B9-D-344-8815.dat</file><file>Run_Angle_Scan-B9-D-344-8900.dat</file><file>Run_Angle_Scan-B9-D-345-8816.dat</file><file>Run_Angle_Scan-B9-D-345-8901.dat</file><file>Run_Angle_Scan-B9-D-346-8817.dat</file><file>Run_Angle_Scan-B9-D-347-8818.dat</file><file>Run_Angle_Scan-B9-D-348-8819.dat</file><file>Run_Angle_Scan-B9-D-349-8820.dat</file><file>Run_Angle_Scan-B9-D-351-8821.dat</file><file>Run_Angle_Scan-B9-D-353-8821.dat</file><file>Run_Angle_Scan-B9-D-354-8822.dat</file><file>Run_Angle_Scan-B9-D-356-8823.dat</file><file>Run_Angle_Scan-B9-D-357-8824.dat</file></AngleScan></directory></root>
\ No newline at end of file
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/TbUTAnalyzer.py b/TbUT/scripts/TbUTAutomaticAnalyzer/TbUTAnalyzer.py
new file mode 100644
index 0000000..a13bb62
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/TbUTAnalyzer.py
@@ -0,0 +1,73 @@
+__author__ = 'ja'
+from xml.dom.minidom import parse
+import xml.dom.minidom
+import os
+from tempfile import mkstemp
+from shutil import move
+from os import remove, close
+
+class TbUTAnalyzer():
+
+    def __init__(self):
+        self.dirToAnalyse="BoardA4"
+        self.pathToDataInEos="/afs/cern.ch/user/a/adendek/eos/lhcb/testbeam/ut/OfficialData/July2015/"
+        self.scanType='BiasScan'  # one of 'AngleScan' 'BiasScan'
+        self.TbUTPath=os.path.expandvars("$KEPLERROOT")+"/../TbUT/"
+
+    def _performAnalysis(self, inputFilename):
+        print( "work on: " +inputFilename)
+        self.__changeOptionFile(inputFilename)
+        os.chdir(self.TbUTPath)
+        os.system("gaudirun.py options/TbUTRun.py")
+        os.system("gaudirun.py options/TbUTRun.py")
+        self._moveOutputRootFilesIntoDirectory(inputFilename)
+        ###
+        # add your stuffs here!
+        ###
+
+
+    def runAnalysis(self):
+        self._createOutputDir()
+        xmlRoot = xml.dom.minidom.parse('July2015Database.xml')
+        for directory in xmlRoot.getElementsByTagName('directory'):
+            if (directory.getAttribute("name")) in self.dirToAnalyse:
+                biasScan=directory.getElementsByTagName(self.scanType)
+                for run in biasScan[0].getElementsByTagName("file"):
+                    dataPath=self.pathToDataInEos+ self.dirToAnalyse+"/RawData/"+run.firstChild.nodeValue
+                    self._performAnalysis(dataPath)
+
+
+    def _createOutputDir(self):
+        self.outDirName=self.TbUTPath+"study_"+self.dirToAnalyse+"_"+self.scanType
+        if not os.path.exists(self.outDirName):
+            os.mkdir(self.outDirName)
+
+    def __changeOptionFile(self,inputFileName):
+        optionFilePath=self.TbUTPath+"options/TbUTRun.py"
+        fh, abs_path = mkstemp()
+        with open(abs_path,'w') as new_file:
+            with open(optionFilePath) as old_file:
+                for line in old_file:
+                    if not  "app.inputData" in line:
+                        new_file.write(line)
+                    else:
+                        new_file.write("app.inputData='"+inputFileName+"'\n")
+        close(fh)
+        #Remove original file
+        remove(optionFilePath)
+        #Move new file
+        move(abs_path, optionFilePath)
+
+    def _moveOutputRootFilesIntoDirectory(self, inputFilename):
+        outputName=inputFilename[:-4]+".root"
+        outputName=outputName[outputName.rfind("/")+1:]
+        move(outputName,self.outDirName+"/"+outputName)
+
+        outputTupleName=inputFilename[:-4]+"_Tuple.root"
+        outputTupleName=outputTupleName[outputTupleName.rfind("/")+1:]
+        move(outputTupleName,self.outDirName+"/"+outputTupleName)
+
+
+if __name__=='__main__':
+    analyzer = TbUTAnalyzer()
+    analyzer.runAnalysis()
diff --git a/TbUT/scripts/TbUTAutomaticAnalyzer/XmlGenerator.py b/TbUT/scripts/TbUTAutomaticAnalyzer/XmlGenerator.py
new file mode 100644
index 0000000..065d30e
--- /dev/null
+++ b/TbUT/scripts/TbUTAutomaticAnalyzer/XmlGenerator.py
@@ -0,0 +1,36 @@
+__author__ = 'ja'
+
+import xml.etree.cElementTree as ET
+from optparse import OptionParser
+import os
+
+parser = OptionParser()
+parser.add_option("-p", "--path", dest="path",
+                  help="path to eos", metavar="FILE")
+
+(options, args) = parser.parse_args()
+
+root = ET.Element("root")
+
+for dirname, dirnames, filenames in os.walk(options.path):
+    if '.git' in dirnames:
+        # don't go into any .git directories.
+        dirnames.remove('.git')
+    for subdirname in dirnames:
+        if "RawData" in subdirname:
+            boardName=dirname[dirname.rfind("/")+1:]
+            directory = ET.SubElement(root, "directory", name=boardName)
+            Pedestal=ET.SubElement(directory, "Pedestal",)
+            Bias=ET.SubElement(directory, "BiasScan",)
+            Angle=ET.SubElement(directory, "AngleScan",)
+
+    for filename in filenames:
+        if "Bias" in filename and ".xml" not in filename:
+            ET.SubElement(Bias, "file", ).text = filename
+        elif "Angle" in filename and ".xml" not in filename:
+            ET.SubElement(Angle, "file", ).text = filename
+        elif "Pedestal" in filename and ".xml" not in filename:
+            ET.SubElement(Pedestal, "file", ).text = filename
+
+tree = ET.ElementTree(root)
+tree.write("July2015Database.xml")
\ No newline at end of file
diff --git a/TbUT/scripts/ThresholdPlotter.cpp b/TbUT/scripts/ThresholdPlotter.cpp
new file mode 100644
index 0000000..f46176d
--- /dev/null
+++ b/TbUT/scripts/ThresholdPlotter.cpp
@@ -0,0 +1,67 @@
+#include<iostream>
+#include<vector>
+#include<string>
+#include "TH2D.h"
+
+
+using namespace std;
+
+void ThresholdPlotter()
+{
+    cout<<"start"<<endl;
+    string fileName="noise_Mamba.dat";
+    
+    ifstream l_file(fileName.c_str());
+    int channelsNumber=512;
+    std::vector<int> thresholVector(channelsNumber,0);
+
+    for(int channel=0;channel<channelsNumber;channel++)
+    {
+        double l_noiseFromFile=0;
+        l_file >> l_noiseFromFile;
+        thresholVector[channel]=l_noiseFromFile;
+        cout<<"NoiseRetreiver===> channel: "<< channel <<"noise: "<<l_noiseFromFile<<endl;
+    }
+   
+ 
+    cout<<"create histograms" <<endl;
+    TH2D* noiseHistogram= new TH2D("Noise Histogram","Noise (1#sigma)",100,-0.5,channelsNumber+0.5 , 100, 0, 200);
+    TH2D*  lowThresholdHistogram=new  TH2D("low Thresholds Histogram","low Thresholds ",100,-0.5,channelsNumber+0.5 , 100, 0, 200);
+    TH2D* highThresholdHistogram=new  TH2D("high Thresholds Histogram","high Thresholds ",100,-0.5,channelsNumber+0.5 , 100, 0, 200);
+
+    int lawThresholdMultiplicity=2.5;
+    int highThresholdMultiplicity=3;
+
+    cout<<"Fill histograms" <<endl;
+
+    for(int channel=0;channel<channelsNumber;channel++)
+    {
+        noiseHistogram->Fill(channel, thresholVector[channel]);
+        lowThresholdHistogram->Fill(channel,lawThresholdMultiplicity* thresholVector[channel]);
+        highThresholdHistogram->Fill(channel,highThresholdMultiplicity* thresholVector[channel]);
+    }
+
+    TCanvas * c1 = new TCanvas("c", "c", 600, 800);
+    
+    noiseHistogram->GetYaxis()->SetTitle("[ADC]");
+    noiseHistogram->GetXaxis()->SetTitle("channel");
+    noiseHistogram->SetMarkerStyle(2);
+    noiseHistogram->SetLineColor(kWhite);
+
+    lowThresholdHistogram->SetMarkerStyle(2);
+    lowThresholdHistogram->SetMarkerColor(kGreen);
+    lowThresholdHistogram->SetLineColor(kWhite);
+
+    highThresholdHistogram->SetMarkerStyle(2);
+    highThresholdHistogram->SetMarkerColor(kRed);
+    highThresholdHistogram->SetLineColor(kWhite);
+
+   
+    noiseHistogram->Draw();
+    lowThresholdHistogram->Draw("same");
+    highThresholdHistogram->Draw("same");
+    
+    c1->BuildLegend(0.7296238,0.8274793,0.9004702,0.8997934);
+    gStyle->SetOptStat(0);
+
+}
diff --git a/TbUT/scripts/charge_tdc.pdf b/TbUT/scripts/charge_tdc.pdf
new file mode 100644
index 0000000..e93cd5d
--- /dev/null
+++ b/TbUT/scripts/charge_tdc.pdf
Binary files differ
diff --git a/TbUT/scripts/clusterHit.pdf b/TbUT/scripts/clusterHit.pdf
new file mode 100644
index 0000000..b6758fd
--- /dev/null
+++ b/TbUT/scripts/clusterHit.pdf
Binary files differ
diff --git a/TbUT/scripts/corr.pdf b/TbUT/scripts/corr.pdf
new file mode 100644
index 0000000..2a73124
--- /dev/null
+++ b/TbUT/scripts/corr.pdf
Binary files differ
diff --git a/TbUT/scripts/correlation.pdf b/TbUT/scripts/correlation.pdf
new file mode 100644
index 0000000..062ab3c
--- /dev/null
+++ b/TbUT/scripts/correlation.pdf
Binary files differ
diff --git a/TbUT/scripts/fastAnalysis.py b/TbUT/scripts/fastAnalysis.py
new file mode 100755
index 0000000..2e5f034
--- /dev/null
+++ b/TbUT/scripts/fastAnalysis.py
@@ -0,0 +1,417 @@
+#!/usr/bin/env python
+
+"""
+fastAnalysis.py for use during UT testbeam data taking
+
+To use:
+1.  Set up TbUT running environment (https://twiki.cern.ch/twiki/bin/view/LHCb/TbUT)
+2.  Edit this script to point to your current eos mount point and the data dir for current testbeam, or use the command line options
+3.  From Tb/TbUT directory, run scripts/fastAnalysis.py with the following required options:
+    -b board    : Letter+number combination, e.g. 'A8'
+    -p pednum   : run number of the pedestal run to use (UT run number)
+    -r runnum   : run number to analyze (UT run number) -- enter 0 for pedestal analysis only
+4.  These are optional arguments:
+    -n nevmax   : number of events to analyze
+    -f force    : Force overwrite of any output files existing
+    -t senstype : sensor type ('PType' or 'NType')
+    -e eosmount : eos mount point for data to use (uses as a simple path)
+    -i indir    : input path relative to eosmount point to find data
+    -o outdir   : Directory to put the monitoring in
+5.  Inside outdir it will make monitoring directories, and save the pedestal .dat, root files, and defined plots there
+6.  It will not re-run the analysis if the files exist already unless you use -f
+7.  After running it will pop open a window to view the new plots, and exit when that window is closed
+"""
+
+############################################################
+##Modify this to change defaults: 
+nevdef=100000
+eosmount='/afs/cern.ch/work/m/mrudolph/private/nov_testbeam/eos'
+indir='lhcb/testbeam/ut/OfficialData/October2015'
+outdir='.'
+############################################################
+
+
+
+
+
+
+############################################################
+##Define all the draw commands for simple monitoring plots from Cluster tuple here
+##Noise mean and width are automatically created as the first 2 plots
+##The last plot will be the ADC in the fiducial region (that gets defined based on previous draw command postprocessing)
+#Potential TODO: create a new module file with the plot configuration to make extension a bit easier
+
+class draw_command():
+    """draw command skeleton for a TTree
+    
+    Need at least command, cut, option, title for histogram to make
+    Can also bind postprocessor functions to draw more stuff or
+    to return to the list of fiducial cuts for the final plot
+    """
+    def __init__(self, command, cut, option, title, postprocessor=None):
+        self.command = command
+        self.cut = cut
+        self.option = option
+        self.title = title
+        self.postprocessor = postprocessor
+
+
+##Post processing functions for histograms defined in draw commands -- expect TPad, TTree, TH1 parameters
+##  Code below could be used for a couple things -- you have the pad so you can process the hist and draw more things,
+##    or you can return a cut string that will be used to define the fiducial region later on
+
+def post_nostat( pad, tree, hist ):
+    """Generic postprocessor to remove stat box"""
+    hist.SetStats(False)
+
+def post_clusterpos( pad, tree, hist ):
+    """Process the cluster position histogram and find beam area"""
+    post_nostat( pad, tree, hist)
+
+    maxbin = hist.GetMaximumBin()
+    maxval = hist.GetBinContent(maxbin)
+    thresh = 0.25
+    #look to the left and then to the right
+    currbin = maxbin
+    while( hist.GetBinContent(currbin) > thresh*maxval ):
+        currbin -= 1
+    left = hist.GetXaxis().GetBinLowEdge(currbin)
+    currbin = maxbin
+    while( hist.GetBinContent(currbin) > thresh*maxval ):
+        currbin += 1
+    right = hist.GetXaxis().GetBinUpEdge(currbin)
+    
+    hist.GetYaxis().SetRangeUser(0,maxval*1.1)
+    from ROOT import TLine
+    l1 = TLine( left ,0, left,maxval*1.1)
+    pad.posl1=l1
+    l1.Draw()
+    l2 = TLine( right,0,right,maxval*1.1)
+    pad.posl2=l2
+    l2.Draw()
+    pad.Update()
+    return "clustersPosition > {} && clustersPosition < {}".format(left,right)
+
+def post_tdc_prof( pad, tree, hist ):
+    """Process the charge v. TDC profile and find timing cut"""
+    ymin = hist.GetMinimum()
+    if ymin < 0:
+        ymin *= 1.2
+    else:
+        ymin *= 0.8
+    ymax = hist.GetMaximum()
+    if ymax < 0:
+        ymax *= 0.8
+    else:
+        ymax *= 1.2
+    hist.GetYaxis().SetRangeUser(ymin,ymax)
+    isneg = (ymax < 0) or ( ymin < 0 and abs(ymin) > abs(ymax) )
+    if isneg:
+        b = hist.GetMinimumBin()
+    else:
+        b = hist.GetMaximumBin()
+
+    from ROOT import TLine
+    l1 = TLine( b - 1.5 ,ymin, b - 1.5,ymax)
+    pad.tdcl1=l1
+    l1.Draw()
+    l2 = TLine( b+1.5,ymin,b+1.5,ymax)
+    pad.tdcl2=l2
+    l2.Draw()
+    return "abs(clustersTDC - {}) <= 1.5".format(b)
+
+############################################################
+##The list of draw commands to run
+##Make sure for each command if you specify anything about the histogram to draw to, give it a unique name!
+## Fiducial adc name is "fidadc", noise are called "meanNoise" and "widthNoise"
+drawcommands = [ draw_command("clusterNumberPerEvent","","","Number of clusters;N_{clusters};Events"),
+                 draw_command("clustersCharge>>charge(200,-1200,0)","clustersSize > 0","","Cluster charge;Tot. charge [ADC];Clusters"),
+                 draw_command("clustersPosition","clustersSize > 0","","Cluster position;Channel;Clusters",postprocessor=post_clusterpos),
+                 draw_command("clustersSize","clustersSize > 0", "","Cluster size;N_{strips};Clusters"),
+                 draw_command("clustersTDC>>tdc(10,0.5,10.5)","","","TDC;TDC;Events",postprocessor=post_nostat),
+                 draw_command("clustersCharge:clustersTDC>>tdcp(10,0.5,10.5)","clustersSize > 0","prof","Charge v TDC;TDC;<charge> [ADC]",postprocessor=post_tdc_prof),
+ ]
+
+##Should be possible to hook into an external file with TTree::MakeProxy using these commands as well if needed, though it hasn't been tested.
+##If you have other histograms to calculate from available inputs, there are two lists (hlist_pre and hlist_post) in the plotting loop they can be added to;
+##  see where the noise histograms are created.  Pre goes before the ttree command and post afterwards
+############################################################
+
+
+import argparse
+    
+parser = argparse.ArgumentParser(
+    description = "Fast analysis of UT testbeam data for quality monitoring",
+    formatter_class=argparse.ArgumentDefaultsHelpFormatter,)
+parser.add_argument('-b','--board',type=str,required=True,
+                    help="Letter+number combination, e.g. 'A8'")
+parser.add_argument('-p','--pednum',type=int,required=True,
+                    help="Run number of the pedestal run to use (UT run number)")
+parser.add_argument('-r','--runnum',type=int,required=True,
+                    help="Run number to analyze (UT run number); use 0 to analyze pedestal only")
+parser.add_argument('-n','--nevmax',type=int,required=False,default=nevdef,
+                    help="Max number of events to analyze")
+parser.add_argument('-f','--force',required=False,action='store_true',
+                    help="Force overwrite of any output files existing")
+parser.add_argument('-t','--senstype',type=str,required=False,default='PType',
+                    help="Sensor type ('PType' or 'NType')")
+parser.add_argument('-e','--eosmount',type=str,required=False,default=eosmount,
+                    help="Eos mount point")
+parser.add_argument('-i','--indir',type=str,required=False,default=indir,
+                    help='Input data directory path relative to eosmount')
+parser.add_argument('-o','--outdir', type=str, required=False,default=outdir,
+                    help="Output directory for root files and plots")
+args = parser.parse_args()
+
+import sys
+import os
+import subprocess
+
+#make sure I have places for output
+pedestaldir = args.outdir + '/Pedestal-Board{}-{}'.format( args.board, args.pednum )
+monitordir = args.outdir + '/Monitoring-Board{}-{}'.format( args.board, args.runnum )
+def ensuredir(dir):
+    try: 
+        os.makedirs(dir)
+    except OSError:
+        if not os.path.isdir(dir):
+            raise
+ensuredir(pedestaldir)
+if(args.runnum!=0):
+    ensuredir(monitordir)
+
+#Run pedestal if it does not already exist
+didPedestal = False
+if(args.force or not os.path.isfile("{}/Fast-Pedestal-Board{}-{}.dat".format( pedestaldir, args.board, args.pednum ) ) ):
+    
+    print "================================================================"
+    print "==ANALYZE PEDESTAL FOR BOARD {} RUN {}=========================".format( args.board, args.pednum )
+    print "================================================================"
+
+    didPedestal = True
+
+    ##Set up the gaudi config for running the pedestal
+    pedCode = ("import sys\n"
+               "sys.path.append( 'options/python' )\n"
+               "from TbUTPedestalRunner import TbUTPedestalRunner\n"
+               "app=TbUTPedestalRunner()\n"
+               "# set parameter\n"
+               "app.inputData= '{}/{}/Board{}/RawData/Pedestal-B{}-{}-{}-.dat'\n"
+               "app.isAType={}\n"
+               "# have to be more than 4k (~10k)\n"
+               "app.eventMax={}\n"
+               "#  keep the pedestals files in $KEPLERROOT/../TbUT/options/UT/ directory !!!!!\n"
+               "app.pedestalOutputData ='{}/Fast-Pedestal-Board{}-{}.dat'\n"
+               "app.runPedestals()\n").format(args.eosmount,args.indir, args.board, args.board[1:], args.board[:1],args.pednum, (args.board[:1]=='A'), args.nevmax, pedestaldir, args.board,args.pednum)
+
+
+    with open('myTempPedRun.py','w') as ftarget:
+        ftarget.write(pedCode)
+
+    ret = subprocess.call(['gaudirun.py','myTempPedRun.py'])
+
+    os.remove('myTempPedRun.py')
+
+    if(ret!=0):
+        sys.exit("Bad return code from pedestal run")
+
+#Determine if we have a data run to process
+if( args.runnum != 0):
+
+    #find the data file by run number
+    dir_to_search = "{}/{}/Board{}/RawData/".format(args.eosmount,args.indir,args.board)
+    paths = subprocess.check_output("find {} -iname '*-{}-*.dat'".format(dir_to_search,args.runnum), shell=True).splitlines()
+
+    if( len(paths)==0):
+        sys.exit("ERROR: no data file found for run number {}".format(args.runnum))
+    elif( len(paths) > 1):
+        print "WARNING: more than one file matching run number, using",paths[0]
+
+    inpath = paths[0]
+    #These are the output names used by TbUTClusterizator
+    outnames = [ os.path.basename(inpath).replace('.dat','.root'), os.path.basename(inpath).replace('.dat','_Tuple.root') ]
+
+    #Skip running if files exist unless forced
+    if( args.force or not (os.path.isfile(monitordir+'/'+outnames[0]) and os.path.isfile(monitordir+'/'+outnames[1])) ):
+
+        print "================================================================"
+        print "==ANALYZE DATA FOR BOARD {} RUN {}=============================".format( args.board, args.runnum )
+        print "================================================================"
+
+        runCode = ("import sys\n"
+                   "sys.path.append('options/python')\n"
+                   "from TbUTClusterizator import TbUTClusterizator\n"
+                   "app = TbUTClusterizator()\n"
+                   "# set parameters\n"
+                   "app.inputData = '{}'\n"
+                   "app.isAType = {}\n"
+                   "app.sensorType = '{}'\n"
+                   "app.eventMax = {}\n"
+                   "app.pedestalInputData = '{}/Fast-Pedestal-Board{}-{}.dat'\n"
+                   "app.eventNumberDisplay = 1000\n"
+                   "app.runClusterization()\n").format(inpath,(args.board[:1]=='A'),args.senstype,args.nevmax,pedestaldir,args.board,args.pednum)
+
+
+
+        with open('myTempRun.py','w') as ftarget:
+            ftarget.write(runCode)
+
+        #run twice because of noise input issue...
+        ret = subprocess.call(['gaudirun.py','myTempRun.py'])
+        ret = subprocess.call(['gaudirun.py','myTempRun.py'])
+
+        #Move them since currently can't control output location from the run
+        if( monitordir != '.' ):
+            subprocess.call(['mv',outnames[0],monitordir+'/'])
+            subprocess.call(['mv',outnames[1],monitordir+'/'])
+
+        os.remove('myTempRun.py')
+
+        if(ret!=0):
+            sys.exit("Bad return code from analysis run")
+
+
+
+
+########################################################
+##Analysis part
+########################################################
+
+
+print "================================================================"
+print "==PLOT DATA FOR BOARD {} RUN {}================================".format( args.board, args.runnum )
+print "================================================================"
+
+#Define what extensions to save plots with
+def saveall( c, outname ):
+    for ext in '.png', '.pdf', '.C':
+        c.SaveAs(outname+ext)
+
+#setup ROOT
+from ROOT import gROOT, TH1F, TCanvas, TFile, TTree, gStyle, TF1,gDirectory,gPad
+gROOT.SetBatch()
+gROOT.SetStyle("Plain")
+
+#keep track of plots we made to open at the end
+plotlist = []
+
+if( didPedestal ):
+    c = TCanvas()
+    #analyze the pedestal only
+    #dat file is space separated list of pedestals by channel number
+    peds = open("{}/Fast-Pedestal-Board{}-{}.dat".format(pedestaldir,args.board,args.pednum), "r")
+    try:
+        pedvals = [float(p) for p in peds.read().split()]
+    except:
+        sys.exit("Bad pedestal data format")
+    
+    nc = len(pedvals)
+    hped = TH1F("hped","Pedestal v. channel;Channel;Pedestal [ADC]",nc,-0.5, nc-0.5)
+    for i,v in enumerate(pedvals):
+        hped.SetBinContent(i+1, v)
+
+    hped.Draw();
+    saveall(c,"{}/pedestal".format(pedestaldir))
+    plotlist += ["{}/pedestal.png".format(pedestaldir)]
+
+#analyze the run
+if( args.runnum != 0 ):
+    fhists = TFile("{}/{}".format(monitordir,outnames[0]))
+    ftrees = TFile("{}/{}".format(monitordir,outnames[1]))
+
+    t = ftrees.Get("TbUT/Clusters")
+    
+    #make the rough noise plots -- use the range -120 to 120 ADC and ignore most of the signal contribution
+    noise2d = fhists.Get("TbUT/CMSData_vs_channel")
+    noise2d.GetYaxis().SetRangeUser(-120,120)
+    nc = noise2d.GetNbinsX()
+
+    meanNoise = TH1F("meanNoise","Mean noise;Channel;<noise> [ADC]",nc,-0.5,nc-0.5)
+    widthNoise = TH1F("widthNoise","Width noise;Channel;#sigma_{noise} [ADC]",nc,-0.5,nc-0.5)
+    meanNoise.SetStats(False)
+    widthNoise.SetStats(False)
+
+    for b in range(1, nc+1):
+        noise2d.GetXaxis().SetRange(b,b)
+        meanNoise.SetBinContent(b, noise2d.GetMean(2))
+        meanNoise.SetBinError(b, noise2d.GetMeanError(2))
+        widthNoise.SetBinContent(b, noise2d.GetStdDev(2))
+        widthNoise.SetBinError(b, noise2d.GetStdDevError(2))
+
+    #hlist_pre is a list of histograms to draw
+    hlist_pre = [meanNoise,widthNoise]
+    npre = len(hlist_pre)
+
+    #hlist_post, however, is a list of functions that create histograms; define some functions for post-draw histograms first:
+    def fiducialADC( t, fidcut ):
+        print "Use fiducial cut:", fidcut
+        t.Draw("clustersCharge>>fidcharge(200,-1200,0)", fidcut)
+        h = t.GetHistogram()
+        h.SetTitle("Fiducial cluster charge;Tot. charge [ADC];Clusters")
+        return h
+
+    #the output ntuple has empty clusters saved in every event, so always cut those out
+    fidcut = "clustersSize > 0"
+    hlist_post = [fiducialADC]
+    npost = len(hlist_post)
+
+    #create the canvases
+    #keep track of how many plots left to do
+    ntreedraw = len(drawcommands)
+    nplotall = npre + ntreedraw + npost
+
+    #9 plots per canvas max
+    ncanvas = nplotall/9
+    #if not an exact divisor we need an extra one for the leftovers:
+    if( nplotall % 9 != 0 ):
+        ncanvas += 1
+    #how many columns and rows we want for each number of plots per canvas
+    colnums = [1,2,2,2,3,3,3,3,3]
+    rownums = [1,1,2,2,2,2,3,3,3]
+    
+    clist = [TCanvas('c{}'.format(i)) for i in range(ncanvas)]
+    plotidx = 0 #count the plots
+    for c in clist:
+        #how many plots on this canvas?
+        #we'll use nplotall as a countdown
+        if( nplotall >= 9):
+            nplot=9
+            nplotall -= 9
+        else:
+            nplot=nplotall
+    
+        #setup the canvas based on number of plots to draw
+        ncols = colnums[nplot - 1]
+        nrows = rownums[nplot - 1]
+        c.SetCanvasSize( 600*ncols, 300*nrows )
+        c.Divide(ncols,nrows)
+
+        for i in range(nplot):
+            #plotidx is overall iterator, i is current canvas iterator
+            if (plotidx < npre):
+                c.cd(i+1)
+                hlist_pre[plotidx].Draw()
+            elif(plotidx < npre + ntreedraw):
+                c.cd(i+1)
+                t.Draw( drawcommands[plotidx-npre].command, drawcommands[plotidx-npre].cut, drawcommands[plotidx-npre].option )
+                h = t.GetHistogram()
+                gPad.h = h
+                h.SetTitle(drawcommands[plotidx-npre].title)
+                if(drawcommands[plotidx-npre].postprocessor):
+                    newcut = drawcommands[plotidx-npre].postprocessor( gPad, t, h )
+                    if type(newcut) == str:
+                        fidcut += " && " + newcut
+            else:
+                c.cd(i+1)
+                hlist_post[plotidx - npre - ntreedraw](t,fidcut).Draw()
+
+            plotidx+=1
+                
+        plotpath = "{}/monitoring-{}".format( monitordir, c.GetName()[1:] )
+        saveall(c, plotpath)
+        plotlist += ["{}.png".format(plotpath)]
+
+#open up an eye of gnome window to look at the plots; use the next and previous arrows to navigate between them
+if( plotlist ):
+    subprocess.call(["eog",]+plotlist) 
+
diff --git a/TbUT/scripts/langaus.C b/TbUT/scripts/langaus.C
new file mode 100644
index 0000000..88df2ba
--- /dev/null
+++ b/TbUT/scripts/langaus.C
@@ -0,0 +1,282 @@
+//-----------------------------------------------------------------------
+//
+// Convoluted Landau and Gaussian Fitting Function
+//         (using ROOT's Landau and Gauss functions)
+//
+//  Based on a Fortran code by R.Fruehwirth (fruhwirth@hephy.oeaw.ac.at)
+//  Adapted for C++/ROOT by H.Pernegger (Heinz.Pernegger@cern.ch) and
+//   Markus Friedl (Markus.Friedl@cern.ch)
+//
+//  to execute this example, do:
+//  root > .x langaus.C
+// or
+//  root > .x langaus.C++
+//
+//-----------------------------------------------------------------------
+
+#include "TH1.h"
+#include "TF1.h"
+#include "TROOT.h"
+#include "TStyle.h"
+#include "TMath.h"
+#include "TFile.h"
+
+Double_t langaufun(Double_t *x, Double_t *par) {
+
+   //Fit parameters:
+   //par[0]=Width (scale) parameter of Landau density
+   //par[1]=Most Probable (MP, location) parameter of Landau density
+   //par[2]=Total area (integral -inf to inf, normalization constant)
+   //par[3]=Width (sigma) of convoluted Gaussian function
+   //
+   //In the Landau distribution (represented by the CERNLIB approximation),
+   //the maximum is located at x=-0.22278298 with the location parameter=0.
+   //This shift is corrected within this function, so that the actual
+   //maximum is identical to the MP parameter.
+
+      // Numeric constants
+      Double_t invsq2pi = 0.3989422804014;   // (2 pi)^(-1/2)
+      Double_t mpshift  = -0.22278298;       // Landau maximum location
+
+      // Control constants
+      Double_t np = 100.0;      // number of convolution steps
+      Double_t sc =   5.0;      // convolution extends to +-sc Gaussian sigmas
+
+      // Variables
+      Double_t xx;
+      Double_t mpc;
+      Double_t fland;
+      Double_t sum = 0.0;
+      Double_t xlow,xupp;
+      Double_t step;
+      Double_t i;
+
+
+      // MP shift correction
+      mpc = par[1] - mpshift * par[0];
+
+      // Range of convolution integral
+      xlow = x[0] - sc * par[3];
+      xupp = x[0] + sc * par[3];
+
+      step = (xupp-xlow) / np;
+
+      // Convolution integral of Landau and Gaussian by sum
+      for(i=1.0; i<=np/2; i++) {
+         xx = xlow + (i-.5) * step;
+         fland = TMath::Landau(xx,mpc,par[0]) / par[0];
+         sum += fland * TMath::Gaus(x[0],xx,par[3]);
+
+         xx = xupp - (i-.5) * step;
+         fland = TMath::Landau(xx,mpc,par[0]) / par[0];
+         sum += fland * TMath::Gaus(x[0],xx,par[3]);
+      }
+
+      return (par[2] * step * sum * invsq2pi / par[3]);
+}
+
+
+
+TF1 *langaufit(TH1F *his, Double_t *fitrange, Double_t *startvalues, Double_t *parlimitslo, Double_t *parlimitshi, Double_t *fitparams, Double_t *fiterrors, Double_t *ChiSqr, Int_t *NDF)
+{
+   // Once again, here are the Landau * Gaussian parameters:
+   //   par[0]=Width (scale) parameter of Landau density
+   //   par[1]=Most Probable (MP, location) parameter of Landau density
+   //   par[2]=Total area (integral -inf to inf, normalization constant)
+   //   par[3]=Width (sigma) of convoluted Gaussian function
+   //
+   // Variables for langaufit call:
+   //   his             histogram to fit
+   //   fitrange[2]     lo and hi boundaries of fit range
+   //   startvalues[4]  reasonable start values for the fit
+   //   parlimitslo[4]  lower parameter limits
+   //   parlimitshi[4]  upper parameter limits
+   //   fitparams[4]    returns the final fit parameters
+   //   fiterrors[4]    returns the final fit errors
+   //   ChiSqr          returns the chi square
+   //   NDF             returns ndf
+
+   Int_t i;
+   Char_t FunName[100];
+
+   sprintf(FunName,"Fitfcn_%s",his->GetName());
+
+   TF1 *ffitold = (TF1*)gROOT->GetListOfFunctions()->FindObject(FunName);
+   if (ffitold) delete ffitold;
+
+   TF1 *ffit = new TF1(FunName,langaufun,fitrange[0],fitrange[1],4);
+   ffit->SetParameters(startvalues);
+   ffit->SetParNames("Width","MP","Area","GSigma");
+
+   for (i=0; i<4; i++) {
+      ffit->SetParLimits(i, parlimitslo[i], parlimitshi[i]);
+   }
+
+   his->Fit(FunName,"RB0");   // fit within specified range, use ParLimits, do not plot
+
+   ffit->GetParameters(fitparams);    // obtain fit parameters
+   for (i=0; i<4; i++) {
+      fiterrors[i] = ffit->GetParError(i);     // obtain fit parameter errors
+   }
+   ChiSqr[0] = ffit->GetChisquare();  // obtain chi^2
+   NDF[0] = ffit->GetNDF();           // obtain ndf
+
+   return (ffit);              // return fit function
+
+}
+
+
+Int_t langaupro(Double_t *params, Double_t &maxx, Double_t &FWHM) {
+
+   // Seaches for the location (x value) at the maximum of the
+   // Landau-Gaussian convolute and its full width at half-maximum.
+   //
+   // The search is probably not very efficient, but it's a first try.
+
+   Double_t p,x,fy,fxr,fxl;
+   Double_t step;
+   Double_t l,lold;
+   Int_t i = 0;
+   Int_t MAXCALLS = 10000;
+
+
+   // Search for maximum
+
+   p = params[1] - 0.1 * params[0];
+   step = 0.05 * params[0];
+   lold = -2.0;
+   l    = -1.0;
+
+
+   while ( (l != lold) && (i < MAXCALLS) ) {
+      i++;
+
+      lold = l;
+      x = p + step;
+      l = langaufun(&x,params);
+
+      if (l < lold)
+         step = -step/10;
+
+      p += step;
+   }
+
+   if (i == MAXCALLS)
+      return (-1);
+
+   maxx = x;
+
+   fy = l/2;
+
+
+   // Search for right x location of fy
+
+   p = maxx + params[0];
+   step = params[0];
+   lold = -2.0;
+   l    = -1e300;
+   i    = 0;
+
+
+   while ( (l != lold) && (i < MAXCALLS) ) {
+      i++;
+
+      lold = l;
+      x = p + step;
+      l = TMath::Abs(langaufun(&x,params) - fy);
+
+      if (l > lold)
+         step = -step/10;
+
+      p += step;
+   }
+
+   if (i == MAXCALLS)
+      return (-2);
+
+   fxr = x;
+
+
+   // Search for left x location of fy
+
+   p = maxx - 0.5 * params[0];
+   step = -params[0];
+   lold = -2.0;
+   l    = -1e300;
+   i    = 0;
+
+   while ( (l != lold) && (i < MAXCALLS) ) {
+      i++;
+
+      lold = l;
+      x = p + step;
+      l = TMath::Abs(langaufun(&x,params) - fy);
+
+      if (l > lold)
+         step = -step/10;
+
+      p += step;
+   }
+
+   if (i == MAXCALLS)
+      return (-3);
+
+
+   fxl = x;
+
+   FWHM = fxr - fxl;
+   return (0);
+}
+
+void langaus() {
+   // Fill Histogram
+   Int_t data[100] = {0,0,0,0,0,0,2,6,11,18,18,55,90,141,255,323,454,563,681,
+                    737,821,796,832,720,637,558,519,460,357,291,279,241,212,
+                    153,164,139,106,95,91,76,80,80,59,58,51,30,49,23,35,28,23,
+                    22,27,27,24,20,16,17,14,20,12,12,13,10,17,7,6,12,6,12,4,
+                    9,9,10,3,4,5,2,4,1,5,5,1,7,1,6,3,3,3,4,5,4,4,2,2,7,2,4};
+   //   TH1F *hSNR = new TH1F("snr","Signal-to-noise",400,0,400);
+
+   //   for (Int_t i=0; i<100; i++) hSNR->Fill(i,data[i]);
+
+   TFile *test = new TFile("/afs/cern.ch/user/c/cbetanco/work/LHCb/KeplerDev_v3r0/Tb/TbUT/plots/AnalysisOutput_A6_50_3.root","open");
+
+   TH1F *hSNR = test->Get("hcTrk")->Clone();
+   //hSNR->Rebin(3);
+
+   // Fitting SNR histo
+   printf("Fitting...\n");
+
+   // Setting fit range and start values
+   Double_t fr[2];
+   Double_t sv[4], pllo[4], plhi[4], fp[4], fpe[4];
+    fr[0]=0.5*hSNR->GetMean();
+   fr[1]=3.0*hSNR->GetMean();
+
+   //fr[0]=130;
+   //fr[1]=500;
+
+   pllo[0]=0.5; pllo[1]=5.0; pllo[2]=1.0; pllo[3]=0.4;
+   plhi[0]=50.0; plhi[1]=500.0; plhi[2]=1000000.0; plhi[3]=5.0;
+   sv[0]=1.8; sv[1]=200.0; sv[2]=50000.0; sv[3]=3.0;
+
+   Double_t chisqr;
+   Int_t    ndf;
+   TF1 *fitsnr = langaufit(hSNR,fr,sv,pllo,plhi,fp,fpe,&chisqr,&ndf);
+
+   Double_t SNRPeak, SNRFWHM;
+   langaupro(fp,SNRPeak,SNRFWHM);
+
+   printf("Fitting done\nPlotting results...\n");
+
+   // Global style settings
+   gStyle->SetOptStat(1111);
+   gStyle->SetOptFit(111);
+   gStyle->SetLabelSize(0.03,"x");
+   gStyle->SetLabelSize(0.03,"y");
+
+   hSNR->GetXaxis()->SetRange(0,70);
+   hSNR->Draw();
+   fitsnr->Draw("lsame");
+}
+
diff --git a/TbUT/scripts/langaus.C~ b/TbUT/scripts/langaus.C~
new file mode 100644
index 0000000..990b0dd
--- /dev/null
+++ b/TbUT/scripts/langaus.C~
@@ -0,0 +1,273 @@
+//-----------------------------------------------------------------------
+//
+// Convoluted Landau and Gaussian Fitting Function
+//         (using ROOT's Landau and Gauss functions)
+//
+//  Based on a Fortran code by R.Fruehwirth (fruhwirth@hephy.oeaw.ac.at)
+//  Adapted for C++/ROOT by H.Pernegger (Heinz.Pernegger@cern.ch) and
+//   Markus Friedl (Markus.Friedl@cern.ch)
+//
+//  to execute this example, do:
+//  root > .x langaus.C
+// or
+//  root > .x langaus.C++
+//
+//-----------------------------------------------------------------------
+
+#include "TH1.h"
+#include "TF1.h"
+#include "TROOT.h"
+#include "TStyle.h"
+#include "TMath.h"
+
+Double_t langaufun(Double_t *x, Double_t *par) {
+
+   //Fit parameters:
+   //par[0]=Width (scale) parameter of Landau density
+   //par[1]=Most Probable (MP, location) parameter of Landau density
+   //par[2]=Total area (integral -inf to inf, normalization constant)
+   //par[3]=Width (sigma) of convoluted Gaussian function
+   //
+   //In the Landau distribution (represented by the CERNLIB approximation),
+   //the maximum is located at x=-0.22278298 with the location parameter=0.
+   //This shift is corrected within this function, so that the actual
+   //maximum is identical to the MP parameter.
+
+      // Numeric constants
+      Double_t invsq2pi = 0.3989422804014;   // (2 pi)^(-1/2)
+      Double_t mpshift  = -0.22278298;       // Landau maximum location
+
+      // Control constants
+      Double_t np = 100.0;      // number of convolution steps
+      Double_t sc =   5.0;      // convolution extends to +-sc Gaussian sigmas
+
+      // Variables
+      Double_t xx;
+      Double_t mpc;
+      Double_t fland;
+      Double_t sum = 0.0;
+      Double_t xlow,xupp;
+      Double_t step;
+      Double_t i;
+
+
+      // MP shift correction
+      mpc = par[1] - mpshift * par[0];
+
+      // Range of convolution integral
+      xlow = x[0] - sc * par[3];
+      xupp = x[0] + sc * par[3];
+
+      step = (xupp-xlow) / np;
+
+      // Convolution integral of Landau and Gaussian by sum
+      for(i=1.0; i<=np/2; i++) {
+         xx = xlow + (i-.5) * step;
+         fland = TMath::Landau(xx,mpc,par[0]) / par[0];
+         sum += fland * TMath::Gaus(x[0],xx,par[3]);
+
+         xx = xupp - (i-.5) * step;
+         fland = TMath::Landau(xx,mpc,par[0]) / par[0];
+         sum += fland * TMath::Gaus(x[0],xx,par[3]);
+      }
+
+      return (par[2] * step * sum * invsq2pi / par[3]);
+}
+
+
+
+TF1 *langaufit(TH1F *his, Double_t *fitrange, Double_t *startvalues, Double_t *parlimitslo, Double_t *parlimitshi, Double_t *fitparams, Double_t *fiterrors, Double_t *ChiSqr, Int_t *NDF)
+{
+   // Once again, here are the Landau * Gaussian parameters:
+   //   par[0]=Width (scale) parameter of Landau density
+   //   par[1]=Most Probable (MP, location) parameter of Landau density
+   //   par[2]=Total area (integral -inf to inf, normalization constant)
+   //   par[3]=Width (sigma) of convoluted Gaussian function
+   //
+   // Variables for langaufit call:
+   //   his             histogram to fit
+   //   fitrange[2]     lo and hi boundaries of fit range
+   //   startvalues[4]  reasonable start values for the fit
+   //   parlimitslo[4]  lower parameter limits
+   //   parlimitshi[4]  upper parameter limits
+   //   fitparams[4]    returns the final fit parameters
+   //   fiterrors[4]    returns the final fit errors
+   //   ChiSqr          returns the chi square
+   //   NDF             returns ndf
+
+   Int_t i;
+   Char_t FunName[100];
+
+   sprintf(FunName,"Fitfcn_%s",his->GetName());
+
+   TF1 *ffitold = (TF1*)gROOT->GetListOfFunctions()->FindObject(FunName);
+   if (ffitold) delete ffitold;
+
+   TF1 *ffit = new TF1(FunName,langaufun,fitrange[0],fitrange[1],4);
+   ffit->SetParameters(startvalues);
+   ffit->SetParNames("Width","MP","Area","GSigma");
+
+   for (i=0; i<4; i++) {
+      ffit->SetParLimits(i, parlimitslo[i], parlimitshi[i]);
+   }
+
+   his->Fit(FunName,"RB0");   // fit within specified range, use ParLimits, do not plot
+
+   ffit->GetParameters(fitparams);    // obtain fit parameters
+   for (i=0; i<4; i++) {
+      fiterrors[i] = ffit->GetParError(i);     // obtain fit parameter errors
+   }
+   ChiSqr[0] = ffit->GetChisquare();  // obtain chi^2
+   NDF[0] = ffit->GetNDF();           // obtain ndf
+
+   return (ffit);              // return fit function
+
+}
+
+
+Int_t langaupro(Double_t *params, Double_t &maxx, Double_t &FWHM) {
+
+   // Seaches for the location (x value) at the maximum of the
+   // Landau-Gaussian convolute and its full width at half-maximum.
+   //
+   // The search is probably not very efficient, but it's a first try.
+
+   Double_t p,x,fy,fxr,fxl;
+   Double_t step;
+   Double_t l,lold;
+   Int_t i = 0;
+   Int_t MAXCALLS = 10000;
+
+
+   // Search for maximum
+
+   p = params[1] - 0.1 * params[0];
+   step = 0.05 * params[0];
+   lold = -2.0;
+   l    = -1.0;
+
+
+   while ( (l != lold) && (i < MAXCALLS) ) {
+      i++;
+
+      lold = l;
+      x = p + step;
+      l = langaufun(&x,params);
+
+      if (l < lold)
+         step = -step/10;
+
+      p += step;
+   }
+
+   if (i == MAXCALLS)
+      return (-1);
+
+   maxx = x;
+
+   fy = l/2;
+
+
+   // Search for right x location of fy
+
+   p = maxx + params[0];
+   step = params[0];
+   lold = -2.0;
+   l    = -1e300;
+   i    = 0;
+
+
+   while ( (l != lold) && (i < MAXCALLS) ) {
+      i++;
+
+      lold = l;
+      x = p + step;
+      l = TMath::Abs(langaufun(&x,params) - fy);
+
+      if (l > lold)
+         step = -step/10;
+
+      p += step;
+   }
+
+   if (i == MAXCALLS)
+      return (-2);
+
+   fxr = x;
+
+
+   // Search for left x location of fy
+
+   p = maxx - 0.5 * params[0];
+   step = -params[0];
+   lold = -2.0;
+   l    = -1e300;
+   i    = 0;
+
+   while ( (l != lold) && (i < MAXCALLS) ) {
+      i++;
+
+      lold = l;
+      x = p + step;
+      l = TMath::Abs(langaufun(&x,params) - fy);
+
+      if (l > lold)
+         step = -step/10;
+
+      p += step;
+   }
+
+   if (i == MAXCALLS)
+      return (-3);
+
+
+   fxl = x;
+
+   FWHM = fxr - fxl;
+   return (0);
+}
+
+void langaus() {
+   // Fill Histogram
+   Int_t data[100] = {0,0,0,0,0,0,2,6,11,18,18,55,90,141,255,323,454,563,681,
+                    737,821,796,832,720,637,558,519,460,357,291,279,241,212,
+                    153,164,139,106,95,91,76,80,80,59,58,51,30,49,23,35,28,23,
+                    22,27,27,24,20,16,17,14,20,12,12,13,10,17,7,6,12,6,12,4,
+                    9,9,10,3,4,5,2,4,1,5,5,1,7,1,6,3,3,3,4,5,4,4,2,2,7,2,4};
+   TH1F *hSNR = new TH1F("snr","Signal-to-noise",400,0,400);
+
+   for (Int_t i=0; i<100; i++) hSNR->Fill(i,data[i]);
+
+   // Fitting SNR histo
+   printf("Fitting...\n");
+
+   // Setting fit range and start values
+   Double_t fr[2];
+   Double_t sv[4], pllo[4], plhi[4], fp[4], fpe[4];
+   fr[0]=0.3*hSNR->GetMean();
+   fr[1]=3.0*hSNR->GetMean();
+
+   pllo[0]=0.5; pllo[1]=5.0; pllo[2]=1.0; pllo[3]=0.4;
+   plhi[0]=5.0; plhi[1]=50.0; plhi[2]=1000000.0; plhi[3]=5.0;
+   sv[0]=1.8; sv[1]=20.0; sv[2]=50000.0; sv[3]=3.0;
+
+   Double_t chisqr;
+   Int_t    ndf;
+   TF1 *fitsnr = langaufit(hSNR,fr,sv,pllo,plhi,fp,fpe,&chisqr,&ndf);
+
+   Double_t SNRPeak, SNRFWHM;
+   langaupro(fp,SNRPeak,SNRFWHM);
+
+   printf("Fitting done\nPlotting results...\n");
+
+   // Global style settings
+   gStyle->SetOptStat(1111);
+   gStyle->SetOptFit(111);
+   gStyle->SetLabelSize(0.03,"x");
+   gStyle->SetLabelSize(0.03,"y");
+
+   hSNR->GetXaxis()->SetRange(0,70);
+   hSNR->Draw();
+   fitsnr->Draw("lsame");
+}
+
diff --git a/TbUT/scripts/plotADCs.C b/TbUT/scripts/plotADCs.C
new file mode 100644
index 0000000..d7c008e
--- /dev/null
+++ b/TbUT/scripts/plotADCs.C
@@ -0,0 +1,309 @@
+///////////////////////////////////////////////////
+//
+// Macro: plotADCs.C
+// Author: S. Blusk
+// Date: Oct 19, 2015
+//
+// Purpose: To loop over events and look at the CMS ADC distribution vs channel number
+// Can also be run on selected events, liste in a file: "MissingDUTHits.dat", which can
+// be obtained by running ClusterAnaWithTrack
+// with the flag 
+//      writeEventsWithMissinhHitsToFile = true
+//
+// Note: The cursor needs to be on the event display window to advance to the next event.
+// Hit ENTER to go to next event.
+//
+///////////////////////////////////////////////////
+
+bool plotSelectedEvents = true;
+bool showEventDisplay = true;
+
+bool fillStatDistribution = true;  // Fill summary histogram
+
+int lowCh = 127; // Low Channel number of ADC distribution
+int hiCh = 256;  // High Channel number of ADC distribution
+
+int evList[20000];
+double nomStrip[20000];
+double xtrk[20000];
+double ytrk[20000];
+// Various arrays of parameters common to this macro
+double tdcTime = 0;
+double adcs[512] = {0};
+double finalSignal[512] = {0};
+
+int NCluster = 0;
+float ClusterCharge[100] = {0};
+int ClusterSize[100] ={0};
+float ClusterPosY[100] ={0};
+float seedChannel[100] ={0};
+
+int iOffSet = 0;               // Offset into tree, to get to specific events
+int printEventDisplays = 0;   // Number of event displays to print to file
+float polarity = -1.0;
+
+
+/////////////////////////////////////////////////////////////////////////////////
+
+void plotADCs(){
+  gStyle->SetNdivisions(505,"Y");
+  gStyle->SetNdivisions(505,"X");
+  gStyle->SetOptStat(0);
+  gStyle->SetOptFit(1);
+  gStyle->SetPadTickX(1);
+  gStyle->SetPadTickY(1);
+
+  //TString sigFile = getFileToOpen(runNum);
+  TString sigFile = "/data2/sblusk/TB/July2015/AnaFiles/BoardA6/Run_Bias_Scan-B6-A-212-8358_Tuple.root";
+
+  
+  // Open signal file
+  TFile *fs = new TFile(sigFile);  
+  TTree* cmstree = (TTree*)fs->Get("TbUT/CMS");
+  TTree* fChain = (TTree*)fs->Get("TbUT/Clusters");
+  int nevents = cmstree->GetEntriesFast();
+
+  // Strip level data
+  Double_t        cmsData[512];
+  // List of branches
+  TBranch        *b_cmsData;   //!
+  cmstree->SetBranchAddress("cmsData", cmsData, &b_cmsData);
+
+  // Clusters
+  // Declaration of leaf types
+  Int_t           clusterNumberPerEvent;
+  UInt_t          clustersTDC;
+  ULong64_t       timestamps;
+  Double_t        clustersPosition[10];
+  Int_t           clustersSeedPosition[10];
+  Double_t        clustersCharge[10];
+  Int_t           clustersSize[10];
+  Double_t        clustersSeedCharge[10];
+  Double_t        clustersCharge2StripLeft[10];
+  Double_t        clustersCharge1StripLeft[10];
+  Double_t        clustersCharge1StripRight[10];
+  Double_t        clustersCharge2StripRight[10];
+  
+  TBranch        *b_clusterNumberPerEvent;   //!
+  TBranch        *b_clustersTDC;   //!
+  TBranch        *b_timestamps;   //!
+  TBranch        *b_clustersPosition;   //!
+  TBranch        *b_clustersSeedPosition;   //!
+  TBranch        *b_clustersCharge;   //!
+  TBranch        *b_clustersSize;   //!
+  TBranch        *b_clustersSeedCharge;   //!
+  TBranch        *b_clustersCharge2StripLeft;   //!
+  TBranch        *b_clustersCharge1StripLeft;   //!
+  TBranch        *b_clustersCharge1StripRight;   //!
+  TBranch        *b_clustersCharge2StripRight;   //!
+  
+  fChain->SetBranchAddress("clusterNumberPerEvent", &clusterNumberPerEvent, &b_clusterNumberPerEvent);
+  fChain->SetBranchAddress("clustersTDC", &clustersTDC, &b_clustersTDC);
+  fChain->SetBranchAddress("timestamps", &timestamps, &b_timestamps);
+  fChain->SetBranchAddress("clustersPosition", clustersPosition, &b_clustersPosition);
+  fChain->SetBranchAddress("clustersSeedPosition", clustersSeedPosition, &b_clustersSeedPosition);
+  fChain->SetBranchAddress("clustersCharge", clustersCharge, &b_clustersCharge);
+  fChain->SetBranchAddress("clustersSize", clustersSize, &b_clustersSize);
+  fChain->SetBranchAddress("clustersSeedCharge", clustersSeedCharge, &b_clustersSeedCharge);
+  fChain->SetBranchAddress("clustersCharge2StripLeft", clustersCharge2StripLeft, &b_clustersCharge2StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripLeft", clustersCharge1StripLeft, &b_clustersCharge1StripLeft);
+  fChain->SetBranchAddress("clustersCharge1StripRight", clustersCharge1StripRight, &b_clustersCharge1StripRight);
+  fChain->SetBranchAddress("clustersCharge2StripRight", clustersCharge2StripRight, &b_clustersCharge2StripRight);
+  
+  TH1F *h = new TH1F("h","ADC, CM + Step Subtracted",512,0.0,512);  
+  TH1F *hm1 = new TH1F("hm1","ADC of nomStrip",110,-100.0,1000);  
+  TH1F *hm = new TH1F("hm","ADC of nomStrip#pm1",110,-100.0,1000);
+  h->SetTitle("");
+  h->SetNdivisions(510,"X");
+
+  TCanvas *theCanvas;
+  int nPrint = 0;
+  
+  char input;
+  int nEvents;
+  
+  int jentry;
+  double strip, xp, yp;
+
+  std::ifstream infile;
+  if(plotSelectedEvents){
+    // Read in event list
+    TString filename = "MissingDUTHits.dat";
+    cout << "------------------------------------------------------------" << endl;
+    cout << " You've selected to view events from file: " << filename << endl;
+    cout << "------------------------------------------------------------" << endl;    
+    infile.open(filename);
+    if(!infile) { // file couldn't be opened
+      cerr << "Error: file could not be opened" << endl;
+      exit(1);
+    }
+    int il = 0;   
+    while ( !infile.eof() ) { // keep reading until end-of-file
+      infile >> jentry >> strip >> xp >> yp;
+     if(il>9999) break;
+     evList[il] = jentry;
+     nomStrip[il] = strip;
+     xtrk[il] = xp;
+     ytrk[il] = yp;
+     il++;     
+   }
+   infile.close();
+   nEvents = nevents - 1000;
+  }else{
+    cout << "How many events do you want to look at ?" << endl;
+    cin >> nEvents;
+    cout << "--------------------------------------"<<endl;
+  }
+
+  //------------------------  
+  // Begin Loop over events
+  //------------------------
+  il = 0;
+  for(int i=iOffSet; i<iOffSet+nEvents; i++){
+    //if(i%1==0) cout << "Processing Event " << i << endl;
+    if(plotSelectedEvents){
+      if(i != evList[il]) continue;
+      //if(showEventDisplay){
+      //  cout << "-------------------------------------------------------------------------------"<<endl;
+      //  cout << "Found selected event: " << i << ", NomStrip of Missing Hit = " << nomStrip[il] << endl;
+      //  cout << "-------------------------------------------------------------------------------"<<endl;
+      //} 
+    }
+
+    cmstree->GetEntry(i);
+    fChain->GetEntry(i);
+    int k=0;
+
+    //--------------
+    // Get CMS data
+    //--------------
+    for(int j=0; j<512;j++){
+      adcs[j] = cmsData[j];
+    }
+
+    //------------------
+    // Get Cluster data
+    //------------------
+    NCluster = clusterNumberPerEvent;
+    if(NCluster>=10) NCluster=10;
+    if(showEventDisplay) cout << "# Clusters = " << NCluster << endl;
+    for(int j=0; j<NCluster; j++){
+      ClusterSize[j] = clustersSize[j];
+      ClusterPosY[j] = 1.0*clustersPosition[j];
+      ClusterCharge[j] = clustersCharge[j];
+      tdcTime = clustersTDC;
+    }
+
+
+    //-------------------------
+    // Get signal distributions
+    //-------------------------
+    getSignal();      
+
+    int nstrip = 0;
+    double vstrip1 = 0, vstrip3 = 0;
+    if(plotSelectedEvents){
+      nstrip = nomStrip[il]+0.5;
+      vstrip1 = finalSignal[nstrip];
+      if(nstrip>1) vstrip3 = vstrip1 + finalSignal[nstrip-1];
+      if(nstrip<511) vstrip3 = vstrip3 + finalSignal[nstrip+1];
+      vstrip1 = -1.0*vstrip1;
+      vstrip3 = -1.0*vstrip3;
+      
+    }
+    
+    //------------------------------------------------------------
+    // Single Event displays of pedestal & noise subtracted data -
+    //------------------------------------------------------------
+    if(showEventDisplay){
+      theCanvas = plotSingleEvent(i, h, nomStrip[il]);  
+      cout << "NomStrip = " << nstrip << " .... Charge in nomStrip and nomStrip +- 1: " << vstrip1 << "  " << vstrip3 << endl;
+      printf("\n <<< ENTER / RETURN to continue >>> \n");
+      theCanvas->WaitPrimitive();
+      if(nPrint < printEventDisplays){
+        theCanvas->Print(Form("./Plots/EventDisplayCorr_%d.png",i));
+        theCanvas->Print(Form("./Plots/EventDisplayCorr_%d.pdf",i)); 
+        nPrint++;
+      }
+    }
+    
+    //----------------
+    // Fill histograms
+    //----------------
+    if(fillStatDistribution && plotSelectedEvents){
+      hm1->Fill(-1.0*vstrip1);
+      hm->Fill(-1.0*vstrip3);
+    }
+    
+    if(plotSelectedEvents) il++;    
+  }
+
+  
+  // Plot statistical distributions
+  TCanvas *c = new TCanvas("c","Plots",500,800);
+  c->Divide(1,2);
+  c->cd(1);  
+  hm1->Draw();
+  c->cd(2);  
+  hm->Draw();
+}
+
+void getSignal(){
+  // -----------------
+  // -  Final result -
+  //    - Here, one could make any "corrections", or flip polarity, etc
+  // -----------------
+  for(int k=0;k<256;k++){finalSignal[k] = adcs[k];}  
+  return;
+}
+
+
+TCanvas* plotSingleEvent(int i, TH1F *h, double xstrip)
+{
+  //-----------------
+  // Final result
+  //-----------------
+  double low = 1000;
+  double hi = -1000;
+
+  h->Reset();  
+  for(int k=0;k<512;k++) {
+    h->Fill(k,finalSignal[k]);
+    if(finalSignal[k]<low) low = finalSignal[k];
+    if(finalSignal[k]>hi) hi = finalSignal[k];
+  }
+  
+  h->SetMinimum(low-100);
+  h->SetMaximum(hi+300);
+  h->GetXaxis()->SetRangeUser(lowCh,hiCh);
+
+  TCanvas *c = new TCanvas("c","",500,0,800,800);
+  h->Draw();
+  TLine *l = new TLine(lowCh, 0, hiCh, 0);
+  TLine *l2 = new TLine(xstrip, low-100, xstrip, hi+150);
+  l2->SetLineColor(5);   l2->SetLineWidth(4); l2->Draw();
+  l->SetLineColor(3); l->SetLineStyle(2); l->SetLineWidth(2); l->Draw();  
+  h->Draw("same");
+  
+
+  TLatex *myLatex = new TLatex();
+  myLatex->SetTextFont(42); myLatex->SetTextColor(1); 
+  myLatex->SetTextAlign(12); myLatex->SetNDC(kTRUE); myLatex->SetTextSize(0.065);
+  myLatex->DrawLatex(0.14,0.85,Form("Event %d",i));
+  TString tdcs = Form("TDC time = %4.1f ns",tdcTime);
+  myLatex->SetTextSize(0.045);myLatex->DrawLatex(0.18,0.79,tdcs);  
+
+
+  float yval = 0.79;
+  myLatex->SetTextSize(0.035);
+  yval = yval - 0.05;
+  for(int k=0;k<NCluster;k++){
+    TString clString = Form("Size=%d,  Q=%3.0f,  Pos=%4.1f",ClusterSize[k],ClusterCharge[k],ClusterPosY[k]);
+    myLatex->DrawLatex(0.14,yval,clString);  
+    yval = yval - 0.05;
+  }
+
+  return c;
+}
+
+
diff --git a/TbUT/scripts/runClusterAna.C b/TbUT/scripts/runClusterAna.C
new file mode 100644
index 0000000..393ae4a
--- /dev/null
+++ b/TbUT/scripts/runClusterAna.C
@@ -0,0 +1,9 @@
+void runClusterAna(int bias = 50){
+
+  gROOT->ProcessLine(".L AnalysisBaseCluOnly.C+");
+  gROOT->ProcessLine(".L ClusterAna.C+");
+  
+  TTree *t;
+  ClusterAna a(bias);
+  a.Loop();
+}
diff --git a/TbUT/scripts/runClusterAnaLoop.C b/TbUT/scripts/runClusterAnaLoop.C
new file mode 100644
index 0000000..86f3edd
--- /dev/null
+++ b/TbUT/scripts/runClusterAnaLoop.C
@@ -0,0 +1,44 @@
+void runClusterAnaLoop(TString board = "A1", int iSector = 1){
+
+  if(board=="A8"){
+    const int nBias = 9;  
+    int bias[nBias] = {400, 350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board=="D5"){
+    const int nBias = 10;  
+    int bias[nBias] = {500, 400, 350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board=="A2"){
+    const int nBias = 9;  
+    int bias[nBias] = {340, 325, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board=="A1"){
+    const int nBias = 8;  
+    int bias[nBias] = {350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board.Contains("D7")){
+    const int nBias = 8;  
+    int bias[nBias] = {500, 400, 300, 200, 150, 100, 75, 50};
+  }else if(board.Contains("A4")){
+    const int nBias = 9;  
+    int bias[nBias] = {400, 350, 300, 250, 200, 150, 100, 75, 50};
+  }else if(board.Contains("A6")){
+    const int nBias = 7;  
+    int bias[nBias] = {300, 250, 200, 150, 100, 75, 50};
+  }
+
+  gROOT->ProcessLine(".L AnalysisBaseCluOnly.C+");
+  gROOT->ProcessLine(".L ClusterAna.C+");
+
+  TTree *t;
+
+  for(int i=0; i<nBias;i++) {
+    int b = bias[i];
+    cout << "+++++++++++++++++++++++++++++++++++++++" << endl;
+    cout << "Processing Bias = " << b << "V " << endl;
+    cout << "+++++++++++++++++++++++++++++++++++++++" << endl;    
+    if(board=="D7" && iSector == 1 && b == 300) continue;
+    
+    
+    ClusterAna a(b);  
+    a.Loop();
+
+  }
+}  
+
diff --git a/TbUT/scripts/runClusterDUT.C b/TbUT/scripts/runClusterDUT.C
new file mode 100644
index 0000000..4e24e13
--- /dev/null
+++ b/TbUT/scripts/runClusterDUT.C
@@ -0,0 +1,24 @@
+#include <stdlib.h> 
+#include "AnalysisBase_Inputs.h"
+
+void runClusterDUT(){
+
+    int bias = atoi(m_bias);
+  
+  gROOT->ProcessLine(".L CMS.C+");
+  gROOT->ProcessLine(".L AnalysisBase.C+");
+  gROOT->ProcessLine(".L ClusterAna.C+");
+  //  gROOT->ProcessLine(".L ClusterTrackAnalysis.C+");
+  //  int bias = atoi(m_bias);
+  //int bias = 300;
+  //    ClusterWithTrackAna a;
+  //a.Loop();
+  
+  //  TTree *t;
+   ClusterWithTrackAna a(bias);
+  //  ClusterTrackAnalysis a(bias);
+  //AnalysisBase a(bias);
+  a.Loop();
+
+
+}
diff --git a/TbUT/scripts/runClusterDUT.C~ b/TbUT/scripts/runClusterDUT.C~
new file mode 100644
index 0000000..705c34a
--- /dev/null
+++ b/TbUT/scripts/runClusterDUT.C~
@@ -0,0 +1,24 @@
+#include <stdlib.h> 
+#include "AnalysisBase_Inputs.h"
+
+void runClusterWithTrackAna(){
+
+    int bias = atoi(m_bias);
+  
+  gROOT->ProcessLine(".L CMS.C+");
+  gROOT->ProcessLine(".L AnalysisBase.C+");
+  gROOT->ProcessLine(".L ClusterWithTrackAna.C+");
+  //  gROOT->ProcessLine(".L ClusterTrackAnalysis.C+");
+  //  int bias = atoi(m_bias);
+  //int bias = 300;
+  //    ClusterWithTrackAna a;
+  //a.Loop();
+  
+  //  TTree *t;
+   ClusterWithTrackAna a(bias);
+  //  ClusterTrackAnalysis a(bias);
+  //AnalysisBase a(bias);
+  a.Loop();
+
+
+}
diff --git a/TbUT/scripts/runClusterWithTrackAna.C b/TbUT/scripts/runClusterWithTrackAna.C
new file mode 100644
index 0000000..d39bc22
--- /dev/null
+++ b/TbUT/scripts/runClusterWithTrackAna.C
@@ -0,0 +1,24 @@
+#include <stdlib.h> 
+#include "AnalysisBase_Inputs.h"
+
+void runClusterWithTrackAna(){
+
+    int bias = atoi(m_bias);
+  
+  gROOT->ProcessLine(".L ../Tb/TbUT/scripts/CMS.C+");
+  gROOT->ProcessLine(".L ../Tb/TbUT/scripts/AnalysisBase.C+");
+  gROOT->ProcessLine(".L ../Tb/TbUT/scripts/ClusterWithTrackAna.C+");
+  //  gROOT->ProcessLine(".L ClusterTrackAnalysis.C+");
+  //  int bias = atoi(m_bias);
+  //int bias = 300;
+  //    ClusterWithTrackAna a;
+  //a.Loop();
+  
+  //  TTree *t;
+   ClusterWithTrackAna a(bias);
+  //  ClusterTrackAnalysis a(bias);
+  //AnalysisBase a(bias);
+  a.Loop();
+
+
+}
diff --git a/TbUT/scripts/runExampleAnalysis.C b/TbUT/scripts/runExampleAnalysis.C
new file mode 100644
index 0000000..050d818
--- /dev/null
+++ b/TbUT/scripts/runExampleAnalysis.C
@@ -0,0 +1,16 @@
+{
+  //-------------------------
+  // To execute:
+  // SetupProject LHCb v36r2
+  // root[]: .x runExampleAnalysis.C
+  //
+  //-------------------------
+
+  gROOT->ProcessLine(".L CMS.C+");
+  gROOT->ProcessLine(".L AnalysisBase.C+");
+  gROOT->ProcessLine(".L ExampleAnalysis.C+");
+
+  //  ExampleAnalysis a;
+  //a.Loop();
+
+}
diff --git a/TbUT/scripts/testing.root b/TbUT/scripts/testing.root
new file mode 100644
index 0000000..7e792ab
--- /dev/null
+++ b/TbUT/scripts/testing.root
Binary files differ
diff --git a/TbUT/scripts/trk_x.pdf b/TbUT/scripts/trk_x.pdf
new file mode 100644
index 0000000..e722a90
--- /dev/null
+++ b/TbUT/scripts/trk_x.pdf
Binary files differ
diff --git a/TbUT/src/.svn/all-wcprops b/TbUT/src/.svn/all-wcprops
new file mode 100644
index 0000000..49d350d
--- /dev/null
+++ b/TbUT/src/.svn/all-wcprops
@@ -0,0 +1,533 @@
+K 25
+svn:wc:ra_dav:version-url
+V 52
+/guest/lhcb/!svn/ver/198103/Kepler/trunk/Tb/TbUT/src
+END
+TbUTMambaDataReader.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/198103/Kepler/trunk/Tb/TbUT/src/TbUTMambaDataReader.h
+END
+TbUTRawDataMonitorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/187186/Kepler/trunk/Tb/TbUT/src/TbUTRawDataMonitorAlgorithm.cpp
+END
+TbUTCommonModeSubtractorFactory.h
+K 25
+svn:wc:ra_dav:version-url
+V 86
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCommonModeSubtractorFactory.h
+END
+Doxyfile
+K 25
+svn:wc:ra_dav:version-url
+V 61
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/Doxyfile
+END
+TbUTClusterCreator.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreator.h
+END
+TbUTIDataReader.h
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTIDataReader.h
+END
+TbUTClusterCreatorDataMonitorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 95
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.cpp
+END
+TbUTNoise.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNoise.cpp
+END
+TbUTIChannelMaskProvider.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTIChannelMaskProvider.h
+END
+TbUTClusterCreatorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreatorAlgorithm.h
+END
+TbUTSensor.h
+K 25
+svn:wc:ra_dav:version-url
+V 65
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/src/TbUTSensor.h
+END
+TbUTNoiseCalculatorfactory.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTNoiseCalculatorfactory.cpp
+END
+TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 101
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
+END
+TbUTPedestalCalculator.h
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalCalculator.h
+END
+TbUTNoiseCalculatorFake.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNoiseCalculatorFake.h
+END
+TbUTPedestalSubtractorDataMonitorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 99
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp
+END
+TbUTRawData.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRawData.cpp
+END
+TbUTAlibavaDataRetreiver.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTAlibavaDataRetreiver.h
+END
+TbUTCluster.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/195966/Kepler/trunk/Tb/TbUT/src/TbUTCluster.h
+END
+TbUTDataMonitorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTDataMonitorAlgorithm.cpp
+END
+TbUTPedestalRetreiver.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalRetreiver.cpp
+END
+TbUTMambaDataReader.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTMambaDataReader.cpp
+END
+TbUTCommonModeSubtractorFactory.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCommonModeSubtractorFactory.cpp
+END
+TbUTChannelMaskProvider.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTChannelMaskProvider.cpp
+END
+TbUTIPedestalFollowing.h
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTIPedestalFollowing.h
+END
+TbUTPedestal.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestal.cpp
+END
+TbUTPedestalFileValidator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTPedestalFileValidator.cpp
+END
+TbUTClusterCreatorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreatorAlgorithm.cpp
+END
+TbUTRawDataFactory.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRawDataFactory.cpp
+END
+TbUTNoiseCalculatorFake.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNoiseCalculatorFake.cpp
+END
+TbUTIClusterCreator.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTIClusterCreator.h
+END
+TbUTCmsPerBeetle.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCmsPerBeetle.h
+END
+TbUTAlibavaDataReader.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTAlibavaDataReader.h
+END
+TbUTNoise.h
+K 25
+svn:wc:ra_dav:version-url
+V 64
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNoise.h
+END
+TbUTNoiseCalculatorfactory.h
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTNoiseCalculatorfactory.h
+END
+TbUTICommonModeSubtractor.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTICommonModeSubtractor.h
+END
+TbUTCommonModeSubtractorDataMonitorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 99
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.h
+END
+TbUTPedestalSubtractorDataMonitorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 97
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.h
+END
+TbUTRawData.h
+K 25
+svn:wc:ra_dav:version-url
+V 66
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRawData.h
+END
+TbUTClusterCreatorFactory.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/197306/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreatorFactory.cpp
+END
+TbUTPedestalRetreiver.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalRetreiver.h
+END
+TbUTChannelMaskFileValidator.h
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTChannelMaskFileValidator.h
+END
+TbUTTresholdProvider.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/194351/Kepler/trunk/Tb/TbUT/src/TbUTTresholdProvider.cpp
+END
+TbUTCMSIterativelyPerBeetle.h
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCMSIterativelyPerBeetle.h
+END
+TbUTChannelMaskProvider.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTChannelMaskProvider.h
+END
+TbUTINoiseCalculator.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTINoiseCalculator.h
+END
+TbUTPedestal.h
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestal.h
+END
+TbUTCmsPerBeetle.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCmsPerBeetle.cpp
+END
+TbUTPedestalFileValidator.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTPedestalFileValidator.h
+END
+TbUTAlibavaDataReader.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTAlibavaDataReader.cpp
+END
+TbUTITresholdProvider.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/194351/Kepler/trunk/Tb/TbUT/src/TbUTITresholdProvider.h
+END
+TbUTCMSLinear.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCMSLinear.cpp
+END
+TbUTCommonModeSubtractorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 90
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCommonModeSubtractorAlgorithm.cpp
+END
+TbUTRawDataReaderAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRawDataReaderAlgorithm.cpp
+END
+TbUTIDataRetreiver.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTIDataRetreiver.h
+END
+TbUTPedestalFollowingFactory.h
+K 25
+svn:wc:ra_dav:version-url
+V 83
+/guest/lhcb/!svn/ver/191830/Kepler/trunk/Tb/TbUT/src/TbUTPedestalFollowingFactory.h
+END
+TbUTPedestalSubtractor.h
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalSubtractor.h
+END
+TbUTIProcessingEngine.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTIProcessingEngine.h
+END
+TbUTRawDataFactory.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRawDataFactory.h
+END
+TbUTPedestalSubtractorAlgorithm.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalSubtractorAlgorithm.cpp
+END
+TbUTRandomNoiseGenerator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRandomNoiseGenerator.cpp
+END
+TbUTNoiseCalculator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNoiseCalculator.cpp
+END
+TbUTNTupleCreator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNTupleCreator.cpp
+END
+TbUTChannelMaskFileValidator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/src/TbUTChannelMaskFileValidator.cpp
+END
+TbUTCMSIterativelyPerBeetle.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 84
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCMSIterativelyPerBeetle.cpp
+END
+TbUTClusterCreatorFactory.h
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/197306/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreatorFactory.h
+END
+TbUTAlbavaFileValidator.h
+K 25
+svn:wc:ra_dav:version-url
+V 78
+/guest/lhcb/!svn/ver/191830/Kepler/trunk/Tb/TbUT/src/TbUTAlbavaFileValidator.h
+END
+TbUTClusterCreator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreator.cpp
+END
+TbUTIFileValidator.h
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTIFileValidator.h
+END
+TbUTTresholdProvider.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/194373/Kepler/trunk/Tb/TbUT/src/TbUTTresholdProvider.h
+END
+TbUTRawDataMonitorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 82
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTRawDataMonitorAlgorithm.h
+END
+TbUTSensor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 67
+/guest/lhcb/!svn/ver/193201/Kepler/trunk/Tb/TbUT/src/TbUTSensor.cpp
+END
+TbUTPedestalFollowingFactory.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 85
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTPedestalFollowingFactory.cpp
+END
+TbUTPedestalSubtractor.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalSubtractor.cpp
+END
+TbUTPedestalCalculator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalCalculator.cpp
+END
+TbUTClusterCreatorDataMonitorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 93
+/guest/lhcb/!svn/ver/197308/Kepler/trunk/Tb/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.h
+END
+TbUTCluster.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/195644/Kepler/trunk/Tb/TbUT/src/TbUTCluster.cpp
+END
+TbUTAlibavaDataRetreiver.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/186100/Kepler/trunk/Tb/TbUT/src/TbUTAlibavaDataRetreiver.cpp
+END
+TbUTCMSLinear.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCMSLinear.h
+END
+TbUTCommonModeSubtractorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 88
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTCommonModeSubtractorAlgorithm.h
+END
+TbUTRawDataReaderAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 81
+/guest/lhcb/!svn/ver/194758/Kepler/trunk/Tb/TbUT/src/TbUTRawDataReaderAlgorithm.h
+END
+TbUTPedestalSubtractorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 86
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTPedestalSubtractorAlgorithm.h
+END
+TbUTDataLocations.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTDataLocations.h
+END
+TbUTRandomNoiseGenerator.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTRandomNoiseGenerator.h
+END
+TbUTNoiseCalculator.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNoiseCalculator.h
+END
+TbUTNTupleCreator.h
+K 25
+svn:wc:ra_dav:version-url
+V 72
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTNTupleCreator.h
+END
+TbUTAlbavaFileValidator.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 80
+/guest/lhcb/!svn/ver/193730/Kepler/trunk/Tb/TbUT/src/TbUTAlbavaFileValidator.cpp
+END
+TbUTDataMonitorAlgorithm.h
+K 25
+svn:wc:ra_dav:version-url
+V 79
+/guest/lhcb/!svn/ver/197804/Kepler/trunk/Tb/TbUT/src/TbUTDataMonitorAlgorithm.h
+END
diff --git a/TbUT/src/.svn/entries b/TbUT/src/.svn/entries
new file mode 100644
index 0000000..040ece0
--- /dev/null
+++ b/TbUT/src/.svn/entries
@@ -0,0 +1,3026 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/src
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-24T11:06:55.044019Z
+198103
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbUTMambaDataReader.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+6eb00cf138024de91e773b316b2b3a54
+2015-11-24T11:06:55.044019Z
+198103
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+679
+
+TbUTRawDataMonitorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+f17b6ee626c6951261e06b3fdc852842
+2015-04-23T07:26:07.964498Z
+187186
+hschindl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+653
+
+TbUTCommonModeSubtractorFactory.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+927dd39301594cdb2d07a5c12a1634e8
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+794
+
+Doxyfile
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+90bc9458ae8d300485ba98171183adee
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+75520
+
+TbUTClusterCreator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+2be1d5577be536412ba6ad647750533b
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2141
+
+TbUTIDataReader.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+f098f07554d9f5807c00bd78510dc720
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+725
+
+TbUTClusterCreatorDataMonitorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+22f52cb16b30c751bef4829628d73d2d
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7875
+
+TbUTNoise.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+61765f82a28f720535f1351361ba3f3f
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3339
+
+TbUTIChannelMaskProvider.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+081f34cd9510ea2ce5871cc7f9f57d51
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+410
+
+TbUTClusterCreatorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+50b2e6de329c233fb17c0febebc94194
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1182
+
+TbUTSensor.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+8b0161925b5047cbd230ea91e94bde51
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+667
+
+TbUTNoiseCalculatorfactory.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+cb2477255e4ffb89128369ff29837300
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+714
+
+TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+85be39f6786daf71d1e3ae808869588b
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6063
+
+TbUTPedestalCalculator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+338f30ba1878dfd39d1c2b1da7467687
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+992
+
+TbUTPedestalSubtractorDataMonitorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+5f3f7585df9229a771c9cced90d04f0b
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1986
+
+TbUTNoiseCalculatorFake.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+9035666c2bb6a5c034bedc4be30ce16a
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+375
+
+TbUTRawData.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+0db0faf56804261d4b6dc3297d08a4bb
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+185
+
+TbUTAlibavaDataRetreiver.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+38167f2675f4ad49ee04c4246fa44557
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+486
+
+TbUTCluster.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+4a054a4f954646f93a89c390fdac65a7
+2015-10-12T13:50:18.231850Z
+195966
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1193
+
+TbUTDataMonitorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+b92a005c49014a1c80c94d66ad4c414d
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5014
+
+TbUTPedestalRetreiver.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+01125767908e638b8fa915b0876ba6ce
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1690
+
+TbUTMambaDataReader.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+9438460ff290d484524b4f94e4fffd53
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2053
+
+TbUTCommonModeSubtractorFactory.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+2d743ea901201726578bef9d69ca7d42
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+789
+
+TbUTChannelMaskProvider.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+cbb8656cab474892ce5a743a83fdb6be
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1722
+
+TbUTIPedestalFollowing.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+84fbe68755f15613303ac0810e165f38
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+545
+
+TbUTPedestal.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+8b3a9636e0ead23fc1eff0fc76e421f3
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+960
+
+TbUTPedestalFileValidator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+efb919872cbccade8228fecbf6ce8804
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+719
+
+TbUTClusterCreatorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+c22e56c7e7c8cdd994745248d6382904
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3814
+
+TbUTRawDataFactory.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+9a8fde417c17bfb31d6fe29bc1450341
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1135
+
+TbUTNoiseCalculatorFake.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+54182d6c055ad1057e753bc9892d3f2c
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+365
+
+TbUTCmsPerBeetle.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+37b2a665534f5e999d4e65da6fc62be7
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+657
+
+TbUTIClusterCreator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+5578fb558ad3fbc7afaaa1192aed31a7
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+500
+
+TbUTAlibavaDataReader.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+d9b094ef7596be9a899d819903238239
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+689
+
+TbUTNoise.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+c4f3b1ee54107f728c3d9cc34fbd220e
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+979
+
+TbUTNoiseCalculatorfactory.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+6e37494a64ef3e2c229ecfabbbfc98d1
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+740
+
+TbUTICommonModeSubtractor.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+a534f85aae3c8c4ab74e55ab07bacea7
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+286
+
+TbUTCommonModeSubtractorDataMonitorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+2ad30bc9e00b2986bde56e9b301fc621
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1175
+
+TbUTPedestalSubtractorDataMonitorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+2e5426982b2fcc1774280b670e0c9b5e
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+619
+
+TbUTRawData.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+28e476c85a40efafbbac6efcb770cf6f
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4236
+
+TbUTClusterCreatorFactory.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+962ed0346d0de1baa6327aff8cda0b30
+2015-11-06T18:00:55.060165Z
+197306
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+702
+
+TbUTPedestalRetreiver.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+f4050de45bafb6b6f75ef264b19f1f8d
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+681
+
+TbUTChannelMaskFileValidator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+9c328d3b7ad94259b3f7d9099fd83535
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+495
+
+TbUTTresholdProvider.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+dca14908cffce77824db906bbee84003
+2015-08-28T14:07:26.476091Z
+194351
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+901
+
+TbUTCMSIterativelyPerBeetle.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+481706364cc5f6daa395c0e0deeda5a5
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+942
+
+TbUTChannelMaskProvider.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+a3165c723a5d056a9966612daf45d16d
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1328
+
+TbUTINoiseCalculator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+048eb862efb88d671098fda37d53bf61
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+339
+
+TbUTPedestal.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+9354f2ddf396addc6dd30e802079dda4
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+759
+
+TbUTCmsPerBeetle.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+f6308682661a8323c042d82830d254ba
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1781
+
+TbUTPedestalFileValidator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+06036f593809c9d7404e1cb7e56ef821
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+506
+
+TbUTAlibavaDataReader.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+e166a71c0d36cd22b6cb9777b6c5c14f
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1376
+
+TbUTITresholdProvider.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+da3ab6b4cf2b7e0a3ae332ba08f7284e
+2015-08-28T14:07:26.476091Z
+194351
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+566
+
+TbUTCMSLinear.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+107a666c0501d02aec3b82eda154be95
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1296
+
+TbUTCommonModeSubtractorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+0bfddb16d6cb06680fc1fe8d5f6b5a90
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4715
+
+TbUTRawDataReaderAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+10e67f8c9de29ff85560e7e13092a692
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3238
+
+TbUTIDataRetreiver.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+c9f82bfec9748156312f505118a554e3
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+469
+
+TbUTPedestalFollowingFactory.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+35b882435bfbc1ec7a1e3d4a42f14afb
+2015-07-14T15:38:17.550603Z
+191830
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+993
+
+TbUTPedestalSubtractor.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+b006ed77ca3b79b6166d57588a6638f6
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+572
+
+alibava
+dir
+
+TbUTIProcessingEngine.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+724a45c13aaa9b0be3a7df0aa63e2559
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+376
+
+TbUTRawDataFactory.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+3ae4c7b28892a0204ba7b6d286acfc98
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1105
+
+TbUTPedestalSubtractorAlgorithm.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+7fb97c479f1eb460b17f1b03aa189f7c
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+5190
+
+TbUTRandomNoiseGenerator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+0494d5865befbcbba1721ebe0b8329cb
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+664
+
+TbUTNTupleCreator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+ae230e51d379a04d0ffb1d970e04b295
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+8787
+
+TbUTNoiseCalculator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+c5ed900adcb00cd6a78ba1c23fea3e23
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+404
+
+TbUTChannelMaskFileValidator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+19011605d12afa7a68edf159cfbbf21e
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+870
+
+TbUTCMSIterativelyPerBeetle.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+85ae1987e49d3a85d2dd1f02681e3349
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2821
+
+mamba
+dir
+
+TbUTClusterCreatorFactory.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+e9ed2061fb6cdfe359dbc38299887b45
+2015-11-06T18:00:55.060165Z
+197306
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+855
+
+TbUTAlbavaFileValidator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+4105eb328c0c93576450c4ca9dced463
+2015-07-14T15:38:17.550603Z
+191830
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+478
+
+TbUTClusterCreator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+bab4c9d49f91f281631355b4761e102a
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7593
+
+TbUTIFileValidator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+1e36419f2bee063711662b874979ddfc
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+235
+
+TbUTTresholdProvider.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+9f1dfc7f17b0b975bfb39fd8e91ed2e1
+2015-08-28T20:30:53.542035Z
+194373
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+697
+
+TbUTRawDataMonitorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+1f293413c5b5212120b1e303201f817b
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+347
+
+TbUTSensor.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+ce0dd90793a5545cd72cabb8657bc132
+2015-08-05T14:17:58.425788Z
+193201
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+627
+
+TbUTPedestalFollowingFactory.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+b2ceb2a6526462211cc979981c778319
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+994
+
+TbUTPedestalSubtractor.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+8cff3597db098328fb4819d21a77e074
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+934
+
+TbUTPedestalCalculator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+2d98adcc409e231db75b49af1b6c8904
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3202
+
+TbUTClusterCreatorDataMonitorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+b714c591340c2f9e5d447bbf7efd989a
+2015-11-06T19:22:53.978535Z
+197308
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1941
+
+TbUTCluster.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+12bf0f6c26b76eaffdab22614b0e3136
+2015-10-08T11:40:41.119370Z
+195644
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+720
+
+TbUTAlibavaDataRetreiver.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+1f2592dddadc3bdd250e8300a6c8a619
+2015-03-31T15:05:08.686916Z
+186100
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+814
+
+TbUTCMSLinear.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+441a36e8d99e600cc09f096b815cacc7
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+596
+
+TbUTCommonModeSubtractorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+28d7c226bafbd7816871ef8a655da85d
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1654
+
+TbUTRawDataReaderAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+2b05b95e62e60769d384a82f69755532
+2015-09-09T16:04:25.162348Z
+194758
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1247
+
+TbUTPedestalSubtractorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+c93c167980d343f10d5d7374cc73620f
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1899
+
+TbUTDataLocations.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+e3c4d68664fc71e8775f4521516f64b8
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+953
+
+TbUTRandomNoiseGenerator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+c3245ea8dc8c63cd95edf172d22896a1
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+441
+
+TbUTNoiseCalculator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+0b7c329412ed8bc90c9e3616084ef88f
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+392
+
+TbUTNTupleCreator.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+1b3b3de74f2232a847b63593d6799de3
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2104
+
+TbUTAlbavaFileValidator.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+d2e9073a1427812d884b9212cbfb6b87
+2015-08-14T17:20:42.072489Z
+193730
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+771
+
+TbUTDataMonitorAlgorithm.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+93a6bdc6c85d1f9c4a24b16d18151cf2
+2015-11-19T22:43:30.677286Z
+197804
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1535
+
diff --git a/TbUT/src/.svn/text-base/Doxyfile.svn-base b/TbUT/src/.svn/text-base/Doxyfile.svn-base
new file mode 100644
index 0000000..552a39c
--- /dev/null
+++ b/TbUT/src/.svn/text-base/Doxyfile.svn-base
@@ -0,0 +1,1781 @@
+# Doxyfile 1.7.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = "My Project"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the
+# mathjax.org site, so you can quickly see the result without installing
+# MathJax, but it is strongly recommended to install a local copy of MathJax
+# before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/TbUT/src/.svn/text-base/TbUTAlbavaFileValidator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTAlbavaFileValidator.cpp.svn-base
new file mode 100644
index 0000000..e097a8a
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTAlbavaFileValidator.cpp.svn-base
@@ -0,0 +1,43 @@
+/*
+ * TbUTAlbavaFileValidator.cpp
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+#include "TbUTAlbavaFileValidator.h"
+#include <string>
+#include <iostream>
+using namespace TbUT;
+using namespace boost::filesystem;
+using namespace std;
+
+
+ AlbavaFileValidator:: AlbavaFileValidator( std::string& p_filename):
+		m_filename(p_filename)
+{
+}
+
+ bool AlbavaFileValidator::validateFile()
+ {
+	 m_path=path(m_filename);
+	 bool l_result=
+			  isfileExist() &&
+			  isRegularFile() &&
+			  hasNonZeroSize();
+	 return l_result;
+ }
+
+ bool AlbavaFileValidator::isfileExist()
+ {
+	 return exists(m_path);
+ }
+
+ bool AlbavaFileValidator::isRegularFile()
+ {
+	 return  is_regular_file(m_path);
+ }
+
+ bool AlbavaFileValidator::hasNonZeroSize()
+ {
+	 return !(0==file_size(m_path));
+ }
diff --git a/TbUT/src/.svn/text-base/TbUTAlbavaFileValidator.h.svn-base b/TbUT/src/.svn/text-base/TbUTAlbavaFileValidator.h.svn-base
new file mode 100644
index 0000000..aefd69e
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTAlbavaFileValidator.h.svn-base
@@ -0,0 +1,29 @@
+/*
+ * TbUTAlbavaFileValidator.h
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIFileValidator.h"
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace TbUT
+{
+class AlbavaFileValidator: public IFileValidator
+{
+public:
+	AlbavaFileValidator( std::string& p_filename);
+	bool validateFile();
+
+private:
+	bool isfileExist();
+	bool isRegularFile();
+	bool hasNonZeroSize();
+
+	std::string& m_filename;
+	boost::filesystem::path  m_path;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTAlibavaDataReader.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTAlibavaDataReader.cpp.svn-base
new file mode 100644
index 0000000..e223479
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTAlibavaDataReader.cpp.svn-base
@@ -0,0 +1,60 @@
+/*
+ * TbUTRawData<>Reader.cpp
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+#include "TbUTAlibavaDataReader.h"
+#include <iostream>
+using namespace TbUT;
+
+
+AlibavaDataReader::AlibavaDataReader(std::string& p_filename  , IDataRetreiver & p_alibava, IFileValidator& p_fileValidator):
+				m_filaname(p_filename ),
+				m_alibava(p_alibava),
+				m_fileValidator(p_fileValidator)
+{
+}
+
+void AlibavaDataReader::checkInput()
+{
+	if( ! m_fileValidator.validateFile() ){
+		std::string errorMsg= "file validation error";
+		throw IDataReader::InputFileError(errorMsg);
+	}
+
+	m_alibava.open(m_filaname);
+	if(! m_alibava.valid()){
+		std::string errorMsg= "alibava validation error";
+		throw IDataReader::InputFileError(errorMsg);
+	}
+}
+
+RawData<>* AlibavaDataReader::getEventData()
+{
+	readEvent();
+	RawData<> *l_outputData=new RawData<>();
+	fillRawData(l_outputData);
+	return l_outputData;
+}
+
+
+void AlibavaDataReader::readEvent()
+{
+	std::string l_errorStr="";
+	if(0 != m_alibava.read_event(l_errorStr))
+	{
+		throw IDataReader::ReadEventError(l_errorStr);
+	}
+}
+
+void AlibavaDataReader::fillRawData(RawData<>* p_outputData)
+{
+	m_alibava.process_event();
+	p_outputData->setTime( m_alibava.time() );
+	p_outputData->setTemp( m_alibava.temp() );
+	for(int chan = RawData<>::getMinChannel(); chan < RawData<>::getMaxChannel(); chan++ )
+		p_outputData->setSignal( m_alibava.data(chan));
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTAlibavaDataReader.h.svn-base b/TbUT/src/.svn/text-base/TbUTAlibavaDataReader.h.svn-base
new file mode 100644
index 0000000..5fb1128
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTAlibavaDataReader.h.svn-base
@@ -0,0 +1,38 @@
+/*
+ * TbUTDataReader.h
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include "TbUTRawData.h"
+#include "TbUTIFileValidator.h"
+#include "TbUTIDataRetreiver.h"
+#include <stdexcept>
+#include <string>
+
+namespace TbUT
+{
+class AlibavaDataReader : public IDataReader
+{
+public:
+
+	AlibavaDataReader(std::string& p_filename ,IDataRetreiver & p_alibava,IFileValidator& p_fileValidator);
+	void checkInput();
+	RawData<>* getEventData(); // unfortunately have to be pointer
+
+private:
+
+	void readEvent();
+	void fillRawData(RawData<>* p_outputData);
+
+	std::string & m_filaname;
+	IDataRetreiver & m_alibava;
+	IFileValidator& m_fileValidator;
+};
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTAlibavaDataRetreiver.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTAlibavaDataRetreiver.cpp.svn-base
new file mode 100644
index 0000000..0d218e2
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTAlibavaDataRetreiver.cpp.svn-base
@@ -0,0 +1,50 @@
+/*
+ * TbUTAlibava.cpp
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+#include "TbUTAlibavaDataRetreiver.h"
+
+using namespace TbUT;
+
+AlibavaDataRetreiver::AlibavaDataRetreiver () :
+    m_assciRoot ()
+{
+}
+
+void AlibavaDataRetreiver::open(std::string & p_filePath)
+{
+	m_assciRoot.open(p_filePath.c_str());
+}
+
+bool
+AlibavaDataRetreiver::valid ()
+{
+  return m_assciRoot.valid ();
+}
+
+int AlibavaDataRetreiver::read_event (std::string & error_code)
+{
+  return m_assciRoot.read_event (error_code);
+}
+
+void AlibavaDataRetreiver::process_event ()
+{
+  m_assciRoot.process_event ();
+}
+
+double AlibavaDataRetreiver::time ()
+{
+  return m_assciRoot.time ();
+}
+
+double AlibavaDataRetreiver::temp ()
+{
+  return m_assciRoot.temp ();
+}
+
+unsigned short AlibavaDataRetreiver::data (int i)
+{
+  return m_assciRoot.data (i);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTAlibavaDataRetreiver.h.svn-base b/TbUT/src/.svn/text-base/TbUTAlibavaDataRetreiver.h.svn-base
new file mode 100644
index 0000000..e2b215d
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTAlibavaDataRetreiver.h.svn-base
@@ -0,0 +1,33 @@
+/*
+ * TbUTAlibava.h
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "alibava/TbAsciiRoot.h"
+#include "TbUTIDataRetreiver.h"
+
+namespace TbUT
+{
+class AlibavaDataRetreiver: public IDataRetreiver
+{
+
+public:
+	AlibavaDataRetreiver();
+	void open(std::string & p_filename);
+	bool valid();
+	int	read_event(std::string & error_code);
+	void process_event();
+	double	time();
+	double	temp();
+	unsigned short data(int i);
+
+private:
+	TbAsciiRoot m_assciRoot;
+};
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTCMSIterativelyPerBeetle.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCMSIterativelyPerBeetle.cpp.svn-base
new file mode 100644
index 0000000..b3c69a3
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCMSIterativelyPerBeetle.cpp.svn-base
@@ -0,0 +1,91 @@
+#include "TbUTCMSIterativelyPerBeetle.h"
+#include <iostream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+CMSIterativelyPerBeetle::CMSIterativelyPerBeetle(IChannelMaskProvider& p_masksProvider):
+        m_masksProvider(p_masksProvider),
+        m_channelNumber(RawData<>::getnChannelNumber()),
+		m_channelPerBeetle(32)
+{
+    cout<<"create iteratively correlation per beetle"<<endl;
+    initializeCorrectionAndHitMaps();
+}
+
+
+void CMSIterativelyPerBeetle::initializeCorrectionAndHitMaps()
+{
+	for (int channel=0;channel<m_channelNumber;channel+=m_channelPerBeetle){
+		m_correctionPerBeetle.insert(std::make_pair(channel,0));
+		m_hitThresholdPerBeetle.insert(std::make_pair(channel,200));
+	}
+}
+
+void CMSIterativelyPerBeetle::processEvent(RawData<>* p_data, RawData<double> **p_output)
+{
+	int numberOfIteration=2;
+	RawData<double>* tmpData;
+	// first iteration
+	calculateCorrection<int>(p_data);
+	removeCM<int, double>(p_data,p_output);
+	// rest of the iterations
+	for(int iteration=1;iteration<numberOfIteration; iteration++){
+		tmpData=new RawData<double>(**p_output);
+		calculateCorrection<double>(tmpData);
+		removeCM<double, double>(tmpData,p_output);
+	}
+	resetHitThresholds();
+}
+
+template<typename DATA_TYPE>
+void CMSIterativelyPerBeetle::calculateCorrection(RawData<DATA_TYPE>* p_inputData)
+{
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		int usedChannels=0;
+		double rmsPerBeetle=0;
+		for(int channel=mapIt.first;channel<mapIt.first+m_channelPerBeetle;channel++)
+		{
+			double signal=static_cast<double>(p_inputData->getSignal(channel));
+			if(!m_masksProvider.isMasked(channel) && abs(signal) <m_hitThresholdPerBeetle[mapIt.first]){
+				mapIt.second+=signal;
+				rmsPerBeetle+=signal*signal;
+				usedChannels++;
+			}
+		}
+		if(usedChannels) mapIt.second/=static_cast<double>(usedChannels);
+		if(usedChannels) rmsPerBeetle/=static_cast<double>(usedChannels);
+		rmsPerBeetle-=mapIt.second*mapIt.second;
+		double rmsMultiplicity=4;
+		m_hitThresholdPerBeetle[mapIt.first]=rmsMultiplicity*sqrt(rmsPerBeetle);
+	}
+}
+
+template<typename INPUT_DATA_TYPE, typename OUTPUT_TYPE_NAME>
+void CMSIterativelyPerBeetle::removeCM(RawData<INPUT_DATA_TYPE>* p_data, RawData<OUTPUT_TYPE_NAME> **p_output)
+{
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		for(int channel=mapIt.first;channel<mapIt.first+m_channelPerBeetle;channel++)
+		{
+			if(m_masksProvider.isMasked(channel)){
+				OUTPUT_TYPE_NAME signalMaskedChannel=0;
+				(*p_output)->setSignal(signalMaskedChannel);
+			}else{
+				OUTPUT_TYPE_NAME l_channelSignal=p_data->getSignal(channel)-mapIt.second;
+				(*p_output)->setSignal(l_channelSignal);
+			}
+		}
+
+	}
+	 (*p_output)->setTDC(p_data->getTDC());
+	 (*p_output)->setTime(p_data->getTime());
+
+}
+
+void CMSIterativelyPerBeetle::resetHitThresholds()
+{
+	for(auto& mapIt : m_hitThresholdPerBeetle) mapIt.second=200;
+}
diff --git a/TbUT/src/.svn/text-base/TbUTCMSIterativelyPerBeetle.h.svn-base b/TbUT/src/.svn/text-base/TbUTCMSIterativelyPerBeetle.h.svn-base
new file mode 100644
index 0000000..3933302
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCMSIterativelyPerBeetle.h.svn-base
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "TbUTICommonModeSubtractor.h"
+#include "TbUTIChannelMaskProvider.h"
+
+#include <map>
+
+namespace TbUT
+{
+    class CMSIterativelyPerBeetle : public  ICommonModeSubtractor
+    {
+    public:
+        CMSIterativelyPerBeetle(IChannelMaskProvider& p_masksProvider);
+        void processEvent(RawData<>* p_data, RawData<double> **p_output);
+
+    private:
+	template<typename DATA_TYPE>
+        void calculateCorrection(RawData<DATA_TYPE>* p_inputData);
+	template<typename INPUT_DATA_TYPE, typename OUTPUT_TYPE_NAME>
+        void removeCM(RawData<INPUT_DATA_TYPE>* p_data, RawData<OUTPUT_TYPE_NAME> **p_output);
+        void resetHitThresholds();
+
+        void initializeCorrectionAndHitMaps();
+
+        IChannelMaskProvider& m_masksProvider;
+        const int m_channelNumber;
+        const int m_channelPerBeetle;
+    	std::map<int, double> m_correctionPerBeetle;
+    	std::map<int, double> m_hitThresholdPerBeetle;
+    };
+}
+
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTCMSLinear.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCMSLinear.cpp.svn-base
new file mode 100644
index 0000000..0effdc0
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCMSLinear.cpp.svn-base
@@ -0,0 +1,53 @@
+/*
+ * CMSLinear.cpp
+ *
+ *  Created on: Nov 23, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCMSLinear.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace std;
+
+CMSLinear::CMSLinear(IChannelMaskProvider& p_masksProvider):
+		m_masksProvider(p_masksProvider),
+		m_channelNumber(RawData<>::getnChannelNumber())
+{
+}
+void CMSLinear::processEvent(RawData<>* p_data, RawData<double> **p_output)
+{
+	double l_correction = calculateCorrection(p_data);
+	for(int channel=0;channel<m_channelNumber;channel++){
+		removeCM(p_data,p_output,channel,l_correction);
+	}
+}
+
+double CMSLinear::calculateCorrection(RawData<>* p_inputData)
+{
+	double correction=0;
+	int usedChannels=0;
+	for(int channel=0;channel<m_channelNumber;channel++){
+		if(!m_masksProvider.isMasked(channel)){
+			correction+=p_inputData->getSignal(channel);
+			usedChannels++;
+		}
+	}
+	if(usedChannels) correction/=static_cast<double>(usedChannels);
+	return correction;
+}
+
+
+void CMSLinear::removeCM(RawData<>* p_data, RawData<double> **p_output, int p_channel, double p_correction)
+{
+	if(m_masksProvider.isMasked(p_channel))
+	{
+		double l_signalMaskedChannel=0;
+		(*p_output)->setSignal(l_signalMaskedChannel);
+	}else{
+		double l_channelSignal=p_data->getSignal(p_channel)-p_correction;
+				(*p_output)->setSignal(l_channelSignal);
+	}
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTCMSLinear.h.svn-base b/TbUT/src/.svn/text-base/TbUTCMSLinear.h.svn-base
new file mode 100644
index 0000000..574c814
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCMSLinear.h.svn-base
@@ -0,0 +1,31 @@
+/*
+ * CMSLinear.h
+ *
+ *  Created on: Nov 23, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTICommonModeSubtractor.h"
+#include "TbUTIChannelMaskProvider.h"
+
+namespace TbUT
+{
+
+class CMSLinear: public ICommonModeSubtractor
+{
+public:
+	CMSLinear(IChannelMaskProvider& p_masksProvider );
+	void processEvent(RawData<>* p_data, RawData<double> **p_output);
+
+private:
+	double calculateCorrection(RawData<>* p_inputData);
+	void removeCM(RawData<>* p_data, RawData<double> **p_output, int p_channel, double p_correction);
+
+	IChannelMaskProvider& m_masksProvider;
+	int m_channelNumber;
+};
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTChannelMaskFileValidator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTChannelMaskFileValidator.cpp.svn-base
new file mode 100644
index 0000000..121d7f7
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTChannelMaskFileValidator.cpp.svn-base
@@ -0,0 +1,45 @@
+/*
+ * TbUTChannelMaskFileValidator.cpp
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTChannelMaskFileValidator.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace boost::filesystem;
+using namespace std;
+
+ChannelMaskFileValidator:: ChannelMaskFileValidator( std::string& p_filename):
+		m_filename(p_filename)
+{
+}
+
+ bool ChannelMaskFileValidator::validateFile()
+ {
+	 m_path=path(m_filename);
+	 bool l_result=
+			  isfileExist() &&
+			  isRegularFile() &&
+			  hasProperSize();
+	  return l_result;
+ }
+
+ bool ChannelMaskFileValidator::isfileExist()
+ {
+	 return exists(m_path);
+ }
+
+ bool ChannelMaskFileValidator::isRegularFile()
+ {
+	return  is_regular_file(m_path);
+ }
+
+ bool ChannelMaskFileValidator::hasProperSize()
+ {
+	unsigned int l_expectedSieze=1024;
+	cout<<file_size(m_path)<<endl;
+	return l_expectedSieze==file_size(m_path);
+ }
diff --git a/TbUT/src/.svn/text-base/TbUTChannelMaskFileValidator.h.svn-base b/TbUT/src/.svn/text-base/TbUTChannelMaskFileValidator.h.svn-base
new file mode 100644
index 0000000..a13b2bf
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTChannelMaskFileValidator.h.svn-base
@@ -0,0 +1,31 @@
+/*
+ * TbUTChannelMaskFileValidator.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIFileValidator.h"
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace TbUT
+{
+class ChannelMaskFileValidator: public IFileValidator
+{
+public:
+	ChannelMaskFileValidator( std::string& p_filename);
+	bool validateFile();
+
+private:
+	bool isfileExist();
+	bool isRegularFile();
+	bool hasProperSize();
+
+
+	std::string& m_filename;
+	boost::filesystem::path  m_path;
+};
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTChannelMaskProvider.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTChannelMaskProvider.cpp.svn-base
new file mode 100644
index 0000000..c674389
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTChannelMaskProvider.cpp.svn-base
@@ -0,0 +1,77 @@
+/*
+ * TbUTChannelMaskProvider.cpp
+ *
+ *  Created on: Oct 11, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTChannelMaskProvider.h"
+#include"TbUTRawData.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace std;
+
+
+ChannelMaskProvider::ChannelMaskProvider(IFileValidator & p_fileValidator):
+		m_fileValidator(p_fileValidator),
+		m_masks()
+{
+}
+
+void ChannelMaskProvider::getMaskFromFile(const string& p_filename)
+{
+	validateFile();
+	ifstream l_file;
+	openfile(p_filename,l_file);
+	retreiveMasksFromFile(l_file);
+	checkMaskVector();
+}
+
+bool ChannelMaskProvider::isMasked(int p_channel)
+{
+	if(!isChannelInRange(p_channel)){
+		std::cout<<"channel out of range"<<p_channel<<std::endl;
+		throw ChannelOutOfRange("");
+	}
+	return (m_masks[p_channel]==0);
+}
+
+
+
+void ChannelMaskProvider::validateFile()
+{
+	if(!m_fileValidator.validateFile())
+		throw InputFileError("Mask File validation error!");
+
+}
+
+void ChannelMaskProvider::openfile(const std::string& p_filename, std::ifstream& p_inputFile)
+{
+	p_inputFile.open(p_filename.c_str(),ios::in);
+	if(!p_inputFile.good())
+		throw InputFileError("Cannot open mask file!"+p_filename);
+}
+
+void ChannelMaskProvider::retreiveMasksFromFile(std::ifstream& p_file)
+{
+	int l_sensorNumber= RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_sensorNumber;channel++){
+		unsigned short l_mask;
+		p_file>>l_mask;
+		m_masks.push_back(l_mask);
+	}
+}
+
+void ChannelMaskProvider::checkMaskVector()
+{
+	const unsigned int l_sensorNumber=RawData<>::getnChannelNumber();
+	if (m_masks.size() !=l_sensorNumber)
+		throw NotEnoughtChannel("");
+}
+
+bool ChannelMaskProvider::isChannelInRange(int p_channel)
+{
+	int l_sensorNumber= RawData<>::getnChannelNumber();
+	return p_channel<l_sensorNumber;
+}
diff --git a/TbUT/src/.svn/text-base/TbUTChannelMaskProvider.h.svn-base b/TbUT/src/.svn/text-base/TbUTChannelMaskProvider.h.svn-base
new file mode 100644
index 0000000..4446511
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTChannelMaskProvider.h.svn-base
@@ -0,0 +1,68 @@
+/*
+ * TbUTChannelMaskProvider.h
+ *
+ *  Created on: Oct 11, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTIFileValidator.h"
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <stdexcept>
+
+
+namespace TbUT
+{
+class ChannelMaskProvider: public IChannelMaskProvider
+{
+public:
+
+	class InputFileError: public std::runtime_error	{
+	public:
+		InputFileError(const std::string& p_errorMsg ):
+				std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+
+	class NotEnoughtChannel: public std::runtime_error	{
+	public:
+		NotEnoughtChannel(const std::string& p_error) :
+				std::runtime_error(p_error)
+		{
+		}
+	};
+
+	class ChannelOutOfRange: public std::runtime_error	{
+	public:
+		ChannelOutOfRange(const std::string& p_error) :
+				std::runtime_error(p_error)
+		{
+		}
+	};
+
+	ChannelMaskProvider(IFileValidator & p_fileValidator);
+	void getMaskFromFile(const std::string& p_filename=TbUT::DataLocations::MaskLocation);
+	bool isMasked(int p_channel);
+
+private:
+	typedef std::vector<unsigned short> MaskVector;
+
+	void validateFile();
+	void openfile(const std::string& p_filename, std::ifstream& p_inputFile);
+	void retreiveMasksFromFile(std::ifstream& p_file);
+	void checkMaskVector();
+	bool isChannelInRange(int p_channel);
+
+
+
+	IFileValidator & m_fileValidator;
+	MaskVector m_masks;
+};
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTCluster.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCluster.cpp.svn-base
new file mode 100644
index 0000000..51744de
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCluster.cpp.svn-base
@@ -0,0 +1,44 @@
+/*
+ * TbUTCluster.cpp
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTCluster.h"
+
+using namespace TbUT;
+
+
+Cluster::Cluster():
+		m_position(0),
+		m_size(0),
+		m_charge(0),
+		m_chargeSeed(0),
+		m_charge2StripLeft(0),
+		m_charge1StripLeft(0),
+		m_charge2StripRight(0),
+		m_charge1StripRight(0)
+{
+}
+
+ClusterContainer::ClusterContainer():
+		m_isEmpty(true),
+		m_clusterVector(),
+		m_timestamp(0),
+		m_tdc(0)
+{
+}
+
+void ClusterContainer::setClusters(ClusterVector& p_clusterVec)
+{
+	m_clusterVector=p_clusterVec;
+	m_isEmpty=false;
+}
+
+void ClusterContainer::addClusters(ClusterVector& p_cluster)
+{
+	m_isEmpty=false;
+	m_clusterVector.insert(m_clusterVector.begin(),p_cluster.begin(),p_cluster.end());
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTCluster.h.svn-base b/TbUT/src/.svn/text-base/TbUTCluster.h.svn-base
new file mode 100644
index 0000000..1f576db
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCluster.h.svn-base
@@ -0,0 +1,56 @@
+/*
+ * TbUTCluster.h
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "GaudiKernel/DataObject.h"
+#include "TbUTRawData.h"
+#include <vector>
+
+namespace TbUT
+{
+
+struct Cluster
+{
+	Cluster();
+	double m_position;
+	int m_seedPosition;
+	int m_size;
+	double m_charge;
+	double m_chargeSeed;
+	double m_charge2StripLeft;
+	double m_charge1StripLeft;
+	double m_charge2StripRight;
+	double m_charge1StripRight;
+};
+
+class ClusterContainer : public DataObject
+{
+public:
+	typedef std::vector<Cluster> ClusterVector;
+	ClusterContainer();
+	void addCluster(Cluster& p_cluster);
+	void addClusters(ClusterVector& p_cluster);
+
+	void setClusters(ClusterVector& p_clusterVec);
+	int size(){return m_clusterVector.size(); }
+	ClusterVector getClusters(){return m_clusterVector;};
+	bool isEmpty(){return m_isEmpty;}
+	unsigned int getTDC()const {return m_tdc;}
+	void setTDC(unsigned int p_tdc){m_tdc=p_tdc;}
+
+	unsigned long long getTimestamp() const {return m_timestamp;}
+	void setTiemestamp(unsigned long long p_timestamp){m_timestamp =p_timestamp;}
+
+private:
+	bool m_isEmpty;
+	ClusterVector m_clusterVector;
+	unsigned long long m_timestamp;
+	unsigned int m_tdc;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreator.cpp.svn-base
new file mode 100644
index 0000000..73463a4
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreator.cpp.svn-base
@@ -0,0 +1,234 @@
+/*
+ * TbUTClusterCreator.cpp
+ *
+ *  Created on: Jan 5, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreator.h"
+#include <iostream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+ClusterCreator::ClusterCreator(const std::string&  p_sensorType,ITresholdProvider& p_thresholds):
+		m_clusterMaxSize(4),
+		m_thresholds(p_thresholds),
+		m_culsterVector()
+{
+	convertStringToSensorType(p_sensorType);
+}
+
+ClusterContainer::ClusterVector ClusterCreator::createClusters(RawData<double> *p_inputData)
+{
+	m_culsterVector.clear();
+	findCulsterSeeds(p_inputData);
+	removeDuplicatedSeeds(p_inputData);
+	extendClusterSeeds(p_inputData);
+	fillOuterStrips(p_inputData);
+	return m_culsterVector;
+}
+
+void ClusterCreator::convertStringToSensorType(const std::string& p_sensorType)
+{
+	if(p_sensorType == "PType")
+		m_sensorType= ClusterCreator::SensorType::P_TYPE;
+	else if (p_sensorType == "NType")
+		m_sensorType= ClusterCreator::SensorType::N_TYPE;
+	else
+		m_sensorType= ClusterCreator::SensorType::CUSTOM;
+}
+
+void ClusterCreator::findCulsterSeeds(RawData<double> *p_inputData)
+{
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(auto channel=0;channel<l_channelNumber;channel++){
+		auto l_channelSignal=p_inputData->getSignal(channel);
+		if(isBiggerThanSeedThreshold(l_channelSignal,channel ))
+			m_culsterVector.push_back(createCluster(p_inputData,channel));
+	}
+
+}
+
+bool ClusterCreator::isBiggerThanSeedThreshold(RawData<double>::DataType p_channelSignal, int p_channel) const
+{
+	double l_channelThreshold=m_thresholds.getHighClusterThreshold(p_channel);
+
+	switch(m_sensorType)
+	{
+	case ClusterCreator::SensorType::P_TYPE:
+		return p_channelSignal<(-1)*l_channelThreshold;
+	case ClusterCreator::SensorType::N_TYPE:
+		return p_channelSignal>l_channelThreshold;
+	default:
+		return abs(p_channelSignal) >l_channelThreshold ;
+	}
+}
+
+Cluster ClusterCreator::createCluster(RawData<double> *p_inputData, int l_channel) const
+{
+	int l_seedSize=1;
+	Cluster l_cluster;
+	l_cluster.m_charge=p_inputData->getSignal(l_channel);
+	l_cluster.m_chargeSeed=p_inputData->getSignal(l_channel);
+	l_cluster.m_seedPosition=l_channel;
+	l_cluster.m_size=l_seedSize;
+	l_cluster.m_position=l_channel*abs(l_cluster.m_charge); //position is weighted average, weight charge
+
+	return l_cluster;
+}
+
+void ClusterCreator::removeDuplicatedSeeds(RawData<double> *p_inputData)
+{
+	if(0==m_culsterVector.size()) return;
+	for(auto firstClusterIt = m_culsterVector.begin();firstClusterIt!=m_culsterVector.end();firstClusterIt++)
+	{
+		for(auto secondClusterIt=firstClusterIt+1;secondClusterIt!=m_culsterVector.end();)
+		{
+			if(arePartOfTheSameCluster(p_inputData, firstClusterIt,secondClusterIt))
+				removeClusterSeedWithSmallerCharge(firstClusterIt,secondClusterIt);
+			else
+				secondClusterIt++;
+			if(secondClusterIt==m_culsterVector.end()) break;
+		}
+		if(firstClusterIt==m_culsterVector.end()) break;
+	}
+}
+
+bool ClusterCreator::arePartOfTheSameCluster(RawData<double>* p_inputData, ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const
+{
+	if(!canBePartOfTheSameCluster(p_firstIt, p_secondIt)) return false;
+
+    auto channelRIterator=p_secondIt->m_seedPosition-1; // take previous strip position than pointed by secondIt
+	auto firstSeedPosition=p_firstIt->m_seedPosition;
+	for(;channelRIterator>firstSeedPosition;channelRIterator--){
+		auto channelCharge=p_inputData->getSignal(channelRIterator);
+		if(! isBiggerThanLowThreshold(channelCharge,channelRIterator) ) return false;
+	}
+	return true;
+}
+
+
+bool ClusterCreator::canBePartOfTheSameCluster(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const
+{
+	int seedDistance=abs(p_firstIt->m_seedPosition-p_secondIt->m_seedPosition);
+	return seedDistance<m_clusterMaxSize;
+}
+
+void ClusterCreator::removeClusterSeedWithSmallerCharge(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt)
+{
+	if(abs(p_firstIt->m_charge)>abs(p_secondIt->m_charge))
+		p_secondIt=m_culsterVector.erase(p_secondIt);
+	else{
+		p_firstIt =m_culsterVector.erase(p_firstIt);
+		p_secondIt=p_firstIt+1;
+	}
+}
+
+void ClusterCreator::extendClusterSeeds(RawData<double> *p_inputData)
+{
+	for(auto clusterIt = m_culsterVector.begin();clusterIt!=m_culsterVector.end();clusterIt++)
+	{
+		extendCluster(clusterIt, p_inputData);
+	}
+}
+
+void ClusterCreator::extendCluster(ClusterIterator& p_clusterIt,RawData<double>* p_inputData)
+{
+	int l_actualShift=1;
+	bool l_checkLeft=true;
+	bool l_checkRight=true;
+	bool l_isCheckingLeft=true;
+
+
+	while(hasNotMaximumSize(p_clusterIt))
+	{
+		l_isCheckingLeft=true;
+		if(l_checkLeft && (l_checkLeft=isStripNeedToBeAddedToCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft ) ) ){
+			updateCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft);
+		}
+		if(! hasNotMaximumSize(p_clusterIt) ) break;
+
+		l_isCheckingLeft=false;
+		if(l_checkRight && (l_checkRight=isStripNeedToBeAddedToCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft ) ) ) updateCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft);
+		l_actualShift++;
+		if(!l_checkLeft && !l_checkRight ) break;
+	}
+}
+
+bool ClusterCreator::hasNotMaximumSize(ClusterIterator& p_firstIt) const
+{
+	return p_firstIt->m_size<m_clusterMaxSize;
+}
+
+bool ClusterCreator::isStripNeedToBeAddedToCluster(ClusterIterator& p_clusterIt, RawData<double> *p_inputData, int p_stripShift,bool p_isCheckingLeft ) const
+{
+	int l_sign =(p_isCheckingLeft)? -1:1;
+	int l_channelNumber=p_clusterIt->m_seedPosition+l_sign*p_stripShift;
+
+	if(isInvalidChannelNumber(l_channelNumber ) ) return false;
+
+	double l_channelSignal=p_inputData->getSignal(l_channelNumber);
+	return isBiggerThanLowThreshold(l_channelSignal, l_channelNumber);
+}
+
+void ClusterCreator::updateCluster(ClusterIterator& p_clusterIt,RawData<double> *p_inputData ,int p_stripShift, bool p_isCheckingLeft)
+{
+	int l_sign =(p_isCheckingLeft)? -1:1;
+	int l_channelNumber=p_clusterIt->m_seedPosition+l_sign*p_stripShift;
+	auto l_channelSignal=p_inputData->getSignal(l_channelNumber);
+	p_clusterIt->m_charge+=l_channelSignal;
+	p_clusterIt->m_size+=1;
+	p_clusterIt->m_position+=l_channelNumber*abs(l_channelSignal);
+}
+
+bool ClusterCreator::isInvalidChannelNumber(int p_stripNumber) const
+{
+	if(p_stripNumber<RawData<>::getMinChannel()) return true;
+	if(p_stripNumber>RawData<>::getMaxChannel()) return true;
+	return false;
+}
+
+bool ClusterCreator::isBiggerThanLowThreshold(RawData<double>::DataType p_channelSignal, int p_chnnel) const
+{
+	double l_threshold=m_thresholds.getLowClusterThreshold(p_chnnel);
+	switch(m_sensorType)
+	{
+	case SensorType::P_TYPE:
+		return p_channelSignal<(-1)*l_threshold;
+	case SensorType::N_TYPE:
+		return p_channelSignal>l_threshold;
+	default:
+		return abs(p_channelSignal) >l_threshold ;
+	}
+}
+
+
+void ClusterCreator::fillOuterStrips(RawData<double> *p_inputData)
+{
+	for(auto& cluster : m_culsterVector){
+		int position=cluster.m_seedPosition;
+		int oneLeft=position-1;
+		if(isInvalidChannelNumber(oneLeft)) cluster.m_charge1StripLeft = 0 ;
+		else cluster.m_charge1StripLeft = p_inputData->getSignal(oneLeft) ;
+
+		int twoLeft=oneLeft-1;
+		if(isInvalidChannelNumber(twoLeft)) cluster.m_charge2StripLeft = 0;
+		else cluster.m_charge2StripLeft = p_inputData->getSignal(twoLeft) ;
+
+		int oneRight=position+1;
+		if(isInvalidChannelNumber(oneRight)) cluster.m_charge1StripRight = 0 ;
+		else cluster.m_charge1StripRight = p_inputData->getSignal(oneRight) ;
+
+		int twoRight=oneRight+1;
+		if(isInvalidChannelNumber(twoRight)) cluster.m_charge2StripRight = 0;
+		else cluster.m_charge2StripRight = p_inputData->getSignal(twoRight) ;
+
+		/// normalize position
+		cluster.m_position/=abs(cluster.m_charge);
+	}
+}
+
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreator.h.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreator.h.svn-base
new file mode 100644
index 0000000..b7ab422
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreator.h.svn-base
@@ -0,0 +1,65 @@
+/*
+ * TbUTClusterCreator.h
+ *
+ *  Created on: Jan 5, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIClusterCreator.h"
+#include "TbUTITresholdProvider.h"
+
+namespace TbUT
+{
+
+class ClusterCreator: public IClusterCreator
+{
+public:
+	ClusterCreator(const std::string&  p_sensorType, ITresholdProvider& p_thresholds);
+	ClusterContainer::ClusterVector createClusters(RawData<double> *p_inputData);
+
+private:
+	 enum SensorType
+	   {
+	      P_TYPE,
+	      N_TYPE,
+	      CUSTOM
+	   };
+
+	typedef ClusterContainer::ClusterVector::iterator ClusterIterator;
+
+	void convertStringToSensorType(const std::string& p_sensorType);
+
+	void findCulsterSeeds(RawData<double> *p_inputData);
+	void removeDuplicatedSeeds(RawData<double> *p_inputData);
+	void extendClusterSeeds(RawData<double> *p_inputData);
+
+	bool isBiggerThanSeedThreshold(RawData<double>::DataType p_channelSignal, int p_channel) const;
+	Cluster createCluster(RawData<double> *p_inputData, int l_channelNumber) const;
+
+	bool arePartOfTheSameCluster(RawData<double>* p_inputData, ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const;
+	bool canBePartOfTheSameCluster(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const;
+
+	void extendCluster(ClusterIterator& p_clusterIt, RawData<double>* p_inputData);
+	void removeClusterSeedWithSmallerCharge(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt);
+	bool hasNotMaximumSize(ClusterIterator& p_clusterIt) const;
+	bool isStripNeedToBeAddedToCluster(ClusterIterator& p_clusterIt, RawData<double> *p_inputData,int p_stripShift, bool p_isCheckingLeft  ) const;
+	void updateCluster(ClusterIterator& p_clusterIt,RawData<double> *p_inputData ,int p_stripShift, bool p_isCheckingLeft);
+	bool isInvalidChannelNumber(int p_stripShift) const;
+	bool isBiggerThanLowThreshold(RawData<double>::DataType p_channelSignal, int p_chnnel) const;
+	void normalizeClusterPosition(ClusterIterator& p_clusterIt);
+	void fillOuterStrips(RawData<double> *p_inputData);
+
+
+
+	const int m_clusterMaxSize;
+	ITresholdProvider& m_thresholds;
+	ClusterContainer::ClusterVector m_culsterVector;
+	SensorType m_sensorType;
+
+};
+
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreatorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreatorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..e44ad04
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreatorAlgorithm.cpp.svn-base
@@ -0,0 +1,126 @@
+/*
+ * TbUTClusterCreatorAlgorithm.cpp
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreatorAlgorithm.h"
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,ClusterCreatorAlgorithm)
+
+ClusterCreatorAlgorithm::ClusterCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+GaudiAlgorithm(name, pSvcLocator),
+m_dataContainer(),
+m_data(),
+m_inputDataLocation(),
+m_outputDataLocation(),
+m_clusterCreatorOption(),
+m_noiseFile(),
+m_sensorType(),
+m_event(),
+m_skipEvent(),
+m_lowThreshold(),
+m_highThreshold(),
+m_zsThresholdProvider(m_noiseFile,m_lowThreshold,m_highThreshold),
+m_clusterCreatorFactory(m_sensorType,m_zsThresholdProvider),
+m_clusterCreator()
+{
+	declareProperty("InputDataLocation", m_inputDataLocation=TbUT::DataLocations::CMSTES);
+	declareProperty("OutputDataLocation", m_outputDataLocation=TbUT::DataLocations::Clusters_TES);
+	declareProperty("ClusterCreatorOption",m_clusterCreatorOption=TbUT::ClusterCreatorType::defaultCreator);
+	declareProperty("NoiseInputFile",m_noiseFile=TbUT::DataLocations::NoiseTreshold);
+	declareProperty("skippEventNumber",m_skipEvent=0);
+	declareProperty("sensorType",m_sensorType="PType");
+	declareProperty("LowThreshold",m_lowThreshold=3);
+	declareProperty("HighThreshold",m_highThreshold=4);
+}
+
+
+StatusCode ClusterCreatorAlgorithm::initialize()
+{
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildClusterCreator()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=retreiveNoise()) return StatusCode::FAILURE;
+
+	info()<<"Cluster thresholds (unit of noise multiplicity):"<<endmsg;
+	info()<<"Low:" <<m_lowThreshold <<endmsg;
+	info()<<"high:" <<m_highThreshold <<endmsg;
+
+	info()<<"Initialized successfully!"<<endmsg;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode ClusterCreatorAlgorithm::execute()
+{
+	if(m_event<m_skipEvent)
+	{
+		m_event++;
+		return StatusCode::SUCCESS;
+	}
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()){
+		ClusterContainer *l_clontainer=new ClusterContainer();
+		put(l_clontainer,m_outputDataLocation);
+		return StatusCode::SUCCESS;
+	}
+	processAndSaveDataToTES();
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode ClusterCreatorAlgorithm::finalize()
+{
+	return GaudiAlgorithm::finalize();
+}
+
+StatusCode ClusterCreatorAlgorithm::initializeBase()
+{
+	return GaudiAlgorithm::initialize();
+}
+
+StatusCode ClusterCreatorAlgorithm::buildClusterCreator()
+try{
+	m_clusterCreator=m_clusterCreatorFactory.createClusterCreator(m_clusterCreatorOption);
+	return StatusCode::SUCCESS;
+}catch(ClusterCreatorFactory::NoSuchState &exception)
+{
+	error()<<"Invalid ZS Engine Type  : "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+StatusCode ClusterCreatorAlgorithm::retreiveNoise()
+try{
+	m_zsThresholdProvider.retreiveTresholds();
+	return StatusCode::SUCCESS;
+}catch(ITresholdProvider::ThresholdProviderError &err){
+	error()<<"Cannot open Noise file: "<<err.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode ClusterCreatorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer <double> >(m_inputDataLocation);
+	if(!m_dataContainer){
+		error()<< " ==> There is no input data: "<< m_inputDataLocation <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+void ClusterCreatorAlgorithm::processAndSaveDataToTES()
+{
+	ClusterContainer *l_container=new ClusterContainer();
+	for(const auto& rawDataIt: m_dataContainer->getData()){
+		m_data=new RawData<double>(rawDataIt);
+		ClusterContainer::ClusterVector clusterVector=m_clusterCreator->createClusters(m_data);
+		l_container->addClusters(clusterVector);
+		l_container->setTDC(m_data->getTDC());
+		l_container->setTiemestamp(m_data->getTime());
+		delete m_data;
+	}
+	put(l_container,m_outputDataLocation);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreatorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreatorAlgorithm.h.svn-base
new file mode 100644
index 0000000..7d8a7ab
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreatorAlgorithm.h.svn-base
@@ -0,0 +1,57 @@
+/*
+ * TbUTClusterCreatorAlgorithm.h
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+#include "TbUTRawData.h"
+#include "TbUTClusterCreatorFactory.h"
+#include "TbUTTresholdProvider.h"
+#include "TbUTCluster.h"
+
+
+namespace TbUT
+{
+
+class ClusterCreatorAlgorithm :  public GaudiAlgorithm
+{
+public:
+	ClusterCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+	virtual StatusCode finalize();
+
+private:
+
+	StatusCode initializeBase();
+	StatusCode buildClusterCreator();
+	StatusCode retreiveNoise();
+
+	StatusCode getData();
+	void processAndSaveDataToTES();
+
+	RawDataContainer<double>* m_dataContainer;
+	RawData<double>* m_data;
+
+	std::string m_inputDataLocation;
+	std::string m_outputDataLocation;
+	std::string m_clusterCreatorOption;
+	std::string m_noiseFile;
+	std::string m_sensorType;
+	int m_event;
+	int m_skipEvent;
+	double m_lowThreshold;
+	double m_highThreshold;
+
+	TresholdProvider m_zsThresholdProvider;
+	ClusterCreatorFactory m_clusterCreatorFactory;
+	ClusterCreatorFactory::ClusterCreatorPtr m_clusterCreator;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreatorDataMonitorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreatorDataMonitorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..fec60a2
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreatorDataMonitorAlgorithm.cpp.svn-base
@@ -0,0 +1,248 @@
+/*
+ * TbUTClusterCreatorDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreatorDataMonitorAlgorithm.h"
+#include "TbUTRawData.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include <boost/format.hpp>
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,ClusterCreatorDataMonitorAlgorithm)
+
+ClusterCreatorDataMonitorAlgorithm::ClusterCreatorDataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ):
+		GaudiHistoAlg ( name , pSvcLocator ),
+		m_evtNumber(0),
+		m_skipEvent(0),
+		m_displayEventNumber(0),
+		m_inputDataLoc(TbUT::DataLocations::Clusters_TES),
+		m_sensorType()
+{
+    declareProperty("skippEventNumber", m_skipEvent=10);
+    declareProperty("displayEventNumber", m_displayEventNumber=10);
+    declareProperty("sensorType",m_sensorType="PType");
+
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::initialize() {
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	setHistoTopDir( const_cast<char*>("TbUT/") );
+	createHistograms();
+  	return StatusCode::SUCCESS;
+}
+
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::execute()
+{
+	if(m_evtNumber<m_skipEvent)
+		return skippEvent();
+	else
+		return fillHistograms();
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::finalize()
+{
+	return GaudiHistoAlg::finalize();
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::initializeBase()
+{
+	  return GaudiHistoAlg::initialize();
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::getData()
+{
+	if(!exist<ClusterContainer>(m_inputDataLoc)){
+		error()<< " ==> There is no input data: "<< m_inputDataLoc <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	m_clusters=get<ClusterContainer>(m_inputDataLoc);
+	if(!m_clusters){
+		error()<< " ==> Input data is Null!"<<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createHistograms()
+{
+	createClusterNumberPerEventHistogram();
+	createClusterNumberHistogram();
+	createClusterSizeHistogram();
+	createClusterChargeHistograms();
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterNumberPerEventHistogram()
+{
+	double l_xmin=0;
+	double l_xmax=6;
+	int l_nbin=6;
+	const std::string l_histogramName="ClusterNumberPerEvent";
+	const std::string l_histogramTitle="Cluster Number Per Event";
+	m_histogramClusterNumberPerEvent=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterNumberHistogram()
+{
+	double l_xmin=-0.5+RawData<>::getMinChannel();
+	double l_xmax=RawData<>::getMaxChannel()-0.5;
+	int l_nbin=RawData<>::getnChannelNumber();
+	std::string l_histogramName="ClusterNumber";
+	std::string l_histogramTitle="Cluster Number vs channel";
+	m_histogramClusterNumber=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterSeedPosition";
+	l_histogramTitle="Cluster Seed Position";
+	m_histogramClusterSeedPosition=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterSizeHistogram()
+{
+	double l_xmin=-0.5;
+	double l_xmax=5.5;
+	int l_nbin=20;
+	const std::string l_histogramName="ClusterSize";
+	const std::string l_histogramTitle="Cluster Size";
+	m_histogramClusterSize=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterChargeHistograms()
+{
+	double l_xmin;
+	double l_xmax;
+
+	if(m_sensorType=="PType"){
+		l_xmin=-1500.;
+		l_xmax=-1.;
+	}else if(m_sensorType=="NType"){
+		l_xmin=1.;
+		l_xmax=1500.;
+	}else{
+		l_xmin=-1500.;
+		l_xmax=1500.;
+	}
+
+	int l_nbin=100;
+	std::string l_histogramName="ClusterCharge";
+	std::string l_histogramTitle="Cluster Charge";
+	m_histogramClusterCharge=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterChargeSingleStrip";
+	l_histogramTitle="Cluster Charge Single Strip";
+	m_histogramClusterChargeSingleStrip=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterChargeDoubleStrip";
+	l_histogramTitle="Cluster Charge Double Strip";
+	m_histogramClusterChargeDoubleStrip=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterChargeTripleStrip";
+	l_histogramTitle="Cluster Charge Triple Strip";
+	m_histogramClusterChargeTripleStrip=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::skippEvent()
+{
+	m_evtNumber++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::fillHistograms()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_clusters->isEmpty())
+	{
+		m_histogramClusterNumberPerEvent->Fill(0.);
+		m_evtNumber++;
+		return StatusCode::SUCCESS;
+	}
+	auto l_clusters=m_clusters->getClusters();
+	fillClusterNumberHistogram(l_clusters);
+	fillClusterSizeHistogram(l_clusters);
+	fillClusterChargeHistograms(l_clusters);
+	if(m_evtNumber<m_displayEventNumber+m_skipEvent)fillEventsHistograms(l_clusters);
+	m_evtNumber++;
+	return StatusCode::SUCCESS;
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillClusterNumberHistogram(ClusterContainer::ClusterVector& p_clusters)
+{
+	m_histogramClusterNumberPerEvent->Fill(p_clusters.size());
+	for(const auto& l_cluster: p_clusters )
+	{
+		auto l_position=l_cluster.m_position;
+		l_position+=RawData<>::getMinChannel();
+		m_histogramClusterNumber->Fill(l_position);
+		auto l_seedPosition=l_cluster.m_seedPosition;
+		m_histogramClusterSeedPosition->Fill(l_seedPosition);
+	}
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillClusterSizeHistogram(ClusterContainer::ClusterVector& p_clusters)
+{
+	for(const auto& l_cluster: p_clusters ){
+		auto l_size=l_cluster.m_size;
+		m_histogramClusterSize->Fill(l_size);
+	}
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillClusterChargeHistograms(ClusterContainer::ClusterVector& p_clusters)
+{
+	using namespace std;
+	for(const auto& l_cluster: p_clusters )
+	{
+		auto l_charge=l_cluster.m_charge;
+		m_histogramClusterCharge->Fill(l_charge);
+		switch(l_cluster.m_size)
+		{
+		case 1:
+			m_histogramClusterChargeSingleStrip->Fill(l_charge);
+			break;
+		case 2:
+			m_histogramClusterChargeDoubleStrip->Fill(l_charge);
+			break;
+		case 3:
+			m_histogramClusterChargeTripleStrip->Fill(l_charge);
+			break;
+		}
+	}
+}
+
+
+void ClusterCreatorDataMonitorAlgorithm::fillEventsHistograms(ClusterContainer::ClusterVector& p_clusters)
+{
+	for(const auto& l_cluster: p_clusters )
+	{
+			auto l_position=l_cluster.m_position;
+			auto l_charge=l_cluster.m_charge;
+			auto l_size=l_cluster.m_size;
+
+			auto l_name=createSingleEventHistogramName("charge");
+			auto l_histogram=bookHistogram(l_name);
+			fillSingleEventHistogram(l_histogram,l_position,l_charge);
+
+			l_name=createSingleEventHistogramName("size");
+			l_histogram=bookHistogram(l_name);
+			fillSingleEventHistogram(l_histogram,l_position,l_size);
+		}
+}
+
+TH1D* ClusterCreatorDataMonitorAlgorithm::bookHistogram(const std::string& p_histogramName)
+{
+	return Gaudi::Utils::Aida2ROOT::aida2root(book1D( p_histogramName,	p_histogramName,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,RawData<>::getnChannelNumber() ));
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillSingleEventHistogram(TH1D* p_histogram, int p_channel, double p_value)
+{
+	p_histogram->SetBinContent(p_channel,p_value);
+}
+
+std::string ClusterCreatorDataMonitorAlgorithm::createSingleEventHistogramName(std::string p_HistogramType)
+{
+	using namespace boost;
+	boost::format l_histogramName("cluster_%s_event_%d");
+		l_histogramName % p_HistogramType % m_evtNumber;
+		return str(l_histogramName);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreatorDataMonitorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreatorDataMonitorAlgorithm.h.svn-base
new file mode 100644
index 0000000..fa528db
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreatorDataMonitorAlgorithm.h.svn-base
@@ -0,0 +1,67 @@
+/*
+ * TbUTClusterCreatorDataMonitorAlgorithm.h
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "GaudiAlg/GaudiHistoAlg.h"
+#include "TbUTCluster.h"
+#include <TH1D.h>
+
+namespace TbUT
+{
+
+class ClusterCreatorDataMonitorAlgorithm: public GaudiHistoAlg
+{
+public:
+	ClusterCreatorDataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute   ();
+	virtual StatusCode finalize  ();
+private:
+
+	virtual StatusCode getData();
+	virtual StatusCode initializeBase();
+	virtual void createHistograms();
+
+	virtual StatusCode skippEvent();
+	virtual StatusCode fillHistograms();
+	virtual void createClusterNumberPerEventHistogram();
+	virtual void createClusterNumberHistogram();
+	virtual void createClusterSizeHistogram();
+	virtual void createClusterChargeHistograms();
+
+	virtual void fillClusterNumberHistogram(ClusterContainer::ClusterVector& p_clusters);
+	virtual void fillClusterSizeHistogram(ClusterContainer::ClusterVector& p_clusters);
+	virtual void fillClusterChargeHistograms(ClusterContainer::ClusterVector& p_clusters);
+
+	virtual void  fillEventsHistograms(ClusterContainer::ClusterVector& p_clusters);
+	virtual TH1D* bookHistogram(const std::string& p_histogramName);
+	virtual void fillSingleEventHistogram(TH1D* p_histogram, int p_channel, double p_value);
+	virtual std::string createSingleEventHistogramName(std::string p_HistogramType);
+
+	int m_evtNumber;
+    int m_skipEvent;
+    int m_displayEventNumber;
+	std::string m_inputDataLoc;
+	std::string m_sensorType;
+
+	ClusterContainer* m_clusters;
+	TH1D* m_histogramClusterNumber;
+	TH1D* m_histogramClusterSeedPosition;
+	TH1D* m_histogramClusterNumberPerEvent;
+	TH1D* m_histogramClusterSize;
+	TH1D* m_histogramClusterCharge;
+	TH1D* m_histogramClusterChargeSingleStrip;
+	TH1D* m_histogramClusterChargeDoubleStrip;
+	TH1D* m_histogramClusterChargeTripleStrip;
+
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreatorFactory.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreatorFactory.cpp.svn-base
new file mode 100644
index 0000000..56d532a
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreatorFactory.cpp.svn-base
@@ -0,0 +1,26 @@
+/*
+ * TbUTClusterCreatorFactory.cpp
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreatorFactory.h"
+#include "TbUTClusterCreator.h"
+
+using namespace TbUT;
+
+
+ClusterCreatorFactory::ClusterCreatorFactory(const std::string&  p_sensorType, ITresholdProvider & p_tresholds):
+	m_sensorType(p_sensorType),
+	m_thresholdPrivder(p_tresholds)
+{
+}
+
+ClusterCreatorFactory::ClusterCreatorPtr ClusterCreatorFactory::createClusterCreator(const std::string& p_clusterCreatorType)
+{
+	if(p_clusterCreatorType == TbUT::ClusterCreatorType::defaultCreator)
+		return ClusterCreatorPtr(new ClusterCreator(m_sensorType,m_thresholdPrivder));
+	else
+		throw NoSuchState(p_clusterCreatorType);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTClusterCreatorFactory.h.svn-base b/TbUT/src/.svn/text-base/TbUTClusterCreatorFactory.h.svn-base
new file mode 100644
index 0000000..8749919
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTClusterCreatorFactory.h.svn-base
@@ -0,0 +1,45 @@
+/*
+ * TbUTClusterCreatorFactory.h
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "TbUTITresholdProvider.h"
+#include "TbUTIClusterCreator.h"
+
+namespace TbUT
+{
+
+namespace ClusterCreatorType
+{
+static const std::string& defaultCreator = "default";
+}
+
+class ClusterCreatorFactory
+{
+public:
+	typedef boost::shared_ptr<IClusterCreator> ClusterCreatorPtr;
+
+	ClusterCreatorFactory(const std::string&  p_sensorType, ITresholdProvider & p_tresholds);
+	ClusterCreatorPtr createClusterCreator(const std::string& p_clusterCreatorType);
+
+	class NoSuchState: public std::runtime_error
+	{
+	public:
+		NoSuchState(const std::string& p_errorMsg ):
+			std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+private:
+	const std::string&  m_sensorType;
+	ITresholdProvider& m_thresholdPrivder;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTCmsPerBeetle.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCmsPerBeetle.cpp.svn-base
new file mode 100644
index 0000000..dceb001
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCmsPerBeetle.cpp.svn-base
@@ -0,0 +1,71 @@
+//
+// Created by ja on 8/4/15.
+//
+
+#include "TbUTCmsPerBeetle.h"
+#include <iostream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+CmsPerBeetle::CmsPerBeetle(IChannelMaskProvider& p_masksProvider,double p_hitThreshold):
+        m_masksProvider(p_masksProvider),
+        m_channelNumber(RawData<>::getnChannelNumber()),
+		m_hitThreshold(p_hitThreshold)
+{
+	cout<<"create correlation per beetle"<<endl;
+	initializeCorrectionMap();
+}
+
+void CmsPerBeetle::initializeCorrectionMap()
+{
+	int channelPerBeetle=32;
+	for (int channel=0;channel<m_channelNumber;channel+=channelPerBeetle)
+		m_correctionPerBeetle.insert(std::make_pair(channel,0));
+}
+
+void CmsPerBeetle::processEvent(RawData<>* p_data, RawData<double> **p_output)
+{
+	calculateCorrection(p_data);
+	removeCM(p_data,p_output);
+}
+
+void CmsPerBeetle::calculateCorrection(RawData<>* p_inputData)
+{
+	int channelPerBeetle=32;
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		int usedChannels=0;
+		for(int channel=mapIt.first;channel<mapIt.first+channelPerBeetle;channel++)
+		{
+			auto signal=p_inputData->getSignal(channel);
+			if(!m_masksProvider.isMasked(channel) && abs(signal) <m_hitThreshold){
+				mapIt.second+=signal;
+				usedChannels++;
+			}
+		}
+		if(usedChannels) mapIt.second/=static_cast<double>(usedChannels);
+	}
+}
+
+void CmsPerBeetle::removeCM(RawData<>* p_data, RawData<double> **p_output)
+{
+	int channelPerBeetle=32;
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		for(int channel=mapIt.first;channel<mapIt.first+channelPerBeetle;channel++)
+		{
+			if(m_masksProvider.isMasked(channel)){
+				double signalMaskedChannel=0;
+				(*p_output)->setSignal(signalMaskedChannel);
+			}else{
+				double l_channelSignal=p_data->getSignal(channel)-mapIt.second;
+				(*p_output)->setSignal(l_channelSignal);
+			}
+		}
+
+	}
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTCmsPerBeetle.h.svn-base b/TbUT/src/.svn/text-base/TbUTCmsPerBeetle.h.svn-base
new file mode 100644
index 0000000..c97e836
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCmsPerBeetle.h.svn-base
@@ -0,0 +1,30 @@
+//
+// Created by ja on 8/4/15.
+//
+#pragma once
+
+#include "TbUTICommonModeSubtractor.h"
+#include "TbUTIChannelMaskProvider.h"
+
+#include <map>
+
+namespace TbUT
+{
+
+class CmsPerBeetle: public ICommonModeSubtractor
+{
+public:
+	CmsPerBeetle(IChannelMaskProvider& p_masksProvider,double p_hitThreshold);
+	void processEvent(RawData<>* p_data, RawData<double> **p_output);
+private:
+	void calculateCorrection(RawData<>* p_inputData);
+	void removeCM(RawData<>* p_data, RawData<double> **p_output);
+
+	void initializeCorrectionMap();
+	IChannelMaskProvider& m_masksProvider;
+	int m_channelNumber;
+	double m_hitThreshold;
+	std::map<int, double> m_correctionPerBeetle;
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..7826b0e
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorAlgorithm.cpp.svn-base
@@ -0,0 +1,159 @@
+/*
+ * TbUTCommonModeSubtractorAlgorithm.cpp
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCommonModeSubtractorAlgorithm.h"
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,CommonModeSubtractorAlgorithm)
+
+
+CommonModeSubtractorAlgorithm::CommonModeSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+		GaudiAlgorithm(name, pSvcLocator),
+		m_dataContainer(),
+		m_data(),
+		m_outputContainer(),
+		m_inputDataLocation(),
+		m_outputDataLocation(),
+		m_channelMaskInputLocation(),
+		m_CMSOption(),
+		m_noiseCalculatorType(),
+		m_noiseOutputLocation(),
+		m_event(0),
+		m_skipEvent(0),
+		m_channelMaskFileValidator(m_channelMaskInputLocation),
+		m_channelMaskProvider(m_channelMaskFileValidator),
+		m_SubtractorFactory(m_channelMaskProvider),
+		m_noiseCalculatorFactory(),
+		m_noiseCalculatorPtr()
+{
+	declareProperty("InputDataLocation", m_inputDataLocation=TbUT::DataLocations::PedestalTES);
+	declareProperty("OutputDataLocation", m_outputDataLocation=TbUT::DataLocations::CMSTES);
+	declareProperty("CMSType",m_CMSOption=TbUT::CMSType::Iteratively);
+	declareProperty("skippEventNumber",m_skipEvent=0);
+	declareProperty("ChannelMaskInputLocation", m_channelMaskInputLocation=TbUT::DataLocations::MaskLocation);
+	declareProperty("NoiseCalculatorType", m_noiseCalculatorType=TbUT::NoiseCalculatorType::calculator);
+	declareProperty("NoiseOutputFile", m_noiseOutputLocation=TbUT::DataLocations::NoiseTreshold);
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::initialize()
+{
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildSubtractorEngine()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildNoiseCalculator()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=retriveMasksFromFile()) return StatusCode::FAILURE;
+
+	info()<<"Initialized successfully my friend!"<<endmsg;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::execute()
+{
+	if(m_event<m_skipEvent)
+	{
+		return skippTreaningEvent();
+	}
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	m_outputContainer =new RawDataContainer<double>();
+
+	if(m_dataContainer->isEmpty()){
+		put(m_outputContainer,m_outputDataLocation);
+		return StatusCode::SUCCESS;
+	}
+
+	for(const auto& rawDataIt: m_dataContainer->getData()){
+		m_data=new RawData<>(rawDataIt);
+		processEvent();
+		delete m_data;
+	}
+	put(m_outputContainer,m_outputDataLocation);
+
+	return StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::finalize()
+{
+	if(StatusCode::SUCCESS !=saveNoiseToFile()) return StatusCode::FAILURE;
+	return GaudiAlgorithm::finalize();
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::initializeBase()
+{
+	  return GaudiAlgorithm::initialize();
+}
+
+StatusCode CommonModeSubtractorAlgorithm::buildSubtractorEngine()
+try{
+	m_CMSEnginePtr.reset(m_SubtractorFactory.createCMSubtractor(m_CMSOption));
+	return StatusCode::SUCCESS;
+}catch(CommonModeSubtractorFactory::NoSuchState &exception)
+{
+	error()<<"Invalid CommonMode Engine Type  : "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::buildNoiseCalculator()
+try{
+	m_noiseCalculatorPtr=m_noiseCalculatorFactory.createNoiseCalculator(m_noiseCalculatorType);
+	return StatusCode::SUCCESS;
+}catch(NoiseCalculatorFactory::NoSuchState &exception)
+{
+	error()<<"Invalid NoiseCalculator Type  : "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::retriveMasksFromFile()
+try{
+	m_channelMaskProvider.getMaskFromFile(m_channelMaskInputLocation);
+	return StatusCode::SUCCESS;
+}catch(ChannelMaskProvider::InputFileError  &exception)
+{
+	error()<<"Channel Mask File Input Error: "<<m_channelMaskInputLocation<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<>>(m_inputDataLocation);
+	if(!m_dataContainer){
+		error()<< " ==> There is no input data: "<< m_inputDataLocation <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+void CommonModeSubtractorAlgorithm::processEvent()
+{
+	RawData<double> *l_afterCMS= new RawData<double>();
+	m_CMSEnginePtr->processEvent(m_data,&l_afterCMS);
+	m_noiseCalculatorPtr->updateNoise(l_afterCMS);
+	m_outputContainer->addData(*l_afterCMS);
+	m_event++;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::skippTreaningEvent()
+{
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::saveNoiseToFile()
+try{
+	m_noiseCalculatorPtr->saveNoiseToFile(m_noiseOutputLocation);
+	return StatusCode::SUCCESS;
+}catch (Noise::NoiseCalculatorError & ex)
+{
+	error()<< ex.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorAlgorithm.h.svn-base
new file mode 100644
index 0000000..7987467
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorAlgorithm.h.svn-base
@@ -0,0 +1,73 @@
+/*
+ * TbUTCommonModeSubtractorAlgorithm.h
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+#include "TbUTRawData.h"
+#include "TbUTCommonModeSubtractorFactory.h"
+#include "TbUTChannelMaskProvider.h"
+#include "TbUTChannelMaskFileValidator.h"
+#include "TbUTNoiseCalculatorfactory.h"
+#include "TbUTNoise.h"
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+class CommonModeSubtractorAlgorithm : public GaudiAlgorithm
+{
+	typedef boost::shared_ptr<ICommonModeSubtractor> CMSubtractorPtr;
+public:
+	CommonModeSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+	virtual StatusCode finalize();
+private:
+
+	StatusCode initializeBase();
+	StatusCode buildSubtractorEngine();
+	StatusCode buildNoiseCalculator();
+	StatusCode retriveMasksFromFile();
+
+	StatusCode getData();
+	void processEvent();
+	StatusCode skippTreaningEvent();
+
+	StatusCode saveNoiseToFile();
+
+	RawDataContainer<>* m_dataContainer;
+	RawData<>* m_data;
+	RawDataContainer<double>* m_outputContainer;
+
+
+	std::string m_inputDataLocation;
+	std::string m_outputDataLocation;
+	std::string m_channelMaskInputLocation;
+	std::string m_CMSOption;
+	std::string m_noiseCalculatorType;
+	std::string m_noiseOutputLocation;
+
+	int m_event;
+	int m_skipEvent;
+
+	ChannelMaskFileValidator m_channelMaskFileValidator;
+	ChannelMaskProvider m_channelMaskProvider;
+	CommonModeSubtractorFactory m_SubtractorFactory;
+	CMSubtractorPtr m_CMSEnginePtr;
+	NoiseCalculatorFactory m_noiseCalculatorFactory;
+	NoiseCalculatorFactory::NoiseCalcualtorPtr m_noiseCalculatorPtr;
+
+};
+
+}
+
+
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..26a8c90
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp.svn-base
@@ -0,0 +1,201 @@
+/*
+ * TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Nov 26, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCommonModeSubtractorDataMonitorAlgorithm.h"
+#include "TbUTDataLocations.h"
+#include "TbUTRawData.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include <boost/format.hpp>
+
+using namespace TbUT;
+using namespace boost;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,CommonModeSubtractorDataMonitorAlgorithm)
+
+using namespace TbUT;
+
+CommonModeSubtractorDataMonitorAlgorithm::CommonModeSubtractorDataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : DataMonitorAlgorithm ( name , pSvcLocator ),
+	m_noise()
+{
+	DataMonitorAlgorithm::m_inputDataLoc=TbUT::DataLocations::CMSTES;
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::execute()
+{
+	DataMonitorAlgorithm::RunPhase l_runPhase=DataMonitorAlgorithm::getRunPhase();
+	switch(l_runPhase)
+	{
+	case SKIP:
+		return DataMonitorAlgorithm::skippEvent();
+	case SAVE_SINGLE_EVENTS:
+		return saveSimpleEvents();
+	default:
+	 	return fillOnly2DHistogram();
+	}
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<double> >(m_inputDataLoc);
+	if(!m_dataContainer){
+		error()<< "=> there is no input data in "<< m_inputDataLoc<<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::saveSimpleEvents()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	for(const auto& rawDataIt : m_dataContainer->getData() )
+	{
+		m_data=RawData<double>(rawDataIt);
+		storeEventIntoHistogram();
+		fillHistogram2D();
+		m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+TH2D * CommonModeSubtractorDataMonitorAlgorithm::bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	int l_ylow=-800;
+	int l_yhigh=800;
+	int l_ybin=1600;
+	return Gaudi::Utils::Aida2ROOT::aida2root(book2D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,p_sensorNumber,
+			l_ylow,l_yhigh,l_ybin ));
+}
+
+std::string CommonModeSubtractorDataMonitorAlgorithm::createHistogramTitle()
+{
+	boost::format l_histogramTitle("Data after CM Subtraction - event%1%");
+	l_histogramTitle% m_evtNumber;
+	return str(l_histogramTitle);
+}
+
+std::string CommonModeSubtractorDataMonitorAlgorithm::createHistogramName()
+{
+	boost::format l_histogramName("Data_after_CMS_event_%d");
+	l_histogramName % m_evtNumber;
+	return str(l_histogramName);
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::createHistogram2D()
+{
+	std::string l_histogramName="CMSData_vs_channel";
+	std::string l_histogramTtttle="Data after CMS vs channel";
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	m_histogram2D=bookHistogram2D(l_histogramName,l_histogramTtttle,l_sensorNum );
+	createNoiseHistograms();
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::fillOnly2DHistogram()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	const int storeNoiseFrequency=10000;
+	for(const auto& rawDataIt :m_dataContainer->getData() )
+	{
+		m_data=RawData<double>(rawDataIt);
+		m_noise.updateNoise(&(m_data));
+		if( 0 ==(DataMonitorAlgorithm::m_evtNumber%storeNoiseFrequency) ) fillNoiseHistograms();
+		fillHistogram2D();
+		DataMonitorAlgorithm::m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::fillHistogram2D()
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan = 0; chan <channelNumber; chan++ ){
+		auto channelSignal=m_data.getSignal(chan);
+		if(0!=channelSignal) // no need to push masked values
+			m_histogram2D->Fill(chan+RawData<>::getMinChannel(),channelSignal);
+	  }
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::fillHistogram(TH1D * p_histogram)
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan =0 ; chan <channelNumber; chan++ ){
+		p_histogram->SetBinContent(chan,m_data.getSignal(chan));
+	  }
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::finalize()
+{
+	DataMonitorAlgorithm::m_outpuProjectionHistogramName="ProjectionCommonMode";
+	return DataMonitorAlgorithm::finalize();
+}
+
+
+void CommonModeSubtractorDataMonitorAlgorithm::createNoiseHistograms()
+{
+	// This function is very ugly!
+	// should be refactored!
+ 	const int l_channelNumber=RawData<>::getnChannelNumber();
+	const int l_ylow=0;
+	const int l_yhigh=100;
+	const int l_ybin=10;
+	const int channelPerBeetle=32;
+	int sensorNumber=0;
+
+	for(int channel=0;channel<l_channelNumber ; channel++){
+		boost::format l_histogramName("Noise_channel_%d");
+		l_histogramName % channel;
+		m_noisePerChannelHistograms.insert(
+				std::make_pair(
+						channel,Gaudi::Utils::Aida2ROOT::aida2root(
+									book1D( l_histogramName.str(),	l_histogramName.str(),l_ybin, l_ylow, l_yhigh)
+								)
+				)
+		);
+		if( 0 == (channel%channelPerBeetle )){
+			l_histogramName= boost::format("Noise_beetle_%d");
+			l_histogramName % sensorNumber;
+			m_noisePerSensorHistograms.insert(
+					std::make_pair(
+							sensorNumber,Gaudi::Utils::Aida2ROOT::aida2root(
+										book1D( l_histogramName.str(),	l_histogramName.str(),l_ybin, l_ylow, l_yhigh)
+									)
+					)
+			);
+			sensorNumber++;
+		}
+
+	}
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::fillNoiseHistograms()
+{
+	m_noise.NormalizeNoise();
+	for(auto noiseHistogramIt:m_noisePerChannelHistograms){
+		noiseHistogramIt.second->Fill(m_noise.getNoise(noiseHistogramIt.first));
+	}
+
+	const int l_channelNumber=RawData<>::getnChannelNumber();
+	const int channelPerBeetle=32;
+	double meanNoisePerBeetle=0;
+	int sensorNumber=0;
+
+	for(int channel=0;channel<l_channelNumber ; channel++){
+		meanNoisePerBeetle+=m_noise.getNoise(channel);
+		if( 0 == (channel%channelPerBeetle )){
+			meanNoisePerBeetle/=static_cast<double>(channelPerBeetle);
+			m_noisePerSensorHistograms[sensorNumber]->Fill(meanNoisePerBeetle);
+			sensorNumber++;
+			meanNoisePerBeetle=0;// reset mean value
+		}
+	}
+	m_noise.Reset();
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorDataMonitorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorDataMonitorAlgorithm.h.svn-base
new file mode 100644
index 0000000..f3b8402
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorDataMonitorAlgorithm.h.svn-base
@@ -0,0 +1,56 @@
+/*
+ * TbUTCommonModeSubtractorDataMonitorAlgorithm.h
+ *
+ *  Created on: Nov 26, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTDataMonitorAlgorithm.h"
+#include "TbUTNoise.h"
+#include <map>
+
+namespace TbUT
+{
+
+class CommonModeSubtractorDataMonitorAlgorithm : public DataMonitorAlgorithm
+{
+public:
+	CommonModeSubtractorDataMonitorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+	StatusCode execute   ();
+	StatusCode finalize();
+
+private:
+	 typedef std::map<int, TH1D*> HistogramMap;
+
+	 StatusCode getData();
+
+	 StatusCode saveSimpleEvents();
+	 virtual StatusCode fillOnly2DHistogram();
+	 
+	 void createHistogram2D();
+	 TH2D * bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+	
+	 std::string createHistogramTitle();
+	 std::string createHistogramName();
+
+	 void fillHistogram2D();
+	 void fillHistogram(TH1D * p_histogram);
+
+	 void createNoiseHistograms();
+	 void fillNoiseHistograms();
+	
+	 TbUT::RawDataContainer<double> *m_dataContainer;
+  	 TbUT::RawData<double> m_data;
+
+	 Noise m_noise;
+
+	 HistogramMap m_noisePerChannelHistograms;
+	 HistogramMap m_noisePerSensorHistograms;
+
+
+};
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorFactory.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorFactory.cpp.svn-base
new file mode 100644
index 0000000..e6b74cf
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorFactory.cpp.svn-base
@@ -0,0 +1,30 @@
+/*
+ * TbUTCommonModeSubtractorFactory.cpp
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCommonModeSubtractorFactory.h"
+
+using namespace TbUT;
+
+
+CommonModeSubtractorFactory::CommonModeSubtractorFactory(IChannelMaskProvider& p_masksProvider):
+		m_masksProvider(p_masksProvider)
+{
+}
+
+ICommonModeSubtractor* CommonModeSubtractorFactory::createCMSubtractor(const std::string& p_CMSType)
+{
+	if(!p_CMSType.compare(TbUT::CMSType::Linear.c_str()))
+		return new CMSLinear(m_masksProvider);
+	else if (p_CMSType == TbUT::CMSType::Beetle){
+		double hitThreshold=160.;
+		return new CmsPerBeetle(m_masksProvider,hitThreshold);
+	}
+	else if(p_CMSType == TbUT::CMSType::Iteratively)
+		return new CMSIterativelyPerBeetle(m_masksProvider);
+	else
+		throw NoSuchState(p_CMSType);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorFactory.h.svn-base b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorFactory.h.svn-base
new file mode 100644
index 0000000..9a52c32
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTCommonModeSubtractorFactory.h.svn-base
@@ -0,0 +1,44 @@
+/*
+ * TbUTCommonModeSubtractorFactory.h
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTCMSLinear.h"
+#include "TbUTCmsPerBeetle.h"
+#include "TbUTCMSIterativelyPerBeetle.h"
+
+namespace TbUT
+{
+
+namespace CMSType
+{
+static const std::string& Iteratively="Iteratively";
+static const std::string& Beetle = "Beetle";
+static const std::string& Linear = "Linear";
+}
+
+class CommonModeSubtractorFactory
+{
+public:
+	CommonModeSubtractorFactory(IChannelMaskProvider& p_masksProvider);
+
+	ICommonModeSubtractor* createCMSubtractor(const std::string& p_CMSType);
+
+	class NoSuchState: public std::runtime_error
+	{
+	public:
+		NoSuchState(const std::string& p_errorMsg ):
+			std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+private:
+	IChannelMaskProvider& m_masksProvider;
+};
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTDataLocations.h.svn-base b/TbUT/src/.svn/text-base/TbUTDataLocations.h.svn-base
new file mode 100644
index 0000000..edece2c
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTDataLocations.h.svn-base
@@ -0,0 +1,30 @@
+/*
+ * TbUTDataLocations.h
+ *
+ *  Created on: Oct 11, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#pragma GCC diagnostic ignored "-Wunused-variable"
+
+#include <string>
+
+namespace TbUT
+{
+namespace DataLocations
+{
+//should be extended
+static const std::string& RawTES      	 		= "Tb/TbUT/Raw";
+static const std::string& HeaderTES                     = "Tb/TbUT/Header";
+static const std::string& PedestalTES 	 		= "Tb/TbUT/Pedestal";
+static const std::string& CMSTES      	 		= "Tb/TbUT/CMS";
+static const std::string& ZS_TES      	 		= "Tb/TbUT/ZS";
+static const std::string& Clusters_TES	 		= "Tb/TbUT/Clusters";
+static const std::string& KeplerCluster_TES	= "Tb/TbUT/KeplerClusters";
+
+static const std::string & MaskLocation      = "$KEPLERROOT/options/UT/ChannelMask_NO.dat";
+static const std::string & PedestalLocation  = "$KEPLERROOT/options/UT/Pedestal.dat";
+static const std::string & NoiseTreshold     = "$KEPLERROOT/options/UT/Noise.dat";
+}
+}
diff --git a/TbUT/src/.svn/text-base/TbUTDataMonitorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTDataMonitorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..607c4f1
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTDataMonitorAlgorithm.cpp.svn-base
@@ -0,0 +1,178 @@
+#include "TbUTDataMonitorAlgorithm.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include "GaudiKernel/AlgFactory.h" 
+#include <boost/format.hpp>
+
+using namespace TbUT;
+using namespace boost;
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,DataMonitorAlgorithm)
+
+
+DataMonitorAlgorithm::DataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : GaudiHistoAlg ( name , pSvcLocator ),
+	m_inputDataLoc(),
+	m_outpuProjectionHistogramName(),
+    m_displayEventNumber(0),
+    m_evtNumber(0),
+	m_skipEvent(0),
+	m_histogram2D()
+{
+    declareProperty("displayEventNumber", m_displayEventNumber=10);
+    declareProperty("skippEventNumber", m_skipEvent=0);
+
+}
+
+DataMonitorAlgorithm::~DataMonitorAlgorithm(){}
+
+StatusCode DataMonitorAlgorithm::initialize() {
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	setHistoTopDir( const_cast<char*>("TbUT/") );
+	createHistogram2D();
+  	return StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::execute()
+{
+	RunPhase l_runPhase=getRunPhase();
+	switch(l_runPhase)
+	{
+	case SKIP:
+		return skippEvent();
+	case SAVE_SINGLE_EVENTS:
+		return saveSimpleEvents();
+	default:
+	 	return fillOnly2DHistogram();
+	}
+}
+
+StatusCode DataMonitorAlgorithm::finalize()
+{
+	buildProjectionHistogram();
+	return GaudiHistoAlg::finalize();
+}
+
+StatusCode DataMonitorAlgorithm::initializeBase()
+{
+	  return GaudiHistoAlg::initialize();
+}
+
+
+void DataMonitorAlgorithm::createHistogram2D()
+{
+	std::string l_histogramName="RawData_vs_channel";
+	std::string l_histogramTtttle="RawData_vs_channel";
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	m_histogram2D=bookHistogram2D(l_histogramName,l_histogramTtttle,l_sensorNum );
+}
+
+StatusCode DataMonitorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<> >(m_inputDataLoc);
+	if(!m_dataContainer){
+		error()<< " ==> there is no input data in "<< m_inputDataLoc<<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::skippEvent()
+{
+	m_evtNumber++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::saveSimpleEvents()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	for(const auto& rawDataIt : m_dataContainer->getData() )
+	{
+		m_data=RawData<>(rawDataIt);
+		storeEventIntoHistogram();
+		fillHistogram2D();
+		m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::fillOnly2DHistogram()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	for(const auto& rawDataIt : m_dataContainer->getData() )
+	{
+		m_data=RawData<>(rawDataIt);
+		fillHistogram2D();
+		m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+void DataMonitorAlgorithm::storeEventIntoHistogram()
+{
+	std::string l_histName= createHistogramName();
+	std::string l_histTitle= createHistogramTitle();
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	TH1D* l_eventHist=bookHistogram(l_histName,l_histTitle, l_sensorNum );
+	fillHistogram(l_eventHist);
+}
+
+std::string DataMonitorAlgorithm::createHistogramName()
+{
+	boost::format l_histogramName("event %d");
+	l_histogramName % m_evtNumber;
+	return str(l_histogramName);
+}
+
+std::string DataMonitorAlgorithm::createHistogramTitle()
+{
+	boost::format l_histogramTitle("Raw Data - event%1%");
+	l_histogramTitle% m_evtNumber;
+	return str(l_histogramTitle);
+}
+
+TH1D * DataMonitorAlgorithm::bookHistogram(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	return Gaudi::Utils::Aida2ROOT::aida2root(book1D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,p_sensorNumber ));
+}
+
+void DataMonitorAlgorithm::fillHistogram(TH1D * p_histogram)
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan =0 ; chan <channelNumber; chan++ ){
+		p_histogram->SetBinContent(chan,m_data.getSignal(chan));
+	  }
+}
+
+TH2D * DataMonitorAlgorithm::bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	int l_ylow=-800;
+	int l_yhigh=800;
+	int l_ybin=1600;
+	return Gaudi::Utils::Aida2ROOT::aida2root(book2D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,p_sensorNumber,
+			l_ylow,l_yhigh,l_ybin ));
+}
+
+void DataMonitorAlgorithm::fillHistogram2D()
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan = 0; chan <channelNumber; chan++ ){
+		auto channelSignal=m_data.getSignal(chan);
+		if(0!=channelSignal) // no need to push masked values
+			m_histogram2D->Fill(chan+RawData<>::getMinChannel(),channelSignal);
+	  }
+}
+
+DataMonitorAlgorithm::RunPhase DataMonitorAlgorithm::getRunPhase()
+{
+	if(m_evtNumber< m_skipEvent) return SKIP;
+	if( m_evtNumber<m_displayEventNumber+m_skipEvent) return SAVE_SINGLE_EVENTS;
+	else return REST;
+}
+
+void DataMonitorAlgorithm::buildProjectionHistogram()
+{
+		m_histogram2D->ProjectionY(m_outpuProjectionHistogramName.c_str());
+}
diff --git a/TbUT/src/.svn/text-base/TbUTDataMonitorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTDataMonitorAlgorithm.h.svn-base
new file mode 100644
index 0000000..4a14ce3
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTDataMonitorAlgorithm.h.svn-base
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "GaudiAlg/GaudiHistoAlg.h"
+#include "TbUTRawData.h"
+#include <TH1D.h>
+#include <TH2D.h>
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT{
+
+class DataMonitorAlgorithm: public GaudiHistoAlg
+{
+public:
+	DataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+
+	virtual 	~DataMonitorAlgorithm();
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute   ();
+	virtual StatusCode finalize  ();
+
+protected:
+
+	enum RunPhase
+	{
+		SKIP,
+		SAVE_SINGLE_EVENTS,
+		REST
+	};
+
+  virtual StatusCode getData();
+  virtual StatusCode initializeBase();
+
+  virtual StatusCode skippEvent();
+  virtual StatusCode saveSimpleEvents();
+  virtual StatusCode fillOnly2DHistogram();
+
+
+  virtual	RunPhase getRunPhase();
+
+  virtual void createHistogram2D();
+  virtual void storeEventIntoHistogram();
+  virtual TH1D * bookHistogram(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+  virtual TH2D * bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+
+  virtual std::string createHistogramTitle();
+  virtual std::string createHistogramName();
+  virtual void fillHistogram(TH1D * p_histogram);
+  virtual void fillHistogram2D();
+  virtual void buildProjectionHistogram();
+
+
+
+  std::string m_inputDataLoc;
+  std::string m_outpuProjectionHistogramName;
+  int m_displayEventNumber;
+  int m_evtNumber;
+  int m_skipEvent;
+  TH2D* m_histogram2D;
+  TbUT::RawDataContainer<> *m_dataContainer;
+  TbUT::RawData<> m_data;
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTIChannelMaskProvider.h.svn-base b/TbUT/src/.svn/text-base/TbUTIChannelMaskProvider.h.svn-base
new file mode 100644
index 0000000..08ed957
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIChannelMaskProvider.h.svn-base
@@ -0,0 +1,22 @@
+/*
+ * TbUTIIChannelMaskProvider.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include <vector>
+#include <string>
+#include "TbUTDataLocations.h"
+
+
+namespace TbUT
+{
+class IChannelMaskProvider{
+public:
+	virtual ~IChannelMaskProvider(){};
+	virtual void getMaskFromFile(const std::string& p_filename=TbUT::DataLocations::MaskLocation)=0;
+	virtual bool isMasked(int p_channel)=0;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTIClusterCreator.h.svn-base b/TbUT/src/.svn/text-base/TbUTIClusterCreator.h.svn-base
new file mode 100644
index 0000000..bfe48d9
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIClusterCreator.h.svn-base
@@ -0,0 +1,34 @@
+/*
+ * TbUTIClusterCreator.h
+ *
+ *  Created on: Jan 5, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTCluster.h"
+#include "TbUTRawData.h"
+
+namespace TbUT
+{
+
+class IClusterCreator
+{
+public:
+	virtual ~IClusterCreator(){};
+	virtual ClusterContainer::ClusterVector createClusters(RawData<double> *p_inputData)=0;
+
+	class ClusterCreatorError: public std::runtime_error
+	{
+	public:
+		ClusterCreatorError(std::string &msg) :
+			std::runtime_error(msg)
+		{
+		}
+	};
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTICommonModeSubtractor.h.svn-base b/TbUT/src/.svn/text-base/TbUTICommonModeSubtractor.h.svn-base
new file mode 100644
index 0000000..8db5791
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTICommonModeSubtractor.h.svn-base
@@ -0,0 +1,23 @@
+/*
+ * TbUTICommonModeSubtractor.h
+ *
+ *  Created on: Nov 23, 2014
+ *      Author: ADendek
+ */
+#pragma once
+
+#include "TbUTIProcessingEngine.h"
+
+
+namespace TbUT
+{
+
+class ICommonModeSubtractor : public IProcessingEngine<int, double>
+{
+public:
+	virtual ~ICommonModeSubtractor(){};
+};
+
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTIDataReader.h.svn-base b/TbUT/src/.svn/text-base/TbUTIDataReader.h.svn-base
new file mode 100644
index 0000000..7e57d3d
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIDataReader.h.svn-base
@@ -0,0 +1,56 @@
+/*
+ * TbUTIDataReader.h
+ *
+ *  Created on: Oct 6, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTRawData.h"
+#include <stdexcept>
+#include <string>
+
+namespace TbUT
+{
+class IDataReader
+{
+public:
+
+	class InputFileError: public std::runtime_error
+	{
+	public:
+		InputFileError(std::string& msg) :
+				std::runtime_error(msg)
+		{
+		}
+	};
+
+	class ReadEventError: public std::runtime_error
+	{
+	public:
+		ReadEventError(std::string & ex) :
+				std::runtime_error(ex)
+		{
+		}
+	};
+
+	class NoMoreEvents: public std::runtime_error
+	{
+	public:
+		NoMoreEvents(std::string & ex) :
+				std::runtime_error(ex)
+		{
+		}
+	};
+
+
+	virtual ~IDataReader(){};
+	virtual void checkInput()=0;
+	virtual RawData<>* getEventData()=0;
+};
+
+}
+
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTIDataRetreiver.h.svn-base b/TbUT/src/.svn/text-base/TbUTIDataRetreiver.h.svn-base
new file mode 100644
index 0000000..85e8071
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIDataRetreiver.h.svn-base
@@ -0,0 +1,38 @@
+/*
+ * TbUTIDataRetreiver.h
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include <string>
+
+namespace TbUT
+{
+
+class IDataRetreiver
+{
+public:
+
+	virtual ~IDataRetreiver()
+	{
+	}
+	;
+	virtual void open(std::string & p_filename)=0;
+	virtual bool
+	valid()=0;
+	virtual int
+	read_event(std::string & error_code)=0;
+	virtual void
+	process_event()=0;
+	virtual double
+	time()=0;
+	virtual double
+	temp()=0;
+	virtual unsigned short
+	data(int i) =0;
+
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTIFileValidator.h.svn-base b/TbUT/src/.svn/text-base/TbUTIFileValidator.h.svn-base
new file mode 100644
index 0000000..cda16b3
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIFileValidator.h.svn-base
@@ -0,0 +1,20 @@
+/*
+ * TbUTIFileValidator.h
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include <string>
+
+namespace TbUT
+{
+class IFileValidator
+{
+public:
+	virtual ~IFileValidator(){};
+	virtual bool validateFile()=0;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTINoiseCalculator.h.svn-base b/TbUT/src/.svn/text-base/TbUTINoiseCalculator.h.svn-base
new file mode 100644
index 0000000..88d4072
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTINoiseCalculator.h.svn-base
@@ -0,0 +1,21 @@
+/*
+ * TbUTINoiseCalculator.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTRawData.h"
+
+namespace TbUT{
+
+class INoiseCalculator
+{
+public:
+	virtual ~INoiseCalculator(){};
+	virtual void updateNoise(RawData<double>* p_inputData)=0;
+	virtual void saveNoiseToFile(const std::string& p_filaname)=0;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTIPedestalFollowing.h.svn-base b/TbUT/src/.svn/text-base/TbUTIPedestalFollowing.h.svn-base
new file mode 100644
index 0000000..1ce5a79
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIPedestalFollowing.h.svn-base
@@ -0,0 +1,33 @@
+/*
+ * TbUTIPedestalFollowing.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTRawData.h"
+
+#include <vector>
+#include <string>
+
+namespace TbUT
+{
+class IPedestalFollowing
+{
+public:
+	virtual ~IPedestalFollowing(){};
+
+	virtual StatusCode processEvent(RawData<>* p_data)=0;
+	virtual void savePedestalToFile(const std::string& p_filename)=0;
+
+	class PedestalCalculatorError: public std::runtime_error
+		{
+		public:
+		PedestalCalculatorError(std::string &msg) :
+					std::runtime_error(msg)
+			{
+			}
+		};
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTIProcessingEngine.h.svn-base b/TbUT/src/.svn/text-base/TbUTIProcessingEngine.h.svn-base
new file mode 100644
index 0000000..a590ead
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTIProcessingEngine.h.svn-base
@@ -0,0 +1,19 @@
+/*
+ * TbUTIProcessingEngine.h
+ *
+ *  Created on: Oct 15, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTRawData.h"
+
+namespace TbUT
+{
+template<typename InputDataType = int , typename OutputDataType = int >
+class IProcessingEngine
+{
+public:
+	virtual ~IProcessingEngine(){};
+	virtual void processEvent(RawData<InputDataType>* p_data, RawData<OutputDataType> **p_output)=0;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTITresholdProvider.h.svn-base b/TbUT/src/.svn/text-base/TbUTITresholdProvider.h.svn-base
new file mode 100644
index 0000000..09667ec
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTITresholdProvider.h.svn-base
@@ -0,0 +1,35 @@
+/*
+ * TbUTIZSTresholdProvider.h
+ *
+ *  Created on: Nov 27, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+
+namespace TbUT
+{
+
+class ITresholdProvider
+{
+public:
+	virtual ~ITresholdProvider(){}
+	virtual void retreiveTresholds()=0;
+	virtual double getLowClusterThreshold(int p_channel)=0;
+	virtual double getHighClusterThreshold(int p_channel)=0;
+
+	class ThresholdProviderError: public std::runtime_error
+	{
+	public:
+		ThresholdProviderError(const std::string& p_errorMsg ):
+					std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTMambaDataReader.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTMambaDataReader.cpp.svn-base
new file mode 100644
index 0000000..a43caed
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTMambaDataReader.cpp.svn-base
@@ -0,0 +1,69 @@
+/*
+ * TbUTMamdaDataReader.cpp
+ *
+ *  Created on: Jun 24, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTMambaDataReader.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace std;
+
+MambaDataReader::MambaDataReader(std::string& p_fileName, IFileValidator& p_fileValidator, bool& p_isAType):
+				m_fileName(p_fileName),
+				m_fileValidator(p_fileValidator),
+				m_decoder(p_isAType)
+{
+}
+
+void MambaDataReader::checkInput()
+{
+	if( ! m_fileValidator.validateFile() ){
+		std::string errorMsg= "file validation error";
+		throw IDataReader::InputFileError(errorMsg);
+
+	}
+	if(! m_decoder.open(m_fileName.c_str())){
+		std::string errorMsg= "cannot open input file";
+		throw IDataReader::InputFileError(errorMsg);
+	}
+}
+
+RawData<>* MambaDataReader::getEventData()
+{
+	while(true){
+		if(m_decoder.eof()){
+			string l_errorMsg ="No more event!";
+			throw IDataReader::NoMoreEvents(l_errorMsg);
+		}
+		if(0==m_decoder.read_event()){
+			continue;
+		}
+		else break;
+	}
+	RawData<> *l_outputData=new RawData<>();
+	fillRawData(l_outputData);
+	return l_outputData;
+}
+
+void MambaDataReader::fillRawData(RawData<>* p_outputData)
+{
+	auto signalVector=m_decoder.ADC();
+	auto headerVector0=m_decoder.BHeader0();
+	auto headerVector1=m_decoder.BHeader1();
+	auto headerVector2=m_decoder.BHeader2();
+	auto headerVector3=m_decoder.BHeader3();
+	auto headerVector3P1=m_decoder.BHeader3P1();
+	auto headerVector3P2=m_decoder.BHeader3P2();
+	for( const auto& l_adc : signalVector) 	p_outputData->setSignal(l_adc);
+	for( const auto& l_hdr0 : headerVector0) 	p_outputData->setHeader0(l_hdr0);
+	for( const auto& l_hdr1 : headerVector1) 	p_outputData->setHeader1(l_hdr1);
+	for( const auto& l_hdr2 : headerVector2) 	p_outputData->setHeader2(l_hdr2);
+	for( const auto& l_hdr3 : headerVector3) 	p_outputData->setHeader3(l_hdr3);
+	for( const auto& l_hdr3P1 : headerVector3P1) 	p_outputData->setHeader3P1(l_hdr3P1);
+	for( const auto& l_hdr3P2 : headerVector3P2) 	p_outputData->setHeader3P2(l_hdr3P2);
+	p_outputData->setTime(m_decoder.TsTimestamp());
+	p_outputData->setTDC(m_decoder.TDC());
+}
diff --git a/TbUT/src/.svn/text-base/TbUTMambaDataReader.h.svn-base b/TbUT/src/.svn/text-base/TbUTMambaDataReader.h.svn-base
new file mode 100644
index 0000000..cce811c
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTMambaDataReader.h.svn-base
@@ -0,0 +1,43 @@
+/*
+ * TbUTMamdaDataReader.h
+ *
+ *  Created on: Jun 24, 2015
+ *      Author: ADendek
+ */
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include "TbUTIFileValidator.h"
+#include "TbUTRawData.h"
+#include "mamba/mamba_decoder.h"
+#include <string>
+#include <fstream>
+#include <vector>
+#include <map>
+
+
+
+namespace TbUT
+{
+
+class MambaDataReader: public IDataReader
+{
+public:
+	MambaDataReader(std::string& p_fileName, IFileValidator& p_fileValidator, bool& p_isAType );
+
+	void checkInput();
+	RawData<>* getEventData();
+
+
+private:
+	void fillRawData(RawData<>* p_outputData);
+
+	std::string& m_fileName;
+	IFileValidator& m_fileValidator;
+	mamba_decoder m_decoder;
+};
+
+
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTNTupleCreator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTNTupleCreator.cpp.svn-base
new file mode 100644
index 0000000..977f8ce
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNTupleCreator.cpp.svn-base
@@ -0,0 +1,233 @@
+
+#include "TbUTNTupleCreator.h"
+#include "GaudiKernel/AlgFactory.h"
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,NTupleCreator)
+
+
+NTupleCreator::NTupleCreator(const std::string& name, ISvcLocator* pSvcLocator):
+		GaudiTupleAlg(name, pSvcLocator),
+		m_eventNumber(0)
+{
+	  declareProperty("StoreEventNumber", m_storeEventNumber = 100);
+
+	  declareProperty("WriteRaw",       m_isRawWritten = true);
+	  declareProperty("WriteHeader",    m_isHeaderWritten = true);
+	  declareProperty("WritePedestal",  m_isPedestalWritten = true);
+	  declareProperty("WriteCMS",       m_isCMSWritten = true);
+	  declareProperty("WriteClusters",  m_isClusterWritten = true);
+
+	  declareProperty("RawLocation",      m_rawLocation = TbUT::DataLocations::RawTES );
+	  declareProperty("HeaderLocation",   m_headerLocation = TbUT::DataLocations::HeaderTES );
+	  declareProperty("PedestalLocation", m_pedestalLocation = TbUT::DataLocations::PedestalTES );
+	  declareProperty("CMSLocation",      m_cmsLocation = TbUT::DataLocations::CMSTES );
+	  declareProperty("ClusterLocation",  m_clusterLocation = TbUT::DataLocations::Clusters_TES );
+
+}
+
+StatusCode NTupleCreator::initialize()
+{
+	StatusCode sc = GaudiTupleAlg::initialize();
+	if (sc.isFailure()) return sc;
+	if(m_isRawWritten) bookRawData();
+	if(m_isHeaderWritten) bookHeaderData();
+	if(m_isPedestalWritten) bookPedestal();
+	if(m_isCMSWritten) bookCMS();
+	if(m_isClusterWritten) bookClusters();
+
+	return StatusCode::SUCCESS;
+}
+
+StatusCode NTupleCreator::execute()
+try{
+	if(m_eventNumber<m_storeEventNumber)
+	{
+		if(m_isRawWritten) fillRawData();
+		if(m_isHeaderWritten) fillHeaderData();
+		if(m_isPedestalWritten) fillPedestal();
+		if(m_isCMSWritten) fillCMS();
+		if(m_isClusterWritten) fillClusters();
+		m_eventNumber++;
+	}
+	return StatusCode::SUCCESS;
+}catch(DataError & err){
+	error()<<err.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+void NTupleCreator::bookRawData()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/RawData");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/RawData",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("rawData",RawData<>::getnChannelNumber(), m_rawSignal);
+}
+
+void NTupleCreator::bookHeaderData()
+{
+ 
+  const unsigned int maxHeaderContainerSize=16;
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/HeaderData");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/HeaderData",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("headerData0",maxHeaderContainerSize, m_header0Signal);
+	ntuple->addItem("headerData1",maxHeaderContainerSize, m_header1Signal);
+	ntuple->addItem("headerData2",maxHeaderContainerSize, m_header2Signal);
+	ntuple->addItem("headerData3",maxHeaderContainerSize, m_header3Signal);
+	ntuple->addItem("headerData3P1",maxHeaderContainerSize, m_header3P1Signal);
+	ntuple->addItem("headerData3P2",maxHeaderContainerSize, m_header3P2Signal);
+}
+
+void NTupleCreator::bookPedestal()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/Pedestal");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/Pedestal",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("pedestalData",RawData<>::getnChannelNumber(), m_pedestalSignal);
+}
+
+void NTupleCreator::bookCMS()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/CMS");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/CMS",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("cmsData",RawData<>::getnChannelNumber() ,m_cmsSignal);
+}
+
+void NTupleCreator::bookClusters()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/Clusters");
+	if (ntuple) return;
+
+	const unsigned int maxClusterContainerSize=10;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/Clusters",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("clusterNumberPerEvent",m_clusterNumberPerEvent);
+	ntuple->addItem("clustersTDC", m_tdc);
+	ntuple->addItem("timestamps", m_timestamp);
+
+	ntuple->addItem("clustersPosition",maxClusterContainerSize ,m_clusterPosition);
+	ntuple->addItem("clustersSeedPosition",maxClusterContainerSize ,m_clusterSeedPosition);
+
+	ntuple->addItem("clustersCharge",maxClusterContainerSize, m_clusterCharge);
+	ntuple->addItem("clustersSize",maxClusterContainerSize ,m_clusterSize);
+
+	ntuple->addItem("clustersSeedCharge",maxClusterContainerSize ,m_clusterSeedCharge);
+	ntuple->addItem("clustersCharge2StripLeft",maxClusterContainerSize ,m_clusterCharge2StripLeft);
+	ntuple->addItem("clustersCharge1StripLeft",maxClusterContainerSize ,m_clusterCharge1StripLeft);
+	ntuple->addItem("clustersCharge1StripRight",maxClusterContainerSize ,m_clusterCharge1StripRight);
+	ntuple->addItem("clustersCharge2StripRight",maxClusterContainerSize ,m_clusterCharge2StripRight);
+
+}
+
+void NTupleCreator::fillRawData()
+{
+	using namespace std;
+	RawDataContainer<>* dataContainer=getDataFromTES<>(m_rawLocation);
+	for(const auto& rawData : dataContainer->getData())// iterate over rawDatas
+	{
+		for(int channel=0;channel<RawData<>::getnChannelNumber();channel++){
+			m_rawSignal[channel]=rawData.getSignal(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/RawData");
+	}
+}
+void NTupleCreator::fillHeaderData()
+{
+  const unsigned int maxHeaderContainerSize=16;
+	RawDataContainer<>* dataContainer=getDataFromTES(m_rawLocation);
+	for(const auto& rawData : dataContainer->getData())// iterate over rawDatas
+	{
+		for(unsigned int channel=0;channel<maxHeaderContainerSize;channel++){
+			m_header0Signal[channel]=rawData.getHeader0(channel);
+			m_header1Signal[channel]=rawData.getHeader1(channel);
+			m_header2Signal[channel]=rawData.getHeader2(channel);
+			m_header3Signal[channel]=rawData.getHeader3(channel);
+			m_header3P1Signal[channel]=rawData.getHeader3P1(channel);
+			m_header3P2Signal[channel]=rawData.getHeader3P2(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/HeaderData");
+	}
+}
+
+void NTupleCreator::fillPedestal()
+{
+	RawDataContainer<>* dataContainer=getDataFromTES<>(m_pedestalLocation);
+	for(const auto& data: dataContainer->getData()) // iterate over rawDatas
+	{
+		for(int channel=0;channel<RawData<>::getnChannelNumber();channel++){
+			m_pedestalSignal[channel]=data.getSignal(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/Pedestal");
+	}
+}
+
+void NTupleCreator::fillCMS()
+{
+	RawDataContainer<double>* dataContainer=getDataFromTES<double>(m_cmsLocation);
+	for(const auto& cmsData:  dataContainer->getData())// iterate over rawDatas
+	{
+		for(int channel=0;channel<RawData<>::getnChannelNumber();channel++){
+			m_cmsSignal[channel]=cmsData.getSignal(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/CMS");
+	}
+}
+template <typename DATA_TYPE>
+RawDataContainer<DATA_TYPE>* NTupleCreator::getDataFromTES(const std::string& p_location)
+{
+	RawDataContainer<DATA_TYPE>* dataContainer=getIfExists<RawDataContainer<DATA_TYPE> >(p_location);
+	if(!dataContainer){
+		std::string errorMsg="There is no data in: " +p_location;
+		throw DataError(errorMsg);
+	}
+	return  dataContainer;
+}
+
+ClusterContainer* NTupleCreator::getClustersFromTES()
+{
+	ClusterContainer* clusterContainer=getIfExists<ClusterContainer>(m_clusterLocation);
+	if(!clusterContainer){
+		std::string errorMsg="There is no clusters in: " +m_clusterLocation;
+		throw DataError(errorMsg);
+	}
+	return  clusterContainer;
+}
+
+void NTupleCreator::fillClusters()
+{
+	ClusterContainer* clusterContainer=getClustersFromTES();
+	m_tdc=clusterContainer->getTDC();
+	m_timestamp=clusterContainer->getTimestamp();
+	if(clusterContainer->isEmpty()){
+		m_clusterNumberPerEvent=0;
+		ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/Clusters");
+		return;
+	}
+	int clusterPerEvent=clusterContainer->size();
+	m_clusterNumberPerEvent=clusterPerEvent;
+	const unsigned int maxClusterContainerSize=10;
+	unsigned int clusterCounter=0;
+	for(const auto& cluster: clusterContainer->getClusters())
+	{
+		m_clusterSize[clusterCounter]=cluster.m_size;
+		m_clusterCharge[clusterCounter]=cluster.m_charge;
+		m_clusterPosition[clusterCounter]=cluster.m_position;
+		m_clusterSeedPosition[clusterCounter]=cluster.m_seedPosition;
+		m_clusterSeedCharge[clusterCounter]=cluster.m_chargeSeed;
+		m_clusterCharge2StripLeft[clusterCounter]=cluster.m_charge2StripLeft;
+		m_clusterCharge1StripLeft[clusterCounter]=cluster.m_charge1StripLeft;
+		m_clusterCharge2StripRight[clusterCounter]=cluster.m_charge2StripRight;
+		m_clusterCharge1StripRight[clusterCounter]=cluster.m_charge1StripRight;
+		clusterCounter++;
+		if(clusterCounter>=maxClusterContainerSize) break;
+	}
+	ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/Clusters");
+}
diff --git a/TbUT/src/.svn/text-base/TbUTNTupleCreator.h.svn-base b/TbUT/src/.svn/text-base/TbUTNTupleCreator.h.svn-base
new file mode 100644
index 0000000..709d01f
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNTupleCreator.h.svn-base
@@ -0,0 +1,88 @@
+
+#pragma once
+
+#include "GaudiAlg/GaudiTupleAlg.h"
+#include "TbUTRawData.h"
+#include "TbUTCluster.h"
+
+#include <string>
+#include <stdexcept>
+
+
+namespace TbUT
+{
+class NTupleCreator : public GaudiTupleAlg {
+
+	class DataError: public std::runtime_error
+	{
+	public:
+		DataError(const std::string& err) :
+			std::runtime_error(err)
+		{
+		}
+	};
+
+ public:
+	NTupleCreator(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+
+ private:
+	void bookRawData();
+        void bookHeaderData();
+	void bookPedestal();
+	void bookCMS();
+	void bookClusters();
+
+
+	void fillRawData();
+        void fillHeaderData();
+	void fillPedestal();
+	void fillCMS();
+	void fillClusters();
+	template <typename DATA_TYPE = int>
+	RawDataContainer<DATA_TYPE>* getDataFromTES(const std::string& p_location);
+	ClusterContainer* getClustersFromTES();
+
+	int m_eventNumber;
+	int m_storeEventNumber;
+	bool m_isRawWritten;
+        bool m_isHeaderWritten;
+	bool m_isPedestalWritten;
+	bool m_isCMSWritten;
+	bool m_isClusterWritten;
+
+	std::string m_rawLocation;
+	std::string m_pedestalLocation;
+	std::string m_cmsLocation;
+	std::string m_clusterLocation;
+	std::string m_headerLocation;
+ 
+	NTuple::Array<double> m_rawSignal;
+	NTuple::Array<double> m_header0Signal;
+	NTuple::Array<double> m_header1Signal;
+	NTuple::Array<double> m_header2Signal;
+	NTuple::Array<double> m_header3Signal;
+	NTuple::Array<double> m_header3P1Signal;
+	NTuple::Array<double> m_header3P2Signal;
+	NTuple::Array<double> m_pedestalSignal;
+	NTuple::Array<double> m_cmsSignal;
+
+	NTuple::Item<int> m_clusterNumberPerEvent;
+	NTuple::Item<unsigned int> m_tdc;
+	NTuple::Item<unsigned long long> m_timestamp;
+
+	NTuple::Array<double> m_clusterPosition;
+	NTuple::Array<int> m_clusterSize;
+	NTuple::Array<int> m_clusterSeedPosition;
+	NTuple::Array<double> m_clusterCharge;
+	NTuple::Array<double> m_clusterSeedCharge;
+	NTuple::Array<double> m_clusterCharge2StripLeft;
+	NTuple::Array<double> m_clusterCharge1StripLeft;
+	NTuple::Array<double> m_clusterCharge2StripRight;
+	NTuple::Array<double> m_clusterCharge1StripRight;
+
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTNoise.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTNoise.cpp.svn-base
new file mode 100644
index 0000000..b196449
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoise.cpp.svn-base
@@ -0,0 +1,126 @@
+/*
+ * TbUTNoise.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoise.h"
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <fstream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+Noise::Noise():
+		m_hitLimit(160)
+{
+	Reset();
+}
+
+void Noise::updateNoise(RawData<double>* p_inputData)
+{
+	int l_channelNumber =RawData<>::getnChannelNumber();
+	const int channelPerBeetle=32;
+	for(int channel=0;channel<l_channelNumber;channel++)
+	{
+		if(0 == (channel%channelPerBeetle) ) m_hitLimit= calcualteHitThreshold(p_inputData, channel);
+		int signal=p_inputData->getSignal(channel);
+		if(abs(signal)<m_hitLimit){
+			double signalSquare=signal*signal;
+			m_noiseVector[channel]+=signalSquare;
+			m_channelEnties[channel]++;
+			m_meanVector[channel]+=signal;
+		}
+	}
+}
+
+void Noise::saveNoiseToFile(const std::string& p_filename)
+{
+	ofstream l_file(p_filename);
+	if(!l_file.good())
+	{
+		std::string l_errorMsg="Saving Noise to file- Cannot open output file: "+p_filename;
+		throw  NoiseCalculatorError(l_errorMsg);
+	}
+	NormalizeNoise();
+	int l_channelsNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelsNumber;channel++)
+	{
+		auto l_noise=m_noiseVector[channel];
+		l_file<<std::to_string(l_noise)<<" ";
+	}
+	l_file.close();
+}
+
+void Noise::retreiveNoiseFromFile(const std::string& p_filename)
+{
+		int l_channelsNumber=RawData<>::getnChannelNumber();
+		ifstream l_file(p_filename);
+		if(!l_file.good()){
+			std::string l_errorMsg="Cannot open input noise file: "+p_filename;
+			throw NoiseCalculatorError(l_errorMsg);
+		}
+
+		for(int channel=0;channel<l_channelsNumber;channel++)
+		{
+			double l_noiseFromFile=0;
+			l_file >> l_noiseFromFile;
+			m_noiseVector[channel]=l_noiseFromFile;
+			cout<<"NoiseRetreiver===> channel: "<< channel <<"noise: "<<l_noiseFromFile<<endl;
+		}
+
+}
+
+double Noise::calcualteHitThreshold(RawData<double>* p_inputData,int channelBegin) const
+{
+	const int channelPerBeetle=32;
+	double rms=0;
+	double mean=0;
+	const double initialHitLimit=160;
+	int usedChannel=0;
+
+	for (int channel=channelBegin;channel<channelBegin+channelPerBeetle;channel++)
+	{
+		auto channelSignal=p_inputData->getSignal(channel);
+		if( (0. != channelSignal ) && (abs(channelSignal)<initialHitLimit) ){
+			rms+=channelSignal*channelSignal;
+			mean+=channelSignal;
+			usedChannel++;
+		}
+
+	}
+	if(usedChannel) rms/=static_cast<double>(usedChannel);
+	if(usedChannel) mean/=static_cast<double>(usedChannel);
+	rms-=mean*mean;
+	double rmsMultiplicity=4;
+	return rmsMultiplicity*sqrt(rms);
+}
+
+
+void Noise::NormalizeNoise()
+{
+	int l_channelsNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelsNumber;channel++)
+		{
+			auto normalizationFactor=m_channelEnties[channel];
+			if(normalizationFactor)m_noiseVector[channel]/= static_cast<double>(normalizationFactor);
+			if(normalizationFactor)m_meanVector[channel]/=static_cast<double>(normalizationFactor);
+			m_noiseVector[channel]-=m_meanVector[channel]*m_meanVector[channel];
+			m_noiseVector[channel]=sqrt(m_noiseVector[channel]);
+		}
+}
+
+void Noise::Reset()
+{
+	int l_initialValue=0;
+	int l_sensorNumber=RawData<>::getnChannelNumber();
+	m_channelEnties=ChannelEntries(l_sensorNumber,l_initialValue);
+	m_noiseVector=NoiseVector(l_sensorNumber,l_initialValue);
+	m_meanVector=NoiseVector(l_sensorNumber,l_initialValue);
+
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTNoise.h.svn-base b/TbUT/src/.svn/text-base/TbUTNoise.h.svn-base
new file mode 100644
index 0000000..6dadf74
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoise.h.svn-base
@@ -0,0 +1,51 @@
+/*
+ * TbUTNoise.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTRawData.h"
+#include <vector>
+
+
+namespace TbUT
+{
+
+class Noise
+{
+	typedef std::vector<double> NoiseVector;
+	typedef std::vector<int> ChannelEntries;
+public:
+	Noise();
+	void updateNoise(RawData<double>* p_inputData);
+	void saveNoiseToFile(const std::string& p_filename);
+	void retreiveNoiseFromFile(const std::string& p_filename);
+
+	double calcualteHitThreshold(RawData<double>* p_inputData, int channelBegin) const;
+
+	double getNoise(int p_channel) const{return m_noiseVector[p_channel];}
+	double operator[](int p_channel) const {return getNoise(p_channel);}
+
+	void NormalizeNoise();
+	void Reset();
+
+	class NoiseCalculatorError: public std::runtime_error
+	{
+	public:
+		NoiseCalculatorError(std::string &msg) :
+					std::runtime_error(msg)
+			{
+			}
+		};
+
+private:
+
+	int m_hitLimit;
+	ChannelEntries m_channelEnties;
+	NoiseVector m_noiseVector;
+	NoiseVector m_meanVector;
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTNoiseCalculator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTNoiseCalculator.cpp.svn-base
new file mode 100644
index 0000000..e9be375
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoiseCalculator.cpp.svn-base
@@ -0,0 +1,26 @@
+/*
+ * TbUTNoiseCalculator.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoiseCalculator.h"
+
+using namespace TbUT;
+
+
+NoiseCalculator::NoiseCalculator()
+{
+}
+
+void NoiseCalculator::updateNoise(RawData<double>* p_inputData)
+{
+	m_noise.updateNoise(p_inputData);
+}
+
+void NoiseCalculator::saveNoiseToFile(const std::string& p_filaname)
+{
+	m_noise.saveNoiseToFile(p_filaname);
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTNoiseCalculator.h.svn-base b/TbUT/src/.svn/text-base/TbUTNoiseCalculator.h.svn-base
new file mode 100644
index 0000000..f3be86d
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoiseCalculator.h.svn-base
@@ -0,0 +1,29 @@
+/*
+ * TbUTNoiseCalculator.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTINoiseCalculator.h"
+#include "TbUTNoise.h"
+
+
+namespace TbUT
+{
+
+class NoiseCalculator: public INoiseCalculator
+{
+public:
+	NoiseCalculator();
+	void updateNoise(RawData<double>* p_inputData);
+	void saveNoiseToFile(const std::string& p_filaname);
+
+private:
+	Noise m_noise;
+
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTNoiseCalculatorFake.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorFake.cpp.svn-base
new file mode 100644
index 0000000..96e7fc2
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorFake.cpp.svn-base
@@ -0,0 +1,26 @@
+/*
+ * TbUTNoiseCalculatorFake.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoiseCalculatorFake.h"
+
+using namespace TbUT;
+
+
+NoiseCalculatorFake::NoiseCalculatorFake()
+{
+
+}
+
+void NoiseCalculatorFake::updateNoise(RawData<double>* /*p_inputData*/)
+{
+
+}
+
+void NoiseCalculatorFake::saveNoiseToFile(const std::string& /*p_filename*/)
+{
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTNoiseCalculatorFake.h.svn-base b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorFake.h.svn-base
new file mode 100644
index 0000000..db3497d
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorFake.h.svn-base
@@ -0,0 +1,24 @@
+/*
+ * TbUTNoiseCalculatorFake.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTINoiseCalculator.h"
+
+namespace TbUT
+{
+
+class NoiseCalculatorFake: public INoiseCalculator
+{
+public:
+	NoiseCalculatorFake();
+	void updateNoise(RawData<double>* p_inputData);
+	void saveNoiseToFile(const std::string& p_filaname);
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTNoiseCalculatorfactory.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorfactory.cpp.svn-base
new file mode 100644
index 0000000..f76fc13
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorfactory.cpp.svn-base
@@ -0,0 +1,29 @@
+/*
+ * TbUTNoiseCalculatorfactory.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoiseCalculatorfactory.h"
+#include "TbUTNoiseCalculator.h"
+#include "TbUTNoiseCalculatorFake.h"
+
+
+using namespace TbUT;
+
+
+NoiseCalculatorFactory::NoiseCalculatorFactory()
+{
+}
+
+NoiseCalculatorFactory::NoiseCalcualtorPtr NoiseCalculatorFactory::createNoiseCalculator(const std::string& p_noiseCalculatorType)
+{
+	if(p_noiseCalculatorType==TbUT::NoiseCalculatorType::calculator)
+		return NoiseCalcualtorPtr(new NoiseCalculator());
+	else if (p_noiseCalculatorType ==TbUT::NoiseCalculatorType::fake)
+		return NoiseCalcualtorPtr(new NoiseCalculatorFake());
+
+	else
+		throw NoSuchState(p_noiseCalculatorType);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTNoiseCalculatorfactory.h.svn-base b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorfactory.h.svn-base
new file mode 100644
index 0000000..6a1c058
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTNoiseCalculatorfactory.h.svn-base
@@ -0,0 +1,41 @@
+/*
+ * TbUTNoiseCalculatorfactory.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+#pragma once
+
+#include "TbUTINoiseCalculator.h"
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+namespace NoiseCalculatorType
+{
+static const std::string& calculator="calculator";
+static const std::string& fake="fake";
+}
+
+class NoiseCalculatorFactory
+{
+public:
+	typedef boost::shared_ptr<INoiseCalculator> NoiseCalcualtorPtr;
+	NoiseCalculatorFactory();
+	NoiseCalcualtorPtr createNoiseCalculator(const std::string& p_noiseCalculatorType);
+
+	class NoSuchState: public std::runtime_error
+		{
+		public:
+			NoSuchState(const std::string& p_errorMsg ):
+				std::runtime_error(p_errorMsg)
+			{
+			}
+		};
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTPedestal.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestal.cpp.svn-base
new file mode 100644
index 0000000..1291d0c
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestal.cpp.svn-base
@@ -0,0 +1,48 @@
+/*
+ * TbUTPedestal.cpp
+ *
+ *  Created on: Dec 31, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestal.h"
+#include <boost/assign/list_of.hpp>
+#include <boost/foreach.hpp>
+
+
+using namespace TbUT;
+using namespace std;
+
+Pedestal::Pedestal():
+		m_normalization(1024),
+		m_isNormalized(false)
+{
+	int l_initialValue=0*m_normalization;// temporary change. until initial value of the pedestal stabilize
+	int l_sensorNumber=RawData<>::getnChannelNumber();
+	m_pedestals=DataVector(l_sensorNumber,l_initialValue);
+}
+
+int Pedestal::getPedestal(int p_channel)
+{
+	//normalizePedestals();
+	return m_pedestals[p_channel];
+}
+
+void Pedestal::setPedestal(int p_channel, int p_value)
+{
+	m_pedestals[p_channel]=p_value;
+}
+
+void Pedestal::normalizePedestals()
+{
+	if(!m_isNormalized){
+		int i=0;
+		BOOST_FOREACH(auto& l_pedestal, m_pedestals)
+		{
+			l_pedestal/=m_normalization;
+			cout<<"channel: "<<i<<" pedestal: " <<l_pedestal<<endl;
+			i++;
+			m_isNormalized=true;
+		}
+	}
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestal.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestal.h.svn-base
new file mode 100644
index 0000000..60b0755
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestal.h.svn-base
@@ -0,0 +1,43 @@
+/*
+ * TbUTPedestal.h
+ *
+ *  Created on: Dec 31, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTRawData.h"
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/vector.hpp>
+#include <iostream>
+
+
+namespace TbUT
+{
+
+class Pedestal
+{
+	typedef std::vector<int> DataVector;
+
+public:
+	Pedestal();
+	 void setPedestal(int p_channel, int p_value);
+	 int  getPedestal(int p_channel);
+	 int & operator[](size_t el) {return m_pedestals[el];}
+	 DataVector& getPedestalVector()
+	 {
+		 normalizePedestals();
+		 return m_pedestals;
+	 }
+	 void normalizePedestals();
+	 void setNormalizationFlag(bool p_flag){m_isNormalized=p_flag;}
+private:
+
+	int m_normalization;
+	bool m_isNormalized;
+	DataVector m_pedestals;
+
+};
+
+} /* namespace TbUT */
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalCalculator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalCalculator.cpp.svn-base
new file mode 100644
index 0000000..121187e
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalCalculator.cpp.svn-base
@@ -0,0 +1,118 @@
+/*
+ * TbUTPedestalCalculator.cpp
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalCalculator.h"
+#include <boost/serialization/serialization.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <fstream>
+
+
+using namespace TbUT;
+using namespace std;
+
+PedestalCalculator::PedestalCalculator(IChannelMaskProvider& p_maskProvider, Pedestal & p_pedestal):
+		m_maskProvider(p_maskProvider),
+		m_pedestal(p_pedestal),
+		m_normalization(1024),
+		m_event(0),
+		m_calculateInitialValueEvents(100)
+{
+}
+
+void PedestalCalculator::savePedestalToFile(const std::string& p_filename)
+{
+	ofstream l_file(p_filename);
+	if(!l_file.good())
+	{
+		std::string l_errorMsg="Saving Pedestal to file- Cannot open output file: "+p_filename;
+		throw  PedestalCalculatorError(l_errorMsg);
+	}
+	BOOST_FOREACH(auto l_pedestal, m_pedestal.getPedestalVector())
+	{
+		l_file<<std::to_string(l_pedestal)<<" ";
+	}
+	l_file.close();
+}
+
+StatusCode PedestalCalculator::processEvent(RawData<>* p_data)
+{
+	RunPhase l_runPhase=getRunPhase();
+	switch(l_runPhase)
+	{
+		case CALCULATE_INITIAL_VALUE:
+			return	calculateInitialValue(p_data);
+		case NORMALIZE_INITIAL_VALUE:
+			return normalizeInitialValue();
+		case CALUCLATE_PEDESTAL:
+			return calculaPedestal(p_data);
+		default:
+			string l_errorMsg="No such Phase!";
+			throw  PedestalCalculatorError(l_errorMsg);
+	}
+}
+
+PedestalCalculator::RunPhase PedestalCalculator::getRunPhase() const
+{
+	if(m_event<m_calculateInitialValueEvents)
+		return	CALCULATE_INITIAL_VALUE;
+	else if (m_event==m_calculateInitialValueEvents)
+		return NORMALIZE_INITIAL_VALUE;
+	else
+		return CALUCLATE_PEDESTAL;
+}
+
+StatusCode PedestalCalculator::calculateInitialValue(RawData<>* p_data)
+{
+	RawData<>::SignalVector l_inputData=p_data->getSignal();
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelNumber;channel++)
+		m_pedestal[channel]+=l_inputData[channel]*m_normalization;
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalCalculator::normalizeInitialValue()
+{
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelNumber;channel++){
+		m_pedestal[channel]/=m_calculateInitialValueEvents;
+		std::cout<<"Initial value of the Pedestal: channel " << channel << " value: "<<m_pedestal[channel]<< std::endl;
+	}
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalCalculator::calculaPedestal(RawData<>* p_data)
+{
+	RawData<>::SignalVector l_inputData=p_data->getSignal();
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelNumber;channel++)
+		m_pedestal[channel]+=calculateUpdate(channel, l_inputData);
+	m_event++;
+
+	return StatusCode::SUCCESS;
+}
+
+double PedestalCalculator::calculateUpdate(int p_channel, RawData<>::SignalVector&  p_data )
+{
+	double l_update=0;
+	double l_saturation=15;
+	if(m_maskProvider.isMasked(p_channel))
+		l_update=0;
+	else
+	{
+		l_update=p_data[p_channel]-(m_pedestal[p_channel]/m_normalization);
+		if(l_update>l_saturation)l_update=l_saturation;
+		else if (l_update <(-1)*l_saturation) l_update=(-1)*l_saturation;
+	}
+	return l_update;
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalCalculator.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalCalculator.h.svn-base
new file mode 100644
index 0000000..cc8b068
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalCalculator.h.svn-base
@@ -0,0 +1,46 @@
+/*
+ * TbUTPedestalCalculator.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTPedestal.h"
+#include <stdexcept>
+
+namespace TbUT
+{
+class PedestalCalculator: public IPedestalFollowing
+{
+	enum RunPhase
+	{
+		CALCULATE_INITIAL_VALUE,
+		NORMALIZE_INITIAL_VALUE,
+		CALUCLATE_PEDESTAL
+	};
+
+public:
+	PedestalCalculator(IChannelMaskProvider& p_maskProvider, Pedestal & p_pedestal);
+	StatusCode processEvent(RawData<>* p_data);
+	void savePedestalToFile(const std::string& p_filename);
+
+private:
+
+	StatusCode calculateInitialValue(RawData<>* p_data);
+	StatusCode normalizeInitialValue();
+	StatusCode calculaPedestal(RawData<>* p_data);
+
+	RunPhase getRunPhase() const;
+
+	double calculateUpdate(int p_channel, RawData<>::SignalVector&  p_data);
+
+	IChannelMaskProvider& m_maskProvider;
+	Pedestal & m_pedestal;
+	int m_normalization;
+	int m_event;
+	const int m_calculateInitialValueEvents;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalFileValidator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalFileValidator.cpp.svn-base
new file mode 100644
index 0000000..2d72cba
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalFileValidator.cpp.svn-base
@@ -0,0 +1,43 @@
+/*
+ * TbUTPedestalFileValidator.cpp
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalFileValidator.h"
+
+using namespace TbUT;
+using namespace boost::filesystem;
+
+
+PedestalFileValidator::PedestalFileValidator(const std::string& p_filename):
+		m_filename(p_filename)
+{
+}
+
+
+bool PedestalFileValidator::validateFile()
+{
+	m_path=path(m_filename);
+	 bool l_result=
+			  isfileExist() &&
+			  isRegularFile() &&
+			  hasNonZeroSize();
+	 return l_result;
+}
+
+bool PedestalFileValidator::isfileExist()
+{
+	 return exists(m_path);
+}
+
+bool PedestalFileValidator::isRegularFile()
+{
+	return  is_regular_file(m_path);
+}
+
+bool PedestalFileValidator::hasNonZeroSize()
+{
+	return !(0==file_size(m_path));
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalFileValidator.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalFileValidator.h.svn-base
new file mode 100644
index 0000000..3386e45
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalFileValidator.h.svn-base
@@ -0,0 +1,31 @@
+/*
+ * TbUTPedestalFileValidator.h
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTIFileValidator.h"
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace TbUT
+{
+
+class PedestalFileValidator: public IFileValidator
+{
+public:
+	PedestalFileValidator(const std::string& p_filename);
+	bool validateFile();
+
+private:
+	bool isfileExist();
+	bool isRegularFile();
+	bool hasNonZeroSize();
+
+	const std::string& m_filename;
+	boost::filesystem::path  m_path;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalFollowingFactory.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalFollowingFactory.cpp.svn-base
new file mode 100644
index 0000000..0240833
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalFollowingFactory.cpp.svn-base
@@ -0,0 +1,32 @@
+/*
+ * PedestalFollowingFactory.cpp
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+
+#include "TbUTPedestalFollowingFactory.h"
+#include "TbUTPedestalCalculator.h"
+#include "TbUTPedestalRetreiver.h"
+
+using namespace TbUT;
+
+PedestalFollowingFactory::PedestalFollowingFactory(IChannelMaskProvider& p_chanelMaskProvider,Pedestal &p_pedestal , IFileValidator& p_fileValidator, const std::string& p_filename):
+		m_chanelMaskProvider(p_chanelMaskProvider),
+		m_pedestal(p_pedestal),
+		m_fileValidator(p_fileValidator),
+		m_filename(p_filename)
+{
+}
+
+
+IPedestalFollowing* PedestalFollowingFactory::createPedestalFollowing(const std::string& p_followingType)
+{
+	if(!p_followingType.compare(TbUT::FollowingOptions::Calculator.c_str()))
+		return new PedestalCalculator(m_chanelMaskProvider, m_pedestal);
+	else if(!p_followingType.compare(TbUT::FollowingOptions::File.c_str()))
+		return new PedestalRetreiver(m_pedestal,m_fileValidator,m_filename);
+	else
+		throw NoSuchState(p_followingType);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalFollowingFactory.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalFollowingFactory.h.svn-base
new file mode 100644
index 0000000..a4846b5
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalFollowingFactory.h.svn-base
@@ -0,0 +1,44 @@
+/*
+ * TbUTPedestalFollowingfactory.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTPedestal.h"
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTIFileValidator.h"
+
+#include <string>
+
+namespace TbUT
+{
+namespace FollowingOptions
+{
+static const std::string& Calculator = "calculator";
+static const std::string& File = "file";
+}
+
+class PedestalFollowingFactory
+{
+public:
+	PedestalFollowingFactory(IChannelMaskProvider& p_chanelMaskProvider,Pedestal &p_pedestal, IFileValidator& p_fileValidator,const std::string& p_filename  );
+	IPedestalFollowing* createPedestalFollowing(const std::string& p_followingType);
+	class NoSuchState: public std::runtime_error
+		{
+		public:
+		NoSuchState(const std::string& p_errorMsg ):
+					std::runtime_error(p_errorMsg)
+			{
+			}
+		};
+private:
+	IChannelMaskProvider& m_chanelMaskProvider;
+	Pedestal &m_pedestal;
+	IFileValidator& m_fileValidator;
+	const std::string& m_filename;
+
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalRetreiver.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalRetreiver.cpp.svn-base
new file mode 100644
index 0000000..949a1e0
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalRetreiver.cpp.svn-base
@@ -0,0 +1,65 @@
+/*
+ * TbUTPedestalRetreiver.cpp
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+#include "TbUTPedestalRetreiver.h"
+
+#include "TbUTRawData.h"
+#include <iostream>
+#include <fstream>
+
+using namespace TbUT;
+using namespace std;
+
+PedestalRetreiver::PedestalRetreiver(Pedestal& p_pedestal, IFileValidator& p_fileValidator, const std::string& p_filename):
+		m_isFillingPedestalRequited(true),
+		m_pedestal(p_pedestal),
+		m_fileValidator(p_fileValidator),
+		m_filename(p_filename)
+{
+}
+
+void PedestalRetreiver::savePedestalToFile(const std::string& /*p_filename*/)
+{
+	cout<<"Not saving Pedestal!"<<endl;
+// do not save nothing!
+}
+
+
+StatusCode PedestalRetreiver::processEvent(RawData<>* /*p_data*/)
+{
+	if(!m_isFillingPedestalRequited){
+		cout<<"PedestalRetreiver===> pedestals ok!"<<endl;
+		return StatusCode::SUCCESS;
+	}
+
+	if(!m_fileValidator.validateFile() ){
+		cout<<"validation error!"<<endl;
+		return StatusCode::FAILURE;
+	}
+	getPedestalFromFile();
+	return StatusCode::SUCCESS;
+}
+
+void PedestalRetreiver::getPedestalFromFile()
+{
+	cout<<"PedestalRetreiver===>getting pedestals from file: "<< m_filename<<endl;
+	int l_channelsNumber=RawData<>::getnChannelNumber();
+	ifstream l_file(m_filename);
+	if(!l_file.good()){
+		std::string lerrorMsg="Cannot open input pedestal file: "+m_filename;
+		throw PedestalCalculatorError(lerrorMsg);
+	}
+
+	for(int channel=0;channel<l_channelsNumber;channel++)
+	{
+		double l_pedestalFromFile=0;
+		l_file >> l_pedestalFromFile;
+		m_pedestal.setPedestal(channel,l_pedestalFromFile);
+		cout<<"PedestalRetreiver===> channel: "<< channel <<"pedestal: "<<l_pedestalFromFile<<endl;
+	}
+	m_pedestal.setNormalizationFlag(true);
+	m_isFillingPedestalRequited=false;
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalRetreiver.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalRetreiver.h.svn-base
new file mode 100644
index 0000000..4ba054e
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalRetreiver.h.svn-base
@@ -0,0 +1,36 @@
+/*
+ * TbUTPedestalRetreiver.h
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTPedestal.h"
+#include "TbUTIFileValidator.h"
+
+namespace TbUT
+{
+
+class PedestalRetreiver: public IPedestalFollowing
+{
+public:
+	PedestalRetreiver(Pedestal& p_pedestal, IFileValidator& p_fileValidator, const std::string& p_filename);
+
+	StatusCode processEvent(RawData<>* p_data);
+	void savePedestalToFile(const std::string& p_filename);
+
+private:
+	void getPedestalFromFile();
+
+	bool m_isFillingPedestalRequited;
+	Pedestal & m_pedestal;
+	IFileValidator& m_fileValidator;
+	const std::string& m_filename;
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalSubtractor.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalSubtractor.cpp.svn-base
new file mode 100644
index 0000000..67f73a4
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalSubtractor.cpp.svn-base
@@ -0,0 +1,36 @@
+/*
+ * TbUTPedestalSubtractor.cpp
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#include"TbUTPedestalSubtractor.h"
+#include <iostream>
+
+using namespace TbUT;
+
+PedestalSubtractor::PedestalSubtractor(Pedestal & p_pedestal,IChannelMaskProvider& p_masksProvider ):
+		m_pedestal(p_pedestal),
+		m_masksProvider(p_masksProvider)
+{
+}
+
+ void PedestalSubtractor::processEvent(RawData<>* p_data, RawData<> **p_output)
+{
+	 int l_channelNumber=RawData<>::getnChannelNumber();
+	 RawData<>::DataType l_maskedChannelValue=0;
+	 for(int channel=0;channel<l_channelNumber;channel++)
+	 {
+		 if(m_masksProvider.isMasked(channel)) (*p_output)->setSignal(l_maskedChannelValue);
+		 else{
+			 RawData<>::DataType l_signalAfterPedestal= p_data->getSignal(channel)-m_pedestal.getPedestal(channel);
+			 (*p_output)->setSignal(l_signalAfterPedestal);
+		 }
+	 }
+	 (*p_output)->setTDC(p_data->getTDC());
+	 (*p_output)->setTime(p_data->getTime());
+
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalSubtractor.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalSubtractor.h.svn-base
new file mode 100644
index 0000000..644bc89
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalSubtractor.h.svn-base
@@ -0,0 +1,30 @@
+/*
+ * TbUTPedestalSubtractor.h
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIProcessingEngine.h"
+#include "TbUTPedestal.h"
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTRawData.h"
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+class PedestalSubtractor : public IProcessingEngine<>
+{
+public:
+	PedestalSubtractor(Pedestal  & p_pedestalSum,IChannelMaskProvider& p_masksProvider );
+	void processEvent(RawData<>* p_data, RawData<> **p_output);
+
+private:
+
+	Pedestal& m_pedestal;
+	IChannelMaskProvider& m_masksProvider;
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalSubtractorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..6a16cd8
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorAlgorithm.cpp.svn-base
@@ -0,0 +1,178 @@
+/*
+ * TbUTPedestalSubtractorAlgorithm.cpp
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalSubtractorAlgorithm.h"
+#include "TbUTDataLocations.h"
+
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,PedestalSubtractorAlgorithm)
+
+
+PedestalSubtractorAlgorithm::PedestalSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+		GaudiAlgorithm(name, pSvcLocator),
+		m_isStandalone(true),
+		m_data(),
+		m_inputDataLocation(),
+		m_outputDataLocation(),
+		m_pedestalInputLocation(),
+		m_pedestalOutputLocation(),
+		m_channelMaskInputLocation(),
+		m_followingOption(),
+		m_event(0),
+		m_treningEventNumber(0),
+		m_skippEvent(0),
+		m_channelMaskFileValidator(m_channelMaskInputLocation),
+		m_channelMaskProvider(m_channelMaskFileValidator),
+		m_pedestal(),
+		m_pedestalFileValidator(m_pedestalInputLocation),
+		m_followingFactory(m_channelMaskProvider, m_pedestal,m_pedestalFileValidator ,m_pedestalInputLocation),
+		m_pedestalFollowingPtr(),
+		m_pedestalSubtractor(m_pedestal, m_channelMaskProvider)
+{
+	declareProperty("SkippEventNumber", m_skippEvent=0);
+	declareProperty("InputDataLocation", m_inputDataLocation=TbUT::DataLocations::RawTES);
+	declareProperty("OutputDataLocation", m_outputDataLocation=TbUT::DataLocations::PedestalTES);
+	declareProperty("FollowingOption",m_followingOption=TbUT::FollowingOptions::Calculator);
+	declareProperty("treningEntry",m_treningEventNumber=1024);
+	declareProperty("ChannelMaskInputLocation", m_channelMaskInputLocation=TbUT::DataLocations::MaskLocation);
+	declareProperty("PedestalInputFile", m_pedestalInputLocation=TbUT::DataLocations::PedestalLocation);
+	declareProperty("PedestalOutputFile", m_pedestalOutputLocation=TbUT::DataLocations::PedestalLocation);
+	declareProperty("standalone",m_isStandalone=true );
+}
+
+StatusCode PedestalSubtractorAlgorithm::initialize()
+{
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildFollowing()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=retriveMasksFromFile()) return StatusCode::FAILURE;
+
+	info()<<"Initialized successfully!"<<endmsg;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalSubtractorAlgorithm::execute()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	m_outputDataContainer=new RawDataContainer<>();
+
+	if(m_dataContainer->isEmpty()){
+		info()<<"ped suba put empty"<<endmsg;
+		put(m_outputDataContainer,m_outputDataLocation);
+		return StatusCode::SUCCESS;
+	}
+
+	for(const auto& rawDataIt: m_dataContainer->getData()){
+		m_data=new RawData<>(rawDataIt);
+		RunPhase l_runPhase=getRunPhase();
+		switch (l_runPhase)
+		{
+		case SKIPP:
+			skippEvent();
+		case TREANING:
+			processTreaning();
+		default:
+			subtractPedestals();
+		}
+		delete m_data;
+	}
+	put(m_outputDataContainer,m_outputDataLocation);
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalSubtractorAlgorithm::finalize()
+{
+	savePedestalsToFile();
+	return GaudiAlgorithm::finalize();
+}
+
+StatusCode PedestalSubtractorAlgorithm::initializeBase()
+{
+	  return GaudiAlgorithm::initialize();
+}
+
+StatusCode PedestalSubtractorAlgorithm::buildFollowing()
+try{
+	m_pedestalFollowingPtr.reset(m_followingFactory.createPedestalFollowing(m_followingOption));
+	return StatusCode::SUCCESS;
+}catch(PedestalFollowingFactory::NoSuchState &exception)
+{
+	error()<<"Invalid Following Option: "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode PedestalSubtractorAlgorithm::retriveMasksFromFile()
+try{
+	m_channelMaskProvider.getMaskFromFile(m_channelMaskInputLocation);
+	return StatusCode::SUCCESS;
+}catch(ChannelMaskProvider::InputFileError  &exception)
+{
+	error()<<"Channel Mask File Input Error: "<<m_channelMaskInputLocation<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode PedestalSubtractorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<> >(m_inputDataLocation);
+	if(!m_dataContainer){
+		error()<< " ==> There is no input data: "<< m_inputDataLocation <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+PedestalSubtractorAlgorithm::RunPhase PedestalSubtractorAlgorithm::getRunPhase()
+{
+	if(m_event<m_skippEvent)
+		return SKIPP;
+	else if (m_event<m_skippEvent+m_treningEventNumber)
+		return TREANING;
+	else
+		return SUBTRACTION;
+}
+
+
+void PedestalSubtractorAlgorithm::skippEvent()
+{
+	m_event++;
+}
+
+void PedestalSubtractorAlgorithm::processTreaning()
+{
+	m_pedestalFollowingPtr->processEvent(m_data);
+	m_event++;
+	//if( m_followingOption != TbUT::FollowingOptions::Calculator) subtractPedestals();
+}
+
+void PedestalSubtractorAlgorithm::subtractPedestals()
+{
+	processAndSaveDataToTES();
+	m_event++;
+}
+
+void PedestalSubtractorAlgorithm::processAndSaveDataToTES()
+{
+	RawData<> *afterPedestal=new RawData<>();
+	m_pedestalSubtractor.processEvent(m_data,&afterPedestal);
+	m_outputDataContainer->addData(*afterPedestal);
+}
+
+
+StatusCode PedestalSubtractorAlgorithm::savePedestalsToFile()
+try{
+	info()<<"Save Pedestal to File"<<endmsg;
+	m_pedestalFollowingPtr->savePedestalToFile(m_pedestalOutputLocation);
+	return  StatusCode::SUCCESS;
+}
+catch(IPedestalFollowing::PedestalCalculatorError &er)
+{
+	error()<<er.what() <<endmsg;
+	return  StatusCode::FAILURE;
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalSubtractorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorAlgorithm.h.svn-base
new file mode 100644
index 0000000..8eafb8d
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorAlgorithm.h.svn-base
@@ -0,0 +1,87 @@
+/*
+ * TbUTPedestalSubtractorAlgorithm.h
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+#include "TbUTRawData.h"
+#include "TbUTPedestalFollowingFactory.h"
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTPedestalSubtractor.h"
+#include "TbUTChannelMaskProvider.h"
+#include "TbUTChannelMaskFileValidator.h"
+#include "TbUTPedestal.h"
+#include "TbUTPedestalFileValidator.h"
+
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+class PedestalSubtractorAlgorithm: public GaudiAlgorithm
+{
+	typedef boost::shared_ptr<IPedestalFollowing> PedestalFollowingPtr;
+
+	enum RunPhase
+	{
+		 SKIPP,
+		 TREANING,
+		SUBTRACTION	
+	};
+
+public:
+	PedestalSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+	virtual StatusCode finalize();
+
+private:
+
+	StatusCode initializeBase();
+	StatusCode buildFollowing();
+	StatusCode retriveMasksFromFile();
+
+	void skippEvent();
+	void processTreaning();
+	void subtractPedestals();
+	
+	StatusCode getData();
+	void processAndSaveDataToTES();
+	StatusCode savePedestalsToFile();
+
+	RunPhase getRunPhase();
+
+	bool m_isStandalone;
+	RawDataContainer<>* m_dataContainer;
+	RawData<>* m_data;
+	RawDataContainer<>* m_outputDataContainer;
+
+	std::string m_inputDataLocation;
+	std::string m_outputDataLocation;
+	std::string m_pedestalInputLocation;
+	std::string m_pedestalOutputLocation;
+	std::string m_channelMaskInputLocation;
+	std::string m_followingOption;
+	int m_event;
+	int m_treningEventNumber;
+	int m_skippEvent;
+
+	ChannelMaskFileValidator m_channelMaskFileValidator;
+	ChannelMaskProvider m_channelMaskProvider;
+	Pedestal m_pedestal;
+	PedestalFileValidator m_pedestalFileValidator;
+	PedestalFollowingFactory m_followingFactory;
+	PedestalFollowingPtr m_pedestalFollowingPtr;
+	PedestalSubtractor m_pedestalSubtractor;
+
+};
+
+} 
+
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..e0b7b86
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp.svn-base
@@ -0,0 +1,62 @@
+/*
+ * TbUTPedestalDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Oct 18, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalSubtractorDataMonitorAlgorithm.h"
+
+#include "TbUTDataLocations.h"
+#include "TbUTRawData.h"
+
+#include "GaudiUtils/Aida2ROOT.h"
+#include <boost/format.hpp>
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,PedestalSubtractorDataMonitorAlgorithm)
+
+using namespace TbUT;
+
+PedestalSubtractorDataMonitorAlgorithm::PedestalSubtractorDataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : DataMonitorAlgorithm ( name , pSvcLocator )
+{
+	DataMonitorAlgorithm::m_inputDataLoc=TbUT::DataLocations::PedestalTES;
+}
+
+std::string PedestalSubtractorDataMonitorAlgorithm::createHistogramName()
+{
+	boost::format l_histogramName("Data_after_pedestal_event_%d");
+	l_histogramName % m_evtNumber;
+	return str(l_histogramName);
+}
+
+TH2D * PedestalSubtractorDataMonitorAlgorithm::bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	int l_ylow=-800;
+	int l_yhigh=800;
+	int l_ybin=1600;
+	return Gaudi::Utils::Aida2ROOT::aida2root(book2D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()+0.5,p_sensorNumber,
+			l_ylow,l_yhigh,l_ybin ));
+}
+
+std::string PedestalSubtractorDataMonitorAlgorithm::createHistogramTitle()
+{
+	boost::format l_histogramTitle("Data after Pedestal Subtraction - event%1%");
+	l_histogramTitle% m_evtNumber;
+	return str(l_histogramTitle);
+}
+
+void PedestalSubtractorDataMonitorAlgorithm::createHistogram2D()
+{
+	std::string l_histogramName="PedestalData_vs_channel";
+	std::string l_histogramTtttle="Data after Pedestal vs channel";
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	m_histogram2D=bookHistogram2D(l_histogramName,l_histogramTtttle,l_sensorNum );
+}
+
+StatusCode PedestalSubtractorDataMonitorAlgorithm::finalize()
+{
+	DataMonitorAlgorithm::m_outpuProjectionHistogramName="ProjectionPedestal";
+	return DataMonitorAlgorithm::finalize();
+}
diff --git a/TbUT/src/.svn/text-base/TbUTPedestalSubtractorDataMonitorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorDataMonitorAlgorithm.h.svn-base
new file mode 100644
index 0000000..4a23f8f
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTPedestalSubtractorDataMonitorAlgorithm.h.svn-base
@@ -0,0 +1,30 @@
+/*
+ * TbUTPedestalDataMonitorAlgorithm.h
+ *
+ *  Created on: Oct 18, 2014
+ *      Author: ADendek
+ */
+#pragma once
+
+
+#include "TbUTDataMonitorAlgorithm.h"
+
+namespace TbUT
+{
+
+class PedestalSubtractorDataMonitorAlgorithm: public DataMonitorAlgorithm
+{
+public:
+	PedestalSubtractorDataMonitorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+	StatusCode finalize();
+
+private:
+	  TH2D * bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+	  std::string createHistogramTitle();
+	  void createHistogram2D();
+	  std::string createHistogramName();
+
+};
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTRandomNoiseGenerator.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTRandomNoiseGenerator.cpp.svn-base
new file mode 100644
index 0000000..7951ad2
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRandomNoiseGenerator.cpp.svn-base
@@ -0,0 +1,33 @@
+/*
+ * TbUTRandomNoiseGenerator.cpp
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTRandomNoiseGenerator.h"
+#include <iostream>
+
+using namespace TbUT;
+
+RandomNoiseGenerator::RandomNoiseGenerator(double& p_sigma, double& p_mean):
+		m_sigma(p_sigma),
+		m_mean(p_mean),
+		m_randomGenerator()
+{
+}
+
+void RandomNoiseGenerator::checkInput()
+{
+}
+
+RawData<>* RandomNoiseGenerator::getEventData()
+{
+	RawData<>* l_outputNoise=new RawData<>();
+	for(int channel=0;channel<RawData<>::getnChannelNumber();channel++)
+	{
+		double l_randomNoise=m_randomGenerator.Gaus(m_sigma,m_mean);
+		l_outputNoise->setSignal(l_randomNoise);
+	}
+	return l_outputNoise;
+}
diff --git a/TbUT/src/.svn/text-base/TbUTRandomNoiseGenerator.h.svn-base b/TbUT/src/.svn/text-base/TbUTRandomNoiseGenerator.h.svn-base
new file mode 100644
index 0000000..a5c8264
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRandomNoiseGenerator.h.svn-base
@@ -0,0 +1,31 @@
+/*
+ * TbUTRandomNoiseGenerator.h
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include <TRandom.h>
+
+namespace TbUT
+{
+
+class RandomNoiseGenerator : public IDataReader
+{
+public:
+	RandomNoiseGenerator(double& p_sigma, double& p_mean);
+	void checkInput();
+	RawData<>* getEventData();
+
+private:
+	double& m_sigma;
+	double& m_mean;
+	TRandom m_randomGenerator;
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTRawData.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTRawData.cpp.svn-base
new file mode 100644
index 0000000..7a6dda0
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawData.cpp.svn-base
@@ -0,0 +1,12 @@
+/*
+ * TbUTRawData<>.cpp
+ *
+ *  Created on: Feb 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTRawData.h"
+using namespace TbUT;
+
+template <>
+Sensor RawData<int>::s_sensor=Sensor(1);
diff --git a/TbUT/src/.svn/text-base/TbUTRawData.h.svn-base b/TbUT/src/.svn/text-base/TbUTRawData.h.svn-base
new file mode 100644
index 0000000..e05115b
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawData.h.svn-base
@@ -0,0 +1,240 @@
+#pragma once
+#include "GaudiKernel/DataObject.h"
+#include <string>
+#include <vector>
+#include "TbUTDataLocations.h"
+#include "TbUTSensor.h"
+
+namespace TbUT
+{
+template<typename DATA_TYPE = int>
+class RawData
+{
+public:
+	typedef std::vector<DATA_TYPE> SignalVector;
+	typedef DATA_TYPE DataType;
+
+	static void setSensor(Sensor p_sensor)
+	{
+		s_sensor=p_sensor;
+	}
+	static int getMaxChannel()
+	{
+		return s_sensor.maxChannel();
+	}
+
+	static int getMinChannel()
+	{
+		return s_sensor.minChannel();
+	}
+	static int getnChannelNumber()
+	{
+		return s_sensor.channelNumber*s_sensor.sensorNumber();
+	}
+
+	static int getSensorNumber()
+	{
+		return s_sensor.sensorNumber();
+	}
+
+	RawData<DATA_TYPE>():
+		m_signal(),
+    		m_header0(), 
+    		m_header1(), 
+    		m_header2(), 
+    		m_header3(), 
+    		m_header3P1(), 
+    		m_header3P2(),
+		m_time(),
+		m_temperature(),
+		m_tdc()
+	{
+	};
+
+	RawData<DATA_TYPE>& operator=( const RawData<DATA_TYPE>& rhs )
+	{
+		 if( this != &rhs ) {
+			 m_signal=rhs.m_signal;
+			 m_header0=rhs.m_header0;
+        	 m_header1=rhs.m_header1;
+	         m_header2=rhs.m_header2;
+        	 m_header3=rhs.m_header3;
+			 m_header3P1=rhs.m_header3P1;
+			 m_header3P2=rhs.m_header3P2;
+			 m_time=rhs.m_time;
+			 m_temperature=rhs.m_temperature;
+			 m_tdc=rhs.m_tdc;
+		 }
+	      return *this;
+	  }
+	RawData<DATA_TYPE>(const RawData<DATA_TYPE> &rhs):
+		 m_signal(rhs.m_signal),
+		 m_header0(rhs.m_header0),
+         m_header1(rhs.m_header1),
+		 m_header2(rhs.m_header2),
+		 m_header3(rhs.m_header3),
+		 m_header3P1(rhs.m_header3P1),
+		 m_header3P2(rhs.m_header3P2),
+		 m_time(rhs.m_time),
+		 m_temperature(rhs.m_temperature),
+		 m_tdc(rhs.m_tdc)
+	{
+	}
+	
+  	void setTemp(double p_temp)
+	{
+		m_temperature = p_temp;
+	}
+	void setTime(unsigned long long p_time)
+	{
+		m_time = p_time;
+	}
+	void setSignal(DATA_TYPE p_signal)
+	{
+		m_signal.push_back(p_signal);
+	}
+  void setHeader0(DATA_TYPE p_header) 
+  {
+    m_header0.push_back(p_header); 
+  }
+  void setHeader1(DATA_TYPE p_header) 
+  {
+    m_header1.push_back(p_header); 
+  }
+  void setHeader2(DATA_TYPE p_header) 
+  {
+    m_header2.push_back(p_header); 
+  }
+  void setHeader3(DATA_TYPE p_header) 
+  {
+    m_header3.push_back(p_header); 
+  }
+  void setHeader3P1(DATA_TYPE p_header) 
+  {
+    m_header3P1.push_back(p_header); 
+  }
+  void setHeader3P2(DATA_TYPE p_header) 
+  {
+    m_header3P2.push_back(p_header); 
+  }
+	SignalVector& getSignal()
+	{
+		return m_signal;
+	}
+	SignalVector& getHeader0()
+	{
+		return m_header0;
+	}
+	SignalVector& getHeader1()
+	{
+		return m_header1;
+	}
+	SignalVector& getHeader2()
+	{
+		return m_header2;
+	}
+	SignalVector& getHeader3()
+	{
+		return m_header3;
+	}
+	SignalVector& getHeader3P1()
+	{
+		return m_header3P1;
+	}
+	SignalVector& getHeader3P2()
+	{
+		return m_header3P2;
+	}
+
+	unsigned long long getTime() const
+	{
+		return m_time;
+	}
+	double getTemp() const
+	{
+		return m_temperature;
+	}
+
+	DATA_TYPE getSignal(int channel) const
+	{
+		return m_signal[channel];
+	}
+	
+  DATA_TYPE getHeader0(int subset) const
+	{
+		return m_header0[subset];
+	}
+  DATA_TYPE getHeader1(int subset) const
+	{
+		return m_header1[subset];
+	}
+  DATA_TYPE getHeader2(int subset) const
+	{
+		return m_header2[subset];
+	}
+  DATA_TYPE getHeader3(int subset) const
+	{
+		return m_header3[subset];
+	}
+  DATA_TYPE getHeader3P1(int subset) const
+	{
+		return m_header3P1[subset];
+	}
+  DATA_TYPE getHeader3P2(int subset) const
+	{
+		return m_header3P2[subset];
+	}
+
+	unsigned int getTDC() const
+	{
+		return m_tdc;
+	}
+
+	void setTDC(unsigned int p_tdc)
+	{
+		m_tdc=p_tdc;
+	}
+
+protected:
+	SignalVector m_signal;
+	SignalVector m_header0;
+	SignalVector m_header1;
+	SignalVector m_header2;
+	SignalVector m_header3;
+	SignalVector m_header3P1;
+	SignalVector m_header3P2;
+	unsigned long long m_time;
+	double m_temperature;
+	unsigned int m_tdc;
+
+	static Sensor s_sensor;
+};
+
+
+template<typename DataType  = int>
+class RawDataContainer:  public DataObject
+{
+public:
+	typedef std::vector<RawData<DataType> > RawDataVec;
+
+	RawDataContainer<DataType>():
+		empty(true),
+		m_dataVector()
+	{};
+
+	void addData(RawData<DataType> rawData)
+	{
+		m_dataVector.push_back(rawData);
+		empty=false;
+	}
+	bool isEmpty(){return empty;}
+	RawDataVec getData(){return m_dataVector;}
+private:
+	bool empty;
+	RawDataVec m_dataVector;
+
+};
+
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTRawDataFactory.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTRawDataFactory.cpp.svn-base
new file mode 100644
index 0000000..c65b591
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawDataFactory.cpp.svn-base
@@ -0,0 +1,40 @@
+/*
+ * TbUTRawDataFactory.cpp
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTRawDataFactory.h"
+#include "TbUTMambaDataReader.h"
+#include "TbUTAlibavaDataReader.h"
+#include "TbUTRandomNoiseGenerator.h"
+
+using namespace TbUT;
+
+
+RawDataFactory::RawDataFactory(std::string& p_filename,
+		IDataRetreiver & p_alibava,
+		IFileValidator& p_fileValidator,
+		bool& p_isAType,
+		double& p_mean,	double& p_sigma):
+				m_filename(p_filename),
+				m_alibava(p_alibava),
+				m_fileValidator(p_fileValidator),
+				m_isAType(p_isAType),
+				m_mean(p_mean),
+				m_sigma(p_sigma)
+{
+}
+
+RawDataFactory::DataReaderPtr  RawDataFactory::createDataEngine(const std::string& p_inputDataOption)
+{
+	if(p_inputDataOption==InputDataOption::Alibava)
+		return DataReaderPtr(new AlibavaDataReader(m_filename,m_alibava, m_fileValidator));
+	if(p_inputDataOption == InputDataOption::Mamba)
+		return DataReaderPtr(new MambaDataReader(m_filename,m_fileValidator,m_isAType ));
+	if(p_inputDataOption==InputDataOption::NoiseGenerator)
+		return DataReaderPtr(new RandomNoiseGenerator(m_mean,m_sigma));
+	else
+		throw NoSuchState(p_inputDataOption);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTRawDataFactory.h.svn-base b/TbUT/src/.svn/text-base/TbUTRawDataFactory.h.svn-base
new file mode 100644
index 0000000..5e42cf3
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawDataFactory.h.svn-base
@@ -0,0 +1,59 @@
+/*
+ * TbUTRawData<>Factory.h
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include "TbUTRawData.h"
+#include "TbUTAlibavaDataRetreiver.h"
+#include "TbUTAlbavaFileValidator.h"
+#include <memory>
+
+namespace TbUT
+{
+
+namespace InputDataOption
+{
+static const std::string& Alibava = "alibava";
+static const std::string& NoiseGenerator = "Generator";
+static const std::string& Mamba = "Mamba";
+}
+
+
+class RawDataFactory
+{
+public:
+	typedef std::shared_ptr<IDataReader> DataReaderPtr;
+
+	class NoSuchState: public std::runtime_error
+	{
+	public:
+		NoSuchState(const std::string& p_errorMsg ):
+			std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+
+	RawDataFactory(std::string& p_filename,
+			IDataRetreiver & p_alibava,
+			IFileValidator& p_fileValidator,
+			bool& p_isAType,
+			double& p_mean,
+			double& p_sigma);
+	DataReaderPtr createDataEngine(const std::string& p_inputDataOption);
+	private:
+	std::string& m_filename;
+	IDataRetreiver & m_alibava;
+	IFileValidator& m_fileValidator;
+	bool& m_isAType;
+	double& m_mean;
+	double& m_sigma;
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/.svn/text-base/TbUTRawDataMonitorAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTRawDataMonitorAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..806c149
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawDataMonitorAlgorithm.cpp.svn-base
@@ -0,0 +1,26 @@
+/*
+ * TbUTRawDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Oct 7, 2014
+ *      Author: ADendek
+ */
+#include "TbUTRawDataMonitorAlgorithm.h"
+#include "TbUTDataLocations.h"
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,RawDataMonitorAlgorithm)
+
+using namespace TbUT;
+
+RawDataMonitorAlgorithm::RawDataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : DataMonitorAlgorithm ( name , pSvcLocator )
+{
+	RawDataMonitorAlgorithm::m_inputDataLoc=TbUT::DataLocations::RawTES;
+}
+
+
+
+StatusCode RawDataMonitorAlgorithm::finalize()
+{
+	DataMonitorAlgorithm::m_outpuProjectionHistogramName="ProjectionRawData";
+	return DataMonitorAlgorithm::finalize();
+}
diff --git a/TbUT/src/.svn/text-base/TbUTRawDataMonitorAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTRawDataMonitorAlgorithm.h.svn-base
new file mode 100644
index 0000000..c782a7e
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawDataMonitorAlgorithm.h.svn-base
@@ -0,0 +1,21 @@
+/*
+ * TbUTRawDataMonitorAlgorithm.h
+ *
+ *  Created on: Oct 7, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTDataMonitorAlgorithm.h"
+
+namespace TbUT
+{
+
+class RawDataMonitorAlgorithm : public DataMonitorAlgorithm
+{
+public:
+	RawDataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+	StatusCode finalize  ();
+};
+}
diff --git a/TbUT/src/.svn/text-base/TbUTRawDataReaderAlgorithm.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTRawDataReaderAlgorithm.cpp.svn-base
new file mode 100644
index 0000000..e8da046
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawDataReaderAlgorithm.cpp.svn-base
@@ -0,0 +1,105 @@
+#include "TbUTRawDataReaderAlgorithm.h"
+#include "GaudiKernel/ToolFactory.h"
+#include "GaudiKernel/IEventProcessor.h"
+
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,RawDataReaderAlgorithm)
+
+RawDataReaderAlgorithm::RawDataReaderAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+	GaudiAlgorithm(name, pSvcLocator),
+	m_isStandalone(true),
+	m_isAType(true),
+	m_eventNumber(0),
+	m_skipEventNumber(0),
+	m_alibavaInputData(),
+	m_outputLocation(),
+	m_sensorNumber(1),
+	m_mean(0),
+	m_sigma(1),
+	m_alibava(),
+	m_fileValidator(m_alibavaInputData),
+	m_rawDataReader(),
+	m_inputDataFactory(m_alibavaInputData, m_alibava,m_fileValidator, m_isAType,m_mean,m_sigma )
+{
+	declareProperty("InputDataType", m_inputDataOption=TbUT::InputDataOption::Mamba);
+	declareProperty("SkipEventNumber", m_skipEventNumber=0);
+	declareProperty("inputData", m_alibavaInputData="run_000007_2607_1639.ali");
+	declareProperty("outputLoc", m_outputLocation=TbUT::DataLocations::RawTES );
+	declareProperty("sensorNumber", m_sensorNumber=1 );
+	declareProperty("standalone", m_isStandalone=true );
+	declareProperty("isAType", m_isAType=true );
+
+
+	declareProperty("sigma", m_sigma=0. );
+	declareProperty("mean", m_mean=1. );
+}
+
+
+StatusCode RawDataReaderAlgorithm::initialize()
+{
+	StatusCode sc = GaudiAlgorithm::initialize();
+	if (!sc.isSuccess()) return StatusCode::FAILURE;
+	try {
+		m_rawDataReader=m_inputDataFactory.createDataEngine(m_inputDataOption);
+		info()<<"Create data engine done"<<endmsg;
+	} catch(RawDataFactory::NoSuchState &ex) {
+		error()<<"Error input in factory: "<< ex.what()<<endmsg;
+		return StatusCode::FAILURE;
+	}
+	try {
+		m_rawDataReader->checkInput();
+		return StatusCode::SUCCESS;
+	} catch(IDataReader::InputFileError &ex) {
+		error()<<"input file error: "<< ex.what() <<endmsg;
+		return StatusCode::FAILURE;
+	}
+	try {
+		Sensor l_sensor(m_sensorNumber);
+		RawData<>::setSensor(l_sensor);
+	} catch(Sensor::SensorNumberError &ex) {
+		error()<<"Error create sensor: "<< ex.what()<<endmsg;
+		return StatusCode::FAILURE;
+	}
+	info()<<"initialization success!"<<endmsg;
+	return StatusCode::SUCCESS;
+
+}
+
+StatusCode RawDataReaderAlgorithm::execute()
+{
+	uint64_t mambaOffset=0; // need to be tuned
+	uint64_t keplerEventBegin = 0;
+	uint64_t keplerEventEnd = 0;
+	if(!m_isStandalone)
+		timingSvc()->eventDefinition(keplerEventBegin, keplerEventEnd);
+	else
+		keplerEventEnd=1;// more than 0
+
+	uint64_t mambaTimestamp=0;
+	RawDataContainer<> * outputDataContainer=new RawDataContainer<>();
+	while(mambaTimestamp+mambaOffset<keplerEventEnd){
+		try{
+			if(0==(m_eventNumber%1000) ) info()<<"Read event"<<m_eventNumber<<endmsg;
+			RawData<> * outputData=m_rawDataReader->getEventData();
+			outputDataContainer->addData(*outputData);
+			m_eventNumber++;
+			if(m_isStandalone) break; // do this loop only once
+		}catch(IDataReader::ReadEventError& ex ){
+			error()<<"event read error: "<< ex.what()<<endmsg;
+			return StatusCode::RECOVERABLE;
+		}catch(IDataReader::NoMoreEvents& ex){
+			SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+			if (app){
+				info()<<"No more event. Terminate!"<<endmsg;
+				return app->stopRun();
+			}
+		}
+
+	}
+	put(outputDataContainer, m_outputLocation );
+	return StatusCode::SUCCESS;
+}
+
+
diff --git a/TbUT/src/.svn/text-base/TbUTRawDataReaderAlgorithm.h.svn-base b/TbUT/src/.svn/text-base/TbUTRawDataReaderAlgorithm.h.svn-base
new file mode 100644
index 0000000..f3e707f
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTRawDataReaderAlgorithm.h.svn-base
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTimingSvc.h"
+
+// Local
+#include "TbUTRawData.h"
+#include "TbUTAlibavaDataRetreiver.h"
+#include "TbUTAlbavaFileValidator.h"
+#include "TbUTRawDataFactory.h"
+#include "TbUTAlibavaDataReader.h"
+
+#include <string>
+
+
+namespace TbUT
+{
+
+class RawDataReaderAlgorithm : public GaudiAlgorithm {
+ public:
+	RawDataReaderAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+
+ private:
+	void termiateApp();
+
+	bool m_isStandalone;
+	bool m_isAType;
+	unsigned int m_eventNumber;
+	unsigned int m_skipEventNumber;
+
+	std::string  m_inputDataOption;
+	std::string m_alibavaInputData;
+	std::string m_outputLocation;
+	int m_sensorNumber;
+
+	double m_mean;
+	double m_sigma;
+
+
+	TbUT::AlibavaDataRetreiver m_alibava;
+	TbUT::AlbavaFileValidator m_fileValidator;
+	TbUT::RawDataFactory::DataReaderPtr m_rawDataReader;
+	TbUT::RawDataFactory m_inputDataFactory;
+
+  /// Pointer to timing service
+  mutable ITbTimingSvc* m_timingSvc;
+  /// Access timing service on-demand
+  ITbTimingSvc* timingSvc() const {
+    if (!m_timingSvc) m_timingSvc = svc<ITbTimingSvc>("TbTimingSvc", true);
+    return m_timingSvc;
+  }
+};
+
+}
+
diff --git a/TbUT/src/.svn/text-base/TbUTSensor.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTSensor.cpp.svn-base
new file mode 100644
index 0000000..c7bf271
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTSensor.cpp.svn-base
@@ -0,0 +1,39 @@
+/*
+ * TbUTSensor.cpp
+ *
+ *  Created on: Feb 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTSensor.h"
+
+using namespace TbUT;
+
+
+Sensor::Sensor():
+		m_channelMax(0),
+		m_channelMin(0)
+{
+	setChannelsNumbers(1);
+}
+
+Sensor::Sensor(int p_sensorNumber):
+		m_sensorNumber(p_sensorNumber),
+		m_channelMax(0),
+		m_channelMin(0)
+{
+	setChannelsNumbers(p_sensorNumber);
+}
+
+
+void Sensor::setChannelsNumbers(int p_number)
+{
+	m_channelMin = 0;
+	m_channelMax=512;
+
+	int l_maxSensorNumber=4;
+	if(p_number>l_maxSensorNumber){
+		std::string l_errMsg="Invalid Sensor Number: "+std::to_string(p_number);
+		throw SensorNumberError(l_errMsg);
+	}
+}
diff --git a/TbUT/src/.svn/text-base/TbUTSensor.h.svn-base b/TbUT/src/.svn/text-base/TbUTSensor.h.svn-base
new file mode 100644
index 0000000..786e00b
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTSensor.h.svn-base
@@ -0,0 +1,43 @@
+/*
+ * TbUTSensor.h
+ *
+ *  Created on: Feb 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+#include <string>
+#include <stdexcept>
+
+namespace TbUT
+{
+
+class Sensor
+{
+public:
+	class SensorNumberError: public std::runtime_error
+	{
+	public:
+		SensorNumberError(std::string &msg) :
+					std::runtime_error(msg)
+			{
+			}
+		};
+	Sensor();
+	Sensor(int p_sensorNumber);
+
+	static const int channelNumber=512;
+	int minChannel() const {return m_channelMin;}
+	int maxChannel() const {return m_channelMax;}
+	int sensorNumber() const {return m_sensorNumber;}
+
+private:
+	void setChannelsNumbers(int p_sensorNumber);
+
+	int m_sensorNumber;
+	int m_channelMax;
+	int m_channelMin;
+
+};
+
+}
diff --git a/TbUT/src/.svn/text-base/TbUTTresholdProvider.cpp.svn-base b/TbUT/src/.svn/text-base/TbUTTresholdProvider.cpp.svn-base
new file mode 100644
index 0000000..0bdb4e2
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTTresholdProvider.cpp.svn-base
@@ -0,0 +1,37 @@
+/*
+ * TbUTTresholdProvider.cpp
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTTresholdProvider.h"
+
+using namespace TbUT;
+
+TresholdProvider::TresholdProvider(const std::string& p_noiseFile,
+		const double& p_lowThresholdMultiplicity,
+		const double& p_highThresholdMultiplicity):
+		m_noiseFile(p_noiseFile),
+		m_lowThresholdMultiplicity(p_lowThresholdMultiplicity),
+		m_highThresholdMultiplicity(p_highThresholdMultiplicity),
+		m_noise()
+{
+}
+
+void TresholdProvider::retreiveTresholds()
+try{
+	m_noise.retreiveNoiseFromFile(m_noiseFile);
+}catch(Noise::NoiseCalculatorError& err){
+	throw ThresholdProviderError(err.what());
+}
+
+double TresholdProvider::getLowClusterThreshold(int p_channel)
+{
+	return (m_noise[p_channel]*m_lowThresholdMultiplicity);
+}
+
+double TresholdProvider::getHighClusterThreshold(int p_channel)
+{
+	return (m_noise[p_channel]*m_highThresholdMultiplicity);
+}
diff --git a/TbUT/src/.svn/text-base/TbUTTresholdProvider.h.svn-base b/TbUT/src/.svn/text-base/TbUTTresholdProvider.h.svn-base
new file mode 100644
index 0000000..6888e6d
--- /dev/null
+++ b/TbUT/src/.svn/text-base/TbUTTresholdProvider.h.svn-base
@@ -0,0 +1,35 @@
+/*
+ * TbUTTresholdProvider.h
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTITresholdProvider.h"
+#include "TbUTNoise.h"
+#include  <string>
+
+namespace TbUT
+{
+
+class TresholdProvider: public ITresholdProvider
+{
+public:
+	TresholdProvider(const std::string& p_noiseFile,
+			const double& p_lowThresholdMultiplicity,
+			const double& p_highThresholdMultiplicity );
+
+	void retreiveTresholds();
+	double getLowClusterThreshold(int p_channel);
+	double getHighClusterThreshold(int p_channel);
+private:
+	const std::string& m_noiseFile;
+	const double& m_lowThresholdMultiplicity;
+	const double& m_highThresholdMultiplicity;
+	Noise m_noise;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/Doxyfile b/TbUT/src/Doxyfile
new file mode 100644
index 0000000..552a39c
--- /dev/null
+++ b/TbUT/src/Doxyfile
@@ -0,0 +1,1781 @@
+# Doxyfile 1.7.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = "My Project"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the
+# mathjax.org site, so you can quickly see the result without installing
+# MathJax, but it is strongly recommended to install a local copy of MathJax
+# before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/TbUT/src/TbUTAlbavaFileValidator.cpp b/TbUT/src/TbUTAlbavaFileValidator.cpp
new file mode 100644
index 0000000..e097a8a
--- /dev/null
+++ b/TbUT/src/TbUTAlbavaFileValidator.cpp
@@ -0,0 +1,43 @@
+/*
+ * TbUTAlbavaFileValidator.cpp
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+#include "TbUTAlbavaFileValidator.h"
+#include <string>
+#include <iostream>
+using namespace TbUT;
+using namespace boost::filesystem;
+using namespace std;
+
+
+ AlbavaFileValidator:: AlbavaFileValidator( std::string& p_filename):
+		m_filename(p_filename)
+{
+}
+
+ bool AlbavaFileValidator::validateFile()
+ {
+	 m_path=path(m_filename);
+	 bool l_result=
+			  isfileExist() &&
+			  isRegularFile() &&
+			  hasNonZeroSize();
+	 return l_result;
+ }
+
+ bool AlbavaFileValidator::isfileExist()
+ {
+	 return exists(m_path);
+ }
+
+ bool AlbavaFileValidator::isRegularFile()
+ {
+	 return  is_regular_file(m_path);
+ }
+
+ bool AlbavaFileValidator::hasNonZeroSize()
+ {
+	 return !(0==file_size(m_path));
+ }
diff --git a/TbUT/src/TbUTAlbavaFileValidator.h b/TbUT/src/TbUTAlbavaFileValidator.h
new file mode 100644
index 0000000..aefd69e
--- /dev/null
+++ b/TbUT/src/TbUTAlbavaFileValidator.h
@@ -0,0 +1,29 @@
+/*
+ * TbUTAlbavaFileValidator.h
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIFileValidator.h"
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace TbUT
+{
+class AlbavaFileValidator: public IFileValidator
+{
+public:
+	AlbavaFileValidator( std::string& p_filename);
+	bool validateFile();
+
+private:
+	bool isfileExist();
+	bool isRegularFile();
+	bool hasNonZeroSize();
+
+	std::string& m_filename;
+	boost::filesystem::path  m_path;
+};
+}
diff --git a/TbUT/src/TbUTAlibavaDataReader.cpp b/TbUT/src/TbUTAlibavaDataReader.cpp
new file mode 100644
index 0000000..e223479
--- /dev/null
+++ b/TbUT/src/TbUTAlibavaDataReader.cpp
@@ -0,0 +1,60 @@
+/*
+ * TbUTRawData<>Reader.cpp
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+#include "TbUTAlibavaDataReader.h"
+#include <iostream>
+using namespace TbUT;
+
+
+AlibavaDataReader::AlibavaDataReader(std::string& p_filename  , IDataRetreiver & p_alibava, IFileValidator& p_fileValidator):
+				m_filaname(p_filename ),
+				m_alibava(p_alibava),
+				m_fileValidator(p_fileValidator)
+{
+}
+
+void AlibavaDataReader::checkInput()
+{
+	if( ! m_fileValidator.validateFile() ){
+		std::string errorMsg= "file validation error";
+		throw IDataReader::InputFileError(errorMsg);
+	}
+
+	m_alibava.open(m_filaname);
+	if(! m_alibava.valid()){
+		std::string errorMsg= "alibava validation error";
+		throw IDataReader::InputFileError(errorMsg);
+	}
+}
+
+RawData<>* AlibavaDataReader::getEventData()
+{
+	readEvent();
+	RawData<> *l_outputData=new RawData<>();
+	fillRawData(l_outputData);
+	return l_outputData;
+}
+
+
+void AlibavaDataReader::readEvent()
+{
+	std::string l_errorStr="";
+	if(0 != m_alibava.read_event(l_errorStr))
+	{
+		throw IDataReader::ReadEventError(l_errorStr);
+	}
+}
+
+void AlibavaDataReader::fillRawData(RawData<>* p_outputData)
+{
+	m_alibava.process_event();
+	p_outputData->setTime( m_alibava.time() );
+	p_outputData->setTemp( m_alibava.temp() );
+	for(int chan = RawData<>::getMinChannel(); chan < RawData<>::getMaxChannel(); chan++ )
+		p_outputData->setSignal( m_alibava.data(chan));
+
+}
+
diff --git a/TbUT/src/TbUTAlibavaDataReader.h b/TbUT/src/TbUTAlibavaDataReader.h
new file mode 100644
index 0000000..5fb1128
--- /dev/null
+++ b/TbUT/src/TbUTAlibavaDataReader.h
@@ -0,0 +1,38 @@
+/*
+ * TbUTDataReader.h
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include "TbUTRawData.h"
+#include "TbUTIFileValidator.h"
+#include "TbUTIDataRetreiver.h"
+#include <stdexcept>
+#include <string>
+
+namespace TbUT
+{
+class AlibavaDataReader : public IDataReader
+{
+public:
+
+	AlibavaDataReader(std::string& p_filename ,IDataRetreiver & p_alibava,IFileValidator& p_fileValidator);
+	void checkInput();
+	RawData<>* getEventData(); // unfortunately have to be pointer
+
+private:
+
+	void readEvent();
+	void fillRawData(RawData<>* p_outputData);
+
+	std::string & m_filaname;
+	IDataRetreiver & m_alibava;
+	IFileValidator& m_fileValidator;
+};
+
+}
+
diff --git a/TbUT/src/TbUTAlibavaDataRetreiver.cpp b/TbUT/src/TbUTAlibavaDataRetreiver.cpp
new file mode 100644
index 0000000..0d218e2
--- /dev/null
+++ b/TbUT/src/TbUTAlibavaDataRetreiver.cpp
@@ -0,0 +1,50 @@
+/*
+ * TbUTAlibava.cpp
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+#include "TbUTAlibavaDataRetreiver.h"
+
+using namespace TbUT;
+
+AlibavaDataRetreiver::AlibavaDataRetreiver () :
+    m_assciRoot ()
+{
+}
+
+void AlibavaDataRetreiver::open(std::string & p_filePath)
+{
+	m_assciRoot.open(p_filePath.c_str());
+}
+
+bool
+AlibavaDataRetreiver::valid ()
+{
+  return m_assciRoot.valid ();
+}
+
+int AlibavaDataRetreiver::read_event (std::string & error_code)
+{
+  return m_assciRoot.read_event (error_code);
+}
+
+void AlibavaDataRetreiver::process_event ()
+{
+  m_assciRoot.process_event ();
+}
+
+double AlibavaDataRetreiver::time ()
+{
+  return m_assciRoot.time ();
+}
+
+double AlibavaDataRetreiver::temp ()
+{
+  return m_assciRoot.temp ();
+}
+
+unsigned short AlibavaDataRetreiver::data (int i)
+{
+  return m_assciRoot.data (i);
+}
diff --git a/TbUT/src/TbUTAlibavaDataRetreiver.h b/TbUT/src/TbUTAlibavaDataRetreiver.h
new file mode 100644
index 0000000..e2b215d
--- /dev/null
+++ b/TbUT/src/TbUTAlibavaDataRetreiver.h
@@ -0,0 +1,33 @@
+/*
+ * TbUTAlibava.h
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "alibava/TbAsciiRoot.h"
+#include "TbUTIDataRetreiver.h"
+
+namespace TbUT
+{
+class AlibavaDataRetreiver: public IDataRetreiver
+{
+
+public:
+	AlibavaDataRetreiver();
+	void open(std::string & p_filename);
+	bool valid();
+	int	read_event(std::string & error_code);
+	void process_event();
+	double	time();
+	double	temp();
+	unsigned short data(int i);
+
+private:
+	TbAsciiRoot m_assciRoot;
+};
+
+}
+
diff --git a/TbUT/src/TbUTCMSIterativelyPerBeetle.cpp b/TbUT/src/TbUTCMSIterativelyPerBeetle.cpp
new file mode 100644
index 0000000..b3c69a3
--- /dev/null
+++ b/TbUT/src/TbUTCMSIterativelyPerBeetle.cpp
@@ -0,0 +1,91 @@
+#include "TbUTCMSIterativelyPerBeetle.h"
+#include <iostream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+CMSIterativelyPerBeetle::CMSIterativelyPerBeetle(IChannelMaskProvider& p_masksProvider):
+        m_masksProvider(p_masksProvider),
+        m_channelNumber(RawData<>::getnChannelNumber()),
+		m_channelPerBeetle(32)
+{
+    cout<<"create iteratively correlation per beetle"<<endl;
+    initializeCorrectionAndHitMaps();
+}
+
+
+void CMSIterativelyPerBeetle::initializeCorrectionAndHitMaps()
+{
+	for (int channel=0;channel<m_channelNumber;channel+=m_channelPerBeetle){
+		m_correctionPerBeetle.insert(std::make_pair(channel,0));
+		m_hitThresholdPerBeetle.insert(std::make_pair(channel,200));
+	}
+}
+
+void CMSIterativelyPerBeetle::processEvent(RawData<>* p_data, RawData<double> **p_output)
+{
+	int numberOfIteration=2;
+	RawData<double>* tmpData;
+	// first iteration
+	calculateCorrection<int>(p_data);
+	removeCM<int, double>(p_data,p_output);
+	// rest of the iterations
+	for(int iteration=1;iteration<numberOfIteration; iteration++){
+		tmpData=new RawData<double>(**p_output);
+		calculateCorrection<double>(tmpData);
+		removeCM<double, double>(tmpData,p_output);
+	}
+	resetHitThresholds();
+}
+
+template<typename DATA_TYPE>
+void CMSIterativelyPerBeetle::calculateCorrection(RawData<DATA_TYPE>* p_inputData)
+{
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		int usedChannels=0;
+		double rmsPerBeetle=0;
+		for(int channel=mapIt.first;channel<mapIt.first+m_channelPerBeetle;channel++)
+		{
+			double signal=static_cast<double>(p_inputData->getSignal(channel));
+			if(!m_masksProvider.isMasked(channel) && abs(signal) <m_hitThresholdPerBeetle[mapIt.first]){
+				mapIt.second+=signal;
+				rmsPerBeetle+=signal*signal;
+				usedChannels++;
+			}
+		}
+		if(usedChannels) mapIt.second/=static_cast<double>(usedChannels);
+		if(usedChannels) rmsPerBeetle/=static_cast<double>(usedChannels);
+		rmsPerBeetle-=mapIt.second*mapIt.second;
+		double rmsMultiplicity=4;
+		m_hitThresholdPerBeetle[mapIt.first]=rmsMultiplicity*sqrt(rmsPerBeetle);
+	}
+}
+
+template<typename INPUT_DATA_TYPE, typename OUTPUT_TYPE_NAME>
+void CMSIterativelyPerBeetle::removeCM(RawData<INPUT_DATA_TYPE>* p_data, RawData<OUTPUT_TYPE_NAME> **p_output)
+{
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		for(int channel=mapIt.first;channel<mapIt.first+m_channelPerBeetle;channel++)
+		{
+			if(m_masksProvider.isMasked(channel)){
+				OUTPUT_TYPE_NAME signalMaskedChannel=0;
+				(*p_output)->setSignal(signalMaskedChannel);
+			}else{
+				OUTPUT_TYPE_NAME l_channelSignal=p_data->getSignal(channel)-mapIt.second;
+				(*p_output)->setSignal(l_channelSignal);
+			}
+		}
+
+	}
+	 (*p_output)->setTDC(p_data->getTDC());
+	 (*p_output)->setTime(p_data->getTime());
+
+}
+
+void CMSIterativelyPerBeetle::resetHitThresholds()
+{
+	for(auto& mapIt : m_hitThresholdPerBeetle) mapIt.second=200;
+}
diff --git a/TbUT/src/TbUTCMSIterativelyPerBeetle.h b/TbUT/src/TbUTCMSIterativelyPerBeetle.h
new file mode 100644
index 0000000..3933302
--- /dev/null
+++ b/TbUT/src/TbUTCMSIterativelyPerBeetle.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "TbUTICommonModeSubtractor.h"
+#include "TbUTIChannelMaskProvider.h"
+
+#include <map>
+
+namespace TbUT
+{
+    class CMSIterativelyPerBeetle : public  ICommonModeSubtractor
+    {
+    public:
+        CMSIterativelyPerBeetle(IChannelMaskProvider& p_masksProvider);
+        void processEvent(RawData<>* p_data, RawData<double> **p_output);
+
+    private:
+	template<typename DATA_TYPE>
+        void calculateCorrection(RawData<DATA_TYPE>* p_inputData);
+	template<typename INPUT_DATA_TYPE, typename OUTPUT_TYPE_NAME>
+        void removeCM(RawData<INPUT_DATA_TYPE>* p_data, RawData<OUTPUT_TYPE_NAME> **p_output);
+        void resetHitThresholds();
+
+        void initializeCorrectionAndHitMaps();
+
+        IChannelMaskProvider& m_masksProvider;
+        const int m_channelNumber;
+        const int m_channelPerBeetle;
+    	std::map<int, double> m_correctionPerBeetle;
+    	std::map<int, double> m_hitThresholdPerBeetle;
+    };
+}
+
+
+
diff --git a/TbUT/src/TbUTCMSLinear.cpp b/TbUT/src/TbUTCMSLinear.cpp
new file mode 100644
index 0000000..0effdc0
--- /dev/null
+++ b/TbUT/src/TbUTCMSLinear.cpp
@@ -0,0 +1,53 @@
+/*
+ * CMSLinear.cpp
+ *
+ *  Created on: Nov 23, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCMSLinear.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace std;
+
+CMSLinear::CMSLinear(IChannelMaskProvider& p_masksProvider):
+		m_masksProvider(p_masksProvider),
+		m_channelNumber(RawData<>::getnChannelNumber())
+{
+}
+void CMSLinear::processEvent(RawData<>* p_data, RawData<double> **p_output)
+{
+	double l_correction = calculateCorrection(p_data);
+	for(int channel=0;channel<m_channelNumber;channel++){
+		removeCM(p_data,p_output,channel,l_correction);
+	}
+}
+
+double CMSLinear::calculateCorrection(RawData<>* p_inputData)
+{
+	double correction=0;
+	int usedChannels=0;
+	for(int channel=0;channel<m_channelNumber;channel++){
+		if(!m_masksProvider.isMasked(channel)){
+			correction+=p_inputData->getSignal(channel);
+			usedChannels++;
+		}
+	}
+	if(usedChannels) correction/=static_cast<double>(usedChannels);
+	return correction;
+}
+
+
+void CMSLinear::removeCM(RawData<>* p_data, RawData<double> **p_output, int p_channel, double p_correction)
+{
+	if(m_masksProvider.isMasked(p_channel))
+	{
+		double l_signalMaskedChannel=0;
+		(*p_output)->setSignal(l_signalMaskedChannel);
+	}else{
+		double l_channelSignal=p_data->getSignal(p_channel)-p_correction;
+				(*p_output)->setSignal(l_channelSignal);
+	}
+
+}
diff --git a/TbUT/src/TbUTCMSLinear.h b/TbUT/src/TbUTCMSLinear.h
new file mode 100644
index 0000000..574c814
--- /dev/null
+++ b/TbUT/src/TbUTCMSLinear.h
@@ -0,0 +1,31 @@
+/*
+ * CMSLinear.h
+ *
+ *  Created on: Nov 23, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTICommonModeSubtractor.h"
+#include "TbUTIChannelMaskProvider.h"
+
+namespace TbUT
+{
+
+class CMSLinear: public ICommonModeSubtractor
+{
+public:
+	CMSLinear(IChannelMaskProvider& p_masksProvider );
+	void processEvent(RawData<>* p_data, RawData<double> **p_output);
+
+private:
+	double calculateCorrection(RawData<>* p_inputData);
+	void removeCM(RawData<>* p_data, RawData<double> **p_output, int p_channel, double p_correction);
+
+	IChannelMaskProvider& m_masksProvider;
+	int m_channelNumber;
+};
+
+}
+
diff --git a/TbUT/src/TbUTChannelMaskFileValidator.cpp b/TbUT/src/TbUTChannelMaskFileValidator.cpp
new file mode 100644
index 0000000..121d7f7
--- /dev/null
+++ b/TbUT/src/TbUTChannelMaskFileValidator.cpp
@@ -0,0 +1,45 @@
+/*
+ * TbUTChannelMaskFileValidator.cpp
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTChannelMaskFileValidator.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace boost::filesystem;
+using namespace std;
+
+ChannelMaskFileValidator:: ChannelMaskFileValidator( std::string& p_filename):
+		m_filename(p_filename)
+{
+}
+
+ bool ChannelMaskFileValidator::validateFile()
+ {
+	 m_path=path(m_filename);
+	 bool l_result=
+			  isfileExist() &&
+			  isRegularFile() &&
+			  hasProperSize();
+	  return l_result;
+ }
+
+ bool ChannelMaskFileValidator::isfileExist()
+ {
+	 return exists(m_path);
+ }
+
+ bool ChannelMaskFileValidator::isRegularFile()
+ {
+	return  is_regular_file(m_path);
+ }
+
+ bool ChannelMaskFileValidator::hasProperSize()
+ {
+	unsigned int l_expectedSieze=1024;
+	cout<<file_size(m_path)<<endl;
+	return l_expectedSieze==file_size(m_path);
+ }
diff --git a/TbUT/src/TbUTChannelMaskFileValidator.h b/TbUT/src/TbUTChannelMaskFileValidator.h
new file mode 100644
index 0000000..a13b2bf
--- /dev/null
+++ b/TbUT/src/TbUTChannelMaskFileValidator.h
@@ -0,0 +1,31 @@
+/*
+ * TbUTChannelMaskFileValidator.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIFileValidator.h"
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace TbUT
+{
+class ChannelMaskFileValidator: public IFileValidator
+{
+public:
+	ChannelMaskFileValidator( std::string& p_filename);
+	bool validateFile();
+
+private:
+	bool isfileExist();
+	bool isRegularFile();
+	bool hasProperSize();
+
+
+	std::string& m_filename;
+	boost::filesystem::path  m_path;
+};
+}
+
diff --git a/TbUT/src/TbUTChannelMaskProvider.cpp b/TbUT/src/TbUTChannelMaskProvider.cpp
new file mode 100644
index 0000000..c674389
--- /dev/null
+++ b/TbUT/src/TbUTChannelMaskProvider.cpp
@@ -0,0 +1,77 @@
+/*
+ * TbUTChannelMaskProvider.cpp
+ *
+ *  Created on: Oct 11, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTChannelMaskProvider.h"
+#include"TbUTRawData.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace std;
+
+
+ChannelMaskProvider::ChannelMaskProvider(IFileValidator & p_fileValidator):
+		m_fileValidator(p_fileValidator),
+		m_masks()
+{
+}
+
+void ChannelMaskProvider::getMaskFromFile(const string& p_filename)
+{
+	validateFile();
+	ifstream l_file;
+	openfile(p_filename,l_file);
+	retreiveMasksFromFile(l_file);
+	checkMaskVector();
+}
+
+bool ChannelMaskProvider::isMasked(int p_channel)
+{
+	if(!isChannelInRange(p_channel)){
+		std::cout<<"channel out of range"<<p_channel<<std::endl;
+		throw ChannelOutOfRange("");
+	}
+	return (m_masks[p_channel]==0);
+}
+
+
+
+void ChannelMaskProvider::validateFile()
+{
+	if(!m_fileValidator.validateFile())
+		throw InputFileError("Mask File validation error!");
+
+}
+
+void ChannelMaskProvider::openfile(const std::string& p_filename, std::ifstream& p_inputFile)
+{
+	p_inputFile.open(p_filename.c_str(),ios::in);
+	if(!p_inputFile.good())
+		throw InputFileError("Cannot open mask file!"+p_filename);
+}
+
+void ChannelMaskProvider::retreiveMasksFromFile(std::ifstream& p_file)
+{
+	int l_sensorNumber= RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_sensorNumber;channel++){
+		unsigned short l_mask;
+		p_file>>l_mask;
+		m_masks.push_back(l_mask);
+	}
+}
+
+void ChannelMaskProvider::checkMaskVector()
+{
+	const unsigned int l_sensorNumber=RawData<>::getnChannelNumber();
+	if (m_masks.size() !=l_sensorNumber)
+		throw NotEnoughtChannel("");
+}
+
+bool ChannelMaskProvider::isChannelInRange(int p_channel)
+{
+	int l_sensorNumber= RawData<>::getnChannelNumber();
+	return p_channel<l_sensorNumber;
+}
diff --git a/TbUT/src/TbUTChannelMaskProvider.h b/TbUT/src/TbUTChannelMaskProvider.h
new file mode 100644
index 0000000..4446511
--- /dev/null
+++ b/TbUT/src/TbUTChannelMaskProvider.h
@@ -0,0 +1,68 @@
+/*
+ * TbUTChannelMaskProvider.h
+ *
+ *  Created on: Oct 11, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTIFileValidator.h"
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <stdexcept>
+
+
+namespace TbUT
+{
+class ChannelMaskProvider: public IChannelMaskProvider
+{
+public:
+
+	class InputFileError: public std::runtime_error	{
+	public:
+		InputFileError(const std::string& p_errorMsg ):
+				std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+
+	class NotEnoughtChannel: public std::runtime_error	{
+	public:
+		NotEnoughtChannel(const std::string& p_error) :
+				std::runtime_error(p_error)
+		{
+		}
+	};
+
+	class ChannelOutOfRange: public std::runtime_error	{
+	public:
+		ChannelOutOfRange(const std::string& p_error) :
+				std::runtime_error(p_error)
+		{
+		}
+	};
+
+	ChannelMaskProvider(IFileValidator & p_fileValidator);
+	void getMaskFromFile(const std::string& p_filename=TbUT::DataLocations::MaskLocation);
+	bool isMasked(int p_channel);
+
+private:
+	typedef std::vector<unsigned short> MaskVector;
+
+	void validateFile();
+	void openfile(const std::string& p_filename, std::ifstream& p_inputFile);
+	void retreiveMasksFromFile(std::ifstream& p_file);
+	void checkMaskVector();
+	bool isChannelInRange(int p_channel);
+
+
+
+	IFileValidator & m_fileValidator;
+	MaskVector m_masks;
+};
+}
+
+
diff --git a/TbUT/src/TbUTCluster.cpp b/TbUT/src/TbUTCluster.cpp
new file mode 100644
index 0000000..51744de
--- /dev/null
+++ b/TbUT/src/TbUTCluster.cpp
@@ -0,0 +1,44 @@
+/*
+ * TbUTCluster.cpp
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTCluster.h"
+
+using namespace TbUT;
+
+
+Cluster::Cluster():
+		m_position(0),
+		m_size(0),
+		m_charge(0),
+		m_chargeSeed(0),
+		m_charge2StripLeft(0),
+		m_charge1StripLeft(0),
+		m_charge2StripRight(0),
+		m_charge1StripRight(0)
+{
+}
+
+ClusterContainer::ClusterContainer():
+		m_isEmpty(true),
+		m_clusterVector(),
+		m_timestamp(0),
+		m_tdc(0)
+{
+}
+
+void ClusterContainer::setClusters(ClusterVector& p_clusterVec)
+{
+	m_clusterVector=p_clusterVec;
+	m_isEmpty=false;
+}
+
+void ClusterContainer::addClusters(ClusterVector& p_cluster)
+{
+	m_isEmpty=false;
+	m_clusterVector.insert(m_clusterVector.begin(),p_cluster.begin(),p_cluster.end());
+}
+
diff --git a/TbUT/src/TbUTCluster.h b/TbUT/src/TbUTCluster.h
new file mode 100644
index 0000000..1f576db
--- /dev/null
+++ b/TbUT/src/TbUTCluster.h
@@ -0,0 +1,56 @@
+/*
+ * TbUTCluster.h
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "GaudiKernel/DataObject.h"
+#include "TbUTRawData.h"
+#include <vector>
+
+namespace TbUT
+{
+
+struct Cluster
+{
+	Cluster();
+	double m_position;
+	int m_seedPosition;
+	int m_size;
+	double m_charge;
+	double m_chargeSeed;
+	double m_charge2StripLeft;
+	double m_charge1StripLeft;
+	double m_charge2StripRight;
+	double m_charge1StripRight;
+};
+
+class ClusterContainer : public DataObject
+{
+public:
+	typedef std::vector<Cluster> ClusterVector;
+	ClusterContainer();
+	void addCluster(Cluster& p_cluster);
+	void addClusters(ClusterVector& p_cluster);
+
+	void setClusters(ClusterVector& p_clusterVec);
+	int size(){return m_clusterVector.size(); }
+	ClusterVector getClusters(){return m_clusterVector;};
+	bool isEmpty(){return m_isEmpty;}
+	unsigned int getTDC()const {return m_tdc;}
+	void setTDC(unsigned int p_tdc){m_tdc=p_tdc;}
+
+	unsigned long long getTimestamp() const {return m_timestamp;}
+	void setTiemestamp(unsigned long long p_timestamp){m_timestamp =p_timestamp;}
+
+private:
+	bool m_isEmpty;
+	ClusterVector m_clusterVector;
+	unsigned long long m_timestamp;
+	unsigned int m_tdc;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTClusterCreator.cpp b/TbUT/src/TbUTClusterCreator.cpp
new file mode 100644
index 0000000..73463a4
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreator.cpp
@@ -0,0 +1,234 @@
+/*
+ * TbUTClusterCreator.cpp
+ *
+ *  Created on: Jan 5, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreator.h"
+#include <iostream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+ClusterCreator::ClusterCreator(const std::string&  p_sensorType,ITresholdProvider& p_thresholds):
+		m_clusterMaxSize(4),
+		m_thresholds(p_thresholds),
+		m_culsterVector()
+{
+	convertStringToSensorType(p_sensorType);
+}
+
+ClusterContainer::ClusterVector ClusterCreator::createClusters(RawData<double> *p_inputData)
+{
+	m_culsterVector.clear();
+	findCulsterSeeds(p_inputData);
+	removeDuplicatedSeeds(p_inputData);
+	extendClusterSeeds(p_inputData);
+	fillOuterStrips(p_inputData);
+	return m_culsterVector;
+}
+
+void ClusterCreator::convertStringToSensorType(const std::string& p_sensorType)
+{
+	if(p_sensorType == "PType")
+		m_sensorType= ClusterCreator::SensorType::P_TYPE;
+	else if (p_sensorType == "NType")
+		m_sensorType= ClusterCreator::SensorType::N_TYPE;
+	else
+		m_sensorType= ClusterCreator::SensorType::CUSTOM;
+}
+
+void ClusterCreator::findCulsterSeeds(RawData<double> *p_inputData)
+{
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(auto channel=0;channel<l_channelNumber;channel++){
+		auto l_channelSignal=p_inputData->getSignal(channel);
+		if(isBiggerThanSeedThreshold(l_channelSignal,channel ))
+			m_culsterVector.push_back(createCluster(p_inputData,channel));
+	}
+
+}
+
+bool ClusterCreator::isBiggerThanSeedThreshold(RawData<double>::DataType p_channelSignal, int p_channel) const
+{
+	double l_channelThreshold=m_thresholds.getHighClusterThreshold(p_channel);
+
+	switch(m_sensorType)
+	{
+	case ClusterCreator::SensorType::P_TYPE:
+		return p_channelSignal<(-1)*l_channelThreshold;
+	case ClusterCreator::SensorType::N_TYPE:
+		return p_channelSignal>l_channelThreshold;
+	default:
+		return abs(p_channelSignal) >l_channelThreshold ;
+	}
+}
+
+Cluster ClusterCreator::createCluster(RawData<double> *p_inputData, int l_channel) const
+{
+	int l_seedSize=1;
+	Cluster l_cluster;
+	l_cluster.m_charge=p_inputData->getSignal(l_channel);
+	l_cluster.m_chargeSeed=p_inputData->getSignal(l_channel);
+	l_cluster.m_seedPosition=l_channel;
+	l_cluster.m_size=l_seedSize;
+	l_cluster.m_position=l_channel*abs(l_cluster.m_charge); //position is weighted average, weight charge
+
+	return l_cluster;
+}
+
+void ClusterCreator::removeDuplicatedSeeds(RawData<double> *p_inputData)
+{
+	if(0==m_culsterVector.size()) return;
+	for(auto firstClusterIt = m_culsterVector.begin();firstClusterIt!=m_culsterVector.end();firstClusterIt++)
+	{
+		for(auto secondClusterIt=firstClusterIt+1;secondClusterIt!=m_culsterVector.end();)
+		{
+			if(arePartOfTheSameCluster(p_inputData, firstClusterIt,secondClusterIt))
+				removeClusterSeedWithSmallerCharge(firstClusterIt,secondClusterIt);
+			else
+				secondClusterIt++;
+			if(secondClusterIt==m_culsterVector.end()) break;
+		}
+		if(firstClusterIt==m_culsterVector.end()) break;
+	}
+}
+
+bool ClusterCreator::arePartOfTheSameCluster(RawData<double>* p_inputData, ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const
+{
+	if(!canBePartOfTheSameCluster(p_firstIt, p_secondIt)) return false;
+
+    auto channelRIterator=p_secondIt->m_seedPosition-1; // take previous strip position than pointed by secondIt
+	auto firstSeedPosition=p_firstIt->m_seedPosition;
+	for(;channelRIterator>firstSeedPosition;channelRIterator--){
+		auto channelCharge=p_inputData->getSignal(channelRIterator);
+		if(! isBiggerThanLowThreshold(channelCharge,channelRIterator) ) return false;
+	}
+	return true;
+}
+
+
+bool ClusterCreator::canBePartOfTheSameCluster(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const
+{
+	int seedDistance=abs(p_firstIt->m_seedPosition-p_secondIt->m_seedPosition);
+	return seedDistance<m_clusterMaxSize;
+}
+
+void ClusterCreator::removeClusterSeedWithSmallerCharge(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt)
+{
+	if(abs(p_firstIt->m_charge)>abs(p_secondIt->m_charge))
+		p_secondIt=m_culsterVector.erase(p_secondIt);
+	else{
+		p_firstIt =m_culsterVector.erase(p_firstIt);
+		p_secondIt=p_firstIt+1;
+	}
+}
+
+void ClusterCreator::extendClusterSeeds(RawData<double> *p_inputData)
+{
+	for(auto clusterIt = m_culsterVector.begin();clusterIt!=m_culsterVector.end();clusterIt++)
+	{
+		extendCluster(clusterIt, p_inputData);
+	}
+}
+
+void ClusterCreator::extendCluster(ClusterIterator& p_clusterIt,RawData<double>* p_inputData)
+{
+	int l_actualShift=1;
+	bool l_checkLeft=true;
+	bool l_checkRight=true;
+	bool l_isCheckingLeft=true;
+
+
+	while(hasNotMaximumSize(p_clusterIt))
+	{
+		l_isCheckingLeft=true;
+		if(l_checkLeft && (l_checkLeft=isStripNeedToBeAddedToCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft ) ) ){
+			updateCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft);
+		}
+		if(! hasNotMaximumSize(p_clusterIt) ) break;
+
+		l_isCheckingLeft=false;
+		if(l_checkRight && (l_checkRight=isStripNeedToBeAddedToCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft ) ) ) updateCluster(p_clusterIt,p_inputData, l_actualShift, l_isCheckingLeft);
+		l_actualShift++;
+		if(!l_checkLeft && !l_checkRight ) break;
+	}
+}
+
+bool ClusterCreator::hasNotMaximumSize(ClusterIterator& p_firstIt) const
+{
+	return p_firstIt->m_size<m_clusterMaxSize;
+}
+
+bool ClusterCreator::isStripNeedToBeAddedToCluster(ClusterIterator& p_clusterIt, RawData<double> *p_inputData, int p_stripShift,bool p_isCheckingLeft ) const
+{
+	int l_sign =(p_isCheckingLeft)? -1:1;
+	int l_channelNumber=p_clusterIt->m_seedPosition+l_sign*p_stripShift;
+
+	if(isInvalidChannelNumber(l_channelNumber ) ) return false;
+
+	double l_channelSignal=p_inputData->getSignal(l_channelNumber);
+	return isBiggerThanLowThreshold(l_channelSignal, l_channelNumber);
+}
+
+void ClusterCreator::updateCluster(ClusterIterator& p_clusterIt,RawData<double> *p_inputData ,int p_stripShift, bool p_isCheckingLeft)
+{
+	int l_sign =(p_isCheckingLeft)? -1:1;
+	int l_channelNumber=p_clusterIt->m_seedPosition+l_sign*p_stripShift;
+	auto l_channelSignal=p_inputData->getSignal(l_channelNumber);
+	p_clusterIt->m_charge+=l_channelSignal;
+	p_clusterIt->m_size+=1;
+	p_clusterIt->m_position+=l_channelNumber*abs(l_channelSignal);
+}
+
+bool ClusterCreator::isInvalidChannelNumber(int p_stripNumber) const
+{
+	if(p_stripNumber<RawData<>::getMinChannel()) return true;
+	if(p_stripNumber>RawData<>::getMaxChannel()) return true;
+	return false;
+}
+
+bool ClusterCreator::isBiggerThanLowThreshold(RawData<double>::DataType p_channelSignal, int p_chnnel) const
+{
+	double l_threshold=m_thresholds.getLowClusterThreshold(p_chnnel);
+	switch(m_sensorType)
+	{
+	case SensorType::P_TYPE:
+		return p_channelSignal<(-1)*l_threshold;
+	case SensorType::N_TYPE:
+		return p_channelSignal>l_threshold;
+	default:
+		return abs(p_channelSignal) >l_threshold ;
+	}
+}
+
+
+void ClusterCreator::fillOuterStrips(RawData<double> *p_inputData)
+{
+	for(auto& cluster : m_culsterVector){
+		int position=cluster.m_seedPosition;
+		int oneLeft=position-1;
+		if(isInvalidChannelNumber(oneLeft)) cluster.m_charge1StripLeft = 0 ;
+		else cluster.m_charge1StripLeft = p_inputData->getSignal(oneLeft) ;
+
+		int twoLeft=oneLeft-1;
+		if(isInvalidChannelNumber(twoLeft)) cluster.m_charge2StripLeft = 0;
+		else cluster.m_charge2StripLeft = p_inputData->getSignal(twoLeft) ;
+
+		int oneRight=position+1;
+		if(isInvalidChannelNumber(oneRight)) cluster.m_charge1StripRight = 0 ;
+		else cluster.m_charge1StripRight = p_inputData->getSignal(oneRight) ;
+
+		int twoRight=oneRight+1;
+		if(isInvalidChannelNumber(twoRight)) cluster.m_charge2StripRight = 0;
+		else cluster.m_charge2StripRight = p_inputData->getSignal(twoRight) ;
+
+		/// normalize position
+		cluster.m_position/=abs(cluster.m_charge);
+	}
+}
+
+
+
diff --git a/TbUT/src/TbUTClusterCreator.h b/TbUT/src/TbUTClusterCreator.h
new file mode 100644
index 0000000..b7ab422
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreator.h
@@ -0,0 +1,65 @@
+/*
+ * TbUTClusterCreator.h
+ *
+ *  Created on: Jan 5, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIClusterCreator.h"
+#include "TbUTITresholdProvider.h"
+
+namespace TbUT
+{
+
+class ClusterCreator: public IClusterCreator
+{
+public:
+	ClusterCreator(const std::string&  p_sensorType, ITresholdProvider& p_thresholds);
+	ClusterContainer::ClusterVector createClusters(RawData<double> *p_inputData);
+
+private:
+	 enum SensorType
+	   {
+	      P_TYPE,
+	      N_TYPE,
+	      CUSTOM
+	   };
+
+	typedef ClusterContainer::ClusterVector::iterator ClusterIterator;
+
+	void convertStringToSensorType(const std::string& p_sensorType);
+
+	void findCulsterSeeds(RawData<double> *p_inputData);
+	void removeDuplicatedSeeds(RawData<double> *p_inputData);
+	void extendClusterSeeds(RawData<double> *p_inputData);
+
+	bool isBiggerThanSeedThreshold(RawData<double>::DataType p_channelSignal, int p_channel) const;
+	Cluster createCluster(RawData<double> *p_inputData, int l_channelNumber) const;
+
+	bool arePartOfTheSameCluster(RawData<double>* p_inputData, ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const;
+	bool canBePartOfTheSameCluster(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt) const;
+
+	void extendCluster(ClusterIterator& p_clusterIt, RawData<double>* p_inputData);
+	void removeClusterSeedWithSmallerCharge(ClusterIterator& p_firstIt, ClusterIterator& p_secondIt);
+	bool hasNotMaximumSize(ClusterIterator& p_clusterIt) const;
+	bool isStripNeedToBeAddedToCluster(ClusterIterator& p_clusterIt, RawData<double> *p_inputData,int p_stripShift, bool p_isCheckingLeft  ) const;
+	void updateCluster(ClusterIterator& p_clusterIt,RawData<double> *p_inputData ,int p_stripShift, bool p_isCheckingLeft);
+	bool isInvalidChannelNumber(int p_stripShift) const;
+	bool isBiggerThanLowThreshold(RawData<double>::DataType p_channelSignal, int p_chnnel) const;
+	void normalizeClusterPosition(ClusterIterator& p_clusterIt);
+	void fillOuterStrips(RawData<double> *p_inputData);
+
+
+
+	const int m_clusterMaxSize;
+	ITresholdProvider& m_thresholds;
+	ClusterContainer::ClusterVector m_culsterVector;
+	SensorType m_sensorType;
+
+};
+
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTClusterCreatorAlgorithm.cpp b/TbUT/src/TbUTClusterCreatorAlgorithm.cpp
new file mode 100644
index 0000000..e44ad04
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreatorAlgorithm.cpp
@@ -0,0 +1,126 @@
+/*
+ * TbUTClusterCreatorAlgorithm.cpp
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreatorAlgorithm.h"
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,ClusterCreatorAlgorithm)
+
+ClusterCreatorAlgorithm::ClusterCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+GaudiAlgorithm(name, pSvcLocator),
+m_dataContainer(),
+m_data(),
+m_inputDataLocation(),
+m_outputDataLocation(),
+m_clusterCreatorOption(),
+m_noiseFile(),
+m_sensorType(),
+m_event(),
+m_skipEvent(),
+m_lowThreshold(),
+m_highThreshold(),
+m_zsThresholdProvider(m_noiseFile,m_lowThreshold,m_highThreshold),
+m_clusterCreatorFactory(m_sensorType,m_zsThresholdProvider),
+m_clusterCreator()
+{
+	declareProperty("InputDataLocation", m_inputDataLocation=TbUT::DataLocations::CMSTES);
+	declareProperty("OutputDataLocation", m_outputDataLocation=TbUT::DataLocations::Clusters_TES);
+	declareProperty("ClusterCreatorOption",m_clusterCreatorOption=TbUT::ClusterCreatorType::defaultCreator);
+	declareProperty("NoiseInputFile",m_noiseFile=TbUT::DataLocations::NoiseTreshold);
+	declareProperty("skippEventNumber",m_skipEvent=0);
+	declareProperty("sensorType",m_sensorType="PType");
+	declareProperty("LowThreshold",m_lowThreshold=3);
+	declareProperty("HighThreshold",m_highThreshold=4);
+}
+
+
+StatusCode ClusterCreatorAlgorithm::initialize()
+{
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildClusterCreator()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=retreiveNoise()) return StatusCode::FAILURE;
+
+	info()<<"Cluster thresholds (unit of noise multiplicity):"<<endmsg;
+	info()<<"Low:" <<m_lowThreshold <<endmsg;
+	info()<<"high:" <<m_highThreshold <<endmsg;
+
+	info()<<"Initialized successfully!"<<endmsg;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode ClusterCreatorAlgorithm::execute()
+{
+	if(m_event<m_skipEvent)
+	{
+		m_event++;
+		return StatusCode::SUCCESS;
+	}
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()){
+		ClusterContainer *l_clontainer=new ClusterContainer();
+		put(l_clontainer,m_outputDataLocation);
+		return StatusCode::SUCCESS;
+	}
+	processAndSaveDataToTES();
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode ClusterCreatorAlgorithm::finalize()
+{
+	return GaudiAlgorithm::finalize();
+}
+
+StatusCode ClusterCreatorAlgorithm::initializeBase()
+{
+	return GaudiAlgorithm::initialize();
+}
+
+StatusCode ClusterCreatorAlgorithm::buildClusterCreator()
+try{
+	m_clusterCreator=m_clusterCreatorFactory.createClusterCreator(m_clusterCreatorOption);
+	return StatusCode::SUCCESS;
+}catch(ClusterCreatorFactory::NoSuchState &exception)
+{
+	error()<<"Invalid ZS Engine Type  : "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+StatusCode ClusterCreatorAlgorithm::retreiveNoise()
+try{
+	m_zsThresholdProvider.retreiveTresholds();
+	return StatusCode::SUCCESS;
+}catch(ITresholdProvider::ThresholdProviderError &err){
+	error()<<"Cannot open Noise file: "<<err.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode ClusterCreatorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer <double> >(m_inputDataLocation);
+	if(!m_dataContainer){
+		error()<< " ==> There is no input data: "<< m_inputDataLocation <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+void ClusterCreatorAlgorithm::processAndSaveDataToTES()
+{
+	ClusterContainer *l_container=new ClusterContainer();
+	for(const auto& rawDataIt: m_dataContainer->getData()){
+		m_data=new RawData<double>(rawDataIt);
+		ClusterContainer::ClusterVector clusterVector=m_clusterCreator->createClusters(m_data);
+		l_container->addClusters(clusterVector);
+		l_container->setTDC(m_data->getTDC());
+		l_container->setTiemestamp(m_data->getTime());
+		delete m_data;
+	}
+	put(l_container,m_outputDataLocation);
+}
diff --git a/TbUT/src/TbUTClusterCreatorAlgorithm.h b/TbUT/src/TbUTClusterCreatorAlgorithm.h
new file mode 100644
index 0000000..7d8a7ab
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreatorAlgorithm.h
@@ -0,0 +1,57 @@
+/*
+ * TbUTClusterCreatorAlgorithm.h
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+#include "TbUTRawData.h"
+#include "TbUTClusterCreatorFactory.h"
+#include "TbUTTresholdProvider.h"
+#include "TbUTCluster.h"
+
+
+namespace TbUT
+{
+
+class ClusterCreatorAlgorithm :  public GaudiAlgorithm
+{
+public:
+	ClusterCreatorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+	virtual StatusCode finalize();
+
+private:
+
+	StatusCode initializeBase();
+	StatusCode buildClusterCreator();
+	StatusCode retreiveNoise();
+
+	StatusCode getData();
+	void processAndSaveDataToTES();
+
+	RawDataContainer<double>* m_dataContainer;
+	RawData<double>* m_data;
+
+	std::string m_inputDataLocation;
+	std::string m_outputDataLocation;
+	std::string m_clusterCreatorOption;
+	std::string m_noiseFile;
+	std::string m_sensorType;
+	int m_event;
+	int m_skipEvent;
+	double m_lowThreshold;
+	double m_highThreshold;
+
+	TresholdProvider m_zsThresholdProvider;
+	ClusterCreatorFactory m_clusterCreatorFactory;
+	ClusterCreatorFactory::ClusterCreatorPtr m_clusterCreator;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.cpp b/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.cpp
new file mode 100644
index 0000000..fec60a2
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.cpp
@@ -0,0 +1,248 @@
+/*
+ * TbUTClusterCreatorDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreatorDataMonitorAlgorithm.h"
+#include "TbUTRawData.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include <boost/format.hpp>
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,ClusterCreatorDataMonitorAlgorithm)
+
+ClusterCreatorDataMonitorAlgorithm::ClusterCreatorDataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator ):
+		GaudiHistoAlg ( name , pSvcLocator ),
+		m_evtNumber(0),
+		m_skipEvent(0),
+		m_displayEventNumber(0),
+		m_inputDataLoc(TbUT::DataLocations::Clusters_TES),
+		m_sensorType()
+{
+    declareProperty("skippEventNumber", m_skipEvent=10);
+    declareProperty("displayEventNumber", m_displayEventNumber=10);
+    declareProperty("sensorType",m_sensorType="PType");
+
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::initialize() {
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	setHistoTopDir( const_cast<char*>("TbUT/") );
+	createHistograms();
+  	return StatusCode::SUCCESS;
+}
+
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::execute()
+{
+	if(m_evtNumber<m_skipEvent)
+		return skippEvent();
+	else
+		return fillHistograms();
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::finalize()
+{
+	return GaudiHistoAlg::finalize();
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::initializeBase()
+{
+	  return GaudiHistoAlg::initialize();
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::getData()
+{
+	if(!exist<ClusterContainer>(m_inputDataLoc)){
+		error()<< " ==> There is no input data: "<< m_inputDataLoc <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	m_clusters=get<ClusterContainer>(m_inputDataLoc);
+	if(!m_clusters){
+		error()<< " ==> Input data is Null!"<<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createHistograms()
+{
+	createClusterNumberPerEventHistogram();
+	createClusterNumberHistogram();
+	createClusterSizeHistogram();
+	createClusterChargeHistograms();
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterNumberPerEventHistogram()
+{
+	double l_xmin=0;
+	double l_xmax=6;
+	int l_nbin=6;
+	const std::string l_histogramName="ClusterNumberPerEvent";
+	const std::string l_histogramTitle="Cluster Number Per Event";
+	m_histogramClusterNumberPerEvent=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterNumberHistogram()
+{
+	double l_xmin=-0.5+RawData<>::getMinChannel();
+	double l_xmax=RawData<>::getMaxChannel()-0.5;
+	int l_nbin=RawData<>::getnChannelNumber();
+	std::string l_histogramName="ClusterNumber";
+	std::string l_histogramTitle="Cluster Number vs channel";
+	m_histogramClusterNumber=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterSeedPosition";
+	l_histogramTitle="Cluster Seed Position";
+	m_histogramClusterSeedPosition=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterSizeHistogram()
+{
+	double l_xmin=-0.5;
+	double l_xmax=5.5;
+	int l_nbin=20;
+	const std::string l_histogramName="ClusterSize";
+	const std::string l_histogramTitle="Cluster Size";
+	m_histogramClusterSize=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+}
+
+void ClusterCreatorDataMonitorAlgorithm::createClusterChargeHistograms()
+{
+	double l_xmin;
+	double l_xmax;
+
+	if(m_sensorType=="PType"){
+		l_xmin=-1500.;
+		l_xmax=-1.;
+	}else if(m_sensorType=="NType"){
+		l_xmin=1.;
+		l_xmax=1500.;
+	}else{
+		l_xmin=-1500.;
+		l_xmax=1500.;
+	}
+
+	int l_nbin=100;
+	std::string l_histogramName="ClusterCharge";
+	std::string l_histogramTitle="Cluster Charge";
+	m_histogramClusterCharge=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterChargeSingleStrip";
+	l_histogramTitle="Cluster Charge Single Strip";
+	m_histogramClusterChargeSingleStrip=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterChargeDoubleStrip";
+	l_histogramTitle="Cluster Charge Double Strip";
+	m_histogramClusterChargeDoubleStrip=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+	l_histogramName="ClusterChargeTripleStrip";
+	l_histogramTitle="Cluster Charge Triple Strip";
+	m_histogramClusterChargeTripleStrip=Gaudi::Utils::Aida2ROOT::aida2root(book1D( l_histogramName, l_histogramTitle,l_xmin, l_xmax, l_nbin ));
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::skippEvent()
+{
+	m_evtNumber++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode ClusterCreatorDataMonitorAlgorithm::fillHistograms()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_clusters->isEmpty())
+	{
+		m_histogramClusterNumberPerEvent->Fill(0.);
+		m_evtNumber++;
+		return StatusCode::SUCCESS;
+	}
+	auto l_clusters=m_clusters->getClusters();
+	fillClusterNumberHistogram(l_clusters);
+	fillClusterSizeHistogram(l_clusters);
+	fillClusterChargeHistograms(l_clusters);
+	if(m_evtNumber<m_displayEventNumber+m_skipEvent)fillEventsHistograms(l_clusters);
+	m_evtNumber++;
+	return StatusCode::SUCCESS;
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillClusterNumberHistogram(ClusterContainer::ClusterVector& p_clusters)
+{
+	m_histogramClusterNumberPerEvent->Fill(p_clusters.size());
+	for(const auto& l_cluster: p_clusters )
+	{
+		auto l_position=l_cluster.m_position;
+		l_position+=RawData<>::getMinChannel();
+		m_histogramClusterNumber->Fill(l_position);
+		auto l_seedPosition=l_cluster.m_seedPosition;
+		m_histogramClusterSeedPosition->Fill(l_seedPosition);
+	}
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillClusterSizeHistogram(ClusterContainer::ClusterVector& p_clusters)
+{
+	for(const auto& l_cluster: p_clusters ){
+		auto l_size=l_cluster.m_size;
+		m_histogramClusterSize->Fill(l_size);
+	}
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillClusterChargeHistograms(ClusterContainer::ClusterVector& p_clusters)
+{
+	using namespace std;
+	for(const auto& l_cluster: p_clusters )
+	{
+		auto l_charge=l_cluster.m_charge;
+		m_histogramClusterCharge->Fill(l_charge);
+		switch(l_cluster.m_size)
+		{
+		case 1:
+			m_histogramClusterChargeSingleStrip->Fill(l_charge);
+			break;
+		case 2:
+			m_histogramClusterChargeDoubleStrip->Fill(l_charge);
+			break;
+		case 3:
+			m_histogramClusterChargeTripleStrip->Fill(l_charge);
+			break;
+		}
+	}
+}
+
+
+void ClusterCreatorDataMonitorAlgorithm::fillEventsHistograms(ClusterContainer::ClusterVector& p_clusters)
+{
+	for(const auto& l_cluster: p_clusters )
+	{
+			auto l_position=l_cluster.m_position;
+			auto l_charge=l_cluster.m_charge;
+			auto l_size=l_cluster.m_size;
+
+			auto l_name=createSingleEventHistogramName("charge");
+			auto l_histogram=bookHistogram(l_name);
+			fillSingleEventHistogram(l_histogram,l_position,l_charge);
+
+			l_name=createSingleEventHistogramName("size");
+			l_histogram=bookHistogram(l_name);
+			fillSingleEventHistogram(l_histogram,l_position,l_size);
+		}
+}
+
+TH1D* ClusterCreatorDataMonitorAlgorithm::bookHistogram(const std::string& p_histogramName)
+{
+	return Gaudi::Utils::Aida2ROOT::aida2root(book1D( p_histogramName,	p_histogramName,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,RawData<>::getnChannelNumber() ));
+}
+
+void ClusterCreatorDataMonitorAlgorithm::fillSingleEventHistogram(TH1D* p_histogram, int p_channel, double p_value)
+{
+	p_histogram->SetBinContent(p_channel,p_value);
+}
+
+std::string ClusterCreatorDataMonitorAlgorithm::createSingleEventHistogramName(std::string p_HistogramType)
+{
+	using namespace boost;
+	boost::format l_histogramName("cluster_%s_event_%d");
+		l_histogramName % p_HistogramType % m_evtNumber;
+		return str(l_histogramName);
+}
diff --git a/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.h b/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.h
new file mode 100644
index 0000000..fa528db
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreatorDataMonitorAlgorithm.h
@@ -0,0 +1,67 @@
+/*
+ * TbUTClusterCreatorDataMonitorAlgorithm.h
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "GaudiAlg/GaudiHistoAlg.h"
+#include "TbUTCluster.h"
+#include <TH1D.h>
+
+namespace TbUT
+{
+
+class ClusterCreatorDataMonitorAlgorithm: public GaudiHistoAlg
+{
+public:
+	ClusterCreatorDataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute   ();
+	virtual StatusCode finalize  ();
+private:
+
+	virtual StatusCode getData();
+	virtual StatusCode initializeBase();
+	virtual void createHistograms();
+
+	virtual StatusCode skippEvent();
+	virtual StatusCode fillHistograms();
+	virtual void createClusterNumberPerEventHistogram();
+	virtual void createClusterNumberHistogram();
+	virtual void createClusterSizeHistogram();
+	virtual void createClusterChargeHistograms();
+
+	virtual void fillClusterNumberHistogram(ClusterContainer::ClusterVector& p_clusters);
+	virtual void fillClusterSizeHistogram(ClusterContainer::ClusterVector& p_clusters);
+	virtual void fillClusterChargeHistograms(ClusterContainer::ClusterVector& p_clusters);
+
+	virtual void  fillEventsHistograms(ClusterContainer::ClusterVector& p_clusters);
+	virtual TH1D* bookHistogram(const std::string& p_histogramName);
+	virtual void fillSingleEventHistogram(TH1D* p_histogram, int p_channel, double p_value);
+	virtual std::string createSingleEventHistogramName(std::string p_HistogramType);
+
+	int m_evtNumber;
+    int m_skipEvent;
+    int m_displayEventNumber;
+	std::string m_inputDataLoc;
+	std::string m_sensorType;
+
+	ClusterContainer* m_clusters;
+	TH1D* m_histogramClusterNumber;
+	TH1D* m_histogramClusterSeedPosition;
+	TH1D* m_histogramClusterNumberPerEvent;
+	TH1D* m_histogramClusterSize;
+	TH1D* m_histogramClusterCharge;
+	TH1D* m_histogramClusterChargeSingleStrip;
+	TH1D* m_histogramClusterChargeDoubleStrip;
+	TH1D* m_histogramClusterChargeTripleStrip;
+
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTClusterCreatorFactory.cpp b/TbUT/src/TbUTClusterCreatorFactory.cpp
new file mode 100644
index 0000000..56d532a
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreatorFactory.cpp
@@ -0,0 +1,26 @@
+/*
+ * TbUTClusterCreatorFactory.cpp
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTClusterCreatorFactory.h"
+#include "TbUTClusterCreator.h"
+
+using namespace TbUT;
+
+
+ClusterCreatorFactory::ClusterCreatorFactory(const std::string&  p_sensorType, ITresholdProvider & p_tresholds):
+	m_sensorType(p_sensorType),
+	m_thresholdPrivder(p_tresholds)
+{
+}
+
+ClusterCreatorFactory::ClusterCreatorPtr ClusterCreatorFactory::createClusterCreator(const std::string& p_clusterCreatorType)
+{
+	if(p_clusterCreatorType == TbUT::ClusterCreatorType::defaultCreator)
+		return ClusterCreatorPtr(new ClusterCreator(m_sensorType,m_thresholdPrivder));
+	else
+		throw NoSuchState(p_clusterCreatorType);
+}
diff --git a/TbUT/src/TbUTClusterCreatorFactory.h b/TbUT/src/TbUTClusterCreatorFactory.h
new file mode 100644
index 0000000..8749919
--- /dev/null
+++ b/TbUT/src/TbUTClusterCreatorFactory.h
@@ -0,0 +1,45 @@
+/*
+ * TbUTClusterCreatorFactory.h
+ *
+ *  Created on: Jan 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include "TbUTITresholdProvider.h"
+#include "TbUTIClusterCreator.h"
+
+namespace TbUT
+{
+
+namespace ClusterCreatorType
+{
+static const std::string& defaultCreator = "default";
+}
+
+class ClusterCreatorFactory
+{
+public:
+	typedef boost::shared_ptr<IClusterCreator> ClusterCreatorPtr;
+
+	ClusterCreatorFactory(const std::string&  p_sensorType, ITresholdProvider & p_tresholds);
+	ClusterCreatorPtr createClusterCreator(const std::string& p_clusterCreatorType);
+
+	class NoSuchState: public std::runtime_error
+	{
+	public:
+		NoSuchState(const std::string& p_errorMsg ):
+			std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+private:
+	const std::string&  m_sensorType;
+	ITresholdProvider& m_thresholdPrivder;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTCmsPerBeetle.cpp b/TbUT/src/TbUTCmsPerBeetle.cpp
new file mode 100644
index 0000000..dceb001
--- /dev/null
+++ b/TbUT/src/TbUTCmsPerBeetle.cpp
@@ -0,0 +1,71 @@
+//
+// Created by ja on 8/4/15.
+//
+
+#include "TbUTCmsPerBeetle.h"
+#include <iostream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+CmsPerBeetle::CmsPerBeetle(IChannelMaskProvider& p_masksProvider,double p_hitThreshold):
+        m_masksProvider(p_masksProvider),
+        m_channelNumber(RawData<>::getnChannelNumber()),
+		m_hitThreshold(p_hitThreshold)
+{
+	cout<<"create correlation per beetle"<<endl;
+	initializeCorrectionMap();
+}
+
+void CmsPerBeetle::initializeCorrectionMap()
+{
+	int channelPerBeetle=32;
+	for (int channel=0;channel<m_channelNumber;channel+=channelPerBeetle)
+		m_correctionPerBeetle.insert(std::make_pair(channel,0));
+}
+
+void CmsPerBeetle::processEvent(RawData<>* p_data, RawData<double> **p_output)
+{
+	calculateCorrection(p_data);
+	removeCM(p_data,p_output);
+}
+
+void CmsPerBeetle::calculateCorrection(RawData<>* p_inputData)
+{
+	int channelPerBeetle=32;
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		int usedChannels=0;
+		for(int channel=mapIt.first;channel<mapIt.first+channelPerBeetle;channel++)
+		{
+			auto signal=p_inputData->getSignal(channel);
+			if(!m_masksProvider.isMasked(channel) && abs(signal) <m_hitThreshold){
+				mapIt.second+=signal;
+				usedChannels++;
+			}
+		}
+		if(usedChannels) mapIt.second/=static_cast<double>(usedChannels);
+	}
+}
+
+void CmsPerBeetle::removeCM(RawData<>* p_data, RawData<double> **p_output)
+{
+	int channelPerBeetle=32;
+	for(auto& mapIt : m_correctionPerBeetle)
+	{
+		for(int channel=mapIt.first;channel<mapIt.first+channelPerBeetle;channel++)
+		{
+			if(m_masksProvider.isMasked(channel)){
+				double signalMaskedChannel=0;
+				(*p_output)->setSignal(signalMaskedChannel);
+			}else{
+				double l_channelSignal=p_data->getSignal(channel)-mapIt.second;
+				(*p_output)->setSignal(l_channelSignal);
+			}
+		}
+
+	}
+
+}
+
diff --git a/TbUT/src/TbUTCmsPerBeetle.h b/TbUT/src/TbUTCmsPerBeetle.h
new file mode 100644
index 0000000..c97e836
--- /dev/null
+++ b/TbUT/src/TbUTCmsPerBeetle.h
@@ -0,0 +1,30 @@
+//
+// Created by ja on 8/4/15.
+//
+#pragma once
+
+#include "TbUTICommonModeSubtractor.h"
+#include "TbUTIChannelMaskProvider.h"
+
+#include <map>
+
+namespace TbUT
+{
+
+class CmsPerBeetle: public ICommonModeSubtractor
+{
+public:
+	CmsPerBeetle(IChannelMaskProvider& p_masksProvider,double p_hitThreshold);
+	void processEvent(RawData<>* p_data, RawData<double> **p_output);
+private:
+	void calculateCorrection(RawData<>* p_inputData);
+	void removeCM(RawData<>* p_data, RawData<double> **p_output);
+
+	void initializeCorrectionMap();
+	IChannelMaskProvider& m_masksProvider;
+	int m_channelNumber;
+	double m_hitThreshold;
+	std::map<int, double> m_correctionPerBeetle;
+};
+
+}
diff --git a/TbUT/src/TbUTCommonModeSubtractorAlgorithm.cpp b/TbUT/src/TbUTCommonModeSubtractorAlgorithm.cpp
new file mode 100644
index 0000000..7826b0e
--- /dev/null
+++ b/TbUT/src/TbUTCommonModeSubtractorAlgorithm.cpp
@@ -0,0 +1,159 @@
+/*
+ * TbUTCommonModeSubtractorAlgorithm.cpp
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCommonModeSubtractorAlgorithm.h"
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,CommonModeSubtractorAlgorithm)
+
+
+CommonModeSubtractorAlgorithm::CommonModeSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+		GaudiAlgorithm(name, pSvcLocator),
+		m_dataContainer(),
+		m_data(),
+		m_outputContainer(),
+		m_inputDataLocation(),
+		m_outputDataLocation(),
+		m_channelMaskInputLocation(),
+		m_CMSOption(),
+		m_noiseCalculatorType(),
+		m_noiseOutputLocation(),
+		m_event(0),
+		m_skipEvent(0),
+		m_channelMaskFileValidator(m_channelMaskInputLocation),
+		m_channelMaskProvider(m_channelMaskFileValidator),
+		m_SubtractorFactory(m_channelMaskProvider),
+		m_noiseCalculatorFactory(),
+		m_noiseCalculatorPtr()
+{
+	declareProperty("InputDataLocation", m_inputDataLocation=TbUT::DataLocations::PedestalTES);
+	declareProperty("OutputDataLocation", m_outputDataLocation=TbUT::DataLocations::CMSTES);
+	declareProperty("CMSType",m_CMSOption=TbUT::CMSType::Iteratively);
+	declareProperty("skippEventNumber",m_skipEvent=0);
+	declareProperty("ChannelMaskInputLocation", m_channelMaskInputLocation=TbUT::DataLocations::MaskLocation);
+	declareProperty("NoiseCalculatorType", m_noiseCalculatorType=TbUT::NoiseCalculatorType::calculator);
+	declareProperty("NoiseOutputFile", m_noiseOutputLocation=TbUT::DataLocations::NoiseTreshold);
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::initialize()
+{
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildSubtractorEngine()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildNoiseCalculator()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=retriveMasksFromFile()) return StatusCode::FAILURE;
+
+	info()<<"Initialized successfully my friend!"<<endmsg;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::execute()
+{
+	if(m_event<m_skipEvent)
+	{
+		return skippTreaningEvent();
+	}
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	m_outputContainer =new RawDataContainer<double>();
+
+	if(m_dataContainer->isEmpty()){
+		put(m_outputContainer,m_outputDataLocation);
+		return StatusCode::SUCCESS;
+	}
+
+	for(const auto& rawDataIt: m_dataContainer->getData()){
+		m_data=new RawData<>(rawDataIt);
+		processEvent();
+		delete m_data;
+	}
+	put(m_outputContainer,m_outputDataLocation);
+
+	return StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::finalize()
+{
+	if(StatusCode::SUCCESS !=saveNoiseToFile()) return StatusCode::FAILURE;
+	return GaudiAlgorithm::finalize();
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::initializeBase()
+{
+	  return GaudiAlgorithm::initialize();
+}
+
+StatusCode CommonModeSubtractorAlgorithm::buildSubtractorEngine()
+try{
+	m_CMSEnginePtr.reset(m_SubtractorFactory.createCMSubtractor(m_CMSOption));
+	return StatusCode::SUCCESS;
+}catch(CommonModeSubtractorFactory::NoSuchState &exception)
+{
+	error()<<"Invalid CommonMode Engine Type  : "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::buildNoiseCalculator()
+try{
+	m_noiseCalculatorPtr=m_noiseCalculatorFactory.createNoiseCalculator(m_noiseCalculatorType);
+	return StatusCode::SUCCESS;
+}catch(NoiseCalculatorFactory::NoSuchState &exception)
+{
+	error()<<"Invalid NoiseCalculator Type  : "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode CommonModeSubtractorAlgorithm::retriveMasksFromFile()
+try{
+	m_channelMaskProvider.getMaskFromFile(m_channelMaskInputLocation);
+	return StatusCode::SUCCESS;
+}catch(ChannelMaskProvider::InputFileError  &exception)
+{
+	error()<<"Channel Mask File Input Error: "<<m_channelMaskInputLocation<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<>>(m_inputDataLocation);
+	if(!m_dataContainer){
+		error()<< " ==> There is no input data: "<< m_inputDataLocation <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+void CommonModeSubtractorAlgorithm::processEvent()
+{
+	RawData<double> *l_afterCMS= new RawData<double>();
+	m_CMSEnginePtr->processEvent(m_data,&l_afterCMS);
+	m_noiseCalculatorPtr->updateNoise(l_afterCMS);
+	m_outputContainer->addData(*l_afterCMS);
+	m_event++;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::skippTreaningEvent()
+{
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorAlgorithm::saveNoiseToFile()
+try{
+	m_noiseCalculatorPtr->saveNoiseToFile(m_noiseOutputLocation);
+	return StatusCode::SUCCESS;
+}catch (Noise::NoiseCalculatorError & ex)
+{
+	error()<< ex.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+
diff --git a/TbUT/src/TbUTCommonModeSubtractorAlgorithm.h b/TbUT/src/TbUTCommonModeSubtractorAlgorithm.h
new file mode 100644
index 0000000..7987467
--- /dev/null
+++ b/TbUT/src/TbUTCommonModeSubtractorAlgorithm.h
@@ -0,0 +1,73 @@
+/*
+ * TbUTCommonModeSubtractorAlgorithm.h
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+#include "TbUTRawData.h"
+#include "TbUTCommonModeSubtractorFactory.h"
+#include "TbUTChannelMaskProvider.h"
+#include "TbUTChannelMaskFileValidator.h"
+#include "TbUTNoiseCalculatorfactory.h"
+#include "TbUTNoise.h"
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+class CommonModeSubtractorAlgorithm : public GaudiAlgorithm
+{
+	typedef boost::shared_ptr<ICommonModeSubtractor> CMSubtractorPtr;
+public:
+	CommonModeSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+	virtual StatusCode finalize();
+private:
+
+	StatusCode initializeBase();
+	StatusCode buildSubtractorEngine();
+	StatusCode buildNoiseCalculator();
+	StatusCode retriveMasksFromFile();
+
+	StatusCode getData();
+	void processEvent();
+	StatusCode skippTreaningEvent();
+
+	StatusCode saveNoiseToFile();
+
+	RawDataContainer<>* m_dataContainer;
+	RawData<>* m_data;
+	RawDataContainer<double>* m_outputContainer;
+
+
+	std::string m_inputDataLocation;
+	std::string m_outputDataLocation;
+	std::string m_channelMaskInputLocation;
+	std::string m_CMSOption;
+	std::string m_noiseCalculatorType;
+	std::string m_noiseOutputLocation;
+
+	int m_event;
+	int m_skipEvent;
+
+	ChannelMaskFileValidator m_channelMaskFileValidator;
+	ChannelMaskProvider m_channelMaskProvider;
+	CommonModeSubtractorFactory m_SubtractorFactory;
+	CMSubtractorPtr m_CMSEnginePtr;
+	NoiseCalculatorFactory m_noiseCalculatorFactory;
+	NoiseCalculatorFactory::NoiseCalcualtorPtr m_noiseCalculatorPtr;
+
+};
+
+}
+
+
+
+
diff --git a/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp b/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
new file mode 100644
index 0000000..26a8c90
--- /dev/null
+++ b/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
@@ -0,0 +1,201 @@
+/*
+ * TbUTCommonModeSubtractorDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Nov 26, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCommonModeSubtractorDataMonitorAlgorithm.h"
+#include "TbUTDataLocations.h"
+#include "TbUTRawData.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include <boost/format.hpp>
+
+using namespace TbUT;
+using namespace boost;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,CommonModeSubtractorDataMonitorAlgorithm)
+
+using namespace TbUT;
+
+CommonModeSubtractorDataMonitorAlgorithm::CommonModeSubtractorDataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : DataMonitorAlgorithm ( name , pSvcLocator ),
+	m_noise()
+{
+	DataMonitorAlgorithm::m_inputDataLoc=TbUT::DataLocations::CMSTES;
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::execute()
+{
+	DataMonitorAlgorithm::RunPhase l_runPhase=DataMonitorAlgorithm::getRunPhase();
+	switch(l_runPhase)
+	{
+	case SKIP:
+		return DataMonitorAlgorithm::skippEvent();
+	case SAVE_SINGLE_EVENTS:
+		return saveSimpleEvents();
+	default:
+	 	return fillOnly2DHistogram();
+	}
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<double> >(m_inputDataLoc);
+	if(!m_dataContainer){
+		error()<< "=> there is no input data in "<< m_inputDataLoc<<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::saveSimpleEvents()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	for(const auto& rawDataIt : m_dataContainer->getData() )
+	{
+		m_data=RawData<double>(rawDataIt);
+		storeEventIntoHistogram();
+		fillHistogram2D();
+		m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+TH2D * CommonModeSubtractorDataMonitorAlgorithm::bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	int l_ylow=-800;
+	int l_yhigh=800;
+	int l_ybin=1600;
+	return Gaudi::Utils::Aida2ROOT::aida2root(book2D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,p_sensorNumber,
+			l_ylow,l_yhigh,l_ybin ));
+}
+
+std::string CommonModeSubtractorDataMonitorAlgorithm::createHistogramTitle()
+{
+	boost::format l_histogramTitle("Data after CM Subtraction - event%1%");
+	l_histogramTitle% m_evtNumber;
+	return str(l_histogramTitle);
+}
+
+std::string CommonModeSubtractorDataMonitorAlgorithm::createHistogramName()
+{
+	boost::format l_histogramName("Data_after_CMS_event_%d");
+	l_histogramName % m_evtNumber;
+	return str(l_histogramName);
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::createHistogram2D()
+{
+	std::string l_histogramName="CMSData_vs_channel";
+	std::string l_histogramTtttle="Data after CMS vs channel";
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	m_histogram2D=bookHistogram2D(l_histogramName,l_histogramTtttle,l_sensorNum );
+	createNoiseHistograms();
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::fillOnly2DHistogram()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	const int storeNoiseFrequency=10000;
+	for(const auto& rawDataIt :m_dataContainer->getData() )
+	{
+		m_data=RawData<double>(rawDataIt);
+		m_noise.updateNoise(&(m_data));
+		if( 0 ==(DataMonitorAlgorithm::m_evtNumber%storeNoiseFrequency) ) fillNoiseHistograms();
+		fillHistogram2D();
+		DataMonitorAlgorithm::m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::fillHistogram2D()
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan = 0; chan <channelNumber; chan++ ){
+		auto channelSignal=m_data.getSignal(chan);
+		if(0!=channelSignal) // no need to push masked values
+			m_histogram2D->Fill(chan+RawData<>::getMinChannel(),channelSignal);
+	  }
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::fillHistogram(TH1D * p_histogram)
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan =0 ; chan <channelNumber; chan++ ){
+		p_histogram->SetBinContent(chan,m_data.getSignal(chan));
+	  }
+}
+
+StatusCode CommonModeSubtractorDataMonitorAlgorithm::finalize()
+{
+	DataMonitorAlgorithm::m_outpuProjectionHistogramName="ProjectionCommonMode";
+	return DataMonitorAlgorithm::finalize();
+}
+
+
+void CommonModeSubtractorDataMonitorAlgorithm::createNoiseHistograms()
+{
+	// This function is very ugly!
+	// should be refactored!
+ 	const int l_channelNumber=RawData<>::getnChannelNumber();
+	const int l_ylow=0;
+	const int l_yhigh=100;
+	const int l_ybin=10;
+	const int channelPerBeetle=32;
+	int sensorNumber=0;
+
+	for(int channel=0;channel<l_channelNumber ; channel++){
+		boost::format l_histogramName("Noise_channel_%d");
+		l_histogramName % channel;
+		m_noisePerChannelHistograms.insert(
+				std::make_pair(
+						channel,Gaudi::Utils::Aida2ROOT::aida2root(
+									book1D( l_histogramName.str(),	l_histogramName.str(),l_ybin, l_ylow, l_yhigh)
+								)
+				)
+		);
+		if( 0 == (channel%channelPerBeetle )){
+			l_histogramName= boost::format("Noise_beetle_%d");
+			l_histogramName % sensorNumber;
+			m_noisePerSensorHistograms.insert(
+					std::make_pair(
+							sensorNumber,Gaudi::Utils::Aida2ROOT::aida2root(
+										book1D( l_histogramName.str(),	l_histogramName.str(),l_ybin, l_ylow, l_yhigh)
+									)
+					)
+			);
+			sensorNumber++;
+		}
+
+	}
+}
+
+void CommonModeSubtractorDataMonitorAlgorithm::fillNoiseHistograms()
+{
+	m_noise.NormalizeNoise();
+	for(auto noiseHistogramIt:m_noisePerChannelHistograms){
+		noiseHistogramIt.second->Fill(m_noise.getNoise(noiseHistogramIt.first));
+	}
+
+	const int l_channelNumber=RawData<>::getnChannelNumber();
+	const int channelPerBeetle=32;
+	double meanNoisePerBeetle=0;
+	int sensorNumber=0;
+
+	for(int channel=0;channel<l_channelNumber ; channel++){
+		meanNoisePerBeetle+=m_noise.getNoise(channel);
+		if( 0 == (channel%channelPerBeetle )){
+			meanNoisePerBeetle/=static_cast<double>(channelPerBeetle);
+			m_noisePerSensorHistograms[sensorNumber]->Fill(meanNoisePerBeetle);
+			sensorNumber++;
+			meanNoisePerBeetle=0;// reset mean value
+		}
+	}
+	m_noise.Reset();
+}
+
+
diff --git a/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.h b/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.h
new file mode 100644
index 0000000..f3b8402
--- /dev/null
+++ b/TbUT/src/TbUTCommonModeSubtractorDataMonitorAlgorithm.h
@@ -0,0 +1,56 @@
+/*
+ * TbUTCommonModeSubtractorDataMonitorAlgorithm.h
+ *
+ *  Created on: Nov 26, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTDataMonitorAlgorithm.h"
+#include "TbUTNoise.h"
+#include <map>
+
+namespace TbUT
+{
+
+class CommonModeSubtractorDataMonitorAlgorithm : public DataMonitorAlgorithm
+{
+public:
+	CommonModeSubtractorDataMonitorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+	StatusCode execute   ();
+	StatusCode finalize();
+
+private:
+	 typedef std::map<int, TH1D*> HistogramMap;
+
+	 StatusCode getData();
+
+	 StatusCode saveSimpleEvents();
+	 virtual StatusCode fillOnly2DHistogram();
+	 
+	 void createHistogram2D();
+	 TH2D * bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+	
+	 std::string createHistogramTitle();
+	 std::string createHistogramName();
+
+	 void fillHistogram2D();
+	 void fillHistogram(TH1D * p_histogram);
+
+	 void createNoiseHistograms();
+	 void fillNoiseHistograms();
+	
+	 TbUT::RawDataContainer<double> *m_dataContainer;
+  	 TbUT::RawData<double> m_data;
+
+	 Noise m_noise;
+
+	 HistogramMap m_noisePerChannelHistograms;
+	 HistogramMap m_noisePerSensorHistograms;
+
+
+};
+
+}
+
diff --git a/TbUT/src/TbUTCommonModeSubtractorFactory.cpp b/TbUT/src/TbUTCommonModeSubtractorFactory.cpp
new file mode 100644
index 0000000..e6b74cf
--- /dev/null
+++ b/TbUT/src/TbUTCommonModeSubtractorFactory.cpp
@@ -0,0 +1,30 @@
+/*
+ * TbUTCommonModeSubtractorFactory.cpp
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTCommonModeSubtractorFactory.h"
+
+using namespace TbUT;
+
+
+CommonModeSubtractorFactory::CommonModeSubtractorFactory(IChannelMaskProvider& p_masksProvider):
+		m_masksProvider(p_masksProvider)
+{
+}
+
+ICommonModeSubtractor* CommonModeSubtractorFactory::createCMSubtractor(const std::string& p_CMSType)
+{
+	if(!p_CMSType.compare(TbUT::CMSType::Linear.c_str()))
+		return new CMSLinear(m_masksProvider);
+	else if (p_CMSType == TbUT::CMSType::Beetle){
+		double hitThreshold=160.;
+		return new CmsPerBeetle(m_masksProvider,hitThreshold);
+	}
+	else if(p_CMSType == TbUT::CMSType::Iteratively)
+		return new CMSIterativelyPerBeetle(m_masksProvider);
+	else
+		throw NoSuchState(p_CMSType);
+}
diff --git a/TbUT/src/TbUTCommonModeSubtractorFactory.h b/TbUT/src/TbUTCommonModeSubtractorFactory.h
new file mode 100644
index 0000000..9a52c32
--- /dev/null
+++ b/TbUT/src/TbUTCommonModeSubtractorFactory.h
@@ -0,0 +1,44 @@
+/*
+ * TbUTCommonModeSubtractorFactory.h
+ *
+ *  Created on: Nov 24, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTCMSLinear.h"
+#include "TbUTCmsPerBeetle.h"
+#include "TbUTCMSIterativelyPerBeetle.h"
+
+namespace TbUT
+{
+
+namespace CMSType
+{
+static const std::string& Iteratively="Iteratively";
+static const std::string& Beetle = "Beetle";
+static const std::string& Linear = "Linear";
+}
+
+class CommonModeSubtractorFactory
+{
+public:
+	CommonModeSubtractorFactory(IChannelMaskProvider& p_masksProvider);
+
+	ICommonModeSubtractor* createCMSubtractor(const std::string& p_CMSType);
+
+	class NoSuchState: public std::runtime_error
+	{
+	public:
+		NoSuchState(const std::string& p_errorMsg ):
+			std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+private:
+	IChannelMaskProvider& m_masksProvider;
+};
+
+}
+
diff --git a/TbUT/src/TbUTDataLocations.h b/TbUT/src/TbUTDataLocations.h
new file mode 100644
index 0000000..edece2c
--- /dev/null
+++ b/TbUT/src/TbUTDataLocations.h
@@ -0,0 +1,30 @@
+/*
+ * TbUTDataLocations.h
+ *
+ *  Created on: Oct 11, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#pragma GCC diagnostic ignored "-Wunused-variable"
+
+#include <string>
+
+namespace TbUT
+{
+namespace DataLocations
+{
+//should be extended
+static const std::string& RawTES      	 		= "Tb/TbUT/Raw";
+static const std::string& HeaderTES                     = "Tb/TbUT/Header";
+static const std::string& PedestalTES 	 		= "Tb/TbUT/Pedestal";
+static const std::string& CMSTES      	 		= "Tb/TbUT/CMS";
+static const std::string& ZS_TES      	 		= "Tb/TbUT/ZS";
+static const std::string& Clusters_TES	 		= "Tb/TbUT/Clusters";
+static const std::string& KeplerCluster_TES	= "Tb/TbUT/KeplerClusters";
+
+static const std::string & MaskLocation      = "$KEPLERROOT/options/UT/ChannelMask_NO.dat";
+static const std::string & PedestalLocation  = "$KEPLERROOT/options/UT/Pedestal.dat";
+static const std::string & NoiseTreshold     = "$KEPLERROOT/options/UT/Noise.dat";
+}
+}
diff --git a/TbUT/src/TbUTDataMonitorAlgorithm.cpp b/TbUT/src/TbUTDataMonitorAlgorithm.cpp
new file mode 100644
index 0000000..607c4f1
--- /dev/null
+++ b/TbUT/src/TbUTDataMonitorAlgorithm.cpp
@@ -0,0 +1,178 @@
+#include "TbUTDataMonitorAlgorithm.h"
+#include "GaudiUtils/Aida2ROOT.h"
+#include "GaudiKernel/AlgFactory.h" 
+#include <boost/format.hpp>
+
+using namespace TbUT;
+using namespace boost;
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,DataMonitorAlgorithm)
+
+
+DataMonitorAlgorithm::DataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : GaudiHistoAlg ( name , pSvcLocator ),
+	m_inputDataLoc(),
+	m_outpuProjectionHistogramName(),
+    m_displayEventNumber(0),
+    m_evtNumber(0),
+	m_skipEvent(0),
+	m_histogram2D()
+{
+    declareProperty("displayEventNumber", m_displayEventNumber=10);
+    declareProperty("skippEventNumber", m_skipEvent=0);
+
+}
+
+DataMonitorAlgorithm::~DataMonitorAlgorithm(){}
+
+StatusCode DataMonitorAlgorithm::initialize() {
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	setHistoTopDir( const_cast<char*>("TbUT/") );
+	createHistogram2D();
+  	return StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::execute()
+{
+	RunPhase l_runPhase=getRunPhase();
+	switch(l_runPhase)
+	{
+	case SKIP:
+		return skippEvent();
+	case SAVE_SINGLE_EVENTS:
+		return saveSimpleEvents();
+	default:
+	 	return fillOnly2DHistogram();
+	}
+}
+
+StatusCode DataMonitorAlgorithm::finalize()
+{
+	buildProjectionHistogram();
+	return GaudiHistoAlg::finalize();
+}
+
+StatusCode DataMonitorAlgorithm::initializeBase()
+{
+	  return GaudiHistoAlg::initialize();
+}
+
+
+void DataMonitorAlgorithm::createHistogram2D()
+{
+	std::string l_histogramName="RawData_vs_channel";
+	std::string l_histogramTtttle="RawData_vs_channel";
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	m_histogram2D=bookHistogram2D(l_histogramName,l_histogramTtttle,l_sensorNum );
+}
+
+StatusCode DataMonitorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<> >(m_inputDataLoc);
+	if(!m_dataContainer){
+		error()<< " ==> there is no input data in "<< m_inputDataLoc<<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::skippEvent()
+{
+	m_evtNumber++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::saveSimpleEvents()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	for(const auto& rawDataIt : m_dataContainer->getData() )
+	{
+		m_data=RawData<>(rawDataIt);
+		storeEventIntoHistogram();
+		fillHistogram2D();
+		m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+StatusCode DataMonitorAlgorithm::fillOnly2DHistogram()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	if(m_dataContainer->isEmpty()) return StatusCode::SUCCESS;
+	for(const auto& rawDataIt : m_dataContainer->getData() )
+	{
+		m_data=RawData<>(rawDataIt);
+		fillHistogram2D();
+		m_evtNumber++;
+	}
+	return StatusCode::SUCCESS;
+}
+
+void DataMonitorAlgorithm::storeEventIntoHistogram()
+{
+	std::string l_histName= createHistogramName();
+	std::string l_histTitle= createHistogramTitle();
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	TH1D* l_eventHist=bookHistogram(l_histName,l_histTitle, l_sensorNum );
+	fillHistogram(l_eventHist);
+}
+
+std::string DataMonitorAlgorithm::createHistogramName()
+{
+	boost::format l_histogramName("event %d");
+	l_histogramName % m_evtNumber;
+	return str(l_histogramName);
+}
+
+std::string DataMonitorAlgorithm::createHistogramTitle()
+{
+	boost::format l_histogramTitle("Raw Data - event%1%");
+	l_histogramTitle% m_evtNumber;
+	return str(l_histogramTitle);
+}
+
+TH1D * DataMonitorAlgorithm::bookHistogram(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	return Gaudi::Utils::Aida2ROOT::aida2root(book1D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,p_sensorNumber ));
+}
+
+void DataMonitorAlgorithm::fillHistogram(TH1D * p_histogram)
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan =0 ; chan <channelNumber; chan++ ){
+		p_histogram->SetBinContent(chan,m_data.getSignal(chan));
+	  }
+}
+
+TH2D * DataMonitorAlgorithm::bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	int l_ylow=-800;
+	int l_yhigh=800;
+	int l_ybin=1600;
+	return Gaudi::Utils::Aida2ROOT::aida2root(book2D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()-0.5,p_sensorNumber,
+			l_ylow,l_yhigh,l_ybin ));
+}
+
+void DataMonitorAlgorithm::fillHistogram2D()
+{
+	int channelNumber=RawData<>::getnChannelNumber();
+	for(int chan = 0; chan <channelNumber; chan++ ){
+		auto channelSignal=m_data.getSignal(chan);
+		if(0!=channelSignal) // no need to push masked values
+			m_histogram2D->Fill(chan+RawData<>::getMinChannel(),channelSignal);
+	  }
+}
+
+DataMonitorAlgorithm::RunPhase DataMonitorAlgorithm::getRunPhase()
+{
+	if(m_evtNumber< m_skipEvent) return SKIP;
+	if( m_evtNumber<m_displayEventNumber+m_skipEvent) return SAVE_SINGLE_EVENTS;
+	else return REST;
+}
+
+void DataMonitorAlgorithm::buildProjectionHistogram()
+{
+		m_histogram2D->ProjectionY(m_outpuProjectionHistogramName.c_str());
+}
diff --git a/TbUT/src/TbUTDataMonitorAlgorithm.h b/TbUT/src/TbUTDataMonitorAlgorithm.h
new file mode 100644
index 0000000..4a14ce3
--- /dev/null
+++ b/TbUT/src/TbUTDataMonitorAlgorithm.h
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "GaudiAlg/GaudiHistoAlg.h"
+#include "TbUTRawData.h"
+#include <TH1D.h>
+#include <TH2D.h>
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT{
+
+class DataMonitorAlgorithm: public GaudiHistoAlg
+{
+public:
+	DataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+
+	virtual 	~DataMonitorAlgorithm();
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute   ();
+	virtual StatusCode finalize  ();
+
+protected:
+
+	enum RunPhase
+	{
+		SKIP,
+		SAVE_SINGLE_EVENTS,
+		REST
+	};
+
+  virtual StatusCode getData();
+  virtual StatusCode initializeBase();
+
+  virtual StatusCode skippEvent();
+  virtual StatusCode saveSimpleEvents();
+  virtual StatusCode fillOnly2DHistogram();
+
+
+  virtual	RunPhase getRunPhase();
+
+  virtual void createHistogram2D();
+  virtual void storeEventIntoHistogram();
+  virtual TH1D * bookHistogram(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+  virtual TH2D * bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+
+  virtual std::string createHistogramTitle();
+  virtual std::string createHistogramName();
+  virtual void fillHistogram(TH1D * p_histogram);
+  virtual void fillHistogram2D();
+  virtual void buildProjectionHistogram();
+
+
+
+  std::string m_inputDataLoc;
+  std::string m_outpuProjectionHistogramName;
+  int m_displayEventNumber;
+  int m_evtNumber;
+  int m_skipEvent;
+  TH2D* m_histogram2D;
+  TbUT::RawDataContainer<> *m_dataContainer;
+  TbUT::RawData<> m_data;
+};
+
+}
diff --git a/TbUT/src/TbUTIChannelMaskProvider.h b/TbUT/src/TbUTIChannelMaskProvider.h
new file mode 100644
index 0000000..08ed957
--- /dev/null
+++ b/TbUT/src/TbUTIChannelMaskProvider.h
@@ -0,0 +1,22 @@
+/*
+ * TbUTIIChannelMaskProvider.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include <vector>
+#include <string>
+#include "TbUTDataLocations.h"
+
+
+namespace TbUT
+{
+class IChannelMaskProvider{
+public:
+	virtual ~IChannelMaskProvider(){};
+	virtual void getMaskFromFile(const std::string& p_filename=TbUT::DataLocations::MaskLocation)=0;
+	virtual bool isMasked(int p_channel)=0;
+};
+}
diff --git a/TbUT/src/TbUTIClusterCreator.h b/TbUT/src/TbUTIClusterCreator.h
new file mode 100644
index 0000000..bfe48d9
--- /dev/null
+++ b/TbUT/src/TbUTIClusterCreator.h
@@ -0,0 +1,34 @@
+/*
+ * TbUTIClusterCreator.h
+ *
+ *  Created on: Jan 5, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTCluster.h"
+#include "TbUTRawData.h"
+
+namespace TbUT
+{
+
+class IClusterCreator
+{
+public:
+	virtual ~IClusterCreator(){};
+	virtual ClusterContainer::ClusterVector createClusters(RawData<double> *p_inputData)=0;
+
+	class ClusterCreatorError: public std::runtime_error
+	{
+	public:
+		ClusterCreatorError(std::string &msg) :
+			std::runtime_error(msg)
+		{
+		}
+	};
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTICommonModeSubtractor.h b/TbUT/src/TbUTICommonModeSubtractor.h
new file mode 100644
index 0000000..8db5791
--- /dev/null
+++ b/TbUT/src/TbUTICommonModeSubtractor.h
@@ -0,0 +1,23 @@
+/*
+ * TbUTICommonModeSubtractor.h
+ *
+ *  Created on: Nov 23, 2014
+ *      Author: ADendek
+ */
+#pragma once
+
+#include "TbUTIProcessingEngine.h"
+
+
+namespace TbUT
+{
+
+class ICommonModeSubtractor : public IProcessingEngine<int, double>
+{
+public:
+	virtual ~ICommonModeSubtractor(){};
+};
+
+}
+
+
diff --git a/TbUT/src/TbUTIDataReader.h b/TbUT/src/TbUTIDataReader.h
new file mode 100644
index 0000000..7e57d3d
--- /dev/null
+++ b/TbUT/src/TbUTIDataReader.h
@@ -0,0 +1,56 @@
+/*
+ * TbUTIDataReader.h
+ *
+ *  Created on: Oct 6, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTRawData.h"
+#include <stdexcept>
+#include <string>
+
+namespace TbUT
+{
+class IDataReader
+{
+public:
+
+	class InputFileError: public std::runtime_error
+	{
+	public:
+		InputFileError(std::string& msg) :
+				std::runtime_error(msg)
+		{
+		}
+	};
+
+	class ReadEventError: public std::runtime_error
+	{
+	public:
+		ReadEventError(std::string & ex) :
+				std::runtime_error(ex)
+		{
+		}
+	};
+
+	class NoMoreEvents: public std::runtime_error
+	{
+	public:
+		NoMoreEvents(std::string & ex) :
+				std::runtime_error(ex)
+		{
+		}
+	};
+
+
+	virtual ~IDataReader(){};
+	virtual void checkInput()=0;
+	virtual RawData<>* getEventData()=0;
+};
+
+}
+
+
+
diff --git a/TbUT/src/TbUTIDataRetreiver.h b/TbUT/src/TbUTIDataRetreiver.h
new file mode 100644
index 0000000..85e8071
--- /dev/null
+++ b/TbUT/src/TbUTIDataRetreiver.h
@@ -0,0 +1,38 @@
+/*
+ * TbUTIDataRetreiver.h
+ *
+ *  Created on: Oct 1, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include <string>
+
+namespace TbUT
+{
+
+class IDataRetreiver
+{
+public:
+
+	virtual ~IDataRetreiver()
+	{
+	}
+	;
+	virtual void open(std::string & p_filename)=0;
+	virtual bool
+	valid()=0;
+	virtual int
+	read_event(std::string & error_code)=0;
+	virtual void
+	process_event()=0;
+	virtual double
+	time()=0;
+	virtual double
+	temp()=0;
+	virtual unsigned short
+	data(int i) =0;
+
+};
+
+}
diff --git a/TbUT/src/TbUTIFileValidator.h b/TbUT/src/TbUTIFileValidator.h
new file mode 100644
index 0000000..cda16b3
--- /dev/null
+++ b/TbUT/src/TbUTIFileValidator.h
@@ -0,0 +1,20 @@
+/*
+ * TbUTIFileValidator.h
+ *
+ *  Created on: Oct 5, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include <string>
+
+namespace TbUT
+{
+class IFileValidator
+{
+public:
+	virtual ~IFileValidator(){};
+	virtual bool validateFile()=0;
+};
+}
diff --git a/TbUT/src/TbUTINoiseCalculator.h b/TbUT/src/TbUTINoiseCalculator.h
new file mode 100644
index 0000000..88d4072
--- /dev/null
+++ b/TbUT/src/TbUTINoiseCalculator.h
@@ -0,0 +1,21 @@
+/*
+ * TbUTINoiseCalculator.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTRawData.h"
+
+namespace TbUT{
+
+class INoiseCalculator
+{
+public:
+	virtual ~INoiseCalculator(){};
+	virtual void updateNoise(RawData<double>* p_inputData)=0;
+	virtual void saveNoiseToFile(const std::string& p_filaname)=0;
+};
+}
diff --git a/TbUT/src/TbUTIPedestalFollowing.h b/TbUT/src/TbUTIPedestalFollowing.h
new file mode 100644
index 0000000..1ce5a79
--- /dev/null
+++ b/TbUT/src/TbUTIPedestalFollowing.h
@@ -0,0 +1,33 @@
+/*
+ * TbUTIPedestalFollowing.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTRawData.h"
+
+#include <vector>
+#include <string>
+
+namespace TbUT
+{
+class IPedestalFollowing
+{
+public:
+	virtual ~IPedestalFollowing(){};
+
+	virtual StatusCode processEvent(RawData<>* p_data)=0;
+	virtual void savePedestalToFile(const std::string& p_filename)=0;
+
+	class PedestalCalculatorError: public std::runtime_error
+		{
+		public:
+		PedestalCalculatorError(std::string &msg) :
+					std::runtime_error(msg)
+			{
+			}
+		};
+};
+}
diff --git a/TbUT/src/TbUTIProcessingEngine.h b/TbUT/src/TbUTIProcessingEngine.h
new file mode 100644
index 0000000..a590ead
--- /dev/null
+++ b/TbUT/src/TbUTIProcessingEngine.h
@@ -0,0 +1,19 @@
+/*
+ * TbUTIProcessingEngine.h
+ *
+ *  Created on: Oct 15, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTRawData.h"
+
+namespace TbUT
+{
+template<typename InputDataType = int , typename OutputDataType = int >
+class IProcessingEngine
+{
+public:
+	virtual ~IProcessingEngine(){};
+	virtual void processEvent(RawData<InputDataType>* p_data, RawData<OutputDataType> **p_output)=0;
+};
+}
diff --git a/TbUT/src/TbUTITresholdProvider.h b/TbUT/src/TbUTITresholdProvider.h
new file mode 100644
index 0000000..09667ec
--- /dev/null
+++ b/TbUT/src/TbUTITresholdProvider.h
@@ -0,0 +1,35 @@
+/*
+ * TbUTIZSTresholdProvider.h
+ *
+ *  Created on: Nov 27, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include <string>
+#include <stdexcept>
+
+namespace TbUT
+{
+
+class ITresholdProvider
+{
+public:
+	virtual ~ITresholdProvider(){}
+	virtual void retreiveTresholds()=0;
+	virtual double getLowClusterThreshold(int p_channel)=0;
+	virtual double getHighClusterThreshold(int p_channel)=0;
+
+	class ThresholdProviderError: public std::runtime_error
+	{
+	public:
+		ThresholdProviderError(const std::string& p_errorMsg ):
+					std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+
+};
+
+}
diff --git a/TbUT/src/TbUTMambaDataReader.cpp b/TbUT/src/TbUTMambaDataReader.cpp
new file mode 100644
index 0000000..a43caed
--- /dev/null
+++ b/TbUT/src/TbUTMambaDataReader.cpp
@@ -0,0 +1,69 @@
+/*
+ * TbUTMamdaDataReader.cpp
+ *
+ *  Created on: Jun 24, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTMambaDataReader.h"
+#include <iostream>
+
+using namespace TbUT;
+using namespace std;
+
+MambaDataReader::MambaDataReader(std::string& p_fileName, IFileValidator& p_fileValidator, bool& p_isAType):
+				m_fileName(p_fileName),
+				m_fileValidator(p_fileValidator),
+				m_decoder(p_isAType)
+{
+}
+
+void MambaDataReader::checkInput()
+{
+	if( ! m_fileValidator.validateFile() ){
+		std::string errorMsg= "file validation error";
+		throw IDataReader::InputFileError(errorMsg);
+
+	}
+	if(! m_decoder.open(m_fileName.c_str())){
+		std::string errorMsg= "cannot open input file";
+		throw IDataReader::InputFileError(errorMsg);
+	}
+}
+
+RawData<>* MambaDataReader::getEventData()
+{
+	while(true){
+		if(m_decoder.eof()){
+			string l_errorMsg ="No more event!";
+			throw IDataReader::NoMoreEvents(l_errorMsg);
+		}
+		if(0==m_decoder.read_event()){
+			continue;
+		}
+		else break;
+	}
+	RawData<> *l_outputData=new RawData<>();
+	fillRawData(l_outputData);
+	return l_outputData;
+}
+
+void MambaDataReader::fillRawData(RawData<>* p_outputData)
+{
+	auto signalVector=m_decoder.ADC();
+	auto headerVector0=m_decoder.BHeader0();
+	auto headerVector1=m_decoder.BHeader1();
+	auto headerVector2=m_decoder.BHeader2();
+	auto headerVector3=m_decoder.BHeader3();
+	auto headerVector3P1=m_decoder.BHeader3P1();
+	auto headerVector3P2=m_decoder.BHeader3P2();
+	for( const auto& l_adc : signalVector) 	p_outputData->setSignal(l_adc);
+	for( const auto& l_hdr0 : headerVector0) 	p_outputData->setHeader0(l_hdr0);
+	for( const auto& l_hdr1 : headerVector1) 	p_outputData->setHeader1(l_hdr1);
+	for( const auto& l_hdr2 : headerVector2) 	p_outputData->setHeader2(l_hdr2);
+	for( const auto& l_hdr3 : headerVector3) 	p_outputData->setHeader3(l_hdr3);
+	for( const auto& l_hdr3P1 : headerVector3P1) 	p_outputData->setHeader3P1(l_hdr3P1);
+	for( const auto& l_hdr3P2 : headerVector3P2) 	p_outputData->setHeader3P2(l_hdr3P2);
+	p_outputData->setTime(m_decoder.TsTimestamp());
+	p_outputData->setTDC(m_decoder.TDC());
+}
diff --git a/TbUT/src/TbUTMambaDataReader.h b/TbUT/src/TbUTMambaDataReader.h
new file mode 100644
index 0000000..cce811c
--- /dev/null
+++ b/TbUT/src/TbUTMambaDataReader.h
@@ -0,0 +1,43 @@
+/*
+ * TbUTMamdaDataReader.h
+ *
+ *  Created on: Jun 24, 2015
+ *      Author: ADendek
+ */
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include "TbUTIFileValidator.h"
+#include "TbUTRawData.h"
+#include "mamba/mamba_decoder.h"
+#include <string>
+#include <fstream>
+#include <vector>
+#include <map>
+
+
+
+namespace TbUT
+{
+
+class MambaDataReader: public IDataReader
+{
+public:
+	MambaDataReader(std::string& p_fileName, IFileValidator& p_fileValidator, bool& p_isAType );
+
+	void checkInput();
+	RawData<>* getEventData();
+
+
+private:
+	void fillRawData(RawData<>* p_outputData);
+
+	std::string& m_fileName;
+	IFileValidator& m_fileValidator;
+	mamba_decoder m_decoder;
+};
+
+
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTNTupleCreator.cpp b/TbUT/src/TbUTNTupleCreator.cpp
new file mode 100644
index 0000000..977f8ce
--- /dev/null
+++ b/TbUT/src/TbUTNTupleCreator.cpp
@@ -0,0 +1,233 @@
+
+#include "TbUTNTupleCreator.h"
+#include "GaudiKernel/AlgFactory.h"
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,NTupleCreator)
+
+
+NTupleCreator::NTupleCreator(const std::string& name, ISvcLocator* pSvcLocator):
+		GaudiTupleAlg(name, pSvcLocator),
+		m_eventNumber(0)
+{
+	  declareProperty("StoreEventNumber", m_storeEventNumber = 100);
+
+	  declareProperty("WriteRaw",       m_isRawWritten = true);
+	  declareProperty("WriteHeader",    m_isHeaderWritten = true);
+	  declareProperty("WritePedestal",  m_isPedestalWritten = true);
+	  declareProperty("WriteCMS",       m_isCMSWritten = true);
+	  declareProperty("WriteClusters",  m_isClusterWritten = true);
+
+	  declareProperty("RawLocation",      m_rawLocation = TbUT::DataLocations::RawTES );
+	  declareProperty("HeaderLocation",   m_headerLocation = TbUT::DataLocations::HeaderTES );
+	  declareProperty("PedestalLocation", m_pedestalLocation = TbUT::DataLocations::PedestalTES );
+	  declareProperty("CMSLocation",      m_cmsLocation = TbUT::DataLocations::CMSTES );
+	  declareProperty("ClusterLocation",  m_clusterLocation = TbUT::DataLocations::Clusters_TES );
+
+}
+
+StatusCode NTupleCreator::initialize()
+{
+	StatusCode sc = GaudiTupleAlg::initialize();
+	if (sc.isFailure()) return sc;
+	if(m_isRawWritten) bookRawData();
+	if(m_isHeaderWritten) bookHeaderData();
+	if(m_isPedestalWritten) bookPedestal();
+	if(m_isCMSWritten) bookCMS();
+	if(m_isClusterWritten) bookClusters();
+
+	return StatusCode::SUCCESS;
+}
+
+StatusCode NTupleCreator::execute()
+try{
+	if(m_eventNumber<m_storeEventNumber)
+	{
+		if(m_isRawWritten) fillRawData();
+		if(m_isHeaderWritten) fillHeaderData();
+		if(m_isPedestalWritten) fillPedestal();
+		if(m_isCMSWritten) fillCMS();
+		if(m_isClusterWritten) fillClusters();
+		m_eventNumber++;
+	}
+	return StatusCode::SUCCESS;
+}catch(DataError & err){
+	error()<<err.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+void NTupleCreator::bookRawData()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/RawData");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/RawData",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("rawData",RawData<>::getnChannelNumber(), m_rawSignal);
+}
+
+void NTupleCreator::bookHeaderData()
+{
+ 
+  const unsigned int maxHeaderContainerSize=16;
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/HeaderData");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/HeaderData",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("headerData0",maxHeaderContainerSize, m_header0Signal);
+	ntuple->addItem("headerData1",maxHeaderContainerSize, m_header1Signal);
+	ntuple->addItem("headerData2",maxHeaderContainerSize, m_header2Signal);
+	ntuple->addItem("headerData3",maxHeaderContainerSize, m_header3Signal);
+	ntuple->addItem("headerData3P1",maxHeaderContainerSize, m_header3P1Signal);
+	ntuple->addItem("headerData3P2",maxHeaderContainerSize, m_header3P2Signal);
+}
+
+void NTupleCreator::bookPedestal()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/Pedestal");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/Pedestal",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("pedestalData",RawData<>::getnChannelNumber(), m_pedestalSignal);
+}
+
+void NTupleCreator::bookCMS()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/CMS");
+	if (ntuple) return;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/CMS",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("cmsData",RawData<>::getnChannelNumber() ,m_cmsSignal);
+}
+
+void NTupleCreator::bookClusters()
+{
+	NTupleFilePtr file1(ntupleSvc(), "/NTUPLES/FILE1");
+	NTuplePtr ntuple(ntupleSvc(), "/NTUPLES/FILE1/TbUT/Clusters");
+	if (ntuple) return;
+
+	const unsigned int maxClusterContainerSize=10;
+	ntuple = ntupleSvc()->book("/NTUPLES/FILE1/TbUT/Clusters",CLID_ColumnWiseTuple, "TbUT nTuple");
+	ntuple->addItem("clusterNumberPerEvent",m_clusterNumberPerEvent);
+	ntuple->addItem("clustersTDC", m_tdc);
+	ntuple->addItem("timestamps", m_timestamp);
+
+	ntuple->addItem("clustersPosition",maxClusterContainerSize ,m_clusterPosition);
+	ntuple->addItem("clustersSeedPosition",maxClusterContainerSize ,m_clusterSeedPosition);
+
+	ntuple->addItem("clustersCharge",maxClusterContainerSize, m_clusterCharge);
+	ntuple->addItem("clustersSize",maxClusterContainerSize ,m_clusterSize);
+
+	ntuple->addItem("clustersSeedCharge",maxClusterContainerSize ,m_clusterSeedCharge);
+	ntuple->addItem("clustersCharge2StripLeft",maxClusterContainerSize ,m_clusterCharge2StripLeft);
+	ntuple->addItem("clustersCharge1StripLeft",maxClusterContainerSize ,m_clusterCharge1StripLeft);
+	ntuple->addItem("clustersCharge1StripRight",maxClusterContainerSize ,m_clusterCharge1StripRight);
+	ntuple->addItem("clustersCharge2StripRight",maxClusterContainerSize ,m_clusterCharge2StripRight);
+
+}
+
+void NTupleCreator::fillRawData()
+{
+	using namespace std;
+	RawDataContainer<>* dataContainer=getDataFromTES<>(m_rawLocation);
+	for(const auto& rawData : dataContainer->getData())// iterate over rawDatas
+	{
+		for(int channel=0;channel<RawData<>::getnChannelNumber();channel++){
+			m_rawSignal[channel]=rawData.getSignal(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/RawData");
+	}
+}
+void NTupleCreator::fillHeaderData()
+{
+  const unsigned int maxHeaderContainerSize=16;
+	RawDataContainer<>* dataContainer=getDataFromTES(m_rawLocation);
+	for(const auto& rawData : dataContainer->getData())// iterate over rawDatas
+	{
+		for(unsigned int channel=0;channel<maxHeaderContainerSize;channel++){
+			m_header0Signal[channel]=rawData.getHeader0(channel);
+			m_header1Signal[channel]=rawData.getHeader1(channel);
+			m_header2Signal[channel]=rawData.getHeader2(channel);
+			m_header3Signal[channel]=rawData.getHeader3(channel);
+			m_header3P1Signal[channel]=rawData.getHeader3P1(channel);
+			m_header3P2Signal[channel]=rawData.getHeader3P2(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/HeaderData");
+	}
+}
+
+void NTupleCreator::fillPedestal()
+{
+	RawDataContainer<>* dataContainer=getDataFromTES<>(m_pedestalLocation);
+	for(const auto& data: dataContainer->getData()) // iterate over rawDatas
+	{
+		for(int channel=0;channel<RawData<>::getnChannelNumber();channel++){
+			m_pedestalSignal[channel]=data.getSignal(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/Pedestal");
+	}
+}
+
+void NTupleCreator::fillCMS()
+{
+	RawDataContainer<double>* dataContainer=getDataFromTES<double>(m_cmsLocation);
+	for(const auto& cmsData:  dataContainer->getData())// iterate over rawDatas
+	{
+		for(int channel=0;channel<RawData<>::getnChannelNumber();channel++){
+			m_cmsSignal[channel]=cmsData.getSignal(channel);
+		}
+	    ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/CMS");
+	}
+}
+template <typename DATA_TYPE>
+RawDataContainer<DATA_TYPE>* NTupleCreator::getDataFromTES(const std::string& p_location)
+{
+	RawDataContainer<DATA_TYPE>* dataContainer=getIfExists<RawDataContainer<DATA_TYPE> >(p_location);
+	if(!dataContainer){
+		std::string errorMsg="There is no data in: " +p_location;
+		throw DataError(errorMsg);
+	}
+	return  dataContainer;
+}
+
+ClusterContainer* NTupleCreator::getClustersFromTES()
+{
+	ClusterContainer* clusterContainer=getIfExists<ClusterContainer>(m_clusterLocation);
+	if(!clusterContainer){
+		std::string errorMsg="There is no clusters in: " +m_clusterLocation;
+		throw DataError(errorMsg);
+	}
+	return  clusterContainer;
+}
+
+void NTupleCreator::fillClusters()
+{
+	ClusterContainer* clusterContainer=getClustersFromTES();
+	m_tdc=clusterContainer->getTDC();
+	m_timestamp=clusterContainer->getTimestamp();
+	if(clusterContainer->isEmpty()){
+		m_clusterNumberPerEvent=0;
+		ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/Clusters");
+		return;
+	}
+	int clusterPerEvent=clusterContainer->size();
+	m_clusterNumberPerEvent=clusterPerEvent;
+	const unsigned int maxClusterContainerSize=10;
+	unsigned int clusterCounter=0;
+	for(const auto& cluster: clusterContainer->getClusters())
+	{
+		m_clusterSize[clusterCounter]=cluster.m_size;
+		m_clusterCharge[clusterCounter]=cluster.m_charge;
+		m_clusterPosition[clusterCounter]=cluster.m_position;
+		m_clusterSeedPosition[clusterCounter]=cluster.m_seedPosition;
+		m_clusterSeedCharge[clusterCounter]=cluster.m_chargeSeed;
+		m_clusterCharge2StripLeft[clusterCounter]=cluster.m_charge2StripLeft;
+		m_clusterCharge1StripLeft[clusterCounter]=cluster.m_charge1StripLeft;
+		m_clusterCharge2StripRight[clusterCounter]=cluster.m_charge2StripRight;
+		m_clusterCharge1StripRight[clusterCounter]=cluster.m_charge1StripRight;
+		clusterCounter++;
+		if(clusterCounter>=maxClusterContainerSize) break;
+	}
+	ntupleSvc()->writeRecord("/NTUPLES/FILE1/TbUT/Clusters");
+}
diff --git a/TbUT/src/TbUTNTupleCreator.h b/TbUT/src/TbUTNTupleCreator.h
new file mode 100644
index 0000000..709d01f
--- /dev/null
+++ b/TbUT/src/TbUTNTupleCreator.h
@@ -0,0 +1,88 @@
+
+#pragma once
+
+#include "GaudiAlg/GaudiTupleAlg.h"
+#include "TbUTRawData.h"
+#include "TbUTCluster.h"
+
+#include <string>
+#include <stdexcept>
+
+
+namespace TbUT
+{
+class NTupleCreator : public GaudiTupleAlg {
+
+	class DataError: public std::runtime_error
+	{
+	public:
+		DataError(const std::string& err) :
+			std::runtime_error(err)
+		{
+		}
+	};
+
+ public:
+	NTupleCreator(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+
+ private:
+	void bookRawData();
+        void bookHeaderData();
+	void bookPedestal();
+	void bookCMS();
+	void bookClusters();
+
+
+	void fillRawData();
+        void fillHeaderData();
+	void fillPedestal();
+	void fillCMS();
+	void fillClusters();
+	template <typename DATA_TYPE = int>
+	RawDataContainer<DATA_TYPE>* getDataFromTES(const std::string& p_location);
+	ClusterContainer* getClustersFromTES();
+
+	int m_eventNumber;
+	int m_storeEventNumber;
+	bool m_isRawWritten;
+        bool m_isHeaderWritten;
+	bool m_isPedestalWritten;
+	bool m_isCMSWritten;
+	bool m_isClusterWritten;
+
+	std::string m_rawLocation;
+	std::string m_pedestalLocation;
+	std::string m_cmsLocation;
+	std::string m_clusterLocation;
+	std::string m_headerLocation;
+ 
+	NTuple::Array<double> m_rawSignal;
+	NTuple::Array<double> m_header0Signal;
+	NTuple::Array<double> m_header1Signal;
+	NTuple::Array<double> m_header2Signal;
+	NTuple::Array<double> m_header3Signal;
+	NTuple::Array<double> m_header3P1Signal;
+	NTuple::Array<double> m_header3P2Signal;
+	NTuple::Array<double> m_pedestalSignal;
+	NTuple::Array<double> m_cmsSignal;
+
+	NTuple::Item<int> m_clusterNumberPerEvent;
+	NTuple::Item<unsigned int> m_tdc;
+	NTuple::Item<unsigned long long> m_timestamp;
+
+	NTuple::Array<double> m_clusterPosition;
+	NTuple::Array<int> m_clusterSize;
+	NTuple::Array<int> m_clusterSeedPosition;
+	NTuple::Array<double> m_clusterCharge;
+	NTuple::Array<double> m_clusterSeedCharge;
+	NTuple::Array<double> m_clusterCharge2StripLeft;
+	NTuple::Array<double> m_clusterCharge1StripLeft;
+	NTuple::Array<double> m_clusterCharge2StripRight;
+	NTuple::Array<double> m_clusterCharge1StripRight;
+
+};
+
+}
diff --git a/TbUT/src/TbUTNoise.cpp b/TbUT/src/TbUTNoise.cpp
new file mode 100644
index 0000000..b196449
--- /dev/null
+++ b/TbUT/src/TbUTNoise.cpp
@@ -0,0 +1,126 @@
+/*
+ * TbUTNoise.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoise.h"
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <fstream>
+#include <cmath>
+
+using namespace TbUT;
+using namespace std;
+
+Noise::Noise():
+		m_hitLimit(160)
+{
+	Reset();
+}
+
+void Noise::updateNoise(RawData<double>* p_inputData)
+{
+	int l_channelNumber =RawData<>::getnChannelNumber();
+	const int channelPerBeetle=32;
+	for(int channel=0;channel<l_channelNumber;channel++)
+	{
+		if(0 == (channel%channelPerBeetle) ) m_hitLimit= calcualteHitThreshold(p_inputData, channel);
+		int signal=p_inputData->getSignal(channel);
+		if(abs(signal)<m_hitLimit){
+			double signalSquare=signal*signal;
+			m_noiseVector[channel]+=signalSquare;
+			m_channelEnties[channel]++;
+			m_meanVector[channel]+=signal;
+		}
+	}
+}
+
+void Noise::saveNoiseToFile(const std::string& p_filename)
+{
+	ofstream l_file(p_filename);
+	if(!l_file.good())
+	{
+		std::string l_errorMsg="Saving Noise to file- Cannot open output file: "+p_filename;
+		throw  NoiseCalculatorError(l_errorMsg);
+	}
+	NormalizeNoise();
+	int l_channelsNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelsNumber;channel++)
+	{
+		auto l_noise=m_noiseVector[channel];
+		l_file<<std::to_string(l_noise)<<" ";
+	}
+	l_file.close();
+}
+
+void Noise::retreiveNoiseFromFile(const std::string& p_filename)
+{
+		int l_channelsNumber=RawData<>::getnChannelNumber();
+		ifstream l_file(p_filename);
+		if(!l_file.good()){
+			std::string l_errorMsg="Cannot open input noise file: "+p_filename;
+			throw NoiseCalculatorError(l_errorMsg);
+		}
+
+		for(int channel=0;channel<l_channelsNumber;channel++)
+		{
+			double l_noiseFromFile=0;
+			l_file >> l_noiseFromFile;
+			m_noiseVector[channel]=l_noiseFromFile;
+			cout<<"NoiseRetreiver===> channel: "<< channel <<"noise: "<<l_noiseFromFile<<endl;
+		}
+
+}
+
+double Noise::calcualteHitThreshold(RawData<double>* p_inputData,int channelBegin) const
+{
+	const int channelPerBeetle=32;
+	double rms=0;
+	double mean=0;
+	const double initialHitLimit=160;
+	int usedChannel=0;
+
+	for (int channel=channelBegin;channel<channelBegin+channelPerBeetle;channel++)
+	{
+		auto channelSignal=p_inputData->getSignal(channel);
+		if( (0. != channelSignal ) && (abs(channelSignal)<initialHitLimit) ){
+			rms+=channelSignal*channelSignal;
+			mean+=channelSignal;
+			usedChannel++;
+		}
+
+	}
+	if(usedChannel) rms/=static_cast<double>(usedChannel);
+	if(usedChannel) mean/=static_cast<double>(usedChannel);
+	rms-=mean*mean;
+	double rmsMultiplicity=4;
+	return rmsMultiplicity*sqrt(rms);
+}
+
+
+void Noise::NormalizeNoise()
+{
+	int l_channelsNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelsNumber;channel++)
+		{
+			auto normalizationFactor=m_channelEnties[channel];
+			if(normalizationFactor)m_noiseVector[channel]/= static_cast<double>(normalizationFactor);
+			if(normalizationFactor)m_meanVector[channel]/=static_cast<double>(normalizationFactor);
+			m_noiseVector[channel]-=m_meanVector[channel]*m_meanVector[channel];
+			m_noiseVector[channel]=sqrt(m_noiseVector[channel]);
+		}
+}
+
+void Noise::Reset()
+{
+	int l_initialValue=0;
+	int l_sensorNumber=RawData<>::getnChannelNumber();
+	m_channelEnties=ChannelEntries(l_sensorNumber,l_initialValue);
+	m_noiseVector=NoiseVector(l_sensorNumber,l_initialValue);
+	m_meanVector=NoiseVector(l_sensorNumber,l_initialValue);
+
+}
+
+
diff --git a/TbUT/src/TbUTNoise.h b/TbUT/src/TbUTNoise.h
new file mode 100644
index 0000000..6dadf74
--- /dev/null
+++ b/TbUT/src/TbUTNoise.h
@@ -0,0 +1,51 @@
+/*
+ * TbUTNoise.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTRawData.h"
+#include <vector>
+
+
+namespace TbUT
+{
+
+class Noise
+{
+	typedef std::vector<double> NoiseVector;
+	typedef std::vector<int> ChannelEntries;
+public:
+	Noise();
+	void updateNoise(RawData<double>* p_inputData);
+	void saveNoiseToFile(const std::string& p_filename);
+	void retreiveNoiseFromFile(const std::string& p_filename);
+
+	double calcualteHitThreshold(RawData<double>* p_inputData, int channelBegin) const;
+
+	double getNoise(int p_channel) const{return m_noiseVector[p_channel];}
+	double operator[](int p_channel) const {return getNoise(p_channel);}
+
+	void NormalizeNoise();
+	void Reset();
+
+	class NoiseCalculatorError: public std::runtime_error
+	{
+	public:
+		NoiseCalculatorError(std::string &msg) :
+					std::runtime_error(msg)
+			{
+			}
+		};
+
+private:
+
+	int m_hitLimit;
+	ChannelEntries m_channelEnties;
+	NoiseVector m_noiseVector;
+	NoiseVector m_meanVector;
+};
+
+}
diff --git a/TbUT/src/TbUTNoiseCalculator.cpp b/TbUT/src/TbUTNoiseCalculator.cpp
new file mode 100644
index 0000000..e9be375
--- /dev/null
+++ b/TbUT/src/TbUTNoiseCalculator.cpp
@@ -0,0 +1,26 @@
+/*
+ * TbUTNoiseCalculator.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoiseCalculator.h"
+
+using namespace TbUT;
+
+
+NoiseCalculator::NoiseCalculator()
+{
+}
+
+void NoiseCalculator::updateNoise(RawData<double>* p_inputData)
+{
+	m_noise.updateNoise(p_inputData);
+}
+
+void NoiseCalculator::saveNoiseToFile(const std::string& p_filaname)
+{
+	m_noise.saveNoiseToFile(p_filaname);
+}
+
diff --git a/TbUT/src/TbUTNoiseCalculator.h b/TbUT/src/TbUTNoiseCalculator.h
new file mode 100644
index 0000000..f3be86d
--- /dev/null
+++ b/TbUT/src/TbUTNoiseCalculator.h
@@ -0,0 +1,29 @@
+/*
+ * TbUTNoiseCalculator.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTINoiseCalculator.h"
+#include "TbUTNoise.h"
+
+
+namespace TbUT
+{
+
+class NoiseCalculator: public INoiseCalculator
+{
+public:
+	NoiseCalculator();
+	void updateNoise(RawData<double>* p_inputData);
+	void saveNoiseToFile(const std::string& p_filaname);
+
+private:
+	Noise m_noise;
+
+};
+
+}
diff --git a/TbUT/src/TbUTNoiseCalculatorFake.cpp b/TbUT/src/TbUTNoiseCalculatorFake.cpp
new file mode 100644
index 0000000..96e7fc2
--- /dev/null
+++ b/TbUT/src/TbUTNoiseCalculatorFake.cpp
@@ -0,0 +1,26 @@
+/*
+ * TbUTNoiseCalculatorFake.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoiseCalculatorFake.h"
+
+using namespace TbUT;
+
+
+NoiseCalculatorFake::NoiseCalculatorFake()
+{
+
+}
+
+void NoiseCalculatorFake::updateNoise(RawData<double>* /*p_inputData*/)
+{
+
+}
+
+void NoiseCalculatorFake::saveNoiseToFile(const std::string& /*p_filename*/)
+{
+
+}
diff --git a/TbUT/src/TbUTNoiseCalculatorFake.h b/TbUT/src/TbUTNoiseCalculatorFake.h
new file mode 100644
index 0000000..db3497d
--- /dev/null
+++ b/TbUT/src/TbUTNoiseCalculatorFake.h
@@ -0,0 +1,24 @@
+/*
+ * TbUTNoiseCalculatorFake.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTINoiseCalculator.h"
+
+namespace TbUT
+{
+
+class NoiseCalculatorFake: public INoiseCalculator
+{
+public:
+	NoiseCalculatorFake();
+	void updateNoise(RawData<double>* p_inputData);
+	void saveNoiseToFile(const std::string& p_filaname);
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTNoiseCalculatorfactory.cpp b/TbUT/src/TbUTNoiseCalculatorfactory.cpp
new file mode 100644
index 0000000..f76fc13
--- /dev/null
+++ b/TbUT/src/TbUTNoiseCalculatorfactory.cpp
@@ -0,0 +1,29 @@
+/*
+ * TbUTNoiseCalculatorfactory.cpp
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTNoiseCalculatorfactory.h"
+#include "TbUTNoiseCalculator.h"
+#include "TbUTNoiseCalculatorFake.h"
+
+
+using namespace TbUT;
+
+
+NoiseCalculatorFactory::NoiseCalculatorFactory()
+{
+}
+
+NoiseCalculatorFactory::NoiseCalcualtorPtr NoiseCalculatorFactory::createNoiseCalculator(const std::string& p_noiseCalculatorType)
+{
+	if(p_noiseCalculatorType==TbUT::NoiseCalculatorType::calculator)
+		return NoiseCalcualtorPtr(new NoiseCalculator());
+	else if (p_noiseCalculatorType ==TbUT::NoiseCalculatorType::fake)
+		return NoiseCalcualtorPtr(new NoiseCalculatorFake());
+
+	else
+		throw NoSuchState(p_noiseCalculatorType);
+}
diff --git a/TbUT/src/TbUTNoiseCalculatorfactory.h b/TbUT/src/TbUTNoiseCalculatorfactory.h
new file mode 100644
index 0000000..6a1c058
--- /dev/null
+++ b/TbUT/src/TbUTNoiseCalculatorfactory.h
@@ -0,0 +1,41 @@
+/*
+ * TbUTNoiseCalculatorfactory.h
+ *
+ *  Created on: Jan 3, 2015
+ *      Author: ADendek
+ */
+#pragma once
+
+#include "TbUTINoiseCalculator.h"
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+namespace NoiseCalculatorType
+{
+static const std::string& calculator="calculator";
+static const std::string& fake="fake";
+}
+
+class NoiseCalculatorFactory
+{
+public:
+	typedef boost::shared_ptr<INoiseCalculator> NoiseCalcualtorPtr;
+	NoiseCalculatorFactory();
+	NoiseCalcualtorPtr createNoiseCalculator(const std::string& p_noiseCalculatorType);
+
+	class NoSuchState: public std::runtime_error
+		{
+		public:
+			NoSuchState(const std::string& p_errorMsg ):
+				std::runtime_error(p_errorMsg)
+			{
+			}
+		};
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTPedestal.cpp b/TbUT/src/TbUTPedestal.cpp
new file mode 100644
index 0000000..1291d0c
--- /dev/null
+++ b/TbUT/src/TbUTPedestal.cpp
@@ -0,0 +1,48 @@
+/*
+ * TbUTPedestal.cpp
+ *
+ *  Created on: Dec 31, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestal.h"
+#include <boost/assign/list_of.hpp>
+#include <boost/foreach.hpp>
+
+
+using namespace TbUT;
+using namespace std;
+
+Pedestal::Pedestal():
+		m_normalization(1024),
+		m_isNormalized(false)
+{
+	int l_initialValue=0*m_normalization;// temporary change. until initial value of the pedestal stabilize
+	int l_sensorNumber=RawData<>::getnChannelNumber();
+	m_pedestals=DataVector(l_sensorNumber,l_initialValue);
+}
+
+int Pedestal::getPedestal(int p_channel)
+{
+	//normalizePedestals();
+	return m_pedestals[p_channel];
+}
+
+void Pedestal::setPedestal(int p_channel, int p_value)
+{
+	m_pedestals[p_channel]=p_value;
+}
+
+void Pedestal::normalizePedestals()
+{
+	if(!m_isNormalized){
+		int i=0;
+		BOOST_FOREACH(auto& l_pedestal, m_pedestals)
+		{
+			l_pedestal/=m_normalization;
+			cout<<"channel: "<<i<<" pedestal: " <<l_pedestal<<endl;
+			i++;
+			m_isNormalized=true;
+		}
+	}
+}
diff --git a/TbUT/src/TbUTPedestal.h b/TbUT/src/TbUTPedestal.h
new file mode 100644
index 0000000..60b0755
--- /dev/null
+++ b/TbUT/src/TbUTPedestal.h
@@ -0,0 +1,43 @@
+/*
+ * TbUTPedestal.h
+ *
+ *  Created on: Dec 31, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTRawData.h"
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/vector.hpp>
+#include <iostream>
+
+
+namespace TbUT
+{
+
+class Pedestal
+{
+	typedef std::vector<int> DataVector;
+
+public:
+	Pedestal();
+	 void setPedestal(int p_channel, int p_value);
+	 int  getPedestal(int p_channel);
+	 int & operator[](size_t el) {return m_pedestals[el];}
+	 DataVector& getPedestalVector()
+	 {
+		 normalizePedestals();
+		 return m_pedestals;
+	 }
+	 void normalizePedestals();
+	 void setNormalizationFlag(bool p_flag){m_isNormalized=p_flag;}
+private:
+
+	int m_normalization;
+	bool m_isNormalized;
+	DataVector m_pedestals;
+
+};
+
+} /* namespace TbUT */
diff --git a/TbUT/src/TbUTPedestalCalculator.cpp b/TbUT/src/TbUTPedestalCalculator.cpp
new file mode 100644
index 0000000..121187e
--- /dev/null
+++ b/TbUT/src/TbUTPedestalCalculator.cpp
@@ -0,0 +1,118 @@
+/*
+ * TbUTPedestalCalculator.cpp
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalCalculator.h"
+#include <boost/serialization/serialization.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/foreach.hpp>
+#include <iostream>
+#include <fstream>
+
+
+using namespace TbUT;
+using namespace std;
+
+PedestalCalculator::PedestalCalculator(IChannelMaskProvider& p_maskProvider, Pedestal & p_pedestal):
+		m_maskProvider(p_maskProvider),
+		m_pedestal(p_pedestal),
+		m_normalization(1024),
+		m_event(0),
+		m_calculateInitialValueEvents(100)
+{
+}
+
+void PedestalCalculator::savePedestalToFile(const std::string& p_filename)
+{
+	ofstream l_file(p_filename);
+	if(!l_file.good())
+	{
+		std::string l_errorMsg="Saving Pedestal to file- Cannot open output file: "+p_filename;
+		throw  PedestalCalculatorError(l_errorMsg);
+	}
+	BOOST_FOREACH(auto l_pedestal, m_pedestal.getPedestalVector())
+	{
+		l_file<<std::to_string(l_pedestal)<<" ";
+	}
+	l_file.close();
+}
+
+StatusCode PedestalCalculator::processEvent(RawData<>* p_data)
+{
+	RunPhase l_runPhase=getRunPhase();
+	switch(l_runPhase)
+	{
+		case CALCULATE_INITIAL_VALUE:
+			return	calculateInitialValue(p_data);
+		case NORMALIZE_INITIAL_VALUE:
+			return normalizeInitialValue();
+		case CALUCLATE_PEDESTAL:
+			return calculaPedestal(p_data);
+		default:
+			string l_errorMsg="No such Phase!";
+			throw  PedestalCalculatorError(l_errorMsg);
+	}
+}
+
+PedestalCalculator::RunPhase PedestalCalculator::getRunPhase() const
+{
+	if(m_event<m_calculateInitialValueEvents)
+		return	CALCULATE_INITIAL_VALUE;
+	else if (m_event==m_calculateInitialValueEvents)
+		return NORMALIZE_INITIAL_VALUE;
+	else
+		return CALUCLATE_PEDESTAL;
+}
+
+StatusCode PedestalCalculator::calculateInitialValue(RawData<>* p_data)
+{
+	RawData<>::SignalVector l_inputData=p_data->getSignal();
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelNumber;channel++)
+		m_pedestal[channel]+=l_inputData[channel]*m_normalization;
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalCalculator::normalizeInitialValue()
+{
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelNumber;channel++){
+		m_pedestal[channel]/=m_calculateInitialValueEvents;
+		std::cout<<"Initial value of the Pedestal: channel " << channel << " value: "<<m_pedestal[channel]<< std::endl;
+	}
+	m_event++;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalCalculator::calculaPedestal(RawData<>* p_data)
+{
+	RawData<>::SignalVector l_inputData=p_data->getSignal();
+	int l_channelNumber=RawData<>::getnChannelNumber();
+	for(int channel=0;channel<l_channelNumber;channel++)
+		m_pedestal[channel]+=calculateUpdate(channel, l_inputData);
+	m_event++;
+
+	return StatusCode::SUCCESS;
+}
+
+double PedestalCalculator::calculateUpdate(int p_channel, RawData<>::SignalVector&  p_data )
+{
+	double l_update=0;
+	double l_saturation=15;
+	if(m_maskProvider.isMasked(p_channel))
+		l_update=0;
+	else
+	{
+		l_update=p_data[p_channel]-(m_pedestal[p_channel]/m_normalization);
+		if(l_update>l_saturation)l_update=l_saturation;
+		else if (l_update <(-1)*l_saturation) l_update=(-1)*l_saturation;
+	}
+	return l_update;
+}
+
+
diff --git a/TbUT/src/TbUTPedestalCalculator.h b/TbUT/src/TbUTPedestalCalculator.h
new file mode 100644
index 0000000..cc8b068
--- /dev/null
+++ b/TbUT/src/TbUTPedestalCalculator.h
@@ -0,0 +1,46 @@
+/*
+ * TbUTPedestalCalculator.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTPedestal.h"
+#include <stdexcept>
+
+namespace TbUT
+{
+class PedestalCalculator: public IPedestalFollowing
+{
+	enum RunPhase
+	{
+		CALCULATE_INITIAL_VALUE,
+		NORMALIZE_INITIAL_VALUE,
+		CALUCLATE_PEDESTAL
+	};
+
+public:
+	PedestalCalculator(IChannelMaskProvider& p_maskProvider, Pedestal & p_pedestal);
+	StatusCode processEvent(RawData<>* p_data);
+	void savePedestalToFile(const std::string& p_filename);
+
+private:
+
+	StatusCode calculateInitialValue(RawData<>* p_data);
+	StatusCode normalizeInitialValue();
+	StatusCode calculaPedestal(RawData<>* p_data);
+
+	RunPhase getRunPhase() const;
+
+	double calculateUpdate(int p_channel, RawData<>::SignalVector&  p_data);
+
+	IChannelMaskProvider& m_maskProvider;
+	Pedestal & m_pedestal;
+	int m_normalization;
+	int m_event;
+	const int m_calculateInitialValueEvents;
+};
+}
diff --git a/TbUT/src/TbUTPedestalFileValidator.cpp b/TbUT/src/TbUTPedestalFileValidator.cpp
new file mode 100644
index 0000000..2d72cba
--- /dev/null
+++ b/TbUT/src/TbUTPedestalFileValidator.cpp
@@ -0,0 +1,43 @@
+/*
+ * TbUTPedestalFileValidator.cpp
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalFileValidator.h"
+
+using namespace TbUT;
+using namespace boost::filesystem;
+
+
+PedestalFileValidator::PedestalFileValidator(const std::string& p_filename):
+		m_filename(p_filename)
+{
+}
+
+
+bool PedestalFileValidator::validateFile()
+{
+	m_path=path(m_filename);
+	 bool l_result=
+			  isfileExist() &&
+			  isRegularFile() &&
+			  hasNonZeroSize();
+	 return l_result;
+}
+
+bool PedestalFileValidator::isfileExist()
+{
+	 return exists(m_path);
+}
+
+bool PedestalFileValidator::isRegularFile()
+{
+	return  is_regular_file(m_path);
+}
+
+bool PedestalFileValidator::hasNonZeroSize()
+{
+	return !(0==file_size(m_path));
+}
diff --git a/TbUT/src/TbUTPedestalFileValidator.h b/TbUT/src/TbUTPedestalFileValidator.h
new file mode 100644
index 0000000..3386e45
--- /dev/null
+++ b/TbUT/src/TbUTPedestalFileValidator.h
@@ -0,0 +1,31 @@
+/*
+ * TbUTPedestalFileValidator.h
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTIFileValidator.h"
+#include <boost/filesystem.hpp>
+#include <string>
+
+namespace TbUT
+{
+
+class PedestalFileValidator: public IFileValidator
+{
+public:
+	PedestalFileValidator(const std::string& p_filename);
+	bool validateFile();
+
+private:
+	bool isfileExist();
+	bool isRegularFile();
+	bool hasNonZeroSize();
+
+	const std::string& m_filename;
+	boost::filesystem::path  m_path;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTPedestalFollowingFactory.cpp b/TbUT/src/TbUTPedestalFollowingFactory.cpp
new file mode 100644
index 0000000..0240833
--- /dev/null
+++ b/TbUT/src/TbUTPedestalFollowingFactory.cpp
@@ -0,0 +1,32 @@
+/*
+ * PedestalFollowingFactory.cpp
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+
+#include "TbUTPedestalFollowingFactory.h"
+#include "TbUTPedestalCalculator.h"
+#include "TbUTPedestalRetreiver.h"
+
+using namespace TbUT;
+
+PedestalFollowingFactory::PedestalFollowingFactory(IChannelMaskProvider& p_chanelMaskProvider,Pedestal &p_pedestal , IFileValidator& p_fileValidator, const std::string& p_filename):
+		m_chanelMaskProvider(p_chanelMaskProvider),
+		m_pedestal(p_pedestal),
+		m_fileValidator(p_fileValidator),
+		m_filename(p_filename)
+{
+}
+
+
+IPedestalFollowing* PedestalFollowingFactory::createPedestalFollowing(const std::string& p_followingType)
+{
+	if(!p_followingType.compare(TbUT::FollowingOptions::Calculator.c_str()))
+		return new PedestalCalculator(m_chanelMaskProvider, m_pedestal);
+	else if(!p_followingType.compare(TbUT::FollowingOptions::File.c_str()))
+		return new PedestalRetreiver(m_pedestal,m_fileValidator,m_filename);
+	else
+		throw NoSuchState(p_followingType);
+}
diff --git a/TbUT/src/TbUTPedestalFollowingFactory.h b/TbUT/src/TbUTPedestalFollowingFactory.h
new file mode 100644
index 0000000..a4846b5
--- /dev/null
+++ b/TbUT/src/TbUTPedestalFollowingFactory.h
@@ -0,0 +1,44 @@
+/*
+ * TbUTPedestalFollowingfactory.h
+ *
+ *  Created on: Oct 10, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTPedestal.h"
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTIFileValidator.h"
+
+#include <string>
+
+namespace TbUT
+{
+namespace FollowingOptions
+{
+static const std::string& Calculator = "calculator";
+static const std::string& File = "file";
+}
+
+class PedestalFollowingFactory
+{
+public:
+	PedestalFollowingFactory(IChannelMaskProvider& p_chanelMaskProvider,Pedestal &p_pedestal, IFileValidator& p_fileValidator,const std::string& p_filename  );
+	IPedestalFollowing* createPedestalFollowing(const std::string& p_followingType);
+	class NoSuchState: public std::runtime_error
+		{
+		public:
+		NoSuchState(const std::string& p_errorMsg ):
+					std::runtime_error(p_errorMsg)
+			{
+			}
+		};
+private:
+	IChannelMaskProvider& m_chanelMaskProvider;
+	Pedestal &m_pedestal;
+	IFileValidator& m_fileValidator;
+	const std::string& m_filename;
+
+};
+}
diff --git a/TbUT/src/TbUTPedestalRetreiver.cpp b/TbUT/src/TbUTPedestalRetreiver.cpp
new file mode 100644
index 0000000..949a1e0
--- /dev/null
+++ b/TbUT/src/TbUTPedestalRetreiver.cpp
@@ -0,0 +1,65 @@
+/*
+ * TbUTPedestalRetreiver.cpp
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+#include "TbUTPedestalRetreiver.h"
+
+#include "TbUTRawData.h"
+#include <iostream>
+#include <fstream>
+
+using namespace TbUT;
+using namespace std;
+
+PedestalRetreiver::PedestalRetreiver(Pedestal& p_pedestal, IFileValidator& p_fileValidator, const std::string& p_filename):
+		m_isFillingPedestalRequited(true),
+		m_pedestal(p_pedestal),
+		m_fileValidator(p_fileValidator),
+		m_filename(p_filename)
+{
+}
+
+void PedestalRetreiver::savePedestalToFile(const std::string& /*p_filename*/)
+{
+	cout<<"Not saving Pedestal!"<<endl;
+// do not save nothing!
+}
+
+
+StatusCode PedestalRetreiver::processEvent(RawData<>* /*p_data*/)
+{
+	if(!m_isFillingPedestalRequited){
+		cout<<"PedestalRetreiver===> pedestals ok!"<<endl;
+		return StatusCode::SUCCESS;
+	}
+
+	if(!m_fileValidator.validateFile() ){
+		cout<<"validation error!"<<endl;
+		return StatusCode::FAILURE;
+	}
+	getPedestalFromFile();
+	return StatusCode::SUCCESS;
+}
+
+void PedestalRetreiver::getPedestalFromFile()
+{
+	cout<<"PedestalRetreiver===>getting pedestals from file: "<< m_filename<<endl;
+	int l_channelsNumber=RawData<>::getnChannelNumber();
+	ifstream l_file(m_filename);
+	if(!l_file.good()){
+		std::string lerrorMsg="Cannot open input pedestal file: "+m_filename;
+		throw PedestalCalculatorError(lerrorMsg);
+	}
+
+	for(int channel=0;channel<l_channelsNumber;channel++)
+	{
+		double l_pedestalFromFile=0;
+		l_file >> l_pedestalFromFile;
+		m_pedestal.setPedestal(channel,l_pedestalFromFile);
+		cout<<"PedestalRetreiver===> channel: "<< channel <<"pedestal: "<<l_pedestalFromFile<<endl;
+	}
+	m_pedestal.setNormalizationFlag(true);
+	m_isFillingPedestalRequited=false;
+}
diff --git a/TbUT/src/TbUTPedestalRetreiver.h b/TbUT/src/TbUTPedestalRetreiver.h
new file mode 100644
index 0000000..4ba054e
--- /dev/null
+++ b/TbUT/src/TbUTPedestalRetreiver.h
@@ -0,0 +1,36 @@
+/*
+ * TbUTPedestalRetreiver.h
+ *
+ *  Created on: Jan 2, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTPedestal.h"
+#include "TbUTIFileValidator.h"
+
+namespace TbUT
+{
+
+class PedestalRetreiver: public IPedestalFollowing
+{
+public:
+	PedestalRetreiver(Pedestal& p_pedestal, IFileValidator& p_fileValidator, const std::string& p_filename);
+
+	StatusCode processEvent(RawData<>* p_data);
+	void savePedestalToFile(const std::string& p_filename);
+
+private:
+	void getPedestalFromFile();
+
+	bool m_isFillingPedestalRequited;
+	Pedestal & m_pedestal;
+	IFileValidator& m_fileValidator;
+	const std::string& m_filename;
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTPedestalSubtractor.cpp b/TbUT/src/TbUTPedestalSubtractor.cpp
new file mode 100644
index 0000000..67f73a4
--- /dev/null
+++ b/TbUT/src/TbUTPedestalSubtractor.cpp
@@ -0,0 +1,36 @@
+/*
+ * TbUTPedestalSubtractor.cpp
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#include"TbUTPedestalSubtractor.h"
+#include <iostream>
+
+using namespace TbUT;
+
+PedestalSubtractor::PedestalSubtractor(Pedestal & p_pedestal,IChannelMaskProvider& p_masksProvider ):
+		m_pedestal(p_pedestal),
+		m_masksProvider(p_masksProvider)
+{
+}
+
+ void PedestalSubtractor::processEvent(RawData<>* p_data, RawData<> **p_output)
+{
+	 int l_channelNumber=RawData<>::getnChannelNumber();
+	 RawData<>::DataType l_maskedChannelValue=0;
+	 for(int channel=0;channel<l_channelNumber;channel++)
+	 {
+		 if(m_masksProvider.isMasked(channel)) (*p_output)->setSignal(l_maskedChannelValue);
+		 else{
+			 RawData<>::DataType l_signalAfterPedestal= p_data->getSignal(channel)-m_pedestal.getPedestal(channel);
+			 (*p_output)->setSignal(l_signalAfterPedestal);
+		 }
+	 }
+	 (*p_output)->setTDC(p_data->getTDC());
+	 (*p_output)->setTime(p_data->getTime());
+
+}
+
+
diff --git a/TbUT/src/TbUTPedestalSubtractor.h b/TbUT/src/TbUTPedestalSubtractor.h
new file mode 100644
index 0000000..644bc89
--- /dev/null
+++ b/TbUT/src/TbUTPedestalSubtractor.h
@@ -0,0 +1,30 @@
+/*
+ * TbUTPedestalSubtractor.h
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIProcessingEngine.h"
+#include "TbUTPedestal.h"
+#include "TbUTIChannelMaskProvider.h"
+#include "TbUTRawData.h"
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+class PedestalSubtractor : public IProcessingEngine<>
+{
+public:
+	PedestalSubtractor(Pedestal  & p_pedestalSum,IChannelMaskProvider& p_masksProvider );
+	void processEvent(RawData<>* p_data, RawData<> **p_output);
+
+private:
+
+	Pedestal& m_pedestal;
+	IChannelMaskProvider& m_masksProvider;
+};
+}
diff --git a/TbUT/src/TbUTPedestalSubtractorAlgorithm.cpp b/TbUT/src/TbUTPedestalSubtractorAlgorithm.cpp
new file mode 100644
index 0000000..6a16cd8
--- /dev/null
+++ b/TbUT/src/TbUTPedestalSubtractorAlgorithm.cpp
@@ -0,0 +1,178 @@
+/*
+ * TbUTPedestalSubtractorAlgorithm.cpp
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalSubtractorAlgorithm.h"
+#include "TbUTDataLocations.h"
+
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,PedestalSubtractorAlgorithm)
+
+
+PedestalSubtractorAlgorithm::PedestalSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+		GaudiAlgorithm(name, pSvcLocator),
+		m_isStandalone(true),
+		m_data(),
+		m_inputDataLocation(),
+		m_outputDataLocation(),
+		m_pedestalInputLocation(),
+		m_pedestalOutputLocation(),
+		m_channelMaskInputLocation(),
+		m_followingOption(),
+		m_event(0),
+		m_treningEventNumber(0),
+		m_skippEvent(0),
+		m_channelMaskFileValidator(m_channelMaskInputLocation),
+		m_channelMaskProvider(m_channelMaskFileValidator),
+		m_pedestal(),
+		m_pedestalFileValidator(m_pedestalInputLocation),
+		m_followingFactory(m_channelMaskProvider, m_pedestal,m_pedestalFileValidator ,m_pedestalInputLocation),
+		m_pedestalFollowingPtr(),
+		m_pedestalSubtractor(m_pedestal, m_channelMaskProvider)
+{
+	declareProperty("SkippEventNumber", m_skippEvent=0);
+	declareProperty("InputDataLocation", m_inputDataLocation=TbUT::DataLocations::RawTES);
+	declareProperty("OutputDataLocation", m_outputDataLocation=TbUT::DataLocations::PedestalTES);
+	declareProperty("FollowingOption",m_followingOption=TbUT::FollowingOptions::Calculator);
+	declareProperty("treningEntry",m_treningEventNumber=1024);
+	declareProperty("ChannelMaskInputLocation", m_channelMaskInputLocation=TbUT::DataLocations::MaskLocation);
+	declareProperty("PedestalInputFile", m_pedestalInputLocation=TbUT::DataLocations::PedestalLocation);
+	declareProperty("PedestalOutputFile", m_pedestalOutputLocation=TbUT::DataLocations::PedestalLocation);
+	declareProperty("standalone",m_isStandalone=true );
+}
+
+StatusCode PedestalSubtractorAlgorithm::initialize()
+{
+	if(StatusCode::SUCCESS !=initializeBase()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=buildFollowing()) return StatusCode::FAILURE;
+	if(StatusCode::SUCCESS !=retriveMasksFromFile()) return StatusCode::FAILURE;
+
+	info()<<"Initialized successfully!"<<endmsg;
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalSubtractorAlgorithm::execute()
+{
+	if(StatusCode::SUCCESS != getData()) return StatusCode::FAILURE;
+	m_outputDataContainer=new RawDataContainer<>();
+
+	if(m_dataContainer->isEmpty()){
+		info()<<"ped suba put empty"<<endmsg;
+		put(m_outputDataContainer,m_outputDataLocation);
+		return StatusCode::SUCCESS;
+	}
+
+	for(const auto& rawDataIt: m_dataContainer->getData()){
+		m_data=new RawData<>(rawDataIt);
+		RunPhase l_runPhase=getRunPhase();
+		switch (l_runPhase)
+		{
+		case SKIPP:
+			skippEvent();
+		case TREANING:
+			processTreaning();
+		default:
+			subtractPedestals();
+		}
+		delete m_data;
+	}
+	put(m_outputDataContainer,m_outputDataLocation);
+	return StatusCode::SUCCESS;
+}
+
+StatusCode PedestalSubtractorAlgorithm::finalize()
+{
+	savePedestalsToFile();
+	return GaudiAlgorithm::finalize();
+}
+
+StatusCode PedestalSubtractorAlgorithm::initializeBase()
+{
+	  return GaudiAlgorithm::initialize();
+}
+
+StatusCode PedestalSubtractorAlgorithm::buildFollowing()
+try{
+	m_pedestalFollowingPtr.reset(m_followingFactory.createPedestalFollowing(m_followingOption));
+	return StatusCode::SUCCESS;
+}catch(PedestalFollowingFactory::NoSuchState &exception)
+{
+	error()<<"Invalid Following Option: "<<exception.what()<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode PedestalSubtractorAlgorithm::retriveMasksFromFile()
+try{
+	m_channelMaskProvider.getMaskFromFile(m_channelMaskInputLocation);
+	return StatusCode::SUCCESS;
+}catch(ChannelMaskProvider::InputFileError  &exception)
+{
+	error()<<"Channel Mask File Input Error: "<<m_channelMaskInputLocation<<endmsg;
+	return StatusCode::FAILURE;
+}
+
+
+StatusCode PedestalSubtractorAlgorithm::getData()
+{
+	m_dataContainer=getIfExists<RawDataContainer<> >(m_inputDataLocation);
+	if(!m_dataContainer){
+		error()<< " ==> There is no input data: "<< m_inputDataLocation <<endmsg;
+		return  StatusCode::FAILURE;
+	}
+	return  StatusCode::SUCCESS;
+}
+
+PedestalSubtractorAlgorithm::RunPhase PedestalSubtractorAlgorithm::getRunPhase()
+{
+	if(m_event<m_skippEvent)
+		return SKIPP;
+	else if (m_event<m_skippEvent+m_treningEventNumber)
+		return TREANING;
+	else
+		return SUBTRACTION;
+}
+
+
+void PedestalSubtractorAlgorithm::skippEvent()
+{
+	m_event++;
+}
+
+void PedestalSubtractorAlgorithm::processTreaning()
+{
+	m_pedestalFollowingPtr->processEvent(m_data);
+	m_event++;
+	//if( m_followingOption != TbUT::FollowingOptions::Calculator) subtractPedestals();
+}
+
+void PedestalSubtractorAlgorithm::subtractPedestals()
+{
+	processAndSaveDataToTES();
+	m_event++;
+}
+
+void PedestalSubtractorAlgorithm::processAndSaveDataToTES()
+{
+	RawData<> *afterPedestal=new RawData<>();
+	m_pedestalSubtractor.processEvent(m_data,&afterPedestal);
+	m_outputDataContainer->addData(*afterPedestal);
+}
+
+
+StatusCode PedestalSubtractorAlgorithm::savePedestalsToFile()
+try{
+	info()<<"Save Pedestal to File"<<endmsg;
+	m_pedestalFollowingPtr->savePedestalToFile(m_pedestalOutputLocation);
+	return  StatusCode::SUCCESS;
+}
+catch(IPedestalFollowing::PedestalCalculatorError &er)
+{
+	error()<<er.what() <<endmsg;
+	return  StatusCode::FAILURE;
+}
diff --git a/TbUT/src/TbUTPedestalSubtractorAlgorithm.h b/TbUT/src/TbUTPedestalSubtractorAlgorithm.h
new file mode 100644
index 0000000..8eafb8d
--- /dev/null
+++ b/TbUT/src/TbUTPedestalSubtractorAlgorithm.h
@@ -0,0 +1,87 @@
+/*
+ * TbUTPedestalSubtractorAlgorithm.h
+ *
+ *  Created on: Oct 14, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+#include "TbUTRawData.h"
+#include "TbUTPedestalFollowingFactory.h"
+#include "TbUTIPedestalFollowing.h"
+#include "TbUTPedestalSubtractor.h"
+#include "TbUTChannelMaskProvider.h"
+#include "TbUTChannelMaskFileValidator.h"
+#include "TbUTPedestal.h"
+#include "TbUTPedestalFileValidator.h"
+
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+namespace TbUT
+{
+
+class PedestalSubtractorAlgorithm: public GaudiAlgorithm
+{
+	typedef boost::shared_ptr<IPedestalFollowing> PedestalFollowingPtr;
+
+	enum RunPhase
+	{
+		 SKIPP,
+		 TREANING,
+		SUBTRACTION	
+	};
+
+public:
+	PedestalSubtractorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+	virtual StatusCode finalize();
+
+private:
+
+	StatusCode initializeBase();
+	StatusCode buildFollowing();
+	StatusCode retriveMasksFromFile();
+
+	void skippEvent();
+	void processTreaning();
+	void subtractPedestals();
+	
+	StatusCode getData();
+	void processAndSaveDataToTES();
+	StatusCode savePedestalsToFile();
+
+	RunPhase getRunPhase();
+
+	bool m_isStandalone;
+	RawDataContainer<>* m_dataContainer;
+	RawData<>* m_data;
+	RawDataContainer<>* m_outputDataContainer;
+
+	std::string m_inputDataLocation;
+	std::string m_outputDataLocation;
+	std::string m_pedestalInputLocation;
+	std::string m_pedestalOutputLocation;
+	std::string m_channelMaskInputLocation;
+	std::string m_followingOption;
+	int m_event;
+	int m_treningEventNumber;
+	int m_skippEvent;
+
+	ChannelMaskFileValidator m_channelMaskFileValidator;
+	ChannelMaskProvider m_channelMaskProvider;
+	Pedestal m_pedestal;
+	PedestalFileValidator m_pedestalFileValidator;
+	PedestalFollowingFactory m_followingFactory;
+	PedestalFollowingPtr m_pedestalFollowingPtr;
+	PedestalSubtractor m_pedestalSubtractor;
+
+};
+
+} 
+
diff --git a/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp b/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp
new file mode 100644
index 0000000..e0b7b86
--- /dev/null
+++ b/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.cpp
@@ -0,0 +1,62 @@
+/*
+ * TbUTPedestalDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Oct 18, 2014
+ *      Author: ADendek
+ */
+
+#include "TbUTPedestalSubtractorDataMonitorAlgorithm.h"
+
+#include "TbUTDataLocations.h"
+#include "TbUTRawData.h"
+
+#include "GaudiUtils/Aida2ROOT.h"
+#include <boost/format.hpp>
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,PedestalSubtractorDataMonitorAlgorithm)
+
+using namespace TbUT;
+
+PedestalSubtractorDataMonitorAlgorithm::PedestalSubtractorDataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : DataMonitorAlgorithm ( name , pSvcLocator )
+{
+	DataMonitorAlgorithm::m_inputDataLoc=TbUT::DataLocations::PedestalTES;
+}
+
+std::string PedestalSubtractorDataMonitorAlgorithm::createHistogramName()
+{
+	boost::format l_histogramName("Data_after_pedestal_event_%d");
+	l_histogramName % m_evtNumber;
+	return str(l_histogramName);
+}
+
+TH2D * PedestalSubtractorDataMonitorAlgorithm::bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber)
+{
+	int l_ylow=-800;
+	int l_yhigh=800;
+	int l_ybin=1600;
+	return Gaudi::Utils::Aida2ROOT::aida2root(book2D( p_histogramName,	p_histogramTitle,
+			-0.5+RawData<>::getMinChannel(),RawData<>::getMaxChannel()+0.5,p_sensorNumber,
+			l_ylow,l_yhigh,l_ybin ));
+}
+
+std::string PedestalSubtractorDataMonitorAlgorithm::createHistogramTitle()
+{
+	boost::format l_histogramTitle("Data after Pedestal Subtraction - event%1%");
+	l_histogramTitle% m_evtNumber;
+	return str(l_histogramTitle);
+}
+
+void PedestalSubtractorDataMonitorAlgorithm::createHistogram2D()
+{
+	std::string l_histogramName="PedestalData_vs_channel";
+	std::string l_histogramTtttle="Data after Pedestal vs channel";
+	int l_sensorNum=RawData<>::getnChannelNumber();
+	m_histogram2D=bookHistogram2D(l_histogramName,l_histogramTtttle,l_sensorNum );
+}
+
+StatusCode PedestalSubtractorDataMonitorAlgorithm::finalize()
+{
+	DataMonitorAlgorithm::m_outpuProjectionHistogramName="ProjectionPedestal";
+	return DataMonitorAlgorithm::finalize();
+}
diff --git a/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.h b/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.h
new file mode 100644
index 0000000..4a23f8f
--- /dev/null
+++ b/TbUT/src/TbUTPedestalSubtractorDataMonitorAlgorithm.h
@@ -0,0 +1,30 @@
+/*
+ * TbUTPedestalDataMonitorAlgorithm.h
+ *
+ *  Created on: Oct 18, 2014
+ *      Author: ADendek
+ */
+#pragma once
+
+
+#include "TbUTDataMonitorAlgorithm.h"
+
+namespace TbUT
+{
+
+class PedestalSubtractorDataMonitorAlgorithm: public DataMonitorAlgorithm
+{
+public:
+	PedestalSubtractorDataMonitorAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+	StatusCode finalize();
+
+private:
+	  TH2D * bookHistogram2D(const std::string & p_histogramName, const std::string & p_histogramTitle, int p_sensorNumber);
+	  std::string createHistogramTitle();
+	  void createHistogram2D();
+	  std::string createHistogramName();
+
+};
+}
+
+
diff --git a/TbUT/src/TbUTRandomNoiseGenerator.cpp b/TbUT/src/TbUTRandomNoiseGenerator.cpp
new file mode 100644
index 0000000..7951ad2
--- /dev/null
+++ b/TbUT/src/TbUTRandomNoiseGenerator.cpp
@@ -0,0 +1,33 @@
+/*
+ * TbUTRandomNoiseGenerator.cpp
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTRandomNoiseGenerator.h"
+#include <iostream>
+
+using namespace TbUT;
+
+RandomNoiseGenerator::RandomNoiseGenerator(double& p_sigma, double& p_mean):
+		m_sigma(p_sigma),
+		m_mean(p_mean),
+		m_randomGenerator()
+{
+}
+
+void RandomNoiseGenerator::checkInput()
+{
+}
+
+RawData<>* RandomNoiseGenerator::getEventData()
+{
+	RawData<>* l_outputNoise=new RawData<>();
+	for(int channel=0;channel<RawData<>::getnChannelNumber();channel++)
+	{
+		double l_randomNoise=m_randomGenerator.Gaus(m_sigma,m_mean);
+		l_outputNoise->setSignal(l_randomNoise);
+	}
+	return l_outputNoise;
+}
diff --git a/TbUT/src/TbUTRandomNoiseGenerator.h b/TbUT/src/TbUTRandomNoiseGenerator.h
new file mode 100644
index 0000000..a5c8264
--- /dev/null
+++ b/TbUT/src/TbUTRandomNoiseGenerator.h
@@ -0,0 +1,31 @@
+/*
+ * TbUTRandomNoiseGenerator.h
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include <TRandom.h>
+
+namespace TbUT
+{
+
+class RandomNoiseGenerator : public IDataReader
+{
+public:
+	RandomNoiseGenerator(double& p_sigma, double& p_mean);
+	void checkInput();
+	RawData<>* getEventData();
+
+private:
+	double& m_sigma;
+	double& m_mean;
+	TRandom m_randomGenerator;
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTRawData.cpp b/TbUT/src/TbUTRawData.cpp
new file mode 100644
index 0000000..7a6dda0
--- /dev/null
+++ b/TbUT/src/TbUTRawData.cpp
@@ -0,0 +1,12 @@
+/*
+ * TbUTRawData<>.cpp
+ *
+ *  Created on: Feb 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTRawData.h"
+using namespace TbUT;
+
+template <>
+Sensor RawData<int>::s_sensor=Sensor(1);
diff --git a/TbUT/src/TbUTRawData.h b/TbUT/src/TbUTRawData.h
new file mode 100644
index 0000000..e05115b
--- /dev/null
+++ b/TbUT/src/TbUTRawData.h
@@ -0,0 +1,240 @@
+#pragma once
+#include "GaudiKernel/DataObject.h"
+#include <string>
+#include <vector>
+#include "TbUTDataLocations.h"
+#include "TbUTSensor.h"
+
+namespace TbUT
+{
+template<typename DATA_TYPE = int>
+class RawData
+{
+public:
+	typedef std::vector<DATA_TYPE> SignalVector;
+	typedef DATA_TYPE DataType;
+
+	static void setSensor(Sensor p_sensor)
+	{
+		s_sensor=p_sensor;
+	}
+	static int getMaxChannel()
+	{
+		return s_sensor.maxChannel();
+	}
+
+	static int getMinChannel()
+	{
+		return s_sensor.minChannel();
+	}
+	static int getnChannelNumber()
+	{
+		return s_sensor.channelNumber*s_sensor.sensorNumber();
+	}
+
+	static int getSensorNumber()
+	{
+		return s_sensor.sensorNumber();
+	}
+
+	RawData<DATA_TYPE>():
+		m_signal(),
+    		m_header0(), 
+    		m_header1(), 
+    		m_header2(), 
+    		m_header3(), 
+    		m_header3P1(), 
+    		m_header3P2(),
+		m_time(),
+		m_temperature(),
+		m_tdc()
+	{
+	};
+
+	RawData<DATA_TYPE>& operator=( const RawData<DATA_TYPE>& rhs )
+	{
+		 if( this != &rhs ) {
+			 m_signal=rhs.m_signal;
+			 m_header0=rhs.m_header0;
+        	 m_header1=rhs.m_header1;
+	         m_header2=rhs.m_header2;
+        	 m_header3=rhs.m_header3;
+			 m_header3P1=rhs.m_header3P1;
+			 m_header3P2=rhs.m_header3P2;
+			 m_time=rhs.m_time;
+			 m_temperature=rhs.m_temperature;
+			 m_tdc=rhs.m_tdc;
+		 }
+	      return *this;
+	  }
+	RawData<DATA_TYPE>(const RawData<DATA_TYPE> &rhs):
+		 m_signal(rhs.m_signal),
+		 m_header0(rhs.m_header0),
+         m_header1(rhs.m_header1),
+		 m_header2(rhs.m_header2),
+		 m_header3(rhs.m_header3),
+		 m_header3P1(rhs.m_header3P1),
+		 m_header3P2(rhs.m_header3P2),
+		 m_time(rhs.m_time),
+		 m_temperature(rhs.m_temperature),
+		 m_tdc(rhs.m_tdc)
+	{
+	}
+	
+  	void setTemp(double p_temp)
+	{
+		m_temperature = p_temp;
+	}
+	void setTime(unsigned long long p_time)
+	{
+		m_time = p_time;
+	}
+	void setSignal(DATA_TYPE p_signal)
+	{
+		m_signal.push_back(p_signal);
+	}
+  void setHeader0(DATA_TYPE p_header) 
+  {
+    m_header0.push_back(p_header); 
+  }
+  void setHeader1(DATA_TYPE p_header) 
+  {
+    m_header1.push_back(p_header); 
+  }
+  void setHeader2(DATA_TYPE p_header) 
+  {
+    m_header2.push_back(p_header); 
+  }
+  void setHeader3(DATA_TYPE p_header) 
+  {
+    m_header3.push_back(p_header); 
+  }
+  void setHeader3P1(DATA_TYPE p_header) 
+  {
+    m_header3P1.push_back(p_header); 
+  }
+  void setHeader3P2(DATA_TYPE p_header) 
+  {
+    m_header3P2.push_back(p_header); 
+  }
+	SignalVector& getSignal()
+	{
+		return m_signal;
+	}
+	SignalVector& getHeader0()
+	{
+		return m_header0;
+	}
+	SignalVector& getHeader1()
+	{
+		return m_header1;
+	}
+	SignalVector& getHeader2()
+	{
+		return m_header2;
+	}
+	SignalVector& getHeader3()
+	{
+		return m_header3;
+	}
+	SignalVector& getHeader3P1()
+	{
+		return m_header3P1;
+	}
+	SignalVector& getHeader3P2()
+	{
+		return m_header3P2;
+	}
+
+	unsigned long long getTime() const
+	{
+		return m_time;
+	}
+	double getTemp() const
+	{
+		return m_temperature;
+	}
+
+	DATA_TYPE getSignal(int channel) const
+	{
+		return m_signal[channel];
+	}
+	
+  DATA_TYPE getHeader0(int subset) const
+	{
+		return m_header0[subset];
+	}
+  DATA_TYPE getHeader1(int subset) const
+	{
+		return m_header1[subset];
+	}
+  DATA_TYPE getHeader2(int subset) const
+	{
+		return m_header2[subset];
+	}
+  DATA_TYPE getHeader3(int subset) const
+	{
+		return m_header3[subset];
+	}
+  DATA_TYPE getHeader3P1(int subset) const
+	{
+		return m_header3P1[subset];
+	}
+  DATA_TYPE getHeader3P2(int subset) const
+	{
+		return m_header3P2[subset];
+	}
+
+	unsigned int getTDC() const
+	{
+		return m_tdc;
+	}
+
+	void setTDC(unsigned int p_tdc)
+	{
+		m_tdc=p_tdc;
+	}
+
+protected:
+	SignalVector m_signal;
+	SignalVector m_header0;
+	SignalVector m_header1;
+	SignalVector m_header2;
+	SignalVector m_header3;
+	SignalVector m_header3P1;
+	SignalVector m_header3P2;
+	unsigned long long m_time;
+	double m_temperature;
+	unsigned int m_tdc;
+
+	static Sensor s_sensor;
+};
+
+
+template<typename DataType  = int>
+class RawDataContainer:  public DataObject
+{
+public:
+	typedef std::vector<RawData<DataType> > RawDataVec;
+
+	RawDataContainer<DataType>():
+		empty(true),
+		m_dataVector()
+	{};
+
+	void addData(RawData<DataType> rawData)
+	{
+		m_dataVector.push_back(rawData);
+		empty=false;
+	}
+	bool isEmpty(){return empty;}
+	RawDataVec getData(){return m_dataVector;}
+private:
+	bool empty;
+	RawDataVec m_dataVector;
+
+};
+
+
+}
+
diff --git a/TbUT/src/TbUTRawDataFactory.cpp b/TbUT/src/TbUTRawDataFactory.cpp
new file mode 100644
index 0000000..c65b591
--- /dev/null
+++ b/TbUT/src/TbUTRawDataFactory.cpp
@@ -0,0 +1,40 @@
+/*
+ * TbUTRawDataFactory.cpp
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTRawDataFactory.h"
+#include "TbUTMambaDataReader.h"
+#include "TbUTAlibavaDataReader.h"
+#include "TbUTRandomNoiseGenerator.h"
+
+using namespace TbUT;
+
+
+RawDataFactory::RawDataFactory(std::string& p_filename,
+		IDataRetreiver & p_alibava,
+		IFileValidator& p_fileValidator,
+		bool& p_isAType,
+		double& p_mean,	double& p_sigma):
+				m_filename(p_filename),
+				m_alibava(p_alibava),
+				m_fileValidator(p_fileValidator),
+				m_isAType(p_isAType),
+				m_mean(p_mean),
+				m_sigma(p_sigma)
+{
+}
+
+RawDataFactory::DataReaderPtr  RawDataFactory::createDataEngine(const std::string& p_inputDataOption)
+{
+	if(p_inputDataOption==InputDataOption::Alibava)
+		return DataReaderPtr(new AlibavaDataReader(m_filename,m_alibava, m_fileValidator));
+	if(p_inputDataOption == InputDataOption::Mamba)
+		return DataReaderPtr(new MambaDataReader(m_filename,m_fileValidator,m_isAType ));
+	if(p_inputDataOption==InputDataOption::NoiseGenerator)
+		return DataReaderPtr(new RandomNoiseGenerator(m_mean,m_sigma));
+	else
+		throw NoSuchState(p_inputDataOption);
+}
diff --git a/TbUT/src/TbUTRawDataFactory.h b/TbUT/src/TbUTRawDataFactory.h
new file mode 100644
index 0000000..5e42cf3
--- /dev/null
+++ b/TbUT/src/TbUTRawDataFactory.h
@@ -0,0 +1,59 @@
+/*
+ * TbUTRawData<>Factory.h
+ *
+ *  Created on: Mar 16, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTIDataReader.h"
+#include "TbUTRawData.h"
+#include "TbUTAlibavaDataRetreiver.h"
+#include "TbUTAlbavaFileValidator.h"
+#include <memory>
+
+namespace TbUT
+{
+
+namespace InputDataOption
+{
+static const std::string& Alibava = "alibava";
+static const std::string& NoiseGenerator = "Generator";
+static const std::string& Mamba = "Mamba";
+}
+
+
+class RawDataFactory
+{
+public:
+	typedef std::shared_ptr<IDataReader> DataReaderPtr;
+
+	class NoSuchState: public std::runtime_error
+	{
+	public:
+		NoSuchState(const std::string& p_errorMsg ):
+			std::runtime_error(p_errorMsg)
+		{
+		}
+	};
+
+	RawDataFactory(std::string& p_filename,
+			IDataRetreiver & p_alibava,
+			IFileValidator& p_fileValidator,
+			bool& p_isAType,
+			double& p_mean,
+			double& p_sigma);
+	DataReaderPtr createDataEngine(const std::string& p_inputDataOption);
+	private:
+	std::string& m_filename;
+	IDataRetreiver & m_alibava;
+	IFileValidator& m_fileValidator;
+	bool& m_isAType;
+	double& m_mean;
+	double& m_sigma;
+
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/TbUTRawDataMonitorAlgorithm.cpp b/TbUT/src/TbUTRawDataMonitorAlgorithm.cpp
new file mode 100644
index 0000000..806c149
--- /dev/null
+++ b/TbUT/src/TbUTRawDataMonitorAlgorithm.cpp
@@ -0,0 +1,26 @@
+/*
+ * TbUTRawDataMonitorAlgorithm.cpp
+ *
+ *  Created on: Oct 7, 2014
+ *      Author: ADendek
+ */
+#include "TbUTRawDataMonitorAlgorithm.h"
+#include "TbUTDataLocations.h"
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,RawDataMonitorAlgorithm)
+
+using namespace TbUT;
+
+RawDataMonitorAlgorithm::RawDataMonitorAlgorithm( const std::string& name,ISvcLocator* pSvcLocator)
+  : DataMonitorAlgorithm ( name , pSvcLocator )
+{
+	RawDataMonitorAlgorithm::m_inputDataLoc=TbUT::DataLocations::RawTES;
+}
+
+
+
+StatusCode RawDataMonitorAlgorithm::finalize()
+{
+	DataMonitorAlgorithm::m_outpuProjectionHistogramName="ProjectionRawData";
+	return DataMonitorAlgorithm::finalize();
+}
diff --git a/TbUT/src/TbUTRawDataMonitorAlgorithm.h b/TbUT/src/TbUTRawDataMonitorAlgorithm.h
new file mode 100644
index 0000000..c782a7e
--- /dev/null
+++ b/TbUT/src/TbUTRawDataMonitorAlgorithm.h
@@ -0,0 +1,21 @@
+/*
+ * TbUTRawDataMonitorAlgorithm.h
+ *
+ *  Created on: Oct 7, 2014
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTDataMonitorAlgorithm.h"
+
+namespace TbUT
+{
+
+class RawDataMonitorAlgorithm : public DataMonitorAlgorithm
+{
+public:
+	RawDataMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator );
+	StatusCode finalize  ();
+};
+}
diff --git a/TbUT/src/TbUTRawDataReaderAlgorithm.cpp b/TbUT/src/TbUTRawDataReaderAlgorithm.cpp
new file mode 100644
index 0000000..e8da046
--- /dev/null
+++ b/TbUT/src/TbUTRawDataReaderAlgorithm.cpp
@@ -0,0 +1,105 @@
+#include "TbUTRawDataReaderAlgorithm.h"
+#include "GaudiKernel/ToolFactory.h"
+#include "GaudiKernel/IEventProcessor.h"
+
+
+using namespace TbUT;
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(TbUT,RawDataReaderAlgorithm)
+
+RawDataReaderAlgorithm::RawDataReaderAlgorithm(const std::string& name, ISvcLocator* pSvcLocator):
+	GaudiAlgorithm(name, pSvcLocator),
+	m_isStandalone(true),
+	m_isAType(true),
+	m_eventNumber(0),
+	m_skipEventNumber(0),
+	m_alibavaInputData(),
+	m_outputLocation(),
+	m_sensorNumber(1),
+	m_mean(0),
+	m_sigma(1),
+	m_alibava(),
+	m_fileValidator(m_alibavaInputData),
+	m_rawDataReader(),
+	m_inputDataFactory(m_alibavaInputData, m_alibava,m_fileValidator, m_isAType,m_mean,m_sigma )
+{
+	declareProperty("InputDataType", m_inputDataOption=TbUT::InputDataOption::Mamba);
+	declareProperty("SkipEventNumber", m_skipEventNumber=0);
+	declareProperty("inputData", m_alibavaInputData="run_000007_2607_1639.ali");
+	declareProperty("outputLoc", m_outputLocation=TbUT::DataLocations::RawTES );
+	declareProperty("sensorNumber", m_sensorNumber=1 );
+	declareProperty("standalone", m_isStandalone=true );
+	declareProperty("isAType", m_isAType=true );
+
+
+	declareProperty("sigma", m_sigma=0. );
+	declareProperty("mean", m_mean=1. );
+}
+
+
+StatusCode RawDataReaderAlgorithm::initialize()
+{
+	StatusCode sc = GaudiAlgorithm::initialize();
+	if (!sc.isSuccess()) return StatusCode::FAILURE;
+	try {
+		m_rawDataReader=m_inputDataFactory.createDataEngine(m_inputDataOption);
+		info()<<"Create data engine done"<<endmsg;
+	} catch(RawDataFactory::NoSuchState &ex) {
+		error()<<"Error input in factory: "<< ex.what()<<endmsg;
+		return StatusCode::FAILURE;
+	}
+	try {
+		m_rawDataReader->checkInput();
+		return StatusCode::SUCCESS;
+	} catch(IDataReader::InputFileError &ex) {
+		error()<<"input file error: "<< ex.what() <<endmsg;
+		return StatusCode::FAILURE;
+	}
+	try {
+		Sensor l_sensor(m_sensorNumber);
+		RawData<>::setSensor(l_sensor);
+	} catch(Sensor::SensorNumberError &ex) {
+		error()<<"Error create sensor: "<< ex.what()<<endmsg;
+		return StatusCode::FAILURE;
+	}
+	info()<<"initialization success!"<<endmsg;
+	return StatusCode::SUCCESS;
+
+}
+
+StatusCode RawDataReaderAlgorithm::execute()
+{
+	uint64_t mambaOffset=0; // need to be tuned
+	uint64_t keplerEventBegin = 0;
+	uint64_t keplerEventEnd = 0;
+	if(!m_isStandalone)
+		timingSvc()->eventDefinition(keplerEventBegin, keplerEventEnd);
+	else
+		keplerEventEnd=1;// more than 0
+
+	uint64_t mambaTimestamp=0;
+	RawDataContainer<> * outputDataContainer=new RawDataContainer<>();
+	while(mambaTimestamp+mambaOffset<keplerEventEnd){
+		try{
+			if(0==(m_eventNumber%1000) ) info()<<"Read event"<<m_eventNumber<<endmsg;
+			RawData<> * outputData=m_rawDataReader->getEventData();
+			outputDataContainer->addData(*outputData);
+			m_eventNumber++;
+			if(m_isStandalone) break; // do this loop only once
+		}catch(IDataReader::ReadEventError& ex ){
+			error()<<"event read error: "<< ex.what()<<endmsg;
+			return StatusCode::RECOVERABLE;
+		}catch(IDataReader::NoMoreEvents& ex){
+			SmartIF<IEventProcessor> app(serviceLocator()->service("ApplicationMgr"));
+			if (app){
+				info()<<"No more event. Terminate!"<<endmsg;
+				return app->stopRun();
+			}
+		}
+
+	}
+	put(outputDataContainer, m_outputLocation );
+	return StatusCode::SUCCESS;
+}
+
+
diff --git a/TbUT/src/TbUTRawDataReaderAlgorithm.h b/TbUT/src/TbUTRawDataReaderAlgorithm.h
new file mode 100644
index 0000000..f3e707f
--- /dev/null
+++ b/TbUT/src/TbUTRawDataReaderAlgorithm.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+// Tb/TbKernel
+#include "TbKernel/ITbTimingSvc.h"
+
+// Local
+#include "TbUTRawData.h"
+#include "TbUTAlibavaDataRetreiver.h"
+#include "TbUTAlbavaFileValidator.h"
+#include "TbUTRawDataFactory.h"
+#include "TbUTAlibavaDataReader.h"
+
+#include <string>
+
+
+namespace TbUT
+{
+
+class RawDataReaderAlgorithm : public GaudiAlgorithm {
+ public:
+	RawDataReaderAlgorithm(const std::string& name, ISvcLocator* pSvcLocator);
+
+	virtual StatusCode initialize();
+	virtual StatusCode execute();
+
+ private:
+	void termiateApp();
+
+	bool m_isStandalone;
+	bool m_isAType;
+	unsigned int m_eventNumber;
+	unsigned int m_skipEventNumber;
+
+	std::string  m_inputDataOption;
+	std::string m_alibavaInputData;
+	std::string m_outputLocation;
+	int m_sensorNumber;
+
+	double m_mean;
+	double m_sigma;
+
+
+	TbUT::AlibavaDataRetreiver m_alibava;
+	TbUT::AlbavaFileValidator m_fileValidator;
+	TbUT::RawDataFactory::DataReaderPtr m_rawDataReader;
+	TbUT::RawDataFactory m_inputDataFactory;
+
+  /// Pointer to timing service
+  mutable ITbTimingSvc* m_timingSvc;
+  /// Access timing service on-demand
+  ITbTimingSvc* timingSvc() const {
+    if (!m_timingSvc) m_timingSvc = svc<ITbTimingSvc>("TbTimingSvc", true);
+    return m_timingSvc;
+  }
+};
+
+}
+
diff --git a/TbUT/src/TbUTSensor.cpp b/TbUT/src/TbUTSensor.cpp
new file mode 100644
index 0000000..c7bf271
--- /dev/null
+++ b/TbUT/src/TbUTSensor.cpp
@@ -0,0 +1,39 @@
+/*
+ * TbUTSensor.cpp
+ *
+ *  Created on: Feb 6, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTSensor.h"
+
+using namespace TbUT;
+
+
+Sensor::Sensor():
+		m_channelMax(0),
+		m_channelMin(0)
+{
+	setChannelsNumbers(1);
+}
+
+Sensor::Sensor(int p_sensorNumber):
+		m_sensorNumber(p_sensorNumber),
+		m_channelMax(0),
+		m_channelMin(0)
+{
+	setChannelsNumbers(p_sensorNumber);
+}
+
+
+void Sensor::setChannelsNumbers(int p_number)
+{
+	m_channelMin = 0;
+	m_channelMax=512;
+
+	int l_maxSensorNumber=4;
+	if(p_number>l_maxSensorNumber){
+		std::string l_errMsg="Invalid Sensor Number: "+std::to_string(p_number);
+		throw SensorNumberError(l_errMsg);
+	}
+}
diff --git a/TbUT/src/TbUTSensor.h b/TbUT/src/TbUTSensor.h
new file mode 100644
index 0000000..786e00b
--- /dev/null
+++ b/TbUT/src/TbUTSensor.h
@@ -0,0 +1,43 @@
+/*
+ * TbUTSensor.h
+ *
+ *  Created on: Feb 6, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+#include <string>
+#include <stdexcept>
+
+namespace TbUT
+{
+
+class Sensor
+{
+public:
+	class SensorNumberError: public std::runtime_error
+	{
+	public:
+		SensorNumberError(std::string &msg) :
+					std::runtime_error(msg)
+			{
+			}
+		};
+	Sensor();
+	Sensor(int p_sensorNumber);
+
+	static const int channelNumber=512;
+	int minChannel() const {return m_channelMin;}
+	int maxChannel() const {return m_channelMax;}
+	int sensorNumber() const {return m_sensorNumber;}
+
+private:
+	void setChannelsNumbers(int p_sensorNumber);
+
+	int m_sensorNumber;
+	int m_channelMax;
+	int m_channelMin;
+
+};
+
+}
diff --git a/TbUT/src/TbUTTresholdProvider.cpp b/TbUT/src/TbUTTresholdProvider.cpp
new file mode 100644
index 0000000..0bdb4e2
--- /dev/null
+++ b/TbUT/src/TbUTTresholdProvider.cpp
@@ -0,0 +1,37 @@
+/*
+ * TbUTTresholdProvider.cpp
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#include "TbUTTresholdProvider.h"
+
+using namespace TbUT;
+
+TresholdProvider::TresholdProvider(const std::string& p_noiseFile,
+		const double& p_lowThresholdMultiplicity,
+		const double& p_highThresholdMultiplicity):
+		m_noiseFile(p_noiseFile),
+		m_lowThresholdMultiplicity(p_lowThresholdMultiplicity),
+		m_highThresholdMultiplicity(p_highThresholdMultiplicity),
+		m_noise()
+{
+}
+
+void TresholdProvider::retreiveTresholds()
+try{
+	m_noise.retreiveNoiseFromFile(m_noiseFile);
+}catch(Noise::NoiseCalculatorError& err){
+	throw ThresholdProviderError(err.what());
+}
+
+double TresholdProvider::getLowClusterThreshold(int p_channel)
+{
+	return (m_noise[p_channel]*m_lowThresholdMultiplicity);
+}
+
+double TresholdProvider::getHighClusterThreshold(int p_channel)
+{
+	return (m_noise[p_channel]*m_highThresholdMultiplicity);
+}
diff --git a/TbUT/src/TbUTTresholdProvider.h b/TbUT/src/TbUTTresholdProvider.h
new file mode 100644
index 0000000..6888e6d
--- /dev/null
+++ b/TbUT/src/TbUTTresholdProvider.h
@@ -0,0 +1,35 @@
+/*
+ * TbUTTresholdProvider.h
+ *
+ *  Created on: Jan 4, 2015
+ *      Author: ADendek
+ */
+
+#pragma once
+
+#include "TbUTITresholdProvider.h"
+#include "TbUTNoise.h"
+#include  <string>
+
+namespace TbUT
+{
+
+class TresholdProvider: public ITresholdProvider
+{
+public:
+	TresholdProvider(const std::string& p_noiseFile,
+			const double& p_lowThresholdMultiplicity,
+			const double& p_highThresholdMultiplicity );
+
+	void retreiveTresholds();
+	double getLowClusterThreshold(int p_channel);
+	double getHighClusterThreshold(int p_channel);
+private:
+	const std::string& m_noiseFile;
+	const double& m_lowThresholdMultiplicity;
+	const double& m_highThresholdMultiplicity;
+	Noise m_noise;
+};
+
+} /* namespace TbUT */
+
diff --git a/TbUT/src/alibava/.svn/all-wcprops b/TbUT/src/alibava/.svn/all-wcprops
new file mode 100644
index 0000000..8eb195c
--- /dev/null
+++ b/TbUT/src/alibava/.svn/all-wcprops
@@ -0,0 +1,71 @@
+K 25
+svn:wc:ra_dav:version-url
+V 60
+/guest/lhcb/!svn/ver/191830/Kepler/trunk/Tb/TbUT/src/alibava
+END
+TbAlibavaHit.h
+K 25
+svn:wc:ra_dav:version-url
+V 75
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/TbAlibavaHit.h
+END
+TbAsciiRoot.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/191830/Kepler/trunk/Tb/TbUT/src/alibava/TbAsciiRoot.cpp
+END
+Tracer.cc
+K 25
+svn:wc:ra_dav:version-url
+V 70
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/Tracer.cc
+END
+utils.cc
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/utils.cc
+END
+TbAlibavaData.h
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/TbAlibavaData.h
+END
+ChanList.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 73
+/guest/lhcb/!svn/ver/187105/Kepler/trunk/Tb/TbUT/src/alibava/ChanList.cpp
+END
+Tracer.h
+K 25
+svn:wc:ra_dav:version-url
+V 69
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/Tracer.h
+END
+utils.h
+K 25
+svn:wc:ra_dav:version-url
+V 68
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/utils.h
+END
+TbAsciiRoot.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/TbAsciiRoot.h
+END
+ChanList.h
+K 25
+svn:wc:ra_dav:version-url
+V 71
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/ChanList.h
+END
+TbAlibavaHit.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 77
+/guest/lhcb/!svn/ver/186934/Kepler/trunk/Tb/TbUT/src/alibava/TbAlibavaHit.cpp
+END
diff --git a/TbUT/src/alibava/.svn/entries b/TbUT/src/alibava/.svn/entries
new file mode 100644
index 0000000..151f0d1
--- /dev/null
+++ b/TbUT/src/alibava/.svn/entries
@@ -0,0 +1,402 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/src/alibava
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-07-14T15:38:17.550603Z
+191830
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+TbAlibavaHit.h
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+b670e2d90439473d757b00c7591f9c15
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+822
+
+TbAsciiRoot.cpp
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+7d9bc020497e30c6a40596644ce9aae5
+2015-07-14T15:38:17.550603Z
+191830
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+26511
+
+Tracer.cc
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+1e94d579f29cffebbd1712c7fbe3aaaf
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+821
+
+utils.cc
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+195b1b4c0a26c44b2e16c5683fcc6ad0
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1431
+
+TbAlibavaData.h
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+9ec6ada239b483e539e57912e2b13edf
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+561
+
+ChanList.cpp
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+5158b7a1d62dabee616136b013f11be4
+2015-04-22T10:33:54.442067Z
+187105
+hschindl
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3456
+
+Tracer.h
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+5e5a7dbc61e4ac62f62a3504e0dd76fb
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+851
+
+utils.h
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+cc1dc60f40a33a19055f2351c7b78ad3
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1204
+
+TbAsciiRoot.h
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+dde75904855246e49f346e9fc070dd22
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+6333
+
+ChanList.h
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+1f75bb8b4c8d2ce49d1e557682f1d4be
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+has-props
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2047
+
+TbAlibavaHit.cpp
+file
+
+
+
+
+2016-03-16T13:50:22.000000Z
+3240ef092e50451ed7d80ba050ffcb61
+2015-04-20T14:02:08.555985Z
+186934
+adendek
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+494
+
diff --git a/TbUT/src/alibava/.svn/prop-base/ChanList.cpp.svn-base b/TbUT/src/alibava/.svn/prop-base/ChanList.cpp.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/src/alibava/.svn/prop-base/ChanList.cpp.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/src/alibava/.svn/prop-base/ChanList.h.svn-base b/TbUT/src/alibava/.svn/prop-base/ChanList.h.svn-base
new file mode 100644
index 0000000..869ac71
--- /dev/null
+++ b/TbUT/src/alibava/.svn/prop-base/ChanList.h.svn-base
@@ -0,0 +1,5 @@
+K 14
+svn:executable
+V 1
+*
+END
diff --git a/TbUT/src/alibava/.svn/text-base/ChanList.cpp.svn-base b/TbUT/src/alibava/.svn/text-base/ChanList.cpp.svn-base
new file mode 100644
index 0000000..428c1da
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/ChanList.cpp.svn-base
@@ -0,0 +1,167 @@
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include "ChanList.h"
+
+static char svStr[8192];
+
+//////////////////////////////////////////////////////////////////////////
+// ChanList class
+//
+//   Created: Mon Sep  7 18:50:38 1998        Author: Carlos Lacasta
+//   Purpose:
+//
+//////////////////////////////////////////////////////////////////////////
+int cmp(const void *x1, const void *x2)
+{
+    double d1 = *(double *) x1 - *(double *) x2;
+    return (d1 == 0. ? 0 : (d1 < 0. ? -1 : 1));
+}
+int icmp(const void *x1, const void *x2)
+{
+    int d1 = *(int *) x1 - *(int *) x2;
+    return (d1 == 0 ? 0 : (d1 < 0 ? -1 : 1));
+}
+
+ChanList::ChanList(int i1, int /*i2*/) :
+        nch(0), cm(0.), noise(0.)
+{
+    for (int i = 0; i < nch; i++)
+        ch.push_back(i1 + i);
+
+    nch = ch.size();
+}
+ChanList::ChanList(const char *str) :
+        cm(0.), noise(0.)
+{
+    if (str == 0)
+        return;
+    Set(str);
+}
+
+ChanList::ChanList(const ChanList &cl)
+{
+    copy(cl);
+}
+
+ChanList &ChanList::operator=(const ChanList &cl)
+{
+    if (&cl == this)
+        return *this;
+    copy(cl);
+    return *this;
+}
+
+void ChanList::copy(const ChanList &cl)
+{
+    if ( &cl != this )
+    {
+        hits = cl.hits;
+        ch = cl.ch;
+        nch = ch.size();
+        cm = cl.cm;
+        noise = cl.noise;
+    }
+}
+int ChanList::Set(const char *str)
+{
+    char *p, *q;
+    int i, is;
+    int ival1, ival2, wRange;
+
+    ch.clear();
+    strcpy(svStr, str);
+    p = q = svStr;
+    wRange = 0;
+    while (*p)
+    {
+        switch (*p)
+        {
+            case ',':
+                *p = 0;
+                if (wRange)
+                {
+                    is = sscanf(q, "%d", &ival2);
+                    for (i = ival1 + 1; i <= ival2; i++)
+                        ch.push_back(i);
+                }
+                else
+                {
+                    is = sscanf(q, "%d", &ival1);
+                    ch.push_back(ival1);
+                }
+                wRange = 0;
+                q = p + 1;
+                p += is;
+                break;
+            case '-':
+                *p = 0;
+                wRange = 1;
+                is = sscanf(q, "%d", &ival1);
+                ch.push_back(ival1);
+                q = p + 1;
+                p += is;
+                break;
+        }
+        p++;
+    }
+    if (wRange)
+    {
+        is = sscanf(q, "%d", &ival2);
+        for (i = ival1 + 1; i <= ival2; i++)
+            ch.push_back(i);
+    }
+    else
+    {
+        is = sscanf(q, "%d", &ival2);
+        ch.push_back(ival2);
+    }
+    // sort
+    std::sort(ch.begin(), ch.end());
+    nch = ch.size();
+    return nch;
+}
+
+std::ostream &operator<<(std::ostream &os, ChanList &cl)
+{
+    for (int i = 0; i < cl.Nch(); i++)
+    {
+        if (i && !(i % 15))
+            os << std::endl;
+        os << std::setw(5) << cl[i];
+    }
+    return os;
+}
+
+int ChanList::ParseChanList(const char *str, ChanList **cl)
+{
+    int ireg, nreg = 0;
+    std::vector<char *> clst;
+    char *q, *p, *ptr;
+
+    if (str == 0)
+        return 0;
+    if (cl == 0)
+        return 0;
+    p = ptr = strdup(str);
+    do
+    {
+        clst.push_back(p);
+        q = strchr(p, ';');
+        if (q == 0)
+            break;
+        *q++ = 0;
+        p = q;
+    } while (*p);
+
+    nreg = clst.size();
+    *cl = new ChanList[nreg];
+    for (ireg = 0; ireg < nreg; ireg++)
+        (*cl)[ireg].Set(clst[ireg]);
+
+    free(ptr);
+    return nreg;
+}
diff --git a/TbUT/src/alibava/.svn/text-base/ChanList.h.svn-base b/TbUT/src/alibava/.svn/text-base/ChanList.h.svn-base
new file mode 100644
index 0000000..d33e8d4
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/ChanList.h.svn-base
@@ -0,0 +1,75 @@
+/* -*- mode: c++ -*- */
+#ifndef __ChanList_h__
+#define __ChanList_h__
+
+#include <iostream>
+#include <vector>
+#include "TbAlibavaHit.h"
+//////////////////////////////////////////////////////////////////////////
+// ChanList
+//
+//   Created: Mon Sep  7 18:46:56 1998        Author: Carlos Lacasta
+//   Purpose: Class to handle channel lists
+//
+//////////////////////////////////////////////////////////////////////////
+
+class ChanList
+{
+    protected:
+        int nch;                 // number of channels in the list
+        std::vector<int> ch;     // list of channels
+        TbAlibavaHitList hits;
+        double cm;               // Common mode
+        double noise;            // noise
+        void copy(const ChanList &);
+    public:
+        ChanList(const char *ch = 0);
+        ChanList(int, int);
+        ChanList(const ChanList &);
+        ChanList &operator=(const ChanList &);
+        virtual ~ChanList()
+        {
+            hits.clear();
+            ch.clear();
+        }
+        int Set(const char *);
+        int Nch() const
+        {
+            return nch;
+        }
+        int Chan(int x) const
+        {
+            return ch[x];
+        }
+
+        int operator[](int x) const { return ch[x]; }
+        void add_hit(const TbAlibavaHit &h) { hits.push_back(h); }
+        bool empty() const { return hits.empty(); }
+        int nhits() const { return hits.size(); }
+        void clear_hits() { hits.clear(); }
+        const TbAlibavaHit &get_hit(int i) const { return hits[i]; }
+        const TbAlibavaHitList hit_list() const { return hits; }
+
+        double CommonMode() const
+        {
+            return cm;
+        }
+        double Noise() const
+        {
+            return noise;
+        }
+        ChanList *CommonMode(double x)
+        {
+            cm = x;
+            return this;
+        }
+        ChanList *Noise(double x)
+        {
+            noise = x;
+            return this;
+        }
+        static int ParseChanList(const char *, ChanList **);
+};
+std::ostream &operator<<(std::ostream &, ChanList&);
+#endif
+
diff --git a/TbUT/src/alibava/.svn/text-base/TbAlibavaData.h.svn-base b/TbUT/src/alibava/.svn/text-base/TbAlibavaData.h.svn-base
new file mode 100644
index 0000000..78744dc
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/TbAlibavaData.h.svn-base
@@ -0,0 +1,32 @@
+#ifndef TBALIBAVADATA_H_
+#define TBALIBAVADATA_H_
+
+/**
+ *  Data is received from the USB port with this format
+ * 
+ */
+struct EventBlock
+{
+        unsigned int time;
+        unsigned short temp;
+        unsigned short data[256];
+};
+
+
+
+/**
+ * We add value as an estra parameter when moving the
+ * data within the application. It tells the value of
+ * the variables which are scanned
+ */
+struct EventData : public EventBlock
+{
+        double value;
+};
+
+struct EventDataBlock : public EventData
+{
+        unsigned short header[32];
+};
+
+#endif /*TBALIBAVADATA_H_*/
diff --git a/TbUT/src/alibava/.svn/text-base/TbAlibavaHit.cpp.svn-base b/TbUT/src/alibava/.svn/text-base/TbAlibavaHit.cpp.svn-base
new file mode 100644
index 0000000..cae9ee3
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/TbAlibavaHit.cpp.svn-base
@@ -0,0 +1,29 @@
+#include "TbAlibavaHit.h"
+
+TbAlibavaHit::TbAlibavaHit(int c, int l, int r, double s) :
+    _center(c), _left(l), _right(r), _sig(s)
+{
+}
+
+TbAlibavaHit::TbAlibavaHit(const TbAlibavaHit &h)
+{
+    cpy(h);
+}
+TbAlibavaHit::~TbAlibavaHit()
+{
+}
+
+void TbAlibavaHit::cpy(const TbAlibavaHit &h)
+{
+    _center = h._center;
+    _left = h._left;
+    _right = h._right;
+    _sig = h._sig;
+}
+TbAlibavaHit &TbAlibavaHit::operator=(const TbAlibavaHit &h)
+{
+    if (&h!=this)
+        cpy(h);
+
+    return *this;
+}
diff --git a/TbUT/src/alibava/.svn/text-base/TbAlibavaHit.h.svn-base b/TbUT/src/alibava/.svn/text-base/TbAlibavaHit.h.svn-base
new file mode 100644
index 0000000..39379fd
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/TbAlibavaHit.h.svn-base
@@ -0,0 +1,35 @@
+#ifndef __TBALIBAVAHIT_H__
+#define __TBALIBAVAHIT_H__
+
+/**
+ * A class representing a hit
+ */
+
+#include <vector>
+
+class TbAlibavaHit
+{
+    private:
+        int _center;
+        int _left;
+        int _right;
+        double _sig;
+        
+        void cpy(const TbAlibavaHit &h);
+    public:
+        TbAlibavaHit(int c=0, int l=0, int r=0, double s=0);
+        TbAlibavaHit(const TbAlibavaHit &h);
+        ~TbAlibavaHit();
+        
+        TbAlibavaHit &operator=(const TbAlibavaHit &h);
+        
+        int center() const { return _center; }
+        int left() const { return _left; }
+        int right() const { return _right; }
+        double signal() const { return _sig; }
+        int width() const { return _right - _left + 1; }
+};
+typedef std::vector< TbAlibavaHit> TbAlibavaHitList;
+
+
+#endif /*__TBALIBAVAHIT_H__*/
diff --git a/TbUT/src/alibava/.svn/text-base/TbAsciiRoot.cpp.svn-base b/TbUT/src/alibava/.svn/text-base/TbAsciiRoot.cpp.svn-base
new file mode 100644
index 0000000..892582a
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/TbAsciiRoot.cpp.svn-base
@@ -0,0 +1,1016 @@
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <ctime>
+#include <cmath>
+#include <sstream>
+#include <csignal>
+#include <vector>
+#include <cstdlib>
+#include <cerrno>
+#include <climits>
+#include <TROOT.h>
+#include <TCanvas.h>
+#include <TProfile2D.h>
+#include <TF1.h>
+#include <TH1.h>
+#include <TH2.h>
+#include "TbAsciiRoot.h"
+#include "utils.h"
+#include "Tracer.h"
+#include "TbAlibavaHit.h"
+#include "ChanList.h"
+/*
+
+#ifdef __APPLE__
+#define sighandler_t sig_t
+#endif
+
+bool _A_do_run = true;
+void _A_got_intr(int)
+{
+    _A_do_run = false;
+}
+*/
+// decodes the header and returns a vector with the integers found
+std::vector<int> decode_header(const std::string &h, TbAsciiRoot::XtraValues &xtra)
+{
+    std::vector<int> vout;
+    std::istringstream istr(h);
+    char *endptr;
+    char buf[256];
+    long val;
+
+    xtra.clear();
+
+    while (istr)
+    {
+        istr.getline(buf, sizeof(buf), ';');
+        if (!istr)
+            break;
+
+        errno = 0;
+        val = strtol(buf, &endptr, 0);
+
+        if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0))
+        {
+            std::string sval(buf), sout;
+            sout = trim_str(sval);
+            if (!sout.empty())
+                xtra.push_back( sout );
+        }
+        else if ( endptr == buf || *endptr != '\0' )
+        {
+            std::string sval(buf), sout;
+            sout = trim_str(sval);
+            if (!sout.empty())
+                xtra.push_back( sout );
+        }
+        else
+        {
+            vout.push_back(atoi(buf) );
+        }
+    }
+    return vout;
+}
+
+TbAsciiRoot::TbAsciiRoot(const char * /*nam*/, const char * /*pedfile*/, const char * /*gainfile*/) :
+    _nchan(max_nchan),_seedcut(10.), _neighcut(5.), _average_gain(1.), _version(2), _polarity(1)
+{
+    int i;
+    for (i=0;i<max_nchan;i++)
+    {
+        _ped[i] = 0.;
+        _gain[i] = 1.;
+        _noise[i] = 1.;
+        _data.data[i] = 0;
+        _mask[i] = false;
+    }
+    ifile=NULL;
+}
+
+TbAsciiRoot::~TbAsciiRoot()
+{
+    if (ifile)
+    {
+        ifile->close();
+    }
+}
+
+void TbAsciiRoot::open(const char *name)
+{
+    ifile = new std::ifstream(name);
+    if (!(*ifile))
+    {
+        std::cout << "Could not open data file: " << name << std::endl;
+        delete ifile;
+        ifile = 0;
+		return;
+    }
+    std::string header;
+    unsigned int ic, lheader;
+    char c;
+    ifile->read((char *)&_t0, sizeof(time_t));
+    //std::cout << "64b: " << ctime(&_t0) << std::endl;
+    ifile->read((char *)&_type, sizeof(int));
+    //std::cout << "type_ " << _type << std::endl;
+    if ( _type > 15 )
+    {
+        ifile->seekg(0, std::ios::beg);
+        ifile->read((char *)&_t0, sizeof(int));
+        ifile->read((char *)&_type, sizeof(int));
+        //std::cout << "32b: " << ctime(&_t0) << std::endl;
+    }
+
+
+    ifile->read((char *)&lheader, sizeof(unsigned int));
+    for (ic=0; ic<80; ic++)
+    {
+        ifile->read(&c, sizeof(char));
+        header.append(1, c);
+    }
+    header = trim_str(header);
+
+    if (header[0]!='V' && header[0]!='v')
+    {
+        _version = 0;
+    }
+    else
+    {
+        _version = int(header[1]-'0');
+        header = header.substr(5);
+    }
+
+    std::cout << "type: " << _type << " header: " << header << std::endl;
+    std::vector<int> param = decode_header(header, _xtra);
+    ifile->read((char *)_ped, max_nchan*sizeof(double));
+    ifile->read((char *)_noise, max_nchan*sizeof(double));
+    switch (_type)
+    {
+        case 1: // calibration
+        case 2: // laser sync
+            _npoints = param[0];
+            _from = param[1];
+            _to = param[2];
+            _step = param[3];
+            break;
+        case 3: // laser run
+        case 4: // source run
+        case 5: // pedestal run
+            if (param.empty())
+                _nevts = 100000;
+            else
+                _nevts = param[0];
+            _npoints = _from = _to = _step = 0;
+            break;
+    }
+    data_start = ifile->tellg();
+}
+
+void TbAsciiRoot::rewind()
+{
+    if (ifile)
+    {
+        ifile->clear();
+        ifile->seekg(data_start, std::ios::beg);
+    }
+}
+
+void TbAsciiRoot::close()
+{
+    if (ifile)
+    {
+        ifile->close();
+        delete ifile;
+        ifile = 0;
+    }
+}
+
+void TbAsciiRoot::reset_data()
+{
+    memset(&_data, 0, sizeof(_data));
+}
+
+int TbAsciiRoot::read_event(std::string & error_code)
+{
+    if (ifile)
+    {
+        unsigned int header, size, user=0, code=0;
+        char *block_data=0;
+        if (_version)
+        {
+            do
+            {
+                do
+                {
+                    ifile->read((char *)&header, sizeof(unsigned int));
+                    if (ifile->bad() || ifile->eof()){
+		      error_code="read Header";
+		      return -1;
+		    }
+
+                    code = (header>>16) & 0xFFFF;
+                } while ( code != 0xcafe );
+
+                code = header & 0x0fff;
+                user = header & 0x1000;
+                switch (code)
+                {
+                    case NewFile:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        new_file(size, block_data);
+                        break;
+                    case StartOfRun:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        start_of_run(size, block_data);
+                        break;
+                    case DataBlock:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        if (user)
+                        {
+                            reset_data();
+                            block_data = new char[size];
+                            ifile->read(block_data, size);
+                            new_data_block(size, block_data);
+                        }
+                        else
+                        {
+                            if ( _version == 1 )
+                            {
+                                ifile->read((char *)&_data, sizeof(EventData));
+                                for (int ii=0; ii<2; ii++)
+                                    memset(_header[ii], 0, 16*sizeof(unsigned short));
+
+                            }
+                            else
+                            {
+                                ifile->read((char *)&_data.value, sizeof(double));
+                                ifile->read((char *)&_data.time, sizeof(unsigned int));
+                                ifile->read((char *)&_data.temp, sizeof(unsigned short));
+                                for (int ii=0; ii<2; ii++)
+                                {
+                                    ifile->read((char *)_header[ii], 16*sizeof(unsigned short));
+                                    ifile->read((char *)&_data.data[ii*128], 128*sizeof(unsigned short));
+                                }
+                            }
+                        }
+
+                        break;
+                    case CheckPoint:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        check_point(size, block_data);
+                        break;
+                    case EndOfRun:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        end_of_run(size, block_data);
+                        break;
+                    default:
+                        std::cout << "Unknown block data type: " << std::hex << header << " - " << code << std::dec << std::endl;
+                }
+                if (block_data)
+                {
+                    delete [] block_data;
+                    block_data = 0;
+                }
+
+            } while ( code != DataBlock && !(ifile->bad() || ifile->eof()) );
+        }
+        else
+        {
+            ifile->read((char *)&_data, sizeof(EventData));
+            for (int ii=0; ii<2; ii++)
+                memset(_header[ii], 0, 16*sizeof(unsigned short));
+        }
+
+        if (ifile->eof())
+        {
+            std::cout << "End of file" << std::endl;
+	    error_code="End of file";
+            return -1;
+        }
+        else if (ifile->bad())
+        {
+            std::cout << "Problems with data file" << std::endl;
+	    error_code="Problems with data file";
+            return -1;
+        }
+        else
+	  {
+	    error_code="No problem";
+            //process_event();
+            return 0;
+        }
+    }
+    else{
+      error_code="big file problem";
+      return -1;
+    }
+}
+
+void TbAsciiRoot::set_data(int nchan, const unsigned short int *data)
+{
+    int i;
+    _nchan = nchan;
+    for (i=0;i<_nchan;i++)
+        _data.data[i] = data[i];
+}
+
+
+double TbAsciiRoot::time() const
+{
+    unsigned short fpart = _data.time & 0xffff;
+    short ipart = (_data.time & 0xffff0000)>>16;
+    if (ipart<0)
+        fpart *= -1;
+    //double tt = 100.*(1. -(ipart + (fpart/65535.)));
+    double tt = 100.0*(ipart + (fpart/65535.));
+    return tt;
+}
+
+double TbAsciiRoot::temp() const
+{
+    return 0.12*_data.temp - 39.8;
+}
+
+
+/*
+TH1 *TbAsciiRoot::show_pedestals()
+{
+    int ic;
+    TH1 *hst = create_h1("hPed","Pedestals",nchan(),-0.5, nchan()-0.5);
+    hst->SetYTitle("ADCs");
+    hst->SetXTitle("Channel no.");
+    for (ic=0; ic<nchan(); ic++)
+        hst->SetBinContent(ic+1, _ped[ic]);
+
+    return hst;
+}*/
+
+/*
+TH1 *TbAsciiRoot::show_noise()
+{
+    int ic;
+    TH1 *hst = create_h1("hNoise","Noise",nchan(),-0.5, nchan()-0.5);
+    if (gain()==1)
+    {
+        hst->SetYTitle("ADCs");
+    }
+    else
+    {
+        hst->SetYTitle("e^{-} ENC");
+    }
+    hst->SetXTitle("Channel no.");
+    for (ic=0; ic<nchan(); ic++)
+        hst->SetBinContent(ic+1, noise(ic));
+
+    return hst;
+}
+*/
+
+void TbAsciiRoot::compute_pedestals_fast(int mxevts, double wped, double wnoise)
+{
+    if (!ifile)
+        return;
+
+    if (mxevts<0)
+        mxevts = 100000000;
+
+    for (int i=0;i<max_nchan;i++)
+        _ped[i] = _noise[i] = 0.;
+
+    // std::ifstream::pos_type here = ifile->tellg();
+    std::cout << "Computing fast pedestals..." << std::endl;
+    std::string error="";
+    for (int ievt=0; read_event(error)==0 && ievt<mxevts; ievt++)
+    {
+        if (!(ievt%100))
+        {
+            std::cout << "\revent " << std::setw(10) << ievt << std::flush;
+        }
+        common_mode();
+        for (int i=0; i<nchan(); i++)
+        {
+            // TODO: figure out how to determine the chip number when
+            //       Plugin::filter_event has been called
+            int ichip = i/128;
+            // IF noise is 0, set it arbitrarily to 1.
+            if (_noise[i]==0.)
+                _noise[i] = 1.;
+
+            if (_ped[i]==0.)
+            {
+                // If pedestal is not yet computed we assume the current
+                // channel value should not be too far
+                _ped[i] = _data.data[i];
+            }
+            else
+            {
+                // Do the pedestal and noise correction
+                double corr;
+                double xs;
+
+                _signal[i] = _data.data[i] - _ped[i];
+                corr = _signal[i] * wped;
+
+                xs = (_signal[i]-_cmmd[ichip])/_noise[i];
+                if (corr > 1.)
+                    corr = 1.;
+
+                if (corr < -1)
+                    corr = -1.;
+
+                _ped[i] += corr;
+
+                if (fabs(xs) < 3.)
+                {
+                    _noise[i] = _noise[i]*(1.0-wnoise) + xs*xs*wnoise;
+                }
+            }
+        }
+    }
+    std::cout << "\nDone" << std::endl;
+    rewind();
+}
+
+/*
+TH2 *TbAsciiRoot::compute_pedestals(int mxevts, bool do_cmmd)
+{
+    if (!ifile)
+        return 0;
+
+    if (mxevts<0)
+        mxevts = 100000000;
+
+    int ievt, ichan;
+    TH2 *hst = create_h2("hRaw","Raw data",nchan(), -0.5,nchan()-0.5, 256, -0.5,1023.5);
+    TH2 *hsts = create_h2("hSig","Signal",nchan(), -0.5,nchan()-0.5,256, -127.5,127.5);
+
+
+    std::ifstream::pos_type here = ifile->tellg();
+    std::cout << "Computing pedestas..." << std::endl;
+    for (ievt=0; read_event()==0 && ievt<mxevts; ievt++)
+    {
+        process_event(do_cmmd);
+        for (ichan=0; ichan<nchan(); ichan++)
+            // TODO: get right chip number in all situations (after calling set_data)
+            hst->Fill(ichan, data(ichan)-get_cmmd(ichan/128));
+
+        if (!(ievt%100))
+        {
+            std::cout << "\revent " << std::setw(10) << ievt << std::flush;
+        }
+    }
+    std::cout << "\nDone" << std::endl;
+    rewind();
+
+    // TODO: _nchan can be updated in an event by event basis
+    //       while here we are assuming that it is the same
+    //       for all the events
+    for (ichan=0; ichan<nchan(); ichan++)
+    {
+        TF1 *g = new TF1("g1", "gaus");
+        TH1 *h1 = hst->ProjectionY("__hx__", ichan+1, ichan+1);
+        g->SetParameters(h1->GetSumOfWeights(), h1->GetMean(), h1->GetRMS());
+        g->SetRange(h1->GetMean()-2.5*h1->GetRMS(), h1->GetMean()+2.5*h1->GetRMS());
+        h1->Fit("g1", "q0wr");
+        _ped[ichan] = h1->GetFunction("g1")->GetParameter(1);
+        _noise[ichan] = h1->GetFunction("g1")->GetParameter(2);
+        delete h1;
+        delete g;
+    }
+
+    rewind();
+    for (ievt=0; read_event()==0 && ievt<mxevts; ievt++)
+    {
+        process_event(do_cmmd);
+        for (ichan=0; ichan<nchan(); ichan++)
+            hsts->Fill(ichan, signal(ichan));
+
+        if (!(ievt%100))
+        {
+            std::cout << "\revent " << std::setw(10) << ievt << std::flush;
+        }
+    }
+    std::cout << "\nDone" << std::endl;
+    rewind();
+
+    return hst;
+}
+*/
+
+
+
+void TbAsciiRoot::find_clusters(int ichip)
+{
+    int chan0=0;
+    int chan1=255;
+    if (ichip>=0 && ichip<2)
+        {
+            chan0 = ichip*128;
+            chan1 = (ichip+1)*128 -1;
+        }
+
+    std::ostringstream ostr;
+    ostr << chan0 << '-' << chan1;
+    ChanList C(ostr.str().c_str());
+
+    clear();
+    find_clusters(C);
+    _hits = C.hit_list();
+}
+
+void TbAsciiRoot::find_clusters(ChanList &C)
+{
+    // TODO: figure out how to determine the chip number in
+    //       all the situations
+    int i, j, imax=-1, left, right;
+    double mxsig=-1.e20, sg, val;
+    std::vector<bool> used(C.Nch());
+
+    for (i=0;i<C.Nch();i++)
+    {
+        used[i]= _mask[C[i]] ? true : false;
+    }
+
+
+
+    while (true)
+    {
+        /*
+         * Find the highest
+         */
+        imax = -1;
+        for (j=0; j<C.Nch(); j++)
+        {
+            i = C[j];
+            if (used[j] || _signal[i]*polarity()<0.)
+                continue;
+
+            if ( polarity()*sn(i) > _seedcut)
+            {
+                val = fabs(signal(i));
+                if (mxsig<val)
+                {
+                    mxsig = val;
+                    imax = j;
+                }
+            }
+        }
+
+        if (imax<0 || imax >= C.Nch() )
+            break;
+
+        sg = signal(C[imax]);
+        used[imax]=true;
+        // Now look at neighbors
+        // first to the left
+        left = imax;
+        for (j=imax-1;j>=0;j--)
+        {
+            i = C[j];
+            if ( used[j] || _signal[i]*polarity()<0.)
+                break;
+
+            if ( fabs(sn(i)) > _neighcut )
+            {
+                used[j] = true;
+                sg += signal(i);
+                left = j;
+            }
+            else
+                // TODO: this needs to be removed
+                // The idea is to merge to clusters that have only one strip in between
+                // In the laser runs this is a consequences of reflections...
+            {
+                int jx = j-1;
+                if (jx>=0  )
+                {
+                    if ( fabs(sn(C[jx])) > _neighcut )
+                        continue;
+                }
+                break;
+            }
+        }
+
+        // now to the right
+        right = imax;
+        for (j=imax+1;j<C.Nch();j++)
+        {
+            i = C[j];
+            if ( used[j] || _signal[i]*polarity()<0.)
+                break;
+            if ( fabs(sn(i))>_neighcut )
+            {
+                used[j] = true;
+                sg += signal(i);
+                right = j;
+            }
+            else
+                // TODO: this needs to be removed
+                // The idea is to merge to clusters that hanve only one strip in between
+                // In the laser runs this is a consequences of reflections...
+            {
+                int jx = i+1;
+                if (jx<C.Nch())
+                {
+                    if ( fabs(sn(C[jx])) > _neighcut )
+                        continue;
+                }
+                break;
+            }
+        }
+        C.add_hit(TbAlibavaHit(imax, left, right, sg));
+    }
+}
+
+void TbAsciiRoot::save_pedestals(const char *fnam)
+{
+    std::ofstream ofile(fnam);
+    if (!ofile)
+    {
+        std::cout << "Could not open " << fnam << " to save pedestals." << std::endl;
+        return;
+    }
+
+    // TODO: _nchan can be updated in an event by event basis
+    //       while here we are assuming that it is the same
+    //       for all the events
+    int i;
+    for (i=0; i<nchan(); i++)
+    {
+        ofile << _ped[i] << "\t" << _noise[i] << "\n";
+    }
+    ofile.close();
+}
+
+void TbAsciiRoot::load_pedestals(const char *fnam)
+{
+    std::ifstream ifile(fnam);
+    if (!ifile)
+    {
+        std::cout << "Could not open " << fnam << " to load pedestals." << std::endl;
+        return;
+    }
+    int i;
+    for (i=0; i<max_nchan; i++)
+    {
+        if (ifile.eof())
+            break;
+
+        ifile >> _ped[i] >> std::ws >> _noise[i] >> std::ws;
+        _mask[i] = (_noise[i]>20. || _noise[i]<=0.);
+    }
+    ifile.close();
+    /*
+    TCanvas *pedcanvas = create_canvas("Pedcanvas", "Pedestal Values", 600, 400);
+    TH1 *pedestalhisto = create_h1("pedestalhisto", "Pedestal Values", 256, -0.5, 255.5);
+    for (i=0; i<256; i++)
+    {
+        pedestalhisto->Fill(i, _ped[i]);
+    }
+    pedcanvas->cd(1);
+    pedestalhisto->Draw();
+*/
+}
+
+void TbAsciiRoot::load_masking(const char *fnam)
+{
+    std::ifstream ifile(fnam);
+    if (!ifile)
+    {
+        std::cout << "Could not open masked.txt. " << std::endl;
+        return;
+    }
+    int val;
+    for (int i=0; i<500; i++)
+    {
+        ifile >> val >> std::ws;
+        if (ifile.eof())
+            break;
+        if (val>255)
+        {
+            std::cout << "A value is greater than 255, causing an overflow crash. Please check the text file again. It has been set to 1 for continuation purposes. " << std::endl;
+            val = 1;
+        }
+        _mask[val] = true;
+    }
+}
+
+void TbAsciiRoot::load_gain(const char *fnam)
+{
+    std::ifstream ifile(fnam);
+    if (!ifile)
+    {
+        std::cout << "Could not open " << fnam << " to load the gain." << std::endl;
+        return;
+    }
+    int i;
+    int ichan;
+    double val, xn, xm;
+    xn=xm=0.;
+    for (i=0; i<max_nchan; i++)
+    {
+        ifile >> ichan >> std::ws;
+        if (ifile.eof())
+            break;
+        ifile >> val;
+        if (ifile.eof())
+            break;
+
+        xn++;
+
+        xm += val;
+        _gain[ichan] = val;
+
+        ifile >> std::ws;
+        if (ifile.eof())
+            break;
+    }
+    if (xn>0)
+    {
+        _average_gain = xm/xn;
+    }
+    ifile.close();
+}
+
+void TbAsciiRoot::process_event(bool do_cmmd)
+{
+    int i;
+    for (i=0; i<nchan(); i++)
+    {
+        _signal[i] = _data.data[i]-_ped[i];
+        _sn[i] = _noise[i]>1. && !_mask[i] ? _signal[i]/_noise[i] : 0.;
+    }
+    if (do_cmmd)
+    {
+        int ichip=-1;
+        common_mode();
+
+        for (i=0; i<nchan(); i++)
+        {
+            // TODO: figure out the right chip number
+            if (!(i%128))
+                ichip ++;
+
+            _signal[i] = _data.data[i]-_ped[i] - _cmmd[ichip];
+            _sn[i] = (_noise[i] >1. && !_mask[i] ? _signal[i]/_noise[i] : 0.);
+        }
+    }
+}
+
+void TbAsciiRoot::add_channel_list(const ChanList &C)
+{
+    chan_list.push_back(C);
+}
+
+
+void TbAsciiRoot::common_mode()
+{
+    ChanList C("0-127");
+    common_mode(C);
+
+    _cmmd[0] = C.CommonMode();
+    _cnoise[0] = C.Noise();
+
+
+    C.Set("128-255");
+    common_mode(C);
+
+    _cmmd[1] = C.CommonMode();
+    _cnoise[1] = C.Noise();
+}
+
+void TbAsciiRoot::common_mode(ChanList &C, bool correct)
+{
+    int ip, i, j;
+
+    double mean, sm, xn, xx, xs, xm, tmp;
+    bool use_it;
+    mean = sm = 0.;
+    for (ip=0;ip<3;ip++)
+    {
+        xn = xs = xm = 0.;
+        for (j=0; j<C.Nch(); j++)
+        {
+            i = C[j];
+            if (_mask[i])
+                continue;
+
+            use_it = true;
+            xx = data(i) - _ped[i];
+            if (ip)
+            {
+                tmp = fabs((xx-mean)/sm);
+                use_it = (tmp<2.5);
+            }
+            if (use_it)
+            {
+                xn++;
+                xm += xx;
+                xs += xx * xx;
+            }
+        }
+        if (xn>0.)
+        {
+            mean = xm / xn;
+            sm = sqrt( xs/xn - mean*mean);
+        }
+        //  std::cout << "...iter " << ip << ": xm " << mean << " xs: " << sm << std::endl;
+    }
+    C.CommonMode(mean);
+    C.Noise(sm);
+
+    if (correct)
+    {
+        for ( j=0; j<C.Nch(); j++ )
+        {
+            i = C[j];
+            _signal[i] = _data.data[i]-_ped[i] - C.CommonMode();
+            _sn[i] = (_noise[i] >1. && !_mask[i] ? _signal[i]/_noise[i] : 0.);
+        }
+    }
+}
+
+
+
+
+/*
+void TbAsciiRoot::spy_data(bool with_signal, int nevt)
+{
+    TVirtualPad *pad;
+    if (!ifile)
+        return;
+
+    sighandler_t old_handler = ::signal(SIGINT, _A_got_intr);
+    _A_do_run = true;
+
+    TCanvas *cnvs = (TCanvas *)gROOT->FindObject("cnvs");
+    if (cnvs)
+    {
+        cnvs->Clear();
+    }
+    else
+       cnvs = new TCanvas("cnvs","cnvs", 700, 800);
+
+    cnvs->Divide(2,3);
+
+
+    TH1 *hsignal = create_h1("hsignal","signal (ADC)",256, -0.5, 255.0);
+    hsignal->SetXTitle("Channel");
+    hsignal->SetYTitle("ADC");
+    hsignal->SetMinimum(-300);
+    hsignal->SetMaximum(300);
+
+    TH1 *helec = create_h1("helec","signal (elec)", 256, -0.5, 255.5);
+    helec->SetXTitle("Channel");
+    helec->SetYTitle("electrons");
+    helec->SetMinimum(-300/gain());
+    helec->SetMaximum(300/gain());
+
+    TH1 *hraw = create_h1("hraw","Raw Data (around 512.)",256, 0., 256.);
+    hraw->SetXTitle("Channel");
+    hraw->SetYTitle("ADC");
+    hraw->SetMinimum(-300);
+    hraw->SetMaximum(+300);
+
+    TH1 *hrawc = create_h1("hrawc","Raw Data (no commd)",256, 0., 256.);
+    hrawc->SetXTitle("Channel");
+    hrawc->SetYTitle("ADC");
+    hrawc->SetMinimum(-300);
+    hrawc->SetMaximum(+300);
+
+
+    TH1 *hcmmd[2];
+    hcmmd[0] = create_h1("hcmmd0","Common mode (Chip 0)",50,-100.,100.);
+    hcmmd[0]->SetXTitle("Common mode");
+    hcmmd[1] = create_h1("hcmmd1","Common mode (Chip 1)",50,-100.,100.);
+    hcmmd[1]->SetXTitle("Common mode");
+
+    int ievt,jevt;
+    for (ievt=jevt=0; read_event()==0 && _A_do_run && ievt<nevt;jevt++)
+    {
+        process_event();
+        find_clusters();
+        if ( with_signal && empty())
+            continue;
+
+        int i,ichip=-1;
+        for (i=0; i<nchan(); i++)
+        {
+            // TODO: figure out chip number
+            if (!(i%128))
+                ichip++;
+
+            hsignal->SetBinContent(i+1, _signal[i]);
+            helec->SetBinContent(i+1, signal(i));
+            hraw->SetBinContent(i+1,data(i)-512.);
+            hrawc->SetBinContent(i+1, data(i)-_ped[i]);
+            // TODO: why we draw the signal + common mode ?
+            //       May be cause signal should be ~0...
+            hcmmd[ichip]->Fill(_signal[i]+get_cmmd(ichip));
+        }
+        pad = cnvs->cd(1);
+        pad->SetGrid(1,1);
+        hsignal->Draw();
+        pad = cnvs->cd(2);
+        pad->SetGrid(1,1);
+        helec->Draw();
+
+        pad = cnvs->cd(3);
+        pad->SetGrid(1,1);
+        hraw->Draw();
+
+        pad = cnvs->cd(4);
+        pad->SetGrid(1,1);
+        hrawc->Draw();
+
+        pad = cnvs->cd(5);
+        pad->SetGrid(1,1);
+        hcmmd[0]->Draw();
+
+        pad = cnvs->cd(6);
+        pad->SetGrid(1,1);
+        hcmmd[1]->Draw();
+
+        std::cout << std::setiosflags(std::ios::fixed);
+        std::cout << "*** Event " << jevt << " *****" << std::endl;
+        std::cout << "Common Mode:" << std::endl
+                  << "   Chip 0 " << std::setw(6) << std::setprecision(1) << get_cmmd(0) << " noise: " << get_cnoise(0)
+                  << std::endl
+                  << "   Chip 1 " << std::setw(6) << std::setprecision(1) << get_cmmd(1) << " noise: " << get_cnoise(1)
+                  << std::endl;
+
+        std::cout << "Time: " << time() << " ns" << std::endl;
+        std::cout << "Signal chan(0) << " << signal(0) << " chan(1) " << signal(1) << std::endl;
+        std::cout << "Clusters: " << std::endl;
+
+        TbAlibavaHitList::iterator ip;
+        for (ip=begin(); ip!=end(); ++ip)
+        {
+            std::cout << "   chan: " << ip->center()
+                      << " sig: "
+                      << std::setw(6) << std::setprecision(1) << ip->signal()
+                      << " left: " << ip->left() << " right: " << ip->right()
+                      << std::endl;
+            std::cout << '\t' << "channels: " << std::endl;
+            int j;
+            for (j=ip->left();j<=ip->right();j++)
+                std::cout << "\t   " << j << " sn: " << _sn[j] << " signal: " << _signal[j] << " noise: " << _noise[j] << '\n';
+            std::cout << std::endl;
+        }
+
+        cnvs->Update();
+        ievt++;
+    }
+    std::cout << std::endl;
+    _A_do_run= true;
+    ::signal(SIGINT, old_handler);
+}
+*/
+
+bool is_text(const char *fnam)
+{
+    int nc;
+    char buffer[1024];
+    std::ifstream ifile(fnam);
+    if (!fnam)
+        return false;
+
+    ifile.read(buffer, sizeof(buffer));
+    nc = ifile.gcount();
+    ifile.close();
+    if (!nc) // empty files are text
+    {
+        return true;
+    }
+
+    std::string ss(buffer, nc);
+    ifile.close();
+
+    if ( ss.find('\0') != ss.npos )
+        return false;
+
+    double nontext = 0.;
+    double ntotal = 0.;
+    std::string::iterator ip;
+    for (ip=ss.begin(); ip!=ss.end(); ++ip)
+    {
+        ntotal++;
+        char c = *ip;
+        if ( (c<' ' || c >'~') && !strchr("\n\t\r\b", c) )
+            nontext++;
+    }
+    if ( nontext/ntotal > 0.3 )
+        return false;
+
+    return true;
+}
+
diff --git a/TbUT/src/alibava/.svn/text-base/TbAsciiRoot.h.svn-base b/TbUT/src/alibava/.svn/text-base/TbAsciiRoot.h.svn-base
new file mode 100644
index 0000000..6f0a570
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/TbAsciiRoot.h.svn-base
@@ -0,0 +1,244 @@
+#ifndef __Alibava_TbAsciiRoot_h__
+#define __Alibava_TbAsciiRoot_h__
+
+#include <vector>
+#include "TbAlibavaData.h"
+#include "TbAlibavaHit.h"
+#include "ChanList.h"
+#include <ctime>
+#include<string>
+#include <TH1.h>
+#include <TH2.h>
+
+
+/**
+ * This is the class that reads the data files
+ */
+
+class TbAsciiRoot
+{
+    public:
+        typedef std::vector<std::string> XtraValues;
+        enum BlockType { NewFile=0, StartOfRun, DataBlock, CheckPoint, EndOfRun };
+    private:
+        static const int max_nchan=256;
+        std::ifstream *ifile;
+        unsigned int data_start;
+        int _type;
+        time_t _t0;
+        int _npoints;
+        int _from;
+        int _to;
+        int _step;
+        int _nevts;
+        int _nchan; // current number of channels
+        XtraValues _xtra; // extra values from header
+        double _seedcut;
+        double _neighcut;
+        unsigned short _header[2][16];
+        double _ped[max_nchan];
+        double _noise[max_nchan];
+        double _signal[max_nchan];
+        double _sn[max_nchan];
+        double _cmmd[2];
+        double _cnoise[2];
+        double _gain[max_nchan];
+        double _average_gain;
+        bool   _mask[max_nchan];
+        int     _version;
+        int     _polarity;
+        TbAlibavaHitList _hits;
+
+        std::vector<ChanList> chan_list;
+        EventDataBlock _data;
+
+    protected:
+        void reset_data();
+
+    public:
+        void set_data(int i, unsigned short x) { _data.data[i] = x; }
+
+    public:
+        TbAsciiRoot(const char *nam=0, const char *pedfile=0, const char *gainfile=0);
+        virtual ~TbAsciiRoot();
+
+        bool valid() const
+        {
+            return (ifile!=0);
+        }
+
+        void open(const char *name);
+        void close();
+        void rewind();
+        int read_event(std::string & error_code);
+        virtual void check_point(int, const char *) {};
+        virtual void new_file(int, const char *) {}
+        virtual void start_of_run(int, const char *) {}
+        virtual void end_of_run(int, const char *) {}
+        virtual void new_data_block(int, const char *) {};
+
+        // The data format version
+        int version() const { return _version; }
+
+
+        int polarity() const { return _polarity; }
+        void polarity(int x) { _polarity = ( x<0 ? -1 : 1); }
+        /*
+         * Sets the number of channels and the data in the case
+         * of non "standard" values. If data==0, then only the number
+         * of channels is changed
+         */
+        void set_data(int nchan, const unsigned short *data=0);
+        int nchan() const { return _nchan; }
+        int type() const
+        {
+            return _type;
+        }
+        char *date() const
+        {
+            return ctime(&_t0);
+        }
+        double ped(int i) const
+        {
+            return _ped[i]/_gain[i];
+        }
+        double noise(int i) const
+        {
+            return _noise[i]/_gain[i];
+        }
+        double signal(int i) const
+        {
+            return _signal[i]/_gain[i];
+        }
+
+        double sn(int i) const
+        {
+            return _sn[i];
+        }
+
+        double get_cmmd(int i) const
+        {
+            return _cmmd[i];
+        }
+
+        double get_cnoise(int i) const
+        {
+            return _cnoise[i];
+        }
+
+        unsigned short data(int i) const
+        {
+            return _data.data[i];
+        }
+        double value() const
+        {
+            return _data.value;
+        }
+        double time() const;
+        double temp() const;
+        int npts() const
+        {
+            return _npoints;
+        }
+        int from() const
+        {
+            return _from;
+        }
+        int to() const
+        {
+            return _to;
+        }
+        int step() const
+        {
+            return _step;
+        }
+        int nevts() const
+        {
+            return _step;
+        }
+
+        void add_hit(const TbAlibavaHit &h)
+        {
+            _hits.push_back(h);
+        }
+        TbAlibavaHitList::iterator begin()
+        {
+            return _hits.begin();
+        }
+        TbAlibavaHitList::iterator end()
+        {
+            return _hits.end();
+        }
+        int nhits() const
+        {
+            return _hits.size();
+        }
+        bool empty() const
+        {
+            return _hits.empty();
+        }
+        const TbAlibavaHit &hit(int i) const
+        {
+            return _hits[i];
+        }
+        void set_hit_list(const TbAlibavaHitList &L) { _hits = L; }
+        void clear()
+        {
+            _hits.clear();
+        }
+
+        double get_gain(int i) const
+        {
+            return _gain[i];
+        }
+        double gain() const
+        {
+            return _average_gain;
+        }
+
+        double seed_cut() const
+        {
+            return _seedcut;
+        }
+        double neigh_cut() const
+        {
+            return _neighcut;
+        }
+        void set_cuts(double s, double n)
+        {
+            _seedcut = s;
+            _neighcut = n;
+        }
+        unsigned short get_header(int ichip, int ibit) { return _header[ichip][ibit]; }
+
+        TH1 *show_pedestals();
+        TH1 *show_noise();
+        TH2 *compute_pedestals(int mxevts=-1, bool do_cmmd=true);
+        void compute_pedestals_fast(int mxevts = -1, double ped_weight=0.01, double noise_weight=0.001);
+
+
+        void process_event(bool do_cmmd=true);
+        void find_clusters(int ichip=-1);
+        void find_clusters(ChanList &C);
+        void save_pedestals(const char *fnam);
+        void load_pedestals(const char *fnam);
+        void load_gain(const char *fnam);
+		void load_masking(const char *fnam);
+        void spy_data(bool with_signal=false, int nevt=1);
+        void common_mode();
+        void common_mode(ChanList &C, bool correct=false);
+
+        int  n_channel_list() const { return chan_list.size(); }
+        void add_channel_list(const ChanList &C);
+        void clear_channel_lists() { chan_list.clear(); }
+        ChanList get_channel_list(int i) const { return chan_list[i]; }
+
+        int nxtra() const { return _xtra.size(); }
+        const std::string xtra(int i) const { return _xtra[i]; }
+        void add_xtra(const std::string &x) { _xtra.push_back(x); }
+        void add_xtra(const char *x) { _xtra.push_back(x); }
+};
+// Return true if file is an ASCII text file
+bool is_text(const char *);
+
+#endif
diff --git a/TbUT/src/alibava/.svn/text-base/Tracer.cc.svn-base b/TbUT/src/alibava/.svn/text-base/Tracer.cc.svn-base
new file mode 100644
index 0000000..dc981c7
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/Tracer.cc.svn-base
@@ -0,0 +1,48 @@
+#include <TH1.h>
+
+#include "Tracer.h"
+
+Tracer::Tracer(const char *name, const char *title, int npts, int avrg)
+    : size(npts), average(avrg), cntr(0.), val(0.)
+{
+    hst = new TH1D(name, title, size, 0, size);
+   
+}
+
+Tracer::~Tracer()
+{
+    delete hst;
+}
+
+void Tracer::Draw(const char *opt)
+{
+    hst->Draw(opt);
+}
+
+void Tracer::fill(double x)
+{
+    if (average>1.)
+    {
+        val = (x + cntr*val)/(++cntr);
+        if ( (int(cntr)%average)==0 )
+        {
+            add_point(val);
+        }
+    }
+    else
+        add_point(x);
+}
+
+void Tracer::add_point(double x)
+{
+    queue.push_back(x);
+    if (queue.size()>size)
+        queue.pop_front();
+    
+    std::deque<double>::iterator ip;
+    int ibin = 1;
+    for (ip=queue.begin();ip!=queue.end();++ip, ibin++)
+    {
+        hst->SetBinContent(ibin, *ip);
+    }
+}
diff --git a/TbUT/src/alibava/.svn/text-base/Tracer.h.svn-base b/TbUT/src/alibava/.svn/text-base/Tracer.h.svn-base
new file mode 100644
index 0000000..f7826a7
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/Tracer.h.svn-base
@@ -0,0 +1,39 @@
+#ifndef TRACER_H_
+#define TRACER_H_
+#include <deque>
+
+class TH1;
+
+class Tracer
+{
+    private:
+        unsigned int size;
+        int average;
+        double cntr;
+        double val;
+        std::deque<double> queue;
+        TH1 *hst;
+
+    public:
+        /**
+         * Defines a tracer. At input npts defines the size of
+         * the buffer (a FIFO actually) with the values that the
+         * Tracer will remember. Also, if average is given, the 
+         * Tracer will add as new points the average over 'average'
+         * inputs
+         */
+        Tracer(const char*nam, const char *tit, int npts, int average=0);
+        virtual ~Tracer();
+
+        void Draw(const char *opt="");
+
+        TH1 *get_hst()
+        {
+            return hst;
+        }
+
+        void fill(double val);
+        void add_point(double x);
+};
+
+#endif /*TRACER_H_*/
diff --git a/TbUT/src/alibava/.svn/text-base/utils.cc.svn-base b/TbUT/src/alibava/.svn/text-base/utils.cc.svn-base
new file mode 100644
index 0000000..398432c
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/utils.cc.svn-base
@@ -0,0 +1,56 @@
+#include <TROOT.h>
+#include "utils.h"
+
+TCanvas *create_canvas(const char *name, const char *title, int wx, int wy)
+{
+    TCanvas *cnvs = (TCanvas *)gROOT->FindObject("name");
+    if (cnvs)
+        delete cnvs;
+
+    if (wx<0 ||wy<0)
+        cnvs = new TCanvas(name, title);
+    else
+        cnvs = new TCanvas(name, title, wx, wy);
+
+    return cnvs;
+}
+
+TH1 *create_h1(const char *name, const char *tit, int n, double x1, double x2)
+{
+    TH1 *hst = (TH1 *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+    
+    hst = new TH1D(name, tit, n, x1, x2);
+    return hst;
+}
+
+TH2 *create_h2(const char *name, const char *tit, int nx, double x1, double x2, int ny, double y1, double y2)
+{
+    TH2 *hst = (TH2 *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+    
+    hst = new TH2D(name, tit, nx, x1, x2, ny, y1, y2);
+    return hst;
+}
+
+TProfile *create_profile(const char *name, const char *tit, int n, double x1, double x2, double y1, double y2)
+{
+    TProfile *hst = (TProfile *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+    
+    hst = new TProfile(name, tit, n, x1, x2, y1, y2);
+    return hst;
+}
+
+TProfile2D *create_profile2d(const char *name, const char *tit, int nx, double x1, double x2, int ny, double y1, double y2)
+{
+    TProfile2D *hst = (TProfile2D *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+
+    hst = new TProfile2D(name, tit, nx, x1, x2, ny, y1, y2);
+    return hst;
+}
diff --git a/TbUT/src/alibava/.svn/text-base/utils.h.svn-base b/TbUT/src/alibava/.svn/text-base/utils.h.svn-base
new file mode 100644
index 0000000..b82693c
--- /dev/null
+++ b/TbUT/src/alibava/.svn/text-base/utils.h.svn-base
@@ -0,0 +1,48 @@
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <string>
+#include <vector>
+#include <TH1.h>
+#include <TH2.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
+#include <TCanvas.h>
+
+/**
+ * Utils
+ */
+inline bool isws(char c, char const * const wstr=" \t\n")
+{
+    return (strchr(wstr, c) != NULL);
+}
+
+inline std::string trim_right(const std::string &s)
+{
+    std::string b=" \t\n";
+    std::string str = s;
+    return str.erase(str.find_last_not_of(b) +1);
+}
+
+inline std::string trim_left(const std::string &s)
+{
+    std::string b=" \t\n";
+    std::string str = s;
+    return str.erase( 0, str.find_first_not_of(b) );
+}
+
+inline std::string trim_str(const std::string &s)
+{
+    std::string str = s;
+    return trim_left(trim_right(str) );
+}
+
+TCanvas *create_canvas(const char *name, const char *title, int wx=-1, int wy=-1);
+TH1 *create_h1(const char *, const char *, int, double, double);
+TH2 *create_h2(const char *, const char *, int, double, double, int, double, double);
+TProfile *create_profile(const char *, const char *, int, double, double, double, double);
+TProfile2D *create_profile2d(const char *name, const char *tit, int nx, double x1, double x2, int ny, double y1, double y2);
+
+
+
+#endif /*UTILS_H_*/
diff --git a/TbUT/src/alibava/ChanList.cpp b/TbUT/src/alibava/ChanList.cpp
new file mode 100755
index 0000000..428c1da
--- /dev/null
+++ b/TbUT/src/alibava/ChanList.cpp
@@ -0,0 +1,167 @@
+#include <iostream>
+#include <iomanip>
+#include <vector>
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include "ChanList.h"
+
+static char svStr[8192];
+
+//////////////////////////////////////////////////////////////////////////
+// ChanList class
+//
+//   Created: Mon Sep  7 18:50:38 1998        Author: Carlos Lacasta
+//   Purpose:
+//
+//////////////////////////////////////////////////////////////////////////
+int cmp(const void *x1, const void *x2)
+{
+    double d1 = *(double *) x1 - *(double *) x2;
+    return (d1 == 0. ? 0 : (d1 < 0. ? -1 : 1));
+}
+int icmp(const void *x1, const void *x2)
+{
+    int d1 = *(int *) x1 - *(int *) x2;
+    return (d1 == 0 ? 0 : (d1 < 0 ? -1 : 1));
+}
+
+ChanList::ChanList(int i1, int /*i2*/) :
+        nch(0), cm(0.), noise(0.)
+{
+    for (int i = 0; i < nch; i++)
+        ch.push_back(i1 + i);
+
+    nch = ch.size();
+}
+ChanList::ChanList(const char *str) :
+        cm(0.), noise(0.)
+{
+    if (str == 0)
+        return;
+    Set(str);
+}
+
+ChanList::ChanList(const ChanList &cl)
+{
+    copy(cl);
+}
+
+ChanList &ChanList::operator=(const ChanList &cl)
+{
+    if (&cl == this)
+        return *this;
+    copy(cl);
+    return *this;
+}
+
+void ChanList::copy(const ChanList &cl)
+{
+    if ( &cl != this )
+    {
+        hits = cl.hits;
+        ch = cl.ch;
+        nch = ch.size();
+        cm = cl.cm;
+        noise = cl.noise;
+    }
+}
+int ChanList::Set(const char *str)
+{
+    char *p, *q;
+    int i, is;
+    int ival1, ival2, wRange;
+
+    ch.clear();
+    strcpy(svStr, str);
+    p = q = svStr;
+    wRange = 0;
+    while (*p)
+    {
+        switch (*p)
+        {
+            case ',':
+                *p = 0;
+                if (wRange)
+                {
+                    is = sscanf(q, "%d", &ival2);
+                    for (i = ival1 + 1; i <= ival2; i++)
+                        ch.push_back(i);
+                }
+                else
+                {
+                    is = sscanf(q, "%d", &ival1);
+                    ch.push_back(ival1);
+                }
+                wRange = 0;
+                q = p + 1;
+                p += is;
+                break;
+            case '-':
+                *p = 0;
+                wRange = 1;
+                is = sscanf(q, "%d", &ival1);
+                ch.push_back(ival1);
+                q = p + 1;
+                p += is;
+                break;
+        }
+        p++;
+    }
+    if (wRange)
+    {
+        is = sscanf(q, "%d", &ival2);
+        for (i = ival1 + 1; i <= ival2; i++)
+            ch.push_back(i);
+    }
+    else
+    {
+        is = sscanf(q, "%d", &ival2);
+        ch.push_back(ival2);
+    }
+    // sort
+    std::sort(ch.begin(), ch.end());
+    nch = ch.size();
+    return nch;
+}
+
+std::ostream &operator<<(std::ostream &os, ChanList &cl)
+{
+    for (int i = 0; i < cl.Nch(); i++)
+    {
+        if (i && !(i % 15))
+            os << std::endl;
+        os << std::setw(5) << cl[i];
+    }
+    return os;
+}
+
+int ChanList::ParseChanList(const char *str, ChanList **cl)
+{
+    int ireg, nreg = 0;
+    std::vector<char *> clst;
+    char *q, *p, *ptr;
+
+    if (str == 0)
+        return 0;
+    if (cl == 0)
+        return 0;
+    p = ptr = strdup(str);
+    do
+    {
+        clst.push_back(p);
+        q = strchr(p, ';');
+        if (q == 0)
+            break;
+        *q++ = 0;
+        p = q;
+    } while (*p);
+
+    nreg = clst.size();
+    *cl = new ChanList[nreg];
+    for (ireg = 0; ireg < nreg; ireg++)
+        (*cl)[ireg].Set(clst[ireg]);
+
+    free(ptr);
+    return nreg;
+}
diff --git a/TbUT/src/alibava/ChanList.h b/TbUT/src/alibava/ChanList.h
new file mode 100755
index 0000000..d33e8d4
--- /dev/null
+++ b/TbUT/src/alibava/ChanList.h
@@ -0,0 +1,75 @@
+/* -*- mode: c++ -*- */
+#ifndef __ChanList_h__
+#define __ChanList_h__
+
+#include <iostream>
+#include <vector>
+#include "TbAlibavaHit.h"
+//////////////////////////////////////////////////////////////////////////
+// ChanList
+//
+//   Created: Mon Sep  7 18:46:56 1998        Author: Carlos Lacasta
+//   Purpose: Class to handle channel lists
+//
+//////////////////////////////////////////////////////////////////////////
+
+class ChanList
+{
+    protected:
+        int nch;                 // number of channels in the list
+        std::vector<int> ch;     // list of channels
+        TbAlibavaHitList hits;
+        double cm;               // Common mode
+        double noise;            // noise
+        void copy(const ChanList &);
+    public:
+        ChanList(const char *ch = 0);
+        ChanList(int, int);
+        ChanList(const ChanList &);
+        ChanList &operator=(const ChanList &);
+        virtual ~ChanList()
+        {
+            hits.clear();
+            ch.clear();
+        }
+        int Set(const char *);
+        int Nch() const
+        {
+            return nch;
+        }
+        int Chan(int x) const
+        {
+            return ch[x];
+        }
+
+        int operator[](int x) const { return ch[x]; }
+        void add_hit(const TbAlibavaHit &h) { hits.push_back(h); }
+        bool empty() const { return hits.empty(); }
+        int nhits() const { return hits.size(); }
+        void clear_hits() { hits.clear(); }
+        const TbAlibavaHit &get_hit(int i) const { return hits[i]; }
+        const TbAlibavaHitList hit_list() const { return hits; }
+
+        double CommonMode() const
+        {
+            return cm;
+        }
+        double Noise() const
+        {
+            return noise;
+        }
+        ChanList *CommonMode(double x)
+        {
+            cm = x;
+            return this;
+        }
+        ChanList *Noise(double x)
+        {
+            noise = x;
+            return this;
+        }
+        static int ParseChanList(const char *, ChanList **);
+};
+std::ostream &operator<<(std::ostream &, ChanList&);
+#endif
+
diff --git a/TbUT/src/alibava/TbAlibavaData.h b/TbUT/src/alibava/TbAlibavaData.h
new file mode 100644
index 0000000..78744dc
--- /dev/null
+++ b/TbUT/src/alibava/TbAlibavaData.h
@@ -0,0 +1,32 @@
+#ifndef TBALIBAVADATA_H_
+#define TBALIBAVADATA_H_
+
+/**
+ *  Data is received from the USB port with this format
+ * 
+ */
+struct EventBlock
+{
+        unsigned int time;
+        unsigned short temp;
+        unsigned short data[256];
+};
+
+
+
+/**
+ * We add value as an estra parameter when moving the
+ * data within the application. It tells the value of
+ * the variables which are scanned
+ */
+struct EventData : public EventBlock
+{
+        double value;
+};
+
+struct EventDataBlock : public EventData
+{
+        unsigned short header[32];
+};
+
+#endif /*TBALIBAVADATA_H_*/
diff --git a/TbUT/src/alibava/TbAlibavaHit.cpp b/TbUT/src/alibava/TbAlibavaHit.cpp
new file mode 100644
index 0000000..cae9ee3
--- /dev/null
+++ b/TbUT/src/alibava/TbAlibavaHit.cpp
@@ -0,0 +1,29 @@
+#include "TbAlibavaHit.h"
+
+TbAlibavaHit::TbAlibavaHit(int c, int l, int r, double s) :
+    _center(c), _left(l), _right(r), _sig(s)
+{
+}
+
+TbAlibavaHit::TbAlibavaHit(const TbAlibavaHit &h)
+{
+    cpy(h);
+}
+TbAlibavaHit::~TbAlibavaHit()
+{
+}
+
+void TbAlibavaHit::cpy(const TbAlibavaHit &h)
+{
+    _center = h._center;
+    _left = h._left;
+    _right = h._right;
+    _sig = h._sig;
+}
+TbAlibavaHit &TbAlibavaHit::operator=(const TbAlibavaHit &h)
+{
+    if (&h!=this)
+        cpy(h);
+
+    return *this;
+}
diff --git a/TbUT/src/alibava/TbAlibavaHit.h b/TbUT/src/alibava/TbAlibavaHit.h
new file mode 100644
index 0000000..39379fd
--- /dev/null
+++ b/TbUT/src/alibava/TbAlibavaHit.h
@@ -0,0 +1,35 @@
+#ifndef __TBALIBAVAHIT_H__
+#define __TBALIBAVAHIT_H__
+
+/**
+ * A class representing a hit
+ */
+
+#include <vector>
+
+class TbAlibavaHit
+{
+    private:
+        int _center;
+        int _left;
+        int _right;
+        double _sig;
+        
+        void cpy(const TbAlibavaHit &h);
+    public:
+        TbAlibavaHit(int c=0, int l=0, int r=0, double s=0);
+        TbAlibavaHit(const TbAlibavaHit &h);
+        ~TbAlibavaHit();
+        
+        TbAlibavaHit &operator=(const TbAlibavaHit &h);
+        
+        int center() const { return _center; }
+        int left() const { return _left; }
+        int right() const { return _right; }
+        double signal() const { return _sig; }
+        int width() const { return _right - _left + 1; }
+};
+typedef std::vector< TbAlibavaHit> TbAlibavaHitList;
+
+
+#endif /*__TBALIBAVAHIT_H__*/
diff --git a/TbUT/src/alibava/TbAsciiRoot.cpp b/TbUT/src/alibava/TbAsciiRoot.cpp
new file mode 100644
index 0000000..892582a
--- /dev/null
+++ b/TbUT/src/alibava/TbAsciiRoot.cpp
@@ -0,0 +1,1016 @@
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+#include <ctime>
+#include <cmath>
+#include <sstream>
+#include <csignal>
+#include <vector>
+#include <cstdlib>
+#include <cerrno>
+#include <climits>
+#include <TROOT.h>
+#include <TCanvas.h>
+#include <TProfile2D.h>
+#include <TF1.h>
+#include <TH1.h>
+#include <TH2.h>
+#include "TbAsciiRoot.h"
+#include "utils.h"
+#include "Tracer.h"
+#include "TbAlibavaHit.h"
+#include "ChanList.h"
+/*
+
+#ifdef __APPLE__
+#define sighandler_t sig_t
+#endif
+
+bool _A_do_run = true;
+void _A_got_intr(int)
+{
+    _A_do_run = false;
+}
+*/
+// decodes the header and returns a vector with the integers found
+std::vector<int> decode_header(const std::string &h, TbAsciiRoot::XtraValues &xtra)
+{
+    std::vector<int> vout;
+    std::istringstream istr(h);
+    char *endptr;
+    char buf[256];
+    long val;
+
+    xtra.clear();
+
+    while (istr)
+    {
+        istr.getline(buf, sizeof(buf), ';');
+        if (!istr)
+            break;
+
+        errno = 0;
+        val = strtol(buf, &endptr, 0);
+
+        if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0))
+        {
+            std::string sval(buf), sout;
+            sout = trim_str(sval);
+            if (!sout.empty())
+                xtra.push_back( sout );
+        }
+        else if ( endptr == buf || *endptr != '\0' )
+        {
+            std::string sval(buf), sout;
+            sout = trim_str(sval);
+            if (!sout.empty())
+                xtra.push_back( sout );
+        }
+        else
+        {
+            vout.push_back(atoi(buf) );
+        }
+    }
+    return vout;
+}
+
+TbAsciiRoot::TbAsciiRoot(const char * /*nam*/, const char * /*pedfile*/, const char * /*gainfile*/) :
+    _nchan(max_nchan),_seedcut(10.), _neighcut(5.), _average_gain(1.), _version(2), _polarity(1)
+{
+    int i;
+    for (i=0;i<max_nchan;i++)
+    {
+        _ped[i] = 0.;
+        _gain[i] = 1.;
+        _noise[i] = 1.;
+        _data.data[i] = 0;
+        _mask[i] = false;
+    }
+    ifile=NULL;
+}
+
+TbAsciiRoot::~TbAsciiRoot()
+{
+    if (ifile)
+    {
+        ifile->close();
+    }
+}
+
+void TbAsciiRoot::open(const char *name)
+{
+    ifile = new std::ifstream(name);
+    if (!(*ifile))
+    {
+        std::cout << "Could not open data file: " << name << std::endl;
+        delete ifile;
+        ifile = 0;
+		return;
+    }
+    std::string header;
+    unsigned int ic, lheader;
+    char c;
+    ifile->read((char *)&_t0, sizeof(time_t));
+    //std::cout << "64b: " << ctime(&_t0) << std::endl;
+    ifile->read((char *)&_type, sizeof(int));
+    //std::cout << "type_ " << _type << std::endl;
+    if ( _type > 15 )
+    {
+        ifile->seekg(0, std::ios::beg);
+        ifile->read((char *)&_t0, sizeof(int));
+        ifile->read((char *)&_type, sizeof(int));
+        //std::cout << "32b: " << ctime(&_t0) << std::endl;
+    }
+
+
+    ifile->read((char *)&lheader, sizeof(unsigned int));
+    for (ic=0; ic<80; ic++)
+    {
+        ifile->read(&c, sizeof(char));
+        header.append(1, c);
+    }
+    header = trim_str(header);
+
+    if (header[0]!='V' && header[0]!='v')
+    {
+        _version = 0;
+    }
+    else
+    {
+        _version = int(header[1]-'0');
+        header = header.substr(5);
+    }
+
+    std::cout << "type: " << _type << " header: " << header << std::endl;
+    std::vector<int> param = decode_header(header, _xtra);
+    ifile->read((char *)_ped, max_nchan*sizeof(double));
+    ifile->read((char *)_noise, max_nchan*sizeof(double));
+    switch (_type)
+    {
+        case 1: // calibration
+        case 2: // laser sync
+            _npoints = param[0];
+            _from = param[1];
+            _to = param[2];
+            _step = param[3];
+            break;
+        case 3: // laser run
+        case 4: // source run
+        case 5: // pedestal run
+            if (param.empty())
+                _nevts = 100000;
+            else
+                _nevts = param[0];
+            _npoints = _from = _to = _step = 0;
+            break;
+    }
+    data_start = ifile->tellg();
+}
+
+void TbAsciiRoot::rewind()
+{
+    if (ifile)
+    {
+        ifile->clear();
+        ifile->seekg(data_start, std::ios::beg);
+    }
+}
+
+void TbAsciiRoot::close()
+{
+    if (ifile)
+    {
+        ifile->close();
+        delete ifile;
+        ifile = 0;
+    }
+}
+
+void TbAsciiRoot::reset_data()
+{
+    memset(&_data, 0, sizeof(_data));
+}
+
+int TbAsciiRoot::read_event(std::string & error_code)
+{
+    if (ifile)
+    {
+        unsigned int header, size, user=0, code=0;
+        char *block_data=0;
+        if (_version)
+        {
+            do
+            {
+                do
+                {
+                    ifile->read((char *)&header, sizeof(unsigned int));
+                    if (ifile->bad() || ifile->eof()){
+		      error_code="read Header";
+		      return -1;
+		    }
+
+                    code = (header>>16) & 0xFFFF;
+                } while ( code != 0xcafe );
+
+                code = header & 0x0fff;
+                user = header & 0x1000;
+                switch (code)
+                {
+                    case NewFile:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        new_file(size, block_data);
+                        break;
+                    case StartOfRun:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        start_of_run(size, block_data);
+                        break;
+                    case DataBlock:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        if (user)
+                        {
+                            reset_data();
+                            block_data = new char[size];
+                            ifile->read(block_data, size);
+                            new_data_block(size, block_data);
+                        }
+                        else
+                        {
+                            if ( _version == 1 )
+                            {
+                                ifile->read((char *)&_data, sizeof(EventData));
+                                for (int ii=0; ii<2; ii++)
+                                    memset(_header[ii], 0, 16*sizeof(unsigned short));
+
+                            }
+                            else
+                            {
+                                ifile->read((char *)&_data.value, sizeof(double));
+                                ifile->read((char *)&_data.time, sizeof(unsigned int));
+                                ifile->read((char *)&_data.temp, sizeof(unsigned short));
+                                for (int ii=0; ii<2; ii++)
+                                {
+                                    ifile->read((char *)_header[ii], 16*sizeof(unsigned short));
+                                    ifile->read((char *)&_data.data[ii*128], 128*sizeof(unsigned short));
+                                }
+                            }
+                        }
+
+                        break;
+                    case CheckPoint:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        check_point(size, block_data);
+                        break;
+                    case EndOfRun:
+                        ifile->read((char *)&size, sizeof(unsigned int));
+                        block_data = new char[size];
+                        ifile->read(block_data, size);
+                        end_of_run(size, block_data);
+                        break;
+                    default:
+                        std::cout << "Unknown block data type: " << std::hex << header << " - " << code << std::dec << std::endl;
+                }
+                if (block_data)
+                {
+                    delete [] block_data;
+                    block_data = 0;
+                }
+
+            } while ( code != DataBlock && !(ifile->bad() || ifile->eof()) );
+        }
+        else
+        {
+            ifile->read((char *)&_data, sizeof(EventData));
+            for (int ii=0; ii<2; ii++)
+                memset(_header[ii], 0, 16*sizeof(unsigned short));
+        }
+
+        if (ifile->eof())
+        {
+            std::cout << "End of file" << std::endl;
+	    error_code="End of file";
+            return -1;
+        }
+        else if (ifile->bad())
+        {
+            std::cout << "Problems with data file" << std::endl;
+	    error_code="Problems with data file";
+            return -1;
+        }
+        else
+	  {
+	    error_code="No problem";
+            //process_event();
+            return 0;
+        }
+    }
+    else{
+      error_code="big file problem";
+      return -1;
+    }
+}
+
+void TbAsciiRoot::set_data(int nchan, const unsigned short int *data)
+{
+    int i;
+    _nchan = nchan;
+    for (i=0;i<_nchan;i++)
+        _data.data[i] = data[i];
+}
+
+
+double TbAsciiRoot::time() const
+{
+    unsigned short fpart = _data.time & 0xffff;
+    short ipart = (_data.time & 0xffff0000)>>16;
+    if (ipart<0)
+        fpart *= -1;
+    //double tt = 100.*(1. -(ipart + (fpart/65535.)));
+    double tt = 100.0*(ipart + (fpart/65535.));
+    return tt;
+}
+
+double TbAsciiRoot::temp() const
+{
+    return 0.12*_data.temp - 39.8;
+}
+
+
+/*
+TH1 *TbAsciiRoot::show_pedestals()
+{
+    int ic;
+    TH1 *hst = create_h1("hPed","Pedestals",nchan(),-0.5, nchan()-0.5);
+    hst->SetYTitle("ADCs");
+    hst->SetXTitle("Channel no.");
+    for (ic=0; ic<nchan(); ic++)
+        hst->SetBinContent(ic+1, _ped[ic]);
+
+    return hst;
+}*/
+
+/*
+TH1 *TbAsciiRoot::show_noise()
+{
+    int ic;
+    TH1 *hst = create_h1("hNoise","Noise",nchan(),-0.5, nchan()-0.5);
+    if (gain()==1)
+    {
+        hst->SetYTitle("ADCs");
+    }
+    else
+    {
+        hst->SetYTitle("e^{-} ENC");
+    }
+    hst->SetXTitle("Channel no.");
+    for (ic=0; ic<nchan(); ic++)
+        hst->SetBinContent(ic+1, noise(ic));
+
+    return hst;
+}
+*/
+
+void TbAsciiRoot::compute_pedestals_fast(int mxevts, double wped, double wnoise)
+{
+    if (!ifile)
+        return;
+
+    if (mxevts<0)
+        mxevts = 100000000;
+
+    for (int i=0;i<max_nchan;i++)
+        _ped[i] = _noise[i] = 0.;
+
+    // std::ifstream::pos_type here = ifile->tellg();
+    std::cout << "Computing fast pedestals..." << std::endl;
+    std::string error="";
+    for (int ievt=0; read_event(error)==0 && ievt<mxevts; ievt++)
+    {
+        if (!(ievt%100))
+        {
+            std::cout << "\revent " << std::setw(10) << ievt << std::flush;
+        }
+        common_mode();
+        for (int i=0; i<nchan(); i++)
+        {
+            // TODO: figure out how to determine the chip number when
+            //       Plugin::filter_event has been called
+            int ichip = i/128;
+            // IF noise is 0, set it arbitrarily to 1.
+            if (_noise[i]==0.)
+                _noise[i] = 1.;
+
+            if (_ped[i]==0.)
+            {
+                // If pedestal is not yet computed we assume the current
+                // channel value should not be too far
+                _ped[i] = _data.data[i];
+            }
+            else
+            {
+                // Do the pedestal and noise correction
+                double corr;
+                double xs;
+
+                _signal[i] = _data.data[i] - _ped[i];
+                corr = _signal[i] * wped;
+
+                xs = (_signal[i]-_cmmd[ichip])/_noise[i];
+                if (corr > 1.)
+                    corr = 1.;
+
+                if (corr < -1)
+                    corr = -1.;
+
+                _ped[i] += corr;
+
+                if (fabs(xs) < 3.)
+                {
+                    _noise[i] = _noise[i]*(1.0-wnoise) + xs*xs*wnoise;
+                }
+            }
+        }
+    }
+    std::cout << "\nDone" << std::endl;
+    rewind();
+}
+
+/*
+TH2 *TbAsciiRoot::compute_pedestals(int mxevts, bool do_cmmd)
+{
+    if (!ifile)
+        return 0;
+
+    if (mxevts<0)
+        mxevts = 100000000;
+
+    int ievt, ichan;
+    TH2 *hst = create_h2("hRaw","Raw data",nchan(), -0.5,nchan()-0.5, 256, -0.5,1023.5);
+    TH2 *hsts = create_h2("hSig","Signal",nchan(), -0.5,nchan()-0.5,256, -127.5,127.5);
+
+
+    std::ifstream::pos_type here = ifile->tellg();
+    std::cout << "Computing pedestas..." << std::endl;
+    for (ievt=0; read_event()==0 && ievt<mxevts; ievt++)
+    {
+        process_event(do_cmmd);
+        for (ichan=0; ichan<nchan(); ichan++)
+            // TODO: get right chip number in all situations (after calling set_data)
+            hst->Fill(ichan, data(ichan)-get_cmmd(ichan/128));
+
+        if (!(ievt%100))
+        {
+            std::cout << "\revent " << std::setw(10) << ievt << std::flush;
+        }
+    }
+    std::cout << "\nDone" << std::endl;
+    rewind();
+
+    // TODO: _nchan can be updated in an event by event basis
+    //       while here we are assuming that it is the same
+    //       for all the events
+    for (ichan=0; ichan<nchan(); ichan++)
+    {
+        TF1 *g = new TF1("g1", "gaus");
+        TH1 *h1 = hst->ProjectionY("__hx__", ichan+1, ichan+1);
+        g->SetParameters(h1->GetSumOfWeights(), h1->GetMean(), h1->GetRMS());
+        g->SetRange(h1->GetMean()-2.5*h1->GetRMS(), h1->GetMean()+2.5*h1->GetRMS());
+        h1->Fit("g1", "q0wr");
+        _ped[ichan] = h1->GetFunction("g1")->GetParameter(1);
+        _noise[ichan] = h1->GetFunction("g1")->GetParameter(2);
+        delete h1;
+        delete g;
+    }
+
+    rewind();
+    for (ievt=0; read_event()==0 && ievt<mxevts; ievt++)
+    {
+        process_event(do_cmmd);
+        for (ichan=0; ichan<nchan(); ichan++)
+            hsts->Fill(ichan, signal(ichan));
+
+        if (!(ievt%100))
+        {
+            std::cout << "\revent " << std::setw(10) << ievt << std::flush;
+        }
+    }
+    std::cout << "\nDone" << std::endl;
+    rewind();
+
+    return hst;
+}
+*/
+
+
+
+void TbAsciiRoot::find_clusters(int ichip)
+{
+    int chan0=0;
+    int chan1=255;
+    if (ichip>=0 && ichip<2)
+        {
+            chan0 = ichip*128;
+            chan1 = (ichip+1)*128 -1;
+        }
+
+    std::ostringstream ostr;
+    ostr << chan0 << '-' << chan1;
+    ChanList C(ostr.str().c_str());
+
+    clear();
+    find_clusters(C);
+    _hits = C.hit_list();
+}
+
+void TbAsciiRoot::find_clusters(ChanList &C)
+{
+    // TODO: figure out how to determine the chip number in
+    //       all the situations
+    int i, j, imax=-1, left, right;
+    double mxsig=-1.e20, sg, val;
+    std::vector<bool> used(C.Nch());
+
+    for (i=0;i<C.Nch();i++)
+    {
+        used[i]= _mask[C[i]] ? true : false;
+    }
+
+
+
+    while (true)
+    {
+        /*
+         * Find the highest
+         */
+        imax = -1;
+        for (j=0; j<C.Nch(); j++)
+        {
+            i = C[j];
+            if (used[j] || _signal[i]*polarity()<0.)
+                continue;
+
+            if ( polarity()*sn(i) > _seedcut)
+            {
+                val = fabs(signal(i));
+                if (mxsig<val)
+                {
+                    mxsig = val;
+                    imax = j;
+                }
+            }
+        }
+
+        if (imax<0 || imax >= C.Nch() )
+            break;
+
+        sg = signal(C[imax]);
+        used[imax]=true;
+        // Now look at neighbors
+        // first to the left
+        left = imax;
+        for (j=imax-1;j>=0;j--)
+        {
+            i = C[j];
+            if ( used[j] || _signal[i]*polarity()<0.)
+                break;
+
+            if ( fabs(sn(i)) > _neighcut )
+            {
+                used[j] = true;
+                sg += signal(i);
+                left = j;
+            }
+            else
+                // TODO: this needs to be removed
+                // The idea is to merge to clusters that have only one strip in between
+                // In the laser runs this is a consequences of reflections...
+            {
+                int jx = j-1;
+                if (jx>=0  )
+                {
+                    if ( fabs(sn(C[jx])) > _neighcut )
+                        continue;
+                }
+                break;
+            }
+        }
+
+        // now to the right
+        right = imax;
+        for (j=imax+1;j<C.Nch();j++)
+        {
+            i = C[j];
+            if ( used[j] || _signal[i]*polarity()<0.)
+                break;
+            if ( fabs(sn(i))>_neighcut )
+            {
+                used[j] = true;
+                sg += signal(i);
+                right = j;
+            }
+            else
+                // TODO: this needs to be removed
+                // The idea is to merge to clusters that hanve only one strip in between
+                // In the laser runs this is a consequences of reflections...
+            {
+                int jx = i+1;
+                if (jx<C.Nch())
+                {
+                    if ( fabs(sn(C[jx])) > _neighcut )
+                        continue;
+                }
+                break;
+            }
+        }
+        C.add_hit(TbAlibavaHit(imax, left, right, sg));
+    }
+}
+
+void TbAsciiRoot::save_pedestals(const char *fnam)
+{
+    std::ofstream ofile(fnam);
+    if (!ofile)
+    {
+        std::cout << "Could not open " << fnam << " to save pedestals." << std::endl;
+        return;
+    }
+
+    // TODO: _nchan can be updated in an event by event basis
+    //       while here we are assuming that it is the same
+    //       for all the events
+    int i;
+    for (i=0; i<nchan(); i++)
+    {
+        ofile << _ped[i] << "\t" << _noise[i] << "\n";
+    }
+    ofile.close();
+}
+
+void TbAsciiRoot::load_pedestals(const char *fnam)
+{
+    std::ifstream ifile(fnam);
+    if (!ifile)
+    {
+        std::cout << "Could not open " << fnam << " to load pedestals." << std::endl;
+        return;
+    }
+    int i;
+    for (i=0; i<max_nchan; i++)
+    {
+        if (ifile.eof())
+            break;
+
+        ifile >> _ped[i] >> std::ws >> _noise[i] >> std::ws;
+        _mask[i] = (_noise[i]>20. || _noise[i]<=0.);
+    }
+    ifile.close();
+    /*
+    TCanvas *pedcanvas = create_canvas("Pedcanvas", "Pedestal Values", 600, 400);
+    TH1 *pedestalhisto = create_h1("pedestalhisto", "Pedestal Values", 256, -0.5, 255.5);
+    for (i=0; i<256; i++)
+    {
+        pedestalhisto->Fill(i, _ped[i]);
+    }
+    pedcanvas->cd(1);
+    pedestalhisto->Draw();
+*/
+}
+
+void TbAsciiRoot::load_masking(const char *fnam)
+{
+    std::ifstream ifile(fnam);
+    if (!ifile)
+    {
+        std::cout << "Could not open masked.txt. " << std::endl;
+        return;
+    }
+    int val;
+    for (int i=0; i<500; i++)
+    {
+        ifile >> val >> std::ws;
+        if (ifile.eof())
+            break;
+        if (val>255)
+        {
+            std::cout << "A value is greater than 255, causing an overflow crash. Please check the text file again. It has been set to 1 for continuation purposes. " << std::endl;
+            val = 1;
+        }
+        _mask[val] = true;
+    }
+}
+
+void TbAsciiRoot::load_gain(const char *fnam)
+{
+    std::ifstream ifile(fnam);
+    if (!ifile)
+    {
+        std::cout << "Could not open " << fnam << " to load the gain." << std::endl;
+        return;
+    }
+    int i;
+    int ichan;
+    double val, xn, xm;
+    xn=xm=0.;
+    for (i=0; i<max_nchan; i++)
+    {
+        ifile >> ichan >> std::ws;
+        if (ifile.eof())
+            break;
+        ifile >> val;
+        if (ifile.eof())
+            break;
+
+        xn++;
+
+        xm += val;
+        _gain[ichan] = val;
+
+        ifile >> std::ws;
+        if (ifile.eof())
+            break;
+    }
+    if (xn>0)
+    {
+        _average_gain = xm/xn;
+    }
+    ifile.close();
+}
+
+void TbAsciiRoot::process_event(bool do_cmmd)
+{
+    int i;
+    for (i=0; i<nchan(); i++)
+    {
+        _signal[i] = _data.data[i]-_ped[i];
+        _sn[i] = _noise[i]>1. && !_mask[i] ? _signal[i]/_noise[i] : 0.;
+    }
+    if (do_cmmd)
+    {
+        int ichip=-1;
+        common_mode();
+
+        for (i=0; i<nchan(); i++)
+        {
+            // TODO: figure out the right chip number
+            if (!(i%128))
+                ichip ++;
+
+            _signal[i] = _data.data[i]-_ped[i] - _cmmd[ichip];
+            _sn[i] = (_noise[i] >1. && !_mask[i] ? _signal[i]/_noise[i] : 0.);
+        }
+    }
+}
+
+void TbAsciiRoot::add_channel_list(const ChanList &C)
+{
+    chan_list.push_back(C);
+}
+
+
+void TbAsciiRoot::common_mode()
+{
+    ChanList C("0-127");
+    common_mode(C);
+
+    _cmmd[0] = C.CommonMode();
+    _cnoise[0] = C.Noise();
+
+
+    C.Set("128-255");
+    common_mode(C);
+
+    _cmmd[1] = C.CommonMode();
+    _cnoise[1] = C.Noise();
+}
+
+void TbAsciiRoot::common_mode(ChanList &C, bool correct)
+{
+    int ip, i, j;
+
+    double mean, sm, xn, xx, xs, xm, tmp;
+    bool use_it;
+    mean = sm = 0.;
+    for (ip=0;ip<3;ip++)
+    {
+        xn = xs = xm = 0.;
+        for (j=0; j<C.Nch(); j++)
+        {
+            i = C[j];
+            if (_mask[i])
+                continue;
+
+            use_it = true;
+            xx = data(i) - _ped[i];
+            if (ip)
+            {
+                tmp = fabs((xx-mean)/sm);
+                use_it = (tmp<2.5);
+            }
+            if (use_it)
+            {
+                xn++;
+                xm += xx;
+                xs += xx * xx;
+            }
+        }
+        if (xn>0.)
+        {
+            mean = xm / xn;
+            sm = sqrt( xs/xn - mean*mean);
+        }
+        //  std::cout << "...iter " << ip << ": xm " << mean << " xs: " << sm << std::endl;
+    }
+    C.CommonMode(mean);
+    C.Noise(sm);
+
+    if (correct)
+    {
+        for ( j=0; j<C.Nch(); j++ )
+        {
+            i = C[j];
+            _signal[i] = _data.data[i]-_ped[i] - C.CommonMode();
+            _sn[i] = (_noise[i] >1. && !_mask[i] ? _signal[i]/_noise[i] : 0.);
+        }
+    }
+}
+
+
+
+
+/*
+void TbAsciiRoot::spy_data(bool with_signal, int nevt)
+{
+    TVirtualPad *pad;
+    if (!ifile)
+        return;
+
+    sighandler_t old_handler = ::signal(SIGINT, _A_got_intr);
+    _A_do_run = true;
+
+    TCanvas *cnvs = (TCanvas *)gROOT->FindObject("cnvs");
+    if (cnvs)
+    {
+        cnvs->Clear();
+    }
+    else
+       cnvs = new TCanvas("cnvs","cnvs", 700, 800);
+
+    cnvs->Divide(2,3);
+
+
+    TH1 *hsignal = create_h1("hsignal","signal (ADC)",256, -0.5, 255.0);
+    hsignal->SetXTitle("Channel");
+    hsignal->SetYTitle("ADC");
+    hsignal->SetMinimum(-300);
+    hsignal->SetMaximum(300);
+
+    TH1 *helec = create_h1("helec","signal (elec)", 256, -0.5, 255.5);
+    helec->SetXTitle("Channel");
+    helec->SetYTitle("electrons");
+    helec->SetMinimum(-300/gain());
+    helec->SetMaximum(300/gain());
+
+    TH1 *hraw = create_h1("hraw","Raw Data (around 512.)",256, 0., 256.);
+    hraw->SetXTitle("Channel");
+    hraw->SetYTitle("ADC");
+    hraw->SetMinimum(-300);
+    hraw->SetMaximum(+300);
+
+    TH1 *hrawc = create_h1("hrawc","Raw Data (no commd)",256, 0., 256.);
+    hrawc->SetXTitle("Channel");
+    hrawc->SetYTitle("ADC");
+    hrawc->SetMinimum(-300);
+    hrawc->SetMaximum(+300);
+
+
+    TH1 *hcmmd[2];
+    hcmmd[0] = create_h1("hcmmd0","Common mode (Chip 0)",50,-100.,100.);
+    hcmmd[0]->SetXTitle("Common mode");
+    hcmmd[1] = create_h1("hcmmd1","Common mode (Chip 1)",50,-100.,100.);
+    hcmmd[1]->SetXTitle("Common mode");
+
+    int ievt,jevt;
+    for (ievt=jevt=0; read_event()==0 && _A_do_run && ievt<nevt;jevt++)
+    {
+        process_event();
+        find_clusters();
+        if ( with_signal && empty())
+            continue;
+
+        int i,ichip=-1;
+        for (i=0; i<nchan(); i++)
+        {
+            // TODO: figure out chip number
+            if (!(i%128))
+                ichip++;
+
+            hsignal->SetBinContent(i+1, _signal[i]);
+            helec->SetBinContent(i+1, signal(i));
+            hraw->SetBinContent(i+1,data(i)-512.);
+            hrawc->SetBinContent(i+1, data(i)-_ped[i]);
+            // TODO: why we draw the signal + common mode ?
+            //       May be cause signal should be ~0...
+            hcmmd[ichip]->Fill(_signal[i]+get_cmmd(ichip));
+        }
+        pad = cnvs->cd(1);
+        pad->SetGrid(1,1);
+        hsignal->Draw();
+        pad = cnvs->cd(2);
+        pad->SetGrid(1,1);
+        helec->Draw();
+
+        pad = cnvs->cd(3);
+        pad->SetGrid(1,1);
+        hraw->Draw();
+
+        pad = cnvs->cd(4);
+        pad->SetGrid(1,1);
+        hrawc->Draw();
+
+        pad = cnvs->cd(5);
+        pad->SetGrid(1,1);
+        hcmmd[0]->Draw();
+
+        pad = cnvs->cd(6);
+        pad->SetGrid(1,1);
+        hcmmd[1]->Draw();
+
+        std::cout << std::setiosflags(std::ios::fixed);
+        std::cout << "*** Event " << jevt << " *****" << std::endl;
+        std::cout << "Common Mode:" << std::endl
+                  << "   Chip 0 " << std::setw(6) << std::setprecision(1) << get_cmmd(0) << " noise: " << get_cnoise(0)
+                  << std::endl
+                  << "   Chip 1 " << std::setw(6) << std::setprecision(1) << get_cmmd(1) << " noise: " << get_cnoise(1)
+                  << std::endl;
+
+        std::cout << "Time: " << time() << " ns" << std::endl;
+        std::cout << "Signal chan(0) << " << signal(0) << " chan(1) " << signal(1) << std::endl;
+        std::cout << "Clusters: " << std::endl;
+
+        TbAlibavaHitList::iterator ip;
+        for (ip=begin(); ip!=end(); ++ip)
+        {
+            std::cout << "   chan: " << ip->center()
+                      << " sig: "
+                      << std::setw(6) << std::setprecision(1) << ip->signal()
+                      << " left: " << ip->left() << " right: " << ip->right()
+                      << std::endl;
+            std::cout << '\t' << "channels: " << std::endl;
+            int j;
+            for (j=ip->left();j<=ip->right();j++)
+                std::cout << "\t   " << j << " sn: " << _sn[j] << " signal: " << _signal[j] << " noise: " << _noise[j] << '\n';
+            std::cout << std::endl;
+        }
+
+        cnvs->Update();
+        ievt++;
+    }
+    std::cout << std::endl;
+    _A_do_run= true;
+    ::signal(SIGINT, old_handler);
+}
+*/
+
+bool is_text(const char *fnam)
+{
+    int nc;
+    char buffer[1024];
+    std::ifstream ifile(fnam);
+    if (!fnam)
+        return false;
+
+    ifile.read(buffer, sizeof(buffer));
+    nc = ifile.gcount();
+    ifile.close();
+    if (!nc) // empty files are text
+    {
+        return true;
+    }
+
+    std::string ss(buffer, nc);
+    ifile.close();
+
+    if ( ss.find('\0') != ss.npos )
+        return false;
+
+    double nontext = 0.;
+    double ntotal = 0.;
+    std::string::iterator ip;
+    for (ip=ss.begin(); ip!=ss.end(); ++ip)
+    {
+        ntotal++;
+        char c = *ip;
+        if ( (c<' ' || c >'~') && !strchr("\n\t\r\b", c) )
+            nontext++;
+    }
+    if ( nontext/ntotal > 0.3 )
+        return false;
+
+    return true;
+}
+
diff --git a/TbUT/src/alibava/TbAsciiRoot.h b/TbUT/src/alibava/TbAsciiRoot.h
new file mode 100644
index 0000000..6f0a570
--- /dev/null
+++ b/TbUT/src/alibava/TbAsciiRoot.h
@@ -0,0 +1,244 @@
+#ifndef __Alibava_TbAsciiRoot_h__
+#define __Alibava_TbAsciiRoot_h__
+
+#include <vector>
+#include "TbAlibavaData.h"
+#include "TbAlibavaHit.h"
+#include "ChanList.h"
+#include <ctime>
+#include<string>
+#include <TH1.h>
+#include <TH2.h>
+
+
+/**
+ * This is the class that reads the data files
+ */
+
+class TbAsciiRoot
+{
+    public:
+        typedef std::vector<std::string> XtraValues;
+        enum BlockType { NewFile=0, StartOfRun, DataBlock, CheckPoint, EndOfRun };
+    private:
+        static const int max_nchan=256;
+        std::ifstream *ifile;
+        unsigned int data_start;
+        int _type;
+        time_t _t0;
+        int _npoints;
+        int _from;
+        int _to;
+        int _step;
+        int _nevts;
+        int _nchan; // current number of channels
+        XtraValues _xtra; // extra values from header
+        double _seedcut;
+        double _neighcut;
+        unsigned short _header[2][16];
+        double _ped[max_nchan];
+        double _noise[max_nchan];
+        double _signal[max_nchan];
+        double _sn[max_nchan];
+        double _cmmd[2];
+        double _cnoise[2];
+        double _gain[max_nchan];
+        double _average_gain;
+        bool   _mask[max_nchan];
+        int     _version;
+        int     _polarity;
+        TbAlibavaHitList _hits;
+
+        std::vector<ChanList> chan_list;
+        EventDataBlock _data;
+
+    protected:
+        void reset_data();
+
+    public:
+        void set_data(int i, unsigned short x) { _data.data[i] = x; }
+
+    public:
+        TbAsciiRoot(const char *nam=0, const char *pedfile=0, const char *gainfile=0);
+        virtual ~TbAsciiRoot();
+
+        bool valid() const
+        {
+            return (ifile!=0);
+        }
+
+        void open(const char *name);
+        void close();
+        void rewind();
+        int read_event(std::string & error_code);
+        virtual void check_point(int, const char *) {};
+        virtual void new_file(int, const char *) {}
+        virtual void start_of_run(int, const char *) {}
+        virtual void end_of_run(int, const char *) {}
+        virtual void new_data_block(int, const char *) {};
+
+        // The data format version
+        int version() const { return _version; }
+
+
+        int polarity() const { return _polarity; }
+        void polarity(int x) { _polarity = ( x<0 ? -1 : 1); }
+        /*
+         * Sets the number of channels and the data in the case
+         * of non "standard" values. If data==0, then only the number
+         * of channels is changed
+         */
+        void set_data(int nchan, const unsigned short *data=0);
+        int nchan() const { return _nchan; }
+        int type() const
+        {
+            return _type;
+        }
+        char *date() const
+        {
+            return ctime(&_t0);
+        }
+        double ped(int i) const
+        {
+            return _ped[i]/_gain[i];
+        }
+        double noise(int i) const
+        {
+            return _noise[i]/_gain[i];
+        }
+        double signal(int i) const
+        {
+            return _signal[i]/_gain[i];
+        }
+
+        double sn(int i) const
+        {
+            return _sn[i];
+        }
+
+        double get_cmmd(int i) const
+        {
+            return _cmmd[i];
+        }
+
+        double get_cnoise(int i) const
+        {
+            return _cnoise[i];
+        }
+
+        unsigned short data(int i) const
+        {
+            return _data.data[i];
+        }
+        double value() const
+        {
+            return _data.value;
+        }
+        double time() const;
+        double temp() const;
+        int npts() const
+        {
+            return _npoints;
+        }
+        int from() const
+        {
+            return _from;
+        }
+        int to() const
+        {
+            return _to;
+        }
+        int step() const
+        {
+            return _step;
+        }
+        int nevts() const
+        {
+            return _step;
+        }
+
+        void add_hit(const TbAlibavaHit &h)
+        {
+            _hits.push_back(h);
+        }
+        TbAlibavaHitList::iterator begin()
+        {
+            return _hits.begin();
+        }
+        TbAlibavaHitList::iterator end()
+        {
+            return _hits.end();
+        }
+        int nhits() const
+        {
+            return _hits.size();
+        }
+        bool empty() const
+        {
+            return _hits.empty();
+        }
+        const TbAlibavaHit &hit(int i) const
+        {
+            return _hits[i];
+        }
+        void set_hit_list(const TbAlibavaHitList &L) { _hits = L; }
+        void clear()
+        {
+            _hits.clear();
+        }
+
+        double get_gain(int i) const
+        {
+            return _gain[i];
+        }
+        double gain() const
+        {
+            return _average_gain;
+        }
+
+        double seed_cut() const
+        {
+            return _seedcut;
+        }
+        double neigh_cut() const
+        {
+            return _neighcut;
+        }
+        void set_cuts(double s, double n)
+        {
+            _seedcut = s;
+            _neighcut = n;
+        }
+        unsigned short get_header(int ichip, int ibit) { return _header[ichip][ibit]; }
+
+        TH1 *show_pedestals();
+        TH1 *show_noise();
+        TH2 *compute_pedestals(int mxevts=-1, bool do_cmmd=true);
+        void compute_pedestals_fast(int mxevts = -1, double ped_weight=0.01, double noise_weight=0.001);
+
+
+        void process_event(bool do_cmmd=true);
+        void find_clusters(int ichip=-1);
+        void find_clusters(ChanList &C);
+        void save_pedestals(const char *fnam);
+        void load_pedestals(const char *fnam);
+        void load_gain(const char *fnam);
+		void load_masking(const char *fnam);
+        void spy_data(bool with_signal=false, int nevt=1);
+        void common_mode();
+        void common_mode(ChanList &C, bool correct=false);
+
+        int  n_channel_list() const { return chan_list.size(); }
+        void add_channel_list(const ChanList &C);
+        void clear_channel_lists() { chan_list.clear(); }
+        ChanList get_channel_list(int i) const { return chan_list[i]; }
+
+        int nxtra() const { return _xtra.size(); }
+        const std::string xtra(int i) const { return _xtra[i]; }
+        void add_xtra(const std::string &x) { _xtra.push_back(x); }
+        void add_xtra(const char *x) { _xtra.push_back(x); }
+};
+// Return true if file is an ASCII text file
+bool is_text(const char *);
+
+#endif
diff --git a/TbUT/src/alibava/Tracer.cc b/TbUT/src/alibava/Tracer.cc
new file mode 100644
index 0000000..dc981c7
--- /dev/null
+++ b/TbUT/src/alibava/Tracer.cc
@@ -0,0 +1,48 @@
+#include <TH1.h>
+
+#include "Tracer.h"
+
+Tracer::Tracer(const char *name, const char *title, int npts, int avrg)
+    : size(npts), average(avrg), cntr(0.), val(0.)
+{
+    hst = new TH1D(name, title, size, 0, size);
+   
+}
+
+Tracer::~Tracer()
+{
+    delete hst;
+}
+
+void Tracer::Draw(const char *opt)
+{
+    hst->Draw(opt);
+}
+
+void Tracer::fill(double x)
+{
+    if (average>1.)
+    {
+        val = (x + cntr*val)/(++cntr);
+        if ( (int(cntr)%average)==0 )
+        {
+            add_point(val);
+        }
+    }
+    else
+        add_point(x);
+}
+
+void Tracer::add_point(double x)
+{
+    queue.push_back(x);
+    if (queue.size()>size)
+        queue.pop_front();
+    
+    std::deque<double>::iterator ip;
+    int ibin = 1;
+    for (ip=queue.begin();ip!=queue.end();++ip, ibin++)
+    {
+        hst->SetBinContent(ibin, *ip);
+    }
+}
diff --git a/TbUT/src/alibava/Tracer.h b/TbUT/src/alibava/Tracer.h
new file mode 100644
index 0000000..f7826a7
--- /dev/null
+++ b/TbUT/src/alibava/Tracer.h
@@ -0,0 +1,39 @@
+#ifndef TRACER_H_
+#define TRACER_H_
+#include <deque>
+
+class TH1;
+
+class Tracer
+{
+    private:
+        unsigned int size;
+        int average;
+        double cntr;
+        double val;
+        std::deque<double> queue;
+        TH1 *hst;
+
+    public:
+        /**
+         * Defines a tracer. At input npts defines the size of
+         * the buffer (a FIFO actually) with the values that the
+         * Tracer will remember. Also, if average is given, the 
+         * Tracer will add as new points the average over 'average'
+         * inputs
+         */
+        Tracer(const char*nam, const char *tit, int npts, int average=0);
+        virtual ~Tracer();
+
+        void Draw(const char *opt="");
+
+        TH1 *get_hst()
+        {
+            return hst;
+        }
+
+        void fill(double val);
+        void add_point(double x);
+};
+
+#endif /*TRACER_H_*/
diff --git a/TbUT/src/alibava/utils.cc b/TbUT/src/alibava/utils.cc
new file mode 100644
index 0000000..398432c
--- /dev/null
+++ b/TbUT/src/alibava/utils.cc
@@ -0,0 +1,56 @@
+#include <TROOT.h>
+#include "utils.h"
+
+TCanvas *create_canvas(const char *name, const char *title, int wx, int wy)
+{
+    TCanvas *cnvs = (TCanvas *)gROOT->FindObject("name");
+    if (cnvs)
+        delete cnvs;
+
+    if (wx<0 ||wy<0)
+        cnvs = new TCanvas(name, title);
+    else
+        cnvs = new TCanvas(name, title, wx, wy);
+
+    return cnvs;
+}
+
+TH1 *create_h1(const char *name, const char *tit, int n, double x1, double x2)
+{
+    TH1 *hst = (TH1 *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+    
+    hst = new TH1D(name, tit, n, x1, x2);
+    return hst;
+}
+
+TH2 *create_h2(const char *name, const char *tit, int nx, double x1, double x2, int ny, double y1, double y2)
+{
+    TH2 *hst = (TH2 *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+    
+    hst = new TH2D(name, tit, nx, x1, x2, ny, y1, y2);
+    return hst;
+}
+
+TProfile *create_profile(const char *name, const char *tit, int n, double x1, double x2, double y1, double y2)
+{
+    TProfile *hst = (TProfile *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+    
+    hst = new TProfile(name, tit, n, x1, x2, y1, y2);
+    return hst;
+}
+
+TProfile2D *create_profile2d(const char *name, const char *tit, int nx, double x1, double x2, int ny, double y1, double y2)
+{
+    TProfile2D *hst = (TProfile2D *)gROOT->FindObject(name);
+    if (hst)
+        delete hst;
+
+    hst = new TProfile2D(name, tit, nx, x1, x2, ny, y1, y2);
+    return hst;
+}
diff --git a/TbUT/src/alibava/utils.h b/TbUT/src/alibava/utils.h
new file mode 100644
index 0000000..b82693c
--- /dev/null
+++ b/TbUT/src/alibava/utils.h
@@ -0,0 +1,48 @@
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <string>
+#include <vector>
+#include <TH1.h>
+#include <TH2.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
+#include <TCanvas.h>
+
+/**
+ * Utils
+ */
+inline bool isws(char c, char const * const wstr=" \t\n")
+{
+    return (strchr(wstr, c) != NULL);
+}
+
+inline std::string trim_right(const std::string &s)
+{
+    std::string b=" \t\n";
+    std::string str = s;
+    return str.erase(str.find_last_not_of(b) +1);
+}
+
+inline std::string trim_left(const std::string &s)
+{
+    std::string b=" \t\n";
+    std::string str = s;
+    return str.erase( 0, str.find_first_not_of(b) );
+}
+
+inline std::string trim_str(const std::string &s)
+{
+    std::string str = s;
+    return trim_left(trim_right(str) );
+}
+
+TCanvas *create_canvas(const char *name, const char *title, int wx=-1, int wy=-1);
+TH1 *create_h1(const char *, const char *, int, double, double);
+TH2 *create_h2(const char *, const char *, int, double, double, int, double, double);
+TProfile *create_profile(const char *, const char *, int, double, double, double, double);
+TProfile2D *create_profile2d(const char *name, const char *tit, int nx, double x1, double x2, int ny, double y1, double y2);
+
+
+
+#endif /*UTILS_H_*/
diff --git a/TbUT/src/mamba/.svn/all-wcprops b/TbUT/src/mamba/.svn/all-wcprops
new file mode 100644
index 0000000..ff204b3
--- /dev/null
+++ b/TbUT/src/mamba/.svn/all-wcprops
@@ -0,0 +1,17 @@
+K 25
+svn:wc:ra_dav:version-url
+V 58
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/src/mamba
+END
+mamba_decoder.cpp
+K 25
+svn:wc:ra_dav:version-url
+V 76
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/src/mamba/mamba_decoder.cpp
+END
+mamba_decoder.h
+K 25
+svn:wc:ra_dav:version-url
+V 74
+/guest/lhcb/!svn/ver/197479/Kepler/trunk/Tb/TbUT/src/mamba/mamba_decoder.h
+END
diff --git a/TbUT/src/mamba/.svn/entries b/TbUT/src/mamba/.svn/entries
new file mode 100644
index 0000000..f3a2757
--- /dev/null
+++ b/TbUT/src/mamba/.svn/entries
@@ -0,0 +1,96 @@
+10
+
+dir
+205119
+http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbUT/src/mamba
+http://svn.cern.ch/guest/lhcb
+
+
+
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+4525493e-7705-40b1-a816-d608a930855b
+
+mamba_decoder.cpp
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+be6d11f132e5dc308b5050dc3d0a5895
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+7974
+
+mamba_decoder.h
+file
+
+
+
+
+2016-03-16T13:50:23.000000Z
+92b46446d02bf5d35b1b837688efdd05
+2015-11-11T21:04:01.853402Z
+197479
+pmanning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1993
+
diff --git a/TbUT/src/mamba/.svn/text-base/mamba_decoder.cpp.svn-base b/TbUT/src/mamba/.svn/text-base/mamba_decoder.cpp.svn-base
new file mode 100644
index 0000000..84033a5
--- /dev/null
+++ b/TbUT/src/mamba/.svn/text-base/mamba_decoder.cpp.svn-base
@@ -0,0 +1,232 @@
+#pragma GCC diagnostic ignored "-Wvla"
+#pragma GCC diagnostic ignored "-Wparentheses"
+
+#include <iostream>
+#include <fstream>
+
+#include <assert.h>
+#include <stdint.h>
+#include <cmath>
+#include <vector>
+
+#include "mamba_decoder.h"
+
+using namespace std;
+
+
+mamba_decoder::mamba_decoder( bool& isAType):
+		m_isAType(isAType)
+{
+  nBeetles=4;                               //Don't change
+  nSubsets=4;                               //Don't change
+  nCH=32;                                   //Don't change
+  startADC = 6;                             //This value must be changed according to the settings of the MAMBA GUI  -> startADC <=8 in order not to cut the beetle header
+
+  stopADC  = 30;                            //This value must be changed according to the settings of the MAMBA GUI  -> minium value for stopADC is defined according to the definition of nADCs (below)  
+  nADCs = (stopADC-startADC - 1 )*2;
+  assert( nADCs >= nCH + 6 );
+    
+}
+
+mamba_decoder::~mamba_decoder(){
+
+  if(ifile)
+    ifile->close();
+}
+
+bool mamba_decoder::open( const char* filename ){
+  cout<<"new decoder"<<endl;
+  cout<<"with A and D sensor"<<endl;
+
+  ifile = new std::ifstream( filename, std::ios::in | std::ios::binary );
+ 
+  if (!(*ifile))
+  {
+    std::cout<<"Can not open data file:\t" << filename << std::endl;
+    delete ifile;
+    ifile = 0;
+    return false;
+  }
+  return true;
+}
+
+
+void mamba_decoder::close()
+{
+  if (ifile)
+  {
+    ifile->close();
+    delete ifile;
+    ifile = 0;
+  }
+}
+
+bool mamba_decoder::find_mamba_header(){
+  bool found = 0;
+  uint32_t temp_header[4];
+  
+  while(!found){
+    ifile->read((char*)temp_header, 4*sizeof(uint32_t));
+    if(ifile->eof()) return 0;
+    
+    if( temp_header[0] == 0xF1CA600D && temp_header[1] == 0x00000000 && temp_header[2] == 0xFFFFFFFF && temp_header[3] == 0xABBAFFFF ){
+      found = 1 ;
+    }
+    else{
+      ifile->seekg(-( 4 * sizeof(uint32_t) ) + 1, std::ios::cur);  //torno indietro e avanzo di un byte
+    }
+  }  
+  return found;
+}
+
+bool mamba_decoder::check_mamba_footer(){
+  bool checked = 0;
+  uint32_t temp_footer[4];
+
+  ifile->seekg( (12 + nBeetles*nSubsets*nADCs/2) * sizeof(uint32_t) , std::ios::cur );  //skip the coincidence,pack_id, trig_id ...infos and ADC values
+  ifile->read( (char*)temp_footer, 4 * sizeof(uint32_t) );
+  if(ifile->eof()) return 0;
+  ifile->seekg( - (12 + (nBeetles*nSubsets*nADCs)/2 + 4) * sizeof(uint32_t) , std::ios::cur);
+
+  if( temp_footer[0] == 0xFFFFFFFF && temp_footer[1] == 0xFFFFFFFF && temp_footer[2] == 0xFFFFFFFF && temp_footer[3] == 0xFFFFFFFF){
+    checked = 1;
+  }
+
+  return checked;  
+}
+
+int mamba_decoder::find_beetle_header( int * subsADCs, int thr ){
+
+  int pos=-1; 
+  for( int iADC = 0; iADC < nADCs-4 ; iADC++ ){  
+    if(        
+        abs(subsADCs[iADC+1]-subsADCs[0]) > thr  &&
+        abs(subsADCs[iADC+2]-subsADCs[0]) > thr  && 
+        abs(subsADCs[iADC+3]-subsADCs[0]) > thr  && 
+        abs(subsADCs[iADC+4]-subsADCs[0]) > thr  ){          
+      pos = iADC+1;                             //returns the position of the last baseline ADC;
+      break;     
+    }
+  }
+  return pos;
+}
+
+bool mamba_decoder::read_event(){
+
+  if(! find_mamba_header()  ) return 0;  //eof()
+  if(! check_mamba_footer() ) return 0;
+  
+  uint64_t temp1, temp2;
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _pack_id = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _trig_id = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _timestamp = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _ts_timestamp = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+    
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _coincidence_id = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+  
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _padding = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+  
+  const int nChannels=nBeetles*nSubsets*nADCs;
+  
+  uint16_t temp_adc[nChannels];
+  ifile->read((char*) temp_adc,        sizeof(uint16_t)* nBeetles*nSubsets*nADCs );
+
+  int temp_adc2[nBeetles][nSubsets][nADCs];
+  _ADC.clear();
+  _bHeader0.clear(); 
+  _bHeader1.clear(); 
+  _bHeader2.clear(); 
+  _bHeader3.clear(); 
+  _bHeader3P1.clear(); 
+  _bHeader3P2.clear(); 
+
+
+  for(int iBeetle = 0; iBeetle < nBeetles; iBeetle++){
+    for(int iSubset = 0; iSubset < nSubsets; iSubset++){  
+      int tempsubset = (iSubset/2)*2 + ((iSubset%2)+1)%2 ;
+      for (int iADC=0; iADC < nADCs; iADC++){  // "A   only" mode  
+        temp_adc2[iBeetle][iSubset][iADC] = ( ( (temp_adc[iADC*nBeetles*nSubsets+nSubsets*iBeetle+tempsubset] ) & 0xFFFF )-2048 ) ;
+      }
+      
+      if(m_isAType && (iBeetle==0 || iBeetle==2) ){
+        _bHeader0.push_back(0); 
+        _bHeader1.push_back(0); 
+        _bHeader2.push_back(0); 
+        _bHeader3.push_back(0); 
+        _bHeader3P1.push_back(0); 
+        _bHeader3P2.push_back(0); 
+        for(int iADC=0; iADC<nCH; iADC++){
+          _ADC.push_back( 0 );
+        }
+      }     
+      else {
+        int thr = 100;
+        int pos_beetle_header = find_beetle_header( temp_adc2[iBeetle][iSubset], thr );
+        //cout<<pos_beetle_header<<endl;
+        //if( pos_beetle_header == -1 || pos_beetle_header >= (nADCs - nCH) ) return 0;  //can't find the header in the expected place
+        _baseline = 0;
+        for( int iADC=0; iADC < pos_beetle_header; iADC++){
+          _baseline += temp_adc2[iBeetle][iSubset][iADC];
+        }      
+        _baseline = _baseline/pos_beetle_header;
+        
+        for(int iCH  = pos_beetle_header+4  ; iCH  < nCH + pos_beetle_header+4  ; iCH++ ){
+          _ADC.push_back( temp_adc2[iBeetle][iSubset][iCH] );
+          //if(iCH==31) cout << "channel: " << iCH << ", ADC: " << temp_adc2[iBeetle][iSubset][iCH] << endl;  
+          //if(iCH==pos_beetle_header+10) cout << "beetle: " << iBeetle << ", subset: " << iSubset << ", channel: " << iCH << ", ADC: " << temp_adc2[iBeetle][iSubset][iCH] << endl;  
+        }
+        _bHeader0.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header] ); 
+        _bHeader1.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+1] ); 
+        _bHeader2.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+2] ); 
+        _bHeader3.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+3] ); 
+        _bHeader3P1.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+4] ); 
+        _bHeader3P2.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+5] ); 
+        //cout << "beetle: "<< iBeetle<<", subset: " <<iSubset<<"beetlepos: "<<pos_beetle_header+3<<", ADC: " << temp_adc2[iBeetle][iSubset][pos_beetle_header+3] << endl;    
+        
+      }
+    }
+  }
+  
+  //cout << endl; 
+    
+  /*_ADC.clear();
+  for(int iBeetle = 0; iBeetle < nBeetles; iBeetle++){
+    for(int iSubset = 0; iSubset < nSubsets; iSubset++){
+      for(int iADC    = 0  ; iADC  < nADCs    ; iADC++   ){
+        _ADC.push_back( temp_adc2[iBeetle][iSubset][iADC] );
+      }
+    }
+  }*/
+
+  
+  uint32_t temp_footer[4];
+  ifile->read((char*) temp_footer,     sizeof(uint32_t)* 4   );
+  
+  uint32_t temp_TDC[4];
+  ifile->read((char*) temp_TDC,        sizeof(uint32_t)* 4   );
+  
+  _TDC = (  ((temp_TDC[3]) & 0xFF) - (temp_TDC[3]>>8) & 0xFF ) % 0xFF;
+  
+  if(ifile->eof()){
+    return 0;
+  }
+  
+  
+  return 1;  
+}
diff --git a/TbUT/src/mamba/.svn/text-base/mamba_decoder.h.svn-base b/TbUT/src/mamba/.svn/text-base/mamba_decoder.h.svn-base
new file mode 100644
index 0000000..63a7edd
--- /dev/null
+++ b/TbUT/src/mamba/.svn/text-base/mamba_decoder.h.svn-base
@@ -0,0 +1,89 @@
+#ifndef MAMBA_DECODER
+#define MAMBA_DECODER
+
+#include <stdint.h>
+#include <vector>
+#include <fstream>
+
+class mamba_decoder
+{
+
+  private:
+	bool& m_isAType;
+
+    int nBeetles;
+    int nSubsets;
+    int nCH;
+    int startADC;
+    int stopADC;
+    int nADCs;
+      
+    uint64_t _pack_id;
+    uint64_t _trig_id;
+    uint64_t _timestamp;
+    uint64_t _ts_timestamp;
+    uint64_t _coincidence_id;
+    uint64_t _padding;
+    std::vector<int>  _ADC;
+    std::vector<int>  _bHeader0;
+    std::vector<int>  _bHeader1;
+    std::vector<int>  _bHeader2;
+    std::vector<int>  _bHeader3;
+    std::vector<int>  _bHeader3P1;
+    std::vector<int>  _bHeader3P2;
+    unsigned int _TDC;
+    double _baseline;
+    
+  public:
+
+    mamba_decoder(	bool& isAType);
+
+    virtual ~mamba_decoder();
+    
+    bool eof(){ return ifile->eof(); }
+
+    bool open(const char * filename);
+    void close();
+    void rewind(){ ifile->clear(); ifile->seekg(0, std::ios::beg); }
+
+    std::ifstream * ifile;  
+    bool find_mamba_header();
+    bool check_mamba_footer();  
+    
+    int find_beetle_header( int * subsADCs, int thr) ;
+
+    bool read_event();
+ 
+    uint64_t PackID(){ return _pack_id; }
+    uint64_t TrigID(){ return _trig_id; }
+    uint64_t Timestamp(){ return _timestamp; }
+    uint64_t TsTimestamp(){ return _ts_timestamp; }
+    uint64_t CoincidenceID(){ return _coincidence_id; }
+    uint64_t Padding(){ return _padding; }
+    std::vector<int> ADC(){
+    	return _ADC;
+    }
+    std::vector<int> BHeader0() {
+      return _bHeader0; 
+    }
+    std::vector<int> BHeader1() {
+      return _bHeader1; 
+    }
+    std::vector<int> BHeader2() {
+      return _bHeader2; 
+    }
+    std::vector<int> BHeader3() {
+      return _bHeader3; 
+    }
+    std::vector<int> BHeader3P1() {
+      return _bHeader3P1; 
+    }
+    std::vector<int> BHeader3P2() {
+      return _bHeader3P2; 
+    }
+    unsigned int TDC(){ return _TDC; }
+
+};
+
+
+#endif
diff --git a/TbUT/src/mamba/mamba_decoder.cpp b/TbUT/src/mamba/mamba_decoder.cpp
new file mode 100644
index 0000000..84033a5
--- /dev/null
+++ b/TbUT/src/mamba/mamba_decoder.cpp
@@ -0,0 +1,232 @@
+#pragma GCC diagnostic ignored "-Wvla"
+#pragma GCC diagnostic ignored "-Wparentheses"
+
+#include <iostream>
+#include <fstream>
+
+#include <assert.h>
+#include <stdint.h>
+#include <cmath>
+#include <vector>
+
+#include "mamba_decoder.h"
+
+using namespace std;
+
+
+mamba_decoder::mamba_decoder( bool& isAType):
+		m_isAType(isAType)
+{
+  nBeetles=4;                               //Don't change
+  nSubsets=4;                               //Don't change
+  nCH=32;                                   //Don't change
+  startADC = 6;                             //This value must be changed according to the settings of the MAMBA GUI  -> startADC <=8 in order not to cut the beetle header
+
+  stopADC  = 30;                            //This value must be changed according to the settings of the MAMBA GUI  -> minium value for stopADC is defined according to the definition of nADCs (below)  
+  nADCs = (stopADC-startADC - 1 )*2;
+  assert( nADCs >= nCH + 6 );
+    
+}
+
+mamba_decoder::~mamba_decoder(){
+
+  if(ifile)
+    ifile->close();
+}
+
+bool mamba_decoder::open( const char* filename ){
+  cout<<"new decoder"<<endl;
+  cout<<"with A and D sensor"<<endl;
+
+  ifile = new std::ifstream( filename, std::ios::in | std::ios::binary );
+ 
+  if (!(*ifile))
+  {
+    std::cout<<"Can not open data file:\t" << filename << std::endl;
+    delete ifile;
+    ifile = 0;
+    return false;
+  }
+  return true;
+}
+
+
+void mamba_decoder::close()
+{
+  if (ifile)
+  {
+    ifile->close();
+    delete ifile;
+    ifile = 0;
+  }
+}
+
+bool mamba_decoder::find_mamba_header(){
+  bool found = 0;
+  uint32_t temp_header[4];
+  
+  while(!found){
+    ifile->read((char*)temp_header, 4*sizeof(uint32_t));
+    if(ifile->eof()) return 0;
+    
+    if( temp_header[0] == 0xF1CA600D && temp_header[1] == 0x00000000 && temp_header[2] == 0xFFFFFFFF && temp_header[3] == 0xABBAFFFF ){
+      found = 1 ;
+    }
+    else{
+      ifile->seekg(-( 4 * sizeof(uint32_t) ) + 1, std::ios::cur);  //torno indietro e avanzo di un byte
+    }
+  }  
+  return found;
+}
+
+bool mamba_decoder::check_mamba_footer(){
+  bool checked = 0;
+  uint32_t temp_footer[4];
+
+  ifile->seekg( (12 + nBeetles*nSubsets*nADCs/2) * sizeof(uint32_t) , std::ios::cur );  //skip the coincidence,pack_id, trig_id ...infos and ADC values
+  ifile->read( (char*)temp_footer, 4 * sizeof(uint32_t) );
+  if(ifile->eof()) return 0;
+  ifile->seekg( - (12 + (nBeetles*nSubsets*nADCs)/2 + 4) * sizeof(uint32_t) , std::ios::cur);
+
+  if( temp_footer[0] == 0xFFFFFFFF && temp_footer[1] == 0xFFFFFFFF && temp_footer[2] == 0xFFFFFFFF && temp_footer[3] == 0xFFFFFFFF){
+    checked = 1;
+  }
+
+  return checked;  
+}
+
+int mamba_decoder::find_beetle_header( int * subsADCs, int thr ){
+
+  int pos=-1; 
+  for( int iADC = 0; iADC < nADCs-4 ; iADC++ ){  
+    if(        
+        abs(subsADCs[iADC+1]-subsADCs[0]) > thr  &&
+        abs(subsADCs[iADC+2]-subsADCs[0]) > thr  && 
+        abs(subsADCs[iADC+3]-subsADCs[0]) > thr  && 
+        abs(subsADCs[iADC+4]-subsADCs[0]) > thr  ){          
+      pos = iADC+1;                             //returns the position of the last baseline ADC;
+      break;     
+    }
+  }
+  return pos;
+}
+
+bool mamba_decoder::read_event(){
+
+  if(! find_mamba_header()  ) return 0;  //eof()
+  if(! check_mamba_footer() ) return 0;
+  
+  uint64_t temp1, temp2;
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _pack_id = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _trig_id = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _timestamp = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _ts_timestamp = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+    
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _coincidence_id = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+  
+  ifile->read((char*) &temp1 ,       sizeof(uint32_t));
+  ifile->read((char*) &temp2 ,       sizeof(uint32_t));
+  _padding = (temp2 & 0xFFFFFFFF) + ((temp1 & 0xFFFFFFFF) << 32);
+  
+  const int nChannels=nBeetles*nSubsets*nADCs;
+  
+  uint16_t temp_adc[nChannels];
+  ifile->read((char*) temp_adc,        sizeof(uint16_t)* nBeetles*nSubsets*nADCs );
+
+  int temp_adc2[nBeetles][nSubsets][nADCs];
+  _ADC.clear();
+  _bHeader0.clear(); 
+  _bHeader1.clear(); 
+  _bHeader2.clear(); 
+  _bHeader3.clear(); 
+  _bHeader3P1.clear(); 
+  _bHeader3P2.clear(); 
+
+
+  for(int iBeetle = 0; iBeetle < nBeetles; iBeetle++){
+    for(int iSubset = 0; iSubset < nSubsets; iSubset++){  
+      int tempsubset = (iSubset/2)*2 + ((iSubset%2)+1)%2 ;
+      for (int iADC=0; iADC < nADCs; iADC++){  // "A   only" mode  
+        temp_adc2[iBeetle][iSubset][iADC] = ( ( (temp_adc[iADC*nBeetles*nSubsets+nSubsets*iBeetle+tempsubset] ) & 0xFFFF )-2048 ) ;
+      }
+      
+      if(m_isAType && (iBeetle==0 || iBeetle==2) ){
+        _bHeader0.push_back(0); 
+        _bHeader1.push_back(0); 
+        _bHeader2.push_back(0); 
+        _bHeader3.push_back(0); 
+        _bHeader3P1.push_back(0); 
+        _bHeader3P2.push_back(0); 
+        for(int iADC=0; iADC<nCH; iADC++){
+          _ADC.push_back( 0 );
+        }
+      }     
+      else {
+        int thr = 100;
+        int pos_beetle_header = find_beetle_header( temp_adc2[iBeetle][iSubset], thr );
+        //cout<<pos_beetle_header<<endl;
+        //if( pos_beetle_header == -1 || pos_beetle_header >= (nADCs - nCH) ) return 0;  //can't find the header in the expected place
+        _baseline = 0;
+        for( int iADC=0; iADC < pos_beetle_header; iADC++){
+          _baseline += temp_adc2[iBeetle][iSubset][iADC];
+        }      
+        _baseline = _baseline/pos_beetle_header;
+        
+        for(int iCH  = pos_beetle_header+4  ; iCH  < nCH + pos_beetle_header+4  ; iCH++ ){
+          _ADC.push_back( temp_adc2[iBeetle][iSubset][iCH] );
+          //if(iCH==31) cout << "channel: " << iCH << ", ADC: " << temp_adc2[iBeetle][iSubset][iCH] << endl;  
+          //if(iCH==pos_beetle_header+10) cout << "beetle: " << iBeetle << ", subset: " << iSubset << ", channel: " << iCH << ", ADC: " << temp_adc2[iBeetle][iSubset][iCH] << endl;  
+        }
+        _bHeader0.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header] ); 
+        _bHeader1.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+1] ); 
+        _bHeader2.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+2] ); 
+        _bHeader3.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+3] ); 
+        _bHeader3P1.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+4] ); 
+        _bHeader3P2.push_back( temp_adc2[iBeetle][iSubset][pos_beetle_header+5] ); 
+        //cout << "beetle: "<< iBeetle<<", subset: " <<iSubset<<"beetlepos: "<<pos_beetle_header+3<<", ADC: " << temp_adc2[iBeetle][iSubset][pos_beetle_header+3] << endl;    
+        
+      }
+    }
+  }
+  
+  //cout << endl; 
+    
+  /*_ADC.clear();
+  for(int iBeetle = 0; iBeetle < nBeetles; iBeetle++){
+    for(int iSubset = 0; iSubset < nSubsets; iSubset++){
+      for(int iADC    = 0  ; iADC  < nADCs    ; iADC++   ){
+        _ADC.push_back( temp_adc2[iBeetle][iSubset][iADC] );
+      }
+    }
+  }*/
+
+  
+  uint32_t temp_footer[4];
+  ifile->read((char*) temp_footer,     sizeof(uint32_t)* 4   );
+  
+  uint32_t temp_TDC[4];
+  ifile->read((char*) temp_TDC,        sizeof(uint32_t)* 4   );
+  
+  _TDC = (  ((temp_TDC[3]) & 0xFF) - (temp_TDC[3]>>8) & 0xFF ) % 0xFF;
+  
+  if(ifile->eof()){
+    return 0;
+  }
+  
+  
+  return 1;  
+}
diff --git a/TbUT/src/mamba/mamba_decoder.h b/TbUT/src/mamba/mamba_decoder.h
new file mode 100644
index 0000000..63a7edd
--- /dev/null
+++ b/TbUT/src/mamba/mamba_decoder.h
@@ -0,0 +1,89 @@
+#ifndef MAMBA_DECODER
+#define MAMBA_DECODER
+
+#include <stdint.h>
+#include <vector>
+#include <fstream>
+
+class mamba_decoder
+{
+
+  private:
+	bool& m_isAType;
+
+    int nBeetles;
+    int nSubsets;
+    int nCH;
+    int startADC;
+    int stopADC;
+    int nADCs;
+      
+    uint64_t _pack_id;
+    uint64_t _trig_id;
+    uint64_t _timestamp;
+    uint64_t _ts_timestamp;
+    uint64_t _coincidence_id;
+    uint64_t _padding;
+    std::vector<int>  _ADC;
+    std::vector<int>  _bHeader0;
+    std::vector<int>  _bHeader1;
+    std::vector<int>  _bHeader2;
+    std::vector<int>  _bHeader3;
+    std::vector<int>  _bHeader3P1;
+    std::vector<int>  _bHeader3P2;
+    unsigned int _TDC;
+    double _baseline;
+    
+  public:
+
+    mamba_decoder(	bool& isAType);
+
+    virtual ~mamba_decoder();
+    
+    bool eof(){ return ifile->eof(); }
+
+    bool open(const char * filename);
+    void close();
+    void rewind(){ ifile->clear(); ifile->seekg(0, std::ios::beg); }
+
+    std::ifstream * ifile;  
+    bool find_mamba_header();
+    bool check_mamba_footer();  
+    
+    int find_beetle_header( int * subsADCs, int thr) ;
+
+    bool read_event();
+ 
+    uint64_t PackID(){ return _pack_id; }
+    uint64_t TrigID(){ return _trig_id; }
+    uint64_t Timestamp(){ return _timestamp; }
+    uint64_t TsTimestamp(){ return _ts_timestamp; }
+    uint64_t CoincidenceID(){ return _coincidence_id; }
+    uint64_t Padding(){ return _padding; }
+    std::vector<int> ADC(){
+    	return _ADC;
+    }
+    std::vector<int> BHeader0() {
+      return _bHeader0; 
+    }
+    std::vector<int> BHeader1() {
+      return _bHeader1; 
+    }
+    std::vector<int> BHeader2() {
+      return _bHeader2; 
+    }
+    std::vector<int> BHeader3() {
+      return _bHeader3; 
+    }
+    std::vector<int> BHeader3P1() {
+      return _bHeader3P1; 
+    }
+    std::vector<int> BHeader3P2() {
+      return _bHeader3P2; 
+    }
+    unsigned int TDC(){ return _TDC; }
+
+};
+
+
+#endif
diff --git a/run.py b/run.py
new file mode 100755
index 0000000..50a1b24
--- /dev/null
+++ b/run.py
@@ -0,0 +1,68 @@
+import os,sys,getopt, subprocess
+
+#telescopePath = "$KEPLERROOT/eos/lhcb/testbeam/ut/TelescopeData/July2015/RootFiles"
+telescopePath = "$KEPLERROOT/eos/lhcb/testbeam/ut/TemporaryData/May2016/TimePix/RootFiles"
+
+#inputPathPedestal = "$KEPLERROOT/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/"
+#inputPathSignal = "$KEPLERROOT/eos/lhcb/testbeam/ut/OfficialData/July2015/BoardA6/RawData/"
+
+inputPathPedestal = "$KEPLERROOT/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/"
+inputPathSignal = "$KEPLERROOT/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/"
+
+
+
+pedFile = "Pedestal-M1-FanIn-51.dat"
+#sigFile = "Run_Bias_Scan-B6-A-299-8431.dat"
+sigFile = "Run_Bias_Scan-M1-FanIn-50-15027.dat"
+if __name__=="__main__":
+        try:
+                opts,args = getopt.getopt(sys.argv[1:],"fp:fs:",["pedestal","signal"])
+        except getopt.GetoptError as err:
+                print str(err)
+                usage()
+                sys.exit(2)
+        for o, a in opts:
+                if o in ('-fp','--pedestal'):
+                        pedFile = str(a)
+                if o in ('-fs','--signal'):
+                        sigFile = str(a)
+
+
+inputFilePedestal = inputPathPedestal+pedFile
+inputFileSignal = inputPathSignal+sigFile
+print inputFilePedestal
+print inputFileSignal
+subprocess.call('source /afs/cern.ch/project/eos/installation/lhcb/etc/setup.sh',shell=True)
+subprocess.call('/afs/cern.ch/project/eos/installation/0.3.15/bin/eos.select -b fuse mount $KEPLERROOT/eos',shell=True)
+shFile = open(os.environ["KEPLERROOT"]+"/../run_k.sh","w")
+shFile.write('#!/bin/bash\n')
+shFile.write('cd $KEPLERROOT/../TbUT\n')
+shFile.write('python options/TbUTPedestal_conf.py -f '+inputFilePedestal+"\n")
+shFile.write('python options/TbUTRun_conf.py -f '+inputFileSignal+"\n")
+shFile.write('cd ../../\n')
+shFile.write('mkdir -p output\n')
+shFile.write('cd output\n')
+shFile.write('gaudirun.py $KEPLERROOT/../TbUT/options/TbUTPedestal.py\n')
+shFile.write('gaudirun.py $KEPLERROOT/../TbUT/options/TbUTRun.py\n')
+shFile.write('gaudirun.py $KEPLERROOT/../TbUT/options/TbUTRun.py\n')
+shFile.write('. LbLogin.sh -c x86_64-slc6-gcc48-opt\n')
+shFile.write('. SetupProject.sh LHCb v36r2\n')
+shFile.write('cd ../Tb/TbUT/scripts/AddTrigTracks\n')
+shFile.write('make\n')
+shFile.write('cd ../../../../output\n')
+shFile.write('pwd\n')
+shFile.write('./../Tb/TbUT/scripts/AddTrigTracks/combDUTwithTrack -i '+sigFile[:-4]+'_Tuple.root -t '+telescopePath+'/Run'+sigFile.split('-')[4][:-4]+'/Kepler-tuple.root -n '+sigFile[:-4]+'.root -o '+sigFile[:-4]+'_Tracks.root\n')
+os.environ['OUTPUTFILE'] = sigFile.split('-')[4][:-4]
+os.environ['BOARD'] = sigFile.split('-')[1]
+os.environ['RUNPLACE'] = sigFile.split('-')[2]
+os.environ['RUNNUMBER'] = sigFile.split('-')[3]
+
+subprocess.call("sed -i 's/defRUN/"+sigFile.split('-')[4][:-4]+"/g' $KEPLERROOT/../TbUT/scripts/AnalysisBase_Inputs.h",shell=True)
+shFile.write('\nmkdir -p Plots')
+shFile.write('\nroot -b -q ../Tb/TbUT/scripts/runClusterWithTrackAna.C')
+shFile.write('\n. LbLogin.sh -c x86_64-slc6-gcc49-opt\n')
+shFile.write('. SetupProject.sh LHCb\n')
+shFile.close()
+subprocess.call("chmod +x "+os.environ["KEPLERROOT"]+"/../run_k.sh",shell=True)
+os.system('/$KEPLERROOT/../run_k.sh')
+subprocess.call("sed -i 's/"+sigFile.split('-')[4][:-4]+"/defRUN/g' $KEPLERROOT/../TbUT/scripts/AnalysisBase_Inputs.h",shell=True)
diff --git a/run_k.sh b/run_k.sh
new file mode 100755
index 0000000..0f6e54f
--- /dev/null
+++ b/run_k.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+cd $KEPLERROOT/../TbUT
+python options/TbUTPedestal_conf.py -f $KEPLERROOT/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/Pedestal-M1-FanIn-51.dat
+python options/TbUTRun_conf.py -f $KEPLERROOT/eos_sup/user/l/lhcbut/Testbeam/May2016/Board_M1_FanIn/Run_Bias_Scan-M1-FanIn-50-15027.dat
+cd ../../
+mkdir -p output
+cd output
+gaudirun.py $KEPLERROOT/../TbUT/options/TbUTPedestal.py
+gaudirun.py $KEPLERROOT/../TbUT/options/TbUTRun.py
+gaudirun.py $KEPLERROOT/../TbUT/options/TbUTRun.py
+. LbLogin.sh -c x86_64-slc6-gcc48-opt
+. SetupProject.sh LHCb v36r2
+cd ../Tb/TbUT/scripts/AddTrigTracks
+make
+cd ../../../../output
+pwd
+./../Tb/TbUT/scripts/AddTrigTracks/combDUTwithTrack -i Run_Bias_Scan-M1-FanIn-50-15027_Tuple.root -t $KEPLERROOT/eos/lhcb/testbeam/ut/TemporaryData/May2016/TimePix/RootFiles/Run15027/Kepler-tuple.root -n Run_Bias_Scan-M1-FanIn-50-15027.root -o Run_Bias_Scan-M1-FanIn-50-15027_Tracks.root
+
+mkdir -p Plots
+root -b -q ../Tb/TbUT/scripts/runClusterWithTrackAna.C
+. LbLogin.sh -c x86_64-slc6-gcc49-opt
+. SetupProject.sh LHCb