9 #include <geometry/modules/CreateFieldMapModule.h> 
   10 #include <framework/geometry/BFieldManager.h> 
   11 #include <framework/utilities/Utils.h> 
   12 #include <framework/gearbox/Unit.h> 
   14 #include <Math/Vector3D.h> 
   15 #include <Math/VectorUtil.h> 
   20 #include <boost/algorithm/string.hpp> 
   21 #include <boost/format.hpp> 
   36   setDescription(
"Create Field maps of the Belle II magnetic field used in the simulation");
 
   39   addParam(
"filename", 
m_filename, 
"ROOT filename for the map", std::string(
"FieldMap.root"));
 
   40   addParam(
"type", 
m_type, 
"type of the fieldmap (xy, zx, zy, zr)", std::string(
"zx"));
 
   41   addParam(
"nU", 
m_nU, 
"number of steps along first coordinate", 1800);
 
   42   addParam(
"minU", 
m_minU, 
"minimum value for the first coordinate", -400.);
 
   43   addParam(
"maxU", 
m_maxU, 
"maximum value for the first coordinate", 500.);
 
   44   addParam(
"nV", 
m_nV, 
"number of steps along second coordinate", 1600);
 
   45   addParam(
"minV", 
m_minV, 
"minimum value for the second coordinate", -400.);
 
   46   addParam(
"maxV", 
m_maxV, 
"maximum value for the second coordinate", 400.);
 
   47   addParam(
"phi", 
m_phi, 
"phi angle for the scan in radians", 0.);
 
   51            "WARNING: output can be huge", 
false);
 
   57     B2WARNING(
"CreateFieldMap: No Filename given, just sampling for fun");
 
   62     B2ERROR(
"CreateFieldMap type '" << 
m_type << 
"' not valid, use one of 'xy', 'zx', 'zy' or 'zr'");
 
   65     B2ERROR(
"Number of steps has to be positive");
 
   68     B2ERROR(
"Range for first coordinate is zero");
 
   73     B2ERROR(
"Range for second coordinate is zero");
 
   79       B2ERROR(
"R values (minV, maxV) must be positive");
 
   82       B2ERROR(
"Number of steps in phi must be positive");
 
   90   TFile* outfile{
nullptr};
 
   93     outfile = 
new TFile(
m_filename.c_str(), 
"RECREATE");
 
  111   auto showProgress = [&]() {
 
  113     const int64_t donePercent = 100 * ++curStep / nSteps;
 
  114     if (donePercent > lastPercent) {
 
  116       const double perStep = totalTime / curStep;
 
  117       if (donePercent == 100) {
 
  118         B2INFO(boost::format(
"BField %s Scan: %d samples, %.3f us per sample, total: %.2f seconds")
 
  122         B2INFO(boost::format(
"BField %s Scan: %3d%%, %.3f us per sample")
 
  126       lastPercent = donePercent;
 
  130   struct { 
float x{0}, y{0}, z{0}, bx{0}, by{0}, bz{0}; } field_point;
 
  131   TTree* all_values{
nullptr};
 
  133     all_values = 
new TTree(
"bfield_values", 
"All B field values");
 
  134     all_values->Branch(
"x", &field_point.x, 
"x/F");
 
  135     all_values->Branch(
"y", &field_point.y, 
"y/F");
 
  136     all_values->Branch(
"z", &field_point.z, 
"z/F");
 
  137     all_values->Branch(
"bx", &field_point.bx, 
"bx/F");
 
  138     all_values->Branch(
"by", &field_point.by, 
"by/F");
 
  139     all_values->Branch(
"bz", &field_point.bz, 
"bz/F");
 
  141   auto fillTree = [&](
const ROOT::Math::XYZVector & p, 
const ROOT::Math::XYZVector & b) {
 
  142     if (!all_values) 
return;
 
  143     field_point.x = p.X();
 
  144     field_point.y = p.Y();
 
  145     field_point.z = p.Z();
 
  146     field_point.bx = b.X();
 
  147     field_point.by = b.Y();
 
  148     field_point.bz = b.Z();
 
  157     for (
int iU = 0; iU < 
m_nU; ++iU) {
 
  158       for (
int iV = 0; iV < 
m_nV; ++iV) {
 
  160         const double u = h_b->GetXaxis()->GetBinCenter(iU + 1);
 
  161         const double v = h_b->GetYaxis()->GetBinCenter(iV + 1);
 
  163         for (
int iPhi = 0; iPhi < 
m_nPhi; ++iPhi) {
 
  164           ROOT::Math::XYZVector pos(v, 0, u);
 
  165           pos = ROOT::Math::VectorUtil::RotateZ(pos, 2 * M_PI * iPhi / 
m_nPhi);
 
  170             h_br->Fill(u, v, bfield.Rho());
 
  171             h_bz->Fill(u, v, bfield.Z());
 
  172             h_b->Fill(u, v, bfield.R());
 
  173             fillTree(pos, bfield);
 
  181       for (TH2D* h : {h_br, h_bz, h_b}) {
 
  187     const std::string nu = 
m_type.substr(0, 1);
 
  188     const std::string nv = 
m_type.substr(1, 1);
 
  195     for (
int iU = 0; iU < 
m_nU; ++iU) {
 
  196       for (
int iV = 0; iV < 
m_nV; ++iV) {
 
  197         ROOT::Math::XYZVector pos(0, 0, 0);
 
  199         const double u = h_bx->GetXaxis()->GetBinCenter(iU + 1);
 
  200         const double v = h_bx->GetYaxis()->GetBinCenter(iV + 1);
 
  215         pos = ROOT::Math::VectorUtil::RotateZ(pos, 
m_phi);
 
  220           h_bx->Fill(u, v, bfield.X());
 
  221           h_by->Fill(u, v, bfield.Y());
 
  222           h_bz->Fill(u, v, bfield.Z());
 
  223           h_b->Fill(u, v, bfield.R());
 
  224           fillTree(pos, bfield);
 
  231       for (TH2D* h : {h_bx, h_by, h_bz, h_b}) {
 
  237     if (all_values) all_values->Write();
 
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
int m_nPhi
number of steps in phi
virtual void initialize() override
Check input parameters.
double m_minV
start value for the first coordinate
double m_wOffset
offset on the third coordinate
double m_minU
start value for the first coordinate
double m_phi
phi rotation when sampling magnetic field (value of pi will convert ZX to ZY scan)
int m_nV
number of steps along the second coordinate
int m_nU
number of steps along the first coordinate
std::string m_type
type of the fieldmap (zx, zy, zr)
double m_maxV
end value for the first coordinate
virtual void beginRun() override
Create the fieldmap.
std::string m_filename
output filename for the fieldmap
EFieldTypes
Types of Fieldmap to be created.
@ c_ZX
scan along ZX plane
@ c_ZY
scan along ZY plane
@ c_ZR
scan along Z and R, averaging over phi
@ c_XY
scan along XY plane
double m_maxU
end value for the first coordinate
bool m_createTree
if true create a TTree with all sampled points
CreateFieldMapModule()
Constructor: Sets the description, the properties and the parameters of the module.
void setDescription(const std::string &description)
Sets the description of the module.
static const double us
[microsecond]
static const double s
[second]
REG_MODULE(B2BIIConvertBeamParams)
Register the module.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
double getClock()
Return current value of the real-time clock.
Abstract base class for different kinds of events.