Skip to content

Commit 2135e2f

Browse files
authored
[PWGEM/Dilepton] quick fix to axis label (#9393)
1 parent 3943ce8 commit 2135e2f

File tree

1 file changed

+334
-1
lines changed

1 file changed

+334
-1
lines changed

PWGEM/Dilepton/TableProducer/filterDielectronEvent.cxx

Lines changed: 334 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1114,13 +1114,346 @@ struct filterDielectronEvent {
11141114
PROCESS_SWITCH(filterDielectronEvent, processMC_TTCA, "process reconstructed info only", false); // with TTCA
11151115
};
11161116
struct prefilterPrimaryElectron {
1117+
using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::EMEvSels>;
1118+
using MyCollisionsWithSWT = soa::Join<MyCollisions, aod::EMSWTriggerInfosTMP>;
1119+
11171120
Produces<aod::EMPrimaryElectronsPrefilterBit> ele_pfb;
1118-
void process(aod::EMPrimaryElectrons const& primaryelectrons)
1121+
1122+
SliceCache cache;
1123+
Preslice<aod::Tracks> perCol_track = o2::aod::track::collisionId;
1124+
PresliceUnsorted<aod::EMPrimaryElectrons> perCol_ele = o2::aod::emprimaryelectron::collisionId;
1125+
1126+
// CCDB options
1127+
Configurable<std::string> ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
1128+
Configurable<std::string> grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"};
1129+
Configurable<std::string> grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};
1130+
Configurable<bool> skipGRPOquery{"skipGRPOquery", true, "skip grpo query"};
1131+
1132+
// Operation and minimisation criteria
1133+
Configurable<double> d_bz_input{"d_bz", -999, "bz field, -999 is automatic"};
1134+
1135+
Configurable<float> max_dcaxy{"max_dcaxy", 0.3, "DCAxy To PV for loose track sample"};
1136+
Configurable<float> max_dcaz{"max_dcaz", 0.3, "DCAz To PV for loose track sample"};
1137+
Configurable<float> minpt{"minpt", 0.1, "min pt for track for loose track sample"};
1138+
Configurable<float> maxeta{"maxeta", 0.9, "eta acceptance for loose track sample"};
1139+
Configurable<int> min_ncluster_tpc{"min_ncluster_tpc", 0, "min ncluster tpc"};
1140+
Configurable<int> mincrossedrows{"mincrossedrows", 70, "min crossed rows"};
1141+
Configurable<float> max_frac_shared_clusters_tpc{"max_frac_shared_clusters_tpc", 999.f, "max fraction of shared clusters in TPC"};
1142+
Configurable<float> min_tpc_cr_findable_ratio{"min_tpc_cr_findable_ratio", 0.8, "min. TPC Ncr/Nf ratio"};
1143+
Configurable<float> maxchi2tpc{"maxchi2tpc", 5.0, "max chi2/NclsTPC"};
1144+
Configurable<float> maxchi2its{"maxchi2its", 6.0, "max chi2/NclsITS"};
1145+
Configurable<int> min_ncluster_its{"min_ncluster_its", 4, "min ncluster its"};
1146+
Configurable<int> min_ncluster_itsib{"min_ncluster_itsib", 1, "min ncluster itsib"};
1147+
Configurable<float> minTPCNsigmaEl{"minTPCNsigmaEl", -3.0, "min. TPC n sigma for electron inclusion"};
1148+
Configurable<float> maxTPCNsigmaEl{"maxTPCNsigmaEl", 3.0, "max. TPC n sigma for electron inclusion"};
1149+
Configurable<float> slope{"slope", 0.0185, "slope for m vs. phiv"};
1150+
Configurable<float> intercept{"intercept", -0.0280, "intercept for m vs. phiv"};
1151+
1152+
Configurable<std::vector<float>> max_mee_vec{"max_mee_vec", std::vector<float>{0.08, 0.10, 0.12}, "vector fo max mee for prefilter in ULS. Please sort this by increasing order."}; // currently, 3 thoresholds are allowed.
1153+
1154+
HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false};
1155+
1156+
int mRunNumber;
1157+
float d_bz;
1158+
Service<o2::ccdb::BasicCCDBManager> ccdb;
1159+
o2::base::Propagator::MatCorrType matCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE;
1160+
1161+
void init(InitContext&)
1162+
{
1163+
mRunNumber = 0;
1164+
d_bz = 0;
1165+
1166+
ccdb->setURL(ccdburl);
1167+
ccdb->setCaching(true);
1168+
ccdb->setLocalObjectValidityChecking();
1169+
ccdb->setFatalWhenNull(false);
1170+
1171+
if (!doprocessDummy) {
1172+
addHistograms();
1173+
}
1174+
}
1175+
1176+
void addHistograms()
1177+
{
1178+
fRegistry.add("Track/hPt", "pT;p_{T} (GeV/c)", kTH1F, {{1000, 0.0f, 10}}, false);
1179+
fRegistry.add("Track/hEtaPhi", "#eta vs. #varphi;#varphi (rad.);#eta", kTH2F, {{180, 0, 2 * M_PI}, {40, -1.0f, 1.0f}}, false);
1180+
fRegistry.add("Track/hTPCNsigmaEl", "loose track TPC PID", kTH2F, {{1000, 0.f, 10}, {100, -5, +5}});
1181+
fRegistry.add("Pair/before/uls/hMvsPt", "mass vs. pT;m_{ee} (GeV/c^{2});p_{T,ee} (GeV/c)", kTH2F, {{400, 0, 4}, {100, 0, 10}});
1182+
fRegistry.add("Pair/before/uls/hMvsPhiV", "mass vs. phiv;#varphi_{V} (rad.);m_{ee} (GeV/c^{2})", kTH2F, {{90, 0.f, M_PI}, {100, 0, 1.f}});
1183+
fRegistry.addClone("Pair/before/uls/", "Pair/before/lspp/");
1184+
fRegistry.addClone("Pair/before/uls/", "Pair/before/lsmm/");
1185+
fRegistry.addClone("Pair/before/", "Pair/after/");
1186+
}
1187+
1188+
void initCCDB(aod::BCsWithTimestamps::iterator const& bc)
1189+
{
1190+
if (mRunNumber == bc.runNumber()) {
1191+
return;
1192+
}
1193+
1194+
// In case override, don't proceed, please - no CCDB access required
1195+
if (d_bz_input > -990) {
1196+
d_bz = d_bz_input;
1197+
o2::parameters::GRPMagField grpmag;
1198+
if (fabs(d_bz) > 1e-5) {
1199+
grpmag.setL3Current(30000.f / (d_bz / 5.0f));
1200+
}
1201+
o2::base::Propagator::initFieldFromGRP(&grpmag);
1202+
mRunNumber = bc.runNumber();
1203+
return;
1204+
}
1205+
1206+
auto run3grp_timestamp = bc.timestamp();
1207+
o2::parameters::GRPObject* grpo = 0x0;
1208+
o2::parameters::GRPMagField* grpmag = 0x0;
1209+
if (!skipGRPOquery)
1210+
grpo = ccdb->getForTimeStamp<o2::parameters::GRPObject>(grpPath, run3grp_timestamp);
1211+
if (grpo) {
1212+
o2::base::Propagator::initFieldFromGRP(grpo);
1213+
// Fetch magnetic field from ccdb for current collision
1214+
d_bz = grpo->getNominalL3Field();
1215+
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG";
1216+
} else {
1217+
grpmag = ccdb->getForTimeStamp<o2::parameters::GRPMagField>(grpmagPath, run3grp_timestamp);
1218+
if (!grpmag) {
1219+
LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp;
1220+
}
1221+
o2::base::Propagator::initFieldFromGRP(grpmag);
1222+
// Fetch magnetic field from ccdb for current collision
1223+
d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f);
1224+
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG";
1225+
}
1226+
mRunNumber = bc.runNumber();
1227+
}
1228+
1229+
o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE;
1230+
1231+
template <typename TCollision, typename TTrack>
1232+
bool checkTrack(TCollision const& collision, TTrack const& track)
1233+
{
1234+
if (!track.hasITS()) {
1235+
return false;
1236+
}
1237+
if (track.itsChi2NCl() > maxchi2its) {
1238+
return false;
1239+
}
1240+
if (track.itsNCls() < min_ncluster_its) {
1241+
return false;
1242+
}
1243+
if (track.itsNClsInnerBarrel() < min_ncluster_itsib) {
1244+
return false;
1245+
}
1246+
1247+
if (!track.hasTPC()) {
1248+
return false;
1249+
}
1250+
if (track.tpcNSigmaEl() < minTPCNsigmaEl || maxTPCNsigmaEl < track.tpcNSigmaEl()) {
1251+
return false;
1252+
}
1253+
if (track.tpcNClsFound() < min_ncluster_tpc) {
1254+
return false;
1255+
}
1256+
if (track.tpcNClsCrossedRows() < mincrossedrows) {
1257+
return false;
1258+
}
1259+
if (track.tpcCrossedRowsOverFindableCls() < min_tpc_cr_findable_ratio) {
1260+
return false;
1261+
}
1262+
if (track.tpcFractionSharedCls() > max_frac_shared_clusters_tpc) {
1263+
return false;
1264+
}
1265+
if (track.tpcChi2NCl() > maxchi2its) {
1266+
return false;
1267+
}
1268+
1269+
gpu::gpustd::array<float, 2> dcaInfo;
1270+
auto track_par_cov_recalc = getTrackParCov(track);
1271+
std::array<float, 3> pVec_recalc = {0, 0, 0}; // px, py, pz
1272+
o2::base::Propagator::Instance()->propagateToDCABxByBz({collision.posX(), collision.posY(), collision.posZ()}, track_par_cov_recalc, 2.f, matCorr, &dcaInfo);
1273+
getPxPyPz(track_par_cov_recalc, pVec_recalc);
1274+
1275+
if (fabs(dcaInfo[0]) > max_dcaxy || fabs(dcaInfo[1]) > max_dcaz) {
1276+
return false;
1277+
}
1278+
1279+
if (track_par_cov_recalc.getPt() < minpt || fabs(track_par_cov_recalc.getEta()) > maxeta) {
1280+
return false;
1281+
}
1282+
1283+
return true;
1284+
}
1285+
1286+
Preslice<aod::TrackAssoc> trackIndicesPerCollision = aod::track_association::collisionId;
1287+
1288+
Filter trackFilter = o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::ITS) == true && ncheckbit(aod::track::v001::detectorMap, (uint8_t)o2::aod::track::TPC) == true;
1289+
using MyFilteredTracks = soa::Filtered<MyTracks>;
1290+
Partition<MyFilteredTracks> posTracks = o2::aod::track::signed1Pt > 0.f;
1291+
Partition<MyFilteredTracks> negTracks = o2::aod::track::signed1Pt < 0.f;
1292+
1293+
Partition<aod::EMPrimaryElectrons> positrons = o2::aod::emprimaryelectron::sign > int8_t(0);
1294+
Partition<aod::EMPrimaryElectrons> electrons = o2::aod::emprimaryelectron::sign < int8_t(0);
1295+
void processSA(MyCollisions const& collisions, aod::BCsWithTimestamps const&, MyFilteredTracks const&, aod::EMPrimaryElectrons const& primaryelectrons)
1296+
{
1297+
std::unordered_map<int, uint8_t> pfb_map; // map track.globalIndex -> prefilter bit
1298+
1299+
for (auto& collision : collisions) {
1300+
auto bc = collision.template foundBC_as<aod::BCsWithTimestamps>();
1301+
initCCDB(bc);
1302+
if (!collision.isSelected()) {
1303+
continue;
1304+
}
1305+
1306+
auto posTracks_per_coll = posTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample
1307+
auto negTracks_per_coll = negTracks->sliceByCached(o2::aod::track::collisionId, collision.globalIndex(), cache); // loose track sample
1308+
1309+
auto positrons_per_coll = positrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample
1310+
auto electrons_per_coll = electrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample
1311+
1312+
for (auto& pos : posTracks_per_coll) {
1313+
if (!checkTrack(collision, pos)) { // track cut is applied to loose sample
1314+
continue;
1315+
}
1316+
fRegistry.fill(HIST("Track/hPt"), pos.pt());
1317+
fRegistry.fill(HIST("Track/hEtaPhi"), pos.phi(), pos.eta());
1318+
}
1319+
for (auto& neg : negTracks_per_coll) {
1320+
if (!checkTrack(collision, neg)) { // track cut is applied to loose sample
1321+
continue;
1322+
}
1323+
fRegistry.fill(HIST("Track/hPt"), neg.pt());
1324+
fRegistry.fill(HIST("Track/hEtaPhi"), neg.phi(), neg.eta());
1325+
}
1326+
1327+
for (auto& [ele, empos] : combinations(CombinationsFullIndexPolicy(negTracks_per_coll, positrons_per_coll))) {
1328+
// auto pos = tracks.rawIteratorAt(empos.trackId()); // use rawIterator, if the table is filtered.
1329+
if (!checkTrack(collision, ele)) { // track cut is applied to loose sample
1330+
continue;
1331+
}
1332+
if (empos.trackId() == ele.globalIndex()) {
1333+
continue;
1334+
}
1335+
1336+
ROOT::Math::PtEtaPhiMVector v1(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); // loose track
1337+
ROOT::Math::PtEtaPhiMVector v2(empos.pt(), empos.eta(), empos.phi(), o2::constants::physics::MassElectron); // signal track
1338+
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2;
1339+
float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(empos.px(), empos.py(), empos.pz(), ele.px(), ele.py(), ele.pz(), empos.sign(), ele.sign(), d_bz);
1340+
fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV"), phiv, v12.M());
1341+
fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt());
1342+
if (v12.M() < max_mee_vec->at(static_cast<int>(max_mee_vec->size()) - 1)) {
1343+
fRegistry.fill(HIST("Track/hTPCNsigmaEl"), ele.tpcInnerParam(), ele.tpcNSigmaEl());
1344+
}
1345+
for (int i = 0; i < static_cast<int>(max_mee_vec->size()); i++) {
1346+
if (v12.M() < max_mee_vec->at(i)) {
1347+
pfb_map[empos.globalIndex()] |= (uint8_t(1) << (static_cast<int>(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_1) + i));
1348+
}
1349+
}
1350+
1351+
if (v12.M() < slope * phiv + intercept) {
1352+
pfb_map[empos.globalIndex()] |= (uint8_t(1) << static_cast<int>(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC));
1353+
}
1354+
1355+
} // end of ULS pairing
1356+
1357+
for (auto& [pos, emele] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, electrons_per_coll))) {
1358+
// auto ele = tracks.rawIteratorAt(emele.trackId()); // use rawIterator, if the table is filtered.
1359+
if (!checkTrack(collision, pos)) { // track cut is applied to loose sample
1360+
continue;
1361+
}
1362+
if (emele.trackId() == pos.globalIndex()) {
1363+
continue;
1364+
}
1365+
1366+
ROOT::Math::PtEtaPhiMVector v1(emele.pt(), emele.eta(), emele.phi(), o2::constants::physics::MassElectron); // signal track
1367+
ROOT::Math::PtEtaPhiMVector v2(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); // loose track
1368+
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2;
1369+
float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), emele.px(), emele.py(), emele.pz(), pos.sign(), emele.sign(), d_bz);
1370+
fRegistry.fill(HIST("Pair/before/uls/hMvsPhiV"), phiv, v12.M());
1371+
fRegistry.fill(HIST("Pair/before/uls/hMvsPt"), v12.M(), v12.Pt());
1372+
if (v12.M() < max_mee_vec->at(static_cast<int>(max_mee_vec->size()) - 1)) {
1373+
fRegistry.fill(HIST("Track/hTPCNsigmaEl"), pos.tpcInnerParam(), pos.tpcNSigmaEl());
1374+
}
1375+
for (int i = 0; i < static_cast<int>(max_mee_vec->size()); i++) {
1376+
if (v12.M() < max_mee_vec->at(i)) {
1377+
pfb_map[emele.globalIndex()] |= (uint8_t(1) << (static_cast<int>(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPi0_1) + i));
1378+
}
1379+
}
1380+
1381+
if (v12.M() < slope * phiv + intercept) {
1382+
pfb_map[emele.globalIndex()] |= (uint8_t(1) << static_cast<int>(o2::aod::pwgem::dilepton::utils::pairutil::DileptonPrefilterBit::kElFromPC));
1383+
}
1384+
1385+
} // end of ULS pairing
1386+
1387+
for (auto& [pos, empos] : combinations(CombinationsFullIndexPolicy(posTracks_per_coll, positrons_per_coll))) {
1388+
// auto pos = tracks.rawIteratorAt(empos.trackId()); // use rawIterator, if the table is filtered.
1389+
if (!checkTrack(collision, pos)) { // track cut is applied to loose sample
1390+
continue;
1391+
}
1392+
if (empos.trackId() == pos.globalIndex()) {
1393+
continue;
1394+
}
1395+
1396+
ROOT::Math::PtEtaPhiMVector v1(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron); // loose track
1397+
ROOT::Math::PtEtaPhiMVector v2(empos.pt(), empos.eta(), empos.phi(), o2::constants::physics::MassElectron); // signal track
1398+
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2;
1399+
float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(empos.px(), empos.py(), empos.pz(), pos.px(), pos.py(), pos.pz(), empos.sign(), pos.sign(), d_bz);
1400+
fRegistry.fill(HIST("Pair/before/lspp/hMvsPhiV"), phiv, v12.M());
1401+
fRegistry.fill(HIST("Pair/before/lspp/hMvsPt"), v12.M(), v12.Pt());
1402+
} // end of LS++ pairing
1403+
1404+
for (auto& [ele, emele] : combinations(CombinationsFullIndexPolicy(negTracks_per_coll, electrons_per_coll))) {
1405+
// auto ele = tracks.rawIteratorAt(emele.trackId()); // use rawIterator, if the table is filtered.
1406+
if (!checkTrack(collision, ele)) { // track cut is applied to loose sample
1407+
continue;
1408+
}
1409+
if (emele.trackId() == ele.globalIndex()) {
1410+
continue;
1411+
}
1412+
1413+
ROOT::Math::PtEtaPhiMVector v1(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron); // loose track
1414+
ROOT::Math::PtEtaPhiMVector v2(emele.pt(), emele.eta(), emele.phi(), o2::constants::physics::MassElectron); // signal track
1415+
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2;
1416+
float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(emele.px(), emele.py(), emele.pz(), ele.px(), ele.py(), ele.pz(), emele.sign(), ele.sign(), d_bz);
1417+
fRegistry.fill(HIST("Pair/before/lsmm/hMvsPhiV"), phiv, v12.M());
1418+
fRegistry.fill(HIST("Pair/before/lsmm/hMvsPt"), v12.M(), v12.Pt());
1419+
} // end of LS-- pairing
1420+
1421+
} // end of collision loop
1422+
1423+
for (auto& ele : primaryelectrons) {
1424+
ele_pfb(pfb_map[ele.globalIndex()]);
1425+
}
1426+
1427+
// check prefilter
1428+
for (auto& collision : collisions) {
1429+
auto positrons_per_coll = positrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample
1430+
auto electrons_per_coll = electrons->sliceByCachedUnsorted(o2::aod::emprimaryelectron::collisionId, collision.globalIndex(), cache); // signal sample
1431+
1432+
for (auto& [ele, pos] : combinations(CombinationsFullIndexPolicy(electrons_per_coll, positrons_per_coll))) {
1433+
if (pfb_map[ele.globalIndex()] != 0 || pfb_map[pos.globalIndex()] != 0) {
1434+
continue;
1435+
}
1436+
1437+
ROOT::Math::PtEtaPhiMVector v1(ele.pt(), ele.eta(), ele.phi(), o2::constants::physics::MassElectron);
1438+
ROOT::Math::PtEtaPhiMVector v2(pos.pt(), pos.eta(), pos.phi(), o2::constants::physics::MassElectron);
1439+
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2;
1440+
float phiv = o2::aod::pwgem::dilepton::utils::pairutil::getPhivPair(pos.px(), pos.py(), pos.pz(), ele.px(), ele.py(), ele.pz(), pos.sign(), ele.sign(), d_bz);
1441+
fRegistry.fill(HIST("Pair/after/uls/hMvsPhiV"), phiv, v12.M());
1442+
fRegistry.fill(HIST("Pair/after/uls/hMvsPt"), v12.M(), v12.Pt());
1443+
} // end of ULS pairing
1444+
} // end of collision loop
1445+
1446+
pfb_map.clear();
1447+
}
1448+
PROCESS_SWITCH(prefilterPrimaryElectron, processSA, "process SA", false);
1449+
1450+
void processDummy(aod::EMPrimaryElectrons const& primaryelectrons)
11191451
{
11201452
for (int i = 0; i < primaryelectrons.size(); i++) {
11211453
ele_pfb(0);
11221454
}
11231455
}
1456+
PROCESS_SWITCH(prefilterPrimaryElectron, processDummy, "processDummy", true);
11241457
};
11251458
struct associateAmbiguousElectron {
11261459
Produces<aod::EMAmbiguousElectronSelfIds> em_amb_ele_ids;

0 commit comments

Comments
 (0)