File indexing completed on 2026-04-06 08:12:10
0001 #ifndef SEPDEVENTPLANECALIB_QVECCALIB_H
0002 #define SEPDEVENTPLANECALIB_QVECCALIB_H
0003
0004 #include "QVecDefs.h"
0005
0006 #include <fun4all/SubsysReco.h>
0007
0008 #include <array>
0009 #include <map>
0010 #include <stdexcept>
0011 #include <string>
0012 #include <string_view>
0013 #include <unordered_set>
0014 #include <vector>
0015
0016 class PHCompositeNode;
0017 class EventPlaneData;
0018 class TFile;
0019 class TH1;
0020 class TH2;
0021 class TProfile;
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class QVecCalib : public SubsysReco
0039 {
0040 public:
0041 explicit QVecCalib(const std::string& name = "QVecCalib");
0042
0043
0044
0045
0046
0047
0048 int Init(PHCompositeNode* topNode) override;
0049
0050
0051
0052
0053
0054 int InitRun(PHCompositeNode *topNode) override;
0055
0056
0057
0058
0059 int process_event(PHCompositeNode* topNode) override;
0060
0061
0062 int ResetEvent(PHCompositeNode* topNode) override;
0063
0064
0065 int End(PHCompositeNode* topNode) override;
0066
0067 enum class Pass
0068 {
0069 ComputeRecentering,
0070 ApplyRecentering,
0071 ApplyFlattening
0072 };
0073
0074 void set_pass(int pass)
0075 {
0076 m_pass = validate_pass(pass);
0077 }
0078
0079 void set_input_hist(std::string_view file)
0080 {
0081 m_input_hist = file;
0082 }
0083
0084 void set_input_Q_calib(std::string_view file)
0085 {
0086 m_input_Q_calib = file;
0087 }
0088
0089 void set_dst_tag(std::string_view tag)
0090 {
0091 m_dst_tag = tag;
0092 }
0093
0094 void set_cdb_output_dir(std::string_view cdb_dir)
0095 {
0096 m_cdb_output_dir = cdb_dir;
0097 }
0098
0099 private:
0100 static Pass validate_pass(int pass)
0101 {
0102 switch (pass)
0103 {
0104 case 0:
0105 return Pass::ComputeRecentering;
0106 case 1:
0107 return Pass::ApplyRecentering;
0108 case 2:
0109 return Pass::ApplyFlattening;
0110 default:
0111 throw std::invalid_argument("Invalid pass value");
0112 }
0113 }
0114
0115 struct CorrectionData
0116 {
0117 QVecShared::QVec avg_Q{};
0118
0119 double avg_Q_xx{0.0};
0120 double avg_Q_yy{0.0};
0121 double avg_Q_xy{0.0};
0122
0123 std::array<std::array<double, 2>, 2> X_matrix{};
0124 };
0125
0126 static constexpr size_t m_cent_bins = QVecShared::CENT_BINS;
0127 static constexpr auto m_harmonics = QVecShared::HARMONICS;
0128
0129 static constexpr float SIGMA_HOT {6.0};
0130 static constexpr float SIGMA_COLD {-6.0};
0131
0132 double m_cent_low{-0.5};
0133 double m_cent_high{79.5};
0134
0135 std::string m_input_hist;
0136 std::string m_input_Q_calib;
0137 std::string m_dst_tag;
0138 std::string m_cdb_output_dir{"."};
0139 Pass m_pass{Pass::ComputeRecentering};
0140 EventPlaneData* m_evtdata{nullptr};
0141
0142 int m_event{0};
0143 int m_runnumber{0};
0144
0145 struct EventCounters
0146 {
0147 int bad_centrality_sepd_correlation{0};
0148 int zero_sepd_total_charge{0};
0149 int total_processed{0};
0150 };
0151
0152 EventCounters m_event_counters;
0153
0154 std::array<std::array<QVecShared::QVec, 2>, m_harmonics.size()> m_q_vectors{};
0155
0156 static constexpr int PROGRESS_REPORT_INTERVAL = 10000;
0157
0158
0159
0160
0161
0162 std::array<std::array<std::array<CorrectionData, 3>, m_harmonics.size()>, m_cent_bins> m_correction_data;
0163
0164
0165 static constexpr std::array<QVecShared::Subdetector, 2> m_subdetectors = {QVecShared::Subdetector::S, QVecShared::Subdetector::N};
0166 static constexpr std::array<QVecShared::QComponent, 2> m_components = {QVecShared::QComponent::X, QVecShared::QComponent::Y};
0167
0168
0169 std::vector<std::vector<std::pair<double, double>>> m_trig_cache;
0170
0171 struct AverageHists
0172 {
0173 TProfile* S_x_avg{nullptr};
0174 TProfile* S_y_avg{nullptr};
0175 TProfile* N_x_avg{nullptr};
0176 TProfile* N_y_avg{nullptr};
0177
0178 TH2* Psi_S{nullptr};
0179 TH2* Psi_N{nullptr};
0180 TH2* Psi_NS{nullptr};
0181 };
0182
0183 struct RecenterHists
0184 {
0185 TProfile* S_x_corr_avg{nullptr};
0186 TProfile* S_y_corr_avg{nullptr};
0187 TProfile* N_x_corr_avg{nullptr};
0188 TProfile* N_y_corr_avg{nullptr};
0189
0190 TProfile* S_xx_avg{nullptr};
0191 TProfile* S_yy_avg{nullptr};
0192 TProfile* S_xy_avg{nullptr};
0193 TProfile* N_xx_avg{nullptr};
0194 TProfile* N_yy_avg{nullptr};
0195 TProfile* N_xy_avg{nullptr};
0196
0197 TProfile* NS_xx_avg{nullptr};
0198 TProfile* NS_yy_avg{nullptr};
0199 TProfile* NS_xy_avg{nullptr};
0200
0201 TH2* Psi_S_corr{nullptr};
0202 TH2* Psi_N_corr{nullptr};
0203 TH2* Psi_NS_corr{nullptr};
0204 };
0205
0206 struct FlatteningHists
0207 {
0208 TProfile* S_x_corr2_avg{nullptr};
0209 TProfile* S_y_corr2_avg{nullptr};
0210 TProfile* N_x_corr2_avg{nullptr};
0211 TProfile* N_y_corr2_avg{nullptr};
0212
0213 TProfile* S_xx_corr_avg{nullptr};
0214 TProfile* S_yy_corr_avg{nullptr};
0215 TProfile* S_xy_corr_avg{nullptr};
0216
0217 TProfile* N_xx_corr_avg{nullptr};
0218 TProfile* N_yy_corr_avg{nullptr};
0219 TProfile* N_xy_corr_avg{nullptr};
0220
0221 TProfile* NS_xx_corr_avg{nullptr};
0222 TProfile* NS_yy_corr_avg{nullptr};
0223 TProfile* NS_xy_corr_avg{nullptr};
0224
0225 TH2* Psi_S_corr2{nullptr};
0226 TH2* Psi_N_corr2{nullptr};
0227 TH2* Psi_NS_corr2{nullptr};
0228 };
0229
0230
0231 std::unordered_set<int> m_bad_channels;
0232
0233 double m_sEPD_min_avg_charge_threshold{1};
0234 double m_sEPD_sigma_threshold{3};
0235
0236
0237 TH1* hCentrality{nullptr};
0238
0239 TH2* h2SEPD_Charge{nullptr};
0240 TH2* h2SEPD_Chargev2{nullptr};
0241
0242 TH2* h2SEPD_South_Charge_rbin{nullptr};
0243 TH2* h2SEPD_North_Charge_rbin{nullptr};
0244
0245 TH2* h2SEPD_South_Charge_rbinv2{nullptr};
0246 TH2* h2SEPD_North_Charge_rbinv2{nullptr};
0247
0248 TProfile* hSEPD_Charge_Min{nullptr};
0249 TProfile* hSEPD_Charge_Max{nullptr};
0250
0251 TProfile* hSEPD_Bad_Channels{nullptr};
0252
0253 std::map<std::string, TH2*> m_hists2D;
0254 std::map<std::string, TProfile*> m_profiles;
0255
0256 std::vector<AverageHists> m_average_hists;
0257 std::vector<RecenterHists> m_recenter_hists;
0258 std::vector<FlatteningHists> m_flattening_hists;
0259
0260
0261
0262
0263
0264
0265 void init_hists();
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 template <typename T>
0278 T* load_and_clone(TFile* file, const std::string& name);
0279
0280
0281
0282
0283
0284
0285 int load_correction_data();
0286
0287
0288
0289
0290
0291
0292
0293 bool process_event_check();
0294
0295
0296
0297
0298
0299
0300
0301 bool process_sEPD();
0302
0303
0304
0305
0306
0307
0308
0309
0310 static void process_averages(double cent, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const AverageHists& h);
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320 void process_recentering(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const RecenterHists& h);
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330 void process_flattening(double cent, size_t h_idx, const QVecShared::QVec& q_S, const QVecShared::QVec& q_N, const FlatteningHists& h);
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346 std::array<std::array<double, 2>, 2> calculate_flattening_matrix(double xx, double yy, double xy, int n, int cent_bin, const std::string& det_label);
0347
0348
0349
0350
0351
0352
0353
0354
0355 void compute_averages(size_t cent_bin, int h_idx);
0356
0357
0358
0359
0360
0361
0362
0363
0364 void compute_recentering(size_t cent_bin, int h_idx);
0365
0366
0367
0368
0369
0370
0371 void print_flattening(size_t cent_bin, int n) const;
0372
0373 void prepare_hists();
0374
0375
0376
0377
0378
0379 void prepare_average_hists();
0380
0381
0382
0383
0384
0385 void prepare_recenter_hists();
0386
0387
0388
0389
0390
0391 void prepare_flattening_hists();
0392
0393
0394
0395
0396
0397
0398 int process_QA_hist();
0399
0400
0401
0402
0403
0404
0405
0406 int process_bad_channels(TFile* file);
0407
0408
0409
0410
0411
0412
0413
0414 int process_sEPD_event_thresholds(TFile* file);
0415
0416 void write_cdb();
0417
0418
0419
0420
0421
0422
0423
0424 void write_cdb_EventPlane();
0425
0426
0427
0428
0429
0430
0431
0432 void write_cdb_BadTowers();
0433 };
0434
0435 #endif