File indexing completed on 2024-04-06 12:21:59
0001
0002
0003
0004
0005
0006
0007
0008 #include "L1Trigger/TrackFindingTracklet/interface/imath.h"
0009
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011
0012 #include <cmath>
0013
0014 using namespace trklet;
0015
0016 std::string VarBase::itos(int i) { return std::to_string(i); }
0017
0018 std::string VarBase::kstring() const {
0019 char s[1024];
0020 std::string t = "";
0021 for (const auto &Kmap : Kmap_) {
0022 sprintf(s, "^(%i)", Kmap.second);
0023 std::string t0(s);
0024 t = t + Kmap.first + t0;
0025 }
0026 return t;
0027 }
0028
0029 void VarBase::analyze() {
0030 if (!readytoanalyze_)
0031 return;
0032
0033 double u = maxval_;
0034 if (u < -minval_)
0035 u = -minval_;
0036
0037 int iu = log2(range() / u);
0038 if (iu > 1) {
0039 char slog[1024];
0040 sprintf(slog,
0041 "analyzing %s: range %g is much larger then %g. suggest cutting by a factor of 2^%i",
0042 name_.c_str(),
0043 range(),
0044 u,
0045 iu);
0046 edm::LogVerbatim("Tracklet") << slog;
0047 }
0048 #ifdef IMATH_ROOT
0049 char slog[100];
0050 if (h_) {
0051 double eff = h_->Integral() / h_->GetEntries();
0052 if (eff < 0.99) {
0053 sprintf(slog, "analyzing %s: range is too small, contains %f", name_.c_str(), eff);
0054 edm::LogVerbatim("Tracklet") << slog;
0055 h_->Print();
0056 }
0057 globals_->h_file_->cd();
0058 TCanvas *c = new TCanvas();
0059 c->cd();
0060 h_->Draw("colz");
0061 h_->Write();
0062 } else {
0063 if (globals_->use_root) {
0064 sprintf(slog, "analyzing %s: no histogram!\n", name_.c_str());
0065 edm::LogVerbatim("Tracklet") << slog;
0066 }
0067 }
0068 #endif
0069
0070 if (p1_)
0071 p1_->analyze();
0072 if (p2_)
0073 p2_->analyze();
0074
0075 readytoanalyze_ = false;
0076 }
0077
0078 std::string VarBase::dump() {
0079 char s[1024];
0080 std::string u = kstring();
0081 sprintf(
0082 s,
0083 "Name = %s \t Op = %s \t nbits = %i \n ival = %li \t fval = %g \t K = %g Range = %f\n units = %s\n",
0084 name_.c_str(),
0085 op_.c_str(),
0086 nbits_,
0087 ival_,
0088 fval_,
0089 K_,
0090 range(),
0091 u.c_str());
0092 std::string t(s);
0093 return t;
0094 }
0095
0096 void VarBase::dump_msg() {
0097 char s[2048];
0098 std::string u = kstring();
0099 sprintf(s,
0100 "Name = %s \t Op = %s \t nbits = %i \n ival = %li \t fval = %g \t K = %g Range = %f\n units = "
0101 "%s\n step = %i, latency = %i\n",
0102 name_.c_str(),
0103 op_.c_str(),
0104 nbits_,
0105 ival_,
0106 fval_,
0107 K_,
0108 range(),
0109 u.c_str(),
0110 step_,
0111 latency_);
0112 std::string t(s);
0113 edm::LogVerbatim("Tracklet") << t;
0114 if (p1_)
0115 p1_->dump_msg();
0116 if (p2_)
0117 p2_->dump_msg();
0118 }
0119
0120 void VarAdjustK::adjust(double Knew, double epsilon, bool do_assert, int nbits) {
0121
0122
0123
0124
0125 K_ = p1_->K();
0126 Kmap_ = p1_->Kmap();
0127 double r = Knew / K_;
0128
0129 lr_ = (r > 1) ? log2(r) + epsilon : log2(r);
0130 K_ = K_ * pow(2, lr_);
0131 if (do_assert)
0132 assert(std::abs(Knew / K_ - 1) < epsilon);
0133
0134 if (nbits > 0)
0135 nbits_ = nbits;
0136 else
0137 nbits_ = p1_->nbits() - lr_;
0138
0139 Kmap_["2"] = Kmap_["2"] + lr_;
0140 }
0141
0142 void VarInv::initLUT(double offset) {
0143 offset_ = offset;
0144 double offsetI = lround(offset_ / p1_->K());
0145 for (int i = 0; i < Nelements_; ++i) {
0146 int i1 = addr_to_ival(i);
0147 LUT[i] = gen_inv(offsetI + i1);
0148 }
0149 }
0150
0151 void VarBase::makeready() {
0152 pipe_counter_ = 0;
0153 pipe_delays_.clear();
0154 readytoprint_ = true;
0155 readytoanalyze_ = true;
0156 usedasinput_ = false;
0157 if (p1_)
0158 p1_->makeready();
0159 if (p2_)
0160 p2_->makeready();
0161 if (p3_)
0162 p3_->makeready();
0163 }
0164
0165 bool VarBase::has_delay(int i) {
0166
0167 for (int pipe_delay : pipe_delays_)
0168 if (pipe_delay == i)
0169 return true;
0170 return false;
0171 }
0172
0173 std::string VarBase::pipe_delay(VarBase *v, int nbits, int delay) {
0174
0175 if (v->has_delay(delay))
0176 return "";
0177 v->add_delay(delay);
0178 std::string name = v->name();
0179 std::string name_delayed = name + "_delay" + itos(delay);
0180 std::string out = "wire signed [" + itos(nbits - 1) + ":0] " + name_delayed + ";\n";
0181 out = out + pipe_delay_wire(v, name_delayed, nbits, delay);
0182 return out;
0183 }
0184 std::string VarBase::pipe_delays(const int step) {
0185 std::string out = "";
0186 if (p1_)
0187 out += p1_->pipe_delays(step);
0188 if (p2_)
0189 out += p2_->pipe_delays(step);
0190 if (p3_)
0191 out += p3_->pipe_delays(step);
0192
0193 int l = step - latency_ - step_;
0194 return (out + pipe_delay(this, nbits(), l));
0195 }
0196 std::string VarBase::pipe_delay_wire(VarBase *v, std::string name_delayed, int nbits, int delay) {
0197 std::string name = v->name();
0198 std::string name_pipe = name + "_pipe" + itos(v->pipe_counter());
0199 v->pipe_increment();
0200 std::string out = "pipe_delay #(.STAGES(" + itos(delay) + "), .WIDTH(" + itos(nbits) + ")) " + name_pipe +
0201 "(.clk(clk), .val_in(" + name + "), .val_out(" + name_delayed + "));\n";
0202 return out;
0203 }
0204
0205 void VarBase::inputs(std::vector<VarBase *> *vd) {
0206 if (op_ == "def" && !usedasinput_) {
0207 usedasinput_ = true;
0208 vd->push_back(this);
0209 } else {
0210 if (p1_)
0211 p1_->inputs(vd);
0212 if (p2_)
0213 p2_->inputs(vd);
0214 if (p3_)
0215 p3_->inputs(vd);
0216 }
0217 }
0218
0219 #ifdef IMATH_ROOT
0220 TTree *VarBase::addToTree(imathGlobals *globals, VarBase *v, char *s) {
0221 if (globals->h_file_ == 0) {
0222 globals->h_file_ = new TFile("imath.root", "RECREATE");
0223 edm::LogVerbatim("Tracklet") << "recreating file imath.root";
0224 }
0225 globals->h_file_->cd();
0226 TTree *tt = (TTree *)globals->h_file_->Get("tt");
0227 if (tt == 0) {
0228 tt = new TTree("tt", "");
0229 edm::LogVerbatim("Tracklet") << "creating TTree tt";
0230 }
0231 std::string si = v->name() + "_i";
0232 std::string sf = v->name() + "_f";
0233 std::string sv = v->name();
0234 if (s != 0) {
0235 std::string prefix(s);
0236 si = prefix + si;
0237 sf = prefix + sf;
0238 sv = prefix + sv;
0239 }
0240 if (!tt->GetBranchStatus(si.c_str())) {
0241 tt->Branch(si.c_str(), (Long64_t *)&(v->ival_));
0242 tt->Branch(sf.c_str(), &(v->fval_));
0243 tt->Branch(sv.c_str(), &(v->val_));
0244 }
0245
0246 if (v->p1_)
0247 addToTree(globals, v->p1_, s);
0248 if (v->p2_)
0249 addToTree(globals, v->p2_, s);
0250 if (v->p3_)
0251 addToTree(globals, v->p3_, s);
0252
0253 return tt;
0254 }
0255 TTree *VarBase::addToTree(imathGlobals *globals, double *v, char *s) {
0256 if (globals->h_file_ == 0) {
0257 globals->h_file_ = new TFile("imath.root", "RECREATE");
0258 edm::LogVerbatim("Tracklet") << "recreating file imath.root";
0259 }
0260 globals->h_file_->cd();
0261 TTree *tt = (TTree *)globals->h_file_->Get("tt");
0262 if (tt == 0) {
0263 tt = new TTree("tt", "");
0264 edm::LogVerbatim("Tracklet") << "creating TTree tt";
0265 }
0266 tt->Branch(s, v);
0267 return tt;
0268 }
0269 TTree *VarBase::addToTree(imathGlobals *globals, int *v, char *s) {
0270 if (globals->h_file_ == 0) {
0271 globals->h_file_ = new TFile("imath.root", "RECREATE");
0272 edm::LogVerbatim("Tracklet") << "recreating file imath.root";
0273 }
0274 globals->h_file_->cd();
0275 TTree *tt = (TTree *)globals->h_file_->Get("tt");
0276 if (tt == 0) {
0277 tt = new TTree("tt", "");
0278 edm::LogVerbatim("Tracklet") << "creating TTree tt";
0279 }
0280 tt->Branch(s, v);
0281 return tt;
0282 }
0283 void VarBase::fillTree(imathGlobals *globals) {
0284 if (globals->h_file_ == 0)
0285 return;
0286 globals->h_file_->cd();
0287 TTree *tt = (TTree *)globals->h_file_->Get("tt");
0288 if (tt == 0)
0289 return;
0290 tt->Fill();
0291 }
0292 void VarBase::writeTree(imathGlobals *globals) {
0293 if (globals->h_file_ == 0)
0294 return;
0295 globals->h_file_->cd();
0296 TTree *tt = (TTree *)globals->h_file_->Get("tt");
0297 if (tt == 0)
0298 return;
0299 tt->Write();
0300 }
0301
0302 #endif
0303
0304 void VarCut::local_passes(std::map<const VarBase *, std::vector<bool> > &passes,
0305 const std::map<const VarBase *, std::vector<bool> > *const previous_passes) const {
0306 const int lower_cut = lower_cut_ / cut_var_->K();
0307 const int upper_cut = upper_cut_ / cut_var_->K();
0308 if (!previous_passes || (previous_passes && !previous_passes->count(cut_var_))) {
0309 if (!passes.count(cut_var_))
0310 passes[cut_var_];
0311 passes.at(cut_var_).push_back(cut_var_->ival() > lower_cut && cut_var_->ival() < upper_cut);
0312 }
0313 }
0314
0315 bool VarBase::local_passes() const {
0316 bool passes = false;
0317 for (const auto &cut : cuts_) {
0318 const VarCut *const cast_cut = (VarCut *)cut;
0319 const int lower_cut = cast_cut->lower_cut() / K_;
0320 const int upper_cut = cast_cut->upper_cut() / K_;
0321 passes = passes || (ival_ > lower_cut && ival_ < upper_cut);
0322 if (globals_->printCutInfo_) {
0323 edm::LogVerbatim("Tracklet") << " " << name_ << " "
0324 << ((ival_ > lower_cut && ival_ < upper_cut) ? "PASSES" : "FAILS")
0325 << " (required: " << lower_cut * K_ << " < " << ival_ * K_ << " < " << upper_cut * K_
0326 << ")";
0327 }
0328 }
0329 return passes;
0330 }
0331
0332 void VarBase::passes(std::map<const VarBase *, std::vector<bool> > &passes,
0333 const std::map<const VarBase *, std::vector<bool> > *const previous_passes) const {
0334 if (p1_)
0335 p1_->passes(passes, previous_passes);
0336 if (p2_)
0337 p2_->passes(passes, previous_passes);
0338 if (p3_)
0339 p3_->passes(passes, previous_passes);
0340
0341 for (const auto &cut : cuts_) {
0342 const VarCut *const cast_cut = (VarCut *)cut;
0343 const int lower_cut = cast_cut->lower_cut() / K_;
0344 const int upper_cut = cast_cut->upper_cut() / K_;
0345 if (!previous_passes || (previous_passes && !previous_passes->count(this))) {
0346 if (!passes.count(this))
0347 passes[this];
0348 passes.at(this).push_back(ival_ > lower_cut && ival_ < upper_cut);
0349 if (globals_->printCutInfo_) {
0350 edm::LogVerbatim("Tracklet") << " " << name_ << " "
0351 << ((ival_ > lower_cut && ival_ < upper_cut) ? "PASSES" : "FAILS")
0352 << " (required: " << lower_cut * K_ << " < " << ival_ * K_ << " < "
0353 << upper_cut * K_ << ")";
0354 }
0355 }
0356 }
0357 }
0358
0359 void VarBase::add_cut(VarCut *cut, const bool call_set_cut_var) {
0360 cuts_.push_back(cut);
0361 if (call_set_cut_var)
0362 cut->set_cut_var(this, false);
0363 }
0364
0365 void VarCut::set_cut_var(VarBase *cut_var, const bool call_add_cut) {
0366 cut_var_ = cut_var;
0367 if (call_add_cut)
0368 cut_var->add_cut(this, false);
0369 if (parent_flag_)
0370 parent_flag_->calculate_step();
0371 }
0372
0373 void VarFlag::add_cut(VarBase *cut, const bool call_set_parent_flag) {
0374 cuts_.push_back(cut);
0375 if (cut->op() == "cut" && call_set_parent_flag) {
0376 VarCut *const cast_cut = (VarCut *)cut;
0377 cast_cut->set_parent_flag(this, false);
0378 }
0379 calculate_step();
0380 }
0381
0382 void VarCut::set_parent_flag(VarFlag *parent_flag, const bool call_add_cut) {
0383 parent_flag_ = parent_flag;
0384 if (call_add_cut)
0385 parent_flag->add_cut(this, false);
0386 }
0387
0388 VarBase *VarBase::cut_var() {
0389 if (op_ == "cut")
0390 return cut_var_;
0391 else
0392 return this;
0393 }
0394
0395 bool VarFlag::passes() {
0396 if (globals_->printCutInfo_) {
0397 edm::LogVerbatim("Tracklet") << "Checking if " << name_ << " passes...";
0398 }
0399
0400 std::map<const VarBase *, std::vector<bool> > passes0, passes1;
0401 for (const auto &cut : cuts_) {
0402 if (cut->op() != "cut")
0403 continue;
0404 const VarCut *const cast_cut = (VarCut *)cut;
0405 cast_cut->local_passes(passes0);
0406 }
0407 for (const auto &cut : cuts_) {
0408 if (cut->op() != "cut")
0409 cut->passes(passes1, &passes0);
0410 else {
0411 if (cut->cut_var()->p1())
0412 cut->cut_var()->p1()->passes(passes1, &passes0);
0413 if (cut->cut_var()->p2())
0414 cut->cut_var()->p2()->passes(passes1, &passes0);
0415 if (cut->cut_var()->p3())
0416 cut->cut_var()->p3()->passes(passes1, &passes0);
0417 }
0418 }
0419
0420 bool passes = true;
0421 for (const auto &cut_var : passes0) {
0422 bool local_passes = false;
0423 for (const auto pass : cut_var.second)
0424 local_passes = local_passes || pass;
0425 passes = passes && local_passes;
0426 }
0427 for (const auto &cut_var : passes1) {
0428 bool local_passes = false;
0429 for (const auto pass : cut_var.second)
0430 local_passes = local_passes || pass;
0431 passes = passes && local_passes;
0432 }
0433
0434 if (globals_->printCutInfo_) {
0435 edm::LogVerbatim("Tracklet") << name_ << " " << (passes ? "PASSES" : "FAILS");
0436 }
0437
0438 return passes;
0439 }