Using PulseTransfer Module

Hello,

I’ve been trying to use the PulseTransfer module in my simulations, having previously used the SimpleTransfer module. The simulation runs fine, but the root file that’s produced doesn’t contain any PixelCharge or PixelHit objects, although I’ve specified that both items be included by the ROOTObjectWriter module and all other objects specified (MCParticle, MCTrack, DepositedCharge and PropagatedCharge) are written to the root file. Running simulations with SimpleTransfer swapped in for PulseTransfer produces PixelCharge and PixelHit objects as expected.

My understanding from the manual is that the PulseTransfer module should take PropagatedCharge objects as input and should produce PixelCharge objects. The release notes imply that the PulseTransfer module should be used with the TransientPropagation module. I think this might explain my issue, as I’ve not been using the TransientPropagation module so as to avoid having to import a weighting potential. I’ve just being using the GenericPropagation module. However, the manual says that TransientPropagation takes DepositedCharge as input and produces PixelCharge, so I’m not sure how that works if PulseTransfer takes PropagatedCharge as input?

Many thanks in advance,
Kirsty

Dear @kirstyap

it looks like you have uncovered a bug here - definitely in the documentation.

The TransientPropagation module (in its published version) generates PropagatedCharge objects, just as the other propagation modules, which then need to e combined by a transfer module. I have corrected the description accordingly: https://gitlab.cern.ch/allpix-squared/allpix-squared/merge_requests/273 . I believe that the wrong documentation stems from an early prototype of the module where we write PixelCharge objects directly, and somehow this escaped scrutiny.

However, also the chain GenericPropagation -> PulsetTransfer -> DefaultDigitizer should work as expected, and this doesn’t seem to be the case your you if I understand correctly. Could you maybe upload the configuration files with which this problem appears?

Best regards,
Simon

Hi @simonspa,

Thanks for your quick response. I’ve attached a copy of the config file I’ve been using. If you can see where I’m going wrong I’d be very grateful.

I was wondering if it might be something in the parameters I’ve used for DefaultDigitizer, but the fact there’s no PropagatedCharge objects suggests the issue is a stage earlier and to do with the PulseTransfer module. I’ve quickly rerun things using the ‘Debug’ logging level and I do get messages from PulseTransfer, and it looks like it determines that 0 charge is induced on any pixels. That maybe explains why there are no PixelHit or PixelCharge objects, though it doesn’t explain why PulseTransfer produces that output. Perhaps it’s one of the parameters I’m using for GenericPropagation?

I’ve been using the installation of Allpix Squared 1.4.3 on cvmfs for Centos7, just in case that’s relevant.

Best wishes,
Kirsty

PulseTransferTest.conf (1.2 KB)

Hi @kirstyap

thanks for sending your configuration, I am able to reproduce part of the issues you are reporting.

What works for me is writing of PropagatedChage objects. I do get the corresponding tree in the output file and it has data in it. Not sure what the problem here was for you.

I can confirm that indeed the PulseTransfer reports 0e despite many PropagatedCharge events, e.g.

|13:47:36.185|    (INFO) [R:GenericPropagation:dut] Propagated 109384 charges in 2440 steps in average time of 9.95336ns
|13:47:36.185|   (DEBUG) [R:PulseTransfer:dut] Received 2440 propagated charge objects.
|13:47:36.185|    (INFO) [R:PulseTransfer:dut] Total charge induced on all pixels: 0e
|13:47:36.185|    (INFO) [R:DefaultDigitizer:dut] Digitized 0 pixel hits

Looking into the code I do see the reason for this. The PropagateCharge object can hold two different types of information: either just a charge or a list of pulses for individual electrodes. Currently, if the pulse list is empty, it simply does nothing - while it should probably just take the total charge collected at the respective electrode.

I will fix this, but for now I guess we have to call it “expected behavior”. If you swap the GenericPropagation out for TransientPropagation it should properly record pulses and sum the in PulseTransfer.

Does that help?
/Simon

Hi @simonspa,

I would like to comment that replacing the GenericPropagation out for TransientPropagation would maybe solve the problem that the PulseTransfer reports 0e despite many PropagatedCharge events, but at the same time the TransientPropagation module will require to use a weighting potential that is provided by the simulation of electric field by TCAD for example. Do you have any idea if there any way to test the pulseTransfer with a linear electric field approximation for the moment?

Thanks for your replay
Tasneem

