# Difference: TAlignmentManual (1 vs. 29)

#### Revision 292017-05-08 - LuciaGrillo

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 36 to 39
shell > .//run gaudirun.py

For example, a job on a 2012 sample, can be run with

>
>

Changed:
<
<
shell > .//run bash
>
>
shell > .//run bash --norc
shell > gaudirun.py $ESCHEROPTS/Escher-AlignHltD0.py$ESCHEROPTS/COLLISION12-Tests.py
>
>
(in order for this one to work a line containing "MaxNTHoles" has to be removed from TAlignement/python/TAlignment/TrackSelections.py)

This will essentially just run the reconstruction sequence starting from the raw data, accumulate the information relevant for alignment, and finally compute new constants and dump them to xml file in finalize.

Line: 86 to 90
shell > lb-dev Alignment HEAD --nightly lhcb-prerelease Today shell> make configure shell> make install
Changed:
<
<
shell > ./run gaudirun.py
>
>
shell > ./run gaudirun.py

# Snapshotting ONLINE database

Line: 95 to 98
shell > export CORAL_DBLOOKUP_PATH=/group/online/conddbserver/ shell > export CORAL_AUTH_PATH=/group/online/conddbserver shell > SetupProject LHCb
Changed:
<
<
shell > CondDBAdmin_MakeSnapshot.py -s 2015-01-01UTC --options /cvmfs/lhcb.cern.ch/lib/lhcb/DBASE/Det/SQLDDDB/v7r10/options/SQLDDDB-Oracle.py ONLINE sqlite_file:ONLINE-2015.db/ONLINE
>
>
shell > CondDBAdmin_MakeSnapshot.py -s 2015-01-01UTC --options /cvmfs/lhcb.cern.ch/lib/lhcb/DBASE/Det/SQLDDDB/v7r10/options/SQLDDDB-Oracle.py ONLINE sqlite_file:ONLINE-2015.db/ONLINE
You should then find a snapshot in a file called ONLINE-2015.db
Line: 348 to 347
# use anyof the methods above to fix (one of) the half frames in space
Changed:
<
<
-- WouterHulsbergen - 17-Dec-2009
>
>
-- WouterHulsbergen - 17-Dec-2009</verbatim>

 META TOPICMOVED by="wouter" date="1262620672" from="LHCb.TAlignmentManuel" to="LHCb.TAlignmentManual"

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 6 to 6
All alignment related code is combined in the 'Alignment' project. For running the TAlignment algorithm, the following packages are most relevant:
Changed:
<
<
• Alignment/Escher contains the option files for running alignment jobs
• Alignment/TAlignment contains the TAlignment code
• Alignment/AlignKernel
• Alignment/AlignmentInterfaces
• Alignment/AlignEvent
• Alignment/AlignSolvTools (this one gives problems with the installation)
• Alignment/AlignTrTools (this one gives problems with the installation)
>
>
• *Alignment/Escher contains the option files for running alignment jobs
• Alignment/TAlignment contains the Tracker Alignment code
• *Alignment/AlignmentDBVisualisationTool
• *Alignment/AlignmentMonitoring
• *Alignment/AlignTrTools
To set up a directory with the current latest version of the software do

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 83 to 83
shell > .//run bash shell > python /Alignment/AlignmentDBVisualizationTool/examples/TrackerAlignmentResults.py
>
>

# Run from the nightlies

shell > lb-dev Alignment HEAD --nightly lhcb-prerelease Today
shell> make configure
shell> make install
shell >  ./run gaudirun.py <opts> <data>

# Snapshotting ONLINE database

shell > source /sw/oracle/set_oraenv.sh

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 11 to 11

• Alignment/AlignKernel
• Alignment/AlignmentInterfaces
• Alignment/AlignEvent
>
>
• Alignment/AlignSolvTools (this one gives problems with the installation)
• Alignment/AlignTrTools (this one gives problems with the installation)
To set up a directory with the current latest version of the software do
>
>
shell> lb-dev Alignment vXrY shell> cd ./AlignmentDev_vXrY
Line: 38 to 41

shell > ./<AlignmentProjectDirectory>/run bash
shell > gaudirun.py $ESCHEROPTS/Escher-AlignHltD0.py$ESCHEROPTS/COLLISION12-Tests.py
>
>
(in order for this one to work a line containing "MaxNTHoles" has to be removed from TAlignement/python/TAlignment/TrackSelections.py)
This will essentially just run the reconstruction sequence starting from the raw data, accumulate the information relevant for alignment, and finally compute new constants and dump them to xml file in finalize.

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 80 to 80
shell > python /Alignment/AlignmentDBVisualizationTool/examples/TrackerAlignmentResults.py

# Snapshotting ONLINE database

Changed:
<
<

>
>
shell > source /sw/oracle/set_oraenv.sh shell > export CORAL_DBLOOKUP_PATH=/group/online/conddbserver/ shell > export CORAL_AUTH_PATH=/group/online/conddbserver shell > SetupProject LHCb shell > CondDBAdmin_MakeSnapshot.py -s 2015-01-01UTC --options /cvmfs/lhcb.cern.ch/lib/lhcb/DBASE/Det/SQLDDDB/v7r10/options/SQLDDDB-Oracle.py ONLINE sqlite_file:ONLINE-2015.db/ONLINE
Changed:
<
<
<\verbatim>
>
>
You should then find a snapshot in a file called ONLINE-2015.db

#### Revision 242016-01-26 - LuciaGrillo

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 78 to 74
(TODO: Set a default list of plots and use an option parser to set the input files)

Similarly, the alignlog.txt file from the alignment that stores information of all the output from the alignment job, can be analysed as a script and interactively by using a tool from Alignment/AlignmentDBVisualizationTool

>
>

shell > ./<AlignmentProjectDirectory>/run bash
Changed:
<
<
shell > python /Alignment/AlignmentDBVisualizationTool/examples/TrackerAlignmentResults.py
>
>
shell > python /Alignment/AlignmentDBVisualizationTool/examples/TrackerAlignmentResults.py

# Snapshotting ONLINE database

shell > source /sw/oracle/set_oraenv.sh
shell > export CORAL_DBLOOKUP_PATH=/group/online/conddbserver/
shell > export CORAL_AUTH_PATH=/group/online/conddbserver
shell > SetupProject LHCb
shell > CondDBAdmin_MakeSnapshot.py -s 2015-01-01UTC --options /cvmfs/lhcb.cern.ch/lib/lhcb/DBASE/Det/SQLDDDB/v7r10/options/SQLDDDB-Oracle.py ONLINE sqlite_file:ONLINE-2015.db/ONLINE
<\verbatim>

You should then find a snapshot in a file called ONLINE-2015.db

# Step 3. Detailed configuration

Line: 331 to 338
# use anyof the methods above to fix (one of) the half frames in space
Changed:
<
<
-- WouterHulsbergen - 17-Dec-2009
>
>
-- WouterHulsbergen - 17-Dec-2009

 META TOPICMOVED by="wouter" date="1262620672" from="LHCb.TAlignmentManuel" to="LHCb.TAlignmentManual"

#### Revision 232016-01-25 - MaurizioMartinelli

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 11 to 11

• Alignment/AlignKernel
• Alignment/AlignmentInterfaces
• Alignment/AlignEvent
>
>
To set up a directory with the current latest version of the software do
>
>

shell> lb-dev Alignment vXrY
Changed:
<
<
shell> cd ./AlignmentDev_vXrY shell> getpack Alignment/Escher HEAD shell> getpack Alignment/TAlignment HEAD shell> getpack Alignment/AlignKernel HEAD shell> getpack Alignment/AlignmentInterfaces HEAD shell> getpack Alignment/AlignEvent HEAD shell> make purge shell> make shell> ./run bash
>
>
shell> cd ./AlignmentDev_vXrY

