Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Common/SimConfig/include/SimConfig/SimConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct SimConfigData {
bool mNoGeant = false; // if Geant transport should be turned off (when one is only interested in the generated events)
bool mIsUpgrade = false; // true if the simulation is for Run 5
std::string mFromCollisionContext = ""; // string denoting a collision context file; If given, this file will be used to determine number of events
//
bool mForwardKine = false; // true if tracks and event headers are to be published on a FairMQ channel (for reading by other consumers)
bool mWriteToDisc = true; // whether we write simulation products (kine, hits) to disc
VertexMode mVertexMode = VertexMode::kDiamondParam; // by default we should use die InteractionDiamond parameter
Expand Down Expand Up @@ -177,6 +178,10 @@ class SimConfig
bool writeToDisc() const { return mConfigData.mWriteToDisc; }
VertexMode getVertexMode() const { return mConfigData.mVertexMode; }

// returns the pair of collision context filename as well as event prefix encoded
// in the mFromCollisionContext string. Returns empty string if information is not available or set.
std::pair<std::string, std::string> getCollContextFilenameAndEventPrefix() const;

private:
SimConfigData mConfigData; //!

Expand Down
30 changes: 18 additions & 12 deletions Common/SimConfig/src/SimConfig.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void SimConfig::initOptions(boost::program_options::options_description& options
"noGeant", bpo::bool_switch(), "prohibits any Geant transport/physics (by using tight cuts)")(
"forwardKine", bpo::bool_switch(), "forward kinematics on a FairMQ channel")(
"noDiscOutput", bpo::bool_switch(), "switch off writing sim results to disc (useful in combination with forwardKine)");
options.add_options()("fromCollContext", bpo::value<std::string>()->default_value(""), "Use a pregenerated collision context to infer number of events to simulate, how to embedd them, the vertex position etc. Takes precedence of other options such as \"--nEvents\".");
options.add_options()("fromCollContext", bpo::value<std::string>()->default_value(""), "Use a pregenerated collision context to infer number of events to simulate, how to embedd them, the vertex position etc. Takes precedence of other options such as \"--nEvents\". The format is COLLISIONCONTEXTFILE.root[:SIGNALNAME] where SIGNALNAME is the event part in the context which is relevant.");
}

void SimConfig::determineActiveModules(std::vector<std::string> const& inputargs, std::vector<std::string> const& skippedModules, std::vector<std::string>& activeModules, bool isUpgrade)
Expand Down Expand Up @@ -270,6 +270,21 @@ void SimConfig::determineReadoutDetectors(std::vector<std::string> const& active
}
}

std::pair<std::string, std::string> SimConfig::getCollContextFilenameAndEventPrefix() const
{
// we decompose the argument to fetch
// (a) collision contextfilename
// (b) sim prefix to use from the context
auto pos = mConfigData.mFromCollisionContext.find(':');
std::string collcontextfile{mConfigData.mFromCollisionContext};
std::string simprefix{mConfigData.mOutputPrefix};
if (pos != std::string::npos) {
collcontextfile = mConfigData.mFromCollisionContext.substr(0, pos);
simprefix = mConfigData.mFromCollisionContext.substr(pos + 1);
}
return std::make_pair(collcontextfile, simprefix);
}

