#include "QFramework/TQUniqueCut.h"
#include "QFramework/TQStringUtils.h"
#include <algorithm>
#include "QFramework/TQLibrary.h"
bool TQUniqueCut::printOnVeto = false;
ClassImp(TQUniqueCut)
#if __cplusplus >= 201103L
#define IS_SORTED(first,last) std::is_sorted(first,last)
#else
template<class ForwardIt>
bool is_sorted(ForwardIt first, ForwardIt last){
if (first != last) {
ForwardIt next = first;
while (++next != last) {
if (*next < *first)
return ( next == last );
first = next;
}
}
return true;
}
#define IS_SORTED(first,last) is_sorted(first,last);
#endif
bool TQUniqueCut::isMergeable() const {
return false;
}
bool TQUniqueCut::setBranchNames(const TString& runBranch, const TString& evtBranch){
this->eventNumberBranch = evtBranch;
this->runNumberBranch = runBranch;
return true;
}
void TQUniqueCut::initUniqueCut(){
this->SetName("UniqueCut");
this->enabled = true;
}
TQUniqueCut::TQUniqueCut() :
runNumberBranch("run"),
eventNumberBranch("event")
{
this->initUniqueCut();
}
TQUniqueCut::TQUniqueCut(const TString& name) :
runNumberBranch("run"),
eventNumberBranch("event")
{
this->initUniqueCut();
this->SetName(name);
}
TQUniqueCut::TQUniqueCut(const TString& runBranch, const TString& evtBranch) :
runNumberBranch(runBranch),
eventNumberBranch(evtBranch)
{
this->initUniqueCut();
}
TQUniqueCut::TQUniqueCut(const TString& name, const TString& runBranch, const TString& evtBranch) :
runNumberBranch(runBranch),
eventNumberBranch(evtBranch)
{
this->initUniqueCut();
this->SetName(name);
}
const TString& TQUniqueCut::getRunNumberExpression() const {
return this->runNumberBranch;
}
const TString& TQUniqueCut::getEventNumberExpression() const {
return this->eventNumberBranch;
}
void TQUniqueCut::clear(){
this->runNumbers.clear();
this->eventNumbers.clear();
}
void TQUniqueCut::setActive(bool active){
this->enabled = active;
}
TObjArray* TQUniqueCut::getOwnBranches(){
TObjArray* bNames = new TObjArray();
TObjArray* rnb = this->runNumberObservable ? this->runNumberObservable->getBranchNames() : nullptr;
TObjArray* enb = this->eventNumberObservable ? this->eventNumberObservable->getBranchNames() : nullptr;
if(rnb){
bNames -> AddAll(rnb);
rnb->SetOwner(false);
delete rnb;
}
if(enb){
bNames -> AddAll(enb);
enb->SetOwner(false);
delete enb;
}
return bNames;
}
bool TQUniqueCut::checkUnique(std::set<long>& entries, long newEntry){
DEBUGclass("entering function");
if (entries.count(newEntry)) return false;
entries.insert(newEntry);
return true;
}
long TQUniqueCut::getIndex(std::vector<long>& entries, long entry){
DEBUGclass("attempting to find index of %d",entry);
if(entries.size() < 1){
DEBUGclass("adding %d as first entry",entry);
entries.insert(entries.begin(),entry);
return 0;
}
long idx = entries.size() -1;
DEBUGclass("checking entry %d against %d",entry,entries[idx]);
if(entry > entries[idx]){
DEBUGclass("adding entry %d at %d",entry,idx);
entries.push_back(entry);
return idx+1;
}
DEBUGclass("searching for entry %d",entry);
while(idx >= 0 && entry < entries[idx]){
idx--;
}
DEBUGclass("stopping search at index %d",idx);
if(idx < 0 || entry > entries[idx]){
long newidx = 1+idx;
DEBUGclass("did not find entry %d, inserting at %d",entry,newidx);
entries.insert(entries.begin()+newidx,entry);
return newidx;
}
DEBUGclass("found %d==%d at %d",entry,entries[idx],idx);
return idx;
}
bool TQUniqueCut::passed(bool doPrint) const {
if(!this->enabled) {
if (doPrint) {
INFOclass("[TreeIndex: %ld] UniqueCut '%s' passed (cut not enabled)", this->fTree?this->fTree->GetReadEntry():-1, this->GetName());
}
return true;
}
long event = this->eventNumberObservable->getValue();
long run = this->runNumberObservable->getValue();
DEBUGclass("checking unique event %ld : %ld",run,event);
long runIdx = getIndex(runNumbers,run);
if(runNumbers.size() > eventNumbers.size()){
DEBUGclass("extending eventnumber list");
auto b = eventNumbers.begin();
std::set<long> newelem;
eventNumbers.insert(b+runIdx,newelem);
}
#ifdef _DEBUG_
if(runIdx >= (long)(eventNumbers.size())){
throw std::runtime_error("event number list has insufficient length!");
} else {
DEBUGclass("event number list length %ld is suffucient for run index %ld",(long)(eventNumbers.size()),runIdx);
}
#endif
DEBUGclass("checking unique for run %ld at %ld (%ld events)",runNumbers[runIdx],runIdx,eventNumbers[runIdx].size());
const bool unique = TQUniqueCut::checkUnique(eventNumbers[runIdx],event);
DEBUGclass("returning %d",unique);
if(!unique){
if (doPrint || TQUniqueCut::printOnVeto) {
INFOclass("[TreeIndex: %ld] UniqueCut failed: event known: runNumber %ld : eventNumber %ld", this->fTree?this->fTree->GetReadEntry():-1, run, event);
} else {
DEBUGclass("[TreeIndex: %ld] UniqueCut failed: event known: runNumber %ld : eventNumber %ld", this->fTree?this->fTree->GetReadEntry():-1, run, event);
}
#ifdef _DEBUG_
#endif
} else {
if (doPrint) {
INFOclass("[TreeIndex: %ld] UniqueCut passed: new event: runNumber %ld : eventNumber %ld",this->fTree?this->fTree->GetReadEntry():-1, run,event);
} else {
DEBUGclass("[TreeIndex: %ld] UniqueCut passed: new event: runNumber %ld : eventNumber %ld",this->fTree?this->fTree->GetReadEntry():-1, run,event);
}
}
return unique;
}
bool TQUniqueCut::initializeObservables() {
this->eventNumberObservable = TQObservable::getObservable(this->eventNumberBranch,this->fSample);
this->runNumberObservable = TQObservable::getObservable(this->runNumberBranch,this->fSample);
if (!runNumberObservable || !eventNumberObservable) return false;
bool ok = true;
if (!runNumberObservable ->initialize(this->fSample)) {
ERRORclass("Failed to initialize runNumberObservable obtained from expression '%s' in TQUniqueCut '%s' for sample '%s'",this->runNumberBranch.Data(), this->GetName(), this->fSample->getPath().Data());
ok = false;
}
if (!eventNumberObservable->initialize(this->fSample)){
ok = false;
}
if (!ok) {
this->finalizeObservables();
return false;
}
return true;
}
bool TQUniqueCut::finalizeObservables() {
if (runNumberObservable && eventNumberObservable){
return runNumberObservable ->finalize() && eventNumberObservable ->finalize();
}
if(runNumberObservable) runNumberObservable ->finalize();
if(eventNumberObservable) eventNumberObservable ->finalize();
return false;
}
void TQUniqueCut::printLists() const {
for (size_t i=0; i<runNumbers.size(); i++) {
std::cout << "===" << runNumbers[i] << "===" << std::endl;
size_t length = eventNumbers[i].size();
for (const long& en : eventNumbers[i]) {
if (--length) {
std::cout << en << ", ";
} else {
std::cout<< en << std::endl;
}
}
}
}
bool TQUniqueCut::initializeSelfSampleFolder(TQSampleFolder* sf){
if(sf->getTagBoolDefault("resetUniqueCut",false)) this->clear();
return true;
}
bool TQUniqueCut::finalizeSelfSampleFolder(TQSampleFolder* sf){
if(sf->getTagBoolDefault("resetUniqueCut",false)) this->clear();
return true;
}