Sensor in Negative Ion Garfield++

I’m running a simulation of single GEM gain with one electron with negative ion drift, now i’m trying to put a sensor just below the GEM. I have few doubts.

  1. Do we need to add Electric fields of the sensor, if not, how to define the drift towards the sensor?
  2. I am starting with the strip wire as the signal sensor, but I don’t understand how to define it in XY plane?

I am also adding the code of my sensor for everyone to review:

  aval->AvalancheNegativeIon(init_x,init_y,init_z,0,0,0);
  Int_t nd = aval->GetNumberOfElectronEndpoints();

  Sensor sensor;  
  // sensor.AddComponent(&linearField);
  ComponentAnalyticField wField;
  constexpr double d = -0.03;
  constexpr double pitch_det = 55.e-4;

  constexpr double halfpitch = 0.5 * pitch_det;
  wField.AddStripOnPlaneY('z',d, -halfpitch, halfpitch,  "strip");
  wField.AddStripOnPlaneX('z',d, -halfpitch, halfpitch,  "strip");
  sensor.AddElectrode(&wField, "strip");
  AvalancheNIMicroscopic drift;
  drift.SetSensor(&sensor);
  drift.SetDistanceSteps(1.e-4);



  const unsigned int nTimeBins = 1000;
  const double tmin =  0.;
  const double tmax = 10.;
  const double tstep = (tmax - tmin) / nTimeBins;
  sensor.SetTimeWindow(tmin, tstep, nTimeBins);


  std::ofstream outfile;
  outfile.open("signal.txt", std::ios::out);
  for (unsigned int i = 0; i < nTimeBins; ++i) {
    const double t = (i + 0.5) * tstep;
    const double f = sensor.GetSignal("strip", i);
    const double fe = sensor.GetElectronSignal("strip", i);
    const double fh = sensor.GetIonSignal("strip", i);
    outfile << t << "  " << f << "  " << fe << "  " << fh << "\n";
  }

Let me know if I’m missing anything because i’m getting zero signal in signal.txt file.
Thanks

Hi,

Do we need to add Electric fields of the sensor?

Yes, you need to define the electric field in the sensor to be able to simulate drift lines. You do this by attaching a “component” to the sensor (AddComponent).

I am starting with the strip wire as the signal sensor, but I don’t understand how to define it in XY plane?

With ComponentAnalyticField, you can define strips in the xz plane and the yz plane. For instance, to define a strip in the yz plane, you first need to define a plane (AddPlaneX) and then define a strip on that plane (AddStripOnPlaneX). The first argument of AddStripOnPlaneX specifies wether the strip is along z or along y.
See Examples/AnalyticField/strip.C · master · garfield / garfieldpp · GitLab for an example.

By the way, I noticed that you are using a class AvalancheNIMicroscopic in your code. Is this something you wrote yourself (it is not part of the Garfield++ repository)?

Hello Heinrich, Thanks a lot for clearing out the queries and yes, I’m using new class AvalancheNIMicroscopic for negative ion studies.

Just a couple of more quick queries:

  1. If the transfer field already exist, can I just add a strip/electrode to collect the signal, is it possible without adding any new electric field?
  2. I’m defining a sensor for the gas i.e.
    Sensor *sens = new Sensor(); sens->AddComponent(fm); sens->SetArea(-0.03, -0.03, -0.03, 0.03, 0.03, 0.03);
    Do I need to define a new sensor or can I just put a strip/electrode in the old gas sensor?

AddComponent defines the “real” electric field to be used in a Sensor for calculating drift lines, avalanches, etc. If you want to compute the induced signal for these drift lines you need to attach a weighting field (AddElectrode) to the same sensor object.
The component used for the weighting field calculation can be different from the one used for the “real” electric field. So

  1. It depends what you mean by “transfer field already exists” and “just add a strip” but yes, you can use a component (like wField in your example) for calculating the weighting potential (AddElectrode) without using its electric field.
  2. Yes, you need to use the same sensor.

Heyy, I have modified my code to same as the https://garfieldpp.web.cern.ch/examples/silicon/ especially for the configuration and it’s running fine with avalanche gain with no error as desired, but still I’m not getting any signal (zero as the output). Can you check where did I’m lacking while putting the strip electrode?

using namespace Garfield; 

int main(int argc, char * argv[]) {
      // Setup the gas.
MediumMagboltz *gas = new MediumMagboltz();
  gas->SetComposition("sf6", 100.);
  gas->SetTemperature(300.15);
  gas->SetPressure(76.);
  gas->SetMaxElectronEnergy(300.);
  gas->EnableDrift();
  gas->Initialise(true);
  //set ion mobility data by user
  gas->LoadIonMobility("./IonMobility_SF6-_SF6.txt");

  // Sensor thickness [cm]
constexpr double d = 100.e-4;
// Bias voltage [V]
constexpr double vbias = -600.;
auto eLinear = [](const double /*x*/, const double y, const double /*z*/,
                  double& ex, double& ey, double& ez) {
  // Depletion voltage [V]
  constexpr double vdep = -100.;
  ex = ez = 0.;
  ey = (vbias - vdep) / d + 2 * y * vdep / (d * d);
};

ComponentUser linearField;
linearField.SetElectricField(eLinear);
linearField.SetArea(-2 * d, 0., -2 * d, 2 * d, d, 2 * d);
linearField.SetMedium(gas);

Sensor sensor;
sensor.AddComponent(&linearField);
MediumSilicon si;

ComponentAnalyticField wField;
wField.SetMedium(&si);
wField.AddPlaneY(0,vbias,"back");
wField.AddPlaneY(d, 0, "front");


constexpr double pitch = 55.e-4;
constexpr double halfpitch = 0.5 * pitch;
wField.AddPixelOnPlaneY(d, -halfpitch, halfpitch, -halfpitch, halfpitch, "pixel");
wField.AddStripOnPlaneY('x',d, -halfpitch, halfpitch, "strip");
sensor.AddElectrode(&wField, "strip");

// Set the time bins.
const unsigned int nTimeBins = 100;
const double tmin =  0.;
const double tmax = 100.;
const double tstep = (tmax - tmin) / nTimeBins;
sensor.SetTimeWindow(tmin, tstep, nTimeBins);

AvalancheNIMicroscopic *aval = new AvalancheNIMicroscopic();
aval->SetSensor(&sensor);
aval->SetElectronTransportCut(1e-20);
aval->SetNegativeIonMass(146);
//aval->SetDistanceSteps(1e-5); // cm
aval->SetDistanceSteps(1e-4); // cm


 // Counting
  double init_x = 0;
  double init_y = 0;
  double init_z = 0;

  aval->AvalancheNegativeIon(init_x,init_y,init_z,0,0.1,0);
  Int_t nd = aval->GetNumberOfElectronEndpoints();

  for(int i=0; i<nd; i++){
    double x0,y0,z0,t0,e0;
    double x1,y1,z1,t1,e1;
    aval->GetElectronEndpoint(i,
                              x0,y0,z0,t0,e0,
                              x1,y1,z1,t1,e1,
                              Stat);
    unsigned int nstep = aval->GetNumberOfElectronDriftLinePoints(i);
    status = Stat;
    nStep  = nstep;
    for(int step=0;step<nstep;step++){
      aval->GetElectronDriftLinePoint(x,y,z,t,change,step,i);
    }
  }
  
  std::ofstream outfile;
outfile.open("signal.txt", std::ios::out);
for (unsigned int i = 0; i < nTimeBins; ++i) {
  const double t = (i + 0.5) * tstep;
  const double f = sensor.GetSignal("strip", i);
  const double fe = sensor.GetElectronSignal("strip", i);
  const double fh = sensor.GetIonSignal("strip", i);
  outfile << t << "  " << f << "  " << fe << "  " << fh << "\n";
}

}

Also, I’m extremely sorry for disturbing, but i’m stuck here for 1 week now, so seeking for help.

Hi,

the parameterisation of the electric field used in the silicon example is specific to a depleted planar silicon sensor; I don’t think it is applicable to your case. If I understood correctly, you are trying to simulate a parallel-plate chamber filled with pure SF6. In this case, you don’t need to define the electric field via a ComponentUser object; you can simply use ComponentAnalyticField and set the active medium to be the MediumMagboltz object (gas) you set up at the beginning of your program.
You might also want to check the dimensions (in particular thickness and strip pitch). A gas gap of 100 μm seems a bit small considering that you operate at 0.1 bar.
I don’t know what your AvalancheNIMicroscopic class does so I cannot really comment on this part of the code, but an electron transport cut of 10-20 (eV?) seems odd to me.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.