To compile with CMake, simply

shell> make configure
shell> make install

Whenever a new package is added to the project directory, make configure needs to be called before compiling with make install. If a package is removed, make purge is needed before re-configuring and compiling the project.

# Step 2. Running an alignment job

Changed:
<
<
First set up a release directory as above. Then go to the 'job' directory in the Escher package and run like a DaVinci or Brunel like application:
>
>
Once the release is setup, in whatever directory is possible to run an alignment job with the following command:

Changed:
<
<
shell> cd $ESCHERROOT/job shell> gaudirun.py$ESCHEROPTS/AlignCollisions2010.py $ESCHEROPTS/2010-Collisions.py > > shell > .//run gaudirun.py For example, a job on a 2012 sample, can be run with shell > ./<AlignmentProjectDirectory>/run bash shell > gaudirun.py$ESCHEROPTS/Escher-AlignHltD0.py ESCHEROPTS/COLLISION12-Tests.py This will essentially just run the reconstruction sequence starting from the raw data, accumulate the information relevant for alignment, and finally compute new constants and dump them to xml file in finalize. Line: 48 to 58 * gaudipariter.py -n [number of iterations] -e [number of events] -p [number of cores] runs several iterations splitting the processing over different cores. It actually just creates subdirectories for each iteration, runs gaudipar.py in that subdirectory, creates a new databases when the job is finished and uses that database as input to the next iteration. Changed: < < The alignment database used as input can be specified in a job option file, but if you use gaudipariter.py then that is not a great idea, since it would simply run the same alignment n times. Therefore, to specify an input database use the -d option. You can specify multiple input databases. For example, to run the alignment of all tracking detectors on a recent 2010 run starting from the v2.3 database, use: > > The alignment database used as input can be specified in a job option file, but if you use gaudipariter.py then that is not a great idea, since it would simply run the same alignment n times. Therefore, to specify an input database use the -d option. You can specify multiple input databases. For example, to run the alignment of all tracking detectors on a recent 2012 run starting from the v2.3 database, use: shell> gaudipariter.py -e 50000 -n 10 -p 8\ Changed: < < -d /afs/cern.ch/user/w/wouter/public/AlignDB/v2.3.dbESCHEROPTS/AlignCollisions2010.py \ $ESCHEROPTS/2010-Collisions.py > > -d /afs/cern.ch/user/m/mamartin/public/AlignDB/v6.2series.db$ESCHEROPTS/Escher-AlignHltD0.py \ ESCHEROPTS/COLLISION12-Tests.py \ For each iteration it creates a directory called Iter[number] which contains among others a file 'Alignment.db' with the output alignment database. It also contains a file histograms.root which contains all histograms. Added: > > The most relevant histograms for alignment can be plot with the AlignmentMonitoring package. Since it is not yet in the released software, one needs to download it (getpack Alignment/AlignmentMonitoring head) and run the script shell > ./<AlignmentProjectDirectory>/run bash shell > pythonALIGNMENTMONITORINGROOT/examples/TrackingMonitoringPlots.py

At the moment, the list of histograms files to run the script on is hardcoded, therefore one needs to copy it to his working directory and modify it accordingly. (TODO: Set a default list of plots and use an option parser to set the input files)

Similarly, the alignlog.txt file from the alignment that stores information of all the output from the alignment job, can be analysed as a script and interactively by using a tool from Alignment/AlignmentDBVisualizationTool

shell > ./<AlignmentProjectDirectory>/run bash
shell > python <AlignmentProjectDirectory>/Alignment/AlignmentDBVisualizationTool/examples/TrackerAlignmentResults.py

# Step 3. Detailed configuration

