I am using Windows 11 OS, and trying to run some simulation of a MR-linac, and the "mingle" is very helpful for running some preliminary tests. I adapted the "target.tg" and update the contents as below:
// define a 5x4x6 m3 cubic hall filled with air
:volu hall BOX 2.5m 2m 3*m G4_AIR
:vis hall OFF
// define a cylindrical MR_Bore filled with air
:volu MR_Bore TUBE 0.0cm 46.55cm 30*cm G4_AIR
:color MR_Bore 0.9 0.9 0.9
:vis MR_Bore ON
// Define a box beamScan of Water tank wall, just as water at this time.
:volu beamScan BOX 30.4cm 12.0cm 25.33*cm G4_WATER
:color beamScan 0 1.0 1.0
// Define a box CsI filled with Water
:volu CsI BOX 30.2cm 11.8cm 25.1*cm G4_WATER
:color CsI 1.0 0.0 0.0
:rotm r000 0 0 0
:place MR_Bore 1 hall r000 0 0 0
:place beamScan 2 hall r000 0 -2.0*cm 0
:place CsI 3 hall r000 0 0 0
// Corresponding structures.
//MR_Bore=chamber; beamScan=vacuum; Water/CsI=CsI
Change the particle type to electron.
Shoot 5 MeV electrons downward
/gps/particle e-
/gps/energy 5 MeV
/gps/pos/centre 0 50.0 0 cm # Ensure electrons reach beamScan
/gps/direction 0 -1 0
At this time when I run "mingle.exe run.mac", I got the "Scoring.ROOT" file.
Then I added the definition of a magnetic field in the "mingle.cc" file, as well as as some other initiation actions. After rebuilt the solution, I confirmed the electrons trajectories were changed due to the magnetic fields, but now "mingle.exe" failed to write the "Scoring.ROOT". The updated "mingle.cc" is as below.
#include "G4VUserDetectorConstruction.hh"
#include "G4NistManager.hh"
#include "G4tgbVolumeMgr.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4FieldManager.hh"
#include "G4TransportationManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4UniformMagField.hh"
#include "G4MagneticField.hh"
#include "G4ThreeVector.hh"
#include "G4VisAttributes.hh"
#include "G4RunManager.hh"
#include "G4ChordFinder.hh"
#include "G4MultiFunctionalDetector.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4PSEnergyDeposit.hh"
#include "G4SDManager.hh"
#include "G4UserSteppingAction.hh"
#include "G4AnalysisManager.hh"
// Custom Magnetic Field for Volume-limited Application
class LocalMagneticField : public G4MagneticField {
public:
G4ThreeVector center;
G4double maxRadius, halfHeight;
G4double fieldStrength;
LocalMagneticField(G4ThreeVector c, G4double rMax, G4double h, G4double B)
: center(c), maxRadius(rMax), halfHeight(h), fieldStrength(B) {
}
void GetFieldValue(const G4double point[4], G4double* Bfield) const override {
G4double x = point[0] - center.x();
G4double y = point[1] - center.y();
G4double z = point[2] - center.z();
G4double r = std::sqrt(x * x + y * y);
if (r <= maxRadius && std::abs(z - center.z()) <= halfHeight) {
Bfield[0] = 0.;
Bfield[1] = 0.;
Bfield[2] = fieldStrength;
}
else {
Bfield[0] = Bfield[1] = Bfield[2] = 0.;
}
}
};
// Detector Construction Class
class Detector : public G4VUserDetectorConstruction {
public:
G4VPhysicalVolume* Construct() override {
G4NistManager* nist = G4NistManager::Instance();
G4Material* LiquidHelium = new G4Material("LiquidHelium", 2, 4.0026 * g / mole, 0.1245 * g / cm3);
G4Material* Aluminum = nist->FindOrBuildMaterial("G4_Al");
G4tgbVolumeMgr::GetInstance()->AddTextFile("target.tg");
G4VPhysicalVolume* world = G4tgbVolumeMgr::GetInstance()->ReadAndConstructDetector();
G4RunManager::GetRunManager()->GeometryHasBeenModified();
// Debug: Print all logical volumes
G4cout << "Listing all available logical volumes:" << G4endl;
for (auto lv : *G4LogicalVolumeStore::GetInstance()) {
G4cout << "Logical Volume: " << lv->GetName() << G4endl;
}
G4LogicalVolume* logicCSI = G4LogicalVolumeStore::GetInstance()->GetVolume("CsI");
if (!logicCSI) {
G4Exception("Detector::Construct()", "VolNotFound", FatalException, "Logical volume beamScan not found!");
}
G4MultiFunctionalDetector* mfd = new G4MultiFunctionalDetector("CSIScorer");
G4PSEnergyDeposit* edepScorer = new G4PSEnergyDeposit("Edep");
mfd->RegisterPrimitive(edepScorer);
G4SDManager::GetSDMpointer()->AddNewDetector(mfd);
logicCSI->SetSensitiveDetector(mfd);
G4LogicalVolume* logicBore = G4LogicalVolumeStore::GetInstance()->GetVolume("MR_Bore");
if (!logicBore) {
G4Exception("Detector::Construct()", "VolNotFound", FatalException, "Logical volume MR_Bore not found!");
}
G4ThreeVector center(0., 0., 0.);
G4double maxRadius = 46.75 * cm;
G4double halfHeight = 30.0 * cm;
G4double fieldStrength = 0.01 * tesla;
LocalMagneticField* magField = new LocalMagneticField(center, maxRadius, halfHeight, fieldStrength);
G4FieldManager* localFieldMgr = new G4FieldManager();
localFieldMgr->SetDetectorField(magField);
localFieldMgr->SetChordFinder(new G4ChordFinder(magField));
logicBore->SetFieldManager(localFieldMgr, true);
return world;
}
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <G4VUserPrimaryGeneratorAction.hh>
#include <G4GeneralParticleSource.hh>
class Generator : public G4VUserPrimaryGeneratorAction
{
private:
G4GeneralParticleSource* fGPS;
public:
Generator() : G4VUserPrimaryGeneratorAction() {
fGPS = new G4GeneralParticleSource;
}
~Generator() { delete fGPS; }
void GeneratePrimaries(G4Event* evt) { fGPS->GeneratePrimaryVertex(evt); }
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <G4VUserActionInitialization.hh>
class Action : public G4VUserActionInitialization
{
public:
void Build() const { SetUserAction(new Generator); }
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <G4TScoreNtupleWriter.hh>
#include <G4RunManagerFactory.hh>
#include <G4PhysListFactory.hh>
#include <G4AnalysisManager.hh>
#include <G4ScoringManager.hh>
#include <G4VisExecutive.hh>
#include <G4UIExecutive.hh>
#include <G4VisManager.hh>
#include <G4UImanager.hh>
int main(int argc, char** argv)
{
auto run = G4RunManagerFactory::CreateRunManager();
G4ScoringManager::GetScoringManager(); // enable macro commands in /score/
// https://geant4-forum.web.cern.ch/t/11480/3
G4TScoreNtupleWriter<G4AnalysisManager> writer; // enable data recording
if (run->GetRunManagerType() != G4RunManager::sequentialRM)
writer.SetNtupleMerging(true);// merge ntuples created in multi threads
// load default physics list, or the one specified by $PHYSLIST
G4PhysListFactory f; run->SetUserInitialization(f.ReferencePhysList());
run->SetUserInitialization(new Detector); // specify detector setup
run->SetUserInitialization(new Action); // specify user action
G4UIExecutive* ui = nullptr; // assume batch mode
if (argc == 1) ui = new G4UIExecutive(argc, argv); // interactive mode
auto vis = new G4VisExecutive(); vis->Initialize(); // enable visialization
if (ui) { // interactive mode
ui->SessionStart(); // do this after vis
delete ui;
}
else { // batch mode
G4String cmd = "/control/execute ";
G4UImanager::GetUIpointer()->ApplyCommand(cmd + argv[1]); // run a macro file
}
delete vis; delete run; // clear up memory
return 0;
}
I am wondering if some of the code in the "detector" class may be wrong, but I don't have any clue as I got this part from ChatGPT.
@jintonic , may I know if you can have a look and help me on this?
I am using Windows 11 OS, and trying to run some simulation of a MR-linac, and the "mingle" is very helpful for running some preliminary tests. I adapted the "target.tg" and update the contents as below:
// define a 5x4x6 m3 cubic hall filled with air
:volu hall BOX 2.5m 2m 3*m G4_AIR
:vis hall OFF
// define a cylindrical MR_Bore filled with air
:volu MR_Bore TUBE 0.0cm 46.55cm 30*cm G4_AIR
:color MR_Bore 0.9 0.9 0.9
:vis MR_Bore ON
// Define a box beamScan of Water tank wall, just as water at this time.
:volu beamScan BOX 30.4cm 12.0cm 25.33*cm G4_WATER
:color beamScan 0 1.0 1.0
// Define a box CsI filled with Water
:volu CsI BOX 30.2cm 11.8cm 25.1*cm G4_WATER
:color CsI 1.0 0.0 0.0
:rotm r000 0 0 0
:place MR_Bore 1 hall r000 0 0 0
:place beamScan 2 hall r000 0 -2.0*cm 0
:place CsI 3 hall r000 0 0 0
// Corresponding structures.
//MR_Bore=chamber; beamScan=vacuum; Water/CsI=CsI
Change the particle type to electron.
Shoot 5 MeV electrons downward
/gps/particle e-
/gps/energy 5 MeV
/gps/pos/centre 0 50.0 0 cm # Ensure electrons reach beamScan
/gps/direction 0 -1 0
At this time when I run "mingle.exe run.mac", I got the "Scoring.ROOT" file.
Then I added the definition of a magnetic field in the "mingle.cc" file, as well as as some other initiation actions. After rebuilt the solution, I confirmed the electrons trajectories were changed due to the magnetic fields, but now "mingle.exe" failed to write the "Scoring.ROOT". The updated "mingle.cc" is as below.
#include "G4VUserDetectorConstruction.hh"
#include "G4NistManager.hh"
#include "G4tgbVolumeMgr.hh"
#include "G4LogicalVolumeStore.hh"
#include "G4FieldManager.hh"
#include "G4TransportationManager.hh"
#include "G4SystemOfUnits.hh"
#include "G4UniformMagField.hh"
#include "G4MagneticField.hh"
#include "G4ThreeVector.hh"
#include "G4VisAttributes.hh"
#include "G4RunManager.hh"
#include "G4ChordFinder.hh"
#include "G4MultiFunctionalDetector.hh"
#include "G4VPrimitiveScorer.hh"
#include "G4PSEnergyDeposit.hh"
#include "G4SDManager.hh"
#include "G4UserSteppingAction.hh"
#include "G4AnalysisManager.hh"
// Custom Magnetic Field for Volume-limited Application
class LocalMagneticField : public G4MagneticField {
public:
G4ThreeVector center;
G4double maxRadius, halfHeight;
G4double fieldStrength;
};
// Detector Construction Class
class Detector : public G4VUserDetectorConstruction {
public:
G4VPhysicalVolume* Construct() override {
G4NistManager* nist = G4NistManager::Instance();
G4Material* LiquidHelium = new G4Material("LiquidHelium", 2, 4.0026 * g / mole, 0.1245 * g / cm3);
G4Material* Aluminum = nist->FindOrBuildMaterial("G4_Al");
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <G4VUserPrimaryGeneratorAction.hh>
#include <G4GeneralParticleSource.hh>
class Generator : public G4VUserPrimaryGeneratorAction
{
private:
G4GeneralParticleSource* fGPS;
public:
Generator() : G4VUserPrimaryGeneratorAction() {
fGPS = new G4GeneralParticleSource;
}
~Generator() { delete fGPS; }
void GeneratePrimaries(G4Event* evt) { fGPS->GeneratePrimaryVertex(evt); }
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <G4VUserActionInitialization.hh>
class Action : public G4VUserActionInitialization
{
public:
void Build() const { SetUserAction(new Generator); }
};
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include <G4TScoreNtupleWriter.hh>
#include <G4RunManagerFactory.hh>
#include <G4PhysListFactory.hh>
#include <G4AnalysisManager.hh>
#include <G4ScoringManager.hh>
#include <G4VisExecutive.hh>
#include <G4UIExecutive.hh>
#include <G4VisManager.hh>
#include <G4UImanager.hh>
int main(int argc, char** argv)
{
auto run = G4RunManagerFactory::CreateRunManager();
}
I am wondering if some of the code in the "detector" class may be wrong, but I don't have any clue as I got this part from ChatGPT.
@jintonic , may I know if you can have a look and help me on this?