Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-18 09:22:11

0001 #include <calobase/TowerInfoDefs.h>
0002 
0003 #include <TSystem.h>
0004 #include <TString.h>
0005 #include <TFile.h>
0006 #include <TProfile2D.h>
0007 #include <TTree.h>
0008 
0009 #include <format>
0010 #include <iostream>
0011 #include <sstream>
0012 #include <vector>
0013 #include <ctime>
0014 
0015 R__LOAD_LIBRARY(libcalo_io.so)
0016 
0017 // Helper: run a psql command, capture output, retry with backoff.
0018 // flags should be like "-t -A" (scalar) or "-t -A -F," (CSV)
0019 bool psql_run(const TString& dbhost,
0020           const TString& dbname,
0021           const TString& sql,   // already fully quoted: e.g. "\"SELECT ...;\""
0022           TString& out,
0023           const char* flags,
0024           int max_retries = 5,
0025           int backoff_ms  = 500)
0026 {
0027   out.Clear();
0028   for (int attempt = 1; attempt <= max_retries; ++attempt) {
0029     // temp file unique per attempt
0030     Long64_t now = static_cast<Long64_t>(time(nullptr));
0031     TString tmp = std::format("/tmp/getCaloTemp_{}_{}_{}.txt",
0032                    gSystem->GetPid(), now, attempt);
0033 
0034     // Build command; stderr suppressed (2>/dev/null) so output is clean
0035     TString cmd = std::format("psql -h {} -d {} {} -c {} > {} 2>/dev/null",
0036                        dbhost.Data(), dbname.Data(), flags, sql.Data(), tmp.Data());
0037 
0038     int code = gSystem->Exec(cmd.Data());
0039     TString contents = gSystem->GetFromPipe(std::format("cat {}; rm -f {}", tmp.Data(), tmp.Data()).c_str());
0040     contents = contents.Strip(TString::kBoth, '\n');
0041 
0042     // Success if exit code is 0 and we got some content (and not an obvious error string)
0043     if (code == 0 && contents.Length() > 0 && !contents.Contains("ERROR")) {
0044       out = contents;
0045       return true;
0046     }
0047 
0048     // Backoff before next attempt
0049     if (attempt < max_retries) gSystem->Sleep(backoff_ms * attempt);
0050   }
0051   return false;
0052 }
0053 
0054 void getCaloTemp(int runnumber = 54263, const TString& detector = "HCALIN",
0055                  int max_retries = 5, int backoff_ms = 500)
0056 {
0057   // Database info
0058   const TString dbhost = "sphnxdaqdbreplica";
0059   const TString dbname = "daq";
0060 
0061   // --- 1) Get run start time (brtimestamp)
0062   TString sql = std::format("\"SELECT brtimestamp FROM run WHERE runnumber={};\"", runnumber);
0063 
0064   TString runtime;
0065   if (!psql_run(dbhost, dbname, sql, runtime, "-t -A", max_retries, backoff_ms)) {
0066     std::cerr << "[getCaloTemp] Run " << runnumber
0067               << ": failed to fetch brtimestamp after retries.\n";
0068     return;
0069   }
0070   runtime = runtime.Strip(TString::kBoth, '\n');
0071   std::cout << "Run " << runnumber << " runtime: " << runtime << std::endl;
0072 
0073   // --- 2) Choose detector table & columns
0074   TString tablename;
0075   TString tempstring = "temp";
0076   int det = -1;
0077   if (detector == "CEMC") {
0078     tablename = "emcal_heartbeat";
0079     // two columns exist; alias first one as 'temp' so our parser keeps using column #2 overall
0080     tempstring = "temp_sipm as temp, temp_pa";
0081   } else if (detector == "HCALIN") {
0082     tablename = "hcal_heartbeat";
0083     det = 1;
0084   } else if (detector == "HCALOUT") {
0085     tablename = "hcal_heartbeat";
0086     det = 0;
0087   } else {
0088     std::cerr << "[getCaloTemp] Unknown detector: " << detector << std::endl;
0089     return;
0090   }
0091 
0092   // --- 3) Find closest timestamp to run start (retry)
0093   
0094   // --- 3) Find closest timestamp to run start (fast + filtered)
0095   
0096   sql = std::format("\"SELECT time FROM {} "
0097            "WHERE {} "
0098            "ORDER BY ABS(EXTRACT(epoch FROM time) - EXTRACT(epoch FROM '{}'::timestamp)) "
0099            "LIMIT 1;\"",
0100            tablename.Data(),
0101            (det >= 0 ? std::format("detector={}", det) : "TRUE"),
0102            runtime.Data());
0103   
0104 /*
0105   sql = std::format("\"SELECT time FROM %s " 
0106              "ORDER BY ABS(EXTRACT(epoch FROM time) - EXTRACT(epoch FROM '%s'::timestamp)) "
0107              "LIMIT 1;\"", tablename.Data(), runtime.Data()); 
0108 */ 
0109 
0110   TString closest_time;
0111   if (!psql_run(dbhost, dbname, sql, closest_time, "-t -A", max_retries, backoff_ms)) {
0112     std::cerr << "[getCaloTemp] Run " << runnumber
0113               << ": failed to fetch closest heartbeat time after retries.\n";
0114     return;
0115   }
0116   closest_time = closest_time.Strip(TString::kBoth, '\n');
0117   std::cout << "Closest DB time: " << closest_time << std::endl;
0118 
0119   // --- 4) Get temperatures (CSV) for that timestamp (retry)
0120   sql = std::format("\"SELECT towerid, {} FROM {} WHERE time='{}'{};\"",
0121              tempstring.Data(),
0122              tablename.Data(),
0123              closest_time.Data(),
0124              (det >= 0 ? std::format(" AND detector={}", det) : ""));
0125 
0126   TString csvrows;
0127   if (!psql_run(dbhost, dbname, sql, csvrows, "-t -A -F,", max_retries, backoff_ms)) {
0128     std::cerr << "[getCaloTemp] Run " << runnumber
0129               << ": failed to fetch temperature rows after retries.\n";
0130     return;
0131   }
0132 
0133   if (csvrows.Length() == 0) {
0134     std::cerr << "[getCaloTemp] Run " << runnumber << ": No temperature data returned.\n";
0135     return;
0136   }
0137   // std::cout << "Raw temperature rows:\n" << csvrows << std::endl;
0138 
0139   // --- 5) Parse and fill
0140   std::istringstream iss(csvrows.Data());
0141   std::string line;
0142   
0143   TString outdir;
0144   if (detector == "HCALOUT") {
0145     outdir = "temp_ohcal";
0146   } else if (detector == "HCALIN") {
0147     outdir = "temp_ihcal";
0148   } else if (detector == "CEMC") {
0149     outdir = "temp_emcal";
0150   } else {
0151     outdir = "temp_other";
0152   }
0153 
0154   gSystem->mkdir(outdir, kTRUE);
0155 
0156   // Build full output filename
0157   TString outname = std::format("{}/{}_temp_{}.root",
0158                        outdir.Data(),
0159                        detector.Data(),
0160                        runnumber);
0161 
0162   TFile* fout = new TFile(outname, "RECREATE");
0163 
0164   TProfile2D* htemp = nullptr;
0165   if (detector == "CEMC")
0166     htemp = new TProfile2D("h_cemc_temp", ";eta;phi", 96, 0, 96, 256, 0, 256);
0167   else
0168     htemp = new TProfile2D(std::format("h_{}_temp", detector.Data()).c_str(), ";eta;phi", 24, 0, 24, 64, 0, 64);
0169 
0170   while (std::getline(iss, line)) {
0171     if (line.empty()) continue;
0172     std::istringstream ls(line);
0173     std::string token;
0174     std::vector<std::string> parts;
0175     while (std::getline(ls, token, ',')) parts.push_back(token);
0176 
0177     // Expect: towerid, temp[, temp_pa]
0178     if (parts.size() < 2) continue;
0179 
0180     int towerid = 0;
0181     try { towerid = std::stoi(parts[0]); } catch (...) { continue; }
0182 
0183     float temp = 0.0F;
0184     try { temp = std::stof(parts[1]); } catch (...) { continue; }
0185 
0186     int calo_key;
0187     if (detector == "CEMC") { calo_key = TowerInfoDefs::encode_emcal(towerid); }
0188     else                    { calo_key = TowerInfoDefs::encode_hcal(towerid); }
0189 
0190     const int etabin = TowerInfoDefs::getCaloTowerEtaBin(calo_key);
0191     const int phibin = TowerInfoDefs::getCaloTowerPhiBin(calo_key);
0192 
0193     htemp->Fill(etabin, phibin, temp);
0194   }
0195 
0196   htemp->Write();
0197   fout->Close();
0198   std::cout << "Histogram written to " << outname << std::endl;
0199 }
0200