File indexing completed on 2025-08-03 08:20:24
0001 #ifndef MACRO_G4BEAMLINE_C
0002 #define MACRO_G4BEAMLINE_C
0003
0004 #include <GlobalVariables.C>
0005
0006 #include <G4_Pipe.C>
0007
0008 #include <g4detectors/BeamLineMagnetSubsystem.h>
0009 #include <g4detectors/PHG4BlockSubsystem.h>
0010 #include <g4detectors/PHG4ConeSubsystem.h>
0011 #include <g4detectors/PHG4CylinderSubsystem.h>
0012 #include <g4detectors/PHG4ZDCSubsystem.h>
0013 #include <g4detectors/PHG4DetectorSubsystem.h>
0014
0015 #include <g4main/PHG4Reco.h>
0016
0017 #include <TSystem.h>
0018
0019 R__LOAD_LIBRARY(libg4detectors.so)
0020
0021 float PosFlip(float pos);
0022 float AngleFlip(float angle);
0023 float MagFieldFlip(float Bfield);
0024
0025
0026 namespace Enable
0027 {
0028 bool BEAMLINE = false;
0029 bool BEAMLINE_ABSORBER = false;
0030 bool BEAMLINE_BLACKHOLE = false;
0031 bool BEAMLINE_OVERLAPCHECK = false;
0032 int BEAMLINE_VERBOSITY = 0;
0033
0034 }
0035
0036 namespace G4BEAMLINE
0037 {
0038
0039
0040 double starting_z = G4PIPE::max_z + 2*no_overlapp;
0041 double enclosure_z_max = 2050. + (800-starting_z);
0042 double enclosure_r_max = 30.;
0043 double enclosure_center = 0.5 * (starting_z + enclosure_z_max);
0044 double skin_thickness = 0.;
0045 int pipe_id_offset = 100;
0046 int roman_pot_pipe_id_offset = 200;
0047 PHG4CylinderSubsystem *ForwardBeamLineEnclosure(nullptr);
0048 PHG4CylinderSubsystem *BackwardBeamLineEnclosure(nullptr);
0049
0050 }
0051
0052 void BeamLineInit()
0053 {
0054 BlackHoleGeometry::min_z = std::min(BlackHoleGeometry::min_z, -G4BEAMLINE::enclosure_z_max);
0055 BlackHoleGeometry::max_z = std::max(BlackHoleGeometry::max_z, G4BEAMLINE::enclosure_z_max);
0056 BlackHoleGeometry::max_radius = std::max(BlackHoleGeometry::max_radius, G4BEAMLINE::enclosure_r_max);
0057 }
0058
0059 void BeamLineDefineMagnets(PHG4Reco *g4Reco)
0060 {
0061 bool overlapCheck = Enable::OVERLAPCHECK || Enable::BEAMLINE_OVERLAPCHECK;
0062 bool AbsorberActive = Enable::ABSORBER || Enable::BEAMLINE_ABSORBER;
0063
0064 int verbosity = std::max(Enable::VERBOSITY, Enable::BEAMLINE_VERBOSITY);
0065
0066 G4BEAMLINE::ForwardBeamLineEnclosure = new PHG4CylinderSubsystem("ForwardBeamLineEnclosure");
0067 G4BEAMLINE::ForwardBeamLineEnclosure->set_double_param("place_z", G4BEAMLINE::enclosure_center );
0068 G4BEAMLINE::ForwardBeamLineEnclosure->set_double_param("radius", 0);
0069 G4BEAMLINE::ForwardBeamLineEnclosure->set_double_param("thickness", G4BEAMLINE::enclosure_r_max);
0070 G4BEAMLINE::ForwardBeamLineEnclosure->set_double_param("length", G4BEAMLINE::enclosure_z_max - G4BEAMLINE::starting_z);
0071 G4BEAMLINE::ForwardBeamLineEnclosure->set_string_param("material", "G4_Galactic");
0072 G4BEAMLINE::ForwardBeamLineEnclosure->set_color(.5, .5, .5, 0.2);
0073 G4BEAMLINE::ForwardBeamLineEnclosure->OverlapCheck(overlapCheck);
0074 if (verbosity) G4BEAMLINE::ForwardBeamLineEnclosure->Verbosity(verbosity);
0075 g4Reco->registerSubsystem(G4BEAMLINE::ForwardBeamLineEnclosure);
0076
0077 G4BEAMLINE::BackwardBeamLineEnclosure = new PHG4CylinderSubsystem("BackwardBeamLineEnclosure");
0078 G4BEAMLINE::BackwardBeamLineEnclosure->set_double_param("place_z", -G4BEAMLINE::enclosure_center);
0079 G4BEAMLINE::BackwardBeamLineEnclosure->set_double_param("radius", 0);
0080 G4BEAMLINE::BackwardBeamLineEnclosure->set_double_param("thickness", G4BEAMLINE::enclosure_r_max);
0081 G4BEAMLINE::BackwardBeamLineEnclosure->set_double_param("length", G4BEAMLINE::enclosure_z_max - G4BEAMLINE::starting_z);
0082 G4BEAMLINE::BackwardBeamLineEnclosure->set_string_param("material", "G4_Galactic");
0083 G4BEAMLINE::BackwardBeamLineEnclosure->set_color(.5, .5, .5, 0.2);
0084 G4BEAMLINE::BackwardBeamLineEnclosure->OverlapCheck(overlapCheck);
0085 if (verbosity) G4BEAMLINE::BackwardBeamLineEnclosure->Verbosity(verbosity);
0086 g4Reco->registerSubsystem(G4BEAMLINE::BackwardBeamLineEnclosure);
0087
0088 string magFile;
0089 magFile = string(getenv("CALIBRATIONROOT")) + "/Beam/D0DXMagnets.dat";
0090
0091
0092 set<int> magnetlist;
0093
0094
0095 BeamLineMagnetSubsystem *bl = nullptr;
0096 std::ifstream infile(magFile);
0097 if (infile.is_open())
0098 {
0099 double biggest_z = 0.;
0100 int imagnet = 0;
0101 std::string line;
0102 while (std::getline(infile, line))
0103 {
0104 if (!line.compare(0, 1, "B") ||
0105 !line.compare(0, 1, "Q") ||
0106 !line.compare(0, 1, "S"))
0107 {
0108 std::istringstream iss(line);
0109 string magname;
0110 double x;
0111 double y;
0112 double z;
0113 double inner_radius_zin;
0114 double inner_radius_zout;
0115 double outer_magnet_diameter;
0116 double length;
0117 double angle;
0118 double dipole_field_x;
0119 double fieldgradient;
0120 if (!(iss >> magname >> x >> y >> z >> inner_radius_zin >> inner_radius_zout >> outer_magnet_diameter >> length >> angle >> dipole_field_x >> fieldgradient))
0121 {
0122 cout << "could not decode " << line << endl;
0123 gSystem->Exit(1);
0124 }
0125 else
0126 {
0127
0128
0129 string magtype;
0130 if (inner_radius_zin != inner_radius_zout)
0131 {
0132 cout << "inner radius at front of magnet " << inner_radius_zin
0133 << " not equal radius at back of magnet " << inner_radius_zout
0134 << " needs change in code (replace tube by cone for beamline)" << endl;
0135 gSystem->Exit(1);
0136 }
0137 if (verbosity > 0)
0138 {
0139 cout << endl
0140 << endl
0141 << "\tID number " << imagnet << endl;
0142 cout << "magname: " << magname << endl;
0143 cout << "x: " << x << endl;
0144 cout << "y: " << y << endl;
0145 cout << "z: " << z << endl;
0146 cout << "inner_radius_zin: " << inner_radius_zin << endl;
0147 cout << "inner_radius_zout: " << inner_radius_zout << endl;
0148 cout << "outer_magnet_diameter: " << outer_magnet_diameter << endl;
0149 cout << "length: " << length << endl;
0150 cout << "angle: " << angle << endl;
0151 cout << "dipole_field_x: " << dipole_field_x << endl;
0152 cout << "fieldgradient: " << fieldgradient << endl;
0153 }
0154 if (!magname.compare(0, 1, "B"))
0155 {
0156 magtype = "DIPOLE";
0157 }
0158 else if (!magname.compare(0, 1, "Q"))
0159 {
0160 magtype = "QUADRUPOLE";
0161 }
0162 else if (!magname.compare(0, 1, "S"))
0163 {
0164 magtype = "SEXTUPOLE";
0165 }
0166 else
0167 {
0168 cout << "cannot decode magnet name " << magname << endl;
0169 gSystem->Exit(1);
0170 }
0171
0172 x *= 100.;
0173 y *= 100.;
0174 z *= 100.;
0175 length *= 100.;
0176 inner_radius_zin *= 100.;
0177 outer_magnet_diameter *= 100.;
0178 angle = (angle / M_PI * 180.) / 1000.;
0179
0180
0181
0182 if (magnetlist.empty() || magnetlist.find(imagnet) != magnetlist.end())
0183 {
0184 bl = new BeamLineMagnetSubsystem("BEAMLINEMAGNET", imagnet);
0185 bl->set_double_param("field_y", MagFieldFlip(dipole_field_x));
0186 bl->set_double_param("fieldgradient", MagFieldFlip(fieldgradient));
0187 bl->set_string_param("magtype", magtype);
0188 bl->set_double_param("length", length);
0189 bl->set_double_param("place_x", PosFlip(x));
0190 bl->set_double_param("place_y", y);
0191 if (z > 0)
0192 {
0193 bl->set_double_param("place_z", z - G4BEAMLINE::enclosure_center);
0194 }
0195 else
0196 {
0197 bl->set_double_param("place_z", z + G4BEAMLINE::enclosure_center);
0198 }
0199 bl->set_double_param("field_global_position_x", PosFlip(x));
0200 bl->set_double_param("field_global_position_y", y);
0201 bl->set_double_param("field_global_position_z", z);
0202 bl->set_double_param("rot_y", AngleFlip(angle));
0203 bl->set_double_param("field_global_rot_y", AngleFlip(angle));
0204 bl->set_double_param("inner_radius", inner_radius_zin);
0205 bl->set_double_param("outer_radius", outer_magnet_diameter / 2.);
0206 bl->set_double_param("skin_thickness",G4BEAMLINE::skin_thickness);
0207 bl->SetActive(AbsorberActive);
0208 bl->SetAbsorberActive(AbsorberActive);
0209 if (Enable::BEAMLINE_BLACKHOLE) bl->BlackHole();
0210 if (z > 0)
0211 {
0212 bl->SetMotherSubsystem(G4BEAMLINE::ForwardBeamLineEnclosure);
0213 }
0214 else
0215 {
0216 bl->SetMotherSubsystem(G4BEAMLINE::BackwardBeamLineEnclosure);
0217 }
0218 bl->OverlapCheck(overlapCheck);
0219 bl->SuperDetector("BEAMLINEMAGNET");
0220 if (verbosity) bl->Verbosity(verbosity);
0221 g4Reco->registerSubsystem(bl);
0222 }
0223 imagnet++;
0224 if (fabs(z) + length > biggest_z)
0225 {
0226 biggest_z = fabs(z) + length;
0227 }
0228 }
0229 }
0230 }
0231 infile.close();
0232 }
0233 }
0234
0235 void BeamLineDefineBeamPipe(PHG4Reco *g4Reco)
0236 {
0237 bool OverlapCheck = Enable::OVERLAPCHECK || Enable::BEAMLINE_OVERLAPCHECK;
0238 bool AbsorberActive = Enable::ABSORBER || Enable::BEAMLINE_ABSORBER;
0239 int verbosity = std::max(Enable::VERBOSITY, Enable::BEAMLINE_VERBOSITY);
0240
0241 const int ntube = 10;
0242 const string nm[ntube] = {"B00", "B01", "B10", "B11", "B20", "B21", "B30", "B31", "B32", "B33"};
0243 const double qlen[ntube] = {233.8, 233.8, 118.7, 118.7, 217.16, 217.16, 182.5, 182.5, 182.5, 182.5};
0244 const double qir[ntube] = {6.08, 6.08, 14.60, 14.60, 20.0, 20.0, 6.07, 6.07, 6.07, 6.07};
0245 const double qor[ntube] = {6.35, 6.35, 15.24, 15.24, 20.96, 20.96, 6.35, 6.35, 6.35, 6.35};
0246 const double qrot[ntube] = {0, 0, 0, 0, 0, 0, 1.074, -1.074, -1.074, 1.074};
0247 const double qxC[ntube] = {0, 0, 0, 0, 0, 0, 12.820, -12.820, 12.820, -12.820};
0248 const double qyC[ntube] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0249 const double qzC[ntube] = {863.1, -863.1, 1474.470, -1474.470, 1642.4, -1642.4, 1843.2, 1843.2, -1843.2, -1843.2};
0250 for (int i = 0; i < ntube; i++)
0251 {
0252 string name = "beamPipe" + nm[i];
0253 PHG4CylinderSubsystem *pipe = new PHG4CylinderSubsystem(name, G4BEAMLINE::pipe_id_offset + i);
0254 if (Enable::BEAMLINE_BLACKHOLE) pipe->BlackHole();
0255 pipe->set_color(1,0,0,1.);
0256 pipe->set_double_param("radius", qir[i]);
0257 pipe->set_double_param("thickness", qor[i] - qir[i]);
0258 pipe->set_double_param("length", qlen[i]);
0259 pipe->set_double_param("rot_y", qrot[i]);
0260 pipe->set_string_param("material", "G4_STAINLESS-STEEL");
0261 pipe->set_double_param("place_x", PosFlip(qxC[i]));
0262 pipe->set_double_param("place_y", qyC[i]);
0263 if (qzC[i] > 0)
0264 {
0265 pipe->set_double_param("place_z", qzC[i] - G4BEAMLINE::enclosure_center);
0266 }
0267 else
0268 {
0269 pipe->set_double_param("place_z", qzC[i] + G4BEAMLINE::enclosure_center);
0270 }
0271 if (AbsorberActive) pipe->SetActive();
0272 pipe->SuperDetector("PIPE");
0273 if (qzC[i] > 0)
0274 {
0275 pipe->SetMotherSubsystem(G4BEAMLINE::ForwardBeamLineEnclosure);
0276 }
0277 else
0278 {
0279 pipe->SetMotherSubsystem(G4BEAMLINE::BackwardBeamLineEnclosure);
0280 }
0281
0282 pipe->OverlapCheck(OverlapCheck);
0283 g4Reco->registerSubsystem(pipe);
0284 }
0285
0286
0287 const int nSec = 2;
0288 const double len[nSec] = {20.87, 20.87};
0289 const double ir1[nSec] = {7.14, 14.60};
0290 const double or1[nSec] = {7.77, 15.24};
0291 const double ir2[nSec] = {14.60, 7.14};
0292 const double or2[nSec] = {15.24, 7.77};
0293 const double xC[nSec] = {0, 0};
0294 const double yC[nSec] = {0, 0};
0295 const double zC[nSec] = {1394.25, -1394.25};
0296 for (int i = 0; i < nSec; i++)
0297 {
0298 string name = "beamPipeRP" + to_string(i);
0299 PHG4ConeSubsystem *pipe = new PHG4ConeSubsystem(name, G4BEAMLINE::roman_pot_pipe_id_offset + i);
0300 pipe->set_string_param("material", "G4_STAINLESS-STEEL");
0301 pipe->set_double_param("place_x", PosFlip(xC[i]));
0302 pipe->set_double_param("place_y", yC[i]);
0303 if (zC[i] > 0)
0304 {
0305 pipe->set_double_param("place_z", zC[i] - G4BEAMLINE::enclosure_center);
0306 }
0307 else
0308 {
0309 pipe->set_double_param("place_z", zC[i] + G4BEAMLINE::enclosure_center);
0310 }
0311 pipe->set_double_param("length", len[i]);
0312 pipe->set_double_param("rmin1", ir1[i]);
0313 pipe->set_double_param("rmin2", ir2[i]);
0314 pipe->set_double_param("rmax1", or1[i]);
0315 pipe->set_double_param("rmax2", or2[i]);
0316 if (zC[i] > 0)
0317 {
0318 pipe->SetMotherSubsystem(G4BEAMLINE::ForwardBeamLineEnclosure);
0319 }
0320 else
0321 {
0322 pipe->SetMotherSubsystem(G4BEAMLINE::BackwardBeamLineEnclosure);
0323 }
0324 if (AbsorberActive) pipe->SetActive();
0325 if (Enable::BEAMLINE_BLACKHOLE) pipe->BlackHole();
0326 pipe->set_color(1,0,0,1.);
0327 pipe->SuperDetector("PIPE");
0328 pipe->OverlapCheck(OverlapCheck);
0329 g4Reco->registerSubsystem(pipe);
0330 }
0331 }
0332
0333 float PosFlip(float pos)
0334 {
0335 return pos;
0336 };
0337 float AngleFlip(float angle)
0338 {
0339 return angle;
0340 };
0341 float MagFieldFlip(float Bfield)
0342 {
0343 return Bfield;
0344 };
0345
0346 #endif