Commit 29b695f2 authored by Cecilia Tosciri's avatar Cecilia Tosciri Committed by Walter Lampl
Browse files

gFEX Jets without Jets algorithm

parent 981da490
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
//***************************************************************************
// gFEXJwoJAlgo - Jets without jets algorithm for gFEX
// -------------------
// begin : 10 08 2021
// email : cecilia.tosciri@cern.ch
//***************************************************************************
#ifndef gFEXJwoJAlgo_H
#define gFEXJwoJAlgo_H
#include "AthenaBaseComps/AthAlgTool.h"
#include "L1CaloFEXToolInterfaces/IgFEXJwoJAlgo.h"
#include "AthenaKernel/CLASS_DEF.h"
#include "L1CaloFEXSim/gFEXJwoJTOB.h"
#include "L1CaloFEXSim/gTowerContainer.h"
#include "AthenaBaseComps/AthAlgorithm.h"
#include "StoreGate/StoreGateSvc.h"
#include "L1CaloFEXSim/FEXAlgoSpaceDefs.h"
namespace LVL1 {
class gFEXJwoJAlgo : public AthAlgTool, virtual public IgFEXJwoJAlgo {
public:
/** Constructors */
gFEXJwoJAlgo(const std::string& type, const std::string& name, const IInterface* parent);
/** standard Athena-Algorithm method */
virtual StatusCode initialize() override;
virtual void setAlgoConstant(unsigned int aFPGA_A, unsigned int bFPGA_A,
unsigned int aFPGA_B, unsigned int bFPGA_B,
int gblockThreshold) override;
virtual std::vector<std::unique_ptr<gFEXJwoJTOB>> jwojAlgo(gTowersCentral Atwr, gTowersCentral Btwr,
std::array<uint32_t, 4> & outTOB) override;
private:
unsigned int m_aFPGA_A;
unsigned int m_bFPGA_A;
unsigned int m_aFPGA_B;
unsigned int m_bFPGA_B;
int m_gBlockthreshold;
virtual void gBlockAB(gTowersCentral twrs, gTowersCentral & gBlkSum);
virtual void metFPGA(gTowersCentral twrs, gTowersCentral & gBlkSum,
unsigned short & MHT_x, unsigned short & MHT_y,
unsigned short & MST_x, unsigned short & MST_y,
unsigned short & MET_x, unsigned short & MET_y);
virtual void metTotal(unsigned short A_MET_x, unsigned short A_MET_y,
unsigned short B_MET_x, unsigned short B_MET_y,
unsigned short & MET_x, unsigned short & MET_y, unsigned short & MET);
virtual void sumEtFPGA(gTowersCentral twrs, unsigned int & partial_sumEt);
virtual void sumEt(unsigned int A_sumEt, unsigned int B_sumEt, unsigned int & total_sumEt);
virtual unsigned short sinLUT(unsigned int phiIDX, unsigned int aw, unsigned int dw);
virtual unsigned short cosLUT(unsigned int phiIDX, unsigned int aw, unsigned int dw);
};
} // end of namespace
#endif
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
//***************************************************************************
// gFEXJwoJTOB - Forms the JwoJ TOBs for gFEX
// -------------------
// begin : 10 08 2021
// email : cecilia.tosciri@cern.ch
//***************************************************************************
#pragma once
#include "AthenaKernel/CLASS_DEF.h"
namespace LVL1 {
class gFEXJwoJTOB
{
//gFEXJwoJTOB class description below:
/** The gFEXJwoJTOB.h class stores the energy, the eta, phi coordinate,
* the status and the type (gRho, gBlock, gJwoJ) of the gFEX JwoJ TOBs
*/
private:
uint32_t m_word;
unsigned int m_quantity1;
unsigned int m_quantity2;
unsigned int m_st1;
unsigned int m_st2;
unsigned int m_satur;
unsigned int m_tobID;
public:
gFEXJwoJTOB();
~gFEXJwoJTOB() {};
inline uint32_t getWord() const {return m_word;}
inline unsigned int getQuantity1() const {return m_quantity1;}
inline unsigned int getQuantity2() const {return m_quantity2;}
inline unsigned int getStatus1() const {return m_st1;}
inline unsigned int getStatus2() const {return m_st2;}
inline unsigned int getSaturation() const {return m_satur;}
inline unsigned int getTobID() const {return m_tobID;}
void setWord(uint32_t);
void setQuantity1(unsigned int);
void setQuantity2(unsigned int);
void setStatus1(unsigned int);
void setStatus2(unsigned int);
void setSaturation(unsigned int);
void setTobID(unsigned int);
};
} // end of namespace
CLASS_DEF( LVL1::gFEXJwoJTOB, 2352924 , 1 )
......@@ -31,11 +31,13 @@ public:
private:
gFEXOutputCollection* m_gFEXOutputCollection;
float m_jet_nTOBs;
float m_global_nTOBs;
bool m_load_truth_jet;
std::vector<float> m_truth_jet_eta;
std::vector<float> m_truth_jet_phi;
std::vector<float> m_truth_jet_ET;
std::vector<float> m_jet_TOB;
std::vector<float> m_jet_TOB_Eta;
std::vector<float> m_jet_TOB_Phi;
......@@ -43,10 +45,20 @@ private:
std::vector<float> m_jet_TOB_ID;
std::vector<float> m_jet_TOB_Status;
std::vector<float> m_global_TOB;
std::vector<float> m_global_TOB_Quantity1;
std::vector<float> m_global_TOB_Quantity2;
std::vector<float> m_global_TOB_Saturation;
std::vector<float> m_global_TOB_ID;
std::vector<float> m_global_TOB_Status1;
std::vector<float> m_global_TOB_Status2;
std::string m_jet_container_name = "AntiKt10TruthJets";
TTree *m_myTree;
StatusCode loadJetAlgoVariables();
StatusCode loadGlobalAlgoVariables();
StatusCode loadTruthElectron();
StatusCode loadTruthJets();
......
......@@ -31,7 +31,8 @@ namespace LVL1 {
~gFEXOutputCollection();
void clear();
void clearJets();
void clearGlobals();
/**
* @brief add a value related to the jet finder algorithm for a TOB
......@@ -41,29 +42,38 @@ namespace LVL1 {
*
*/
void addValueJet(std::string key, float value);
void addValueGlobal(std::string key, float value);
//Save all jet values. Use only after finishing defining all jet values for one TOB.
void fillJet();
void fillGlobal();
//Get total number of TOBs saved
int size();
int jetsSize();
int globalsSize();
//Get all jeta related values the ith TOB
//Get all jets related values
std::unordered_map<std::string, float> getJet(int) const;
std::unordered_map<std::string, float> getGlobal(int) const;
//Add a 32-bit jet TOB word
void addJetTob(uint32_t);
void addGlobalTob(uint32_t);
//Get all jet TOB words of an event
std::vector<uint32_t> getJetTob() const;
std::vector<uint32_t> getGlobalTob() const;
private:
//vector of TOB words
std::vector<uint32_t> m_jettob;
std::vector<uint32_t> m_globaltob;
// /// jet related values of a TOB
std::unordered_map<std::string, float> m_values_gFEXJet;
std::unordered_map<std::string, float> m_values_gFEXGlobal;
/// jet related values of all TOBs in an event
std::vector<std::unordered_map<std::string, float>> m_allvalues_gFEXjet;
std::vector<std::unordered_map<std::string, float>> m_allvalues_gFEXglobal;
};
}
......
......@@ -17,6 +17,8 @@
#include "L1CaloFEXSim/gFEXFPGA.h"
#include "L1CaloFEXSim/gFEXJetAlgo.h"
#include "L1CaloFEXSim/gFEXJetTOB.h"
#include "L1CaloFEXSim/gFEXJwoJAlgo.h"
#include "L1CaloFEXSim/gFEXJwoJTOB.h"
#include "L1CaloFEXSim/gFEXOutputCollection.h"
......@@ -39,14 +41,10 @@ namespace LVL1 {
/** Destructor */
virtual ~gFEXSim();
//virtual void init (int id) override ;
virtual void reset () override ;
virtual void execute() override ;
//virtual int ID() override {return m_id;}
virtual StatusCode executegFEXSim(gTowersIDs tmp) override;
virtual std::vector<uint32_t> getgRhoTOBs() const override;
......@@ -55,6 +53,8 @@ namespace LVL1 {
virtual std::vector<uint32_t> getgJetTOBs() const override;
virtual std::vector<uint32_t> getgGlobalTOBs() const override;
/** Internal data */
private:
......@@ -68,15 +68,15 @@ namespace LVL1 {
std::vector<uint32_t> m_gJetTobWords;
// std::array<uint32_t> m_gRhoTobWords;
std::vector<uint32_t> m_gGlobalTobWords;
// std::array<uint32_t> m_gBlockTobWords;
// std::array<uint32_t> m_gJetTobWords;
ToolHandle<IgFEXFPGA> m_gFEXFPGA_Tool {this, "gFEXFPGATool", "LVL1::gFEXFPGA", "Tool that simulates the FPGA hardware"};
ToolHandle<IgFEXJetAlgo> m_gFEXJetAlgoTool {this, "gFEXJetAlgoTool", "LVL1::gFEXJetAlgo", "Tool that runs the gFEX jet algorithm"};
ToolHandle<IgFEXJwoJAlgo> m_gFEXJwoJAlgoTool {this, "gFEXJwoJAlgoTool", "LVL1::gFEXJwoJAlgo", "Tool that runs the gFEX Jets without Jets algorithm"};
};
} // end of namespace
......
......@@ -20,6 +20,10 @@
#include "xAODTrigger/gFexJetRoIContainer.h"
#include "xAODTrigger/gFexJetRoIAuxContainer.h"
#include "xAODTrigger/gFexGlobalRoI.h"
#include "xAODTrigger/gFexGlobalRoIContainer.h"
#include "xAODTrigger/gFexGlobalRoIAuxContainer.h"
namespace LVL1 {
//Doxygen class description below:
......@@ -56,6 +60,8 @@ namespace LVL1 {
virtual StatusCode fillgJetEDM(uint32_t tobWord) override ;
virtual StatusCode fillgGlobalEDM(uint32_t tobWord) override ;
/** Internal data */
private:
std::unique_ptr< xAOD::gFexJetRoIContainer > m_gRhoContainer;
......@@ -67,6 +73,10 @@ namespace LVL1 {
std::unique_ptr< xAOD::gFexJetRoIContainer > m_gJetContainer;
std::unique_ptr< xAOD::gFexJetRoIAuxContainer > m_gJetAuxContainer;
std::unique_ptr< xAOD::gFexGlobalRoIContainer > m_gGlobalContainer;
std::unique_ptr< xAOD::gFexGlobalRoIAuxContainer > m_gGlobalAuxContainer;
std::vector<gFEXSim*> m_gFEXCollection;
ToolHandle<IgFEXSim> m_gFEXSimTool {this, "gFEXSimTool", "LVL1::gFEXSim", "Tool that creates the gFEX Simulation"};
......@@ -75,10 +85,12 @@ namespace LVL1 {
SG::ReadHandleKey<CaloCellContainer> m_scellsCollectionSGKey {this, "SCell", "SCell", "SCell"};
SG::WriteHandleKey< xAOD::gFexJetRoIContainer > m_gFexJetOutKey {this,"Key_gFexJetOutputContainer","L1_gJetRoI","Output gFexJet container"};
SG::WriteHandleKey< xAOD::gFexGlobalRoIContainer > m_gFexGlobalOutKey {this,"Key_gFexGlobalOutputContainer","L1_gJetRoI","Output gFexGlobal container"};
std::vector<uint32_t> m_allgRhoTobs;
std::vector<uint32_t> m_allgBlockTobs;
std::vector<uint32_t> m_allgJetTobs;
std::vector<uint32_t> m_allgGlobalTobs;
};
......
......@@ -40,6 +40,5 @@ svcMgr.THistSvc.Output += ["ANALYSIS DATAFILE='myfile.root' OPT='RECREATE'"]
log.info("==========================================================")
log.info("Scheduling gFEXDriver")
athAlgSeq += CfgMgr.LVL1__gFEXDriver('MygFEXDriver')
#athAlgSeq += CfgMgr.LVL1__gFEXNtupleWriter('MygFEXNtupleWriter')
log.info("==========================================================")
#######################################################
......@@ -32,6 +32,7 @@
#include "L1CaloFEXSim/gFEXSim.h"
#include "L1CaloFEXSim/gFEXFPGA.h"
#include "L1CaloFEXSim/gFEXJetAlgo.h"
#include "L1CaloFEXSim/gFEXJwoJAlgo.h"
#include "L1CaloFEXSim/gFEXNtupleWriter.h"
......@@ -75,5 +76,6 @@ DECLARE_COMPONENT(gTowerBuilder)
DECLARE_COMPONENT(gSuperCellTowerMapper)
DECLARE_COMPONENT(gFEXFPGA)
DECLARE_COMPONENT(gFEXJetAlgo)
DECLARE_COMPONENT(gFEXJwoJAlgo)
DECLARE_COMPONENT(gFEXNtupleWriter)
......@@ -11,6 +11,7 @@
#include "L1CaloFEXSim/gFEXSim.h"
#include "L1CaloFEXSim/gFEXOutputCollection.h"
#include "L1CaloFEXSim/gFEXJetTOB.h"
#include "L1CaloFEXSim/gFEXJwoJTOB.h"
#include "StoreGate/WriteHandle.h"
#include "StoreGate/ReadHandle.h"
......@@ -83,7 +84,7 @@ StatusCode gFEXDriver::initialize()
//STEP 1 - Do some monitoring
gFEXOutputCollection* my_gFEXOutputCollection = new gFEXOutputCollection();
ATH_CHECK( evtStore()->record(my_gFEXOutputCollection,"gFEXOutputCollection") );
// SG::WriteHandle<LVL1::gFEXOutputCollection> gFEXOutputCollectionSG(m_gFEXOutputCollectionSGKey);
// ATH_CHECK(gFEXOutputCollectionSG.record(std::move(my_gFEXOutputCollection)));
......
/*
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
*/
//***************************************************************************
// gFEXJwoJAlg - Jets without jets algorithm for gFEX
// -------------------
// begin : 10 08 2021
// email : cecilia.tosciri@cern.ch
//***************************************************************************
#define _USE_MATH_DEFINES
#include <cmath>
#include <vector>
#include "L1CaloFEXSim/gFEXJwoJAlgo.h"
#include "L1CaloFEXSim/gFEXJwoJTOB.h"
#include "L1CaloFEXSim/gTowerContainer.h"
#include "L1CaloFEXSim/gTower.h"
namespace LVL1 {
// default constructor for persistency
gFEXJwoJAlgo::gFEXJwoJAlgo(const std::string& type, const std::string& name, const IInterface* parent):
AthAlgTool(type, name, parent)
{
declareInterface<IgFEXJwoJAlgo>(this);
}
StatusCode gFEXJwoJAlgo::initialize(){
return StatusCode::SUCCESS;
}
void gFEXJwoJAlgo::setAlgoConstant(unsigned int aFPGA_A, unsigned int bFPGA_A,
unsigned int aFPGA_B, unsigned int bFPGA_B,
int gblockThreshold) {
m_aFPGA_A = aFPGA_A;
m_bFPGA_A = bFPGA_A;
m_aFPGA_B = aFPGA_B;
m_bFPGA_B = bFPGA_B;
m_gBlockthreshold = gblockThreshold;
}
std::vector<std::unique_ptr<gFEXJwoJTOB>> gFEXJwoJAlgo::jwojAlgo(gTowersCentral Atwr, gTowersCentral Btwr,
std::array<uint32_t, 4> & outTOB) {
// find gBlocks
gTowersCentral gBLKA;
gBlockAB(Atwr, gBLKA);
gTowersCentral gBLKB;
gBlockAB(Btwr, gBLKB);
//FPGA A observables
unsigned short A_MHT_x = 0x0;
unsigned short A_MHT_y = 0x0;
unsigned short A_MST_x = 0x0;
unsigned short A_MST_y = 0x0;
unsigned short A_MET_x = 0x0;
unsigned short A_MET_y = 0x0;
unsigned int A_sumEt = 0x0;
//FPGA B observables
unsigned short B_MHT_x = 0x0;
unsigned short B_MHT_y = 0x0;
unsigned short B_MST_x = 0x0;
unsigned short B_MST_y = 0x0;
unsigned short B_MET_x = 0x0;
unsigned short B_MET_y = 0x0;
unsigned int B_sumEt = 0x0;
//Global observables
unsigned short MET_x = 0x0;
unsigned short MET_y = 0x0;
unsigned short MET = 0x0;
unsigned int total_sumEt = 0x0;
unsigned int MHT_x = 0x0;
unsigned int MHT_y = 0x0;
unsigned int MST_x = 0x0;
unsigned int MST_y = 0x0;
metFPGA(Atwr, gBLKA, A_MHT_x, A_MHT_y, A_MST_x, A_MST_y, A_MET_x, A_MET_y);
metFPGA(Btwr, gBLKB, B_MHT_x, B_MHT_y, B_MST_x, B_MST_y, B_MET_x, B_MET_y);
metTotal(A_MET_x, A_MET_y, B_MET_x, B_MET_y, MET_x, MET_y, MET);
sumEtFPGA(Atwr, A_sumEt);
sumEtFPGA(Btwr, B_sumEt);
sumEt(A_sumEt, B_sumEt, total_sumEt);
sumEt(A_MHT_x, B_MHT_x, MHT_x);
sumEt(A_MHT_y, B_MHT_y, MHT_y);
sumEt(A_MST_x, B_MST_x, MST_x);
sumEt(A_MST_y, B_MST_y, MST_y);
//Define a vector to be filled with all the TOBs of one event
std::vector<std::unique_ptr<gFEXJwoJTOB>> tobs_v;
tobs_v.resize(4);
// fill in TOBs
// The order of the TOBs is given according to the TOB ID (TODO: check how it's done in fw)
// First TOB is (MET, SumEt)
outTOB[0] = total_sumEt; //set the Quantity2 to the corresponding slot (LSB)
outTOB[0] = outTOB[0] | (MET & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
if (total_sumEt != 0) outTOB[0] = outTOB[0] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
if (MET != 0) outTOB[0] = outTOB[0] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
outTOB[0] = outTOB[0] | (1 & 0x0000001F) << 26;//TOB ID is 1 for scalar values (5 bits starting at 26)
// Second TOB is (MET_x, MET_y)
outTOB[1] = MET_y; //set the Quantity2 to the corresponding slot (LSB)
outTOB[1] = outTOB[1] | (MET_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
if (MET_y != 0) outTOB[1] = outTOB[1] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
if (MET_x != 0) outTOB[1] = outTOB[1] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
outTOB[1] = outTOB[1] | (2 & 0x0000001F) << 26;//TOB ID is 2 for MET_x, MET_y (5 bits starting at 26)
// Third TOB is hard components (MHT_x, MHT_y)
outTOB[2] = MHT_y; //set the Quantity2 to the corresponding slot (LSB)
outTOB[2] = outTOB[2] | (MHT_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
if (MHT_y != 0) outTOB[2] = outTOB[2] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
if (MHT_x != 0) outTOB[2] = outTOB[2] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
outTOB[2] = outTOB[2] | (3 & 0x0000001F) << 26;//TOB ID is 3 for hard components (5 bits starting at 26)
// Fourth TOB is hard components (MHT_x, MHT_y)
outTOB[3] = MST_y; //set the Quantity2 to the corresponding slot (LSB)
outTOB[3] = outTOB[3] | (MST_x & 0x00000FFF) << 12;//Quantity 1 (in bit number 12)
if (MST_y != 0) outTOB[3] = outTOB[3] | 0x00000001 << 24;//Status bit for Quantity 2 (0 if quantity is null)
if (MST_x != 0) outTOB[3] = outTOB[3] | 0x00000001 << 25;//Status bit for Quantity 1 (0 if quantity is null)
outTOB[3] = outTOB[3] | (4 & 0x0000001F) << 26;//TOB ID is 4 for soft components (5 bits starting at 26)
tobs_v[0] = std::make_unique<gFEXJwoJTOB>();
tobs_v[0]->setWord(outTOB[0]);
tobs_v[0]->setQuantity1(MET);
tobs_v[0]->setQuantity2(total_sumEt);
tobs_v[0]->setSaturation(0); //Always 0 for now, need a threshold?
tobs_v[0]->setTobID(1);
if( MET != 0 ) tobs_v[0]->setStatus1(1);
else tobs_v[0]->setStatus1(0);
if(total_sumEt!= 0) tobs_v[0]->setStatus2(1);
else tobs_v[0]->setStatus2(0);
tobs_v[1] = std::make_unique<gFEXJwoJTOB>();
tobs_v[1]->setWord(outTOB[1]);
tobs_v[1]->setQuantity1(MET_x);
tobs_v[1]->setQuantity2(MET_y);
tobs_v[1]->setSaturation(0); //Always 0 for now, need a threshold?
tobs_v[1]->setTobID(2);
if( MET_x != 0 ) tobs_v[1]->setStatus1(1);
else tobs_v[1]->setStatus1(0);
if(MET_y!= 0) tobs_v[1]->setStatus2(1);
else tobs_v[1]->setStatus2(0);
tobs_v[2] = std::make_unique<gFEXJwoJTOB>();
tobs_v[2]->setWord(outTOB[2]);
tobs_v[2]->setQuantity1(MHT_x);
tobs_v[2]->setQuantity2(MHT_y);
tobs_v[2]->setSaturation(0); //Always 0 for now, need a threshold?
tobs_v[2]->setTobID(3);
if( MHT_x != 0 ) tobs_v[2]->setStatus1(1);
else tobs_v[2]->setStatus1(0);
if(MHT_y!= 0) tobs_v[2]->setStatus2(1);
else tobs_v[2]->setStatus2(0);
tobs_v[3] = std::make_unique<gFEXJwoJTOB>();
tobs_v[3]->setWord(outTOB[3]);
tobs_v[3]->setQuantity1(MST_x);
tobs_v[3]->setQuantity2(MST_y);
tobs_v[3]->setSaturation(0); //Always 0 for now, need a threshold?
tobs_v[3]->setTobID(4);
if( MST_x != 0 ) tobs_v[3]->setStatus1(1);
else tobs_v[2]->setStatus1(0);
if(MST_y!= 0) tobs_v[3]->setStatus2(1);
else tobs_v[3]->setStatus2(0);
return tobs_v;
}
void gFEXJwoJAlgo::gBlockAB(gTowersCentral twrs, gTowersCentral & gBlkSum){
int rows = twrs.size();
int cols = twrs[0].size();
for( int irow = 0; irow < rows; irow++ ){
for(int jcolumn = 0; jcolumn<cols; jcolumn++){
// zero jet sum here
gBlkSum[irow][jcolumn] = 0;
int krowUp = (irow + 1)%32;
int krowDn = (irow - 1 +32)%32;
if( (jcolumn == 0) || (jcolumn == 6) ) {
//left edge case
gBlkSum[irow][jcolumn] =
twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
twrs[irow][jcolumn+1] + twrs[krowUp][jcolumn+1] + twrs[krowDn][jcolumn+1];
} else if( (jcolumn == 5) || (jcolumn == 11)) {
// right edge case
gBlkSum[irow][jcolumn] =
twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
twrs[irow][jcolumn-1] + twrs[krowUp][jcolumn-1] + twrs[krowDn][jcolumn-1];
} else{
// normal case
gBlkSum[irow][jcolumn] =
twrs[irow][jcolumn] + twrs[krowUp][jcolumn] + twrs[krowDn][jcolumn] +
twrs[irow][jcolumn-1] + twrs[krowUp][jcolumn-1] + twrs[krowDn][jcolumn-1] +
twrs[irow][jcolumn+1] + twrs[krowUp][jcolumn+1] + twrs[krowDn][jcolumn+1];
}