Signal question

I simulated the current signal of a proportional counter tube at a working voltage of 1100V, and the results are as follows:


The signal has two peaks generated by ions and electrons, respectively. The peak value of ions is close to that of electrons. I’m not sure if this is correct?

@hschindl could you please take a look at this question?

Hi @Migu, the signal looks “unusual” to me, but I cannot say much more without knowing in a bit more detail what your configuration looks like and how you simulated the signal. Could you provide a minimal working example?

Thanks for the reply! Here is the working example.
IonMobility_Ar+_Ar.txt (807 Bytes)
Li_in_Ar_CO2_gas.txt (5.5 KB)
signalv3.1.C (21.9 KB)

Thanks! What I had in mind though was a minimal working example: How to create a Minimal, Reproducible Example - Help Center - Stack Overflow
Can you try to trim your program such that contains only what is essential to reproduce the issue at hand?

Oh sorry!
I used TrackSrim with SRIM-generated files to simulate the initial ionization process of incident particles.

TrackSrim tr;
  tr.SetSensor(&sensor); 
  const std::string file = "Li_in_Ar_CO2_gas.txt";   
  tr.SetKineticEnergy(0.84e6);    
  tr.SetWorkFunction(27.7);       
  tr.SetFanoFactor(0.172);      
  const double za = ratioofAr * (18. / 39.948) +ratioofCO2 * (22. / 44.0095);  // Set A and Z of the gas (not sure what's the correct mixing law).
  tr.SetAtomicMassNumbers(22. / za, 22);
  tr.EnableTransverseStraggling(false);
  tr.EnableLongitudinalStraggling(false);

I used AvalancheMicroscopic to drift the electrons and sequentially corrected the initial ionization positions in each cluster.

const bool notnewtrack= !tr.NewTrack(projectilex, projectiley, projectilez, projectileT, projectiledx, projectiledy, projectiledz);    
    if (notnewtrack) {
      std::cerr << "Generating clusters failed; skipping this particle's track.\n";
      continue;
    }
    unsigned int netot = 0;
    std::vector<std::array<double,7>> informationofclusters;
    while (true) {                          
      int ne = 0;
      double xc, yc, zc, tc, ec, ekin;
      const bool done = tr.GetCluster(xc, yc, zc, tc, ne, ec, ekin);  
      if(done) {                                                                 
      informationofclusters.push_back({xc, yc, zc, tc, ne, ec,ekin});          
      netot += ne;        
      }   
      if (!done) {
        break;                    
      }
    }
    double MLi=6.9405*1.66053886e-27;     
    double Mev=1.602176565e-13;              
    for(int i=0;i<informationofclusters.size()-1;++i){
      double speedofprojectile=sqrt(2*informationofclusters[i+1][6]*Mev/MLi)/1.e7;    
      double distanceofclusters=sqrt(pow(informationofclusters[i+1][0]-informationofclusters[i][0],2) \
                                    +pow(informationofclusters[i+1][1]-informationofclusters[i][1],2) \
                                    +pow(informationofclusters[i+1][2]-informationofclusters[i][2],2));  
      double duation=distanceofclusters/speedofprojectile;                  
      informationofclusters[i+1][3]=informationofclusters[i][3]+duation;     
    }

Then, I conducted an avalanche of electrons in each cluster and also calculated the ions.

