diff --git a/PWGCF/Flow/Tasks/CMakeLists.txt b/PWGCF/Flow/Tasks/CMakeLists.txt index c3c7d9b566e..bb658dc7398 100644 --- a/PWGCF/Flow/Tasks/CMakeLists.txt +++ b/PWGCF/Flow/Tasks/CMakeLists.txt @@ -33,3 +33,8 @@ o2physics_add_dpl_workflow(flow-gf SOURCES flowAnalysisGF.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore COMPONENT_NAME Analysis) + +o2physics_add_dpl_workflow(flow-pbpb-pikp-task + SOURCES FlowPbPbpikp.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore + COMPONENT_NAME Analysis) diff --git a/PWGCF/Flow/Tasks/FlowPbPbpikp.cxx b/PWGCF/Flow/Tasks/FlowPbPbpikp.cxx new file mode 100644 index 00000000000..dbe1e308b08 --- /dev/null +++ b/PWGCF/Flow/Tasks/FlowPbPbpikp.cxx @@ -0,0 +1,486 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +/// +/// \brief this is a code for the elliptic flow of identified hadrons +/// \author prottay das, preet +/// \since 29/05/2024 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "CCDB/BasicCCDBManager.h" +#include "CCDB/CcdbApi.h" +#include "Common/Core/TrackSelection.h" +#include "Common/Core/trackUtilities.h" +#include "Common/DataModel/Centrality.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/Multiplicity.h" +#include "Common/DataModel/PIDResponse.h" +#include "Common/DataModel/TrackSelectionTables.h" +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/StepTHn.h" +#include "Framework/runDataProcessing.h" +#include "PWGLF/DataModel/LFStrangenessTables.h" +#include "ReconstructionDataFormats/Track.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; +using std::array; + +struct v2ellip { + + // Connect to ccdb + Service ccdb; + Configurable nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"}; + Configurable url{"ccdb-url", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"}; + + SliceCache cache; + + // Histograms are defined with HistogramRegistry + HistogramRegistry rEventSelection{"eventSelection", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject, true, true}; + + // Confugrable for QA histograms + Configurable onlyTOF{"onlyTOF", false, "only TOF tracks"}; + Configurable onlyTOFHIT{"onlyTOFHIT", false, "accept only TOF hit tracks at high pt"}; + Configurable onlyTPC{"onlyTPC", true, "only TPC tracks"}; + + // Configurables for track selections + Configurable cfgCutPT{"cfgCutPT", 0.2f, "PT cut on daughter track"}; + Configurable cfgCutEta{"cfgCutEta", 0.8f, "Eta cut on daughter track"}; + Configurable cfgCutDCAxy{"cfgCutDCAxy", 2.0f, "DCAxy range for tracks"}; + Configurable cfgCutDCAz{"cfgCutDCAz", 2.0f, "DCAz range for tracks"}; + Configurable nsigmaCutTPCPi{"nsigmacutTPCPi", 3.0, "Value of the TPC Nsigma cut for pions"}; + Configurable nsigmaCutTPCKa{"nsigmacutTPCKa", 3.0, "Value of the TPC Nsigma cut for kaons"}; + Configurable nsigmaCutTPCPr{"nsigmacutTPCPr", 3.0, "Value of the TPC Nsigma cut for protons"}; + Configurable nsigmaCutTOFPi{"nsigmacutTOFPi", 3.0, "Value of the TOF Nsigma cut for pions"}; + Configurable nsigmaCutTOFKa{"nsigmacutTOFKa", 3.0, "Value of the TOF Nsigma cut for kaons"}; + Configurable nsigmaCutTOFPr{"nsigmacutTOFPr", 3.0, "Value of the TOF Nsigma cut for protons"}; + Configurable nsigmaCutCombined{"nsigmaCutCombined", 3.0, "Value of the Combined Nsigma cut"}; + Configurable ismanualDCAcut{"ismanualDCAcut", true, "ismanualDCAcut"}; + Configurable cfgITScluster{"cfgITScluster", 0, "Number of ITS cluster"}; + Configurable cfgTPCcluster{"cfgTPCcluster", 70, "Number of TPC cluster"}; + + // Event selection configurables + Configurable timFrameEvsel{"timFrameEvsel", false, "TPC Time frame boundary cut"}; + Configurable TVXEvsel{"TVXEvsel", false, "Triggger selection"}; + Configurable cutzvertex{"cutzvertex", 10.0f, "Accepted z-vertex range (cm)"}; + Configurable MID{"MID", false, "Misidentification of tracks"}; + + // Configurable for histograms + Configurable nBins{"nBins", 100, "N bins in all histos"}; + ConfigurableAxis binsMultPlot{"binsCent", {201, -0.5f, 200.5f}, "Binning of the centrality axis for plots"}; + + void init(InitContext const&) + { + // Axes + AxisSpec vertexZAxis = {nBins, -15., 15., "vrtx_{Z} [cm] for plots"}; + AxisSpec axisv2ref = {5, 0, 5, "v2_{ref}"}; + AxisSpec axisv2diff = {14, 0, 14, "v2_{def}"}; + + // Histograms + // Event selection + rEventSelection.add("hVertexZRec", "hVertexZRec", {HistType::kTH1F, {vertexZAxis}}); + rEventSelection.add("hmult", "Centrality distribution", kTH1F, {{binsMultPlot}}); + + // v2 tprofiles for reference and differential flow + histos.add("profv2ref", "profv2ref", kTProfile, {axisv2ref}); + histos.add("profv2diff_pr", "profv2diff_pr", kTProfile, {axisv2diff}); + histos.add("profv2diff_pi", "profv2diff_pi", kTProfile, {axisv2diff}); + histos.add("profv2diff_k", "profv2diff_k", kTProfile, {axisv2diff}); + } + + template + bool selectionTrack(const T& candidate) + { + if (ismanualDCAcut && !(candidate.isGlobalTrackWoDCA() && candidate.isPVContributor() && std::abs(candidate.dcaXY()) < cfgCutDCAxy && std::abs(candidate.dcaZ()) < cfgCutDCAz && candidate.itsNCls() > cfgITScluster && candidate.tpcNClsFound() > cfgTPCcluster)) { + return false; + } + + return true; + } + + template + bool selectionPID(const T& candidate, int PID) + { + if (PID == 0) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOFPi) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < nsigmaCutTOFPi) { + return true; + } + if (!candidate.hasTOF() && + std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (nsigmaCutCombined * nsigmaCutCombined)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < nsigmaCutTPCPi) { + return true; + } + } + } else if (PID == 1) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOFKa) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < nsigmaCutTOFKa) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (nsigmaCutCombined * nsigmaCutCombined)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < nsigmaCutTPCKa) { + return true; + } + } + } else if (PID == 2) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < nsigmaCutTOFPr) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < nsigmaCutTOFPr) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < nsigmaCutTPCPr) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPr()) < nsigmaCutTPCPr) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPr() * candidate.tofNSigmaPr() + candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr()) < (nsigmaCutCombined * nsigmaCutCombined)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < nsigmaCutTPCPr) { + return true; + } + } + } + return false; + } + + template + bool MIDselectionPID(const T& candidate, int PID) + { + if (PID == 0) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < 3.0) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPi()) < 3.0) { + return true; + } + if (!candidate.hasTOF() && + std::abs(candidate.tpcNSigmaPi()) < 3.0) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPi()) < 3.0) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPi() * candidate.tofNSigmaPi() + candidate.tpcNSigmaPi() * candidate.tpcNSigmaPi()) < (3.0 * 3.0)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPi()) < 3.0) { + return true; + } + } + } else if (PID == 1) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < 3.0) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaKa()) < 3.0) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < 3.0) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaKa()) < 3.0) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaKa() * candidate.tofNSigmaKa() + candidate.tpcNSigmaKa() * candidate.tpcNSigmaKa()) < (3.0 * 3.0)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaKa()) < 3.0) { + return true; + } + } + } else if (PID == 2) { + if (onlyTOF) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < 3.0) { + return true; + } + } else if (onlyTOFHIT) { + if (candidate.hasTOF() && std::abs(candidate.tofNSigmaPr()) < 3.0) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < 3.0) { + return true; + } + } else if (onlyTPC) { + if (std::abs(candidate.tpcNSigmaPr()) < 3.0) { + return true; + } + } else { + if (candidate.hasTOF() && (candidate.tofNSigmaPr() * candidate.tofNSigmaPr() + candidate.tpcNSigmaPr() * candidate.tpcNSigmaPr()) < (3.0 * 3.0)) { + return true; + } + if (!candidate.hasTOF() && std::abs(candidate.tpcNSigmaPr()) < 3.0) { + return true; + } + } + } + return false; + } + + // Defining filters for events (event selection) + // Processed events will be already fulfilling the event selection + // requirements + + Filter posZFilter = (nabs(o2::aod::collision::posZ) < cutzvertex); + Filter acceptanceFilter = (nabs(aod::track::eta) < cfgCutEta && nabs(aod::track::pt) > cfgCutPT); + Filter DCAcutFilter = (nabs(aod::track::dcaXY) < cfgCutDCAxy) && (nabs(aod::track::dcaZ) < cfgCutDCAz); + + using EventCandidates = soa::Filtered>; + using TrackCandidates = soa::Filtered>; + + // Defining partitions for subevents for eta-gap method + Partition Atracks = (aod::track::eta > 0.4f) && (aod::track::eta < 0.8f); // partition for subevent A + Partition Btracks = (aod::track::eta < -0.4f) && (aod::track::eta > -0.8f); // partition for subevent B + + array ptbins = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.4, 1.8, 2.2, 2.6, 3.0, 3.5, 4.0, 4.5, 5.0}; + + void processSE(EventCandidates::iterator const& collision, TrackCandidates const& tracks, aod::BCs const&) + + { + float sum_sinA = 0.0, sum_cosA = 0.0, sum_sinB = 0.0, sum_cosB = 0.0; + int multA = 0, multB = 0; + + // Q vector elements + array sum_sindsA = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // sin component of Q vector for subevent A + array sum_cosdsA = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // cos component of Q vector for subevent A + array sum_sindsB = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // sin component of Q vector for subevent B + array sum_cosdsB = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // cos component of Q vector for subevent B + + // p vector definitions for subevent A + array pn_sumsinA_pr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for proton + array pn_sumcosA_pr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for proton + + array pn_sumsinA_pi = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for pion + array pn_sumcosA_pi = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for pion + + array pn_sumsinA_k = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for kaon + array pn_sumcosA_k = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for kaon + + // p vector definitions for subevent B + array pn_sumsinB_pr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for proton + array pn_sumcosB_pr = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for proton + + array pn_sumsinB_pi = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for pion + array pn_sumcosB_pi = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for pion + + array pn_sumsinB_k = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for kaon + array pn_sumcosB_k = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; // to store ptwise pn vector components for kaon + + // POI multiplicities + array mpA_pr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // proton multiplicity for subevent A + array mpB_pr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // proton multiplicity for subevent B + + array mpA_pi = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // pion multiplicity for subevent A + array mpB_pi = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // pion multiplicity for subevent B + + array mpA_k = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // kaon multiplicity for subevent A + array mpB_k = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // kaon multiplicity for subevent B + + if (!collision.sel8()) { + return; + } + + if (timFrameEvsel && (!collision.selection_bit(aod::evsel::kNoTimeFrameBorder) || !collision.selection_bit(aod::evsel::kNoITSROFrameBorder))) { + return; + } + + if (TVXEvsel && (!collision.selection_bit(aod::evsel::kIsTriggerTVX))) { + return; + } + + float multiplicity = 0.0f; + multiplicity = collision.centFT0C(); + + // Fill the event counter + rEventSelection.fill(HIST("hVertexZRec"), collision.posZ()); + rEventSelection.fill(HIST("hmult"), multiplicity); + + auto atrack = Atracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + auto btrack = Btracks->sliceByCached(aod::track::collisionId, collision.globalIndex(), cache); + + for (auto track1 : atrack) { + if (!selectionTrack(track1)) { + continue; + } + + if (!selectionPID(track1, 0) && !selectionPID(track1, 1) && !selectionPID(track1, 2)) { + continue; + } // If track not pion, kaon and proton then discard the track + + if (MID) { + if (MIDselectionPID(track1, 0)) { + continue; + } // misidentified as pion + if (MIDselectionPID(track1, 2)) { + continue; + } // misidentified as proton + } + + sum_sinA += TMath::Sin(2.0 * track1.phi()); // sum of sin components of Q vector + sum_cosA += TMath::Cos(2.0 * track1.phi()); // sum of cos components of Q vector + multA++; // charged particle multiplicity + + // pt loop for component sums of p vector, POI multiplicities pt wise + for (auto pt = 0; pt < 14; pt++) { + sum_sindsA[pt] += TMath::Sin(2 * track1.phi()); + sum_cosdsA[pt] += TMath::Cos(2 * track1.phi()); + + if (track1.pt() > ptbins[pt] && track1.pt() <= ptbins[pt + 1] && selectionPID(track1, 2)) { + pn_sumsinA_pr[pt] += TMath::Sin(2 * track1.phi()); + pn_sumcosA_pr[pt] += TMath::Cos(2 * track1.phi()); + mpA_pr[pt]++; + } else if (track1.pt() > ptbins[pt] && track1.pt() <= ptbins[pt + 1] && selectionPID(track1, 0)) { + pn_sumsinA_pi[pt] += TMath::Sin(2 * track1.phi()); + pn_sumcosA_pi[pt] += TMath::Cos(2 * track1.phi()); + mpA_pi[pt]++; + } else if (track1.pt() > ptbins[pt] && track1.pt() <= ptbins[pt + 1] && selectionPID(track1, 1)) { + pn_sumsinA_k[pt] += TMath::Sin(2 * track1.phi()); + pn_sumcosA_k[pt] += TMath::Cos(2 * track1.phi()); + mpA_k[pt]++; + } else { + continue; + } + } // end of pt loop + } // track loop ends + + for (auto track2 : btrack) { + if (!selectionTrack(track2)) { + continue; + } + + if (!selectionPID(track2, 0) && !selectionPID(track2, 1) && !selectionPID(track2, 2)) { + continue; + } // If track not pion, kaon and proton then discard the track + + if (MID) { + if (MIDselectionPID(track2, 1)) { + continue; + } // misidentified as kaon + } + + sum_sinB += TMath::Sin(2.0 * track2.phi()); // sum of sin components of Q vector + sum_cosB += TMath::Cos(2.0 * track2.phi()); // sum of cos components of Q vector + multB++; // charged particle multiplicity + + // pt loop for component sums of p vector, POI multiplicities pt wise + for (auto pt = 0; pt < 14; pt++) { + sum_sindsB[pt] += TMath::Sin(2 * track2.phi()); + sum_cosdsB[pt] += TMath::Cos(2 * track2.phi()); + + if (track2.pt() > ptbins[pt] && track2.pt() <= ptbins[pt + 1] && selectionPID(track2, 2)) { + pn_sumsinB_pr[pt] += TMath::Sin(2 * track2.phi()); + pn_sumcosB_pr[pt] += TMath::Cos(2 * track2.phi()); + mpB_pr[pt]++; + } else if (track2.pt() > ptbins[pt] && track2.pt() <= ptbins[pt + 1] && selectionPID(track2, 0)) { + pn_sumsinB_pi[pt] += TMath::Sin(2 * track2.phi()); + pn_sumcosB_pi[pt] += TMath::Cos(2 * track2.phi()); + mpB_pi[pt]++; + } else if (track2.pt() > ptbins[pt] && track2.pt() <= ptbins[pt + 1] && selectionPID(track2, 1)) { + pn_sumsinB_k[pt] += TMath::Sin(2 * track2.phi()); + pn_sumcosB_k[pt] += TMath::Cos(2 * track2.phi()); + mpB_k[pt]++; + } else { + continue; + } + } // end of pt loop + + } // track loop ends + + // std::cout<<"MultA: "<(cfgc)}; +}