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.