ZPD LUT Formats
The LUT formats are defined most exactly in their VHDL code.
A close second which is more readable by most people is the
C++ code in L1DctConfig/L1DZpdLut.cc. A few of
the more common and/or changeable LUTs are documented here.
Decision Module Cuts
Also see the
ZPD memory map document. If that
documentation and this website disagree, that documentation is probably
the correct one.
| Bit 0 A10 track cuts
| Bit 0 A7 track cuts
|
|---|
| Addr | Cut | Addr | Cut
|
|---|
| 0x100 | min curvature | 0x110 | min curvature
| | 0x101 | max curvature | 0x111 | max curvature
| | 0x102 | min tanλ | 0x112 | min tanλ
| | 0x103 | max tanλ | 0x113 | max tanλ
| | 0x104 | min z0 | 0x114 | min z0
| | 0x105 | max z0 | 0x115 | max z0
| | 0x106 | max z0 error | 0x116 | max z0 error
| | 0x107 | max missing segments | 0x117 | max missing segments
|
The cuts for bit 1 start at 0x200, for bit 2 at 0x300, etc.
The cuts are implemented as min < value < max,
i.e., less-than, not less-than-or-equal...).
Decision Module Max Possible Segments
Block 0x8000 Addr 0x1000 - 0x1fff
Each memory address contains a 4-bit maximum number of segments possible
for a certain curvature (rho) and tanλ (dip) combination.
Ideally we would use all 8 bits of both quantities to form a 16 bit
address (216 = 65k) LUT. But we don't have enough memory
(or address space) for that so we need to drop some bits of precision.
Since the LUT would be symmetric in positive/negative curvature, we drop
one bit by taking the absolute value. Then we drop the remaining 2 least
significant bits. Since the number of possible segments depends more
strongly on tanλ, we only drop one LSB there.
Here is a snippet of C++ code which converts rho and dip
into the memory address for that combination:
// addr[15:12] = 0001
// addr[11: 7] = abs(rho[7:0]) [6:2]
// addr[ 6: 0] = dip[7:1]
unsigned getMaxSegsLutAddr(int rho, int dip)
{
// rho and dip are 8 bit signed quantities range [-128,127]
assert(-128 <= rho && rho < 128);
assert(-128 <= dip && dip < 128);
// take |rho|, use +127 for |-128| because +128 takes 9 bits, not 8...
unsigned absrho = ( -128==rho ? 127 : abs(rho) );
unsigned irho = (absrho>>2) & 0x1f; // 5 bits
unsigned idip = (dip>>1) & 0x7f; // 7 bits
unsigned addr = 0x1000 + (irho<<7) + idip;
return addr;
}
When L1DctConfig/L1DZpdLut calculates the contents of this LUT,
it uses
z0 = +10 for tanλ>0 and
z0 = -10 for tanλ<0. This makes the maximum possible
segments value somewhat conservative.
Basic Parameters
The basic parameters which were used to derived the Fitter LUT contents are
stored in block 1 addresses 0x11-0x1d:
| Addr | Value | Units
|
|---|
| 0x11 | Number of curvature bins |
| | 0x12 | min pT | MeV
| | 0x13 | number of tanλ bins (A10) |
| | 0x14 | min tanλ (A10) | 10-3
| | 0x15 | max tanλ (A10) | 10-3
| | 0x16 | number of tanλ bins (A7) |
| | 0x17 | min tanλ (A7) | 10-3
| | 0x18 | max tanλ (A7) | 10-3
| | 0x19 | B field | milliTesla
| | 0x1a | IPx | 10-3 cmz
| | 0x1b | IPy | 10-3 cm
| | 0x1c | IPz | 10-3 cm
| | 0x1d | ZPD octant |
|
The Finders also store the basic parameters which were used to generate
their LUT contents. They are stored in each Finder block
(0x2, 0x8, 0x20, 0x80, 0x200, 0x800) at addresses 0x110 to 0x116:
| Addr | Value | Units
|
|---|
| 0x110 | Number of curvature bins |
| | 0x111 | min pT | MeV
| | 0x112 | number of tanλ bins (A10) |
| | 0x113 | min tanλ (A10) | 10-3
| | 0x114 | max tanλ (A10) | 10-3
| | 0x115 | phi merge |
| | 0x116 | B field | milliTesla
|
The ZPD configuration code checks the consistency of the
Finder and Fitter basic parameters to ensure that they match.
Other LUTs
There are other LUTs in the Finder and Fitter, but if you want to change
their contents you probably should understand and use the code in
L1DctConfig/L1DZpdLut.cc. So rather than document it here and
have it get out of date when that code changes, please just refer to that
code.
|