Hi @Tasneem,

The problem in the end is that without the full time-resolved simulation with weighting potential you don’t really have pulses but only charge carriers which arrive at an electrode at a given time.

That said, one can of course simplify things and e.g. look at the arrival times of these charge carriers at the electrodes instead of the induced current. I have some working code for that which needs to be reviewed before merging, but if you want you can already try it out:

Let me know if you need help in compiling APSQ from source.

/Simon

Hi @simonspa,

You’ve actually reproduced the issue I was having exactly. It was PixelCharge and and PixelHit objects that I was having difficulty creating, not PropagatedCharge (sorry, that was a typo in my second message, it was right in my original post).

Thank you for your help in figuring out what was going wrong. I think this just means I have to finally learn to to use TCAD :slightly_smiling_face:

Many thanks,
Kirsty

Hi @kirstyap

depending on your geometry you might also be able to use the WeightingPotential generator found in tools/weightingpotential_generator which should be build automatically. I just realized that it completely lacks documentation in form of a README. :confused:
What it does is basically the same thing as the pad function of the WeightingPotentialReader module, calculating the potential with a Tailor expansion.

/Simon

Just for reference:

The PulseTransfer module in the recently released version 1.5 is now also capable of simply summing charge carrier arrival times at the electrodes in case there is no Shockley-Ramo induced current information available.

See: https://gitlab.cern.ch/allpix-squared/allpix-squared/-/blob/master/src/modules/PulseTransfer/README.md

Best regards,
Simon

Dear @simonspa,

I noticed that you have mentioned there is a tool called weightingpotential_generator, do it means we can calculate weightingpotential without external E-field data input (TACD E-field results for example), am I right?

Another question, do Allpix2 have tools that can generated E-field data bsaed on some simple geometry? For example a silicon strip sensor with 125um pitch and 24um inplant. Because sometimes TCAD may be not feasible and easy to use.

Cheers,
Shen

Dear @wangsh

sorry for the late response - yes, the tool is capable of calculating the weighting potential of pixel geometries (pad over plane condenser), the reference for the paper on which it is based is given in the user manual.

Currently it is only calculating the weigthing potential, an extension to be able to also generate the electric field would be very nice and I would welcome any contributions. :slight_smile:
Feel free to contact me if you would like to take this task up and need some guidance!

Best regards,
Simon

Dear @simonspa

Oh, I see, that’s because the weighting field and the realistic E field have the same distributions in pad structure.

I will be glad to have some efforts on allpix2. Now I have made some electric field simulation based on MATLAB (Solving Partial Differential Equations), I want to konw what’s the standard E field data format for Allpix2 reader, so that I can import those field data to Allpix2 and apply to charge caculation. (with the help of WeightingPotentialReader module) .

Cheers,
Shen

Dear @wangsh

Allpix Squared reads two different file formats, .init and .apf. The former is a simple ASCII text file while the latter is the binary “Allpix Squared Field Data” format. Both are read and written by the simple (header-only) tool you can find in the src/tools/field_parser.h file of the repository. Usage of the tool is described in Section 12.1 of the user manual.

In short, the text format consists of a header (with some unused fields because it is a legacy format from other tools). Just copy the following snippet and replace the parts in <...> pointy brackets with your relevant parameters:

This First line is interpreted as descriptive header of the file
##UNUSED##  ##UNUSED##
##UNUSED## ##UNUSED## ##UNUSED##
##UNUSED## ##UNUSED## ##UNUSED##
<size_z> <size_x> <size_y> ##UNUSED## ##UNUSED## ##UNUSED## ##UNUSED## <bins_x> <bins_y> <bins_z> ##UNUSED##

It is followed by a list in the form of three indices and three field components like

bin_x bin_y bin_z feld_x feld_y feld_z

for a vector field. For a scalar field, of course only one component is present for the field data.
This should give you a starting point.

However, it would be cool if others could also profit from your work. In tools/tcad_dfise_converter of the repository, you will find a tool which currently takes a TCAD electrostatic field in adaptive mesh and interpolates it onto a regular grid and writes it out in a format readable by Allix Squared.

It would be very nice if you could provide some code to read MATLAB fields into this tool (I guess your mesh is adaptive, too?). This would mean basically providing the MATLAB-equivalent of the DFISEParser.[hc]pp you find in this folder. Would this be of interest to you?

Best regards,
Simon