for(int j=0; j<informationofclusters.size(  ); ++j){  
        double avalancheelectrons=0;
        double avalancheions=0;   
        AvalancheMicroscopic driftelectron;
        driftelectron.SetSensor(&sensor);
        driftelectron.EnableSignalCalculation();      
        driftelectron.EnablePlotting(&driftView);  
        
        AvalancheMC driftion;           
        driftion.SetSensor(&sensor);    
        driftion.SetDistanceSteps(2.e-4);   
        driftion.EnableSignalCalculation();    

        AvalancheMC driftprimaryion;           
        driftprimaryion.SetSensor(&sensor);     
        driftprimaryion.SetDistanceSteps(2.e-4);        
        driftprimaryion.EnableSignalCalculation();    

        for (int k = 0; k <informationofclusters[j][4]; ++k) {           
          driftelectron.AvalancheElectron(informationofclusters[j][0], informationofclusters[j][1], \
                                          informationofclusters[j][2], informationofclusters[j][3], 0.00001, 0., 0., 0.); 
        }
        int np=0;
        np=driftelectron.GetNumberOfElectronEndpoints();  
        for(int m=0; m<np; ++m){                         
          double xestart, yestart, zestart, testart, eestart;
          double xeend, yeend, zeend, teend, eeend;
          int status;
          driftelectron.GetElectronEndpoint(m, xestart, yestart, zestart, testart, eestart, xeend, yeend, zeend, teend, eeend, status);
          driftion.SetIonSignalScalingFactor(informationofclusters[j][4]);
          driftion.DriftIon(xestart, yestart, zestart, testart);
        } 
        driftprimaryion.SetIonSignalScalingFactor(informationofclusters[j][4]);
        driftprimaryion.DriftIon(informationofclusters[j][0], informationofclusters[j][1], \
                                 informationofclusters[j][2], informationofclusters[j][3]);       

      }

Hi,
thanks for the explanations; I don’t know if it’s sufficient to explain the signal shape, but it looks like you are simulating (some of) the ions twice. When looping over the electron drift lines and simulating an ion drift line from the starting point of each electron trajectory, you already include the “primary” ions, you don’t need to simulate them explicitly again.

I’ve attached a trimmed down and slightly modified version of your code. I didn’t manage to reproduce the signal shape you observed though…
mre.C (3.2 KB)

Thank you so much for the reply. I will adjust my code based on the example you provided and compare the signal results. But i am so sorry that maybe i will reply after two days.

Hi!I encountered the following problem while running ‘mre.c’:

Please update to the latest version of the master branch; or copy the ion mobility file to your local directory; or set the full path to the ion mobility file.

Hi !
Running ‘mre.c’ requires more than eight hours. Is there any method of enhancing the program’s calculation speed?

Hi,
indeed, you have quite a lot of primary electrons on the track, and simulating avalanches on a microscopic level for each of them will be quite time consuming. Have you considered using DriftLineRKF instead?

Hello,

I’ve attached a faster version of the simulation. It uses AvalancheMC instead of AvalancheMicroscopic (I also left the DriftLineRKF version commented out) and OpenMP. You’ll probably have to tweak the step size to get the desired results. You’ll also have to generate a .gas file for the desired mixture, I didn’t have one so I used 80/20 instead of 85/15.

CMakeLists.txt (336 Bytes)

mre.C (3.3 KB)

Sincerely,
Gabriel

Hi,
Thank you very much for offering the revised version. I attempted to run your code and allocated 64 processors to my virtual machine. However, I’ve been stuck on the first cluster for 20 minutes and have yet to proceed to the second cluster for calculations.


Could you tell me how long your program has been running calculations for?

Hello,

That’s strange. I’ve attached the output of my last run of the unaltered version of the code, i.e. AvalancheMC with step size of 0.01[cm]. I just ran it on my side with a i9-10900k (36 logic processors). If the environment variable OMP_NUM_THREADS is set to 64 then the loop should be using the 64 logic processors available on your virtual machine, and if it is not set the loop defaults to the maximum number anyways. The easiest way to check this by running the command echo $OMP_NUM_THREADS. The second easiest way is checking if CPU usage peaks for each logic processor you’ve allocated.

It could also be that you got an unlucky sequence with the RNG that caused the drift line calculation time of one of the electrons to skyrocket, impeding the calculation of the next cluster of electrons.

Some other important info as well:

ROOT version: 6.32.12
Garfield++ version (commit SHA): d34fbdf7
Platform: Ubuntu-22.04 (WSL)

Hello!
Thank you for your reply! I will try to find out what happened.