ATLAS Offline Software
Loading...
Searching...
No Matches
LVL1::gFEXJetAlgo Class Reference

#include <gFEXJetAlgo.h>

Inheritance diagram for LVL1::gFEXJetAlgo:
Collaboration diagram for LVL1::gFEXJetAlgo:

Public Member Functions

 gFEXJetAlgo (const std::string &type, const std::string &name, const IInterface *parent)
 Constructors.
virtual StatusCode initialize () override
 standard Athena-Algorithm method
virtual void pileUpCalculation (gTowersType &twrs, int rhoThreshold_Max, int inputScale, int &PUCp, int &PUC_JWJ) const override
virtual std::vector< std::unique_ptr< gFEXJetTOB > > largeRfinder (const gTowersType &Atwr, const gTowersType &Btwr, const gTowersType &CNtwr, const gTowersType &Asat, const gTowersType &Bsat, const gTowersType &CNsat, int pucA, int pucB, int pucC, int gLJ_seedThrA, int gLJ_seedThrB, int gLJ_seedThrC, int gJ_ptMinToTopoCounts1, int gJ_ptMinToTopoCounts2, int jetThreshold, int gLJ_ptMinToTopoCounts1, int gLJ_ptMinToTopoCounts2, std::array< uint32_t, 7 > &ATOB1_dat, std::array< uint32_t, 7 > &ATOB2_dat, std::array< uint32_t, 7 > &BTOB1_dat, std::array< uint32_t, 7 > &BTOB2_dat, std::array< uint32_t, 7 > &CTOB1_dat, std::array< uint32_t, 7 > &CTOB2_dat) const override
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Static Public Member Functions

static const InterfaceID & interfaceID ()

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

virtual void singleHalf (const gTowersType &twrs, gTowersType &FPGAsum) const
virtual void InternalPartialAB (const gTowersType &twrs, gTowersPartialSums &lps, gTowersPartialSums &rps) const
virtual void addInternalLin (gTowersType &jets, gTowersPartialSums &partial) const
virtual void addInternalRin (gTowersType &jets, gTowersPartialSums &partial) const
virtual void pileUpCorrectionAB (gTowersType &jets, int puc) const
virtual void ZeroNegative (gTowersType &jets) const
virtual void SaturateJets (gTowersType &jets, const gTowersType &sat, int fpga) const
virtual void SaturateBlocks (gTowersType &gBlkSum, const gTowersType &sat, int fpga) const
virtual void gBlockAB (const gTowersType &twrs, gTowersType &gBlkSum, gTowersType &hasSeed, int seedThreshold) const
virtual void blkOutAB (gTowersType &blocks, std::array< int, 32 > &jetOutL, std::array< int, 32 > &etaIndL, std::array< int, 32 > &jetOutR, std::array< int, 32 > &etaIndR) const
virtual void gBlockMax2 (const gTowersType &gBlkSum, int BjetColumn, int localColumn, std::array< int, 3 > &gBlockV, std::array< int, 3 > &gBlockEta, std::array< int, 3 > &gBlockPhi) const
virtual void gBlockMax192 (const gTowersJetEngine &gBlkSum, std::array< int, 3 > &gBlockVp, std::array< int, 3 > &gBlockEtap, std::array< int, 3 > &gBlockPhip, int index) const
virtual void gBlockVetoAB (gTowersType &jets, gTowersType &hasSeed) const
virtual void RemotePartialAB (const gTowersType &twrs, gTowersPartialSums &lps, gTowersPartialSums &rps) const
virtual void RemotePartialCN (const gTowersJetEngine &twrs, gTowersPartialSums &rps) const
virtual void RemotePartialCP (const gTowersJetEngine &twrs, gTowersPartialSums &lps) const
virtual void addRemoteRin (gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void addRemoteLin (gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void addRemoteCNin (gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void addRemoteCPin (gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void gJetVetoAB (gTowersType &twrs, int jet_threshold) const
virtual void jetOutAB (const gTowersType &jets, std::array< int, 32 > &jetOutL, std::array< int, 32 > &etaIndL, std::array< int, 32 > &jetOutR, std::array< int, 32 > &etaIndR) const
virtual void gJetTOBgen (const std::array< int, FEXAlgoSpaceDefs::ABCrows > &jetOut, const std::array< int, FEXAlgoSpaceDefs::ABCrows > &etaInd, int TOBnum, int jetThreshold, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBs, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBv, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBeta, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBphi) const
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

SG::ReadHandleKey< LVL1::gTowerContainerm_gFEXJetAlgo_gTowerContainerKey {this, "MyGTowers", "gTowerContainer", "Input container for gTowers"}
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Definition at line 31 of file gFEXJetAlgo.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ gFEXJetAlgo()

LVL1::gFEXJetAlgo::gFEXJetAlgo ( const std::string & type,
const std::string & name,
const IInterface * parent )

Constructors.

Definition at line 22 of file gFEXJetAlgo.cxx.

22 :
23 AthAlgTool(type, name, parent)
24 {
25 declareInterface<IgFEXJetAlgo>(this);
26 }
AthAlgTool()
Default constructor:

Member Function Documentation

◆ addInternalLin()

void LVL1::gFEXJetAlgo::addInternalLin ( gTowersType & jets,
gTowersPartialSums & partial ) const
privatevirtual

Definition at line 916 of file gFEXJetAlgo.cxx.

916 {
917 // add parial sums for left side of FPGA
918 for(unsigned int irow=0;irow<FEXAlgoSpaceDefs::ABCrows;irow++){
919 for(unsigned int ipartial= 0; ipartial <FEXAlgoSpaceDefs::n_partial; ipartial++){
920 jets[irow][2+ipartial] = jets[irow][2+ipartial] + partial[irow][ipartial];
921 }
922 }
923}
static constexpr int ABCrows
static constexpr int n_partial

◆ addInternalRin()

void LVL1::gFEXJetAlgo::addInternalRin ( gTowersType & jets,
gTowersPartialSums & partial ) const
privatevirtual

Definition at line 926 of file gFEXJetAlgo.cxx.

926 {
927 // add parial sums for right side of FPGA
928 for(unsigned int irow=0;irow<FEXAlgoSpaceDefs::ABCrows;irow++){
929 for(unsigned int ipartial= 0; ipartial <FEXAlgoSpaceDefs::n_partial; ipartial++){
930 jets[irow][6+ipartial] = jets[irow][6+ipartial] + partial[irow][ipartial];
931 }
932 }
933}

◆ addRemoteCNin()

void LVL1::gFEXJetAlgo::addRemoteCNin ( gTowersType & jets,
const gTowersPartialSums & partial,
int ps_upper,
int ps_lower,
int ps_shift ) const
privatevirtual

Definition at line 1324 of file gFEXJetAlgo.cxx.

1325 {
1326
1327 int rows = partial.size();
1328 int cols = partial[0].size();
1329 // add partial sums
1330 for(int irow=0; irow < rows; irow++){
1331 for(int ipartial= 0; ipartial <cols; ipartial++){
1332 // current behavior
1333 int truncPart = -1;
1334 if( partial[irow][ipartial] > ps_upper ) {
1335 truncPart = ps_upper;
1336 } else if ( partial[irow][ipartial] < ps_lower ) {
1337 truncPart = ps_lower;
1338 } else {
1339 truncPart = partial[irow][ipartial];
1340 }
1341
1342 truncPart = (truncPart >> ps_shift );
1343 truncPart = (truncPart << ps_shift );
1344
1345 jets[irow][ipartial+2] = jets[irow][ipartial+2] + truncPart;
1346
1347 }
1348 }
1349}

◆ addRemoteCPin()

void LVL1::gFEXJetAlgo::addRemoteCPin ( gTowersType & jets,
const gTowersPartialSums & partial,
int ps_upper,
int ps_lower,
int ps_shift ) const
privatevirtual

Definition at line 1351 of file gFEXJetAlgo.cxx.

1352 {
1353
1354 int rows = partial.size();
1355 int cols = partial[0].size();
1356 // add partial sums
1357 for(int irow=0;irow<rows;irow++){
1358 for(int ipartial= 0; ipartial <cols; ipartial++){
1359 int truncPart = -1;
1360 if( partial[irow][ipartial] > ps_upper ) {
1361 truncPart = ps_upper;
1362 } else if ( partial[irow][ipartial] < ps_lower ) {
1363 truncPart = ps_lower;
1364 } else {
1365 truncPart = partial[irow][ipartial];
1366 }
1367
1368 truncPart = (truncPart >> ps_shift );
1369 truncPart = (truncPart << ps_shift );
1370
1371 jets[irow][ipartial+6] = jets[irow][ipartial+6] + truncPart;
1372
1373 }
1374 }
1375}

◆ addRemoteLin()

void LVL1::gFEXJetAlgo::addRemoteLin ( gTowersType & jets,
const gTowersPartialSums & partial,
int ps_upper,
int ps_lower,
int ps_shift ) const
privatevirtual

Definition at line 1297 of file gFEXJetAlgo.cxx.

1298 {
1299
1300 int rows = partial.size();
1301 int cols = partial[0].size();
1302 // add partial sums
1303 for(int irow=0;irow<rows;irow++){
1304 for(int ipartial= 0; ipartial <cols; ipartial++){
1305 // current behavior
1306 int truncPart = -1;
1307 if( partial[irow][ipartial] > ps_upper ) {
1308 truncPart = ps_upper;
1309 } else if ( partial[irow][ipartial] < ps_lower ) {
1310 truncPart = ps_lower;
1311 } else {
1312 truncPart = partial[irow][ipartial];
1313 }
1314 // change LSB from 200 MeV to 1600 MeV and then back to 200 MeV.
1315 truncPart = (truncPart >> ps_shift );
1316 truncPart = (truncPart << ps_shift );
1317
1318 jets[irow][ipartial] = jets[irow][ipartial] + truncPart;
1319 }
1320 }
1321}

◆ addRemoteRin()

void LVL1::gFEXJetAlgo::addRemoteRin ( gTowersType & jets,
const gTowersPartialSums & partial,
int ps_upper,
int ps_lower,
int ps_shift ) const
privatevirtual

Definition at line 1269 of file gFEXJetAlgo.cxx.

1270 {
1271
1272 // See https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/kw-dev/jwj_verif/common/jet_finder/HDL/ab_encode.vhd
1273
1274 int rows = partial.size();
1275 int cols = partial[0].size();
1276 // add partial sums
1277 for(int irow=0;irow<rows;irow++){
1278 for(int ipartial= 0; ipartial <cols; ipartial++){
1279 // current behavior
1280 int truncPart = -1;
1281 if( partial[irow][ipartial] > ps_upper ) {
1282 truncPart = ps_upper;
1283 } else if ( partial[irow][ipartial] < ps_lower ) {
1284 truncPart = ps_lower;
1285 } else {
1286 truncPart = partial[irow][ipartial];
1287 }
1288 // change LSB from 200 MeV to 1600 MeV and then back to 200 MeV.
1289 truncPart = (truncPart >> ps_shift );
1290 truncPart = (truncPart << ps_shift );
1291
1292 jets[irow][8+ipartial] = jets[irow][8+ipartial] + truncPart;
1293 }
1294 }
1295}

◆ blkOutAB()

void LVL1::gFEXJetAlgo::blkOutAB ( gTowersType & blocks,
std::array< int, 32 > & jetOutL,
std::array< int, 32 > & etaIndL,
std::array< int, 32 > & jetOutR,
std::array< int, 32 > & etaIndR ) const
privatevirtual

Definition at line 1065 of file gFEXJetAlgo.cxx.

1065 {
1066
1067 // find maximum in each jet engine for gBlocks (not done in hardware)
1068
1069 //loop over left engines
1070 for(unsigned int ieng=0; ieng<FEXAlgoSpaceDefs::ABCrows; ieng++){
1071 for(unsigned int localEta = 0; localEta<6; localEta++){
1072 if( blocks[ieng][localEta] > jetOutL[ieng] ){
1073 jetOutL[ieng] = blocks[ieng][localEta];
1074 etaIndL[ieng] = localEta;
1075 }
1076 }
1077 }
1078 // loop over right engines
1079 for(unsigned int ieng=0; ieng<FEXAlgoSpaceDefs::ABCrows; ieng++){
1080 for(unsigned int localEta = 0; localEta<6; localEta++){
1081 if( blocks[ieng][localEta+6] > jetOutR[ieng] ) {
1082 jetOutR[ieng] = blocks[ieng][localEta+6];
1083 etaIndR[ieng] = localEta;
1084 }
1085 }
1086 }
1087}

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ gBlockAB()

void LVL1::gFEXJetAlgo::gBlockAB ( const gTowersType & twrs,
gTowersType & gBlkSum,
gTowersType & hasSeed,
int seedThreshold ) const
privatevirtual

Definition at line 1017 of file gFEXJetAlgo.cxx.

1017 {
1018
1019 const int rows = twrs.size();
1020 const int cols = twrs[0].size();
1021 for( int irow = 0; irow < rows; irow++ ){
1022 for(int jcolumn = 0; jcolumn<cols; jcolumn++){
1023 // zero jet sum here
1024 gBlkSum[irow][jcolumn] = 0;
1025 int krowUp = (irow + 1)%32;
1026 int krowDn = (irow - 1 +32)%32;
1027 if( (jcolumn == 0) || (jcolumn == 6) ) {
1028 //left edge case
1029 gBlkSum[irow][jcolumn] =
1030 twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
1031 twrs[irow][jcolumn+1] + twrs[krowUp][jcolumn+1] + twrs[krowDn][jcolumn+1];
1032 } else if( (jcolumn == 5) || (jcolumn == 11)) {
1033 // right edge case
1034 gBlkSum[irow][jcolumn] =
1035 twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
1036 twrs[irow][jcolumn-1] + twrs[krowUp][jcolumn-1] + twrs[krowDn][jcolumn-1];
1037 } else{
1038 // normal case; jcolumn is not 11 so does not overrun
1039 //coverity[OVERRUN:FALSE]
1040 gBlkSum[irow][jcolumn] =
1041 twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
1042 twrs[irow][jcolumn-1] + twrs[krowUp][jcolumn-1] + twrs[krowDn][jcolumn-1] +
1043 twrs[irow][jcolumn+1] + twrs[krowUp][jcolumn+1] + twrs[krowDn][jcolumn+1];
1044 }
1045
1046 if( gBlkSum[irow][jcolumn] > seedThreshold) {
1047 hasSeed[irow][jcolumn] = 1;
1048 } else {
1049 hasSeed[irow][jcolumn] = 0;
1050 }
1051
1052 if ( gBlkSum[irow][jcolumn] < 0 )
1053 gBlkSum[irow][jcolumn] = 0;
1054
1055 // was bits 11+3 downto 3, now is 11 downto 0
1056 if ( gBlkSum[irow][jcolumn] > FEXAlgoSpaceDefs::gBlockMax ) {
1057 gBlkSum[irow][jcolumn] = FEXAlgoSpaceDefs::gBlockMax;
1058 }
1059 }
1060 }
1061}
static constexpr int gBlockMax

◆ gBlockMax192()

void LVL1::gFEXJetAlgo::gBlockMax192 ( const gTowersJetEngine & gBlkSum,
std::array< int, 3 > & gBlockVp,
std::array< int, 3 > & gBlockEtap,
std::array< int, 3 > & gBlockPhip,
int index ) const
privatevirtual

Definition at line 1129 of file gFEXJetAlgo.cxx.

1133 {
1134 // gBLKSum are the sums
1135 // gBlockVp is the returned value for the max block
1136 // gBlockEtap is the eta in the local corrdinate system
1137 // gBlockPhip is the phi (global and local are the same)
1138
1139 int inpv[192]{};
1140 int maxv1[96]{};
1141 int maxv2[48]{};
1142 int maxv3[24]{};
1143 int maxv4[12]{};
1144 int maxv5[6]{};
1145 int maxv6[3]{};
1146
1147 int inpi[192]{};
1148 int maxi1[96]{};
1149 int maxi2[48]{};
1150 int maxi3[24]{};
1151 int maxi4[12]{};
1152 int maxi5[6]{};
1153 int maxi6[3]{};
1154
1155 int maxvall;
1156 int maxiall;
1157
1158
1159 // ABCcolumnsEng is 6 in hardware
1160 int maxv = 0;
1161
1162 for(unsigned int icolumn = 0; icolumn<FEXAlgoSpaceDefs::ABCcolumnsEng; icolumn++){
1163 for(unsigned int irow = 0; irow<FEXAlgoSpaceDefs::ABCrows; irow++){
1164 inpv[irow + icolumn*FEXAlgoSpaceDefs::ABCrows] = gBlkSum[irow][icolumn];
1165 inpi[irow + icolumn*FEXAlgoSpaceDefs::ABCrows] = irow + icolumn*FEXAlgoSpaceDefs::ABCrows;
1166
1167 if( gBlkSum[irow][icolumn] > maxv){
1168 maxv = gBlkSum[irow][icolumn];
1169 }
1170 }
1171 }
1172
1173 for(int i = 0; i<96; i++){
1174 if( inpv[2*i+1] > inpv[2*i] ) {
1175 maxv1[i] = inpv[2*i+1];
1176 maxi1[i] = inpi[2*i+1];
1177 } else {
1178 maxv1[i] = inpv[2*i];
1179 maxi1[i] = inpi[2*i];
1180 }
1181 }
1182
1183 for(int i = 0; i<48; i++){
1184 if( maxv1[2*i+1] > maxv1[2*i] ) {
1185 maxv2[i] = maxv1[2*i+1];
1186 maxi2[i] = maxi1[2*i+1];
1187 } else {
1188 maxv2[i] = maxv1[2*i];
1189 maxi2[i] = maxi1[2*i];
1190 }
1191 }
1192
1193 for(int i = 0; i<24; i++){
1194 if( maxv2[2*i+1] > maxv2[2*i] ) {
1195 maxv3[i] = maxv2[2*i+1];
1196 maxi3[i] = maxi2[2*i+1];
1197 } else {
1198 maxv3[i] = maxv2[2*i];
1199 maxi3[i] = maxi2[2*i];
1200 }
1201 }
1202
1203 for(int i = 0; i<12; i++){
1204 if( maxv3[2*i+1] > maxv3[2*i] ) {
1205 maxv4[i] = maxv3[2*i+1];
1206 maxi4[i] = maxi3[2*i+1];
1207 } else {
1208 maxv4[i] = maxv3[2*i];
1209 maxi4[i] = maxi3[2*i];
1210 }
1211 }
1212
1213 for(int i = 0; i<6; i++){
1214 if( maxv4[2*i+1] > maxv4[2*i] ) {
1215 maxv5[i] = maxv4[2*i+1];
1216 maxi5[i] = maxi4[2*i+1];
1217 } else {
1218 maxv5[i] = maxv4[2*i];
1219 maxi5[i] = maxi4[2*i];
1220 }
1221 }
1222
1223 for(int i = 0; i<3; i++){
1224 if( maxv5[2*i+1] > maxv5[2*i] ) {
1225 maxv6[i] = maxv5[2*i+1];
1226 maxi6[i] = maxi5[2*i+1];
1227 } else {
1228 maxv6[i] = maxv5[2*i];
1229 maxi6[i] = maxi5[2*i];
1230 }
1231 }
1232
1233 if( ( maxv6[1] > maxv6[0] ) && ( maxv6[1] > maxv6[2] ) ) {
1234 maxvall = maxv6[1];
1235 maxiall = maxi6[1];
1236 } else {
1237 if( maxv6[0] > maxv6[2] ){
1238 maxvall = maxv6[0];
1239 maxiall = maxi6[0];
1240 } else {
1241 maxvall = maxv6[2];
1242 maxiall = maxi6[2];
1243 }
1244 }
1245
1246
1247 gBlockVp[index] = maxvall ;
1248 gBlockEtap[index] = maxiall/32;
1249 gBlockPhip[index] = maxiall%32;
1250
1251}
static constexpr int ABCcolumnsEng
str index
Definition DeMoScan.py:362

◆ gBlockMax2()

void LVL1::gFEXJetAlgo::gBlockMax2 ( const gTowersType & gBlkSum,
int BjetColumn,
int localColumn,
std::array< int, 3 > & gBlockV,
std::array< int, 3 > & gBlockEta,
std::array< int, 3 > & gBlockPhi ) const
privatevirtual

Definition at line 1090 of file gFEXJetAlgo.cxx.

1090 {
1091 // gBlkSum are the 9 or 6 gTower sums
1092 // BjetColumn is the Block Column -- 0 for CN, 1, 2 for A 3, 4 for B and 5 for CP
1093 // gBlockV is the array of values currently 2
1094 // gBlockEta is the eta in global
1095
1096 gTowersJetEngine gBlkSumC;
1097
1098 // copy the correct column
1099 for( int irow = 0; irow<FEXAlgoSpaceDefs::ABCrows; irow++){
1100 for( int icolumn =0; icolumn<FEXAlgoSpaceDefs::ABCcolumnsEng; icolumn++){
1101 gBlkSumC[irow][icolumn] = gBlkSum[irow][icolumn + localColumn*FEXAlgoSpaceDefs::ABCcolumnsEng];
1102 }
1103 }
1104
1105 gBlockMax192(gBlkSumC, gBlockV, gBlockEta, gBlockPhi, 0);
1106
1107 for(int i = -1; i<2; i++){
1108 int iGlobal = i + gBlockPhi[0];
1109 // map row number in to 0-31
1110 if ( iGlobal < 0 ) iGlobal = iGlobal + 32;
1111 if ( iGlobal > 31 ) iGlobal = iGlobal - 32;
1112 // don't do anything outside of the six columsn
1113 for( int j = -1; j<2; j++){
1114 int jGlobal = j + gBlockEta[0];
1115 if( (jGlobal > -1) && (jGlobal < 6) ) {
1116 gBlkSumC[iGlobal][jGlobal] = 0;
1117 }
1118 }
1119 }
1120
1121 gBlockMax192(gBlkSumC, gBlockV, gBlockEta, gBlockPhi, 1);
1122
1123 // need to wait until the end for this!
1124 gBlockEta[0] = gBlockEta[0] + 2 + 6*BjetColumn;
1125 gBlockEta[1] = gBlockEta[1] + 2 + 6*BjetColumn;
1126}
virtual void gBlockMax192(const gTowersJetEngine &gBlkSum, std::array< int, 3 > &gBlockVp, std::array< int, 3 > &gBlockEtap, std::array< int, 3 > &gBlockPhip, int index) const
std::array< std::array< int, 6 >, 32 > gTowersJetEngine
Definition gFEXJetAlgo.h:28
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ gBlockVetoAB()

void LVL1::gFEXJetAlgo::gBlockVetoAB ( gTowersType & jets,
gTowersType & hasSeed ) const
privatevirtual

Definition at line 1254 of file gFEXJetAlgo.cxx.

1254 {
1255 int rows = jets.size();
1256 int cols = jets[0].size();
1257 for( int irow = 0; irow < rows; irow++ ){
1258 for(int jcolumn = 0; jcolumn < cols; jcolumn++){
1259 if( hasSeed[irow][jcolumn] == 0 ) {
1260 // set to negative value as in hardware
1261 // https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/devel/common/jet_finder/HDL/jet_eng.vhd#L561
1262 jets[irow][jcolumn] = 0XFFFFF000;
1263 }
1264 }
1265 }
1266}

◆ gJetTOBgen()

void LVL1::gFEXJetAlgo::gJetTOBgen ( const std::array< int, FEXAlgoSpaceDefs::ABCrows > & jetOut,
const std::array< int, FEXAlgoSpaceDefs::ABCrows > & etaInd,
int TOBnum,
int jetThreshold,
std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > & gJetTOBs,
std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > & gJetTOBv,
std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > & gJetTOBeta,
std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > & gJetTOBphi ) const
privatevirtual

Definition at line 1488 of file gFEXJetAlgo.cxx.

1493 {
1494
1495 int jetOutZS[FEXAlgoSpaceDefs::ABCrows]{};
1496 // apply the tobthreshold to the values
1497 //note that jetThreshold is not a configurable parameter in firmware, it is used to check that jet values are positive
1498 for( int irow =0; irow<FEXAlgoSpaceDefs::ABCrows; irow++){
1499 if( jetOut[irow] > jetThreshold ) {
1500 jetOutZS[irow] = jetOut[irow];
1501 } else {
1502 jetOutZS[irow] = 0 ;
1503 }
1504 }
1505
1506
1507 // offset of TOBs according to official format
1508 int etaOff[FEXAlgoSpaceDefs::gJetTOBfib] = {8,14,20,26,2,32};
1509
1510 // see tob_gen.vhd
1511 int l1mv[16]{};
1512 int l1met[16]{};
1513 int l1mphi[16]{};
1514
1515 int l2mv[8]{};
1516 int l2met[8]{};
1517 int l2mphi[8]{};
1518
1519 int l3mv[4]{};
1520 int l3met[4]{};
1521 int l3mphi[4]{};
1522
1523 int l4mv[2]{};
1524 int l4met[2]{};
1525 int l4mphi[2]{};
1526
1527 for(int i=0; i<16; i++){
1528 if( jetOut[2*i + 1] > jetOutZS[2*i] ){
1529 l1mv[i] = jetOutZS[2*i + 1];
1530 l1met[i] = etaInd[2*i + 1];
1531 l1mphi[i] = 2*i + 1;
1532 } else {
1533 l1mv[i] = jetOutZS[2*i ];
1534 l1met[i] = etaInd[2*i ];
1535 l1mphi[i] = 2*i ;
1536 }
1537 }
1538
1539 for(int i=0; i<8; i++){
1540 if( l1mv[2*i + 1] > l1mv[2*i] ){
1541 l2mv[i] = l1mv[ 2*i + 1 ];
1542 l2met[i] = l1met[ 2*i + 1];
1543 l2mphi[i] = l1mphi[2*i + 1];
1544 } else {
1545 l2mv[i] = l1mv[ 2*i ];
1546 l2met[i] = l1met[ 2*i ];
1547 l2mphi[i] = l1mphi[2*i ];
1548 }
1549 }
1550
1551 for(int i=0; i<4; i++){
1552 if( l2mv[2*i + 1] > l2mv[2*i] ){
1553 l3mv[i] = l2mv[ 2*i + 1];
1554 l3met[i] = l2met[ 2*i + 1];
1555 l3mphi[i] = l2mphi[2*i + 1];
1556 } else {
1557 l3mv[i] = l2mv[2*i ];
1558 l3met[i] = l2met[2*i ];
1559 l3mphi[i] = l2mphi[2*i ];
1560 }
1561 }
1562
1563 for(int i=0; i<2; i++){
1564 if( l3mv[2*i + 1] > l3mv[2*i] ){
1565 l4mv[i] = l3mv[ 2*i + 1];
1566 l4met[i] = l3met[ 2*i + 1];
1567 l4mphi[i] = l3mphi[2*i + 1];
1568 } else {
1569 l4mv[i] = l3mv[2*i ];
1570 l4met[i] = l3met[2*i ];
1571 l4mphi[i] = l3mphi[2*i ];
1572 }
1573 }
1574
1575 if( l4mv[1] > l4mv[0] ){
1576 if(l4mv[1] > jetThreshold){
1577 gJetTOBv[TOBnum] = l4mv[1];
1578 gJetTOBeta[TOBnum] = l4met[1] + etaOff[TOBnum];
1579 gJetTOBphi[TOBnum] = l4mphi[1];
1580 gJetTOBs[TOBnum] = 1;
1581 } else {
1582 gJetTOBv[TOBnum] = l4mv[1];
1583 gJetTOBeta[TOBnum] = l4met[1] + etaOff[TOBnum];
1584 gJetTOBphi[TOBnum] = l4mphi[1];
1585 gJetTOBs[TOBnum] = 0;
1586 }
1587 } else {
1588 if(l4mv[0] > jetThreshold){
1589 gJetTOBv[TOBnum] = l4mv[0];
1590 gJetTOBeta[TOBnum] = l4met[0] + etaOff[TOBnum];
1591 gJetTOBphi[TOBnum] = l4mphi[0];
1592 gJetTOBs[TOBnum] = 1;
1593 } else {
1594 gJetTOBv[TOBnum] = l4mv[0];
1595 gJetTOBeta[TOBnum] = l4met[0] + etaOff[TOBnum];
1596 gJetTOBphi[TOBnum] = l4mphi[0];
1597 gJetTOBs[TOBnum] = 0;
1598 }
1599 }
1600
1601}
static constexpr int gJetTOBfib

◆ gJetVetoAB()

void LVL1::gFEXJetAlgo::gJetVetoAB ( gTowersType & twrs,
int jet_threshold ) const
privatevirtual

Definition at line 1378 of file gFEXJetAlgo.cxx.

1378 {
1379 int rows = twrs.size();
1380 int cols = twrs[0].size();
1381 for( int irow = 0; irow < rows; irow++ ){
1382 for(int jcolumn = 0; jcolumn<cols; jcolumn++){
1383 if( twrs[irow][jcolumn] < jet_threshold+1 ) {
1384 twrs[irow][jcolumn] = 0;
1385 }
1386 }
1387 }
1388}

◆ initialize()

StatusCode LVL1::gFEXJetAlgo::initialize ( )
overridevirtual

standard Athena-Algorithm method

Definition at line 29 of file gFEXJetAlgo.cxx.

29 {
30
32
33 return StatusCode::SUCCESS;
34
35}
#define ATH_CHECK
Evaluate an expression and check for errors.
SG::ReadHandleKey< LVL1::gTowerContainer > m_gFEXJetAlgo_gTowerContainerKey

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ interfaceID()

const InterfaceID & LVL1::IgFEXJetAlgo::interfaceID ( )
inlinestaticinherited

Definition at line 45 of file IgFEXJetAlgo.h.

46 {
47 return IID_IgFEXJetAlgo;
48 }
static const InterfaceID IID_IgFEXJetAlgo("LVL1::IgFEXJetAlgo", 1, 0)

◆ InternalPartialAB()

void LVL1::gFEXJetAlgo::InternalPartialAB ( const gTowersType & twrs,
gTowersPartialSums & lps,
gTowersPartialSums & rps ) const
privatevirtual

Definition at line 847 of file gFEXJetAlgo.cxx.

847 {
848
849 // Computes partial sums for FPGA A or B
850 // twrs are the 32 x 12 = 284 gTowers in FPGA A or B
851 //
852 // lps: partial sum for left hand side of FPGA
853 // rps: partial sum for right half of the FPGA
854
855 // NOTE rps is available first
856
857 // number of rows above/below for right partial sum
858 // when sending to the right send values for largest partial sum first, i.e. for column 6
859 unsigned int NUpDwnR[4][4] = { {2,3,4,4}, {0,2,3,4}, {0,0,2,3}, {0,0,0,2} };
860
861 // number of rows above or below for left partial sum
862 // when sending to the left send values for smallest partial sumn first (i.e. for column 2 )
863 unsigned int NUpDwnL[4][4] = { {2,0,0,0}, {3,2,0,0}, {4,3,2,0}, {4,4,3,2} };
864
865
866 // Do partial sum for output to right side FPGA first
867 // for the right partial sum this starts from the right-most value first
868 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
869 for(unsigned int rcolumn = 0; rcolumn<FEXAlgoSpaceDefs::n_partial; rcolumn++){
870 // start calculating right partial sums for remote column rcolumn
871 rps[irow][rcolumn] = 0;
872 for(unsigned int lcolumn = 0; lcolumn<FEXAlgoSpaceDefs::n_partial; lcolumn++){
873 // add in any energy from towers in this row
874 // no need of modular arithmetic
875 if ( NUpDwnR[rcolumn][lcolumn] > 0 ) {
876 // this is partial sum for the right half of the FPGA -- columns 2,3,4,5
877 rps[irow][rcolumn] = rps[irow][rcolumn] + twrs[irow][lcolumn+2];
878 }
879 // now add rup1, rup2, rup3, rup4, ldn1, ldn2, ln3, ln4 -- use a loop instead of enumeratin in firmware
880 for(unsigned int rowOff = 1 ; rowOff < NUpDwnR[rcolumn][lcolumn]+1; rowOff++){
881 const int row = static_cast<int>(irow);
882 const int off = static_cast<int>(rowOff);
883 int rowModUp = (row + off)%32;
884 int rowModDn = (row - off + 32 )%32;
885 // this is partial sum for the right half of the FPGA -- columns 2,3,4,5
886 rps[irow][rcolumn] = rps[irow][rcolumn] + twrs[rowModUp][lcolumn+2] + twrs[rowModDn][lcolumn+2];
887 }
888 }
889 }
890 }
891 // do partial sum for output to left half of the FPGA second
892 // for the left partial sum this starts also with the right most column -- which is the smallest sum
893 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
894 for(unsigned int rcolumn = 0; rcolumn<FEXAlgoSpaceDefs::n_partial; rcolumn++){
895 // start calculating right partial sums for remote column rcolumn
896 lps[irow][rcolumn] = 0;
897 for(unsigned int lcolumn = 0; lcolumn<FEXAlgoSpaceDefs::n_partial; lcolumn++){
898 // add in any energy from towers in this row
899 // no need of modular arithmetic
900 if ( NUpDwnL[rcolumn][lcolumn] > 0 ) {
901 lps[irow][rcolumn] = lps[irow][rcolumn] + twrs[irow][lcolumn+6];
902 }
903 // now add rup1, rup2, rup3, rup4, ldn1, ldn2, ln3, ln4 -- use a loop instead of enumeratin in firmware
904 for(unsigned int rowOff = 1 ; rowOff < NUpDwnL[rcolumn][lcolumn]+1; rowOff++){
905 int rowModUp = (irow + rowOff)%32;
906 int rowModDn = (irow - rowOff + 32 )%32;
907 // this is partial sum for the left half of the FPGA -- columns 6,7,8,9
908 lps[irow][rcolumn] = lps[irow][rcolumn] + twrs[rowModUp][lcolumn+6] + twrs[rowModDn][lcolumn+6];
909 }
910 }
911 }
912 }
913}
row
Appending html table to final .html summary file.

◆ jetOutAB()

void LVL1::gFEXJetAlgo::jetOutAB ( const gTowersType & jets,
std::array< int, 32 > & jetOutL,
std::array< int, 32 > & etaIndL,
std::array< int, 32 > & jetOutR,
std::array< int, 32 > & etaIndR ) const
privatevirtual

Definition at line 1391 of file gFEXJetAlgo.cxx.

1393 {
1394 // find maximum in each jet engine or either gJets and requires corresponding gBlock be above threhsold
1395 //loop over left engines
1396 for(int ieng=0; ieng<FEXAlgoSpaceDefs::ABCrows; ieng++){
1397 jetOutL[ieng] = 0;
1398 etaIndL[ieng] = 0;
1399 for(int localEta = 0; localEta<6; localEta++){
1400 if( jets[ieng][localEta] > jetOutL[ieng] ){
1401 jetOutL[ieng] = jets[ieng][localEta];
1402 etaIndL[ieng] = localEta;
1403 }
1404 }
1405 // truncation and mapping from 12 to 15 bits
1406 // https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/kw-dev/jet_finder_abc/common/jet_finder/HDL/jet_eng.vhd#L561
1407 // https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/kw-dev/jet_finder_abc/common/jet_finder/HDL/jet_eng.vhd#L561
1408 // Turncate to 15 bits as in VHDL (Corresponds to 13 TeV)
1409
1410 if( jetOutL[ieng] > FEXAlgoSpaceDefs::gJetMax ) jetOutL[ieng] = FEXAlgoSpaceDefs::gJetMax;
1411 if( jetOutL[ieng] < 0 ) jetOutL[ieng] = 0;
1412 }
1413 // loop over right engines
1414 for(int ieng=0; ieng<FEXAlgoSpaceDefs::ABCrows; ieng++){
1415 jetOutR[ieng] = 0;
1416 etaIndR[ieng] = 0;
1417 for(int localEta = 0; localEta < 6; localEta++){
1418 if( jets[ieng][localEta+6] > jetOutR[ieng] ){
1419 jetOutR[ieng] = jets[ieng][localEta+6];
1420 etaIndR[ieng] = localEta;
1421 }
1422 }
1423 // Turncate to 15 bits as in VHDL (orresponds to 13 TeV)
1424 if( jetOutR[ieng] > FEXAlgoSpaceDefs::gJetMax ) jetOutR[ieng] = FEXAlgoSpaceDefs::gJetMax;
1425 if( jetOutR[ieng] < 0 ) jetOutR[ieng] = 0;
1426 // https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/kw-dev/jet_finder_abc/common/jet_finder/HDL/jet_finder_abc.vhd#L1103
1427 // https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/kw-dev/jet_finder_abc/common/jet_finder/HDL/jet_finder_abc.vhd#L1119
1428
1429 }
1430
1431}
static constexpr int gJetMax

◆ largeRfinder()

std::vector< std::unique_ptr< gFEXJetTOB > > LVL1::gFEXJetAlgo::largeRfinder ( const gTowersType & Atwr,
const gTowersType & Btwr,
const gTowersType & CNtwr,
const gTowersType & Asat,
const gTowersType & Bsat,
const gTowersType & CNsat,
int pucA,
int pucB,
int pucC,
int gLJ_seedThrA,
int gLJ_seedThrB,
int gLJ_seedThrC,
int gJ_ptMinToTopoCounts1,
int gJ_ptMinToTopoCounts2,
int jetThreshold,
int gLJ_ptMinToTopoCounts1,
int gLJ_ptMinToTopoCounts2,
std::array< uint32_t, 7 > & ATOB1_dat,
std::array< uint32_t, 7 > & ATOB2_dat,
std::array< uint32_t, 7 > & BTOB1_dat,
std::array< uint32_t, 7 > & BTOB2_dat,
std::array< uint32_t, 7 > & CTOB1_dat,
std::array< uint32_t, 7 > & CTOB2_dat ) const
overridevirtual

Define a vector to be filled with all the TOBs of one event

Implements LVL1::IgFEXJetAlgo.

Definition at line 39 of file gFEXJetAlgo.cxx.

51 {
52
53 // Arrays for gJets
54 // s = status (1 if above threshold)
55 // v = value 200 MeV LSB
56 // eta and phi are bin numbers
57 std::array<int, FEXAlgoSpaceDefs::gJetTOBfib> gTOBsat = {{0,0,0,0,0,0}};
58 std::array<int, FEXAlgoSpaceDefs::gJetTOBfib> gJetTOBs = {{0,0,0,0,0,0}};
59 std::array<int, FEXAlgoSpaceDefs::gJetTOBfib> gJetTOBv = {{0,0,0,0,0,0}};
60 std::array<int, FEXAlgoSpaceDefs::gJetTOBfib> gJetTOBeta = {{0,0,0,0,0,0}};
61 std::array<int, FEXAlgoSpaceDefs::gJetTOBfib> gJetTOBphi = {{0,0,0,0,0,0}};
62
63 // Arrays for gBlocks (so far only 2 gBlocks per fiber)
64 // first index is for the fiber number (A 0 and 1, B 0 and 1, C P and C N )
65 // second index is for leading, sub-leading, and sub-sub-leading (not used)
66 std::array<std::array<int, 3>, FEXAlgoSpaceDefs::BTOBFIB> gBlockTOBv = {{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }};
67 std::array<std::array<int, 3>, FEXAlgoSpaceDefs::BTOBFIB> gBlockTOBeta = {{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }};
68 std::array<std::array<int, 3>, FEXAlgoSpaceDefs::BTOBFIB> gBlockTOBphi = {{ {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}}, {{0,0,0}} }};
69
70
71 //Alternate format for FPGC C (split in two)
72
73 gTowersJetEngine CNtwr;
74 gTowersJetEngine CPtwr;
75
76 for(int irow=0; irow<FEXAlgoSpaceDefs::ABCrows; irow++){
77 for(int jcolumn=0;jcolumn<FEXAlgoSpaceDefs::ABCcolumnsEng;jcolumn++){
78 CNtwr[irow][jcolumn] = Ctwr[irow][jcolumn] ;
79 CPtwr[irow][jcolumn] = Ctwr[irow][jcolumn+FEXAlgoSpaceDefs::ABCcolumnsEng] ;
80 }
81
82 for(unsigned int jcolumn=0;jcolumn<FEXAlgoSpaceDefs::ABcolumns;jcolumn++){
83
84 if( jcolumn < 6 ) {
85 // TOB1
86 if( Asat[irow][jcolumn] == 1 ) gTOBsat[0] = 1;
87 if( Bsat[irow][jcolumn] == 1 ) gTOBsat[2] = 1;
88 if( Csat[irow][jcolumn] == 1 ) gTOBsat[4] = 1;
89 } else {
90 //TOB2
91 if( Asat[irow][jcolumn] == 1 ) gTOBsat[1] = 1;
92 if( Bsat[irow][jcolumn] == 1 ) gTOBsat[3] = 1;
93 if( Csat[irow][jcolumn] == 1 ) gTOBsat[5] = 1;
94 }
95 }
96 }
97
98
99
100 gTowersType AjetsAlt;
101 singleHalf(Atwr,AjetsAlt);
102
103 gTowersPartialSums AlpsAltOut;
104 gTowersPartialSums ArpsAltOut;
105
106 InternalPartialAB(Atwr, AlpsAltOut, ArpsAltOut);
107
108 gTowersType BjetsAlt;
109 singleHalf(Btwr,BjetsAlt);
110
111 gTowersPartialSums BlpsAltOut;
112 gTowersPartialSums BrpsAltOut;
113
114 InternalPartialAB(Btwr, BlpsAltOut, BrpsAltOut);
115
116 gTowersType CjetsAlt;
117 singleHalf(Ctwr,CjetsAlt);
118
119 // Add the left local partial sum (zero if right column)
120 addInternalLin(AjetsAlt, AlpsAltOut);
121 addInternalLin(BjetsAlt, BlpsAltOut);
122
123 pileUpCorrectionAB(AjetsAlt,pucA);
124 pileUpCorrectionAB(BjetsAlt,pucB);
125 pileUpCorrectionAB(CjetsAlt,pucC);
126
127 // If the local sum is less than zero set it to zero
128 ZeroNegative(AjetsAlt);
129 ZeroNegative(BjetsAlt);
130 ZeroNegative(CjetsAlt);
131
132 // Add the right local partial sum (zero if right column)
133 addInternalRin(AjetsAlt, ArpsAltOut);
134 addInternalRin(BjetsAlt, BrpsAltOut);
135
136 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
137 for(unsigned int icolumn =0; icolumn<FEXAlgoSpaceDefs::ABcolumns; icolumn++){
138 // set 18 bits on
139 if (Asat[irow][icolumn] != 0){
140 }
141 }
142 }
143
144 SaturateJets( AjetsAlt, Asat, 0 );
145 SaturateJets( BjetsAlt, Bsat, 1 );
146 SaturateJets( CjetsAlt, Csat, 2 );
147
148 gTowersType AjetsRestricted;
149 gTowersType BjetsRestricted;
150 gTowersType CjetsRestricted;
151
152
153 for(int irow=0; irow<FEXAlgoSpaceDefs::ABCrows; irow++){
154 for(int icolumn=0; icolumn<FEXAlgoSpaceDefs::ABcolumns; icolumn++){
155 AjetsRestricted[irow][icolumn] = AjetsAlt[irow][icolumn];
156 BjetsRestricted[irow][icolumn] = BjetsAlt[irow][icolumn];
157 CjetsRestricted[irow][icolumn] = CjetsAlt[irow][icolumn];
158 }
159 }
160
161 // find gBlocks
162 gTowersType gBLKA;
163 gTowersType hasSeedA;
164 gBlockAB(Atwr, gBLKA, hasSeedA, gLJ_seedThrA);
165
166 SaturateBlocks(gBLKA, Asat, 0);
167
168 // TODO: Temporary fix to match FW saturation eta-alignment bug.
169 // In firmware, seed_ovf forces et9 to max positive → have_seed=1 unconditionally.
170 // The same −1 eta shift applies: overflow at col K forces have_seed at col K-1.
171 // @see jet_eng.vhd lines 849-870: seed_ovf → et9=max → have_seed=1
172 // Revert this block when the FW saturation alignment is fixed.
173 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++){
174 for(unsigned int icol = 0; icol < FEXAlgoSpaceDefs::ABcolumns; icol++){
175 if(Asat[irow][icol] && (icol % 6 != 0)) hasSeedA[irow][icol - 1] = 1;
176 }
177 }
178
179 gTowersType gBLKB;
180 gTowersType hasSeedB;
181 gBlockAB(Btwr, gBLKB, hasSeedB, gLJ_seedThrB);
182 SaturateBlocks(gBLKB, Bsat, 1);
183
184 // TODO: Temporary fix to match FW saturation eta-alignment bug.
185 // Revert this block when the FW saturation alignment is fixed.
186 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++){
187 for(unsigned int icol = 0; icol < FEXAlgoSpaceDefs::ABcolumns; icol++){
188 if(Bsat[irow][icol] && (icol % 6 != 0) && icol != 11) hasSeedB[irow][icol - 1] = 1;
189 }
190 }
191
192 gTowersType gBLKC;
193 gTowersType hasSeedC;
194 gBlockAB(Ctwr, gBLKC, hasSeedC, gLJ_seedThrC);
195 SaturateBlocks(gBLKC, Csat, 2);
196
197 // TODO: Temporary fix to match FW saturation eta-alignment bug.
198 // Revert this block when the FW saturation alignment is fixed.
199 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++){
200 for(unsigned int icol = 0; icol < FEXAlgoSpaceDefs::ABcolumns; icol++){
201 if(Csat[irow][icol] && (icol % 6 != 0) && (icol % 6 != 5)) hasSeedC[irow][icol - 1] = 1;
202 }
203 }
204
205 // sorting by jet engine -- not done in FPGA
206 std::array<int, 32> AgBlockOutL{};
207 std::array<int, 32> AgBlockEtaIndL{};
208 std::array<int, 32> AgBlockOutR{};
209 std::array<int, 32> AgBlockEtaIndR{};
210 blkOutAB(gBLKA, AgBlockOutL, AgBlockEtaIndL, AgBlockOutR, AgBlockEtaIndR);
211
212 std::array<int, 32> BgBlockOutL{};
213 std::array<int, 32> BgBlockEtaIndL{};
214 std::array<int, 32> BgBlockOutR{};
215 std::array<int, 32> BgBlockEtaIndR{};
216 blkOutAB(gBLKB, BgBlockOutL, BgBlockEtaIndL, BgBlockOutR, BgBlockEtaIndR);
217
218 std::array<int, 32> CgBlockOutL{};
219 std::array<int, 32> CgBlockEtaIndL{};
220 std::array<int, 32> CgBlockOutR{};
221 std::array<int, 32> CgBlockEtaIndR{};
222 blkOutAB(gBLKC, CgBlockOutL, CgBlockEtaIndL, CgBlockOutR, CgBlockEtaIndR) ;
223
224 // sorting by 192 blocks 0 = left, 1 = right
225 // second index is column number, the eta value is 2 + 6*column number + local eta
226
227 // find the leading and subleading gBlock in the left column of FPGA A
228 gBlockMax2(gBLKA, 1, 0, gBlockTOBv[0], gBlockTOBeta[0], gBlockTOBphi[0]);
229 // find the leading and subleading gBlock in the right column of FPGA A
230 gBlockMax2(gBLKA, 2, 1, gBlockTOBv[1], gBlockTOBeta[1], gBlockTOBphi[1]);
231
232 // find the leading and subleading gBlock in the left column of FPGA B
233 gBlockMax2(gBLKB, 3, 0, gBlockTOBv[2], gBlockTOBeta[2], gBlockTOBphi[2]);
234 // find the leading and subleading gBlock in the right column of FPGA B
235 gBlockMax2(gBLKB, 4, 1, gBlockTOBv[3], gBlockTOBeta[3], gBlockTOBphi[3]);
236
237 // find the leading and subleading gBlock in the CN column of FPGA C
238 gBlockMax2( gBLKC, 0, 0, gBlockTOBv[4], gBlockTOBeta[4], gBlockTOBphi[4]);
239 // find the leading and subleading gBlock in the CP column of FPGA C
240 gBlockMax2( gBLKC, 5, 1, gBlockTOBv[5], gBlockTOBeta[5], gBlockTOBphi[5]);
241
242 // in hardware vetos happen before remote sums come in.
243 gBlockVetoAB(AjetsRestricted, hasSeedA);
244 gBlockVetoAB(BjetsRestricted, hasSeedB);
245 gBlockVetoAB(CjetsRestricted, hasSeedC);
246
247 // calculate A & B remote partial sums first
248 gTowersPartialSums RAlps_out, RArps_out;
249 RemotePartialAB(Atwr, RAlps_out, RArps_out);
250
251 gTowersPartialSums RBlps_out, RBrps_out;
252 RemotePartialAB(Btwr, RBlps_out, RBrps_out);
253
254 gTowersPartialSums RCNrps_out, RCPlps_out;
255 RemotePartialCN(CNtwr, RCNrps_out);
256 RemotePartialCP(CPtwr, RCPlps_out);
257
258
260
261 // input partial sums from FPGA B to A (lps_out -> rps_in)
263
264 // input partial sums from FPGA B to A (lps_out -> rps_in)
266
267 }
268
270
272
274
275 }
276
277// this are added into the jets you have to truncate to the number of bits on the interFPGA communication
278
280
282
284
285 }
286
287 // Emulate firmware sum69o_del_ovf: after remote partial sums are added,
288 // re-saturate jets whose input towers were saturated.
289 // In firmware (jet_eng.vhd), sum69o_del_ovf = delayK(dat_ovf_in, SUM69O_DEL_DELAY)
290 // overrides sum69o_del to max positive *instead of* adding remote_ps.
291 // Without this, the simulation adds remote_ps on top of an already-max jet value,
292 // biasing the max-finder (jetOutAB) toward columns that receive remote partial sums
293 // and shifting the reported eta.
294 // The same -1 eta shift as SaturateJets applies here.
295 SaturateJets( AjetsRestricted, Asat, 0 );
296 SaturateJets( BjetsRestricted, Bsat, 1 );
297 SaturateJets( CjetsRestricted, Csat, 2 );
298
299 //Emulate switch to unsigned values by zeroing everything below the jet threshold
300 //https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/devel/common/jet_finder/HDL/jet_eng.vhd#L550
301
302 gJetVetoAB(AjetsRestricted, jetThreshold);
303 gJetVetoAB(BjetsRestricted, jetThreshold);
304 gJetVetoAB(CjetsRestricted, jetThreshold);
305
306 std::array<int, 32> AjetOutL;
307 std::array<int, 32> AetaIndL;
308 std::array<int, 32> AjetOutR;
309 std::array<int, 32> AetaIndR;
310
311
312 jetOutAB(AjetsRestricted, AjetOutL, AetaIndL, AjetOutR, AetaIndR);
313
314 std::array<int, 32> BjetOutL;
315 std::array<int, 32> BetaIndL;
316 std::array<int, 32> BjetOutR;
317 std::array<int, 32> BetaIndR;
318
319 jetOutAB(BjetsRestricted, BjetOutL, BetaIndL, BjetOutR, BetaIndR);
320
321 std::array<int, 32> CNjetOut;
322 std::array<int, 32> CNetaInd;
323 std::array<int, 32> CPjetOut;
324 std::array<int, 32> CPetaInd;
325
326 jetOutAB(CjetsRestricted, CNjetOut, CNetaInd, CPjetOut, CPetaInd);
327
328 gJetTOBgen(AjetOutL, AetaIndL, 0, jetThreshold, gJetTOBs, gJetTOBv, gJetTOBeta, gJetTOBphi);
329 gJetTOBgen(AjetOutR, AetaIndR, 1, jetThreshold, gJetTOBs, gJetTOBv, gJetTOBeta, gJetTOBphi);
330
331 gJetTOBgen(BjetOutL, BetaIndL, 2, jetThreshold, gJetTOBs, gJetTOBv, gJetTOBeta, gJetTOBphi);
332 gJetTOBgen(BjetOutR, BetaIndR, 3, jetThreshold, gJetTOBs, gJetTOBv, gJetTOBeta, gJetTOBphi);
333
334 gJetTOBgen(CNjetOut, CNetaInd, 4, jetThreshold, gJetTOBs, gJetTOBv, gJetTOBeta, gJetTOBphi);
335 gJetTOBgen(CPjetOut, CPetaInd, 5, jetThreshold, gJetTOBs, gJetTOBv, gJetTOBeta, gJetTOBphi);
336
338 std::vector<std::unique_ptr<gFEXJetTOB>> tobs_v;
339 tobs_v.resize(14);
340
341 // fill in TOBs
342 ATOB1_dat[0] = 0;
343 BTOB1_dat[0] = 0;
344 CTOB1_dat[0] = 0;
345
346 ATOB2_dat[0] = (( pucA & 0x0000FFFF ) << 8);
347 BTOB2_dat[0] = (( pucB & 0x0000FFFF ) << 8);
348 CTOB2_dat[0] = (( pucC & 0x0000FFFF ) << 8);
349
350 // //First available TOBs are the gRho for each central FPGA
351 tobs_v[0] = std::make_unique<gFEXJetTOB>();
352 tobs_v[0]->setWord(ATOB2_dat[0]);
353 tobs_v[0]->setET(pucA);
354 tobs_v[0]->setEta(0);
355 tobs_v[0]->setPhi(0);
356 tobs_v[0]->setTobID(0);
357 tobs_v[0]->setStatus(1);//is 1 only if rho calculation is valid, but rho is not calculated at the moment
358
359 tobs_v[1] = std::make_unique<gFEXJetTOB>();
360 tobs_v[1]->setWord(BTOB2_dat[0]);
361 tobs_v[1]->setET(pucB);
362 tobs_v[1]->setEta(0);
363 tobs_v[1]->setPhi(0);
364 tobs_v[1]->setTobID(0);
365 tobs_v[1]->setStatus(1);//is 1 only if rho calculation is valid, but rho is not calculated at the moment
366
367 // leading gBlocks (available first and go in first TOB value)
368 // TOBs 2-5 are leading gBlocks
369 ATOB1_dat[1] = 0x00000001; //set the TOB ID in the corresponding slot (LSB)
370 if( gBlockTOBv[0][0] > gJ_ptMinToTopoCounts2 ) ATOB1_dat[1] = ATOB1_dat[1] | 0x00000080;//status
371 ATOB1_dat[1] = ATOB1_dat[1] | ( ( gBlockTOBv[0][0] & 0x00000FFF ) << 8);
372 ATOB1_dat[1] = ATOB1_dat[1] | ( ( gBlockTOBeta[0][0] & 0x0000003F ) <<20);
373 ATOB1_dat[1] = ATOB1_dat[1] | ( ( gBlockTOBphi[0][0] & 0x0000001F ) <<26);
374
375 tobs_v[2] = std::make_unique<gFEXJetTOB>();
376 tobs_v[2]->setWord(ATOB1_dat[1]);
377 tobs_v[2]->setET(gBlockTOBv[0][0]);
378 tobs_v[2]->setEta(gBlockTOBeta[0][0]);
379 tobs_v[2]->setPhi(gBlockTOBphi[0][0]);
380 tobs_v[2]->setTobID(1);
381 if( gBlockTOBv[0][0] > gJ_ptMinToTopoCounts2 ) tobs_v[2]->setStatus(1);
382 else tobs_v[2]->setStatus(0);
383
384 ATOB2_dat[1] = 0x00000002;
385 if( gBlockTOBv[1][0] > gJ_ptMinToTopoCounts1 ) ATOB2_dat[1] = ATOB2_dat[1] | 0x00000080;
386 ATOB2_dat[1] = ATOB2_dat[1] | ( ( gBlockTOBv[1][0] & 0x00000FFF ) << 8);
387 ATOB2_dat[1] = ATOB2_dat[1] | ( ( gBlockTOBeta[1][0] & 0x0000003F ) <<20);
388 ATOB2_dat[1] = ATOB2_dat[1] | ( ( gBlockTOBphi[1][0] & 0x0000001F ) <<26);
389
390 tobs_v[3] = std::make_unique<gFEXJetTOB>();
391 tobs_v[3]->setWord(ATOB2_dat[1]);
392 tobs_v[3]->setET(gBlockTOBv[1][0]);
393 tobs_v[3]->setEta(gBlockTOBeta[1][0]);
394 tobs_v[3]->setPhi(gBlockTOBphi[1][0]);
395 tobs_v[3]->setTobID(2);
396 if( gBlockTOBv[1][0] > gJ_ptMinToTopoCounts1 ) tobs_v[3]->setStatus(1);
397 else tobs_v[3]->setStatus(0);
398
399
400 BTOB1_dat[1] = 0x00000001;
401 if( gBlockTOBv[2][0] > gJ_ptMinToTopoCounts1 ) BTOB1_dat[1] = BTOB1_dat[1] | 0x00000080;
402 BTOB1_dat[1] = BTOB1_dat[1] | ( ( gBlockTOBv[2][0] & 0x00000FFF ) << 8);
403 BTOB1_dat[1] = BTOB1_dat[1] | ( ( gBlockTOBeta[2][0] & 0x0000003F ) <<20);
404 BTOB1_dat[1] = BTOB1_dat[1] | ( ( gBlockTOBphi[2][0] & 0x0000001F) <<26);
405
406 tobs_v[4] = std::make_unique<gFEXJetTOB>();
407 tobs_v[4]->setWord(BTOB1_dat[1]);
408 tobs_v[4]->setET(gBlockTOBv[2][0]);
409 tobs_v[4]->setEta(gBlockTOBeta[2][0]);
410 tobs_v[4]->setPhi(gBlockTOBphi[2][0]);
411 tobs_v[4]->setTobID(1);
412 if( gBlockTOBv[2][0] > gJ_ptMinToTopoCounts1 ) tobs_v[4]->setStatus(1);
413 else tobs_v[4]->setStatus(0);
414
415
416 BTOB2_dat[1] = 0x00000002;
417 if( gBlockTOBv[3][0] > gJ_ptMinToTopoCounts2 ) BTOB2_dat[1] = BTOB2_dat[1] | 0x00000080;
418 BTOB2_dat[1] = BTOB2_dat[1] | ( ( gBlockTOBv[3][0] & 0x00000FFF ) << 8);
419 BTOB2_dat[1] = BTOB2_dat[1] | ( ( gBlockTOBeta[3][0] & 0x0000003F ) <<20);
420 BTOB2_dat[1] = BTOB2_dat[1] | ( ( gBlockTOBphi[3][0] & 0x0000001F ) <<26);
421
422 tobs_v[5] = std::make_unique<gFEXJetTOB>();
423 tobs_v[5]->setWord(BTOB2_dat[1]);
424 tobs_v[5]->setET(gBlockTOBv[3][0]);
425 tobs_v[5]->setEta(gBlockTOBeta[3][0]);
426 tobs_v[5]->setPhi(gBlockTOBphi[3][0]);
427 tobs_v[5]->setTobID(2);
428 if( gBlockTOBv[3][0] > gJ_ptMinToTopoCounts2 ) tobs_v[5]->setStatus(1);
429 else tobs_v[5]->setStatus(0);
430
431
432 CTOB1_dat[1] = 0x00000001;
433 if( gBlockTOBv[4][0] > gJ_ptMinToTopoCounts1 ) CTOB1_dat[1] = CTOB1_dat[1] | 0x00000080;
434 CTOB1_dat[1] = CTOB1_dat[1] | ( ( gBlockTOBv[4][0] & 0x00000FFF ) << 8);
435 CTOB1_dat[1] = CTOB1_dat[1] | ( ( gBlockTOBeta[4][0] & 0x0000003F ) <<20);
436 CTOB1_dat[1] = CTOB1_dat[1] | ( ( gBlockTOBphi[4][0] & 0x0000001F) <<26);
437
438
439 CTOB2_dat[1] = 0x00000002;
440 if( gBlockTOBv[5][0] > gJ_ptMinToTopoCounts2) CTOB2_dat[1] = CTOB2_dat[1] | 0x00000080;
441 CTOB2_dat[1] = CTOB2_dat[1] | ( ( gBlockTOBv[5][0] & 0x00000FFF ) << 8);
442 CTOB2_dat[1] = CTOB2_dat[1] | ( ( gBlockTOBeta[5][0] & 0x0000003F ) <<20);
443 CTOB2_dat[1] = CTOB2_dat[1] | ( ( gBlockTOBphi[5][0] & 0x0000001F ) <<26);
444
445
446 // subleading gBlocks
447 // TOBs 6-9 are subleading gBlocks
448 ATOB1_dat[2] = 0x00000003;
449 if( gBlockTOBv[0][1] > gJ_ptMinToTopoCounts2 ) ATOB1_dat[2] = ATOB1_dat[2] | 0x00000080;
450 ATOB1_dat[2] = ATOB1_dat[2] | ( ( gBlockTOBv[0][1] & 0x00000FFF ) << 8);
451 ATOB1_dat[2] = ATOB1_dat[2] | ( ( gBlockTOBeta[0][1] & 0x0000003F ) <<20);
452 ATOB1_dat[2] = ATOB1_dat[2] | ( ( gBlockTOBphi[0][1] & 0x0000001F ) <<26);
453
454 tobs_v[6] = std::make_unique<gFEXJetTOB>();
455 tobs_v[6]->setWord(ATOB1_dat[2]);
456 tobs_v[6]->setET(gBlockTOBv[0][1]);
457 tobs_v[6]->setEta(gBlockTOBeta[0][1]);
458 tobs_v[6]->setPhi(gBlockTOBphi[0][1]);
459 tobs_v[6]->setTobID(3);
460 if( gBlockTOBv[0][1] > gJ_ptMinToTopoCounts2 ) tobs_v[6]->setStatus(1);
461 else tobs_v[6]->setStatus(0);
462
463
464 ATOB2_dat[2] = 0x00000004;
465 if( gBlockTOBv[1][1] > gJ_ptMinToTopoCounts1 ) ATOB2_dat[2] = ATOB2_dat[2] | 0x00000080;
466 ATOB2_dat[2] = ATOB2_dat[2] | ( ( gBlockTOBv[1][1] & 0x00000FFF ) << 8);
467 ATOB2_dat[2] = ATOB2_dat[2] | ( ( gBlockTOBeta[1][1] & 0x0000003F ) <<20);
468 ATOB2_dat[2] = ATOB2_dat[2] | ( ( gBlockTOBphi[1][1] & 0x0000001F ) <<26);
469
470 tobs_v[7] = std::make_unique<gFEXJetTOB>();
471 tobs_v[7]->setWord(ATOB2_dat[2]);
472 tobs_v[7]->setET(gBlockTOBv[1][1]);
473 tobs_v[7]->setEta(gBlockTOBeta[1][1]);
474 tobs_v[7]->setPhi(gBlockTOBphi[1][1]);
475 tobs_v[7]->setTobID(4);
476 if( gBlockTOBv[1][1] > gJ_ptMinToTopoCounts1 ) tobs_v[7]->setStatus(1);
477 else tobs_v[7]->setStatus(0);
478
479
480 BTOB1_dat[2] = 0x00000003;
481 if( gBlockTOBv[2][1] > gJ_ptMinToTopoCounts1 ) BTOB1_dat[2] = BTOB1_dat[2] | 0x00000080;
482 BTOB1_dat[2] = BTOB1_dat[2] | ( ( gBlockTOBv[2][1] & 0x00000FFF ) << 8);
483 BTOB1_dat[2] = BTOB1_dat[2] | ( ( gBlockTOBeta[2][1] & 0x0000003F ) <<20);
484 BTOB1_dat[2] = BTOB1_dat[2] | ( ( gBlockTOBphi[2][1] & 0x0000001F ) <<26);
485
486 tobs_v[8] = std::make_unique<gFEXJetTOB>();
487 tobs_v[8]->setWord(BTOB1_dat[2]);
488 tobs_v[8]->setET(gBlockTOBv[2][1]);
489 tobs_v[8]->setEta(gBlockTOBeta[2][1]);
490 tobs_v[8]->setPhi(gBlockTOBphi[2][1]);
491 tobs_v[8]->setTobID(3);
492 if( gBlockTOBv[2][1] > gJ_ptMinToTopoCounts1 ) tobs_v[8]->setStatus(1);
493 else tobs_v[8]->setStatus(0);
494
495
496 BTOB2_dat[2] = 0x00000004;
497 if( gBlockTOBv[3][1] > gJ_ptMinToTopoCounts2 ) BTOB2_dat[2] = BTOB2_dat[2] | 0x00000080;
498 BTOB2_dat[2] = BTOB2_dat[2] | ( ( gBlockTOBv[3][1] & 0x00000FFF ) << 8);
499 BTOB2_dat[2] = BTOB2_dat[2] | ( ( gBlockTOBeta[3][1] & 0x0000003F ) <<20);
500 BTOB2_dat[2] = BTOB2_dat[2] | ( ( gBlockTOBphi[3][1] & 0x0000001F ) <<26);
501
502 tobs_v[9] = std::make_unique<gFEXJetTOB>();
503 tobs_v[9]->setWord(BTOB2_dat[2]);
504 tobs_v[9]->setET(gBlockTOBv[3][1]);
505 tobs_v[9]->setEta(gBlockTOBeta[3][1]);
506 tobs_v[9]->setPhi(gBlockTOBphi[3][1]);
507 tobs_v[9]->setTobID(4);
508 if( gBlockTOBv[3][1] > gJ_ptMinToTopoCounts2 ) tobs_v[9]->setStatus(1);
509 else tobs_v[9]->setStatus(0);
510
511
512 CTOB1_dat[2] = 0x00000003;
513 if( gBlockTOBv[4][1] > gJ_ptMinToTopoCounts1 ) CTOB1_dat[2] = CTOB1_dat[2] | 0x00000080;
514 CTOB1_dat[2] = CTOB1_dat[2] | ( ( gBlockTOBv[4][1] & 0x00000FFF ) << 8);
515 CTOB1_dat[2] = CTOB1_dat[2] | ( ( gBlockTOBeta[4][1] & 0x0000003F ) <<20);
516 CTOB1_dat[2] = CTOB1_dat[2] | ( ( gBlockTOBphi[4][1] & 0x0000001F ) <<26);
517
518 CTOB2_dat[2] = 0x00000004;
519 if( gBlockTOBv[5][1] > gJ_ptMinToTopoCounts2 ) CTOB2_dat[2] = CTOB2_dat[2] | 0x00000080;
520 CTOB2_dat[2] = CTOB2_dat[2] | ( ( gBlockTOBv[5][1] & 0x00000FFF ) << 8);
521 CTOB2_dat[2] = CTOB2_dat[2] | ( ( gBlockTOBeta[5][1] & 0x0000003F ) <<20);
522 CTOB2_dat[2] = CTOB2_dat[2] | ( ( gBlockTOBphi[5][1] & 0x0000001F ) <<26);
523
524
525 // finally the main event -- lead gJET
526 // according the specification https://docs.google.com/spreadsheets/d/15YVVtGofhXMtV7jXRFzWO0FVUtUAjS-X-aQjh3FKE_w/edit#gid=523371660
527 // we should have an lsb of 3.2 GeV -- so ignore lower 4 bits.
528
529 // TOBs 10-13 are leading gJets
530 // shift is done before sorting as in firmware!
531 int tobvShift = 8;
532 int tobvMask = 0x00000FFF;
533
534
535 ATOB1_dat[3] = 0x00000005;
536 if( gJetTOBv[0] > gLJ_ptMinToTopoCounts2 ) ATOB1_dat[3] = ATOB1_dat[3] | 0x00000080;
537 ATOB1_dat[3] = ATOB1_dat[3] | ( ( gJetTOBv[0] & tobvMask) << tobvShift);
538 ATOB1_dat[3] = ATOB1_dat[3] | ( ( gJetTOBeta[0] & 0x0000003F ) <<20);
539 ATOB1_dat[3] = ATOB1_dat[3] | ( ( gJetTOBphi[0] & 0x0000001F ) <<26);
540
541 tobs_v[10] = std::make_unique<gFEXJetTOB>();
542 tobs_v[10]->setWord(ATOB1_dat[3]);
543 tobs_v[10]->setET(gJetTOBv[0]);
544 tobs_v[10]->setEta(gJetTOBeta[0]);
545 tobs_v[10]->setPhi(gJetTOBphi[0]);
546 tobs_v[10]->setTobID(5);
547 if(gJetTOBv[0] > gLJ_ptMinToTopoCounts2 ) tobs_v[10]->setStatus(1);
548 else tobs_v[10]->setStatus(0);
549
550
551 ATOB2_dat[3] = 0x00000006;
552 if( gJetTOBv[1] > gLJ_ptMinToTopoCounts1 ) ATOB2_dat[3] = ATOB2_dat[3] | 0x00000080;
553 ATOB2_dat[3] = ATOB2_dat[3] | ( ( gJetTOBv[1] & tobvMask ) << tobvShift);
554 ATOB2_dat[3] = ATOB2_dat[3] | ( ( gJetTOBeta[1] & 0x0000003F ) <<20);
555 ATOB2_dat[3] = ATOB2_dat[3] | ( ( gJetTOBphi[1] & 0x0000001F ) <<26);
556
557 tobs_v[11] = std::make_unique<gFEXJetTOB>();
558 tobs_v[11]->setWord(ATOB2_dat[3]);
559 tobs_v[11]->setET(gJetTOBv[1]);
560 tobs_v[11]->setEta(gJetTOBeta[1]);
561 tobs_v[11]->setPhi(gJetTOBphi[1]);
562 tobs_v[11]->setTobID(6);
563 if( gJetTOBv[1] > gLJ_ptMinToTopoCounts1 ) tobs_v[11]->setStatus(1);
564 else tobs_v[11]->setStatus(0);
565
566
567 BTOB1_dat[3] = 0x00000005;
568 if( gJetTOBv[2] > gLJ_ptMinToTopoCounts1 ) BTOB1_dat[3] = BTOB1_dat[3] | 0x00000080;
569 BTOB1_dat[3] = BTOB1_dat[3] | ( ( gJetTOBv[2] & tobvMask) << tobvShift);
570 BTOB1_dat[3] = BTOB1_dat[3] | ( ( gJetTOBeta[2] & 0x0000003F ) <<20);
571 BTOB1_dat[3] = BTOB1_dat[3] | ( ( gJetTOBphi[2] & 0x0000001F ) <<26);
572
573 tobs_v[12] = std::make_unique<gFEXJetTOB>();
574 tobs_v[12]->setWord(BTOB1_dat[3]);
575 tobs_v[12]->setET(gJetTOBv[2]);
576 tobs_v[12]->setEta(gJetTOBeta[2]);
577 tobs_v[12]->setPhi(gJetTOBphi[2]);
578 tobs_v[12]->setTobID(5);
579 if( gJetTOBv[2] > gLJ_ptMinToTopoCounts1 ) tobs_v[12]->setStatus(1);
580 else tobs_v[12]->setStatus(0);
581
582
583 BTOB2_dat[3] = 0x00000006;
584 if( gJetTOBv[3] > gLJ_ptMinToTopoCounts2 ) BTOB2_dat[3] = BTOB2_dat[3] | 0x00000080;
585 BTOB2_dat[3] = BTOB2_dat[3] | ( ( gJetTOBv[3] & tobvMask ) << tobvShift);
586 BTOB2_dat[3] = BTOB2_dat[3] | ( ( gJetTOBeta[3] & 0x0000003F ) <<20);
587 BTOB2_dat[3] = BTOB2_dat[3] | ( ( gJetTOBphi[3] & 0x0000001F ) <<26);
588
589 tobs_v[13] = std::make_unique<gFEXJetTOB>();
590 tobs_v[13]->setWord(BTOB2_dat[3]);
591 tobs_v[13]->setET(gJetTOBv[3]);
592 tobs_v[13]->setEta(gJetTOBeta[3]);
593 tobs_v[13]->setPhi(gJetTOBphi[3]);
594 tobs_v[13]->setTobID(6);
595 if( gJetTOBv[3] > gLJ_ptMinToTopoCounts2 ) tobs_v[13]->setStatus(1);
596 else tobs_v[13]->setStatus(0);
597
598 // // CECILIA - TO BE CHECKED
599 CTOB1_dat[3] = 0x00000005;
600 if( gJetTOBv[4] > gLJ_ptMinToTopoCounts1 ) CTOB1_dat[3] = CTOB1_dat[3] | 0x00000080;
601 CTOB1_dat[3] = CTOB1_dat[3] | ( ( gJetTOBv[4] & tobvMask) << tobvShift);
602 CTOB1_dat[3] = CTOB1_dat[3] | ( ( gJetTOBeta[4] & 0x0000003F ) <<20);
603 CTOB1_dat[3] = CTOB1_dat[3] | ( ( gJetTOBphi[4] & 0x0000001F ) <<26);
604
605 CTOB2_dat[3] = 0x00000006;
606 if( gJetTOBv[5] > gLJ_ptMinToTopoCounts2 ) CTOB2_dat[3] = CTOB2_dat[3] | 0x00000080;
607 CTOB2_dat[3] = CTOB2_dat[3] | ( ( gJetTOBv[5] & tobvMask ) << tobvShift);
608 CTOB2_dat[3] = CTOB2_dat[3] | ( ( gJetTOBeta[5] & 0x0000003F ) <<20);
609 CTOB2_dat[3] = CTOB2_dat[3] | ( ( gJetTOBphi[5] & 0x0000001F ) <<26);
610
611
612// saturation currently not set in firmware
613//
614//
615 bool setSat = 0;
616 if ( setSat) {
617 if( gTOBsat[0] ) {
618 ATOB1_dat[1] = ( ATOB1_dat[1] | 0x80000000 );
619 ATOB1_dat[3] = ( ATOB1_dat[3] | 0x80000000 );
620 }
621
622 if( gTOBsat[1] ) {
623 ATOB2_dat[1] = ( ATOB2_dat[1] | 0x80000000 );
624 ATOB2_dat[3] = ( ATOB2_dat[3] | 0x80000000 );
625 }
626
627 if( gTOBsat[2] ) {
628 BTOB1_dat[1] = ( BTOB1_dat[1] | 0x80000000 );
629 BTOB1_dat[3] = ( BTOB1_dat[3] | 0x80000000 );
630 }
631
632 if( gTOBsat[3] ) {
633 BTOB2_dat[1] = ( BTOB2_dat[1] | 0x80000000 );
634 BTOB2_dat[3] = ( BTOB2_dat[3] | 0x80000000 );
635 }
636
637 if( gTOBsat[4] ) {
638 CTOB1_dat[1] = ( CTOB1_dat[1] | 0x80000000 );
639 CTOB1_dat[3] = ( CTOB1_dat[3] | 0x80000000 );
640 }
641
642 if( gTOBsat[5] ) {
643 CTOB2_dat[1] = ( CTOB2_dat[1] | 0x80000000 );
644 CTOB2_dat[3] = ( CTOB2_dat[3] | 0x80000000 );
645 }
646 }
647
648 // zero tob 4 word
649
650 ATOB1_dat[4] = 0 ;
651 ATOB2_dat[4] = 0 ;
652 BTOB1_dat[4] = 0 ;
653 BTOB2_dat[4] = 0 ;
654 CTOB1_dat[4] = 0 ;
655 CTOB2_dat[4] = 0 ;
656
657
658 // add seven bits as in the hardware of BCID in 6th TOB word ( index 5)
659 int BCID = 0;
660
661 ATOB1_dat[5] = ( (BCID&0x0000007F)<<8 ) ;
662 ATOB2_dat[5] = ( (BCID&0x0000007F)<<8 ) ;
663 BTOB1_dat[5] = ( (BCID&0x0000007F)<<8 ) ;
664 BTOB2_dat[5] = ( (BCID&0x0000007F)<<8 ) ;
665 CTOB1_dat[5] = ( (BCID&0x0000007F)<<8 ) ;
666 CTOB2_dat[5] = ( (BCID&0x0000007F)<<8 ) ;
667
668 // 3 is gFEX FEX number, set CRC to zero for now
669 int CRC = 0;
670
671
672 ATOB1_dat[6] = 0x000000BC | ( (BCID&0x0000000F)<<8 ) | (3<<12) | (CRC<<23);
673 ATOB2_dat[6] = 0x000000BC | ( (BCID&0x0000000F)<<8 ) | (3<<12) | (CRC<<23);
674 BTOB1_dat[6] = 0x000000BC | ( (BCID&0x0000000F)<<8 ) | (3<<12) | (CRC<<23);
675 BTOB2_dat[6] = 0x000000BC | ( (BCID&0x0000000F)<<8 ) | (3<<12) | (CRC<<23);
676 CTOB1_dat[6] = 0x000000BC | ( (BCID&0x0000000F)<<8 ) | (3<<12) | (CRC<<23);
677 CTOB2_dat[6] = 0x000000BC | ( (BCID&0x0000000F)<<8 ) | (3<<12) | (CRC<<23);
678
679
680
681 return tobs_v;
682
683}
static constexpr int PS_UPPER_AB
static constexpr int BTOBFIB
static constexpr bool ENABLE_INTER_AB
static constexpr bool ENABLE_INTER_ABC
static constexpr bool ENABLE_INTER_C
static constexpr int PS_SHIFT_C
static constexpr int PS_LOWER_C
static constexpr int ABcolumns
static constexpr int PS_SHIFT_AB
static constexpr int PS_LOWER_AB
static constexpr int PS_UPPER_C
virtual void gBlockMax2(const gTowersType &gBlkSum, int BjetColumn, int localColumn, std::array< int, 3 > &gBlockV, std::array< int, 3 > &gBlockEta, std::array< int, 3 > &gBlockPhi) const
virtual void gBlockVetoAB(gTowersType &jets, gTowersType &hasSeed) const
virtual void pileUpCorrectionAB(gTowersType &jets, int puc) const
virtual void addRemoteCPin(gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void ZeroNegative(gTowersType &jets) const
virtual void addRemoteLin(gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void gJetVetoAB(gTowersType &twrs, int jet_threshold) const
virtual void blkOutAB(gTowersType &blocks, std::array< int, 32 > &jetOutL, std::array< int, 32 > &etaIndL, std::array< int, 32 > &jetOutR, std::array< int, 32 > &etaIndR) const
virtual void InternalPartialAB(const gTowersType &twrs, gTowersPartialSums &lps, gTowersPartialSums &rps) const
virtual void RemotePartialCN(const gTowersJetEngine &twrs, gTowersPartialSums &rps) const
virtual void addRemoteRin(gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void SaturateJets(gTowersType &jets, const gTowersType &sat, int fpga) const
virtual void singleHalf(const gTowersType &twrs, gTowersType &FPGAsum) const
virtual void RemotePartialCP(const gTowersJetEngine &twrs, gTowersPartialSums &lps) const
virtual void gBlockAB(const gTowersType &twrs, gTowersType &gBlkSum, gTowersType &hasSeed, int seedThreshold) const
virtual void gJetTOBgen(const std::array< int, FEXAlgoSpaceDefs::ABCrows > &jetOut, const std::array< int, FEXAlgoSpaceDefs::ABCrows > &etaInd, int TOBnum, int jetThreshold, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBs, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBv, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBeta, std::array< int, FEXAlgoSpaceDefs::gJetTOBfib > &gJetTOBphi) const
virtual void addRemoteCNin(gTowersType &jets, const gTowersPartialSums &partial, int ps_upper, int ps_lower, int ps_shift) const
virtual void SaturateBlocks(gTowersType &gBlkSum, const gTowersType &sat, int fpga) const
virtual void addInternalRin(gTowersType &jets, gTowersPartialSums &partial) const
virtual void jetOutAB(const gTowersType &jets, std::array< int, 32 > &jetOutL, std::array< int, 32 > &etaIndL, std::array< int, 32 > &jetOutR, std::array< int, 32 > &etaIndR) const
virtual void addInternalLin(gTowersType &jets, gTowersPartialSums &partial) const
virtual void RemotePartialAB(const gTowersType &twrs, gTowersPartialSums &lps, gTowersPartialSums &rps) const
std::array< std::array< int, 12 >, 32 > gTowersType
Definition IgFEXFPGA.h:25
std::array< std::array< int, 4 >, 32 > gTowersPartialSums
Definition gFEXJetAlgo.h:29

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ pileUpCalculation()

void LVL1::gFEXJetAlgo::pileUpCalculation ( gTowersType & twrs,
int rhoThreshold_Max,
int inputScale,
int & PUCp,
int & PUC_JWJ ) const
overridevirtual

Implements LVL1::IgFEXJetAlgo.

Definition at line 1434 of file gFEXJetAlgo.cxx.

1434 {
1435 // input are 50 MeV "fine" scale towers (i.e. inputScale = 1)
1436 // to use 200 MeV towers use inputScale = 4
1437 // PUCp output is the pileup correction for 69 towers at 200 MeV energy scale
1438
1439 int rows = twrs.size();
1440 int cols = twrs[0].size();
1441 int pucSum = 0;
1442 int pucSumJWJ = 0;
1443 int nSum = 0;
1444 for(int irow=0; irow<rows; irow++){
1445 for( int icolumn=0; icolumn<cols; icolumn++){
1446 int fineGT = twrs[irow][icolumn]*inputScale;
1447 // set floor and ceiling here (currently 255 and -256 )
1450
1451 if( fineGT < rhoThreshold_Max ) {
1452 pucSum = pucSum + fineGT;
1453 nSum = nSum + 1;
1454 }
1455 }
1456 }
1457 // in firmware this is done with a lookup table see https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/devel/common/jet_finder/HDL/inv_lut19.vhd
1458 // See also https://gitlab.cern.ch/atlas-l1calo/gfex/firmware/-/blob/devel/common/jet_finder/HDL/gt_build_all_AB.vhd#L1471
1459
1460 // oneOverN is stored as a 32 bit number in inv_lut19
1461 unsigned int oneOverNTab = 69<<25;
1462 unsigned int JWJoneOverNTab = 69<<25;
1463 if( nSum > 0 && nSum < 385 ) {
1464 oneOverNTab = FEXAlgoSpaceDefs::inv19[nSum];
1465 JWJoneOverNTab = FEXAlgoSpaceDefs::jwjinv19[nSum];
1466 } else {
1467 oneOverNTab = 0;
1468 JWJoneOverNTab = 0;
1469 }
1470
1471 int oneOverN = oneOverNTab;
1472 int JWJoneOverN = JWJoneOverNTab;
1473
1474 // largest value should be 255*2^14 ~ 2^22 -- should easily fit in int -- try expliciting putting in int here.
1475 pucSumJWJ = pucSum * JWJoneOverN;
1476 pucSum = pucSum * oneOverN;
1477
1478 // PUChres = pucSum;
1479
1480 // current system 19 bits in table (69*4096 is max value) sign exten
1481 pucSum = ( pucSum >> 14);
1482 pucSumJWJ = ( pucSumJWJ >> 16);
1483 PUCp = pucSum;
1484 PUC_JWJ = pucSumJWJ;
1485
1486}
static constexpr std::array< unsigned int, 513 > jwjinv19
static constexpr std::array< unsigned int, 385 > inv19
static constexpr int fineCeiling
static constexpr int fineFloor

◆ pileUpCorrectionAB()

void LVL1::gFEXJetAlgo::pileUpCorrectionAB ( gTowersType & jets,
int puc ) const
privatevirtual

Definition at line 936 of file gFEXJetAlgo.cxx.

936 {
937 int rows = jets.size();
938 int cols = jets[0].size();
939 for(int irow=0;irow<rows;irow++){
940 for(int icolumn=0;icolumn<cols;icolumn++){
941 jets[irow][icolumn] = jets[irow][icolumn] - puc;
942 }
943 }
944}

◆ RemotePartialAB()

void LVL1::gFEXJetAlgo::RemotePartialAB ( const gTowersType & twrs,
gTowersPartialSums & lps,
gTowersPartialSums & rps ) const
privatevirtual

Definition at line 686 of file gFEXJetAlgo.cxx.

686 {
687
688 // Computes partial sums for FPGA A or B
689 // twrs are the 32 x 12 = 284 gTowers in FPGA A or B
690
691 // number of rows above/below for right partial sum
692 // when sending to the right send values for largest partial sum first, i.e. for column 0
693 typedef std::array<std::array<int, 4>, 4> gTowersNeighbours;
694 gTowersNeighbours NUpDwnR = {{ {{2,3,4,4}}, {{0,2,3,4}}, {{0,0,2,3}}, {{0,0,0,2}} }};
695
696 // number of rows above or below for left partial sum
697 // when sending to the left send values for smallest partial sum first (i.e. for column 8 )
698 gTowersNeighbours NUpDwnL = {{ {{2,0,0,0}}, {{3,2,0,0}}, {{4,3,2,0}}, {{4,4,3,2}} }};
699
700 // Do partial sum for output to right FPGA first
701 for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
702 for(int rcolumn = 0; rcolumn<FEXAlgoSpaceDefs::n_partial; rcolumn++){
703 // start calculating right partial sums for remote column rcolumn
704 rps[irow][rcolumn] = 0;
705 for(int lcolumn = 0; lcolumn<FEXAlgoSpaceDefs::n_partial; lcolumn++){
706 // add in any energy from towers in this row
707 // no need of modular arithmetic
708 if ( NUpDwnR[rcolumn][lcolumn] > 0 ) {
709 rps[irow][rcolumn] = rps[irow][rcolumn] + twrs[irow][lcolumn+8];
710 }
711 // now add rup1, rup2, rup3, rup4, ldn1, ldn2, ln3, ln4 -- use a loop instead of enumeratin in firmware
712 for( int rowOff = 1 ; rowOff < NUpDwnR[rcolumn][lcolumn]+1; rowOff++){
713 int rowModUp = (irow + rowOff)%32;
714 int rowModDn = (irow - rowOff + 32 )%32;
715 // printf("row %d remote column %d local column %d rowOff %d rowModUp %d rowModDn %d \n",
716 rps[irow][rcolumn] = rps[irow][rcolumn] + twrs[rowModUp][lcolumn+8] + twrs[rowModDn][lcolumn+8];
717 }
718 }
719 }
720 }
721
722 // do partial sum for output to left FPGA second
723 for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
724 for(int rcolumn = 0; rcolumn<FEXAlgoSpaceDefs::n_partial; rcolumn++){
725 // start calculating right partial sums for remote column rcolumn
726 lps[irow][rcolumn] = 0;
727 for(int lcolumn = 0; lcolumn<FEXAlgoSpaceDefs::n_partial; lcolumn++){
728 // add in any energy from towers in this row
729 // no need of modular arithmetic
730 if ( NUpDwnL[rcolumn][lcolumn] > 0 ) {
731 lps[irow][rcolumn] = lps[irow][rcolumn] + twrs[irow][lcolumn];
732 }
733 // now add rup1, rup2, rup3, rup4, ldn1, ldn2, ln3, ln4 -- use a loop instead of enumeratin in firmware
734 for( int rowOff = 1 ; rowOff < NUpDwnL[rcolumn][lcolumn]+1; rowOff++){
735 int rowModUp = (irow + rowOff)%32;
736 int rowModDn = (irow - rowOff + 32 )%32;
737 lps[irow][rcolumn] = lps[irow][rcolumn] + twrs[rowModUp][lcolumn] + twrs[rowModDn][lcolumn];
738 }
739 }
740 }
741 }
742
743}

◆ RemotePartialCN()

void LVL1::gFEXJetAlgo::RemotePartialCN ( const gTowersJetEngine & twrs,
gTowersPartialSums & rps ) const
privatevirtual

Definition at line 746 of file gFEXJetAlgo.cxx.

746 {
747
748 typedef std::array<std::array<int, 4>, 4> gTowersNeighbours;
749 gTowersNeighbours NUpDwnR = {{ {{2,3,4,4}}, {{0,2,3,4}}, {{0,0,2,3}}, {{0,0,0,2}} }};
750
751 // same as AB for right partial sum
752 // starts from the righ most partial sum -- largest partial sum
753 for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
754 for(int rcolumn = 0; rcolumn<FEXAlgoSpaceDefs::n_partial; rcolumn++){
755 rps[irow][rcolumn] = 0;
756 for(int lcolumn = 0; lcolumn<FEXAlgoSpaceDefs::n_partial; lcolumn++){
757 if ( NUpDwnR[rcolumn][lcolumn] > 0 ) {
758 rps[irow][rcolumn] = rps[irow][rcolumn] + twrs[irow][lcolumn+2];
759 }
760 for( int rowOff = 1 ; rowOff < NUpDwnR[rcolumn][lcolumn]+1; rowOff++){
761 int rowModUp = (irow + rowOff)%32;
762 int rowModDn = (irow - rowOff + 32 )%32;
763 rps[irow][rcolumn] = rps[irow][rcolumn] + twrs[rowModUp][lcolumn+2] + twrs[rowModDn][lcolumn+2];
764 }
765 }
766 }
767 }
768}

◆ RemotePartialCP()

void LVL1::gFEXJetAlgo::RemotePartialCP ( const gTowersJetEngine & twrs,
gTowersPartialSums & lps ) const
privatevirtual

Definition at line 771 of file gFEXJetAlgo.cxx.

771 {
772
773 typedef std::array<std::array<int, 4>, 4> gTowersNeighbours;
774 gTowersNeighbours NUpDwnL = {{ {{2,0,0,0}}, {{3,2,0,0}}, {{4,3,2,0}}, {{4,4,3,2}} }};
775 // do partial sum for output to left FPGA second
776 for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
777 for(int rcolumn = 0; rcolumn<FEXAlgoSpaceDefs::n_partial; rcolumn++){
778 // start calculating right partial sums for remote column rcolumn
779 lps[irow][rcolumn] = 0;
780 for(int lcolumn = 0; lcolumn<FEXAlgoSpaceDefs::n_partial; lcolumn++){
781 // add in any energy from towers in this row
782 // no need of modular arithmetic
783 if ( NUpDwnL[rcolumn][lcolumn] > 0 ) {
784 lps[irow][rcolumn] = lps[irow][rcolumn] + twrs[irow][lcolumn];
785 }
786 for( int rowOff = 1 ; rowOff < NUpDwnL[rcolumn][lcolumn]+1; rowOff++){
787 int rowModUp = (irow + rowOff)%32;
788 int rowModDn = (irow - rowOff + 32 )%32;
789 lps[irow][rcolumn] = lps[irow][rcolumn] + twrs[rowModUp][lcolumn] + twrs[rowModDn][lcolumn];
790 }
791 }
792 }
793 }
794}

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ SaturateBlocks()

void LVL1::gFEXJetAlgo::SaturateBlocks ( gTowersType & gBlkSum,
const gTowersType & sat,
int fpga ) const
privatevirtual

Definition at line 990 of file gFEXJetAlgo.cxx.

990 {
991 // TODO: Temporary fix to match FW saturation eta-alignment bug.
992 // In firmware, seed_ovf = delayK(dat_ovf_in, SEED_OVF_DELAY=10).
993 // dat_ovf_in for col K arrives at clock K; seed_ovf fires at clock K+10.
994 // et9 for col J is computed at clock 11+J (SEED_DLY+J).
995 // So overflow at col K fires during et9 for col K+10-11 = K-1.
996 // First column (icol%6==0) is always skipped (pulse falls in dead/gap).
997 // Last column skipping is FPGA-specific (see SaturateJets comments):
998 // FPGA A: no last-col skip (cols 5,11 regular).
999 // FPGA B: skip col 11 only (extended).
1000 // FPGA C: skip all last cols (all extended).
1001 // @see jet_eng.vhd lines 849-863: seed_ovf forces et9/seed_out to max
1002 // @see delayK.vhd: DLY FFs with combinatorial in/out
1003 // Revert this to use icol (not icol-1) when the FW saturation alignment is fixed.
1004 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
1005 for(unsigned int icol = 0; icol < FEXAlgoSpaceDefs::ABcolumns; icol++){
1006 if(sat[irow][icol] && (icol % 6 != 0)){
1007 if (fpga == 1 && icol == 11) continue; // FPGA B col 11 extended
1008 if (fpga == 2 && icol % 6 == 5) continue; // FPGA C all last cols extended
1009 gBlkSum[irow][icol - 1] = 0x00000fff;
1010 }
1011 }
1012 }
1013}

◆ SaturateJets()

void LVL1::gFEXJetAlgo::SaturateJets ( gTowersType & jets,
const gTowersType & sat,
int fpga ) const
privatevirtual

Definition at line 957 of file gFEXJetAlgo.cxx.

957 {
958 // TODO: Temporary fix to match FW saturation eta-alignment bug.
959 // In firmware, sum69_ovf = delayK(dat_ovf_in, SUM69_OVF_DELAY=16).
960 // dat_ovf_in for col K arrives at clock K; sum69_ovf fires at clock K+16.
961 // sum69o for col J is computed at clock 17+J (LPS_A_DLY+J).
962 // So overflow at col K fires during sum69o for col K+16-17 = K-1.
963 // Engine-boundary columns:
964 // - First column (local col 0 = global 0,6): K-1 falls in the dead/gap
965 // phase of the serialiser → no valid target, skip (icol%6 != 0).
966 // - Last column (local col 5 = global 5,11): the override is gated by
967 // have_seed_d5 in jet_eng.vhd. For extended columns the seed is
968 // computed from regular etower+htower only (the extended xetower
969 // contribution is added after the seed stage via lps_a), so the seed
970 // typically fails and the override is blocked. This is FPGA-specific:
971 // FPGA A (fpga=0): cols 5,11 are regular → override goes through.
972 // FPGA B (fpga=1): col 11 is extended (xetower+xhtower) → skip.
973 // col 5 is regular → override goes through.
974 // FPGA C (fpga=2): all columns extended → skip all last cols.
975 // @see jet_eng.vhd: sum69_ovf forces sum69o to max positive
976 // @see jet_eng.vhd: have_seed_d5 gates delm_din, blocking override
977 // @see delayK.vhd: DLY FFs with combinatorial in/out
978 // Revert this to use icol (not icol-1) when the FW saturation alignment is fixed.
979 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
980 for(unsigned int icol = 0; icol < FEXAlgoSpaceDefs::ABcolumns; icol++){
981 if(sat[irow][icol] && (icol % 6 != 0)){
982 if (fpga == 1 && icol == 11) continue; // FPGA B col 11 extended
983 if (fpga == 2 && icol % 6 == 5) continue; // FPGA C all last cols extended
984 jets[irow][icol - 1] = 0x0003ffff;
985 }
986 }
987 }
988}

◆ singleHalf()

void LVL1::gFEXJetAlgo::singleHalf ( const gTowersType & twrs,
gTowersType & FPGAsum ) const
privatevirtual

Definition at line 797 of file gFEXJetAlgo.cxx.

797 {
798 // Finds jets in a single FPGA
799 // This version only gives sum in the right or left half of the FPGA
800
801 // Number of up and down FPGAs to add
802 std::array<int, 9> NUpDwn = {{2,3,4,4,4,4,4,3,2}};
803
804 // Evaluate jet centered on each possible eta and phi gTower
805 for( int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
806 for(int jcolumn = 0; jcolumn<FEXAlgoSpaceDefs::ABcolumns; jcolumn++){
807 // zero jet sum here
808 FPGAsum[irow][jcolumn] = 0;
809
810 // local column goes from 0 to 8
811 for(int localColumn = 0; localColumn<9; localColumn++){
812 int sumColumn = jcolumn + localColumn - 4;
813
814 // calculate min and max columns for FPGA half
815 int lmin = 0;
816 int lmax = 5;
817
818 if( jcolumn > 5 ) {
819 lmin = 6;
820 lmax = 11;
821 }
822
823 // check if tower to be summed is actually in FPGA
824 if( (sumColumn >= lmin) && (sumColumn <= lmax) ) {
825
826 // sum tower in the same row as jet center
827 FPGAsum[irow][jcolumn] = FPGAsum[irow][jcolumn] + twrs[irow][sumColumn];
828
829 // add rows above and below according NUpDwn
830 // localRow goes from 1 to 2, 1 to 3 or 1 to 4
831 for(int localRow = 1; localRow<=NUpDwn[localColumn]; localRow++){
832 int krowUp = (irow + localRow);
833 if( krowUp > 31 ) krowUp = krowUp - 32;
834 int krowDn = (irow - localRow);
835 if( krowDn < 0 ) krowDn = krowDn + 32;
836 FPGAsum[irow][jcolumn] = FPGAsum[irow][jcolumn] +
837 twrs[krowUp][sumColumn] +
838 twrs[krowDn][sumColumn];
839 }
840 }
841 }
842 }
843 }
844}

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

◆ ZeroNegative()

void LVL1::gFEXJetAlgo::ZeroNegative ( gTowersType & jets) const
privatevirtual

Definition at line 947 of file gFEXJetAlgo.cxx.

947 {
948 for(unsigned int irow = 0; irow < FEXAlgoSpaceDefs::ABCrows; irow++ ){
949 for(unsigned int icolumn =0; icolumn<FEXAlgoSpaceDefs::ABcolumns; icolumn++){
950 if(jets[irow][icolumn] < 0) jets[irow][icolumn] = 0;
951 }
952 }
953}

Member Data Documentation

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_gFEXJetAlgo_gTowerContainerKey

SG::ReadHandleKey<LVL1::gTowerContainer> LVL1::gFEXJetAlgo::m_gFEXJetAlgo_gTowerContainerKey {this, "MyGTowers", "gTowerContainer", "Input container for gTowers"}
private

Definition at line 112 of file gFEXJetAlgo.h.

112{this, "MyGTowers", "gTowerContainer", "Input container for gTowers"};

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files: