Problems in ViewDrift and ViewSignal

Hi everyone,
I am beginner of Garfieldpp.I tried to imitate Silicon in the example to output a gif of the drift lines and signals. I used the ComponentTcad2d and TrackHeed classes in the simulation, but the output remains the same instead of being updated.
I attach the Plot code and the result.

double t = 0.;
double dt = 0.1;
const unsigned int nFrames = 100;
for (unsigned int i = 0; i < 100; ++i) {
  vDrift.Clear();
  drift.SetTimeWindow(t, t + dt);
  vDrift.Plot2d(true, true);
  vSignal.PlotSignal("anode");
  gSystem->ProcessEvents();
  constexpr bool gif = true;
  if (!gif) {
      char filename[50];
      sprintf(filename, "frames/frame_%03d.png", i);
      canvas.SaveAs(filename);
  } else {
  if (i == nFrames - 1) {
      canvas.Print("movie.gif++");
  } else {
      canvas.Print("movie.gif+3");
  }`Preformatted text`
  }
std::cout << "Drift time window: [" << t << ", " << t + dt << "] ns\n";
t += dt;
}
    std::cout << "End of GIF" << "\n";

Hello! @hschindl will surely be able to help here.

Hi,
you’re missing a line like

drift.ResumeAvalanche();

after

drift.SetTimeWindow(t, t + dt);

Thanks for your reply!
I added this code as you suggested, but it doesn’t seem to work and the output is still the same as before.

In fact, if it is not a gif but a static graph, the drift line and signal can be output normally, so I think I do not know enough about the code caused this problem.
Attach the main code.

#include <iostream>
#include <fstream>
#include <cmath>
#include "Garfield/TrackTrim.hh"
#include <TCanvas.h>
#include <TROOT.h>
#include <TApplication.h>
#include <TSystem.h>
#include <array>
#include "Garfield/MediumSilicon.hh"
#include "Garfield/MediumDiamond.hh"
#include "Garfield/ComponentTcad2d.hh"
#include "Garfield/ComponentAnalyticField.hh"
#include "Garfield/Sensor.hh"
#include "Garfield/TrackHeed.hh"
#include "Garfield/AvalancheMC.hh"
#include "Garfield/ViewField.hh"
#include "Garfield/ViewDrift.hh"
#include "Garfield/ViewSignal.hh"
#include "Garfield/FundamentalConstants.hh"
#include "Garfield/Random.hh"
#include "Garfield/Plotting.hh"

using namespace Garfield;

int main(int argc, char * argv[]) {

  TApplication app("app", &argc, argv);

  // Sensor thickness.
  const double width = 0.055;//cm
  // Sensor width.
  const double thickness = 0.45;//cm
  //const double length = 0.0095;//cm

  MediumDiamond Diamond;
  Diamond.SetTemperature(293.);
  // Import a two-dimensional TCAD field map.
  ComponentTcad2d fm;
  // Load the mesh (.grd file) and electric field (.dat).
  fm.Initialise("n4_des.grd", "n4_des.dat");
  fm.SetRangeZ(thickness/-2, thickness/2);

  fm.SetWeightingField("n17_des.dat", "n4_des.dat",1,"anode");
  // Associate the Diamond regions in the field map with a medium object.
  fm.SetMedium("Diamond", &Diamond);

  Sensor sensor;
  sensor.AddComponent(&fm);
  sensor.AddElectrode(&fm, "anode");

  const int nSignalBins = 1000;
    const double tmin = 0.;
    const double tmax = 10.;//ns
  const double tStep = (tmax - tmin) / nSignalBins;//ns
  sensor.SetTimeWindow(0., tStep, nSignalBins);

    // Read the TRIM output file.
    TrackTrim track;
    track.SetSensor(&sensor);
    const std::string filename = "EXYZ.txt";
    // Import the first 100 ions.
    if (!track.ReadFile(filename, 1000)) {
        std::cerr << "Reading TRIM EXYZ file failed.\n";
        return 1;
    }

  AvalancheMC drift(&sensor);
  //drift.SetTimeSteps(0.01);//0.02=20ps
  drift.SetDistanceSteps(1.e-4);

  ViewSignal vSignal;
  vSignal.SetSensor(&sensor);
  constexpr bool plotSignal = true;

  ViewDrift vDrift;
  constexpr bool plotDrift = true;
  if (plotDrift) {
    vDrift.SetArea(-0.5 * thickness,-0. * width,-0.5 * thickness,0.5 * thickness,1. * width,0.5 * thickness);
    track.EnablePlotting(&vDrift);
    drift.EnablePlotting(&vDrift);
  }
  
  sensor.ClearSignal();
  TCanvas canvas("c", "", 1400, 600);
  canvas.Divide(2, 1);
  auto pad1 = canvas.cd(1);
  auto pad2 = canvas.cd(2);
  vDrift.SetCanvas((TPad*)canvas.cd(1));
  vSignal.SetCanvas((TPad*)canvas.cd(2));
  
    const double x0 = 0.;
    const double y0 = width;
    const double z0 = 0.;
    const double t0 = 0.1;

    track.NewTrack(x0, y0, z0, t0, 0., -1, 0.);

    for (const auto& cluster : track.GetClusters()) {
        drift.SetElectronSignalScalingFactor(cluster.n);
        drift.DriftElectron(cluster.x, cluster.y, cluster.z, cluster.t);
        drift.SetHoleSignalScalingFactor(cluster.n);
        drift.DriftHole(cluster.x, cluster.y, cluster.z, cluster.t);
    }

    double t = 0.;
    double dt = 0.1;
    const unsigned int nFrames = 100;
    for (unsigned int i = 0; i < 100; ++i) {
      vDrift.Clear();
      drift.SetTimeWindow(t, t + dt);
      vDrift.Plot2d(true, true);
      vSignal.PlotSignal("anode");
      gSystem->ProcessEvents();
        constexpr bool gif = true;
        if (!gif) {
            char filename[50];
            sprintf(filename, "frames/frame_%03d.png", i);
            canvas.SaveAs(filename);
        } else {
            if (i == nFrames - 1) {
                canvas.Print("movie.gif++");
            } else {
                canvas.Print("movie.gif+3");
            }
        }
        std::cout << "Drift time window: [" << t << ", " << t + dt << "] ns\n";
        t += dt;
    }
    std::cout << "End of GIF" << "\n";

  app.Run(true);

}

Hi,
sorry for the late reply. The drift of the electrons and holes already happens in this loop:

track.NewTrack(x0, y0, z0, t0, 0., -1, 0.);
for (const auto& cluster : track.GetClusters()) {
  drift.SetElectronSignalScalingFactor(cluster.n);
  drift.DriftElectron(cluster.x, cluster.y, cluster.z, cluster.t);
  drift.SetHoleSignalScalingFactor(cluster.n);
  drift.DriftHole(cluster.x, cluster.y, cluster.z, cluster.t);
}

So the drift line calculation and signal are already once this loop is finished.
If you want to create an animation, you need to call AddElectron, AddHole instead of DriftElectron, DriftHole and then use SetTimeWindow, ResumeAvalanche in a subsequent loop to simulate the drift, as done in this example:

There is however a catch; if you do that, you cannot do the scaling of the signal (SetElectronSignalScalingFactor, SetHoleSignalScalingFactor) the way it’s done in your program. I’ll need to implement an additional functionality to set a weighting factor for each electron/hole.