The TAlignment framework is configured using the TAlignment configurable. The name is historical: the original application was for the alignment of OT and IT. (The functionality was never limited to these systems though.) The easiest way to use the software is to follow examples. There are several example job option files in the ESCHERROOT/options directory. In the following we will try to explain in a bit more detail how the most important parts of the confuguration actually work. Together with the Escher examples, this should allow anybody to configure the alignment algorithm. Line: 79 to 102 from Configurables import TAlignment velorighthalf = "/dd/Structure/LHCb/BeforeMagnetRegion/Velo/VeloRight : Tx Ty Tz Rx Ry Rz" Changed: < < TAlignment().ElementsToAlign = [ velorighthalf ] > > TAlignment().ElementsToAlign = [ velorighthalf ] The strings between the parameters can be omitted, so you could use "TxTyTzRxRyRz" for the last part. (Note however, the inconsistency with the lagrange constarints below: in that case the spaces are essential. So, it is better to leave them in for now.) Line: 85 to 107 The strings between the parameters can be omitted, so you could use "TxTyTzRxRyRz" for the last part. (Note however, the inconsistency with the lagrange constarints below: in that case the spaces are essential. So, it is better to leave them in for now.) To simplify the configuration a syntax has been developed that makes use of patterns: rather than specifying each alignable explicitly one uses a 'regular expression'. For example, to align for all velo modules in Tx and Ty, one could do Added: > > velosensors = "/dd/Structure/LHCb/BeforeMagnetRegion/Velo/Velo(Right|Left)/Module.{1,2} : Tx Ty" Changed: < < TAlignment().ElementsToAlign = [ velosensors ] > > TAlignment().ElementsToAlign = [ velosensors ] The regular expressions work like the standard Perl (?) regular expressions. We use boost_regex for this. There is one very important caveat here: For now you need to specify every slash ('/') in the regular expression. (You could not specify the Velo modules by using e.g. ".*/Velo.*/Module.{2}".). The reason for this is performance: Rather than matching all elements in LHCb against the string, the string is matched 'level-by-level': We first find /dd/Structure/LHCb/BeforeMagnetRegion/Velo and then loop over all its daughters to find those that match "Velo(Right|Left)", etc. without this trick, we would need to decode the entire LHCb geometry in the initialization of the alignment. Line: 97 to 119 The geometry of the OT is also arranged such that (unfortunately) the hierarchy doesn't exactly correspond to the way the detector was built. In particular there is no concept of a C-frame in the OT geometry. To allow for the alignment of C-frames, we group all associated 'quarter' elements together. To 'update' the C-frame alignment, the constants of all these quarters are changed by the same amount in the alignment 'condition' in the database. To specify a group of elements, we add prepend the strings introduced above with another one that represents the group name, the name of the alignable to which all elements belong. For example, to define the X translation of the first OT C-frame, one would use Added: > > Changed: < < TAlignment().ElementsToAlign.append( "OT/T1X1UASide : /dd/Structure/LHCb/AfterMagnetRegion/T/OT/T1/(X1|U)/Q(1|3) : Tx" ) > > TAlignment().ElementsToAlign.append( "OT/T1X1UASide : /dd/Structure/LHCb/AfterMagnetRegion/T/OT/T1/(X1|U)/Q(1|3) : Tx" ) Note that the regular expression has a different purpose here: it selects all elements that belong to the OT/T1X1UASide C-frame. To specify the alignment constants for all C-frames, you would still need to define each of them separately. (You cannot sue a regular expression for the name.) Line: 110 to 133 elements.VeloRModules("Tx Ty") elements.VeloPhiModules("Tx Ty") elements.OTCFrames("Tx Ty Tz") Changed: < < TAlignment().ElementsToAlign = list( elements ) > > TAlignment().ElementsToAlign = list( elements ) You can find the available list in theTALIGNMENTROOT/python/TAlignment/Alignables.py source code. If your favourite alignable isn't there, it should just be added.
Line: 116 to 138
You can find the available list in the TALIGNMENTROOT/python/TAlignment/Alignables.py source code. If your favourite alignable isn't there, it should just be added. By default all alignment constants are defined in the local frame of the detector element associated to the Alignable. For groups an average of the frames of the elements is taken. If for some reason you prefer all parameters to be defined in the global frame, you can modify the UseLocalFrame field of the TAlignment configureble: Added: > > Changed: < < TAlignment().UseLocalFrame = False > > TAlignment().UseLocalFrame = False ## Using Lagrange constraints Line: 145 to 167 # specify the list of constraints constraints = [ "Tx", "Ty", "Tz" ] Changed: < < TAlignment().Constraints = constraints > > TAlignment().Constraints = constraints However, much more fine grained control can be obtained by specifying regular expressions that define the list of elements to which the constraint must be applied. For example, to fix only the average translation of all Velo-A, you can do Added: > > Changed: < < constraints += [ "VeloA : .*?/VeloRight.*? : Tx Ty Tz"] > > constraints += [ "VeloA : .*?/VeloRight.*? : Tx Ty Tz"] Note: Line: 164 to 185 The regular expression can also be replaced by the name of an alignable: this is useful if you want to constrain just a single element. Some of the constraints have two modes of operation. By default the change of the linear combination of parameters is constraint to zero. However, by adding an extra argument 'total' you can also constrain the difference with respect to nominal of that combination of parameters. For example, the following Deleted: < < Changed: < < constraints += [ "Velo : .*?/Velo(Right|Left).*? : Tx Ty Tz : total"] > > constraints += [ "Velo : .*?/Velo(Right|Left).*? : Tx Ty Tz : total"] will constrain the average position of the two velo halves exactly at the origin. If you replace 'total' by 'delta' you get the default behaviour: in that case the average position of the velo is not constraint to zero, but only the change in the average position (with respect to the input alignment) is fixed to zero. Line: 186 to 205 Consequently, survey constraints are of limited value in tracking alignment. Therefore, in what follows a pragmatic approach has been taken, with as the most important limitation that no correlations can be specified. (Think about what this means: in the example above the OT module survey cannot be used.) To still allow for more precise 'local' than 'global' information, all constraints are specified in the local frame of the alignment element, so with respect to its mother. That wouldn't help if it could not be combined with another powerful feature of the alignment sofware: one can align the detector at different levels of granularity simultaneously. Survey constraints can be specified in two ways. First, we can hardcode the 6 parameters with errors as follows: Deleted: < < surveyconstraints = [ ""OT/T3X1UASide : -1.52 -1.25 0.0 0.0 0.0 0.0 : 0.5 0.5 0.5 0.0001 0.0001 0.0001"] Changed: < < TAlignment().SurveyConstraints = surveyconstraints > > TAlignment().SurveyConstraints = surveyconstraints Like for the Lagrange constraints, the colon act as a token. Unlike the Lagrange constraints, the first string is not the name of the constraint, but the name of the element. The first set of 6 numbers are the parameters for the 6 degrees of freedom. The second set of 6 numbers are the uncertainties. (So, in this case the position coordinates have an uncertainty of 0.5 mm, while the rotation uncertainties are 0.1 mrad.) Line: 195 to 212 Like for the Lagrange constraints, the colon act as a token. Unlike the Lagrange constraints, the first string is not the name of the constraint, but the name of the element. The first set of 6 numbers are the parameters for the 6 degrees of freedom. The second set of 6 numbers are the uncertainties. (So, in this case the position coordinates have an uncertainty of 0.5 mm, while the rotation uncertainties are 0.1 mrad.) A regular expression can be used to add constraints for more than one element at a time. For example, to fix all OT modules to their local nominal position, you can do Deleted: < < Changed: < < surveyconstraints = [ "/.*?/OT/.*?/M. : 0 0 0 0 0 0 : 0.1 0.1 0.1 0.0001 0.0001 0.0001" ] > > surveyconstraints = [ "/.*?/OT/.*?/M. : 0 0 0 0 0 0 : 0.1 0.1 0.1 0.0001 0.0001 0.0001" ] This constraint means: fix the position of a module to its nominal value in the local frame with an uncertainty of 100 micron. Line: 203 to 218 This constraint means: fix the position of a module to its nominal value in the local frame with an uncertainty of 100 micron. Now, you may wonder why this is useful. Consider the following scenario: We want to align the modules within a C-frame in X. However, at the same time we want to align the C-frame itself as a global structure in X and Y. Naively, we could just try the following: Added: > > elements.OTCFrames("TxTy") Changed: < < elements.OTModules("Tx") > > elements.OTModules("Tx") However, we clearly have created a problem now: There is a redundancy in the alignment degrees of freedom because the C-frame movement is just an average movement of the modules. The solution is to add a chisquare term for the position of the modules inside the C-frame: Added: > > elements.OTCFrames("TxTy") elements.OTModules("Tx" Line: 212 to 228 elements.OTCFrames("TxTy") elements.OTModules("Tx" Changed: < < surveyconstraints = [ "/.*?/OT/.*?/M. : 0 0 0 0 0 0 : 0.1 0.1 0.1 0.0001 0.0001 0.0001" ] > > surveyconstraints = [ "/.*?/OT/.*?/M. : 0 0 0 0 0 0 : 0.1 0.1 0.1 0.0001 0.0001 0.0001" ] The uncertainty of 0.1 mm in the constraints for the modules is large enough that it will not really affect the module position itself: modules can still move freely inside the C-frame. However, what will effectively happen now is that the C-frame is positioned such that the average deviation of the modules from their nominal geometry is minimal. The alignment problem is perfectly constrained despite the redundancy in parameter. So, chisquare constraints allow to align the detector at different levels of granularity simultaneously. Line: 218 to 233 The uncertainty of 0.1 mm in the constraints for the modules is large enough that it will not really affect the module position itself: modules can still move freely inside the C-frame. However, what will effectively happen now is that the C-frame is positioned such that the average deviation of the modules from their nominal geometry is minimal. The alignment problem is perfectly constrained despite the redundancy in parameter. So, chisquare constraints allow to align the detector at different levels of granularity simultaneously. More useful than specifying constraints individually as above is to use a 'survey xml' as the reference point. For this, you can simply add the path to the file to the list of constraints Deleted: < < Changed: < < surveyconstraints += ["myfile.xml"] > > surveyconstraints += ["myfile.xml"] The matching to the alignable element is performed by matching the name of the condition. The uncertainties assigned to the parameters can only be specified by talking directly to the AlignChisquareConstraintTool. For example, the uncertainties of all TT conditions are set with: Deleted: < < from Configurables import Al__AlignChisqConstraintTool as AlignChisqConstraintTool AlignChisqConstraintTool().XmlUncertainties += [ Line: 232 to 244 "TT. : 0.1 0.1 0.1 0.0005 0.0005 0.0005", "TT..Layer : 0.1 0.1 0.1 0.0005 0.0005 0.0005", "TT..Layer.Side : 0.1 0.1 0.1 0.0005 0.0005 0.0005", Changed: < < "TT..LayerR.Module.*? : 0.1 0.1 0.1 0.0005 0.0005 0.0005"] > > "TT..LayerR.Module.*? : 0.1 0.1 0.1 0.0005 0.0005 0.0005"] (The TT..LayerSide does not exist as a condition, but it exists as an Alignable.) Line: 243 to 253 from SurveyConstraints import * surveyconstraints = SurveyConstraints() surveyconstraints.All() Changed: < < TAlignment().SurveyConstraints = list( surveyconstraints ) > > TAlignment().SurveyConstraints = list( surveyconstraints ) you'll get the survey constraints for every parameter that you align for. (Watch for warning in the log file: if the survey information is missing, it will actually tell you.) For IT and TT it uses the survey xml, which is collected in the Alignment/TAlignment/surveyxml directory. Line: 253 to 262 You may have seen that your alignment spits out a file called 'alignderivatives.dat'. In this file the accumulated chisquare derivatives are persisted. You can take this file feed it to the 'AlignUpdateTool' and it will recompute the alignment exactly as it would if you would process the events first. It is now possible to use the alignment result obtained with a different as constraint. This is for example useful if you want to combine information from field-off and field-on data. If 'alignderivativesfieldoff.dat' is the file that you from the last iteration of your magnet-off alignment, you simply 'add' this file as input to your magnet on alignment: Added: > > Changed: < < AlignAlgorithm("Alignment").InputDataFiles = [ 'alignderivativesfieldoff.dat' ] > > AlignAlgorithm("Alignment").InputDataFiles = [ 'alignderivativesfieldoff.dat' ] When the input file is added to information that from the evetns that you process, it is corrected for intermediate alignments. That means that (to first order) it is not necessary that you create the alignderivativesfieldoff.dat file with the same input alignment as that you process your new job with. (Without this feature you would need to rerun the field-off alignment for every iteration as well.) Line: 266 to 275 The derivatives are computed with respect to a certain version of the geometry. The Gaudi framework (more precisely the UpdateManagerSvc) uses the geometry corresponding to a particular time. The leads to two different problems. First, the UpdateManagerSvc by default initializes the geometry using the current time. That could mean for example that if the velo is 'now' open (because we are not taking data), but if it was closed at the time of running, then the alignment derivatives will be computed with respect to an 'open' velo. This problem can be partially solved by specifying the time used at initialization: Added: > > # specify the time of the 'first' event in ns Changed: < < EventClockSvc().InitialTime = 1260350949785664000 > > EventClockSvc().InitialTime = 1260350949785664000 Second, during event processing the UpdateMnagerSvc will update the geometry according to the event time. Consequently, it could happen that the geometry changes while you are processing evens. The alignment software is currently not protected against such geometry changes. Line: 288 to 296 surveyconstraints.IT() # remember to 'cast' to a list when configuraing TAlignment: TAlignment().ElementsToAlign = list(elements) Changed: < < TAlignment().SurveyConstraints = list(surveyconstraints) > > TAlignment().SurveyConstraints = list(surveyconstraints) ### Fixing Velo modules in a Velo half with exactly zero shearing Deleted: < < # align modules in Tx and Ty elements.VeloModules("Tx Ty") Line: 310 to 316 # constraints.append( "VeloGlobal : .*?Velo(Right|Left) : Tx Ty") # or you could fix the change in the position of the primary vertex Changed: < < constraints.append( "PVx PVy") > > constraints.append( "PVx PVy") ### Fixing Velo modules in a Velo half using the nominal geometry as 'survey' Deleted: < < elements.VeloModules("Tx Ty") elements.VeloHalves("Rx Ry Tx Ty") Line: 325 to 329 surveyconstraints.append(".*?Velo(Left|Right)/Module.{1,2} : Tx : 0 +/- 0.02") surveyconstraints.append(".*?Velo(Left|Right)/Module.{1,2} : Ty : 0 +/- 0.02") Changed: < < # use anyof the methods above to fix (one of) the half frames in space > > # use anyof the methods above to fix (one of) the half frames in space -- WouterHulsbergen - 17-Dec-2009 #### Revision 222016-01-25 - FrancescaDordei Line: 1 to 1  META TOPICPARENT name="LHCbDetectorAlignment" Line: 8 to 8 • Alignment/Escher contains the option files for running alignment jobs • Alignment/TAlignment contains the TAlignment code Added: > > • Alignment/AlignKernel • Alignment/AlignmentInterfaces • Alignment/AlignEvent To set up a directory with the current latest version of the software do Changed: < < shell> setenvAlignment shell> SetupAlignment > > shell> lb-dev Alignment vXrY shell> cd ./AlignmentDev_vXrY shell> getpack Alignment/Escher HEAD shell> getpack Alignment/TAlignment HEAD Changed: < < shell> cd Alignment/Escher/cmt shell> source setup.[c]sh shell> cmt br cmt config shell> cmt br 'gmake -j' > > shell> getpack Alignment/AlignKernel HEAD shell> getpack Alignment/AlignmentInterfaces HEAD shell> getpack Alignment/AlignEvent HEAD shell> make purge shell> make shell> ./run bash Deleted: < < After setenvAlignment press enter to select the current latest version of the software. # Step 2. Running an alignment job First set up a release directory as above. Then go to the 'job' directory in the Escher package and run like a DaVinci or Brunel like application: #### Revision 212014-01-21 - JasonAndrews Line: 1 to 1  META TOPICPARENT name="LHCbDetectorAlignment" Line: 280 to 280 elements.ITBoxes("Tx Ty Rz") elements.ITLayers("Tx") elements.ITLadders("Tx") Changed: < < # now load te survey > > # now load the survey surveyconstraints = SurveyConstraints() surveyconstraints.IT() # remember to 'cast' to a list when configuraing TAlignment: #### Revision 202014-01-21 - JasonAndrews Line: 1 to 1  META TOPICPARENT name="LHCbDetectorAlignment" #### Revision 192014-01-20 - JasonAndrews Line: 1 to 1  META TOPICPARENT name="LHCbDetectorAlignment" Line: 38 to 37 • AlignMonitorSeq is a sequence that runs the same algorithms as the standard Brunel monitoring sequence and a few more. What is special about it is that if you run with the 'gaudiiter.py' script (see below), it actually clones the sequence such that you get monitoring histograms both for the first and the last iteration. • AlignAlgorithm/Alignment is the TAlignment algorithm: it takes as input a list of tracks and eventually vertices and accumulates the 'chisquare-derivatives' that are the input to the alignment update. • GaudiSequencer/WriteCondSeq contains the algorithms that write the xml in the 'finalize' stage of your gaudi job Changed: < < To make it possible to run iterations or split your event processing over the different cores of a machine, some scrits are setup that replace gaudirun.py. They currently reside in Escher/options but should actually be moved to Escher/scripts: > > To make it possible to run iterations or split your event processing over the different cores of a machine, some scrits are setup that replace gaudirun.py. They can be found in Escher/scripts: * gaudiiter.py -n [number of iterations] -e [number of events] = runs =n iterations of the alignment within a single gaudiapplication. The alignment updates are triggered at the end of each iteration by a gaudi 'incident'. Line: 56 to 54ESCHEROPTS/2010-Collisions.py
Changed:
<
<
For each iteration it creates a directory calles Iter[number] which contains among others a file 'Alignment.db' with the output alignment database. It also contains a file histograms.root which contains all histograms.
>
>
For each iteration it creates a directory called Iter[number] which contains among others a file 'Alignment.db' with the output alignment database. It also contains a file histograms.root which contains all histograms.

# Step 3. Detailed configuration

Line: 88 to 86
velosensors = "/dd/Structure/LHCb/BeforeMagnetRegion/Velo/Velo(Right|Left)/Module.{1,2} : Tx Ty" TAlignment().ElementsToAlign = [ velosensors ]
Changed:
<
<
The regular expressions work like the standard Perl (?) regular expressions. We use boost_regex for this. There is one very important caveat here: For now you need to specify every slash ('/') in the regular expression. (You could not specify the Velo modules by using e.g. ".*/Velo.*/Module.{2}".). The reason for this is performance: Rather than matching all elements in LHCb against the string, the string is matched 'level-by-level': We first find /dd/Structure/LHCb/BeforeMagnetRegion/Velo and then loop over all its daughters to find those that match "Velo(Right|Left)", etc. without this trick, we would need to decode the entire LHCb geometry in the initialization of the alignment.
>
>
The regular expressions work like the standard Perl (?) regular expressions. We use boost_regex for this. There is one very important caveat here: For now you need to specify every slash ('/') in the regular expression. (You could not specify the Velo modules by using e.g. ".*/Velo.*/Module.{2}".). The reason for this is performance: Rather than matching all elements in LHCb against the string, the string is matched 'level-by-level': We first find /dd/Structure/LHCb/BeforeMagnetRegion/Velo and then loop over all its daughters to find those that match "Velo(Right|Left)", etc. without this trick, we would need to decode the entire LHCb geometry in the initialization of the alignment.
We have now shown how to create alignables that correspond to a single detector element. All detector elements can be used provided that they have an alignment condition. (That holds for most of them.) In particular for the OT, it is important to specify alignables to correspond to a group of detector elements. For example, a physical OT module has two detector elements associated to it, one for the top and one for the bottom half. In the alignment we would like to treat these as a single object. Since the alignment parameters in the condition database are actually organized by elements, this will mean that the module constants appear twice in the database.
Line: 99 to 97

TAlignment().ElementsToAlign.append( "OT/T1X1UASide :  /dd/Structure/LHCb/AfterMagnetRegion/T/OT/T1/(X1|U)/Q(1|3) : Tx" )
>
>
Note that the regular expression has a different purpose here: it selects all elements that belong to the OT/T1X1UASide C-frame. To specify the alignment constants for all C-frames, you would still need to define each of them separately. (You cannot sue a regular expression for the name.)
Changed:
<
<
Because this is clearly still too complicated a python class Alignables was written that holds all expressions for the most commonly used alignables. E.g. to align all Velo modules and OT C-frames, you would do:
>
>
Because this is clearly still too complicated, a python class Alignables was written that holds all expressions for the most commonly used alignables. E.g. to align all Velo modules and OT C-frames, you would do:

from TAlignment.Alignables import Alignables
elements = Alignables()
Line: 151 to 149

constraints += [ "VeloA : .*?/VeloRight.*? : Tx Ty Tz"]
>
>
Note:
>
>

• the string consists of 3 parts seperated by colons
• the first part is the 'name' of the constraint. This name must be unique.
Changed:
<
<
• the second part is the regular expression. In this case it will select all alignable elements that contain '/VeloRight' in the name of any associated detector element.
>
>
• the second part is the regular expression. In this case it will select all alignable elements that contain '/VeloRight' in the name of any associated detector element.

• the third part are the constraints. These must be seperated by a space.
Deleted:
<
<
In the log file the constraints will now appear as 'VeloATx', 'VeloATy', and 'VeloATz'.
Changed:
<
<
The regular expression can also be replaced by the name of an alignable: this is useful if you want to constrain just a single element.
>
>
The regular expression can also be replaced by the name of an alignable: this is useful if you want to constrain just a single element.
Some of the constraints have two modes of operation. By default the change of the linear combination of parameters is constraint to zero. However, by adding an extra argument 'total' you can also constrain the difference with respect to nominal of that combination of parameters. For example, the following
Line: 221 to 220
surveyconstraints += ["myfile.xml"]
Changed:
<
<
The matching to the alignable element is performed by matching the name of the condition. The uncertainties assigned to the parameters can only be specified by talking directly to the AlignChisquareConstraintTool. For example, the uncertainties of all TT conditions are set with:
>
>
The matching to the alignable element is performed by matching the name of the condition. The uncertainties assigned to the parameters can only be specified by talking directly to the AlignChisquareConstraintTool. For example, the uncertainties of all TT conditions are set with:

from Configurables import Al__AlignChisqConstraintTool as AlignChisqConstraintTool

#### Revision 182014-01-16 - GiulioDujany

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 91 to 91
The regular expressions work like the standard Perl (?) regular expressions. We use boost_regex for this. There is one very important caveat here: For now you need to specify every slash ('/') in the regular expression. (You could not specify the Velo modules by using e.g. ".*/Velo.*/Module.{2}".). The reason for this is performance: Rather than matching all elements in LHCb against the string, the string is matched 'level-by-level': We first find /dd/Structure/LHCb/BeforeMagnetRegion/Velo and then loop over all its daughters to find those that match "Velo(Right|Left)", etc. without this trick, we would need to decode the entire LHCb geometry in the initialization of the alignment.
Changed:
<
<
We have now shown how to create alignables that correspond to a single detector element. All detector elements can be used provided that they have an alignment condition. (That holds for most of them.) In particular for the OT, it is important to specify alignables to correspond to a group of detector elements. For example, a physical OT module has two detector elements associated to it, one for the top and one for the bottom half. In the alignment we would like to treat these as a single object. Snce the aliugnment parameters in the condition database are actually organized by elements, this will mean that the module constants appear twice in the database.
>
>
We have now shown how to create alignables that correspond to a single detector element. All detector elements can be used provided that they have an alignment condition. (That holds for most of them.) In particular for the OT, it is important to specify alignables to correspond to a group of detector elements. For example, a physical OT module has two detector elements associated to it, one for the top and one for the bottom half. In the alignment we would like to treat these as a single object. Since the alignment parameters in the condition database are actually organized by elements, this will mean that the module constants appear twice in the database.
The geometry of the OT is also arranged such that (unfortunately) the hierarchy doesn't exactly correspond to the way the detector was built. In particular there is no concept of a C-frame in the OT geometry. To allow for the alignment of C-frames, we group all associated 'quarter' elements together. To 'update' the C-frame alignment, the constants of all these quarters are changed by the same amount in the alignment 'condition' in the database.
Line: 129 to 129

Changed:
<
<
where \lambda is the Lagrange parameter. By taking the derivatives to \lambda and \alphda, you can see that if we add \lambda as an additional parameter to the set of fit parameters, then the condition above is automatically satisfied if the chisquare is minimal.
>
>
where is the Lagrange parameter. By taking the derivatives to and , you can see that if we add as an additional parameter to the set of fit parameters, then the condition above is automatically satisfied if the chisquare is minimal.
In the alignment Lagrange constraints can be used to fix unconstrained or poorly constrained degrees of freedom. The Lagrange constraints are implemented in AlignConstraintTool for (linear combinations of) the following parameters:

#### Revision 172014-01-14 - GiulioDujany

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 11 to 11
To set up a directory with the current latest version of the software do
Changed:
<
<
shell> SetupProject --build-env Alignment v4r7 shell> cd ~/cmtuser/Alignment_v4r7 shell> SetupProject Alignment v4r7
>
>
shell> setenvAlignment shell> SetupAlignment
shell> getpack Alignment/Escher HEAD shell> getpack Alignment/TAlignment HEAD shell> cd Alignment/Escher/cmt shell> source setup.[c]sh
>
>
shell> cmt br cmt config
shell> cmt br 'gmake -j'
>
>
After setenvAlignment press enter to select the current latest version of the software.

# Step 2. Running an alignment job

First set up a release directory as above. Then go to the 'job' directory in the Escher package and run like a DaVinci or Brunel like application:

#### Revision 162014-01-14 - GiulioDujany

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 11 to 11
To set up a directory with the current latest version of the software do
Changed:
<
<
shell> SetupProject --buildenv Alignment v4r7
>
>
shell> SetupProject --build-env Alignment v4r7
shell> cd ~/cmtuser/Alignment_v4r7 shell> SetupProject Alignment v4r7 shell> getpack Alignment/Escher HEAD

#### Revision 152010-04-06 - NicolaChiapolini

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 43 to 43
* gaudipar.py -e [number of events] -p [number of cores] runs (like gaudirun.py) a single iteration. The event processing is split over multiple cores in a rather simple way: it runs several m (delfault 8) applications n paralel over the same input data. Each application has a fiter that selecs 1 out of every m events. After the event processing is finished, the alignment derivatives from the m processes are added up and the alignment constants are updated.
Changed:
<
<
* gaudipariter.py -n [number of iterations] -e [number of events] -p [number of cores] runs several iterations splitting the processing over different cores. It actually just creates subdirectories for each iteration, runs  =gaudipar.py in that subdirectory, creates a new databases when the job is finished and uses that database as input to the next iteration.
>
>
* gaudipariter.py -n [number of iterations] -e [number of events] -p [number of cores] runs several iterations splitting the processing over different cores. It actually just creates subdirectories for each iteration, runs gaudipar.py in that subdirectory, creates a new databases when the job is finished and uses that database as input to the next iteration.
The alignment database used as input can be specified in a job option file, but if you use gaudipariter.py then that is not a great idea, since it would simply run the same alignment n times. Therefore, to specify an input database use the -d option. You can specify multiple input databases. For example, to run the alignment of all tracking detectors on a recent 2010 run starting from the v2.3 database, use:

#### Revision 142010-04-05 - WouterHulsbergen

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Changed:
<
<

>
>

Changed:
<
<
The Kalman alignment framework is configured using the TAlignment configurable. The name is historical: the original application was for the alignment of OT and IT. (The functionality was never limited to these systems though.) The easiest way to use the software is to follow examples. There are several example job option files in the ESCHERROOT/options directory. In the following we will try to explain in a bit more detail how the most important parts of the confuguration actually work. Together with the Escher examples, this should allow anybody to configure the alignment algorithm. > > All alignment related code is combined in the 'Alignment' project. For running the TAlignment algorithm, the following packages are most relevant: • Alignment/Escher contains the option files for running alignment jobs • Alignment/TAlignment contains the TAlignment code To set up a directory with the current latest version of the software do shell> SetupProject --buildenv Alignment v4r7 shell> cd ~/cmtuser/Alignment_v4r7 shell> SetupProject Alignment v4r7 shell> getpack Alignment/Escher HEAD shell> getpack Alignment/TAlignment HEAD shell> cd Alignment/Escher/cmt shell> source setup.[c]sh shell> cmt br 'gmake -j' # Step 2. Running an alignment job First set up a release directory as above. Then go to the 'job' directory in the Escher package and run like a DaVinci or Brunel like application: shell> cdESCHERROOT/job
shell> gaudirun.py $ESCHEROPTS/AlignCollisions2010.py$ESCHEROPTS/2010-Collisions.py

This will essentially just run the reconstruction sequence starting from the raw data, accumulate the information relevant for alignment, and finally compute new constants and dump them to xml file in finalize.

If you run with the option --printsequence it wil show the sequence of algorithms that is run. Note the GaudiSequencer/AlignSequence sequence which contains the alignment specific algorithms, in particular

• AlignMonitorSeq is a sequence that runs the same algorithms as the standard Brunel monitoring sequence and a few more. What is special about it is that if you run with the 'gaudiiter.py' script (see below), it actually clones the sequence such that you get monitoring histograms both for the first and the last iteration.
• AlignAlgorithm/Alignment is the TAlignment algorithm: it takes as input a list of tracks and eventually vertices and accumulates the 'chisquare-derivatives' that are the input to the alignment update.
• GaudiSequencer/WriteCondSeq contains the algorithms that write the xml in the 'finalize' stage of your gaudi job

To make it possible to run iterations or split your event processing over the different cores of a machine, some scrits are setup that replace gaudirun.py. They currently reside in Escher/options but should actually be moved to Escher/scripts:

* gaudiiter.py -n [number of iterations] -e [number of events] = runs =n iterations of the alignment within a single gaudiapplication. The alignment updates are triggered at the end of each iteration by a gaudi 'incident'.

* gaudipar.py -e [number of events] -p [number of cores] runs (like gaudirun.py) a single iteration. The event processing is split over multiple cores in a rather simple way: it runs several m (delfault 8) applications n paralel over the same input data. Each application has a fiter that selecs 1 out of every m events. After the event processing is finished, the alignment derivatives from the m processes are added up and the alignment constants are updated.

* gaudipariter.py -n [number of iterations] -e [number of events] -p [number of cores] runs several iterations splitting the processing over different cores. It actually just creates subdirectories for each iteration, runs  =gaudipar.py in that subdirectory, creates a new databases when the job is finished and uses that database as input to the next iteration.

The alignment database used as input can be specified in a job option file, but if you use gaudipariter.py then that is not a great idea, since it would simply run the same alignment n times. Therefore, to specify an input database use the -d option. You can specify multiple input databases. For example, to run the alignment of all tracking detectors on a recent 2010 run starting from the v2.3 database, use:

shell> gaudipariter.py -e 50000 -n 10 -p 8\
-d /afs/cern.ch/user/w/wouter/public/AlignDB/v2.3.db \
$ESCHEROPTS/AlignCollisions2010.py \$ESCHEROPTS/2010-Collisions.py \

For each iteration it creates a directory calles Iter[number] which contains among others a file 'Alignment.db' with the output alignment database. It also contains a file histograms.root which contains all histograms.

# Step 3. Detailed configuration

>
>
The Kalman alignment framework is configured using the TAlignment configurable. The name is historical: the original application was for the alignment of OT and IT. (The functionality was never limited to these systems though.) The easiest way to use the software is to follow examples. There are several example job option files in the ESCHERROOT/options directory. In the following we will try to explain in a bit more detail how the most important parts of the confuguration actually work. Together with the Escher examples, this should allow anybody to configure the alignment algorithm. The most important fields of the TAlignment configurable are: • TrackLocation: the name of the eventstore container with tracks used for alignment • ElementsToAlign: a list of strings defining the alignment degrees of freedom • Constraints: the list of lagrange constraints • SurveyConstraints: the list of survey (of 'chisquare') constraints • WriteCondSubDetList: a list with the subdetector names for which xml files must be produced (usually you want this to match the degrees of freedom) ## Specifying alignment degrees of freedom Changed: < < Obviously, the most important part of the configuration is the specification of the alignment parameters. > > Obviously, the most important part of the configuration is the specification of the alignment parameters. In the context of the alignment software we call the detector elements that we align for 'alignable objects' or simply 'alignables'. Each alignable represents a single detector element or a group of detector elements. Each alignable is calibrated for maximum 6 parameters namely, the 3 translations labelled Tx, Ty and Tz and three rotations labelled Rx, Ry and Rz (for rotations aound the X, Y and Z axis respectively). It is currently not possible to align for other degrees of freedom (also called 'deformations'), but this functionality can be added in the future. Each alignable is configured with a string, that consists of two parts separated by a colon. The first part of the string specifies the detector element; the second part the parameters (Tx,Ty,Tz,Rx,Ry,Rz). The single string is then appended to the ElementsToAlign field of the TAlignment configurable. For example to align the right half of the Velo in all its degrees of freedom, one would do: from Configurables import TAlignment velorighthalf = "/dd/Structure/LHCb/BeforeMagnetRegion/Velo/VeloRight : Tx Ty Tz Rx Ry Rz" TAlignment().ElementsToAlign = [ velorighthalf ] The strings between the parameters can be omitted, so you could use "TxTyTzRxRyRz" for the last part. (Note however, the inconsistency with the lagrange constarints below: in that case the spaces are essential. So, it is better to leave them in for now.) To simplify the configuration a syntax has been developed that makes use of patterns: rather than specifying each alignable explicitly one uses a 'regular expression'. For example, to align for all velo modules in Tx and Ty, one could do velosensors = "/dd/Structure/LHCb/BeforeMagnetRegion/Velo/Velo(Right|Left)/Module.{1,2} : Tx Ty" TAlignment().ElementsToAlign = [ velosensors ] The regular expressions work like the standard Perl (?) regular expressions. We use boost_regex for this. There is one very important caveat here: For now you need to specify every slash ('/') in the regular expression. (You could not specify the Velo modules by using e.g. ".*/Velo.*/Module.{2}".). The reason for this is performance: Rather than matching all elements in LHCb against the string, the string is matched 'level-by-level': We first find /dd/Structure/LHCb/BeforeMagnetRegion/Velo and then loop over all its daughters to find those that match "Velo(Right|Left)", etc. without this trick, we would need to decode the entire LHCb geometry in the initialization of the alignment. We have now shown how to create alignables that correspond to a single detector element. All detector elements can be used provided that they have an alignment condition. (That holds for most of them.) In particular for the OT, it is important to specify alignables to correspond to a group of detector elements. For example, a physical OT module has two detector elements associated to it, one for the top and one for the bottom half. In the alignment we would like to treat these as a single object. Snce the aliugnment parameters in the condition database are actually organized by elements, this will mean that the module constants appear twice in the database. The geometry of the OT is also arranged such that (unfortunately) the hierarchy doesn't exactly correspond to the way the detector was built. In particular there is no concept of a C-frame in the OT geometry. To allow for the alignment of C-frames, we group all associated 'quarter' elements together. To 'update' the C-frame alignment, the constants of all these quarters are changed by the same amount in the alignment 'condition' in the database. To specify a group of elements, we add prepend the strings introduced above with another one that represents the group name, the name of the alignable to which all elements belong. For example, to define the X translation of the first OT C-frame, one would use TAlignment().ElementsToAlign.append( "OT/T1X1UASide : /dd/Structure/LHCb/AfterMagnetRegion/T/OT/T1/(X1|U)/Q(1|3) : Tx" ) Note that the regular expression has a different purpose here: it selects all elements that belong to the OT/T1X1UASide C-frame. To specify the alignment constants for all C-frames, you would still need to define each of them separately. (You cannot sue a regular expression for the name.) Because this is clearly still too complicated a python class Alignables was written that holds all expressions for the most commonly used alignables. E.g. to align all Velo modules and OT C-frames, you would do: from TAlignment.Alignables import Alignables elements = Alignables() elements.VeloRModules("Tx Ty") elements.VeloPhiModules("Tx Ty") elements.OTCFrames("Tx Ty Tz") TAlignment().ElementsToAlign = list( elements ) You can find the available list in theTALIGNMENTROOT/python/TAlignment/Alignables.py source code. If your favourite alignable isn't there, it should just be added.

By default all alignment constants are defined in the local frame of the detector element associated to the Alignable. For groups an average of the frames of the elements is taken. If for some reason you prefer all parameters to be defined in the global frame, you can modify the UseLocalFrame field of the TAlignment configureble:

TAlignment().UseLocalFrame = False

Deleted:
<
<
• element
• groups
• the Alignables configurable

## Using Lagrange constraints

Line: 49 to 98
constrain just a single element.
Changed:
<
<

>
>

## Using chisquare ('survey') constraints: aligning different elements in the hierarchy simultaneously.

Survey constraints can be added as penalty terms to the chisquare. The penalty term is the square of the difference between an alignment parameter and a reference value divided by an uncertainty in the reference value:

Changed:
<
<
The reference value is always defined in the local frame of the alignment element. In other words, you need to make sure you also align the elements in the local frame. (See the UseLocalFrame parameter above.) The use of these constraints is most easily explained by a few examples. The simplest constraint looks like this:
>
>
Ideally, one would use a certain version of the geometry ('the surveyed geometry') as input to the alignment. In practise, this is very complicated. First, in the LHCb software framework one has access to only two geometries, namely 'ideal' and 'aligned' where the latter uses a particular set of alignment conditions (determined by the event time, see also below.) To run the alignment one will hardly ever start from the survey, except maybe the very first time we align the detector. Therefore, the survey geometry is lost for anything but the first alignment: one cannot access simultanesouly the 'current' geometry and the 'somewhere-in-the-past-surveyed' geometry.

Second, to make use of the survey the uncertainties need to make sense and correlations need to be taken into account. For example, the position of modules within an OT C-frame is known within 200 micron, yet the position of the C-frame itself has an uncertainty of 1mm. To represent that information consistently in a covariance matrix is hard.

Finally, a generic problem with such chiquare constraints is that their importance reduces if the number of tracks increases. Since a single track already gives information about the position of an element with an accuracy that comes close to the hit resolution, the survey input is very soon irrelevant: The survey simply cannot pull the alignment sufficiently.

Consequently, survey constraints are of limited value in tracking alignment. Therefore, in what follows a pragmatic approach has been taken, with as the most important limitation that no correlations can be specified. (Think about what this means: in the example above the OT module survey cannot be used.) To still allow for more precise 'local' than 'global' information, all constraints are specified in the local frame of the alignable, so with respect to its mother. That wouldn't help if it could not be combined with another powerful feature of the alignment sofware: one can align the detector at different levels of granularity simultaneously.

The use of the chisquare constraints is most easily explained with a few examples. The simplest constraint looks like this:

surveyconstraints = [ "OT/T1X1UCSide : Tx : -0.79 +/- 0.5" ]
Line: 85 to 142
The uncertainty of 0.1 mm in the constraints for the modules is large enough that it will not really affect the module position itself: modules can still move freely inside the C-frame. However, what will effectively happen now is that the C-frame is positioned such that the average deviation of the modules from their nominal geometry is minimal. The alignment problem is perfectly constrained despite the redundancy in parameter. So, chisquare constraints allow to align the detector at different levels of granularity simultaneously.
>
>
To simplifiy the use of such constraints a python class SurveyConstraints was written. Currently, it only holds numbers for OT, but other can easily be added.

## Other initialization issues

#### Revision 42010-01-04 - WouterHulsbergen

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
Line: 70 to 70
surveyconstraints = [ "/.*?/OT/.*?/M. : Tx : 0.1" ]
>
>
This constraint means: fix the position of a module to its nominal value in the local frame with an uncertainty of 100 micron.
Now, you may wonder why this is useful. Consider the following scenario: We want to align the modules within a C-frame in X. However, at the same time we want to align the C-frame itself as a global structure in X and Y. Naively, we could just try the following:
elements.OTCFrames("TxTy")
elements.OTModules("Tx")
Changed:
<
<
However, we clearly have created a problem now: There is a redundancy in the alignment degrees of freedom, because the C-frame movement is just an average movement of the modules. The solution is to add a chisquare term for the position of the modules inside the C-frame:
>
>
However, we clearly have created a problem now: There is a redundancy in the alignment degrees of freedom because the C-frame movement is just an average movement of the modules. The solution is to add a chisquare term for the position of the modules inside the C-frame:

elements.OTCFrames("TxTy")
elements.OTModules("Tx"

#### Revision 32010-01-04 - WouterHulsbergen

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
>
>

# Configuration of the 'Kalman' alignment framework

The Kalman alignment framework is configured using the TAlignment configurable. The name is historical: the original application was for the alignment of OT and IT. (The functionality was never limited to these systems though.) The easiest way to use the software is to follow examples. There are several example job option files in the \$ESCHERROOT/options directory. In the following we will try to explain in a bit more detail how the most important parts of the confuguration actually work. Together with the Escher examples, this should allow anybody to configure the alignment algorithm.

## Specifying alignment degrees of freedom

Obviously, the most important part of the configuration is the specification of the alignment parameters.

• element
• groups
• the Alignables configurable

## Using Lagrange constraints

Lagrange constraints can be used to fix unconstrained or poorly constrained degrees of freedom. A Lagrange constraints fixes the change in an alignment parameter or a linear combination of a set of alignment parameters to zero. The Lagrange constraints are implemented in AlignConstraintTool. The following constraints are available:

Line: 37 to 51

## Using chisquare ('survey') constraints

Changed:
<
<
Survey constraints can be added as penalty terms to the chisquare. The penalty term is the difference between an alignment parameter and a reference value divided by an uncertainty in the reference value. Currently, the only reference value that can be used is '0'. In other words, chisquare constraints, constrain the alignment to the nominal alignment. The reference value is always defined in the local frame. In other words, you can constrain daughter elements to their nominal position in the frame of the mother. The mother itself can be at a position different from nominal.
>
>
Survey constraints can be added as penalty terms to the chisquare. The penalty term is the square of the difference between an alignment parameter and a reference value divided by an uncertainty in the reference value:

The reference value is always defined in the local frame of the alignment element. In other words, you need to make sure you also align the elements in the local frame. (See the UseLocalFrame parameter above.) The use of these constraints is most easily explained by a few examples. The simplest constraint looks like this:

surveyconstraints = [ "OT/T1X1UCSide : Tx : -0.79 +/- 0.5" ]
TAlignment().SurveyConstraints = surveyconstraints

Like for the Lagrange constraints, the colon act as a token. Unlike the Lagrange constraints, the first string is not the name of the constraint, but the name of the element. The second string is the degree of freedom. For chisquare constraints this should be a single parameter. The third string is the reference value with its error. The constraint therefore means: fix the X position of the OT/T1X1UCSide C-frame to a value "-0.79 +/- 0.5" mm.

If the reference is the nominal geometry, then the value itself, but not the error can be omitted. (You can also a omit the "+/-" then.) Furthermore, a regular expression can be used to add constraints for more than one element at a time. For example, to fix all OT modules to their local nominal position, you can do

surveyconstraints = [ "/.*?/OT/.*?/M. : Tx : 0.1" ]

Changed:
<
<
To illustrate why such constraintsw are useful consider the following example.
>
>
Now, you may wonder why this is useful. Consider the following scenario: We want to align the modules within a C-frame in X. However, at the same time we want to align the C-frame itself as a global structure in X and Y. Naively, we could just try the following:
elements.OTCFrames("TxTy")
elements.OTModules("Tx")
However, we clearly have created a problem now: There is a redundancy in the alignment degrees of freedom, because the C-frame movement is just an average movement of the modules. The solution is to add a chisquare term for the position of the modules inside the C-frame:
elements.OTCFrames("TxTy")
elements.OTModules("Tx"
surveyconstraints = [ "/.*?/OT/.*?/M. : Tx : 0.1" ]
The uncertainty of 0.1 mm in the constraints for the modules is large enough that it will not really affect the module position itself: modules can still move freely inside the C-frame. However, what will effectively happen now is that the C-frame is positioned such that the average deviation of the modules from their nominal geometry is minimal. The alignment problem is perfectly constrained despite the redundancy in parameter. So, chisquare constraints allow to align the detector at different levels of granularity simultaneously.

Deleted:
<
<
There are a few cases in which this is useful. For example, it is allows to align an IT box and the layers in the box *simultaneously

## Other initialization issues

#### Revision 22009-12-30 - WouterHulsbergen

Line: 1 to 1

 META TOPICPARENT name="LHCbDetectorAlignment"
>
>

## Using Lagrange constraints

>
>
Lagrange constraints can be used to fix unconstrained or poorly constrained degrees of freedom. A Lagrange constraints fixes the change in an alignment parameter or a linear combination of a set of alignment parameters to zero. The Lagrange constraints are implemented in AlignConstraintTool. The following constraints are available:

Changed:
<
<
* Using Lagrange constraints
>
>
 Tx, Ty, Tz translation in x, y, z Rx, Ry, Rz rotation about x, y, z Szx, Szy shearing of x and y versus z, e.g. a transformation like delta-x = const * z Szz, Sxx scaling in x or z, e.g. a transformation like =delta-z = const * z SRz twist around z, so a transformation like delta-rot-z = const * z PVx, PVy, PVz translation of average primary vertex

Each of these constraints is applied to a set of elements. By default that set is 'all' elements. For example, to fix the change in the average translation of all aligned objects, you can do

# specify the list of constraints
constraints = [ "Tx", "Ty", "Tz" ]
TAlignment().Constraints = constraints

However, much more fine grained control can be obtained by specifying regular expressions that define the list of elements to which the constraint must be applied. For example, to fix only the average translation of all Velo-A, you can do

constraints += [ "VeloA : .*?/VeloRight.*? : Tx Ty Tz"]
Note:
• the string consists of 3 parts seperated by colons
• the first part is the 'name' of the constraint. This name must be unique.
• the second part is the regular expression. In this case it will select all alignable elements that contain '/VeloRight' in the name of any associated detector element.
• the third part are the constraints. These must be seperated by a space.

Changed:
<
<
* Using chisquare ('survey') constraints
>
>
In the log file the constraints will now appear as 'VeloATx', 'VeloATy', and 'VeloATz'.

The regular expression can also be replaced by the name of an alignable: this is useful if you want to constrain just a single element.

## Using chisquare ('survey') constraints

Survey constraints can be added as penalty terms to the chisquare. The penalty term is the difference between an alignment parameter and a reference value divided by an uncertainty in the reference value. Currently, the only reference value that can be used is '0'. In other words, chisquare constraints, constrain the alignment to the nominal alignment. The reference value is always defined in the local frame. In other words, you can constrain daughter elements to their nominal position in the frame of the mother. The mother itself can be at a position different from nominal.
Line: 12 to 43
There are a few cases in which this is useful. For example, it is allows to align an IT box and the layers in the box *simultaneously
>
>

## Other initialization issues

The derivatives are computed with respect to a certain version of the geometry. The Gaudi framework (more precisely the UpdateManagerSvc) uses the geometry corresponding to a particular time. The leads to two different problems.

First, the UpdateManagerSvc by default initializes the geometry using the current time. That could mean for example that if the velo is 'now' open (because we are not taking data), but if it was closed at the time of running, then the alignment derivatives will be computed with respect to an 'open' velo. This problem can be partially solved by specifying the time used at initialization:

# specify the time of the 'first' event in ns
EventClockSvc().InitialTime = 1260350949785664000

Second, during event processing the UpdateMnagerSvc will update the geometry according to the event time. Consequently, it could happen that the geometry changes while you are processing evens. The alignment software is currently not protected against such geometry changes.

-- WouterHulsbergen - 17-Dec-2009 \ No newline at end of file

#### Revision 12009-12-17 - WouterHulsbergen

Line: 1 to 1
>
>
 META TOPICPARENT name="LHCbDetectorAlignment"

* Using Lagrange constraints

* Using chisquare ('survey') constraints

Survey constraints can be added as penalty terms to the chisquare. The penalty term is the difference between an alignment parameter and a reference value divided by an uncertainty in the reference value. Currently, the only reference value that can be used is '0'. In other words, chisquare constraints, constrain the alignment to the nominal alignment. The reference value is always defined in the local frame. In other words, you can constrain daughter elements to their nominal position in the frame of the mother. The mother itself can be at a position different from nominal.

To illustrate why such constraintsw are useful consider the following example.

There are a few cases in which this is useful. For example, it is allows to align an IT box and the layers in the box *simultaneously

-- WouterHulsbergen - 17-Dec-2009

Copyright &© 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback