Skip to content

Commit

Permalink
Sector Finder: Support for charged & neutral particles, added action …
Browse files Browse the repository at this point in the history
…function and validator (#243)
  • Loading branch information
rtysonCLAS12 committed Jul 31, 2024
1 parent 05347b2 commit 2e7540c
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 61 deletions.
168 changes: 118 additions & 50 deletions src/iguana/algorithms/clas12/SectorFinder/Algorithm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,96 +9,164 @@ namespace iguana::clas12 {

// define options, their default values, and cache them
ParseYAMLConfig();
o_bankname = GetOptionScalar<std::string>("bank");
o_bankname_charged = GetOptionScalar<std::string>("bank_charged");
o_bankname_uncharged = GetOptionScalar<std::string>("bank_uncharged");

bool setDefaultBanks=false;
// get expected bank indices
b_particle = GetBankIndex(banks, "REC::Particle");
if(o_bankname != "default") {
b_user = GetBankIndex(banks, o_bankname);
userSpecifiedBank = true;
if(o_bankname_charged != "default") {
b_user_charged = GetBankIndex(banks, o_bankname_charged);
userSpecifiedBank_charged = true;
}
else {
b_calorimeter = GetBankIndex(banks, "REC::Calorimeter");
b_track = GetBankIndex(banks, "REC::Track");
b_scint = GetBankIndex(banks, "REC::Scintillator");
userSpecifiedBank = false;
setDefaultBanks = true;
userSpecifiedBank_charged = false;
}

if(o_bankname_uncharged != "default") {
b_user_uncharged = GetBankIndex(banks, o_bankname_uncharged);
userSpecifiedBank_uncharged = true;
}
else {
//avoid setting default banks twice
if(!setDefaultBanks){
b_calorimeter = GetBankIndex(banks, "REC::Calorimeter");
b_track = GetBankIndex(banks, "REC::Track");
b_scint = GetBankIndex(banks, "REC::Scintillator");
setDefaultBanks = true;
}
userSpecifiedBank_uncharged = false;
}

// create the output bank
// FIXME: generalize the groupid and itemid
auto result_schema = CreateBank(banks, b_result, "REC::Particle::Sector", {"sector/I"}, 0xF000, 2);
auto result_schema = CreateBank(banks, b_result, "REC::Particle::Sector", {"sector/I","pindex/I"}, 0xF000, 4);
i_sector = result_schema.getEntryOrder("sector");
i_pindex = result_schema.getEntryOrder("pindex");
}


void SectorFinder::Run(hipo::banklist& banks) const
{
auto& particleBank = GetBank(banks, b_particle, "REC::Particle");
auto& resultBank = GetBank(banks, b_result, "REC::Particle::Sector");

std::vector<int> sectors_uncharged;
std::vector<int> pindices_uncharged;
if(userSpecifiedBank_uncharged){
auto const& userBank = GetBank(banks, b_user_uncharged);
GetListsSectorPindex(userBank,sectors_uncharged,pindices_uncharged);
}

std::vector<int> sectors_charged;
std::vector<int> pindices_charged;
if(userSpecifiedBank_charged){
auto const& userBank = GetBank(banks, b_user_charged);
GetListsSectorPindex(userBank,sectors_charged,pindices_charged);
}

std::vector<int> sectors_track;
std::vector<int> pindices_track;
if(!userSpecifiedBank_charged || !userSpecifiedBank_uncharged){
auto const& trackBank = GetBank(banks, b_track);
GetListsSectorPindex(trackBank,sectors_track,pindices_track);
}

std::vector<int> sectors_cal;
std::vector<int> pindices_cal;
if(!userSpecifiedBank_charged || !userSpecifiedBank_uncharged){
auto const& calBank = GetBank(banks, b_calorimeter);
GetListsSectorPindex(calBank,sectors_cal,pindices_cal);
}

std::vector<int> sectors_scint;
std::vector<int> pindices_scint;
if(!userSpecifiedBank_charged || !userSpecifiedBank_uncharged){
auto const& scintBank = GetBank(banks, b_scint);
GetListsSectorPindex(scintBank,sectors_scint,pindices_scint);
}


// sync new bank with particle bank, and fill it with zeroes
resultBank.setRows(particleBank.getRows());
resultBank.getMutableRowList().setList(particleBank.getRowList());
for(int row = 0; row < resultBank.getRows(); row++)
for(int row = 0; row < resultBank.getRows(); row++){
resultBank.putInt(i_sector, row, 0);

// filter the input bank for requested PDG code(s)
if(userSpecifiedBank) { // if user specified a specific bank
auto const& userBank = GetBank(banks, b_user);
for(auto const& row : particleBank.getRowList()) {
if(userBank.getRowList().size() > 0) {
resultBank.putInt(i_sector, row, GetSector(userBank, row));
}
}
resultBank.putInt(i_pindex, row, row);
}
else { // use the standard method
auto const& calBank = GetBank(banks, b_calorimeter);
auto const& scintBank = GetBank(banks, b_scint);
auto const& trackBank = GetBank(banks, b_track);
for(auto const& row : particleBank.getRowList()) {
int trackSector = 0;
if(trackBank.getRowList().size() > 0) {
trackSector = GetSector(trackBank, row);
}

int scintSector = 0;
if(scintBank.getRowList().size() > 0) {
scintSector = GetSector(scintBank, row);
}

int calSector = 0;
if(calBank.getRowList().size() > 0) {
calSector = GetSector(calBank, row);
}
for(int row = 0; row < particleBank.getRows(); row++) {
int charge=particleBank.getInt("charge",row);

if(trackSector != 0) {
resultBank.putInt(i_sector, row, trackSector);
}
else if(scintSector != 0) {
resultBank.putInt(i_sector, row, scintSector);
bool userSp = charge==0 ? userSpecifiedBank_uncharged : userSpecifiedBank_charged;
std::vector<int>& sct_us = charge==0 ? sectors_uncharged : sectors_charged;
std::vector<int>& pin_us = charge==0 ? pindices_uncharged : pindices_charged;



if(userSp){
int sect=GetSector(sct_us, pin_us,row);
if (sect!=-1){
resultBank.putInt(i_sector, row, sect);
resultBank.putInt(i_pindex, row, row);
}
else {
// FIXME: add even if calSector is 0
// need an entry per pindex
// can happen that particle not in FD
// ie sector is 0
resultBank.putInt(i_sector, row, calSector);
} else {
enum det_enum {kTrack, kScint, kCal, nDet}; // try to get sector from these detectors, in this order
for(int d = 0; d < nDet; d++) {
int sect = -1;
std::string det_name;
switch(d) {
case kTrack:
sect=GetSector(sectors_track, pindices_track,row);
det_name="track";
break;
case kScint:
sect=GetSector(sectors_scint, pindices_scint,row);
det_name="scint";
break;
case kCal:
sect=GetSector(sectors_cal, pindices_cal,row);
det_name="cal";
break;
}
if(sect != -1) {
m_log->Trace("{} pindex {} sect {}", det_name, row, sect);
resultBank.putInt(i_sector, row, sect);
resultBank.putInt(i_pindex, row, row);
break;
}
}
}
}

ShowBank(resultBank, Logger::Header("CREATED BANK"));
}

int SectorFinder::GetSector(hipo::bank const& bank, int const pindex) const
void SectorFinder::GetListsSectorPindex(hipo::bank const& bank, std::vector<int>& sectors, std::vector<int>& pindices) const
{
int sector = 0;
for(auto const& row : bank.getRowList()) {
if(bank.getInt("pindex", row) == pindex) {
return bank.getInt("sector", row);
//check that we're only using FD detectors
//eg have "sectors" in CND which we don't want to add here
int det=bank.getInt("detector",row);
if (listFDDets.find(det) != listFDDets.end()) {
sectors.push_back(bank.getInt("sector", row));
pindices.push_back(bank.getInt("pindex", row));
}
}
}

int SectorFinder::GetSector(std::vector<int> const& sectors, std::vector<int> const& pindices, int const pindex) const
{
for(std::size_t i=0;i<sectors.size();i++){
if (pindices.at(i)==pindex){
return sectors.at(i);
}
}
return sector;
return -1;
}

void SectorFinder::Stop()
Expand Down
63 changes: 55 additions & 8 deletions src/iguana/algorithms/clas12/SectorFinder/Algorithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,51 @@ namespace iguana::clas12 {
void Run(hipo::banklist& banks) const override;
void Stop() override;

/// get sector from bank for a given pindex
/// @param bank bank to get sector from
/// @param pindex index in bank for which to get sector
/// @returns sector for pindex in bank
int GetSector(hipo::bank const& bank, int const pindex) const;
/// @action_function{vector creator} for a given particle with index `pindex`, get its sector from a detector bank's list of `sectors` and `pindices` (both must be ordered in the same way);
/// _nb_: this is done instead of finding the `pindex` in the bank directly, to have an action function
///
/// **Example:**
/// ```cpp
///
/// //... Initialise algorithms & banks ...
///
/// //For each event, do:
///
/// std::vector<int> sectors;
/// std::vector<int> pindices
///
/// //bank is a hipo::bank object from which we want to get the sectors
/// //for example the bank object related to REC::Calorimeter
/// for(auto const& row : bank.getRowList()) {
///
/// int det=bank.getInt("detector",row);
///
/// //NB: you should check you read from an FD detector
/// // eg det 7 is the ECAL
/// if(det==7){
/// sectors.push_back(bank.getInt("sector", row));
/// pindices.push_back(bank.getInt("pindex", row));
/// }
/// }
///
/// //partbank is a hipo::bank object related to REC::Particle
/// //algo_sector_finder is the iguana::clas12::SectorFinder object
/// for(auto const& row : partbank.getRowList()) {
/// int sector = algo_sector_finder.GetSector(sectors, pindices, row);
/// }
/// ```
///
/// @param sectors list of sectors in a detector bank
/// @param pindices list of pindices in a detector bank
/// @param pindex index in `REC::Particle` bank for which to get sector
/// @returns sector for `pindex` in list, -1 if `pindex` not in inputted list
int GetSector(std::vector<int> const& sectors, std::vector<int> const& pindices, int const pindex) const;

/// fill lists of sectors and pindices present in the input bank
/// @param bank bank from which to get lists of sectors and pindices
/// @param sectors list to fill with sectors in the bank
/// @param pindices list to fill with pindices in the bank
void GetListsSectorPindex(hipo::bank const& bank, std::vector<int>& sectors, std::vector<int>& pindices) const;

private:

Expand All @@ -38,15 +78,22 @@ namespace iguana::clas12 {
hipo::banklist::size_type b_calorimeter;
hipo::banklist::size_type b_track;
hipo::banklist::size_type b_scint;
hipo::banklist::size_type b_user;
hipo::banklist::size_type b_user_charged;
hipo::banklist::size_type b_user_uncharged;
hipo::banklist::size_type b_result;
bool userSpecifiedBank{false};
bool userSpecifiedBank_charged{false};
bool userSpecifiedBank_uncharged{true};

// `b_result` bank item indices
int i_sector;
int i_pindex;

/// Configuration options
std::string o_bankname;
std::string o_bankname_charged;
std::string o_bankname_uncharged;

//only want sectors from FD detectors
std::set<int> const listFDDets{6,7,12,15,16,18};
};

}
10 changes: 8 additions & 2 deletions src/iguana/algorithms/clas12/SectorFinder/Config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
clas12::SectorFinder:
# use the default banks
bank: default
# for both charged/uncharged particles
bank_charged: default
bank_uncharged: default

# or force finder to use a certain bank with eg:
#bank: REC::Calorimeter
#can have default for charged but not uncharged particles
#or vice versa
#bank_charged: default
#bank_uncharged: REC::Calorimeter
Loading

0 comments on commit 2e7540c

Please sign in to comment.