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..12af7b8 --- /dev/null +++ b/Kepler/.svn/entries @@ -0,0 +1,83 @@ +10 + +dir +205620 +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-02T14:11:41.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..10ec51b --- /dev/null +++ b/Kepler/GangaPlugin/.svn/entries @@ -0,0 +1,99 @@ +10 + +dir +205620 +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-02T14:11:40.000000Z +a22dc58bad8f0b1505056a3ee94855a5 +2014-12-02T16:29:08.269559Z +181040 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +945 + +Lib +dir + +__init__.py +file + + + + +2016-05-02T14:11:40.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..508e7c9 --- /dev/null +++ b/Kepler/GangaPlugin/Lib/.svn/entries @@ -0,0 +1,368 @@ +10 + +dir +205620 +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-02T14:11:40.000000Z +9877f074e227de4fd9e67bfb8c9719db +2015-05-18T12:16:24.810119Z +188391 +tevans + + + + + + + + + + + + + + + + + + + + + +3232 + +TbDataset.py +file + + + + +2016-05-02T14:11:40.000000Z +57153a9055dd95cfd2939c4ef7f1610f +2015-05-18T12:16:24.810119Z +188391 +tevans + + + + + + + + + + + + + + + + + + + + + +3464 + +TbQuery.py +file + + + + +2016-05-02T14:11:40.000000Z +3eb40edad33fad63942ce363c1a2800d +2015-03-09T15:49:35.540995Z +185115 +tevans + + + + + + + + + + + + + + + + + + + + + +1229 + +TbStack.py +file + + + + +2016-05-02T14:11:40.000000Z +90aba4190c4e51d2acb2d6529e02d1da +2015-07-11T15:08:56.796151Z +191710 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +3250 + +RecursiveSearch.py +file + + + + +2016-05-02T14:11:40.000000Z +b785c3ae5adb84bac44d20c16f4bf2e5 +2014-12-11T15:21:40.788791Z +181396 +tevans + + + + + + + + + + + + + + + + + + + + + +1070 + +__init__.py +file + + + + +2016-05-02T14:11:40.000000Z +3adb378dac75e00c28bd559ff88c86d6 +2015-05-18T12:16:24.810119Z +188391 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +180 + +TbEosUpload.py +file + + + + +2016-05-02T14:11:40.000000Z +81ae5fdb3bf653d5b970f24c894c52a1 +2015-05-18T12:16:24.810119Z +188391 +tevans + + + + + + + + + + + + + + + + + + + + + +1949 + +TbMetaAnalysisMerger.py +file + + + + +2016-05-02T14:11:40.000000Z +44c355cc03164fe34ee604d73efabee5 +2014-12-14T09:02:44.425677Z +181576 +hschindl + + + + + + + + + + + + + + + + + + + + + +5236 + +TbMetaAnaylsisMerger.py +file + + + + +2016-05-02T14:11:40.000000Z +8641e9f43602a6b190facf59a71fe489 +2014-12-02T16:29:08.269559Z +181040 +tevans + + + + + + + + + + + + + + + + + + + + + +1128 + +KeplerApp.py +file + + + + +2016-05-02T14:11:40.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 " 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.\').' + 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 " 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.\').' + 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..2ea6851 --- /dev/null +++ b/Kepler/Scripts/.svn/entries @@ -0,0 +1,266 @@ +10 + +dir +205620 +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-02T14:11:38.000000Z +277dbebd71065c1c0ff14f6ed92d3f59 +2015-11-11T10:19:10.842818Z +197451 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +1198 + +Kepler +file + + + + +2016-05-02T14:11:38.000000Z +1f2dc6c4e5bc6b769af1595092cded8a +2015-11-09T14:58:52.060865Z +197371 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +2792 + +PixelMapAnalysis.cpp +file + + + + +2016-05-02T14:11:38.000000Z +9d36fbf4459321de46a669f7ec838572 +2014-08-13T19:35:06.427094Z +176307 +snoek + + + + + + + + + + + + + + + + + + + + + +4263 + +spatialEfficiency.py +file + + + + +2016-05-02T14:11:38.000000Z +222415ff2297bd8a124309ad0f38af47 +2014-08-15T12:23:45.657594Z +176372 +hschindl + + + + + + + + + + + + + + + + + + + + + +909 + +UTDaemonScript.sh +file + + + + +2016-05-02T14:11:38.000000Z +6231c26fa65788b087c8b96e5ec59aed +2015-11-11T10:34:01.998798Z +197454 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +1249 + +PixelMapAnalysis_Kepler.h +file + + + + +2016-05-02T14:11:38.000000Z +98d305e6169cc4be949c79f5dcae6406 +2014-07-31T13:54:18.832554Z +175890 +lhcbvelo + + + + + + + + + + + + + + + + + + + + + +1932 + +PixelMapAnalysis_KeplerConfig.cpp +file + + + + +2016-05-02T14:11:38.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 +#include +#include +#include +#include +#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 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;i10*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;i10*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() << "-----------" <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 +#include +#include +#include +#include +#include "TROOT.h" +#include "TKey.h" +#include "TIterator.h" +#include + +/* +...................................................................... +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 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;i10*total) + os << plane << " "<< col << " "<< row << endl; + } + else { + for (uint i=0;i10*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 +#include +#include +#include +#include +#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 +#include + +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 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;i10*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;i10*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() << "-----------" <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 +#include +#include +#include +#include +#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 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;i10*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;i10*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() << "-----------" <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 +#include +#include +#include +#include +#include "TROOT.h" +#include "TKey.h" +#include "TIterator.h" +#include + +/* +...................................................................... +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 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;i10*total) + os << plane << " "<< col << " "<< row << endl; + } + else { + for (uint i=0;i10*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 +#include +#include +#include +#include +#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 +#include + +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 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;i10*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;i10*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() << "-----------" <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..dcad5ec --- /dev/null +++ b/Kepler/cmt/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:37.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..398098d --- /dev/null +++ b/Kepler/doc/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:37.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 @@ +
+Package: Tb/Kepler
+Package Coordinator: Tim Evans and Heinrich Schindler
+Purpose: testbeam analysis program
+
+ +

2015-05-19 Kepler v3r0

+ + - Add Ganga plugin. + - Add TbClusterAssociator and TbDUTMonitor to Telescope/Monitoring sequence. + +

2014-11-30 Kepler v2r1

+ +- New flag to switch on/off tracking. +- New sequence UserAlgorithms. +- Updated QMTest. + +

2014-08-19 Kepler v2r0

+ +- 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. + +

2014-05-30 Kepler v1r0

+ +- 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 @@ +
+Package: Tb/Kepler
+Package Coordinator: Tim Evans and Heinrich Schindler
+Purpose: testbeam analysis program
+
+ +

2015-05-19 Kepler v3r0

+ + - Add Ganga plugin. + - Add TbClusterAssociator and TbDUTMonitor to Telescope/Monitoring sequence. + +

2014-11-30 Kepler v2r1

+ +- New flag to switch on/off tracking. +- New sequence UserAlgorithms. +- Updated QMTest. + +

2014-08-19 Kepler v2r0

+ +- 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. + +

2014-05-30 Kepler v1r0

+ +- 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..329ff63 --- /dev/null +++ b/Kepler/options/.svn/entries @@ -0,0 +1,352 @@ +10 + +dir +205620 +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-02T14:11:40.000000Z +f905f98f12fb64899d3a9851c858f8d6 +2015-11-12T16:32:14.477020Z +197520 +dsaunder + + + + + + + + + + + + + + + + + + + + + +1188 + +EmptyPixelMask.dat +file + + + + +2016-05-02T14:11:40.000000Z +571422dc8d79730cdd4d839ff0dc8c2f +2014-09-26T19:44:39.626662Z +178010 +dsaunder + + + + + + + + + + + + + + + + + + + + + +22 + +online +dir + +MaskPixels.dat +file + + + + +2016-05-02T14:11:40.000000Z +1ce17e27110bedd69c6ee1bd5606b5e1 +2014-08-11T14:54:15.630649Z +176251 +hschindl + + + + + + + + + + + + + + + + + + + + + +132 + +singleChipExample.py +file + + + + +2016-05-02T14:11:40.000000Z +3852d5610e7b0528ae1074fd16219511 +2014-09-26T19:44:39.626662Z +178010 +dsaunder + + + + + + + + + + + + + + + + + + + + + +983 + +TbTrackingWithKalman.cpp +file + + + + +2016-05-02T14:11:40.000000Z +0ff4ba9d4ee94e82ca24c6faf4a40204 +2014-10-12T09:43:57.711037Z +178725 +ptsopela + + + + + + + + + + + + + + + + + + + + + +21913 + +ResStudies +dir + +efficiency.py +file + + + + +2016-05-02T14:11:40.000000Z +a6a5ecb632688a58ed92bdb53b9047d6 +2015-11-17T13:18:40.094527Z +197726 +dsaunder + + + + + + + + + + + + + + + + + + + + + +3649 + +TbTrackingWithKalman.h +file + + + + +2016-05-02T14:11:40.000000Z +48dfd50efccb18ebb3084343e532cb63 +2014-10-12T09:44:10.893545Z +178726 +ptsopela + + + + + + + + + + + + + + + + + + + + + +3854 + +tracking +dir + +combat +dir + +trackfit +dir + +batch.py +file + + + + +2016-05-02T14:11:40.000000Z +d4c6c756e7d720ec1ecf45267433f734 +2015-03-15T14:01:57.475945Z +185430 +hschindl + + + + + + + + + + + + + + + + + + + + + +689 + +debug.py +file + + + + +2016-05-02T14:11:40.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 +#include + +// Local +#include "TbTracking.h" +#include + +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("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(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& clusters = + const_cast&>(trial_track->clusters()); + std::sort(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + 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& clusters = + const_cast&>(best_track->clusters()); + auto earliest_hit = std::min_element(clusters.begin(), clusters.end(), + TbFunctors::LessByTime()); + + 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& ktracks) { + + std::vector::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& 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 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&); + + float lowR, highR, binsR, lowS, highS; + + + // Kalman filter histos + //--------------------------------------------------- + + // Track parameters + TH1D* m_Kfit_chi2; + TH1D* m_Kfit_prob; + + // unbiased residuals + std::vector m_XunresKfit; + std::vector m_YunresKfit; + // biased residuals + std::vector m_XresKfit; + std::vector m_YresKfit; + // biased residuals on X,Y + std::vector m_XresKfitOnX; + std::vector m_XresKfitOnY; + + std::vector m_YresKfitOnY; + std::vector m_YresKfitOnX; + + // biased residuals on X,Y slopes + std::vector m_XresKfitOnTX; + std::vector m_XresKfitOnTY; + + std::vector m_YresKfitOnTY; + std::vector m_YresKfitOnTX; + + // biased residuals errors + std::vector m_XreserrKfit; + std::vector m_YreserrKfit; + + // residual pulls + std::vector m_XrespullKfit; + std::vector m_YrespullKfit; + + // quality biased residuals + std::vector m_qXresKfit; + std::vector m_qYresKfit; + + // quality residual pulls + std::vector m_qXrespullKfit; + std::vector m_qYrespullKfit; + + + // TbKalmanTrack container + std::vector 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..6f1c8a2 --- /dev/null +++ b/Kepler/options/ResStudies/.svn/entries @@ -0,0 +1,337 @@ +10 + +dir +205620 +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-02T14:11:39.000000Z +6067cd7f9b55813339b9de630c2c37d1 +2015-05-22T14:01:52.553303Z +188713 +chombach + + + + + + + + + + + + + + + + + + + + + +1173 + +Alignments +dir + +submitRes.py +file + + + + +2016-05-02T14:11:39.000000Z +79c5c5ce1c2e8a0d6d33ac7585862bf5 +2015-05-22T14:01:52.553303Z +188713 +chombach + + + + + + + + + + + + + + + + + + + + + +1997 + +ZPos.txt +file + + + + +2016-05-02T14:11:39.000000Z +b3d99c8d4639a809ddc6c3a09d7a2e80 +2015-05-22T14:01:52.553303Z +188713 +chombach + + + + + + + + + + + + + + + + + + + + + +316 + +lhcbStyle.C +file + + + + +2016-05-02T14:11:39.000000Z +1ee5d8770506b4b08016c0cbf38f7cd7 +2015-05-21T16:04:13.551304Z +188632 +chombach + + + + + + + + + + + + + + + + + + + + + +6500 + +AlignQualy.py +file + + + + +2016-05-02T14:11:39.000000Z +0ad5bc78b9ed300f6597e730528bbd99 +2015-05-22T14:01:52.553303Z +188713 +chombach + + + + + + + + + + + + + + + + + + + + + +2204 + +res_analysis.C +file + + + + +2016-05-02T14:11:39.000000Z +887a109d0cc76dca8e0e89e7ba82f28a +2015-05-21T16:04:13.551304Z +188632 +chombach + + + + + + + + + + + + + + + + + + + + + +7431 + +Runs.py +file + + + + +2016-05-02T14:11:39.000000Z +f6ff329f3ee4d45662ecff884c0298da +2015-05-12T10:54:52.097095Z +188051 +chombach + + + + + + + + + + + + + + + + + + + + + +2687 + +restudies.py +file + + + + +2016-05-02T14:11:39.000000Z +383e69c43a61e51ce5b01e3873137193 +2015-05-22T14:01:52.553303Z +188713 +chombach + + + + + + + + + + + + + + + + + + + + + +3679 + +runList.txt +file + + + + +2016-05-02T14:11:39.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 +#include "Riostream.h" +#include +#include +#include +#include +#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; subjobSetTitle("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] <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] <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 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..37a6506 --- /dev/null +++ b/Kepler/options/ResStudies/Alignments/.svn/entries @@ -0,0 +1,28 @@ +10 + +dir +205620 +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 +#include "Riostream.h" +#include +#include +#include +#include +#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; subjobSetTitle("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] <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] <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 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 +#include + +// Local +#include "TbTracking.h" +#include + +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("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(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& clusters = + const_cast&>(trial_track->clusters()); + std::sort(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + 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& clusters = + const_cast&>(best_track->clusters()); + auto earliest_hit = std::min_element(clusters.begin(), clusters.end(), + TbFunctors::LessByTime()); + + 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& ktracks) { + + std::vector::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& 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 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&); + + float lowR, highR, binsR, lowS, highS; + + + // Kalman filter histos + //--------------------------------------------------- + + // Track parameters + TH1D* m_Kfit_chi2; + TH1D* m_Kfit_prob; + + // unbiased residuals + std::vector m_XunresKfit; + std::vector m_YunresKfit; + // biased residuals + std::vector m_XresKfit; + std::vector m_YresKfit; + // biased residuals on X,Y + std::vector m_XresKfitOnX; + std::vector m_XresKfitOnY; + + std::vector m_YresKfitOnY; + std::vector m_YresKfitOnX; + + // biased residuals on X,Y slopes + std::vector m_XresKfitOnTX; + std::vector m_XresKfitOnTY; + + std::vector m_YresKfitOnTY; + std::vector m_YresKfitOnTX; + + // biased residuals errors + std::vector m_XreserrKfit; + std::vector m_YreserrKfit; + + // residual pulls + std::vector m_XrespullKfit; + std::vector m_YrespullKfit; + + // quality biased residuals + std::vector m_qXresKfit; + std::vector m_qYresKfit; + + // quality residual pulls + std::vector m_qXrespullKfit; + std::vector m_qYrespullKfit; + + + // TbKalmanTrack container + std::vector 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..3cea76d --- /dev/null +++ b/Kepler/options/alignment/.svn/entries @@ -0,0 +1,232 @@ +10 + +dir +205620 +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-02T14:11:39.000000Z +8768e912c7ac5fa6a7a3a632ee922308 +2015-03-15T14:01:57.475945Z +185430 +hschindl + + + + + + + + + + + + + + + + + + + + + +266 + +survey.py +file + + + + +2016-05-02T14:11:39.000000Z +4f81c8fc6792116d3edd656a07994b6e +2015-03-15T14:01:57.475945Z +185430 +hschindl + + + + + + + + + + + + + + + + + + + + + +614 + +alignment.sh +file + + + + +2016-05-02T14:11:39.000000Z +8f806925e826b02845d00328cc5c9bc4 +2015-03-15T14:01:57.475945Z +185430 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +538 + +millepede.py +file + + + + +2016-05-02T14:11:39.000000Z +7824d30c9f8716b389852e3ff78a49a3 +2015-05-12T10:54:52.097095Z +188051 +chombach + + + + + + + + + + + + + + + + + + + + + +1049 + +minuit_alignment.py +file + + + + +2016-05-02T14:11:39.000000Z +0238d2f186269a4823bea0739132df6e +2015-03-15T14:01:57.475945Z +185430 +hschindl + + + + + + + + + + + + + + + + + + + + + +807 + +minuit_alignment.sh +file + + + + +2016-05-02T14:11:39.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..b337f6d --- /dev/null +++ b/Kepler/options/combat/.svn/entries @@ -0,0 +1,164 @@ +10 + +dir +205620 +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-02T14:11:38.000000Z +b2ca0a57964d5a0bce8526c33848a2fb +2015-03-05T10:08:33.568013Z +184842 +hschindl + + + + + + + + + + + + + + + + + + + + + +2387 + +singleChipExample.py +file + + + + +2016-05-02T14:11:38.000000Z +3852d5610e7b0528ae1074fd16219511 +2015-03-15T14:01:57.475945Z +185430 +hschindl + + + + + + + + + + + + + + + + + + + + + +983 + +CombatAlignment.dat +file + + + + +2016-05-02T14:11:38.000000Z +8d8d31d71795971b9305d3859b510f8e +2015-03-05T10:08:33.568013Z +184842 +hschindl + + + + + + + + + + + + + + + + + + + + + +390 + +CombatAlignment.py +file + + + + +2016-05-02T14:11:38.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..88a06d2 --- /dev/null +++ b/Kepler/options/online/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +205620 +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-02T14:11:38.000000Z +a7c961b9962079afaafd217d9803e207 +2014-08-12T12:51:03.631406Z +176267 +hschindl + + + + + + + + + + + + + + + + + + + + + +618 + +presenter.cfg +file + + + + +2016-05-02T14:11:38.000000Z +49ed6693969c8940bd6386d870c91066 +2014-08-12T12:51:03.631406Z +176267 +hschindl + + + + + + + + + + + + + + + + + + + + + +498 + +runOnlineMonitor.py +file + + + + +2016-05-02T14:11:38.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..3841618 --- /dev/null +++ b/Kepler/options/trackfit/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:39.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..0f43500 --- /dev/null +++ b/Kepler/options/tracking/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +205620 +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-02T14:11:38.000000Z +b135df7141dac4fb507a4768c54d4b28 +2015-03-15T14:01:57.475945Z +185430 +hschindl + + + + + + + + + + + + + + + + + + + + + +190 + +tracking.py +file + + + + +2016-05-02T14:11:38.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..9effa44 --- /dev/null +++ b/Kepler/python/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +205620 +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..b719b9f --- /dev/null +++ b/Kepler/python/Kepler/.svn/entries @@ -0,0 +1,99 @@ +10 + +dir +205620 +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-02T14:11:36.000000Z +d41d8cd98f00b204e9800998ecf8427e +2014-06-15T18:07:47.065480Z +173882 +hschindl + + + + + + + + + + + + + + + + + + + + + +0 + +QMTest +dir + +Configuration.py +file + + + + +2016-05-02T14:11:36.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..a653417 --- /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..3fa81e4 --- /dev/null +++ b/Kepler/python/Kepler/QMTest/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +205620 +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-02T14:11:35.000000Z +4f56c805ef0451aa3d150a2e64a6cc4b +2014-06-28T14:51:04.243151Z +174354 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +237 + +__init__.py +file + + + + +2016-05-02T14:11:35.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..5a0e0a5 --- /dev/null +++ b/Kepler/tests/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +205620 +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..bfc439d --- /dev/null +++ b/Kepler/tests/qmtest/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +205620 +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..ea189cc --- /dev/null +++ b/Kepler/tests/qmtest/kepler.qms/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +205620 +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-02T14:11:37.000000Z +736d5e4781276d707cdc6faf86679682 +2015-10-23T15:17:24.703715Z +196708 +hschindl + + + + + + + + + + + + + + + + + + + + + +1334 + +july2014.qmt +file + + + + +2016-05-02T14:11:37.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 @@ + + + gaudirun.py + +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 + + $KEPLERROOT/tests/refs/testJuly2014.ref + +from Kepler.QMTest.KeplerExclusions import preprocessor +validateWithReference(preproc = preprocessor) + + 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 @@ + + + gaudirun.py + +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] + + 4 + $KEPLERROOT/tests/refs/testMillepede.ref + +from Kepler.QMTest.KeplerExclusions import preprocessor +validateWithReference(preproc = preprocessor) + + 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 @@ + + + gaudirun.py + +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 + + $KEPLERROOT/tests/refs/testJuly2014.ref + +from Kepler.QMTest.KeplerExclusions import preprocessor +validateWithReference(preproc = preprocessor) + + 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 @@ + + + gaudirun.py + +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] + + 4 + $KEPLERROOT/tests/refs/testMillepede.ref + +from Kepler.QMTest.KeplerExclusions import preprocessor +validateWithReference(preproc = preprocessor) + + 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..926ed39 --- /dev/null +++ b/Kepler/tests/refs/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +205620 +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-02T14:11:36.000000Z +1e7518821596cad40a5aaa96d8601cbe +2015-10-20T16:53:50.358128Z +196509 +hschindl + + + + + + + + + + + + + + + + + + + + + +46345 + +testMillepede.ref +file + + + + +2016-05-02T14:11:36.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 +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) | | | 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 +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) | | | 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 +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) | | | 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 +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) | | | 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..3b4a33a --- /dev/null +++ b/TbAlgorithms/.svn/entries @@ -0,0 +1,71 @@ +10 + +dir +205620 +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-02T14:11:35.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..a1fe161 --- /dev/null +++ b/TbAlgorithms/cmt/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:34.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..d05da73 --- /dev/null +++ b/TbAlgorithms/doc/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:34.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..171c82d --- /dev/null +++ b/TbAlgorithms/src/.svn/entries @@ -0,0 +1,980 @@ +10 + +dir +205620 +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-02T14:11:34.000000Z +ec3ed33a14b35cca78bb29eeb0f73ed5 +2016-01-31T12:06:55.490490Z +200685 +hschindl + + + + + + + + + + + + + + + + + + + + + +4961 + +TbDUTMonitor.h +file + + + + +2016-05-02T14:11:34.000000Z +d0e188dfd7afb59fdf500b94717a5378 +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +2285 + +TbClusterAssociator.cpp +file + + + + +2016-05-02T14:11:34.000000Z +2fe987d4736270234c15979ce25308a9 +2016-02-01T08:44:59.600258Z +200706 +hschindl + + + + + + + + + + + + + + + + + + + + + +4338 + +TbTriggerMonitor.cpp +file + + + + +2016-05-02T14:11:34.000000Z +5024fdef2729187437e2f13d1327a9fd +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +4365 + +TbSimpleTracking.cpp +file + + + + +2016-05-02T14:11:34.000000Z +0153c1f1de549a5d3336d4d1a6a6bcbb +2016-02-24T06:59:33.333028Z +201952 +hschindl + + + + + + + + + + + + + + + + + + + + + +15068 + +TbVisualiserOutput.h +file + + + + +2016-05-02T14:11:34.000000Z +a3c28cc9ac69b9356617137e8226b433 +2015-11-14T14:26:10.932331Z +197618 +hschindl + + + + + + + + + + + + + + + + + + + + + +833 + +TbClusterAssociator.h +file + + + + +2016-05-02T14:11:34.000000Z +0bc3bc1c3f8adf768350dbbe469fa219 +2016-02-01T08:44:59.600258Z +200706 +hschindl + + + + + + + + + + + + + + + + + + + + + +1031 + +TbClustering.cpp +file + + + + +2016-05-02T14:11:34.000000Z +60932036800a3e8e0fe281a98a5098e8 +2016-02-24T06:59:33.333028Z +201952 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +13698 + +TbTriggerMonitor.h +file + + + + +2016-05-02T14:11:34.000000Z +6814dafb0fea9572b850af3aa30d032b +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +1225 + +TbSimpleTracking.h +file + + + + +2016-05-02T14:11:34.000000Z +db11bd565a8697106ff7871b88fc766e +2016-02-24T06:59:33.333028Z +201952 +hschindl + + + + + + + + + + + + + + + + + + + + + +2349 + +TbClustering.h +file + + + + +2016-05-02T14:11:34.000000Z +c7439204e4bd661a30c02d78ed796398 +2016-02-24T06:59:33.333028Z +201952 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +2660 + +TbTrackPlots.cpp +file + + + + +2016-05-02T14:11:34.000000Z +45dcb54b9e28fbfb905bbe60618f3247 +2016-02-04T17:42:06.201374Z +200904 +hschindl + + + + + + + + + + + + + + + + + + + + + +20629 + +TbCalibration.cpp +file + + + + +2016-05-02T14:11:34.000000Z +abd525a6e54f84f32be52814bf6ac0d3 +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +10378 + +TbTrackPlots.h +file + + + + +2016-05-02T14:11:34.000000Z +c04c163a2e1375adb356988e30f9edc7 +2016-02-01T08:44:59.600258Z +200706 +hschindl + + + + + + + + + + + + + + + + + + + + + +4015 + +TbTriggerAssociator.cpp +file + + + + +2016-05-02T14:11:34.000000Z +975770c64fe4d8ac034bad6a8b66d6a6 +2016-01-26T09:15:46.130838Z +200231 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +3159 + +TbHitMonitor.cpp +file + + + + +2016-05-02T14:11:34.000000Z +3ad54d0e6ed8bd92f65ba8dbc4a661df +2016-01-28T21:57:07.788859Z +200592 +hschindl + + + + + + + + + + + + + + + + + + + + + +5120 + +TbCalibration.h +file + + + + +2016-05-02T14:11:34.000000Z +b2f759a3979e3904ff26ad1bf89198ea +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +3788 + +TbTrackVolume.cpp +file + + + + +2016-05-02T14:11:34.000000Z +ea2c94ea42472605a4b3926c10657ee1 +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +5434 + +TbTriggerAssociator.h +file + + + + +2016-05-02T14:11:34.000000Z +c8ad35bd45153447de3f60b84d08f55c +2016-01-26T09:15:46.130838Z +200231 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +1241 + +TbVertexTracking.cpp +file + + + + +2016-05-02T14:11:34.000000Z +5a12e849b2a69a72f5c279250533fe3e +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +23934 + +TbHitMonitor.h +file + + + + +2016-05-02T14:11:34.000000Z +53b2664f5f7af79959e1bb91121faabc +2016-01-28T21:57:07.788859Z +200592 +hschindl + + + + + + + + + + + + + + + + + + + + + +1577 + +TbTrackVolume.h +file + + + + +2016-05-02T14:11:34.000000Z +abef658e16281f0f3f9a80c5900c3c05 +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +1997 + +TbTracking.cpp +file + + + + +2016-05-02T14:11:34.000000Z +3869d2d1345bc03ecace305861b6acde +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +16280 + +TbClusterPlots.cpp +file + + + + +2016-05-02T14:11:34.000000Z +57920adef9bc788e26b675385c3b3666 +2016-02-04T17:42:06.201374Z +200904 +hschindl + + + + + + + + + + + + + + + + + + + + + +25474 + +TbDUTMonitor.cpp +file + + + + +2016-05-02T14:11:34.000000Z +23c7d087b2ed413b31c5cfa8d1e941f5 +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +11958 + +TbVertexTracking.h +file + + + + +2016-05-02T14:11:34.000000Z +0a69626152898e69cbe1d12f6b0fc8e6 +2015-04-13T14:01:42.074593Z +186577 +hschindl + + + + + + + + + + + + + + + + + + + + + +2326 + +TbTracking.h +file + + + + +2016-05-02T14:11:34.000000Z +14cabe8e5ba81e925be836549847f914 +2016-01-26T09:15:46.130838Z +200231 +hschindl + + + + + + + + + + + + + + + + + + + + + +2732 + +TbVisualiserOutput.cpp +file + + + + +2016-05-02T14:11:34.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 + +// 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(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(m_hitLocation + std::to_string(i)); + if (!hits) continue; + hotPixel_execute(hits); + } + } + if (m_checkSyncronisation) { + if (m_syncMethod == 0) { + std::vector clusters; + for (unsigned int i = 0; i < m_nPlanes; ++i) + clusters.push_back(getIfExists(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 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 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& 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 { + PROFILE1D(unsigned int size = 0) : std::vector(size, POINT()) {} + }; + + struct PROFILE2D : public std::vector> { + PROFILE2D(unsigned int size_x = 0, unsigned int size_y = 0) + : std::vector>( + size_x, std::vector(size_y, POINT())) {}; + + inline POINT element(const unsigned int x, const unsigned int y) const { + std::vector tmp = *(begin() + x); + return tmp[y]; + } + + std::vector neighbours(const unsigned int x, + const unsigned int y) const { + std::vector 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 m_offsets; + std::vector 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& 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(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(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 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 + +// 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("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(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(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(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<htime()<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"<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 m_hToT; + std::vector m_hToTOnePixel; + std::vector m_hToTTwoPixel; + std::vector m_hToTThreePixel; + std::vector m_hToTFourPixel; + std::vector m_hToTAssociated; + std::vector m_hToTNonAssociated; + // Charge distribution + std::vector m_hCharge; + std::vector m_hChargeOnePixel; + std::vector m_hChargeTwoPixel; + std::vector m_hChargeThreePixel; + std::vector m_hChargeFourPixel; + std::vector m_hChargeAssociated; + std::vector m_hChargeNonAssociated; + // Cluster size + std::vector m_hSize; + std::vector m_hSizeAssociated; + std::vector m_hSizeNonAssociated; + std::vector m_hWidthCol; + std::vector m_hWidthRow; + // Cluster time + std::vector m_hTime; + std::vector m_hTimeAssociated; + std::vector m_hTimeNonAssociated; + std::vector m_hTimeBetweenClusters; + // Time spread of pixel hits in a cluster + std::vector m_hTimeSeedMinusHit; + + // Hitmaps + std::vector m_hHitMap; + std::vector m_hHitMapAssociated; + std::vector m_hHitMapNonAssociated; + + AIDA::IHistogram2D* m_hGlobalXvsZ; + AIDA::IHistogram2D* m_hGlobalYvsZ; + + // Global correlations. + std::vector m_gx_correls; + std::vector m_gy_correls; + std::vector m_gt_correls; + + // Global differences. + std::vector m_gx_diffs; + std::vector m_gy_diffs; + std::vector m_gt_diffs; + + std::vector 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(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 used(hits->size(), false); + std::vector 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()); + // 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()); + // 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()); + // Fill the counter. + counter("NumberOfClusters" + ext) += clusters->size(); + } + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finding touching hits +//============================================================================= +void TbClustering::addNeighbouringHits(std::vector& pixels, + LHCb::TbHits::const_iterator begin, + LHCb::TbHits::const_iterator end, + std::vector& 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& 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 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 coefficients; + }; + /// Set of eta-correction parameters per plane, direction, and cluster width. + std::vector >, 2> > m_eta; + + /// Add pixels to a given seed pixel. + void addNeighbouringHits(std::vector& pixels, + LHCb::TbHits::const_iterator begin, + LHCb::TbHits::const_iterator end, + std::vector& 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& 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& 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 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 xaxis(6, 0); + std::vector yaxis(6, 0); + std::vector::iterator xL = + std::find(labels.begin(), labels.end(), m_parScanX.title()); + std::vector::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(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 m_duts; + std::map 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 m_hResLocalX; + std::vector m_hResLocalY; + std::vector m_hResGlobalX; + std::vector m_hResGlobalY; + std::vector m_hResTime; + + std::vector m_hUnbiasedResGlobalXvsGlobalX; + std::vector m_hUnbiasedResGlobalYvsGlobalY; + std::vector m_hUnbiasedResGlobalXvsTrackChi2; + std::vector m_hUnbiasedResGlobalYvsTrackChi2; + + std::vector m_hUnbiasedResGlobalXvsPixelX; + std::vector m_hUnbiasedResGlobalXvsPixelY; + std::vector m_hUnbiasedResGlobalYvsPixelX; + std::vector m_hUnbiasedResGlobalYvsPixelY; + + std::vector m_hUnbiasedResGlobalXvsTrackTx; + std::vector m_hUnbiasedResGlobalXvsTrackTy; + std::vector m_hUnbiasedResGlobalYvsTrackTx; + std::vector m_hUnbiasedResGlobalYvsTrackTy; + std::vector m_UnbiasedResGlobalXvshUnbiasedResGlobalY; + std::vector m_hUnbiasedResGlobalXvsClusterSize; + std::vector m_hUnbiasedResGlobalYvsClusterSize; + + std::vector m_hScanXvsX; + std::vector m_hScanYvsY; + + std::vector 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(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 m_hHitMap; + std::vector m_hToT; + std::vector m_hCharge; + std::vector m_hToTvsCol; + std::vector m_hChargevsCol; + std::vector m_hHitsInEvent; + std::vector m_hHitsInEventTrend; + std::vector 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(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(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(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&>(track->clusters()); + // Sort the clusters by plane. + std::sort(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + // 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()); + // 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 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 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 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(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(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(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 m_hIntercepts; + std::vector m_hInterceptsAssociated; + std::vector m_hInterceptsNonAssociated; + /// Biased residuals. + std::vector m_hBiasedResGX; + std::vector m_hBiasedResGY; + std::vector m_hBiasedResLX; + std::vector m_hBiasedResLY; + /// Unbiased residuals. + std::vector m_hUnbiasedResGX; + std::vector m_hUnbiasedResGY; + std::vector m_hUnbiasedResLX; + std::vector m_hUnbiasedResLY; + + /// Biased residuals as functions of x/y. + std::vector m_hBiasedResGXvsLX; + std::vector m_hBiasedResGYvsLY; + /// Unbiased residuals as functions of x/y. + std::vector m_hUnbiasedResGXvsGX; + std::vector m_hUnbiasedResGYvsGY; + /// Biased residuals as functions of track probability. + std::vector m_hBiasedResGXvsTrackProb; + std::vector m_hBiasedResGYvsTrackProb; + + /// Cluster time residuals. + std::vector m_hBiasedResT; + /// Cluster time residuals as function of global x. + std::vector m_hBiasedResTvsGX; + /// Pixel time residuals as function of column number. + std::vector 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 m_hSyncDifferences; + std::vector 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()); + 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 + +// 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 > 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 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 +#include + +// 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(m_trackFitTool, "Fitter", this); + if (!m_trackFit) return Error("Cannot retrieve track fit tool."); + // Set up the cluster finder. + m_clusterFinder = + tool("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(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(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& clusters = + const_cast&>(trialTrack->clusters()); + std::sort(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + // 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& clusters = + const_cast&>(best_track->clusters()); + auto earliest_hit = + std::min_element(clusters.begin(), clusters.end(), + TbFunctors::LessByTime()); + + 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 m_PlaneSearchOrder; + /// Max. size of clusters on a track + unsigned int m_clusterSizeCut; + + std::vector > 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(m_trackLocation); + if (!tracks) { + return Error("No tracks in " + m_trackLocation); + } + // Grab the triggers. + std::vector triggers(m_nPlanes, nullptr); + std::vector begin(m_nPlanes); + std::vector 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(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> summary = m_missedTriggers[i]; + if( summary.size() != 0 ){ + info() << "Trigger jumps on plane " << i << endmsg;; + for( std::vector>::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(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 m_counter; + + std::vector m_hTimeBetweenTriggers; + std::vector m_hTriggersInEvent; + std::vector m_hTriggersInEventTrend; + std::vector>> 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 +#include + +// 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(m_trackFitTool, "Fitter", this); + if (!m_trackFit) return Error("Cannot retrieve track fit tool."); + // Set up the cluster finder. + m_clusterFinder = + tool("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(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(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& clusters = + const_cast&>( + (*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& clusters = + const_cast&>( + (*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& tracks = + const_cast&>((*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& clusters = + const_cast&>(track->clusters()); + auto earliest_hit = + std::min_element(clusters.begin(), clusters.end(), + TbFunctors::LessByTime()); + + if (timingSvc()->beforeOverlap((*earliest_hit)->time()) || m_combatRun) { + auto farthest_hit = + std::max_element(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + 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()); + 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 > m_endCluster; + std::vector > m_vertexedCluster; + std::vector > m_volumed; + + double m_twindow; + unsigned int m_MinNClusters; + unsigned int m_MinNClustersRepeat; + double m_ChiSqRedCut; + std::string m_ClusterFinderSearchAlgorithm; + std::vector 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 +#include + +// 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("TbClusterFinder", "ClusterFinder", this); + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode TbVisualiserOutput::execute() { + m_tracks = getIfExists(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(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 + +// 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(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(m_hitLocation + std::to_string(i)); + if (!hits) continue; + hotPixel_execute(hits); + } + } + if (m_checkSyncronisation) { + if (m_syncMethod == 0) { + std::vector clusters; + for (unsigned int i = 0; i < m_nPlanes; ++i) + clusters.push_back(getIfExists(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 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 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& 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 { + PROFILE1D(unsigned int size = 0) : std::vector(size, POINT()) {} + }; + + struct PROFILE2D : public std::vector> { + PROFILE2D(unsigned int size_x = 0, unsigned int size_y = 0) + : std::vector>( + size_x, std::vector(size_y, POINT())) {}; + + inline POINT element(const unsigned int x, const unsigned int y) const { + std::vector tmp = *(begin() + x); + return tmp[y]; + } + + std::vector neighbours(const unsigned int x, + const unsigned int y) const { + std::vector 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 m_offsets; + std::vector 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& 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(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(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 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 + +// 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("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(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(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(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<htime()<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"<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 m_hToT; + std::vector m_hToTOnePixel; + std::vector m_hToTTwoPixel; + std::vector m_hToTThreePixel; + std::vector m_hToTFourPixel; + std::vector m_hToTAssociated; + std::vector m_hToTNonAssociated; + // Charge distribution + std::vector m_hCharge; + std::vector m_hChargeOnePixel; + std::vector m_hChargeTwoPixel; + std::vector m_hChargeThreePixel; + std::vector m_hChargeFourPixel; + std::vector m_hChargeAssociated; + std::vector m_hChargeNonAssociated; + // Cluster size + std::vector m_hSize; + std::vector m_hSizeAssociated; + std::vector m_hSizeNonAssociated; + std::vector m_hWidthCol; + std::vector m_hWidthRow; + // Cluster time + std::vector m_hTime; + std::vector m_hTimeAssociated; + std::vector m_hTimeNonAssociated; + std::vector m_hTimeBetweenClusters; + // Time spread of pixel hits in a cluster + std::vector m_hTimeSeedMinusHit; + + // Hitmaps + std::vector m_hHitMap; + std::vector m_hHitMapAssociated; + std::vector m_hHitMapNonAssociated; + + AIDA::IHistogram2D* m_hGlobalXvsZ; + AIDA::IHistogram2D* m_hGlobalYvsZ; + + // Global correlations. + std::vector m_gx_correls; + std::vector m_gy_correls; + std::vector m_gt_correls; + + // Global differences. + std::vector m_gx_diffs; + std::vector m_gy_diffs; + std::vector m_gt_diffs; + + std::vector 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(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 used(hits->size(), false); + std::vector 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()); + // 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()); + // 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()); + // Fill the counter. + counter("NumberOfClusters" + ext) += clusters->size(); + } + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Finding touching hits +//============================================================================= +void TbClustering::addNeighbouringHits(std::vector& pixels, + LHCb::TbHits::const_iterator begin, + LHCb::TbHits::const_iterator end, + std::vector& 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& 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 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 coefficients; + }; + /// Set of eta-correction parameters per plane, direction, and cluster width. + std::vector >, 2> > m_eta; + + /// Add pixels to a given seed pixel. + void addNeighbouringHits(std::vector& pixels, + LHCb::TbHits::const_iterator begin, + LHCb::TbHits::const_iterator end, + std::vector& 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& 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& 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 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 xaxis(6, 0); + std::vector yaxis(6, 0); + std::vector::iterator xL = + std::find(labels.begin(), labels.end(), m_parScanX.title()); + std::vector::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(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 m_duts; + std::map 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 m_hResLocalX; + std::vector m_hResLocalY; + std::vector m_hResGlobalX; + std::vector m_hResGlobalY; + std::vector m_hResTime; + + std::vector m_hUnbiasedResGlobalXvsGlobalX; + std::vector m_hUnbiasedResGlobalYvsGlobalY; + std::vector m_hUnbiasedResGlobalXvsTrackChi2; + std::vector m_hUnbiasedResGlobalYvsTrackChi2; + + std::vector m_hUnbiasedResGlobalXvsPixelX; + std::vector m_hUnbiasedResGlobalXvsPixelY; + std::vector m_hUnbiasedResGlobalYvsPixelX; + std::vector m_hUnbiasedResGlobalYvsPixelY; + + std::vector m_hUnbiasedResGlobalXvsTrackTx; + std::vector m_hUnbiasedResGlobalXvsTrackTy; + std::vector m_hUnbiasedResGlobalYvsTrackTx; + std::vector m_hUnbiasedResGlobalYvsTrackTy; + std::vector m_UnbiasedResGlobalXvshUnbiasedResGlobalY; + std::vector m_hUnbiasedResGlobalXvsClusterSize; + std::vector m_hUnbiasedResGlobalYvsClusterSize; + + std::vector m_hScanXvsX; + std::vector m_hScanYvsY; + + std::vector 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(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 m_hHitMap; + std::vector m_hToT; + std::vector m_hCharge; + std::vector m_hToTvsCol; + std::vector m_hChargevsCol; + std::vector m_hHitsInEvent; + std::vector m_hHitsInEventTrend; + std::vector 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(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(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(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&>(track->clusters()); + // Sort the clusters by plane. + std::sort(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + // 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()); + // 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 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 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 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(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(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(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 m_hIntercepts; + std::vector m_hInterceptsAssociated; + std::vector m_hInterceptsNonAssociated; + /// Biased residuals. + std::vector m_hBiasedResGX; + std::vector m_hBiasedResGY; + std::vector m_hBiasedResLX; + std::vector m_hBiasedResLY; + /// Unbiased residuals. + std::vector m_hUnbiasedResGX; + std::vector m_hUnbiasedResGY; + std::vector m_hUnbiasedResLX; + std::vector m_hUnbiasedResLY; + + /// Biased residuals as functions of x/y. + std::vector m_hBiasedResGXvsLX; + std::vector m_hBiasedResGYvsLY; + /// Unbiased residuals as functions of x/y. + std::vector m_hUnbiasedResGXvsGX; + std::vector m_hUnbiasedResGYvsGY; + /// Biased residuals as functions of track probability. + std::vector m_hBiasedResGXvsTrackProb; + std::vector m_hBiasedResGYvsTrackProb; + + /// Cluster time residuals. + std::vector m_hBiasedResT; + /// Cluster time residuals as function of global x. + std::vector m_hBiasedResTvsGX; + /// Pixel time residuals as function of column number. + std::vector 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 m_hSyncDifferences; + std::vector 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()); + 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 + +// 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 > 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 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 +#include + +// 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(m_trackFitTool, "Fitter", this); + if (!m_trackFit) return Error("Cannot retrieve track fit tool."); + // Set up the cluster finder. + m_clusterFinder = + tool("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(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(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& clusters = + const_cast&>(trialTrack->clusters()); + std::sort(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + // 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& clusters = + const_cast&>(best_track->clusters()); + auto earliest_hit = + std::min_element(clusters.begin(), clusters.end(), + TbFunctors::LessByTime()); + + 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 m_PlaneSearchOrder; + /// Max. size of clusters on a track + unsigned int m_clusterSizeCut; + + std::vector > 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(m_trackLocation); + if (!tracks) { + return Error("No tracks in " + m_trackLocation); + } + // Grab the triggers. + std::vector triggers(m_nPlanes, nullptr); + std::vector begin(m_nPlanes); + std::vector 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(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> summary = m_missedTriggers[i]; + if( summary.size() != 0 ){ + info() << "Trigger jumps on plane " << i << endmsg;; + for( std::vector>::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(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 m_counter; + + std::vector m_hTimeBetweenTriggers; + std::vector m_hTriggersInEvent; + std::vector m_hTriggersInEventTrend; + std::vector>> 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 +#include + +// 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(m_trackFitTool, "Fitter", this); + if (!m_trackFit) return Error("Cannot retrieve track fit tool."); + // Set up the cluster finder. + m_clusterFinder = + tool("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(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(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& clusters = + const_cast&>( + (*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& clusters = + const_cast&>( + (*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& tracks = + const_cast&>((*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& clusters = + const_cast&>(track->clusters()); + auto earliest_hit = + std::min_element(clusters.begin(), clusters.end(), + TbFunctors::LessByTime()); + + if (timingSvc()->beforeOverlap((*earliest_hit)->time()) || m_combatRun) { + auto farthest_hit = + std::max_element(clusters.begin(), clusters.end(), + TbFunctors::LessByZ()); + 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()); + 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 > m_endCluster; + std::vector > m_vertexedCluster; + std::vector > m_volumed; + + double m_twindow; + unsigned int m_MinNClusters; + unsigned int m_MinNClustersRepeat; + double m_ChiSqRedCut; + std::string m_ClusterFinderSearchAlgorithm; + std::vector 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 +#include + +// 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("TbClusterFinder", "ClusterFinder", this); + + return StatusCode::SUCCESS; +} + +//============================================================================= +// Main execution +//============================================================================= +StatusCode TbVisualiserOutput::execute() { + m_tracks = getIfExists(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(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..7d81e95 --- /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/205019/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..f7aa912 --- /dev/null +++ b/TbAlignment/.svn/entries @@ -0,0 +1,71 @@ +10 + +dir +205620 +http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlignment +http://svn.cern.ch/guest/lhcb + + + +2016-04-19T19:58:58.694018Z +205019 +tevans + + + + + + + + + + + + + + +4525493e-7705-40b1-a816-d608a930855b + +cmt +dir + +doc +dir + +src +dir + +CMakeLists.txt +file + + + + +2016-05-02T14:11:42.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..81b59dd --- /dev/null +++ b/TbAlignment/cmt/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:41.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..09fd5c0 --- /dev/null +++ b/TbAlignment/doc/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:41.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..faada16 --- /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/205019/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/205019/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..c0a6c56 --- /dev/null +++ b/TbAlignment/src/.svn/entries @@ -0,0 +1,572 @@ +10 + +dir +205620 +http://svn.cern.ch/guest/lhcb/Kepler/trunk/Tb/TbAlignment/src +http://svn.cern.ch/guest/lhcb + + + +2016-04-19T19:58:58.694018Z +205019 +tevans + + + + + + + + + + + + + + +4525493e-7705-40b1-a816-d608a930855b + +TbAlignmentBase.cpp +file + + + + +2016-05-02T14:11:41.000000Z +555c7164d0cba131292775f48983a61c +2016-04-19T19:58:58.694018Z +205019 +tevans + + + + + + + + + + + + + + + + + + + + + +9872 + +TbAlignmentBase.h +file + + + + +2016-05-02T14:11:41.000000Z +ee56b0abef1ea3a0045737092ac8af18 +2015-11-01T22:22:30.088045Z +197093 +hschindl + + + + + + + + + + + + + + + + + + + + + +2728 + +TbAlignment.cpp +file + + + + +2016-05-02T14:11:41.000000Z +e937dbfb3b0121a7f6ebf47ef651b5eb +2015-11-01T22:22:30.088045Z +197093 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +4971 + +TbAlignment.h +file + + + + +2016-05-02T14:11:41.000000Z +cccb40b370315d048a88bf214eaf6b3c +2015-11-01T22:22:30.088045Z +197093 +hschindl + + + + + + + + + + + + + + + + + + + + + +1223 + +TbAlignmentMinuit0.cpp +file + + + + +2016-05-02T14:11:41.000000Z +7a3329de64eaf3785902afdea05ff8ba +2015-11-04T10:41:09.903529Z +197185 +hschindl + + + + + + + + + + + + + + + + + + + + + +4045 + +TbAlignmentMinuit1.cpp +file + + + + +2016-05-02T14:11:41.000000Z +504c649d2d4a6698151658aa59d2ec15 +2015-10-31T19:56:10.654704Z +197055 +hschindl + + + + + + + + + + + + + + + + + + + + + +4535 + +TbAlignmentMinuit2.cpp +file + + + + +2016-05-02T14:11:41.000000Z +719d12f82a68d1cca3c7c6afdac08bb1 +2016-04-19T19:58:58.694018Z +205019 +tevans + + + + + + + + + + + + + + + + + + + + + +9938 + +TbAlignmentMinuit0.h +file + + + + +2016-05-02T14:11:41.000000Z +0d613c50c3ad3102214305ae9969beba +2015-11-04T10:41:09.903529Z +197185 +hschindl + + + + + + + + + + + + + + + + + + + + + +510 + +TbAlignmentMinuit1.h +file + + + + +2016-05-02T14:11:41.000000Z +2992264c22fafc0698438d3c6ba76442 +2015-10-29T08:39:29.812074Z +196953 +hschindl + + + + + + + + + + + + + + + + + + + + + +511 + +TbAlignmentMinuit2.h +file + + + + +2016-05-02T14:11:41.000000Z +08bd76c8f4b3bbdf30333c1216c88f73 +2016-04-19T19:58:58.694018Z +205019 +tevans + + + + + + + + + + + + + + + + + + + + + +1016 + +TbAlignmentSurvey.cpp +file + + + + +2016-05-02T14:11:41.000000Z +9a0a6163b9f8849f4da0446c9f485b85 +2015-10-31T19:56:10.654704Z +197055 +hschindl + + + + + + + + + + + + + + + + + + + + + +2770 + +TbAlignmentMinuitBase.cpp +file + + + + +2016-05-02T14:11:41.000000Z +d360ba7bcc991f65866a8acca7614523 +2015-11-04T10:41:09.903529Z +197185 +hschindl + + + + + + + + + + + + + + + + + + + + + +4774 + +TbMillepede.cpp +file + + + + +2016-05-02T14:11:41.000000Z +15fe78ad51875a8eb413e581606c226d +2016-04-19T19:58:58.694018Z +205019 +tevans +has-props + + + + + + + + + + + + + + + + + + + + +40277 + +TbAlignmentSurvey.h +file + + + + +2016-05-02T14:11:41.000000Z +bba2d3c41435a6bbf27587bf30e445b3 +2015-10-22T11:28:21.744746Z +196613 +hschindl + + + + + + + + + + + + + + + + + + + + + +400 + +TbAlignmentMinuitBase.h +file + + + + +2016-05-02T14:11:41.000000Z +24b802ba73464041e74772d6684d2f6c +2015-11-04T10:41:09.903529Z +197185 +hschindl + + + + + + + + + + + + + + + + + + + + + +750 + +TbMillepede.h +file + + + + +2016-05-02T14:11:41.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 + +// 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(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 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 m_alignmentSequence; + /// For the track counter printout + unsigned int m_lastTrackPrint; + + /// Tracks for alignment + std::vector m_tracks; + /// Number of alignment tracks after which to stop processsing. + unsigned int m_nTracks; + + std::vector m_toolChain; + std::vector::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 +#include +#include +#include + +// 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(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 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("TbTrackFit", "Fitter", this); + if (!m_trackFit) { + return Error("Failed to initialise track fit."); + } + return StatusCode::SUCCESS; +} + +void TbAlignmentBase::plotResiduals(std::vector& tracks, + const std::string& tag) { + + if (!m_monitoring) return; + // Book histograms. + std::vector hResGlobalX; + std::vector hResGlobalY; + std::vector hResGlobalXvsGlobalX; + std::vector 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 ty(m_nPlanes, 0.); + std::vector yty(m_nPlanes, 0.); + std::vector y(m_nPlanes, 0.); + std::vector yy(m_nPlanes, 0.); + std::vector 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& alignmentTracks) { + + // Get the tracks. + LHCb::TbTracks* tracks = getIfExists(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& alignmentTracks); + /// Alignment function (called after enough tracks have been collected). + virtual void align(std::vector& alignmentTracks) = 0; + + bool clearTracks() const { return m_clearTracks; } + /// Fill monitoring histograms. + void plotResiduals(std::vector& 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 m_dofs; + /// Default degrees of freedom + std::vector m_dofsDefault; + /// List of masked planes + std::vector m_maskedPlanes; + /// Flags whether a plane is masked or not. + std::vector 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 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("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 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& 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& 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& 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& 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 + +// 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& alignmentTracks) { + + // Grab the tracks. + LHCb::TbTracks* tracks = getIfExists(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(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()); + 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::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::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& 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& tracks); + + virtual void align(std::vector& 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& 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& 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 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& /*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& 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..8a7b25c --- /dev/null +++ b/TbAlignment/src/.svn/text-base/TbMillepede.cpp.svn-base @@ -0,0 +1,1093 @@ +#include +#include +#include + +// 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& 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 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 ftx(nParameters, 0.); + std::vector fty(nParameters, 0.); + std::vector ftz(nParameters, 0.); + std::vector frx(nParameters, 0.); + std::vector fry(nParameters, 0.); + std::vector frz(nParameters, 0.); + std::vector fscaz(nParameters, 0.); + std::vector shearx(nParameters, 0.); + std::vector 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 constraints = {true, true, true, true, false, + false, true, false, 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& 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 equations; + const unsigned int nParameters = 6 * nPlanes; + // Global derivatives + std::vector dergb(nParameters, 0.); + // Global derivatives non linearly related to residual + std::vector dernl(nParameters, 0.); + // Local parameter indices associated with non-linear derivatives + std::vector dernli(nParameters, 0); + // Track slopes + std::vector 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& 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 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 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 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& equations, + const std::vector& derlc, + const std::vector& dergb, + const std::vector& dernl, + const std::vector& dernli, + const std::vector& 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& equations, + std::vector& trackParams, + const bool singlefit, const unsigned int iteration) { + + std::vector blvec(m_nalc, 0.); + std::vector > clmat(m_nalc, + std::vector(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(m_nalc, 0.)); + unsigned int nagbn = 0; + std::vector indnz(m_nagb, -1); + std::vector 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(nRows, 0.)); + m_corrv.assign(m_nagb, 0.); + m_corrm.assign(m_nagb, std::vector(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 bgvecPrev(m_nagb, 0.); + std::vector trackParams(2 * m_nalc + 2, 0.); + const unsigned int nTracks = m_equations.size(); + std::vector > localParams( + nTracks, std::vector(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 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 >& v, + std::vector& b, const int n) { + int rank = 0; + const double eps = 0.0000000000001; + + std::vector diag(n, 0.); + std::vector used_param(n, true); + std::vector 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 r(n, 0.); + std::vector 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 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 >& v, + std::vector& b, const int n) { + + int rank = 0; + const double eps = 0.0000000000001; + + std::vector flag(n, true); + std::vector 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 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 >& a, + const std::vector& x, + std::vector& 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 >& v, + const std::vector >& a, + std::vector >& 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& alignmentTracks); + + virtual void updateGeometry(); + + private: + struct Equation { + double rmeas; + double weight; + std::vector indG; + std::vector derG; + std::vector indL; + std::vector derL; + std::vector indNL; + std::vector derNL; + std::vector slopes; + }; + struct Constraint { + /// Right-hand side (Lagrange multiplier) + double rhs; + /// Coefficients + std::vector 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& 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& equations, + const std::vector& derlc, + const std::vector& dergb, + const std::vector& dernl, + const std::vector& dernli, + const std::vector& dernls, const double rmeas, + const double sigma); + /// Perform local parameters fit using the equations for one track. + bool fitTrack(const std::vector& equations, + std::vector& 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 >& v, std::vector& b, + const int n); + /// Matrix inversion and solution for local fit. + int invertMatrixLocal(std::vector >& v, + std::vector& 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 >& a, + const std::vector& x, std::vector& y, + const unsigned int n, const unsigned int m); + /// Multiply matrices + bool multiplyAVAt(const std::vector >& v, + const std::vector >& a, + std::vector >& 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 > m_equations; + /// Constraint equations + std::vector m_constraints; + + /// Flag for each global parameter whether it is fixed or not. + std::vector m_fixed; + /// Sigmas for each global parameter. + std::vector m_psigm; + + std::vector > m_cgmat; + std::vector > m_corrm; + std::vector > m_clcmat; + + std::vector m_bgvec; + std::vector m_corrv; + std::vector m_diag; + + /// Difference in misalignment parameters with respect to initial values. + std::vector m_dparm; + + /// Mapping of internal numbering to geometry service planes. + std::vector 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 m_sigmas; + /// Planes to be kept fixed + std::vector 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 + +// 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(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 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 m_alignmentSequence; + /// For the track counter printout + unsigned int m_lastTrackPrint; + + /// Tracks for alignment + std::vector m_tracks; + /// Number of alignment tracks after which to stop processsing. + unsigned int m_nTracks; + + std::vector m_toolChain; + std::vector::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 +#include +#include +#include + +// 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(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 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("TbTrackFit", "Fitter", this); + if (!m_trackFit) { + return Error("Failed to initialise track fit."); + } + return StatusCode::SUCCESS; +} + +void TbAlignmentBase::plotResiduals(std::vector& tracks, + const std::string& tag) { + + if (!m_monitoring) return; + // Book histograms. + std::vector hResGlobalX; + std::vector hResGlobalY; + std::vector hResGlobalXvsGlobalX; + std::vector 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 ty(m_nPlanes, 0.); + std::vector yty(m_nPlanes, 0.); + std::vector y(m_nPlanes, 0.); + std::vector yy(m_nPlanes, 0.); + std::vector 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& alignmentTracks) { + + // Get the tracks. + LHCb::TbTracks* tracks = getIfExists(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& alignmentTracks); + /// Alignment function (called after enough tracks have been collected). + virtual void align(std::vector& alignmentTracks) = 0; + + bool clearTracks() const { return m_clearTracks; } + /// Fill monitoring histograms. + void plotResiduals(std::vector& 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 m_dofs; + /// Default degrees of freedom + std::vector m_dofsDefault; + /// List of masked planes + std::vector m_maskedPlanes; + /// Flags whether a plane is masked or not. + std::vector 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 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("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 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& 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& 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& 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& 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 + +// 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& alignmentTracks) { + + // Grab the tracks. + LHCb::TbTracks* tracks = getIfExists(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(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()); + 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::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::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& 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& tracks); + + virtual void align(std::vector& 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& 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& 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 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& /*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& alignmentTracks); +}; diff --git a/TbAlignment/src/TbMillepede.cpp b/TbAlignment/src/TbMillepede.cpp new file mode 100755 index 0000000..8a7b25c --- /dev/null +++ b/TbAlignment/src/TbMillepede.cpp @@ -0,0 +1,1093 @@ +#include +#include +#include + +// 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& 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 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 ftx(nParameters, 0.); + std::vector fty(nParameters, 0.); + std::vector ftz(nParameters, 0.); + std::vector frx(nParameters, 0.); + std::vector fry(nParameters, 0.); + std::vector frz(nParameters, 0.); + std::vector fscaz(nParameters, 0.); + std::vector shearx(nParameters, 0.); + std::vector 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 constraints = {true, true, true, true, false, + false, true, false, 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& 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 equations; + const unsigned int nParameters = 6 * nPlanes; + // Global derivatives + std::vector dergb(nParameters, 0.); + // Global derivatives non linearly related to residual + std::vector dernl(nParameters, 0.); + // Local parameter indices associated with non-linear derivatives + std::vector dernli(nParameters, 0); + // Track slopes + std::vector 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& 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 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 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 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& equations, + const std::vector& derlc, + const std::vector& dergb, + const std::vector& dernl, + const std::vector& dernli, + const std::vector& 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& equations, + std::vector& trackParams, + const bool singlefit, const unsigned int iteration) { + + std::vector blvec(m_nalc, 0.); + std::vector > clmat(m_nalc, + std::vector(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(m_nalc, 0.)); + unsigned int nagbn = 0; + std::vector indnz(m_nagb, -1); + std::vector 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(nRows, 0.)); + m_corrv.assign(m_nagb, 0.); + m_corrm.assign(m_nagb, std::vector(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 bgvecPrev(m_nagb, 0.); + std::vector trackParams(2 * m_nalc + 2, 0.); + const unsigned int nTracks = m_equations.size(); + std::vector > localParams( + nTracks, std::vector(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 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 >& v, + std::vector& b, const int n) { + int rank = 0; + const double eps = 0.0000000000001; + + std::vector diag(n, 0.); + std::vector used_param(n, true); + std::vector 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 r(n, 0.); + std::vector 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 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 >& v, + std::vector& b, const int n) { + + int rank = 0; + const double eps = 0.0000000000001; + + std::vector flag(n, true); + std::vector 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 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 >& a, + const std::vector& x, + std::vector& 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 >& v, + const std::vector >& a, + std::vector >& 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& alignmentTracks); + + virtual void updateGeometry(); + + private: + struct Equation { + double rmeas; + double weight; + std::vector indG; + std::vector derG; + std::vector indL; + std::vector derL; + std::vector indNL; + std::vector derNL; + std::vector slopes; + }; + struct Constraint { + /// Right-hand side (Lagrange multiplier) + double rhs; + /// Coefficients + std::vector 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& 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& equations, + const std::vector& derlc, + const std::vector& dergb, + const std::vector& dernl, + const std::vector& dernli, + const std::vector& dernls, const double rmeas, + const double sigma); + /// Perform local parameters fit using the equations for one track. + bool fitTrack(const std::vector& equations, + std::vector& 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 >& v, std::vector& b, + const int n); + /// Matrix inversion and solution for local fit. + int invertMatrixLocal(std::vector >& v, + std::vector& 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 >& a, + const std::vector& x, std::vector& y, + const unsigned int n, const unsigned int m); + /// Multiply matrices + bool multiplyAVAt(const std::vector >& v, + const std::vector >& a, + std::vector >& 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 > m_equations; + /// Constraint equations + std::vector m_constraints; + + /// Flag for each global parameter whether it is fixed or not. + std::vector m_fixed; + /// Sigmas for each global parameter. + std::vector m_psigm; + + std::vector > m_cgmat; + std::vector > m_corrm; + std::vector > m_clcmat; + + std::vector m_bgvec; + std::vector m_corrv; + std::vector m_diag; + + /// Difference in misalignment parameters with respect to initial values. + std::vector m_dparm; + + /// Mapping of internal numbering to geometry service planes. + std::vector 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 m_sigmas; + /// Planes to be kept fixed + std::vector 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..dcd9a76 --- /dev/null +++ b/TbAnalysis/.svn/entries @@ -0,0 +1,71 @@ +10 + +dir +205620 +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-02T14:11:48.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..d59c637 --- /dev/null +++ b/TbAnalysis/cmt/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:47.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..1ab5022 --- /dev/null +++ b/TbAnalysis/doc/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:48.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..1943688 --- /dev/null +++ b/TbAnalysis/src/.svn/entries @@ -0,0 +1,436 @@ +10 + +dir +205620 +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-02T14:11:48.000000Z +0aa8b51d435603d7012317a9411ee48d +2015-01-10T23:07:56.865725Z +182246 +tevans + + + + + + + + + + + + + + + + + + + + + +562 + +TbEfficiency.h +file + + + + +2016-05-02T14:11:48.000000Z +d3ec6a1137a160320c9f15a14a32eddb +2015-11-17T13:18:40.094527Z +197726 +dsaunder + + + + + + + + + + + + + + + + + + + + + +1376 + +TbTimewalkMonitor.h +file + + + + +2016-05-02T14:11:48.000000Z +52686757b12cbe3dd20728f67a2e2071 +2015-06-15T11:23:40.096784Z +190289 +tevans + + + + + + + + + + + + + + + + + + + + + +1560 + +TbResolutionMonitor.cpp +file + + + + +2016-05-02T14:11:48.000000Z +f001371c56c9e600d3ef14e6c5a19c99 +2015-10-17T15:37:57.736429Z +196412 +hschindl + + + + + + + + + + + + + + + + + + + + + +4148 + +TbVertexing.cpp +file + + + + +2016-05-02T14:11:48.000000Z +5f51593e57cf73e07167538119b29a41 +2015-11-10T17:28:27.488768Z +197430 +tevans + + + + + + + + + + + + + + + + + + + + + +4744 + +TbEffPur.h +file + + + + +2016-05-02T14:11:48.000000Z +512a6da1800e9cd8316e47d5db99d04a +2015-10-23T11:15:02.549411Z +196683 +hschindl + + + + + + + + + + + + + + + + + + + + + +3799 + +TbResolutionMonitor.h +file + + + + +2016-05-02T14:11:48.000000Z +0f96703f005e8931c476e854b4e87088 +2014-11-20T19:24:21.222174Z +180518 +hschindl + + + + + + + + + + + + + + + + + + + + + +571 + +TbVertexing.h +file + + + + +2016-05-02T14:11:48.000000Z +22804f786e162cd44ab4b7eb8984cc6c +2015-11-10T17:28:27.488768Z +197430 +tevans + + + + + + + + + + + + + + + + + + + + + +2893 + +TbChargeCalib.cpp +file + + + + +2016-05-02T14:11:48.000000Z +e8a1fccc22bed61872c10442bcb8ace9 +2015-10-17T15:37:57.736429Z +196412 +hschindl + + + + + + + + + + + + + + + + + + + + + +2446 + +TbEfficiency.cpp +file + + + + +2016-05-02T14:11:48.000000Z +f3d5b2f047f8e75c4a0261a3f934e287 +2015-11-20T04:35:00.494755Z +197807 +hschindl + + + + + + + + + + + + + + + + + + + + + +7419 + +TbTimewalkMonitor.cpp +file + + + + +2016-05-02T14:11:48.000000Z +572b3086a01e101920e188654d8b560e +2015-12-02T13:34:23.155536Z +198560 +tevans + + + + + + + + + + + + + + + + + + + + + +9133 + +TbEffPur.cpp +file + + + + +2016-05-02T14:11:48.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(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 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 + +// 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("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) <GetEfficiency(0) << " + " << m_purs->GetEfficiencyErrorUp(0) <<" - "<< m_purs->GetEfficiencyErrorLow(0) <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; ixAxis().bins(); i++) { + for (int j=0; jyAxis().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; iWrite(); +// //m_effHitmapInterPixelVsSizes[i]->CreateHistogram()->Write(); +// } + f->Close(); + return TbAlgorithm::finalize(); +} + + +//============================================================================= +// Main execution +//============================================================================= +StatusCode TbEffPur::execute() +{ + m_nEvent++; + + m_tracks = getIfExists(m_trackLocation); + //m_vertices = getIfExists(m_vertexLocation); + m_clusters = getIfExists(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 * cutClusters = new std::vector(); + std::vector 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(cutTracks.size(), false); + //std::cout<<"Fraction tracks not veto'd: "<size()/(1.0*nClustersPreVeto)<<"\tEvent: "<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()< * cutClusters, + std::vector * cutTracks) +{ + // Gather all cluster times (over all planes) and sort it ___________________ + std::vector allClusterTimes; + for (unsigned int i=0; i(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 tGapCenters; + tGapCenters.push_back(0); + for (std::vector::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::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_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 * cutTracks, + std::vector * cutClusters) +{ + for (std::vector::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::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::iterator itrack = cutTracks->begin(); + itrack != cutTracks->end(); itrack++) { + for (std::vector::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()<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 * cutClusters, + std::vector * cutTracks) +{ + for (LHCb::TbTrack* track : *m_tracks) cutTracks->push_back(track); + for (std::vector::iterator iClust = m_clusters->begin(); + iClust != m_clusters->end(); iClust++) cutClusters->push_back(*iClust); +} + + +//============================================================================= +// +//============================================================================= +void TbEffPur::fillTrackClusters(std::vector * cutClusters, + std::vector * 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!"<htime() > tlow && cluster->htime() < tup) { + cutClusters->push_back(cluster); + m_vetoClustersHitmap->fill(cluster->x(), cluster->y()); + } + } +} + + +//============================================================================= +// Global cuts +//============================================================================= +void TbEffPur::trackClusters(std::vector * cutClusters, + std::vector * cutTracks) +{ + for (std::vector::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::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 (radialDistancehtime() - (*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()< 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; isize(); 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; ilocalToGlobal(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 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 * 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 * cutClusters, + std::vector * 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 * cutClusters, + std::vector * cutTracks); + void correlateRemains(std::vector * cutTracks, + std::vector * cutClusters); + void fillTrackClusters(std::vector * cutClusters, + std::vector * cutTracks, double tlow, double tup); + void fillAllTrackClusters(std::vector * cutClusters, + std::vector * 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: "<GetEfficiency(1)<<"\t ±"<GetEfficiencyErrorLow(1)<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: "<GetName()<(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 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()<htime()< 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!"< 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(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(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 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;iGetNbinsX();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(m_trackLocation); + if (!tracks) return StatusCode::SUCCESS; + for (const LHCb::TbTrack* track : *tracks) { + // info() << track << endmsg; + const SmartRefVector& 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& 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(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 m_timewalk; + std::vector m_timewalkOneHit; + std::vector m_timewalkTwoHit; + std::vector m_timewalkQ; + std::vector m_dtDist; + std::vector m_cDist; + + std::vector m_space; + std::vector m_dt; + std::vector m_LRSYNC; + + std::vector m_UDSYNC; + std::vector m_quad; + + std::vector m_inscol; + std::vector m_interscol; + + std::vector m_twd; + std::vector m_twdQ; + std::vector m_twdQL; + std::vector m_twdQR; + std::vector m_spd2D; + + std::vector m_twdL; + std::vector 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 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("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(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()); + + 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 m_index; + NTuple::Item m_matched; + NTuple::Item m_common; + NTuple::Array m_vtxX; + NTuple::Array m_vtxY; + NTuple::Array 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& 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(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 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 + +// 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("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) <GetEfficiency(0) << " + " << m_purs->GetEfficiencyErrorUp(0) <<" - "<< m_purs->GetEfficiencyErrorLow(0) <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; ixAxis().bins(); i++) { + for (int j=0; jyAxis().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; iWrite(); +// //m_effHitmapInterPixelVsSizes[i]->CreateHistogram()->Write(); +// } + f->Close(); + return TbAlgorithm::finalize(); +} + + +//============================================================================= +// Main execution +//============================================================================= +StatusCode TbEffPur::execute() +{ + m_nEvent++; + + m_tracks = getIfExists(m_trackLocation); + //m_vertices = getIfExists(m_vertexLocation); + m_clusters = getIfExists(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 * cutClusters = new std::vector(); + std::vector 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(cutTracks.size(), false); + //std::cout<<"Fraction tracks not veto'd: "<size()/(1.0*nClustersPreVeto)<<"\tEvent: "<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()< * cutClusters, + std::vector * cutTracks) +{ + // Gather all cluster times (over all planes) and sort it ___________________ + std::vector allClusterTimes; + for (unsigned int i=0; i(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 tGapCenters; + tGapCenters.push_back(0); + for (std::vector::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::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_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 * cutTracks, + std::vector * cutClusters) +{ + for (std::vector::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::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::iterator itrack = cutTracks->begin(); + itrack != cutTracks->end(); itrack++) { + for (std::vector::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()<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 * cutClusters, + std::vector * cutTracks) +{ + for (LHCb::TbTrack* track : *m_tracks) cutTracks->push_back(track); + for (std::vector::iterator iClust = m_clusters->begin(); + iClust != m_clusters->end(); iClust++) cutClusters->push_back(*iClust); +} + + +//============================================================================= +// +//============================================================================= +void TbEffPur::fillTrackClusters(std::vector * cutClusters, + std::vector * 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!"<htime() > tlow && cluster->htime() < tup) { + cutClusters->push_back(cluster); + m_vetoClustersHitmap->fill(cluster->x(), cluster->y()); + } + } +} + + +//============================================================================= +// Global cuts +//============================================================================= +void TbEffPur::trackClusters(std::vector * cutClusters, + std::vector * cutTracks) +{ + for (std::vector::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::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 (radialDistancehtime() - (*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()< 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; isize(); 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; ilocalToGlobal(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 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 * 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 * cutClusters, + std::vector * 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 * cutClusters, + std::vector * cutTracks); + void correlateRemains(std::vector * cutTracks, + std::vector * cutClusters); + void fillTrackClusters(std::vector * cutClusters, + std::vector * cutTracks, double tlow, double tup); + void fillAllTrackClusters(std::vector * cutClusters, + std::vector * 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: "<GetEfficiency(1)<<"\t ±"<GetEfficiencyErrorLow(1)<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: "<GetName()<(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 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()<htime()< 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!"< 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(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(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 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;iGetNbinsX();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(m_trackLocation); + if (!tracks) return StatusCode::SUCCESS; + for (const LHCb::TbTrack* track : *tracks) { + // info() << track << endmsg; + const SmartRefVector& 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& 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(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 m_timewalk; + std::vector m_timewalkOneHit; + std::vector m_timewalkTwoHit; + std::vector m_timewalkQ; + std::vector m_dtDist; + std::vector m_cDist; + + std::vector m_space; + std::vector m_dt; + std::vector m_LRSYNC; + + std::vector m_UDSYNC; + std::vector m_quad; + + std::vector m_inscol; + std::vector m_interscol; + + std::vector m_twd; + std::vector m_twdQ; + std::vector m_twdQL; + std::vector m_twdQR; + std::vector m_spd2D; + + std::vector m_twdL; + std::vector 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 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("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(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()); + + 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 m_index; + NTuple::Item m_matched; + NTuple::Item m_common; + NTuple::Array m_vtxX; + NTuple::Array m_vtxY; + NTuple::Array 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& 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..cb9f03a --- /dev/null +++ b/TbEvent/.svn/entries @@ -0,0 +1,80 @@ +10 + +dir +205620 +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-02T14:11:47.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..3603605 --- /dev/null +++ b/TbEvent/Event/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +205620 +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-02T14:11:45.000000Z +2fae4ace705051d585d9682d3ef40688 +2016-02-14T10:34:45.226731Z +201498 +hschindl + + + + + + + + + + + + + + + + + + + + + +876 + +TbKalmanNode.h +file + + + + +2016-05-02T14:11:45.000000Z +14e3b9e0815a43b8bf5c2154e568f4ed +2015-03-16T20:41:44.561223Z +185530 +hschindl + + + + + + + + + + + + + + + + + + + + + +6502 + +TbKalmanPixelMeasurement.h +file + + + + +2016-05-02T14:11:45.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(*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& 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 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(*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& 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 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..f5a801f --- /dev/null +++ b/TbEvent/cmt/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:46.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..1d2b12e --- /dev/null +++ b/TbEvent/dict/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:46.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..58a465e --- /dev/null +++ b/TbEvent/doc/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +205620 +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-02T14:11:46.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 to std::vector. + - 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 to std::vector. + - 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..b759474 --- /dev/null +++ b/TbEvent/src/.svn/entries @@ -0,0 +1,266 @@ +10 + +dir +205620 +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-02T14:11:47.000000Z +d08e3a578bc56780f73136ef63e4dcb0 +2016-02-14T10:34:45.226731Z +201498 +hschindl + + + + + + + + + + + + + + + + + + + + + +6320 + +TbKalmanNode.cpp +file + + + + +2016-05-02T14:11:47.000000Z +9ab06b2fb44f39bc95290768abbec534 +2016-02-14T10:34:45.226731Z +201498 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +10541 + +TbKalmanPixelMeasurement.cpp +file + + + + +2016-05-02T14:11:47.000000Z +479aff0b28b1dc77e5ab6f9f7b1e88d6 +2016-02-14T10:34:45.226731Z +201498 +hschindl + + + + + + + + + + + + + + + + + + + + + +2742 + +ChiSquare.cpp +file + + + + +2016-05-02T14:11:47.000000Z +b4e5ff6ad6ad890c9c407cadbaa40639 +2015-03-16T20:41:44.561223Z +185530 +hschindl + + + + + + + + + + + + + + + + + + + + + +327 + +TbState.cpp +file + + + + +2016-05-02T14:11:47.000000Z +20596b0ee888875a177e44edaa2abb10 +2014-05-24T14:29:04.255487Z +173162 +hschindl + + + + + + + + + + + + + + + + + + + + + +665 + +TbCluster.cpp +file + + + + +2016-05-02T14:11:47.000000Z +e774b6db1aa0f57fb253e04ff09af1e1 +2014-12-28T21:37:52.040452Z +182079 +hschindl + + + + + + + + + + + + + + + + + + + + + +518 + +TbTrack.cpp +file + + + + +2016-05-02T14:11:47.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(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(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(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 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(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(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(), + 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(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(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(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 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(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(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(), + 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..d0d3cd2 --- /dev/null +++ b/TbEvent/xml/.svn/entries @@ -0,0 +1,303 @@ +10 + +dir +205620 +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-02T14:11:44.000000Z +87e31bd2fe0a51c78866b895799e0729 +2014-11-23T16:26:09.716773Z +180600 +dsaunder + + + + + + + + + + + + + + + + + + + + + +1360 + +ChiSquare.xml +file + + + + +2016-05-02T14:11:44.000000Z +83522e27c0212db544259ea577bafb6e +2014-10-20T12:11:38.986809Z +179152 +hschindl + + + + + + + + + + + + + + + + + + + + + +2240 + +TbState.xml +file + + + + +2016-05-02T14:11:44.000000Z +c4572572817b9e20e8571d25487e11da +2015-03-24T11:06:24.702813Z +185837 +hschindl + + + + + + + + + + + + + + + + + + + + + +6699 + +TbCluster.xml +file + + + + +2016-05-02T14:11:44.000000Z +d0e1b945b09bb490fc894e08e2e54eaa +2016-02-04T17:03:58.484591Z +200901 +hschindl + + + + + + + + + + + + + + + + + + + + + +3759 + +TbTrigger.xml +file + + + + +2016-05-02T14:11:44.000000Z +730843cce7e54d7273021bf037aa4998 +2014-11-02T12:09:43.753299Z +179695 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +1802 + +gdd.dtd +file + + + + +2016-05-02T14:11:44.000000Z +f30759bfd18065f36d66ad486065f567 +2014-03-31T17:37:58.454693Z +170762 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +10369 + +lcgdict +dir + +TbHit.xml +file + + + + +2016-05-02T14:11:44.000000Z +a79f3df4fffc5c967050c8f3c4038ae8 +2016-01-28T20:16:13.414912Z +200589 +hschindl +has-props + + + + + + + + + + + + + + + + + + + + +2319 + +TbTrack.xml +file + + + + +2016-05-02T14:11:44.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 @@ + + + + + + + + + + + + + + + + + + return m_nDoF>0 ? m_chi2/m_nDoF : 0 ; + + + + + + + + + + m_chi2 += rhs.m_chi2 ; + m_nDoF += rhs.m_nDoF ; + return *this ; + + + + + + + m_chi2 -= rhs.m_chi2 ; + m_nDoF -= rhs.m_nDoF ; + return *this ; + + + + + + + ChiSquare rc = *this ; + rc += rhs ; + return rc ; + + + + + + + ChiSquare rc = *this ; + rc -= rhs ; + return rc ; + + + + + + + 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 @@ + + + + + + + + + &KeyedObject; + + + + + m_hits.reserve(10); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + return m_hits.size(); + + + + + + m_associated = tracked; + for (auto it = m_hits.begin(), end = m_hits.end(); it != end; ++it) { + (*it)->setAssociated(tracked); + } + + + + + + 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 @@ + + + + + + + + + + &KeyedContainer; + + + + + + + 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(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + &StlPtrVector; + + + + + + + + + + + + + + + + + + return m_covariance(0, 0); + + + + + + return m_covariance(1, 1); + + + + + + return m_covariance(2, 2); + + + + + + return m_covariance(3, 3); + + + + + + + + + return Gaudi::XYZPoint(m_parameters[0], m_parameters[1], m_z); + + + + + + return m_parameters[0]; + + + + + + return m_parameters[1]; + + + + + + return Gaudi::XYZVector(m_parameters[2], m_parameters[3], 1.); + + + + + + return m_parameters[2]; + + + + + + return m_parameters[3]; + + + + + + m_parameters[0] = value; + + + + + + m_parameters[1] = value; + + + + + + m_z = value; + + + + + + m_parameters[2] = value; + + + + + + m_parameters[3] = value; + + + + + + + + m_covariance = value; + + + + + + + os << "{ " + << "parameters: " << m_parameters << std::endl + << "z: " << m_z << std::endl + << " }"; + return os; + + + + + + + + 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 @@ + + + + + + + + + + + + + &KeyedObject; + + + + m_clusters.reserve(10); + m_triggers.reserve(10); + m_associatedClusters.reserve(10); + m_states.reserve(10); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + return m_chi2PerNdof * m_ndof; + + + + + + + + + + + + return m_clusters.size(); + + + + + + for (auto it = m_clusters.begin(), end = m_clusters.end(); it != end; ++it) { + (*it)->setAssociated(flag); + } + + + + + + 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 @@ + + + + + + + + + &KeyedContainer; + + + + m_plane = 0; + m_data = data; + m_time = 0xFFFFFFFFFFF & data; + m_counter = (data >> 44) & 0xFFF; + + + + + + m_plane = other->plane(); + m_data = other->data(); + m_time = other->time(); + m_counter = other->counter(); + m_htime = other->htime(); + m_associated = other->associated(); + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + &KeyedObject; + + + + + + + + + + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +