I want to simulate Cerenkov radiation. I want to shoot gammas to water. There are .txt file which has 100000 gammas of different energies. I wrote the following code
ReadFiles();
G4ThreeVector pos(0., 0., 0.);
//G4ThreeVector mon(0., 0., 1.);
G4ThreeVector mon = G4RandomDirection();
for(auto a =0;a<100000;a++){
G4ParticleDefinition* particle = G4ParticleTable::GetParticleTable()->FindParticle("gamma");
fParticleGun->SetParticleDefinition(particle);
fParticleGun->SetParticleEnergy(gammasv[a]*keV);
fParticleGun->SetParticlePosition(pos);
fParticleGun->SetParticleMomentumDirection(mon);
fParticleGun->GeneratePrimaryVertex(anEvent);
}
This creates only one event. I want 100000 gammas as 100000 events.
That looks like the XXXGeneratePrimaryVertex()XXX GeneratePrimaries() code (I’m guessing, because you didn’t show us). The stuff inside the loop should be the only stuff in your XXXGeneratePrimaryVertex()XXX GeneratePrimaries() function.
Read the data into your array at the beginning of the run. Don’t bother with the loop at all. In XXXGeneratePrimaryVertex()XXX GeneratePrimaries(), get the event ID and use that to index into your array.
Do you want each gamma thrown in a random direction, or do you want all of them going the same way?
Yes, this is GeneratePrimaryVertex() , the .hh file looks like this
class MyPrimaryGenerator : public G4VUserPrimaryGeneratorAction
{
public:
MyPrimaryGenerator();
~MyPrimaryGenerator();
private:
G4ParticleGun fParticleGun;
//G4GeneralParticleSource fParticleGun; //new gun
std::vector gammasv;
};
. I am sorry to say, I did not understand, how should I loop with eventID, and if I will not take care of loop inside the GeneratePrimaryVertex(), how should I generate all those gammas?
First, my mistake typing: “GeneratePrimaryVertex()” is the function we use in our own different generators. You’re correct that the function is GeneratePrimaries(); I’ve edited my initial response above.
Notice that GeneratePrimaries() takes a G4Event pointer as argument. It is called at the beginning of each individual event, and G4Event has a unique event ID. So the general idea is that you’ll open the file at the beginning of the job, and either read all the data into a buffer (what you’re doing now), or read one line at a time within GeneratePrimaries(). Then, you can use the unique event ID in place of your [a] index, to get a different single gamma for each event.
This is code you will need to write yourself. I don’t know if there are examples which deal with reading primaries as inputs from a file.
10 million shouldn’t be a big deal. You can’t do more than 2.14 billion in a job, because G4 event ID is an int not an unsigned. Is it really “stopped,” or is it just taking a long time to finish? Before your /run/beamOn line, you could add a line in your macro file, /run/printProgress 1000. It’ll print a line every 1000 events so you can tell that the job is still moving.
Ah, you’re reopening and reading the file on every event; that’s what’s taking the huge amount of time.
Are you running this with multiple threads, or with just a single thread? If you’re using just a single thread, then you know that eventID==0 is the start of the run, so you can write,
G4int eventNumber = anEvent->GetEventID();
if (eventNumber==0) ReadFiles();
using your old, original version of ReadFiles() where you fill the array of gamma energies.
If you’re running multi-threaded, it gets a bit trickier, because you’ll need to create a separate global singleton class to handle the file, and provide a const accessor function so the different threads can ask the singleton for each gamma energy.