Skip to content

Failed to save scoring.root when a magnetic field is added to the simulation #1

Description

@jimingshuo

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?

Activity

  1. jintonic commented on Mar 30, 2025

    @jintonic
    Owner

    First of all, there is no need to create another sensitive detector using C++. When you use things like

    /score/create/boxMesh mesh
    /score/mesh/boxSize 4 1 1 cm
    /score/mesh/nBin 40 1 1
    /score/mesh/translate/xyz -3.97 0. 0. m
    
    /score/quantity/nOfStep nOfStepEMinus
    /score/filter/particle eMinusFilter e-
    /score/quantity/nOfStep nOfStepAlpha
    /score/filter/particle AlphaFilter alpha
    /score/close
    /score/list
    

    a sensitive region with the mesh attached will be created automatically. I suspect that your new sensitive detector definition caused your problem.

    Secondly, your "// Debug: Print all logical volumes..." is not necessary.

    /vis/ASCIITree/verbose 13
    /vis/drawTree
    

    gives your more information about your geometry. No C++ is needed.

    There is also no need to define your materials in C++. They can be done in your .tg file.

    In summary, the only C++ that is needed here is your definition of field. Remove the sensitive detector definition and try again.

    This is not an issue of MinGLE.

  2. jintonic commented on Apr 2, 2025

    @jintonic
    Owner

    I used Geant4's default way to add a uniform B field in MinGLE. You don't have to write your own code to do this now.

  3. jimingshuo commented on Apr 2, 2025

    @jimingshuo
    Author

    Thanks! I figured it out in the last weekend, The Geant4's default way does not work for this scenario as I want to limit the magnetic field in a certain dimension - the MR_Bore, but not in the whole room.

    Yes, that "G4MultiFunctionalDetector* mfd = new G4MultiFunctionalDetector("CSIScorer");" in the Detector class caused the problem. After I updated the code as below, it works
    LocalMagneticField* magField = new LocalMagneticField(center, maxRadius, halfHeight, fieldStrength);
    // Create a Field Manager for the MRI Bore
    G4FieldManager* localFieldMgr = new G4FieldManager();
    localFieldMgr->SetDetectorField(magField);
    localFieldMgr->SetChordFinder(new G4ChordFinder(magField));

    Your "Gear" and "Mingle" project templates were my first introductions to making Geant4 work, and I truly appreciate how elegant and intuitive they are. At the same time, most tutorial examples from other teams and projects still follow a more traditional C++ coding style, which makes it challenging for beginners like me to find solutions when adding new items and features.

  4. added
    DiscussionGeneral discussion about MinGLE or Geant4
    and removed
    DiscussionGeneral discussion about MinGLE or Geant4
    on Jan 5, 2026
  5. Repository owner locked and limited conversation to collaborators on Jan 5, 2026
  6. converted this issue into a discussion #3 on Jan 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions