xrt icon indicating copy to clipboard operation
xrt copied to clipboard

propagating "multi_electron_waves" ?

Open marcocamma opened this issue 4 years ago • 8 comments

Dear developers,

I have used "multi_electron_stack" method of the undulator class to get Electric fields for different electrons in the electron bunch. Watching how the different electrons build up the total intensity is actually quite instructive. I have also used the functions provided by the coherent module to measure the coherent lengths and so on.

Now I would like to do the same "measurements" after propagating through some optics (slits, mirrors, etc.). Is there a way I can do so with XRT ? I have tried to play a bit but failed likely because I have yet understood how XRT does wave propagation.

Any help to get me started would be appreciated

marcocamma avatar Apr 24 '20 20:04 marcocamma

Technically, it is possible to propagate multi_electron_stack fields. We would need to loop over all electrons and for each electron create a Beam object with the given field distribution from a slice of the stack and give it starting points and directional cosines for each pixel of the stacked image. It would take a handful of lines. Then we'd propagate that Beam in a usual way. But I don't see a reason, there are better mechanisms.

Firstly, I don't like a gridded version of field sampling because the positional periodicity may introduce an unwanted grating effect. Secondly, with a grid, you'd need to check the convergence with respect to the grid steps in the two directions, and this is a problem in itself. I view the Monte Carlo sampling as a big advantage compared to the gridded sampling of SRW. In the MC sampling, you only care about the total number of samples, which you can assess by examining a dark filed area somewhere on the periphery.

Please look at the examples of 14_SoftiMAX for wave propagation. For any plot, you can specify fluxKind='EsPCA' (this one is for the s polarization) that will create a stack array yourPlot.field3D of the shape (repeats, xaxis.bins, yaxis.bins), and this is what you want, I think. Please confirm.

Good luck with it!

kklmn avatar Apr 25 '20 10:04 kklmn

Thanks a lot for your suggestions and suggestions. I understand your concerns but I will give it a shot anyway.

I guess that what you are suggesting is to use multi_electron_stack to get the fields. for each "electron" then one would:

  • copy the Es to the beam.Es
  • fix the beam.(a,b,c) for all pixels to the electron "pointing"
  • propagate the beam as shown in the examples

The only doubt I have is how to get the electron "pointing". I don't think that multi_electron_stack can return it. Is there a smart way or should I create my own "multi_electron_stack" to return this information ?

I will try in the next days when I will find some time and I will report back. thanks

marcocamma avatar Apr 26 '20 08:04 marcocamma

The x,y,z will be the global coordinates of the stack pixels. The a,b,c are much less important. They can only slightly affect the calculated Kirchhof integral. I studied this a long time ago and concluded that in most cases the directions can be taken as paraxial: a=c=0 and b=1. In the propagation sequence, we assign the directions as being originated from the center of the previous optical element, in your case -- the source, independently of the actual trajectory of a given electron. I've never seen an example where this rule may break. You can also experiment with the a,b,c values by giving the origin a large transverse kick, much bigger than the electron beam size. I expect that you will see no effect of it.

kklmn avatar Apr 26 '20 09:04 kklmn

Hi again, I finally found some time to get started. I run in some issues though at the preliminary step of running normal "Monte Carlo" propagation.

This script (https://gist.github.com/marcocamma/76053e9c516cef1b9a7c03b76add92b7) calculates the diffraction from a slit at different distances.

The problem is that I get data only every second row and column (see attached screenshot below). The script is usually run with --nrays 1e5 or --nrays 1e6. But the problem appears for all nrays.

It can be seen in:

  • the plots
  • the data saved by the plot instances
  • the "total4D" array I save by hand.

Here the job output in case it can help job_output.txt, Do you have any idea what can be the reason causing it ? thanks a lot as usual, marco

Screenshot_2020-06-16_23-09-14

marcocamma avatar Jun 16 '20 21:06 marcocamma

Hi! Make sure rw.diffract() is really calculated for the screen pixels. In other words, when you do screen.prepare_wave(), check that x and z coordinates are those expected.

kklmn avatar Jun 17 '20 10:06 kklmn

I tried to verify what you have asked (see code below) and found that Es and x attributes of the screens look fine. No 'zero' values are present. The x and y values are what I would have expected. I used the very same machine I used when having problems. It seems that the problem comes from the plot instance. I will keep trying to understand, any help is appreciated, marco

import simple_diffract
bl = simple_diffract.build_beamline()
d = simple_diffract.run_process(bl)
b=d["screen_at_100m"].Es
x=d["screen_at_100m"].x

marcocamma avatar Jun 17 '20 12:06 marcocamma

I don't understand your answer.

Lines 132-133:

        xm, zm, _ = prepare_mesh(bl,screen)
        wave = screen.prepare_wave(bl.slit1, xm, zm)

make shure xm and zm are really the screen pixels coordinates you want.

kklmn avatar Jun 17 '20 12:06 kklmn

Problem solved. There was an inconsistency between the screen and the plot instances (same number of bins but different ranges). Sorry for having bothered you.

marcocamma avatar Jun 17 '20 12:06 marcocamma