File indexing completed on 2026-04-05 08:08:16
0001 #include "AsymmetryCalc/ShuffleBunches.h"
0002 #include "AsymmetryCalc/Constants.h"
0003
0004 #include <iostream>
0005 #include <fstream>
0006 #include <sstream>
0007 #include <random>
0008 #include <cstdlib>
0009 #include <numeric> // for iota
0010
0011 namespace AsymmetryCalc {
0012
0013 ShuffleBunches::ShuffleBunches(const int iMin,
0014 const int iMax,
0015 const std::string& inputfilename_fill_run,
0016 const std::string& inputfilename_spin_pattern,
0017 const std::string& inputfile_template,
0018 const std::string& input_csv_pt_pi0_name,
0019 const std::string& input_csv_eta_pi0_name,
0020 const std::string& input_csv_xf_pi0_name,
0021 const std::string& input_csv_pt_eta_name,
0022 const std::string& input_csv_eta_eta_name,
0023 const std::string& input_csv_xf_eta_name,
0024 const std::string& input_csv_pt_ratios_pi0_name,
0025 const std::string& input_csv_eta_ratios_pi0_name,
0026 const std::string& input_csv_xf_ratios_pi0_name,
0027 const std::string& input_csv_pt_ratios_eta_name,
0028 const std::string& input_csv_eta_ratios_eta_name,
0029 const std::string& input_csv_xf_ratios_eta_name)
0030 : iterMin(iMin),
0031 iterMax(iMax),
0032 infile_template(inputfile_template)
0033 {
0034 nIterations = iterMax - iterMin + 1;
0035 std::ifstream infile_fill_run(inputfilename_fill_run);
0036 if (!infile_fill_run) {
0037 std::cerr << "Could not open file " << inputfilename_fill_run << std::endl;
0038 std::exit(1);
0039 }
0040
0041 int fill_number, run_number;
0042 while (infile_fill_run >> fill_number >> run_number) {
0043 if (fill_to_runs.empty() || fill_to_runs.back().first != fill_number)
0044 {
0045 fill_to_runs.push_back({fill_number, {}});
0046 }
0047 fill_to_runs.back().second.push_back(run_number);
0048 }
0049 nFills = fill_to_runs.size();
0050
0051
0052
0053 get_average_bin_pt_pi0(input_csv_pt_pi0_name);
0054 get_average_bin_eta_pi0(input_csv_eta_pi0_name);
0055 get_average_bin_xf_pi0(input_csv_xf_pi0_name);
0056 get_average_bin_pt_eta(input_csv_pt_eta_name);
0057 get_average_bin_eta_eta(input_csv_eta_eta_name);
0058 get_average_bin_xf_eta(input_csv_xf_eta_name);
0059
0060
0061 get_pt_ratios_pi0(input_csv_pt_ratios_pi0_name);
0062 get_eta_ratios_pi0(input_csv_eta_ratios_pi0_name);
0063 get_xf_ratios_pi0(input_csv_xf_ratios_pi0_name);
0064 get_pt_ratios_eta(input_csv_pt_ratios_eta_name);
0065 get_eta_ratios_eta(input_csv_eta_ratios_eta_name);
0066 get_xf_ratios_eta(input_csv_xf_ratios_eta_name);
0067
0068
0069 inputfile_spin = TFile::Open(inputfilename_spin_pattern.c_str());
0070 spin_patterns = (TTree*)inputfile_spin->Get("spin_patterns");
0071 spin_patterns->SetBranchAddress("fill_number", &fill_spin);
0072 spin_patterns->SetBranchAddress("yellow_polarization", &yellow_polarization);
0073 spin_patterns->SetBranchAddress("blue_polarization", &blue_polarization);
0074 spin_patterns->SetBranchAddress("yellow_spin_pattern", &yellow_spin_pattern);
0075 spin_patterns->SetBranchAddress("blue_spin_pattern", &blue_spin_pattern);
0076 }
0077
0078 void ShuffleBunches::get_average_bin_pt_pi0(const std::string& input_csv_name)
0079 {
0080 std::string line;
0081 std::stringstream linestream;
0082 std::string entry;
0083 std::ifstream input_csv;
0084 input_csv.open(input_csv_name);
0085 if (!input_csv) {
0086 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0087 return;
0088 }
0089 std::getline(input_csv, line);
0090 std::stringstream line_pi0(line);
0091 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0092 std::getline(line_pi0, entry, ',');
0093 float pTMean = std::stof(entry);
0094 pTMeans[0][iPt] = pTMean;
0095 }
0096 std::getline(input_csv, line);
0097 std::stringstream line_eta(line);
0098 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0099 std::getline(line_eta, entry, ',');
0100 }
0101 }
0102
0103 void ShuffleBunches::get_average_bin_pt_eta(const std::string& input_csv_name)
0104 {
0105 std::string line;
0106 std::stringstream linestream;
0107 std::string entry;
0108 std::ifstream input_csv;
0109 input_csv.open(input_csv_name);
0110 if (!input_csv) {
0111 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0112 return;
0113 }
0114 std::getline(input_csv, line);
0115 std::stringstream line_pi0(line);
0116 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0117 std::getline(line_pi0, entry, ',');
0118 }
0119 std::getline(input_csv, line);
0120 std::stringstream line_eta(line);
0121 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0122 std::getline(line_eta, entry, ',');
0123 float pTMean = std::stof(entry);
0124 pTMeans[1][iPt] = pTMean;
0125 }
0126 }
0127
0128 void ShuffleBunches::get_average_bin_eta_pi0(const std::string& input_csv_name)
0129 {
0130 std::string line;
0131 std::stringstream linestream;
0132 std::string entry;
0133 std::ifstream input_csv;
0134 input_csv.open(input_csv_name);
0135 if (!input_csv) {
0136 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0137 return;
0138 }
0139 std::getline(input_csv, line);
0140 std::stringstream line_pi0(line);
0141 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0142 std::getline(line_pi0, entry, ',');
0143 float etaMean = std::stof(entry);
0144 etaMeans[0][iEta] = etaMean;
0145 }
0146 std::getline(input_csv, line);
0147 std::stringstream line_eta(line);
0148 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0149 std::getline(line_eta, entry, ',');
0150 }
0151 }
0152
0153 void ShuffleBunches::get_average_bin_eta_eta(const std::string& input_csv_name)
0154 {
0155 std::string line;
0156 std::stringstream linestream;
0157 std::string entry;
0158 std::ifstream input_csv;
0159 input_csv.open(input_csv_name);
0160 if (!input_csv) {
0161 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0162 return;
0163 }
0164 std::getline(input_csv, line);
0165 std::stringstream line_pi0(line);
0166 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0167 std::getline(line_pi0, entry, ',');
0168 }
0169 std::getline(input_csv, line);
0170 std::stringstream line_eta(line);
0171 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0172 std::getline(line_eta, entry, ',');
0173 float etaMean = std::stof(entry);
0174 etaMeans[1][iEta] = etaMean;
0175 }
0176 }
0177
0178 void ShuffleBunches::get_average_bin_xf_pi0(const std::string& input_csv_name)
0179 {
0180 std::string line;
0181 std::stringstream linestream;
0182 std::string entry;
0183 std::ifstream input_csv;
0184 input_csv.open(input_csv_name);
0185 if (!input_csv) {
0186 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0187 return;
0188 }
0189 std::getline(input_csv, line);
0190 std::stringstream line_pi0(line);
0191 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0192 std::getline(line_pi0, entry, ',');
0193 float xfMean = std::stof(entry);
0194 xfMeans[0][iXf] = xfMean;
0195 }
0196 std::getline(input_csv, line);
0197 std::stringstream line_eta(line);
0198 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0199 std::getline(line_eta, entry, ',');
0200 }
0201 }
0202
0203 void ShuffleBunches::get_average_bin_xf_eta(const std::string& input_csv_name)
0204 {
0205 std::string line;
0206 std::stringstream linestream;
0207 std::string entry;
0208 std::ifstream input_csv;
0209 input_csv.open(input_csv_name);
0210 if (!input_csv) {
0211 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0212 return;
0213 }
0214 std::getline(input_csv, line);
0215 std::stringstream line_pi0(line);
0216 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0217 std::getline(line_pi0, entry, ',');
0218 }
0219 std::getline(input_csv, line);
0220 std::stringstream line_eta(line);
0221 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0222 std::getline(line_eta, entry, ',');
0223 float xfMean = std::stof(entry);
0224 xfMeans[1][iXf] = xfMean;
0225 }
0226 }
0227
0228 void ShuffleBunches::get_pt_ratios_pi0(const std::string& input_csv_name)
0229 {
0230 std::string line;
0231 std::stringstream linestream;
0232 std::string entry;
0233 std::ifstream input_csv;
0234 input_csv.open(input_csv_name);
0235 if (!input_csv) {
0236 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0237 return;
0238 }
0239 std::getline(input_csv, line);
0240 std::stringstream line_pi0(line);
0241 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0242 std::getline(line_pi0, entry, ',');
0243 float pTRatio = std::stof(entry);
0244 bkg_ratio_pt[0][iPt] = pTRatio;
0245 }
0246 std::getline(input_csv, line);
0247 std::stringstream line_eta(line);
0248 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0249 std::getline(line_eta, entry, ',');
0250 }
0251 std::getline(input_csv, line);
0252 std::stringstream line_pi0_err(line);
0253 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0254 std::getline(line_pi0_err, entry, ',');
0255 float pTRatioErr = std::stof(entry);
0256 bkg_ratio_err_pt[0][iPt] = pTRatioErr;
0257 }
0258 std::getline(input_csv, line);
0259 std::stringstream line_eta_err(line);
0260 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0261 std::getline(line_eta_err, entry, ',');
0262 }
0263 }
0264
0265 void ShuffleBunches::get_pt_ratios_eta(const std::string& input_csv_name)
0266 {
0267 std::string line;
0268 std::stringstream linestream;
0269 std::string entry;
0270 std::ifstream input_csv;
0271 input_csv.open(input_csv_name);
0272 if (!input_csv) {
0273 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0274 return;
0275 }
0276 std::getline(input_csv, line);
0277 std::stringstream line_pi0(line);
0278 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0279 std::getline(line_pi0, entry, ',');
0280 }
0281 std::getline(input_csv, line);
0282 std::stringstream line_eta(line);
0283 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0284 std::getline(line_eta, entry, ',');
0285 float pTRatio = std::stof(entry);
0286 bkg_ratio_pt[1][iPt] = pTRatio;
0287 }
0288 std::getline(input_csv, line);
0289 std::stringstream line_pi0_err(line);
0290 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0291 std::getline(line_pi0_err, entry, ',');
0292 }
0293 std::getline(input_csv, line);
0294 std::stringstream line_eta_err(line);
0295 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
0296 std::getline(line_eta_err, entry, ',');
0297 float pTRatioErr = std::stof(entry);
0298 bkg_ratio_err_pt[1][iPt] = pTRatioErr;
0299 }
0300 }
0301
0302 void ShuffleBunches::get_eta_ratios_pi0(const std::string& input_csv_name)
0303 {
0304 std::string line;
0305 std::stringstream linestream;
0306 std::string entry;
0307 std::ifstream input_csv;
0308 input_csv.open(input_csv_name);
0309 if (!input_csv) {
0310 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0311 return;
0312 }
0313 std::getline(input_csv, line);
0314 std::stringstream line_pi0(line);
0315 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0316 std::getline(line_pi0, entry, ',');
0317 float etaRatio = std::stof(entry);
0318 bkg_ratio_eta[0][iEta] = etaRatio;
0319 }
0320 std::getline(input_csv, line);
0321 std::stringstream line_eta(line);
0322 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0323 std::getline(line_eta, entry, ',');
0324 }
0325 std::getline(input_csv, line);
0326 std::stringstream line_pi0_err(line);
0327 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0328 std::getline(line_pi0_err, entry, ',');
0329 float etaRatioErr = std::stof(entry);
0330 bkg_ratio_err_eta[0][iEta] = etaRatioErr;
0331 }
0332 std::getline(input_csv, line);
0333 std::stringstream line_eta_err(line);
0334 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0335 std::getline(line_eta_err, entry, ',');
0336 }
0337 }
0338
0339 void ShuffleBunches::get_eta_ratios_eta(const std::string& input_csv_name)
0340 {
0341 std::string line;
0342 std::stringstream linestream;
0343 std::string entry;
0344 std::ifstream input_csv;
0345 input_csv.open(input_csv_name);
0346 if (!input_csv) {
0347 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0348 return;
0349 }
0350 std::getline(input_csv, line);
0351 std::stringstream line_pi0(line);
0352 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0353 std::getline(line_pi0, entry, ',');
0354 }
0355 std::getline(input_csv, line);
0356 std::stringstream line_eta(line);
0357 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0358 std::getline(line_eta, entry, ',');
0359 float etaRatio = std::stof(entry);
0360 bkg_ratio_eta[1][iEta] = etaRatio;
0361 }
0362 std::getline(input_csv, line);
0363 std::stringstream line_pi0_err(line);
0364 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0365 std::getline(line_pi0_err, entry, ',');
0366 }
0367 std::getline(input_csv, line);
0368 std::stringstream line_eta_err(line);
0369 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
0370 std::getline(line_eta_err, entry, ',');
0371 float etaRatioErr = std::stof(entry);
0372 bkg_ratio_err_eta[1][iEta] = etaRatioErr;
0373 }
0374 }
0375
0376 void ShuffleBunches::get_xf_ratios_pi0(const std::string& input_csv_name)
0377 {
0378 std::string line;
0379 std::stringstream linestream;
0380 std::string entry;
0381 std::ifstream input_csv;
0382 input_csv.open(input_csv_name);
0383 if (!input_csv) {
0384 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0385 return;
0386 }
0387 std::getline(input_csv, line);
0388 std::stringstream line_pi0(line);
0389 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0390 std::getline(line_pi0, entry, ',');
0391 float xfRatio = std::stof(entry);
0392 bkg_ratio_xf[0][iXf] = xfRatio;
0393 }
0394 std::getline(input_csv, line);
0395 std::stringstream line_eta(line);
0396 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0397 std::getline(line_eta, entry, ',');
0398 }
0399 std::getline(input_csv, line);
0400 std::stringstream line_pi0_err(line);
0401 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0402 std::getline(line_pi0_err, entry, ',');
0403 float xfRatioErr = std::stof(entry);
0404 bkg_ratio_err_xf[0][iXf] = xfRatioErr;
0405 }
0406 std::getline(input_csv, line);
0407 std::stringstream line_eta_err(line);
0408 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0409 std::getline(line_eta_err, entry, ',');
0410 }
0411 }
0412
0413 void ShuffleBunches::get_xf_ratios_eta(const std::string& input_csv_name)
0414 {
0415 std::string line;
0416 std::stringstream linestream;
0417 std::string entry;
0418 std::ifstream input_csv;
0419 input_csv.open(input_csv_name);
0420 if (!input_csv) {
0421 std::cout << "File " << input_csv_name << " could not be opened." << std::endl;
0422 return;
0423 }
0424 std::getline(input_csv, line);
0425 std::stringstream line_pi0(line);
0426 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0427 std::getline(line_pi0, entry, ',');
0428 }
0429 std::getline(input_csv, line);
0430 std::stringstream line_eta(line);
0431 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0432 std::getline(line_eta, entry, ',');
0433 float xfRatio = std::stof(entry);
0434 bkg_ratio_xf[1][iXf] = xfRatio;
0435 }
0436 std::getline(input_csv, line);
0437 std::stringstream line_pi0_err(line);
0438 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0439 std::getline(line_pi0_err, entry, ',');
0440 }
0441 std::getline(input_csv, line);
0442 std::stringstream line_eta_err(line);
0443 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
0444 std::getline(line_eta_err, entry, ',');
0445 float xfRatioErr = std::stof(entry);
0446 bkg_ratio_err_xf[1][iXf] = xfRatioErr;
0447 }
0448 }
0449
0450 ShuffleBunches::~ShuffleBunches()
0451 {
0452 clear_fill_yields();
0453 clear_fill_raw_asyms();
0454 clear_average_raw_asyms();
0455 clear_corr_asyms();
0456 clear_fit_asyms();
0457 }
0458
0459 void ShuffleBunches::clear_fill_yields()
0460 {
0461 vec_yield_pt.clear();
0462 vec_yield_eta.clear();
0463 vec_yield_xf.clear();
0464 }
0465
0466 void ShuffleBunches::clear_fill_raw_asyms()
0467 {
0468 fill_pt_asyms.clear();
0469 fill_eta_asyms.clear();
0470 fill_xf_asyms.clear();
0471 fill_pt_asym_errs.clear();
0472 fill_eta_asym_errs.clear();
0473 fill_xf_asym_errs.clear();
0474 }
0475
0476 void ShuffleBunches::clear_average_raw_asyms()
0477 {
0478 mean_pt.clear();
0479 mean_eta.clear();
0480 mean_xf.clear();
0481 unc_pt.clear();
0482 unc_eta.clear();
0483 unc_xf.clear();
0484 }
0485
0486 void ShuffleBunches::clear_corr_asyms()
0487 {
0488 corrected_mean_pt.clear();
0489 corrected_mean_eta.clear();
0490 corrected_mean_xf.clear();
0491 corrected_unc_pt.clear();
0492 corrected_unc_eta.clear();
0493 corrected_unc_xf.clear();
0494 }
0495
0496 void ShuffleBunches::clear_fit_asyms()
0497 {
0498 fit_mean_pt.clear();
0499 fit_mean_eta.clear();
0500 fit_mean_xf.clear();
0501 fit_unc_pt.clear();
0502 fit_unc_eta.clear();
0503 fit_unc_xf.clear();
0504 }
0505
0506 void ShuffleBunches::reserve_fill_yields()
0507 {
0508 vec_yield_pt.reserve(nIterations);
0509 vec_yield_eta.reserve(nIterations);
0510 vec_yield_xf.reserve(nIterations);
0511 }
0512
0513
0514 void ShuffleBunches::reserve_fill_raw_asyms()
0515 {
0516 fill_pt_asyms.reserve(nFills * nIterations);
0517 fill_eta_asyms.reserve(nFills * nIterations);
0518 fill_xf_asyms.reserve(nFills * nIterations);
0519 fill_pt_asym_errs.reserve(nFills * nIterations);
0520 fill_eta_asym_errs.reserve(nFills * nIterations);
0521 fill_xf_asym_errs.reserve(nFills * nIterations);
0522 }
0523
0524 void ShuffleBunches::reserve_average_raw_asyms()
0525 {
0526 mean_pt.reserve(nIterations);
0527 mean_eta.reserve(nIterations);
0528 mean_xf.reserve(nIterations);
0529 unc_pt.reserve(nIterations);
0530 unc_eta.reserve(nIterations);
0531 unc_xf.reserve(nIterations);
0532 }
0533
0534 void ShuffleBunches::reserve_corr_asyms()
0535 {
0536 corrected_mean_pt.reserve(nIterations);
0537 corrected_mean_eta.reserve(nIterations);
0538 corrected_mean_xf.reserve(nIterations);
0539 corrected_unc_pt.reserve(nIterations);
0540 corrected_unc_eta.reserve(nIterations);
0541 corrected_unc_xf.reserve(nIterations);
0542 }
0543
0544 void ShuffleBunches::reserve_fit_asyms()
0545 {
0546 fit_mean_pt.reserve(nIterations);
0547 fit_mean_eta.reserve(nIterations);
0548 fit_mean_xf.reserve(nIterations);
0549 fit_unc_pt.reserve(nIterations);
0550 fit_unc_eta.reserve(nIterations);
0551 fit_unc_xf.reserve(nIterations);
0552 }
0553
0554 void ShuffleBunches::reset()
0555 {
0556 clear_fill_yields();
0557 clear_fill_raw_asyms();
0558 clear_average_raw_asyms();
0559 clear_corr_asyms();
0560 clear_fit_asyms();
0561 }
0562
0563 void ShuffleBunches::run_1()
0564 {
0565 reserve_fill_yields();
0566 reserve_fill_raw_asyms();
0567 global_irun = 0;
0568 std::cout << "Compute " << nFills << " fills" << std::endl;
0569 for (int iFill = 0; iFill < nFills; iFill++)
0570 {
0571 compute_fill(iFill);
0572 }
0573 }
0574
0575 void ShuffleBunches::run_2()
0576 {
0577 reserve_average_raw_asyms();
0578 for (int iIter = 0; iIter < nIterations; iIter++) {
0579 std::cout << "average iter " << (iterMin + iIter) << std::endl;
0580 if (store_iter_histos) {
0581 std::stringstream outputfilename;
0582 outputfilename << outfilename_iter_template << "raw_" << (iterMin + iIter) << ".root";
0583 book_outfile_iter_histograms(outputfilename.str().c_str());
0584 }
0585 average_asyms(iIter);
0586 if (store_iter_histos) {
0587 get_iter_raw_asym_histograms();
0588 save_outfile_iter_histograms();
0589 }
0590 }
0591 clear_fill_raw_asyms();
0592 reserve_fit_asyms();
0593 for (int iIter = 0; iIter < nIterations; iIter++) {
0594 std::cout << "fit iter " << (iterMin + iIter) << std::endl;
0595 if (store_iter_histos) {
0596 std::stringstream outputfilename;
0597 outputfilename << outfilename_iter_template << "fit_" << (iterMin + iIter) << ".root";
0598 book_outfile_iter_histograms(outputfilename.str().c_str());
0599 }
0600 fit_raw_asyms(iIter);
0601 if (store_iter_histos) {
0602 get_iter_fit_asym_histograms();
0603 save_outfile_iter_histograms();
0604 }
0605 }
0606 clear_average_raw_asyms();
0607 reserve_corr_asyms();
0608 for (int iIter = 0; iIter < nIterations; iIter++) {
0609 std::cout << "corr iter " << (iterMin + iIter) << std::endl;
0610 if (store_iter_histos) {
0611 std::stringstream outputfilename;
0612 outputfilename << outfilename_iter_template << "corr_" << (iterMin + iIter) << ".root";
0613 book_outfile_iter_histograms(outputfilename.str().c_str());
0614 }
0615 compute_corrected_asyms(iIter);
0616 if (store_iter_histos) {
0617 get_iter_corr_asym_histograms();
0618 save_outfile_iter_histograms();
0619 }
0620 }
0621 }
0622
0623 void ShuffleBunches::set_store_fill_histos(bool val, const std::string& outputfilename_template)
0624 {
0625 if (val && nIterations > 1)
0626 {
0627 std::cerr << "Error. Can't store histograms for more than one shuffle iteration" << std::endl;
0628 store_fill_histos = false;
0629 }
0630 else if (val)
0631 {
0632 store_fill_histos = true;
0633 outfilename_fill_template = outputfilename_template;
0634 }
0635 else
0636 {
0637 store_fill_histos = false;
0638 }
0639 }
0640
0641 void ShuffleBunches::set_store_iter_histos(bool val, const std::string& outputfilename_template)
0642 {
0643 if (val && nIterations > 1)
0644 {
0645 std::cerr << "Error. Can't store histograms for more than one shuffle iteration" << std::endl;
0646 store_iter_histos = false;
0647 }
0648 else if (val)
0649 {
0650 store_iter_histos = true;
0651 outfilename_iter_template = outputfilename_template;
0652 }
0653 else
0654 {
0655 store_iter_histos = false;
0656 }
0657 }
0658
0659 void ShuffleBunches::book_outfile_fill_histograms(const std::string& outputfilename)
0660 {
0661
0662 outfile_fill_histograms = new TFile(outputfilename.c_str(), "RECREATE");
0663 }
0664
0665 void ShuffleBunches::book_outfile_iter_histograms(const std::string& outputfilename)
0666 {
0667
0668 outfile_iter_histograms = new TFile(outputfilename.c_str(), "RECREATE");
0669 }
0670
0671 void ShuffleBunches::save_outfile_fill_histograms()
0672 {
0673 outfile_fill_histograms->cd();
0674 outfile_fill_histograms->Write();
0675 outfile_fill_histograms->Close();
0676 delete outfile_fill_histograms;
0677 outfile_fill_histograms = nullptr;
0678 }
0679
0680 void ShuffleBunches::save_outfile_iter_histograms()
0681 {
0682 outfile_iter_histograms->cd();
0683 outfile_iter_histograms->Write();
0684 outfile_iter_histograms->Close();
0685 delete outfile_iter_histograms;
0686 outfile_iter_histograms = nullptr;
0687 }
0688
0689 void ShuffleBunches::get_yield_histograms()
0690 {
0691 pt_yield_array &arr_pt_yield = vec_yield_pt.back();
0692 eta_yield_array &arr_eta_yield = vec_yield_eta.back();
0693 xf_yield_array &arr_xf_yield = vec_yield_xf.back();
0694
0695 outfile_fill_histograms->cd();
0696 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++)
0697 {
0698 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++)
0699 {
0700 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++)
0701 {
0702 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++)
0703 {
0704 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++)
0705 {
0706 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++)
0707 {
0708
0709 std::stringstream h_yield_name;
0710 h_yield_name << "h_yield_" << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP]
0711 << "_" << ASYM_CONSTANTS::regions[iR] << "_"
0712 << "pT_" << iPt << "_"
0713 << ASYM_CONSTANTS::directions[iDir]
0714 << "_" << ASYM_CONSTANTS::spins[iS];
0715 std::stringstream h_yield_title;
0716 h_yield_title << "#phi_{" << (iB == 0 ? "yellow" : "blue")
0717 << "};counts";
0718 h_yield_pt[iB][iP][iR][iPt][iDir][iS] =
0719 new TH1F(h_yield_name.str().c_str(),
0720 h_yield_title.str().c_str(), 12, -M_PI, M_PI);
0721
0722
0723 for (int iphi = 0; iphi < ASYM_CONSTANTS::nPhiBins; iphi++)
0724 {
0725 h_yield_pt[iB][iP][iR][iPt][iDir][iS]->SetBinContent(
0726 iphi + 1,
0727 arr_pt_yield(iB, iP, iR, iPt, iDir, iS, iphi));
0728 }
0729 }
0730 }
0731 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++)
0732 {
0733
0734 std::stringstream h_yield_name;
0735 h_yield_name << "h_yield_" << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP]
0736 << "_" << ASYM_CONSTANTS::regions[iR] << "_"
0737 << "eta_" << (int) iEta << "_" << ASYM_CONSTANTS::spins[iS];
0738 std::stringstream h_yield_title;
0739 h_yield_title << "#phi_{" << (iB == 0 ? "yellow" : "blue")
0740 << "};counts";
0741 h_yield_eta[iB][iP][iR][iEta][iS] =
0742 new TH1F(h_yield_name.str().c_str(),
0743 h_yield_title.str().c_str(), 12, -M_PI, M_PI);
0744
0745
0746 for (int iphi = 0; iphi < ASYM_CONSTANTS::nPhiBins; iphi++)
0747 {
0748 h_yield_eta[iB][iP][iR][iEta][iS]->SetBinContent(
0749 iphi + 1,
0750 arr_eta_yield(iB, iP, iR, iEta, iS, iphi));
0751 }
0752 }
0753 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++)
0754 {
0755
0756 std::stringstream h_yield_name;
0757 h_yield_name << "h_yield_" << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP]
0758 << "_" << ASYM_CONSTANTS::regions[iR] << "_"
0759 << "xf_" << (int) iXf << "_" << ASYM_CONSTANTS::spins[iS];
0760 std::stringstream h_yield_title;
0761 h_yield_title << "#phi_{" << (iB == 0 ? "yellow" : "blue")
0762 << "};counts";
0763 h_yield_xf[iB][iP][iR][iXf][iS] =
0764 new TH1F(h_yield_name.str().c_str(),
0765 h_yield_title.str().c_str(), 12, -M_PI, M_PI);
0766
0767
0768 for (int iphi = 0; iphi < ASYM_CONSTANTS::nPhiBins; iphi++)
0769 {
0770 h_yield_xf[iB][iP][iR][iXf][iS]->SetBinContent(
0771 iphi + 1,
0772 arr_xf_yield(iB, iP, iR, iXf, iS, iphi));
0773 }
0774 }
0775 }
0776 }
0777 }
0778 }
0779 }
0780
0781 void ShuffleBunches::get_fill_raw_asym_histograms()
0782 {
0783 pt_asym_array& arr_pt_asym = fill_pt_asyms.back();
0784 eta_asym_array& arr_eta_asym = fill_eta_asyms.back();
0785 xf_asym_array& arr_xf_asym = fill_xf_asyms.back();
0786 pt_asym_array& arr_pt_asym_err = fill_pt_asym_errs.back();
0787 eta_asym_array& arr_eta_asym_err = fill_eta_asym_errs.back();
0788 xf_asym_array& arr_xf_asym_err = fill_xf_asym_errs.back();
0789
0790 outfile_fill_histograms->cd();
0791 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++)
0792 {
0793 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++)
0794 {
0795 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++)
0796 {
0797 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++)
0798 {
0799 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++)
0800 {
0801 TGraphErrors *graph_AN = new TGraphErrors();
0802 std::stringstream graph_AN_name;
0803 graph_AN_name << "graph_asym_pt_"
0804 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
0805 << ASYM_CONSTANTS::regions[iR] << "_"
0806 << "pT_" << iPt << "_"
0807 << ASYM_CONSTANTS::directions[iDir] << "_"
0808 << "sqrt";
0809 graph_AN->SetName(graph_AN_name.str().c_str());
0810 std::stringstream graph_title;
0811 graph_title << "; #phi; " << (iR == 0 ? "Raw" : "Bkg") << " Asymmetry";
0812 graph_AN->SetTitle(graph_title.str().c_str());
0813 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++)
0814 {
0815 float phi = -M_PI + M_PI / 12 + iPhi * M_PI / 6.;
0816 graph_AN->SetPoint(iPhi, phi, arr_pt_asym(iB, iP, iR, iPt, iDir, iPhi));
0817 graph_AN->SetPointError(iPhi, 0, arr_pt_asym_err(iB, iP, iR, iPt, iDir, iPhi));
0818 }
0819 graph_AN->Write();
0820 }
0821 }
0822 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++)
0823 {
0824 TGraphErrors *graph_AN = new TGraphErrors();
0825 std::stringstream graph_AN_name;
0826 graph_AN_name << "graph_asym_eta_"
0827 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
0828 << ASYM_CONSTANTS::regions[iR] << "_"
0829 << "eta_" << iEta << "_sqrt";
0830 graph_AN->SetName(graph_AN_name.str().c_str());
0831 std::stringstream graph_title;
0832 graph_title << "; #phi; " << (iR == 0 ? "Raw" : "Bkg") << " Asymmetry";
0833 graph_AN->SetTitle(graph_title.str().c_str());
0834 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++)
0835 {
0836 float phi = -M_PI + M_PI / 12 + iPhi * M_PI / 6.;
0837 graph_AN->SetPoint(iPhi, phi, arr_eta_asym(iB, iP, iR, iEta, iPhi));
0838 graph_AN->SetPointError(iPhi, 0, arr_eta_asym_err(iB, iP, iR, iEta, iPhi));
0839 }
0840 graph_AN->Write();
0841 }
0842 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++)
0843 {
0844 TGraphErrors *graph_AN = new TGraphErrors();
0845 std::stringstream graph_AN_name;
0846 graph_AN_name << "graph_asym_xf_"
0847 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
0848 << ASYM_CONSTANTS::regions[iR] << "_"
0849 << "xf_" << iXf << "_sqrt";
0850 graph_AN->SetName(graph_AN_name.str().c_str());
0851 std::stringstream graph_title;
0852 graph_title << "; #phi; " << (iR == 0 ? "Raw" : "Bkg") << " Asymmetry";
0853 graph_AN->SetTitle(graph_title.str().c_str());
0854
0855
0856 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++)
0857 {
0858 float phi = -M_PI + M_PI / 12 + iPhi * M_PI / 6.;
0859 graph_AN->SetPoint(iPhi, phi, arr_xf_asym(iB, iP, iR, iXf, iPhi));
0860 graph_AN->SetPointError(iPhi, 0, arr_xf_asym_err(iB, iP, iR, iXf, iPhi));
0861 }
0862 graph_AN->Write();
0863 }
0864 }
0865 }
0866 }
0867 }
0868
0869 void ShuffleBunches::compute_fill(const int ifill)
0870 {
0871
0872
0873 const int fill_number = fill_to_runs[ifill].first;
0874 const std::vector<int>& runs = fill_to_runs[ifill].second;
0875 const int nRuns = runs.size();
0876
0877
0878 spin_patterns->GetEntry((unsigned long)ifill);
0879 if (fill_number != fill_spin) {
0880 std::cerr << "Mismatch in fill number: " << fill_number << " != " << fill_spin << std::endl;
0881 return;
0882 }
0883 for (int i = 0; i < ASYM_CONSTANTS::nBunches; i++) {
0884 spin_pattern[0][i] = yellow_spin_pattern[i];
0885 spin_pattern[1][i] = blue_spin_pattern[i];
0886 }
0887 polarization[0] = yellow_polarization;
0888 polarization[1] = blue_polarization;
0889
0890 if (store_fill_histos)
0891 {
0892 std::stringstream outputfilename;
0893 outputfilename << outfilename_fill_template << fill_number << ".root";
0894 book_outfile_fill_histograms(outputfilename.str());
0895 }
0896
0897 for (int iRun = 0; iRun < nRuns; iRun++)
0898 {
0899 std::string infilename = infile_template + std::to_string(runs[iRun]) + ".bin";
0900 read_binary_array(infilename);
0901 for (int iIter = 0; iIter < nIterations; iIter++)
0902 {
0903 int iter = iterMin + iIter;
0904
0905 int seednumber = (do_shuffle ? (iter + 100000 * (global_irun + iRun)) : 0);
0906 shuffle_bunch_indices(seednumber);
0907
0908
0909 sum_yields(iIter);
0910 }
0911 }
0912
0913
0914
0915 if (store_fill_histos) {
0916 get_yield_histograms();
0917 }
0918
0919 for (int iIter = 0; iIter < nIterations; iIter++)
0920 {
0921
0922 compute_raw_asyms(iIter);
0923 }
0924 clear_fill_yields();
0925
0926
0927
0928 global_irun += nRuns;
0929
0930 if (store_fill_histos)
0931 {
0932 get_fill_raw_asym_histograms();
0933 save_outfile_fill_histograms();
0934 }
0935 }
0936
0937 void ShuffleBunches::read_binary_array(const std::string& inputfilename)
0938 {
0939 std::ifstream inbinary(inputfilename, std::ios::binary);
0940
0941 inbinary.read(reinterpret_cast<char*>(array_yield_pt_bunches), sizeof(array_yield_pt_bunches));
0942 inbinary.read(reinterpret_cast<char*>(array_yield_eta_bunches), sizeof(array_yield_eta_bunches));
0943 inbinary.read(reinterpret_cast<char*>(array_yield_xf_bunches), sizeof(array_yield_xf_bunches));
0944 }
0945
0946 void ShuffleBunches::shuffle_bunch_indices(const int seednumber)
0947 {
0948
0949
0950
0951
0952
0953 std::iota(shuffled_indices, shuffled_indices + ASYM_CONSTANTS::nBunches, 0);
0954 if (seednumber != 0)
0955 {
0956
0957
0958 std::mt19937 rng(seednumber);
0959 std::shuffle(shuffled_indices, shuffled_indices + ASYM_CONSTANTS::nBunches, rng);
0960
0961
0962 std::uniform_int_distribution<std::mt19937::result_type> dist2(0, 1);
0963 int factor = 2 * (int) dist2(rng) - 1;
0964 spin_flip = (factor == -1 ? true : false);
0965 }
0966
0967
0968
0969
0970
0971 }
0972
0973 void ShuffleBunches::sum_yields(const int iIter)
0974 {
0975 pt_yield_array arr_yield_pt;
0976 eta_yield_array arr_yield_eta;
0977 xf_yield_array arr_yield_xf;
0978
0979
0980 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
0981 for (int iBunch = 0; iBunch < ASYM_CONSTANTS::nBunches; iBunch++) {
0982 shuffled_spin_pattern[iB][iBunch] = spin_pattern[iB][shuffled_indices[iBunch]];
0983 }
0984 }
0985
0986 auto spin_to_index = [](int8_t s) -> int {
0987 if (s == 1) return 0;
0988 if (s == -1) return 1;
0989 std::cerr << "Error for spin value (expected +1 or -1)" << std::endl;
0990 exit(1);
0991 };
0992
0993 for (int iBunch = 0; iBunch < ASYM_CONSTANTS::nBunches; ++iBunch) {
0994 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; ++iB) {
0995 const int8_t true_spin = spin_pattern[iB][iBunch];
0996
0997 int8_t shuffled_spin = shuffled_spin_pattern[iB][iBunch];
0998 if (spin_flip) shuffled_spin = -shuffled_spin;
0999
1000 const int iS_true = spin_to_index(true_spin);
1001 const int iS_shuffle = spin_to_index(shuffled_spin);
1002
1003 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; ++iP) {
1004 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; ++iR) {
1005 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; ++iPhi) {
1006 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; ++iPt) {
1007 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; ++iDir) {
1008 arr_yield_pt(iB, iP, iR, iPt, iDir, iS_shuffle, iPhi) +=
1009 array_yield_pt_bunches[iB][iP][iR][iPt][iDir][iS_true][iPhi][iBunch];
1010 }
1011 }
1012
1013 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; ++iEta) {
1014 arr_yield_eta(iB, iP, iR, iEta, iS_shuffle, iPhi) +=
1015 array_yield_eta_bunches[iB][iP][iR][iEta][iS_true][iPhi][iBunch];
1016 }
1017
1018 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; ++iXf) {
1019 arr_yield_xf(iB, iP, iR, iXf, iS_shuffle, iPhi) +=
1020 array_yield_xf_bunches[iB][iP][iR][iXf][iS_true][iPhi][iBunch];
1021 }
1022 }
1023 }
1024 }
1025 }
1026 }
1027
1028 if (vec_yield_pt.size() <= iIter) {
1029 vec_yield_pt.resize(iIter+1);
1030 vec_yield_eta.resize(iIter+1);
1031 vec_yield_xf.resize(iIter+1);
1032 }
1033 vec_yield_pt[iIter] += arr_yield_pt;
1034 vec_yield_eta[iIter] += arr_yield_eta;
1035 vec_yield_xf[iIter] += arr_yield_xf;
1036 }
1037
1038 void ShuffleBunches::compute_raw_asyms(const int iIter)
1039 {
1040 pt_yield_array &arr_pt_yield = vec_yield_pt[iIter];
1041 eta_yield_array &arr_eta_yield = vec_yield_eta[iIter];
1042 xf_yield_array &arr_xf_yield = vec_yield_xf[iIter];
1043
1044 pt_asym_array arr_pt_asym;
1045 pt_nodir_asym_array arr_pt_nodir_asym;
1046 eta_asym_array arr_eta_asym;
1047 xf_asym_array arr_xf_asym;
1048 pt_asym_array arr_pt_asym_err;
1049 pt_nodir_asym_array arr_pt_nodir_asym_err;
1050 eta_asym_array arr_eta_asym_err;
1051 xf_asym_array arr_xf_asym_err;
1052 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1053 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1054 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++) {
1055 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1056 {
1057 double array_asym[ASYM_CONSTANTS::nPhiBins];
1058 double array_asym_err[ASYM_CONSTANTS::nPhiBins];
1059 uint32_t array_yield[ASYM_CONSTANTS::nSpins][ASYM_CONSTANTS::nPhiBins];
1060 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++) {
1061 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1062 array_yield[iS][iPhi] =
1063 arr_pt_yield(iB, iP, iR, iPt, 0, iS, iPhi) +
1064 arr_pt_yield(iB, iP, iR, iPt, 1, iS, iPhi);
1065 }
1066 }
1067 compute_sqrt_asym(array_yield, polarization[iB], array_asym, array_asym_err);
1068 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1069 arr_pt_nodir_asym(iB, iP, iR, iPt, iPhi) = array_asym[iPhi];
1070 arr_pt_nodir_asym_err(iB, iP, iR, iPt, iPhi) = array_asym_err[iPhi];
1071 }
1072 }
1073 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1074 double array_asym[ASYM_CONSTANTS::nPhiBins];
1075 double array_asym_err[ASYM_CONSTANTS::nPhiBins];
1076 uint32_t array_yield[ASYM_CONSTANTS::nSpins][ASYM_CONSTANTS::nPhiBins];
1077 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++) {
1078 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1079 array_yield[iS][iPhi] = arr_pt_yield(iB, iP, iR, iPt, iDir, iS, iPhi);
1080 }
1081 }
1082 compute_sqrt_asym(array_yield, polarization[iB], array_asym, array_asym_err);
1083 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1084 arr_pt_asym(iB, iP, iR, iPt, iDir, iPhi) = array_asym[iPhi];
1085 arr_pt_asym_err(iB, iP, iR, iPt, iDir, iPhi) = array_asym_err[iPhi];
1086
1087 }
1088 }
1089 }
1090 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
1091 double array_asym[ASYM_CONSTANTS::nPhiBins];
1092 double array_asym_err[ASYM_CONSTANTS::nPhiBins];
1093 uint32_t array_yield[ASYM_CONSTANTS::nSpins][ASYM_CONSTANTS::nPhiBins];
1094 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++) {
1095 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1096 array_yield[iS][iPhi] = arr_eta_yield(iB, iP, iR, iEta, iS, iPhi);
1097 }
1098 }
1099 compute_sqrt_asym(array_yield, polarization[iB], array_asym, array_asym_err);
1100 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1101 arr_eta_asym(iB, iP, iR, iEta, iPhi) = array_asym[iPhi];
1102 arr_eta_asym_err(iB, iP, iR, iEta, iPhi) = array_asym_err[iPhi];
1103 }
1104 }
1105 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
1106 double array_asym[ASYM_CONSTANTS::nPhiBins];
1107 double array_asym_err[ASYM_CONSTANTS::nPhiBins];
1108 uint32_t array_yield[ASYM_CONSTANTS::nSpins][ASYM_CONSTANTS::nPhiBins];
1109 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++) {
1110 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1111 array_yield[iS][iPhi] = arr_xf_yield(iB, iP, iR, iXf, iS, iPhi);
1112 }
1113 }
1114 compute_sqrt_asym(array_yield, polarization[iB], array_asym, array_asym_err);
1115 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1116 arr_xf_asym(iB, iP, iR, iXf, iPhi) = array_asym[iPhi];
1117 arr_xf_asym_err(iB, iP, iR, iXf, iPhi) = array_asym_err[iPhi];
1118 }
1119 }
1120 }
1121 }
1122 }
1123 fill_pt_asyms.push_back(arr_pt_asym);
1124 fill_pt_nodir_asyms.push_back(arr_pt_nodir_asym);
1125 fill_eta_asyms.push_back(arr_eta_asym);
1126 fill_xf_asyms.push_back(arr_xf_asym);
1127 fill_pt_asym_errs.push_back(arr_pt_asym_err);
1128 fill_pt_nodir_asym_errs.push_back(arr_pt_nodir_asym_err);
1129 fill_eta_asym_errs.push_back(arr_eta_asym_err);
1130 fill_xf_asym_errs.push_back(arr_xf_asym_err);
1131 }
1132
1133 void ShuffleBunches::average_asyms(const int iIter)
1134 {
1135 double sum_weights_pt[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nPtBins][ASYM_CONSTANTS::nDirections][ASYM_CONSTANTS::nPhiBins] = {0};
1136 double sum_weights_pt_nodir[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nPtBins][ASYM_CONSTANTS::nPhiBins] = {0};
1137 double sum_weights_eta[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nEtaBins][ASYM_CONSTANTS::nPhiBins] = {0};
1138 double sum_weights_xf[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nXfBins][ASYM_CONSTANTS::nPhiBins] = {0};
1139
1140 double sum_weighted_asym_pt[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nPtBins][ASYM_CONSTANTS::nDirections][ASYM_CONSTANTS::nPhiBins] = {0};
1141 double sum_weighted_asym_pt_nodir[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nPtBins][ASYM_CONSTANTS::nPhiBins] = {0};
1142 double sum_weighted_asym_eta[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nEtaBins][ASYM_CONSTANTS::nPhiBins] = {0};
1143 double sum_weighted_asym_xf[ASYM_CONSTANTS::nBeams][ASYM_CONSTANTS::nParticles][ASYM_CONSTANTS::nRegions][ASYM_CONSTANTS::nXfBins][ASYM_CONSTANTS::nPhiBins] = {0};
1144
1145 for (size_t iFill = 0; iFill < nFills; iFill++) {
1146 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1147 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1148 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++) {
1149 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1150 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1151 {
1152 const double& asym = fill_pt_nodir_asyms[nIterations * iFill + iIter](iB, iP, iR, iPt, iPhi);
1153 const double& asym_err = fill_pt_nodir_asym_errs[nIterations * iFill + iIter](iB, iP, iR, iPt, iPhi);
1154 if (asym == asym && asym_err == asym_err && asym_err > 0)
1155 {
1156 sum_weights_pt_nodir[iB][iP][iR][iPt][iPhi] += std::pow(asym_err, -2);
1157 sum_weighted_asym_pt_nodir[iB][iP][iR][iPt][iPhi] += asym * std::pow(asym_err, -2);
1158 }
1159 }
1160 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1161 const double& asym = fill_pt_asyms[nIterations * iFill + iIter](iB, iP, iR, iPt, iDir, iPhi);
1162 const double& asym_err = fill_pt_asym_errs[nIterations * iFill + iIter](iB, iP, iR, iPt, iDir, iPhi);
1163 if (asym == asym && asym_err == asym_err && asym_err > 0)
1164 {
1165 sum_weights_pt[iB][iP][iR][iPt][iDir][iPhi] += std::pow(asym_err, -2);
1166 sum_weighted_asym_pt[iB][iP][iR][iPt][iDir][iPhi] += asym * std::pow(asym_err, -2);
1167 }
1168 }
1169 }
1170 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
1171 const double& asym = fill_eta_asyms[nIterations * iFill + iIter](iB, iP, iR, iEta, iPhi);
1172 const double& asym_err = fill_eta_asym_errs[nIterations * iFill + iIter](iB, iP, iR, iEta, iPhi);
1173 if (asym == asym && asym_err == asym_err && asym_err > 0)
1174 {
1175 sum_weights_eta[iB][iP][iR][iEta][iPhi] += std::pow(asym_err, -2);
1176 sum_weighted_asym_eta[iB][iP][iR][iEta][iPhi] += asym * std::pow(asym_err, -2);
1177 }
1178 }
1179 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
1180 const double& asym = fill_xf_asyms[nIterations * iFill + iIter](iB, iP, iR, iXf, iPhi);
1181 const double& asym_err = fill_xf_asym_errs[nIterations * iFill + iIter](iB, iP, iR, iXf, iPhi);
1182 if (asym == asym && asym_err == asym_err && asym_err > 0)
1183 {
1184
1185 sum_weights_xf[iB][iP][iR][iXf][iPhi] += std::pow(asym_err, -2);
1186 sum_weighted_asym_xf[iB][iP][iR][iXf][iPhi] += asym * std::pow(asym_err, -2);
1187
1188
1189
1190
1191
1192
1193
1194
1195 }
1196 }
1197 }
1198 }
1199 }
1200 }
1201 }
1202
1203 pt_asym_array average_mean_pt;
1204 pt_nodir_asym_array average_mean_pt_nodir;
1205 eta_asym_array average_mean_eta;
1206 xf_asym_array average_mean_xf;
1207
1208 pt_asym_array average_unc_pt;
1209 pt_nodir_asym_array average_unc_pt_nodir;
1210 eta_asym_array average_unc_eta;
1211 xf_asym_array average_unc_xf;
1212
1213 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1214 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1215 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++) {
1216 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1217 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1218 {
1219 if (sum_weights_pt_nodir[iB][iP][iR][iPt][iPhi] > 0) {
1220 average_mean_pt_nodir(iB, iP, iR, iPt, iPhi) =
1221 sum_weighted_asym_pt_nodir[iB][iP][iR][iPt][iPhi] /
1222 sum_weights_pt_nodir[iB][iP][iR][iPt][iPhi];
1223 average_unc_pt_nodir(iB, iP, iR, iPt, iPhi) = 1. /
1224 std::sqrt(sum_weights_pt_nodir[iB][iP][iR][iPt][iPhi]);
1225 }
1226 else {
1227 average_mean_pt_nodir(iB, iP, iR, iPt, iPhi) = 0;
1228 average_unc_pt_nodir(iB, iP, iR, iPt, iPhi) = 0;
1229 }
1230 }
1231 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1232 if (sum_weights_pt[iB][iP][iR][iPt][iDir][iPhi] > 0) {
1233 average_mean_pt(iB, iP, iR, iPt, iDir, iPhi) =
1234 sum_weighted_asym_pt[iB][iP][iR][iPt][iDir][iPhi] /
1235 sum_weights_pt[iB][iP][iR][iPt][iDir][iPhi];
1236 average_unc_pt(iB, iP, iR, iPt, iDir, iPhi) = 1. /
1237 std::sqrt(sum_weights_pt[iB][iP][iR][iPt][iDir][iPhi]);
1238 }
1239 else {
1240 average_mean_pt(iB, iP, iR, iPt, iDir, iPhi) = 0;
1241 average_unc_pt(iB, iP, iR, iPt, iDir, iPhi) = 0;
1242 }
1243 }
1244 }
1245 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
1246 if (sum_weights_eta[iB][iP][iR][iEta][iPhi] > 0) {
1247 average_mean_eta(iB, iP, iR, iEta, iPhi) =
1248 sum_weighted_asym_eta[iB][iP][iR][iEta][iPhi] /
1249 sum_weights_eta[iB][iP][iR][iEta][iPhi];
1250 average_unc_eta(iB, iP, iR, iEta, iPhi) = 1. /
1251 std::sqrt(sum_weights_eta[iB][iP][iR][iEta][iPhi]);
1252 } else {
1253 average_mean_eta(iB, iP, iR, iEta, iPhi) = 0;
1254 average_unc_eta(iB, iP, iR, iEta, iPhi) = 0;
1255 }
1256 }
1257 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
1258 if (sum_weights_xf[iB][iP][iR][iXf][iPhi] > 0) {
1259 average_mean_xf(iB, iP, iR, iXf, iPhi) =
1260 sum_weighted_asym_xf[iB][iP][iR][iXf][iPhi] /
1261 sum_weights_xf[iB][iP][iR][iXf][iPhi];
1262 average_unc_xf(iB, iP, iR, iXf, iPhi) = 1. /
1263 std::sqrt(sum_weights_xf[iB][iP][iR][iXf][iPhi]);
1264 } else {
1265 average_mean_xf(iB, iP, iR, iXf, iPhi) = 0;
1266 average_unc_xf(iB, iP, iR, iXf, iPhi) = 0;
1267 }
1268 }
1269 }
1270 }
1271 }
1272 }
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283 mean_pt.push_back(average_mean_pt);
1284 mean_pt_nodir.push_back(average_mean_pt_nodir);
1285 mean_eta.push_back(average_mean_eta);
1286 mean_xf.push_back(average_mean_xf);
1287 unc_pt.push_back(average_unc_pt);
1288 unc_pt_nodir.push_back(average_unc_pt_nodir);
1289 unc_eta.push_back(average_unc_eta);
1290 unc_xf.push_back(average_unc_xf);
1291 }
1292
1293 void ShuffleBunches::fit_raw_asyms(const int iIter)
1294 {
1295 const pt_asym_array& average_mean_pt = mean_pt[iIter];
1296 const pt_nodir_asym_array& average_mean_pt_nodir = mean_pt_nodir[iIter];
1297 const eta_asym_array& average_mean_eta = mean_eta[iIter];
1298 const xf_asym_array& average_mean_xf = mean_xf[iIter];
1299 const pt_asym_array& average_unc_pt = unc_pt[iIter];
1300 const pt_nodir_asym_array& average_unc_pt_nodir = unc_pt_nodir[iIter];
1301 const eta_asym_array& average_unc_eta = unc_eta[iIter];
1302 const xf_asym_array& average_unc_xf = unc_xf[iIter];
1303
1304 pt_fit_array fit_average_mean_pt;
1305 pt_nodir_fit_array fit_average_mean_pt_nodir;
1306 eta_fit_array fit_average_mean_eta;
1307 xf_fit_array fit_average_mean_xf;
1308 pt_fit_array fit_average_unc_pt;
1309 pt_nodir_fit_array fit_average_unc_pt_nodir;
1310 eta_fit_array fit_average_unc_eta;
1311 xf_fit_array fit_average_unc_xf;
1312
1313 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1314 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1315 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++) {
1316 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1317 {
1318 double asym_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1319 double asym_err_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1320 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1321 asym_azimuth[iPhi] = average_mean_pt_nodir(iB, iP, iR, iPt, iPhi);
1322 asym_err_azimuth[iPhi] = average_unc_pt_nodir(iB, iP, iR, iPt, iPhi);
1323 }
1324 fit_asym(fit_average_mean_pt_nodir(iB, iP, iR, iPt),
1325 fit_average_unc_pt_nodir(iB, iP, iR, iPt),
1326 asym_azimuth,
1327 asym_err_azimuth);
1328 }
1329 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1330 double asym_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1331 double asym_err_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1332 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1333 asym_azimuth[iPhi] = average_mean_pt(iB, iP, iR, iPt, iDir, iPhi);
1334 asym_err_azimuth[iPhi] = average_unc_pt(iB, iP, iR, iPt, iDir, iPhi);
1335 }
1336 fit_asym(fit_average_mean_pt(iB, iP, iR, iPt, iDir),
1337 fit_average_unc_pt(iB, iP, iR, iPt, iDir),
1338 asym_azimuth,
1339 asym_err_azimuth);
1340 }
1341 }
1342 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
1343 double asym_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1344 double asym_err_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1345 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1346 asym_azimuth[iPhi] = average_mean_eta(iB, iP, iR, iEta, iPhi);
1347 asym_err_azimuth[iPhi] = average_unc_eta(iB, iP, iR, iEta, iPhi);
1348 }
1349 fit_asym(fit_average_mean_eta(iB, iP, iR, iEta),
1350 fit_average_unc_eta(iB, iP, iR, iEta),
1351 asym_azimuth,
1352 asym_err_azimuth);
1353 }
1354 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
1355 double asym_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1356 double asym_err_azimuth[ASYM_CONSTANTS::nPhiBins] = {0};
1357 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1358 asym_azimuth[iPhi] = average_mean_xf(iB, iP, iR, iXf, iPhi);
1359 asym_err_azimuth[iPhi] = average_unc_xf(iB, iP, iR, iXf, iPhi);
1360 }
1361 fit_asym(fit_average_mean_xf(iB, iP, iR, iXf),
1362 fit_average_unc_xf(iB, iP, iR, iXf),
1363 asym_azimuth,
1364 asym_err_azimuth);
1365 }
1366 }
1367 }
1368 }
1369 fit_mean_pt.push_back(fit_average_mean_pt);
1370 fit_mean_pt_nodir.push_back(fit_average_mean_pt_nodir);
1371 fit_mean_eta.push_back(fit_average_mean_eta);
1372 fit_mean_xf.push_back(fit_average_mean_xf);
1373 fit_unc_pt.push_back(fit_average_unc_pt);
1374 fit_unc_pt_nodir.push_back(fit_average_unc_pt_nodir);
1375 fit_unc_eta.push_back(fit_average_unc_eta);
1376 fit_unc_xf.push_back(fit_average_unc_xf);
1377 }
1378
1379 void ShuffleBunches::fit_asym(double& asym_amplitude,
1380 double& asym_amplitude_err,
1381 const double (&asym_azimuth_values)[ASYM_CONSTANTS::nPhiBins],
1382 const double (&asym_azimuth_uncertainties)[ASYM_CONSTANTS::nPhiBins],
1383 bool fit_geom)
1384 {
1385 int N = (fit_geom ? ASYM_CONSTANTS::nPhiBins / 2 : ASYM_CONSTANTS::nPhiBins);
1386
1387
1388 asym_amplitude = 0.0;
1389 asym_amplitude_err = 0.0;
1390
1391
1392 double phi[N];
1393 double y[N];
1394 double ex[N];
1395 double ey[N];
1396
1397 double phiMin = (fit_geom ? - M_PI / 2 : -M_PI);
1398 double phiMax = (fit_geom ? M_PI / 2 : M_PI);
1399 const double dphi = (phiMax - phiMin) / N;
1400
1401 for (int i = 0; i < N; ++i) {
1402 int iphi = (fit_geom ? i + 3 : i);
1403 phi[i] = phiMin + (i + 0.5) * dphi;
1404 y[i] = asym_azimuth_values[iphi];
1405 ex[i] = 0.0;
1406
1407
1408 ey[i] = (asym_azimuth_uncertainties[iphi] > 0.0)
1409 ? asym_azimuth_uncertainties[iphi]
1410 : 1.0;
1411 }
1412
1413 TGraphErrors gr(N, phi, y, ex, ey);
1414 gr.SetName("gr_asym_phi");
1415 gr.SetTitle("Asymmetry vs #phi;#phi;Asymmetry");
1416
1417
1418 TF1 f_asym("f_asym", "-[0]*sin(x)", phiMin, phiMax);
1419 f_asym.SetParName(0, "A");
1420
1421
1422
1423 TFitResultPtr fitResult = gr.Fit(&f_asym, "QS");
1424
1425 asym_amplitude = f_asym.GetParameter(0);
1426 asym_amplitude_err = f_asym.GetParError(0);
1427 }
1428
1429 void ShuffleBunches::compute_corrected_asyms(const int iIter)
1430 {
1431 const pt_fit_array& fit_average_mean_pt = fit_mean_pt[iIter];
1432 const pt_nodir_fit_array& fit_average_mean_pt_nodir = fit_mean_pt_nodir[iIter];
1433 const eta_fit_array& fit_average_mean_eta = fit_mean_eta[iIter];
1434 const xf_fit_array& fit_average_mean_xf = fit_mean_xf[iIter];
1435 const pt_fit_array& fit_average_unc_pt = fit_unc_pt[iIter];
1436 const pt_nodir_fit_array& fit_average_unc_pt_nodir = fit_unc_pt_nodir[iIter];
1437 const eta_fit_array& fit_average_unc_eta = fit_unc_eta[iIter];
1438 const xf_fit_array& fit_average_unc_xf = fit_unc_xf[iIter];
1439
1440 pt_corr_array corrected_average_mean_pt;
1441 pt_nodir_corr_array corrected_average_mean_pt_nodir;
1442 eta_corr_array corrected_average_mean_eta;
1443 xf_corr_array corrected_average_mean_xf;
1444 pt_corr_array corrected_average_unc_pt;
1445 pt_nodir_corr_array corrected_average_unc_pt_nodir;
1446 eta_corr_array corrected_average_unc_eta;
1447 xf_corr_array corrected_average_unc_xf;
1448
1449 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1450 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1451 {
1452 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1453 compute_corrected_asym(corrected_average_mean_pt_nodir(iB, iP, iPt),
1454 corrected_average_unc_pt_nodir(iB, iP, iPt),
1455 fit_average_mean_pt_nodir(iB, iP, 0, iPt),
1456 fit_average_mean_pt_nodir(iB, iP, 1, iPt),
1457 fit_average_unc_pt_nodir(iB, iP, 0, iPt),
1458 fit_average_unc_pt_nodir(iB, iP, 1, iPt),
1459 bkg_ratio_pt[iP][iPt],
1460 bkg_ratio_err_pt[iP][iPt]);
1461 }
1462 }
1463 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1464 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1465 compute_corrected_asym(corrected_average_mean_pt(iB, iP, iPt, iDir),
1466 corrected_average_unc_pt(iB, iP, iPt, iDir),
1467 fit_average_mean_pt(iB, iP, 0, iPt, iDir),
1468 fit_average_mean_pt(iB, iP, 1, iPt, iDir),
1469 fit_average_unc_pt(iB, iP, 0, iPt, iDir),
1470 fit_average_unc_pt(iB, iP, 1, iPt, iDir),
1471 bkg_ratio_pt[iP][iPt],
1472 bkg_ratio_err_pt[iP][iPt]);
1473 }
1474 }
1475 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++) {
1476 compute_corrected_asym(corrected_average_mean_eta(iB, iP, iEta),
1477 corrected_average_unc_eta(iB, iP, iEta),
1478 fit_average_mean_eta(iB, iP, 0, iEta),
1479 fit_average_mean_eta(iB, iP, 1, iEta),
1480 fit_average_unc_eta(iB, iP, 0, iEta),
1481 fit_average_unc_eta(iB, iP, 1, iEta),
1482 bkg_ratio_eta[iP][iEta],
1483 bkg_ratio_err_eta[iP][iEta]);
1484 }
1485 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++) {
1486 compute_corrected_asym(corrected_average_mean_xf(iB, iP, iXf),
1487 corrected_average_unc_xf(iB, iP, iXf),
1488 fit_average_mean_xf(iB, iP, 0, iXf),
1489 fit_average_mean_xf(iB, iP, 1, iXf),
1490 fit_average_unc_xf(iB, iP, 0, iXf),
1491 fit_average_unc_xf(iB, iP, 1, iXf),
1492 bkg_ratio_xf[iP][iXf],
1493 bkg_ratio_err_xf[iP][iXf]);
1494 }
1495 }
1496 }
1497 corrected_mean_pt.push_back(corrected_average_mean_pt);
1498 corrected_mean_pt_nodir.push_back(corrected_average_mean_pt_nodir);
1499 corrected_mean_eta.push_back(corrected_average_mean_eta);
1500 corrected_mean_xf.push_back(corrected_average_mean_xf);
1501 corrected_unc_pt.push_back(corrected_average_unc_pt);
1502 corrected_unc_pt_nodir.push_back(corrected_average_unc_pt_nodir);
1503 corrected_unc_eta.push_back(corrected_average_unc_eta);
1504 corrected_unc_xf.push_back(corrected_average_unc_xf);
1505 }
1506
1507 void ShuffleBunches::compute_corrected_asym(double &corrected_asym,
1508 double &corrected_asym_err,
1509 const double &raw_asym,
1510 const double &bkg_asym,
1511 const double &raw_asym_err,
1512 const double &bkg_asym_err,
1513 const double &R,
1514 const double &R_err)
1515 {
1516 const double Delta_R = 0;
1517 const double Delta_raw = (R > 1 ? 0 : raw_asym_err / (1 - R));
1518 const double Delta_bkg = (R > 1 ? 0 : -R * bkg_asym_err / (1 - R));
1519 corrected_asym = (R > 1 ? 0 : (raw_asym - R * bkg_asym) / (1 - R));
1520 corrected_asym_err = (R > 1 ? 0 : std::sqrt(std::pow(Delta_R, 2) + std::pow(Delta_raw, 2) + std::pow(Delta_bkg, 2)));
1521 }
1522
1523 void ShuffleBunches::get_iter_raw_asym_histograms()
1524 {
1525 pt_asym_array& arr_pt_asym = mean_pt.back();
1526 eta_asym_array& arr_eta_asym = mean_eta.back();
1527 xf_asym_array& arr_xf_asym = mean_xf.back();
1528 pt_asym_array& arr_pt_asym_err = unc_pt.back();
1529 eta_asym_array& arr_eta_asym_err = unc_eta.back();
1530 xf_asym_array& arr_xf_asym_err = unc_xf.back();
1531
1532 outfile_iter_histograms->cd();
1533 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++)
1534 {
1535 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++)
1536 {
1537 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++)
1538 {
1539 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++)
1540 {
1541 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++)
1542 {
1543 TGraphErrors *graph_AN = new TGraphErrors();
1544 std::stringstream graph_AN_name;
1545 graph_AN_name << "graph_asym_pt_"
1546 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
1547 << ASYM_CONSTANTS::regions[iR] << "_"
1548 << "pT_" << iPt << "_"
1549 << ASYM_CONSTANTS::directions[iDir] << "_"
1550 << "sqrt";
1551 graph_AN->SetName(graph_AN_name.str().c_str());
1552 std::stringstream graph_title;
1553 graph_title << "; #phi; " << (iR == 0 ? "Raw" : "Bkg") << " Asymmetry";
1554 graph_AN->SetTitle(graph_title.str().c_str());
1555 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++)
1556 {
1557 float phi = -M_PI + M_PI / 12 + iPhi * M_PI / 6.;
1558 graph_AN->SetPoint(iPhi, phi, arr_pt_asym(iB, iP, iR, iPt, iDir, iPhi));
1559 graph_AN->SetPointError(iPhi, 0, arr_pt_asym_err(iB, iP, iR, iPt, iDir, iPhi));
1560 }
1561 graph_AN->Write();
1562 }
1563 }
1564 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++)
1565 {
1566 TGraphErrors *graph_AN = new TGraphErrors();
1567 std::stringstream graph_AN_name;
1568 graph_AN_name << "graph_asym_eta_"
1569 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
1570 << ASYM_CONSTANTS::regions[iR] << "_"
1571 << "eta_" << iEta << "_sqrt";
1572 graph_AN->SetName(graph_AN_name.str().c_str());
1573 std::stringstream graph_title;
1574 graph_title << "; #phi; " << (iR == 0 ? "Raw" : "Bkg") << " Asymmetry";
1575 graph_AN->SetTitle(graph_title.str().c_str());
1576 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++)
1577 {
1578 float phi = -M_PI + M_PI / 12 + iPhi * M_PI / 6.;
1579 graph_AN->SetPoint(iPhi, phi, arr_eta_asym(iB, iP, iR, iEta, iPhi));
1580 graph_AN->SetPointError(iPhi, 0, arr_eta_asym_err(iB, iP, iR, iEta, iPhi));
1581 }
1582 graph_AN->Write();
1583 }
1584 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++)
1585 {
1586 TGraphErrors *graph_AN = new TGraphErrors();
1587 std::stringstream graph_AN_name;
1588 graph_AN_name << "graph_asym_xf_"
1589 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
1590 << ASYM_CONSTANTS::regions[iR] << "_"
1591 << "xf_" << iXf << "_sqrt";
1592 graph_AN->SetName(graph_AN_name.str().c_str());
1593 std::stringstream graph_title;
1594 graph_title << "; #phi; " << (iR == 0 ? "Raw" : "Bkg") << " Asymmetry";
1595 graph_AN->SetTitle(graph_title.str().c_str());
1596
1597
1598 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++)
1599 {
1600 float phi = -M_PI + M_PI / 12 + iPhi * M_PI / 6.;
1601 graph_AN->SetPoint(iPhi, phi, arr_xf_asym(iB, iP, iR, iXf, iPhi));
1602 graph_AN->SetPointError(iPhi, 0, arr_xf_asym_err(iB, iP, iR, iXf, iPhi));
1603 }
1604 graph_AN->Write();
1605 }
1606 }
1607 }
1608 }
1609 }
1610
1611 void ShuffleBunches::get_iter_fit_asym_histograms()
1612 {
1613 pt_fit_array& arr_pt_asym = fit_mean_pt.back();
1614 eta_fit_array& arr_eta_asym = fit_mean_eta.back();
1615 xf_fit_array& arr_xf_asym = fit_mean_xf.back();
1616 pt_fit_array& arr_pt_asym_err = fit_unc_pt.back();
1617 eta_fit_array& arr_eta_asym_err = fit_unc_eta.back();
1618 xf_fit_array& arr_xf_asym_err = fit_unc_xf.back();
1619
1620 outfile_iter_histograms->cd();
1621 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++)
1622 {
1623 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++)
1624 {
1625 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++)
1626 {
1627 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++)
1628 {
1629 TGraphErrors *graph_AN = new TGraphErrors();
1630 std::stringstream graph_AN_name;
1631 graph_AN_name << "graph_asym_pt_"
1632 << ASYM_CONSTANTS::beams[iB] << "_"
1633 << ASYM_CONSTANTS::particle[iP] << "_"
1634 << ASYM_CONSTANTS::regions[iR] << "_"
1635 << ASYM_CONSTANTS::directions[iDir] << "_"
1636 << "sqrt";
1637 graph_AN->SetName(graph_AN_name.str().c_str());
1638 std::stringstream graph_title;
1639 graph_title << "; p_{T} [GeV]; A_{N}^{" << (iR == 0 ? "Raw" : "Bkg") << "}";
1640 graph_AN->SetTitle(graph_title.str().c_str());
1641 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++)
1642 {
1643 float pT = pTMeans[iP][iPt];
1644 graph_AN->SetPoint(iPt, pT, arr_pt_asym(iB, iP, iR, iPt, iDir));
1645 graph_AN->SetPointError(iPt, 0, arr_pt_asym_err(iB, iP, iR, iPt, iDir));
1646 graph_AN->Write();
1647 }
1648 }
1649 {
1650 TGraphErrors *graph_AN = new TGraphErrors();
1651 std::stringstream graph_AN_name;
1652 graph_AN_name << "graph_asym_eta_"
1653 << ASYM_CONSTANTS::beams[iB] << "_"
1654 << ASYM_CONSTANTS::particle[iP] << "_"
1655 << ASYM_CONSTANTS::regions[iR] << "_"
1656 << "sqrt";
1657 graph_AN->SetName(graph_AN_name.str().c_str());
1658 std::stringstream graph_title;
1659 graph_title << "; #eta; A_{N}^{" << (iR == 0 ? "Raw" : "Bkg") << "}";
1660 graph_AN->SetTitle(graph_title.str().c_str());
1661 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++)
1662 {
1663 float eta = etaMeans[iP][iEta];
1664 graph_AN->SetPoint(iEta, eta, arr_eta_asym(iB, iP, iR, iEta));
1665 graph_AN->SetPointError(iEta, 0, arr_eta_asym_err(iB, iP, iR, iEta));
1666
1667 }
1668 graph_AN->Write();
1669 }
1670 {
1671 TGraphErrors *graph_AN = new TGraphErrors();
1672 std::stringstream graph_AN_name;
1673 graph_AN_name << "graph_asym_xf_"
1674 << ASYM_CONSTANTS::beams[iB] << "_"
1675 << ASYM_CONSTANTS::particle[iP] << "_"
1676 << ASYM_CONSTANTS::regions[iR] << "_"
1677 << "sqrt";
1678 graph_AN->SetName(graph_AN_name.str().c_str());
1679 std::stringstream graph_title;
1680 graph_title << "; x_{F}; A_{N}^{" << (iR == 0 ? "Raw" : "Bkg") << "}";
1681 graph_AN->SetTitle(graph_title.str().c_str());
1682 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++)
1683 {
1684 float xf = xfMeans[iP][iXf];
1685 graph_AN->SetPoint(iXf, xf, arr_xf_asym(iB, iP, iR, iXf));
1686 graph_AN->SetPointError(iXf, 0, arr_xf_asym_err(iB, iP, iR, iXf));
1687
1688 }
1689 graph_AN->Write();
1690 }
1691 }
1692 }
1693 }
1694 }
1695
1696 void ShuffleBunches::get_iter_corr_asym_histograms()
1697 {
1698 pt_corr_array& arr_pt_asym = corrected_mean_pt.back();
1699 eta_corr_array& arr_eta_asym = corrected_mean_eta.back();
1700 xf_corr_array& arr_xf_asym = corrected_mean_xf.back();
1701 pt_corr_array& arr_pt_asym_err = corrected_unc_pt.back();
1702 eta_corr_array& arr_eta_asym_err = corrected_unc_eta.back();
1703 xf_corr_array& arr_xf_asym_err = corrected_unc_xf.back();
1704
1705 outfile_iter_histograms->cd();
1706 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++)
1707 {
1708 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++)
1709 {
1710 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++)
1711 {
1712 TGraphErrors *graph_AN = new TGraphErrors();
1713 std::stringstream graph_AN_name;
1714 graph_AN_name << "graph_asym_pt_"
1715 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
1716 << ASYM_CONSTANTS::directions[iDir] << "_"
1717 << "sqrt";
1718 graph_AN->SetName(graph_AN_name.str().c_str());
1719 std::stringstream graph_title;
1720 graph_title << "; p_{T} [GeV]; A_{N}";
1721 graph_AN->SetTitle(graph_title.str().c_str());
1722 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++)
1723 {
1724 float pT = pTMeans[iP][iPt];
1725 graph_AN->SetPoint(iPt, pT, arr_pt_asym(iB, iP, iPt, iDir));
1726 graph_AN->SetPointError(iPt, 0, arr_pt_asym_err(iB, iP, iPt, iDir));
1727 graph_AN->Write();
1728 }
1729 }
1730 {
1731 TGraphErrors *graph_AN = new TGraphErrors();
1732 std::stringstream graph_AN_name;
1733 graph_AN_name << "graph_asym_eta_"
1734 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_sqrt";
1735 graph_AN->SetName(graph_AN_name.str().c_str());
1736 std::stringstream graph_title;
1737 graph_title << "; #eta; A_{N}";
1738 graph_AN->SetTitle(graph_title.str().c_str());
1739 for (int iEta = 0; iEta < ASYM_CONSTANTS::nEtaBins; iEta++)
1740 {
1741 float eta = etaMeans[iP][iEta];
1742 graph_AN->SetPoint(iEta, eta, arr_eta_asym(iB, iP, iEta));
1743 graph_AN->SetPointError(iEta, 0, arr_eta_asym_err(iB, iP, iEta));
1744
1745 }
1746 graph_AN->Write();
1747 }
1748 {
1749 TGraphErrors *graph_AN = new TGraphErrors();
1750 std::stringstream graph_AN_name;
1751 graph_AN_name << "graph_asym_xf_"
1752 << ASYM_CONSTANTS::beams[iB] << "_" << ASYM_CONSTANTS::particle[iP] << "_"
1753 << "sqrt";
1754 graph_AN->SetName(graph_AN_name.str().c_str());
1755 std::stringstream graph_title;
1756 graph_title << "; x_{F}; A_{N}";
1757 graph_AN->SetTitle(graph_title.str().c_str());
1758 for (int iXf = 0; iXf < ASYM_CONSTANTS::nXfBins; iXf++)
1759 {
1760 float xf = xfMeans[iP][iXf];
1761 graph_AN->SetPoint(iXf, xf, arr_xf_asym(iB, iP, iXf));
1762 graph_AN->SetPointError(iXf, 0, arr_xf_asym_err(iB, iP, iXf));
1763
1764 }
1765 graph_AN->Write();
1766 }
1767 }
1768 }
1769 }
1770
1771 void ShuffleBunches::check_array()
1772 {
1773 std::memset(array_yield_pt, 0, sizeof(array_yield_pt));
1774 std::memset(array_yield_eta, 0, sizeof(array_yield_eta));
1775 std::memset(array_yield_xf, 0, sizeof(array_yield_xf));
1776
1777 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1778 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1779 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++) {
1780 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1781 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1782 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++) {
1783 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1784 for(int iBunch = 0; iBunch < ASYM_CONSTANTS::nBunches; iBunch++) {
1785
1786 array_yield_pt[iB][iP][iR][iPt][iDir][iS][iPhi] +=
1787 array_yield_pt_bunches[iB][iP][iR][iPt][iDir][iS][iPhi][iBunch];
1788 }
1789 }
1790 }
1791 }
1792 }
1793 }
1794 }
1795 }
1796
1797 for (int iB = 0; iB < ASYM_CONSTANTS::nBeams; iB++) {
1798 for (int iP = 0; iP < ASYM_CONSTANTS::nParticles; iP++) {
1799 for (int iR = 0; iR < ASYM_CONSTANTS::nRegions; iR++) {
1800 for (int iPt = 0; iPt < ASYM_CONSTANTS::nPtBins; iPt++) {
1801 for (int iDir = 0; iDir < ASYM_CONSTANTS::nDirections; iDir++) {
1802 for (int iS = 0; iS < ASYM_CONSTANTS::nSpins; iS++) {
1803 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1804 std::cout << "array_yield_pt[" << iB << "][" << iP << "][" << iR << "][" << iPt << "][" << iDir << "][" << iS << "][" << iPhi << "] = "
1805 << array_yield_pt[iB][iP][iR][iPt][iDir][iS][iPhi] << std::endl;
1806 }
1807 }
1808 }
1809 }
1810 }
1811 }
1812 }
1813 }
1814
1815 void ShuffleBunches::compute_rellum_asym(const uint32_t (&array_yield)[ASYM_CONSTANTS::nSpins][ASYM_CONSTANTS::nPhiBins],
1816 const double pol,
1817 double (&array_asym)[ASYM_CONSTANTS::nPhiBins],
1818 double (&array_asym_err)[ASYM_CONSTANTS::nPhiBins])
1819 {
1820 auto rellum_asym = [&](double Nup, double Ndown, double RL) -> double {
1821 double numerator = Nup - RL * Ndown;
1822 double denominator = Nup + RL * Ndown;
1823 double asym = numerator / denominator / pol * 100;
1824 return asym;
1825 };
1826
1827 auto rellum_asym_err = [&](double Nup, double Ndown, double RL) -> double {
1828
1829 double NupErr = std::sqrt(Nup);
1830 double NdownErr = std::sqrt(Ndown);
1831 double t1 = 2 * RL * Ndown * NupErr;
1832 double t2 = 2 * RL * Nup * NdownErr;
1833 double denominator = pow(Nup + RL * Ndown,2);
1834 double asym_err = sqrt(pow(t1, 2) + pow(t2, 2)) / denominator / pol * 100;
1835 return asym_err;
1836 };
1837
1838 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1839 double Nup = (double) array_yield[0][iPhi];
1840 double Ndown = (double) array_yield[1][iPhi];
1841
1842 array_asym[iPhi] = rellum_asym(Nup, Ndown, relative_luminosity);
1843 array_asym_err[iPhi] = rellum_asym_err(Nup, Ndown, relative_luminosity);
1844 }
1845 }
1846
1847 void ShuffleBunches::compute_sqrt_asym(const uint32_t (&array_yield)[ASYM_CONSTANTS::nSpins][ASYM_CONSTANTS::nPhiBins],
1848 const double pol,
1849 double (&array_asym)[ASYM_CONSTANTS::nPhiBins],
1850 double (&array_asym_err)[ASYM_CONSTANTS::nPhiBins])
1851 {
1852 auto sqrt_asym = [&](double NLup, double NLdown, double NRup, double NRdown) -> double {
1853 double numerator = sqrt(NLup*NRdown)-sqrt(NRup*NLdown);
1854 double denominator = sqrt(NLup*NRdown)+sqrt(NRup*NLdown);
1855 double asym = numerator / denominator / pol * 100;
1856 return asym;
1857 };
1858
1859 auto sqrt_asym_err = [&](double NLup, double NLdown, double NRup, double NRdown) -> double {
1860 double NLupErr = std::sqrt(NLup);
1861 double NLdownErr = std::sqrt(NLdown);
1862 double NRupErr = std::sqrt(NRup);
1863 double NRdownErr = std::sqrt(NRdown);
1864 double t1 = sqrt(NLdown*NRup*NRdown/NLup)*NLupErr;
1865 double t2 = sqrt(NLup*NRup*NRdown/NLdown)*NLdownErr;
1866 double t3 = sqrt(NLup*NLdown*NRdown/NRup)*NRupErr;
1867 double t4 = sqrt(NLup*NLdown*NRup/NRdown)*NRdownErr;
1868 double denominator = pow(sqrt(NLup*NRdown)+sqrt(NRup*NLdown),2);
1869 double asym_err = sqrt(pow(t1,2)+pow(t2,2)+pow(t3,2)+pow(t4,2)) / denominator / pol * 100;
1870 return asym_err;
1871 };
1872
1873 for (int iPhi = 0; iPhi < ASYM_CONSTANTS::nPhiBins; iPhi++) {
1874 int iPhiL = iPhi;
1875 int iPhiR = (iPhi + (int)(ASYM_CONSTANTS::nPhiBins/2)) % ASYM_CONSTANTS::nPhiBins;
1876 double NLup = (double) array_yield[0][iPhiL];
1877 double NLdown = (double) array_yield[1][iPhiL];
1878 double NRup = (double) array_yield[0][iPhiR];
1879 double NRdown = (double) array_yield[1][iPhiR];
1880
1881 array_asym[iPhi] = sqrt_asym(NLup, NLdown, NRup, NRdown);
1882 array_asym_err[iPhi] = sqrt_asym_err(NLup, NLdown, NRup, NRdown);
1883 }
1884 }
1885 };