bool SimConfig::resetFromParsedMap(boost::program_options::variables_map const& vm)
{
using o2::detectors::DetID;
Expand Down Expand Up @@ -333,17 +348,8 @@ bool SimConfig::resetFromParsedMap(boost::program_options::variables_map const&
mConfigData.mFilterNoHitEvents = true;
}
mConfigData.mFromCollisionContext = vm["fromCollContext"].as<std::string>();
// we decompose the argument to fetch
// (a) collision contextfilename
// (b) sim prefix to use from the context
auto pos = mConfigData.mFromCollisionContext.find(':');
std::string collcontextfile{mConfigData.mFromCollisionContext};
std::string simprefix{mConfigData.mOutputPrefix};
if (pos != std::string::npos) {
collcontextfile = mConfigData.mFromCollisionContext.substr(0, pos);
simprefix = mConfigData.mFromCollisionContext.substr(pos + 1);
}
adjustFromCollContext(collcontextfile, simprefix);
auto collcontext_simprefix = getCollContextFilenameAndEventPrefix();
adjustFromCollContext(collcontext_simprefix.first, collcontext_simprefix.second);

// analyse vertex options
if (!parseVertexModeString(vm["vertexMode"].as<std::string>(), mConfigData.mVertexMode)) {
Expand Down
2 changes: 2 additions & 0 deletions DataFormats/simulation/src/DigitizationContext.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -578,5 +578,7 @@ DigitizationContext DigitizationContext::extractSingleTimeframe(int timeframeid,
} catch (std::exception) {
LOG(warn) << "No such timeframe id in collision context. Returing empty object";
}
// fix number of collisions
r.setNCollisions(r.mEventRecords.size());
return r;
}
48 changes: 34 additions & 14 deletions Steer/src/CollisionContextTool.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "CommonUtils/ConfigurableParam.h"
#include <CCDB/BasicCCDBManager.h>
#include "DataFormatsParameters/GRPLHCIFData.h"
#include "SimConfig/SimConfig.h"

//
// Created by Sandro Wenzel on 13.07.21.
Expand All @@ -52,11 +53,12 @@ struct Options {
bool useexistingkinematics = false;
bool noEmptyTF = false; // prevent empty timeframes; the first interaction will be shifted backwards to fall within the range given by Options.orbits
int maxCollsPerTF = -1; // the maximal number of hadronic collisions per TF (can be used to constrain number of collisions per timeframe to some maximal value)
bool genVertices = false; // whether to assign vertices to collisions
std::string configKeyValues = ""; // string to init config key values
long timestamp = -1; // timestamp for CCDB queries
std::string individualTFextraction = ""; // triggers extraction of individuel timeframe components when non-null
// format is path prefix
std::string vertexModeString{"kNoVertex"}; // Vertex Mode; vertices will be assigned to collisions of mode != kNoVertex
o2::conf::VertexMode vertexMode = o2::conf::VertexMode::kNoVertex;
};

enum class InteractionLockMode {
Expand Down Expand Up @@ -203,7 +205,9 @@ bool parseOptions(int argc, char* argv[], Options& optvalues)
"first-orbit", bpo::value<double>(&optvalues.firstFractionalOrbit)->default_value(0), "First (fractional) orbit in the run (HBFUtils.firstOrbit + BC from decimal)")(
"maxCollsPerTF", bpo::value<int>(&optvalues.maxCollsPerTF)->default_value(-1), "Maximal number of MC collisions to put into one timeframe. By default no constraint.")(
"noEmptyTF", bpo::bool_switch(&optvalues.noEmptyTF), "Enforce to have at least one collision")(
"configKeyValues", bpo::value<std::string>(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")("with-vertices", "Assign vertices to collisions.")("timestamp", bpo::value<long>(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring")(
"configKeyValues", bpo::value<std::string>(&optvalues.configKeyValues)->default_value(""), "Semicolon separated key=value strings (e.g.: 'TPC.gasDensity=1;...')")(
"with-vertices", bpo::value<std::string>(&optvalues.vertexModeString)->default_value("kNoVertex"), "Assign vertices to collisions. Argument is the vertex mode. Defaults to no vertexing applied")(
"timestamp", bpo::value<long>(&optvalues.timestamp)->default_value(-1L), "Timestamp for CCDB queries / anchoring")(
"extract-per-timeframe", bpo::value<std::string>(&optvalues.individualTFextraction)->default_value(""),
"Extract individual timeframe contexts. Format required: time_frame_prefix[:comma_separated_list_of_signals_to_offset]");

Expand All @@ -225,9 +229,8 @@ bool parseOptions(int argc, char* argv[], Options& optvalues)
if (vm.count("use-existing-kine")) {
optvalues.useexistingkinematics = true;
}
if (vm.count("with-vertices")) {
optvalues.genVertices = true;
}

o2::conf::SimConfig::parseVertexModeString(optvalues.vertexModeString, optvalues.vertexMode);

// fix the first orbit and bunch crossing
// auto orbitbcpair = parseOrbitAndBC(optvalues.firstIRString);
Expand Down Expand Up @@ -277,10 +280,9 @@ int main(int argc, char* argv[])
LOG(info) << "Fetch bcPattern information from CCDB";
// fetch the GRP Object
auto& ccdb = o2::ccdb::BasicCCDBManager::instance();
ccdb.setTimestamp(options.timestamp);
ccdb.setCaching(false);
ccdb.setLocalObjectValidityChecking(true);
auto grpLHC = ccdb.get<o2::parameters::GRPLHCIFData>("GLO/Config/GRPLHCIF");
auto grpLHC = ccdb.getForTimeStamp<o2::parameters::GRPLHCIFData>("GLO/Config/GRPLHCIF", options.timestamp);
LOG(info) << "Fetched injection scheme " << grpLHC->getInjectionScheme() << " from CCDB";
sampler.setBunchFilling(grpLHC->getBunchFilling());
} else {
Expand Down Expand Up @@ -449,14 +451,32 @@ int main(int argc, char* argv[])

auto numTimeFrames = digicontext.finalizeTimeframeStructure(orbitstart, options.orbitsPerTF);

if (options.genVertices) {
// TODO: offer option taking meanVertex directly from CCDB ! "GLO/Calib/MeanVertex"
// sample interaction vertices
if (options.vertexMode != o2::conf::VertexMode::kNoVertex) {
switch (options.vertexMode) {
case o2::conf::VertexMode::kCCDB: {
// fetch mean vertex from CCDB
auto meanv = o2::ccdb::BasicCCDBManager::instance().getForTimeStamp<o2::dataformats::MeanVertexObject>("GLO/Calib/MeanVertex", options.timestamp);
if (meanv) {
LOG(info) << "Applying vertexing using CCDB mean vertex " << *meanv;
digicontext.sampleInteractionVertices(*meanv);
} else {
LOG(fatal) << "No vertex available";
}
break;
}

// init this vertex from CCDB or InteractionDiamond parameter
const auto& dparam = o2::eventgen::InteractionDiamondParam::Instance();
o2::dataformats::MeanVertexObject meanv(dparam.position[0], dparam.position[1], dparam.position[2], dparam.width[0], dparam.width[1], dparam.width[2], dparam.slopeX, dparam.slopeY);
digicontext.sampleInteractionVertices(meanv);
case o2::conf::VertexMode::kDiamondParam: {
// init this vertex from CCDB or InteractionDiamond parameter
const auto& dparam = o2::eventgen::InteractionDiamondParam::Instance();
o2::dataformats::MeanVertexObject meanv(dparam.position[0], dparam.position[1], dparam.position[2], dparam.width[0], dparam.width[1], dparam.width[2], dparam.slopeX, dparam.slopeY);
LOG(info) << "Applying vertexing using DiamondParam mean vertex " << meanv;
digicontext.sampleInteractionVertices(meanv);
break;
}
default: {
LOG(error) << "Unknown vertex mode ... Not generating vertices";
}
}
}

// we fill QED contributions to the context
Expand Down
5 changes: 3 additions & 2 deletions run/O2PrimaryServerDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ class O2PrimaryServerDevice final : public fair::mq::Device
mPrimGen->SetEvent(&mEventHeader);

// A good moment to couple to collision context
auto collContextFileName = mSimConfig.getConfigData().mFromCollisionContext;
auto collContextFileName_PrefixPair = mSimConfig.getCollContextFilenameAndEventPrefix();
auto collContextFileName = collContextFileName_PrefixPair.first;
if (collContextFileName.size() > 0) {
LOG(info) << "Simulation has collission context";
mCollissionContext = o2::steer::DigitizationContext::loadFromFile(collContextFileName);
Expand All @@ -147,7 +148,7 @@ class O2PrimaryServerDevice final : public fair::mq::Device
LOG(info) << "We found " << vertices.size() << " vertices included ";

// initialize the eventID to collID mapping
const auto source = mCollissionContext->findSimPrefix(mSimConfig.getOutPrefix());
const auto source = mCollissionContext->findSimPrefix(collContextFileName_PrefixPair.second);
if (source == -1) {
LOG(fatal) << "Wrong simulation prefix";
}
Expand Down