Closed dnjohnstone closed 6 months ago
In other work with @robtovey we used MULTEM (https://github.com/Ivanlh20/MULTEM) for some multislice simulations via its matlab interface. I think if we do go with providing access to multislice simulations through diffsims we might consider doing it by writing a python wrapper for that.
In short, I think we want all of these as well as adding:
* Kikuchi diffraction
My plans for this:
ReciprocalLatticePoint
class, a geometrical model (not using structure factors) for projecting lines ("Kikuchi bands") on an EBSD detector.kikuchipy.detectors
module with EBSDDetector
and ProjectionCentre
(pattern centre) classes, and a kikuchipy.projections
module with a Gnomonic
class. The EBSDDetector.projection
attribute would be set to Gnomonic
.Do these modules and classes overlap with any ideas anyone else have? I'm not interested in writing code specifically to project bands onto a TEM detector, however I can work with someone who is.
Yes, this gets to the point nicely. I think my ideal architecture (right now, subject to change as with everything) for the kinematical case would be:
calculate_orientated
(or similar) which does what calculate_ed_data
does at the moment, for a single crystal, deals with shape functions etc.
calculate_powder
(or similar) which does what calculate_profile_data
does, doesn't have a shape factor term, but could (in future) be expanded to deal with textured data
The key point is that internally these should both rely on the same kinematical (structure factor) model, which we can then commit some real effort to making effective. I think this should be what is currently simulate_kinematical_scattering
which should also be offered to users for when they have more interesting cases (that they still want to simulate kinematically).
I think AtomicDiffractionGenerator is probably okay as is right now.
Then in terms of dynamic simulations, (okay @hakonanes has dealt with Kikuchi already) I think we should be wrapping things. I've got a fair sense of what's out there for multislice codes (although they all come with their own installation challenges) but in terms of Bloch wave I would need to do some investigation.
I think getting the kinematical case sorted is the first thing though.
My plans for this:
Locally I have, using the
ReciprocalLatticePoint
class, a geometrical model (not using structure factors) for projecting lines ("Kikuchi bands") on an EBSD detector.My plan was to create a
kikuchipy.detectors
module withEBSDDetector
andProjectionCentre
(pattern centre) classes, and > akikuchipy.projections
module with aGnomonic
class. TheEBSDDetector.projection
attribute would be set toGnomonic
.Do these modules and classes overlap with any ideas anyone else has? I'm not interested in writing code specifically to project bands onto a TEM detector, however I can work with someone who is.
I would suggest in the medium term having something, however qualitative in is such a big improvement that it's still worth doing. If it's built in a way that makes it extensible, then as/when people want more, more will happen.
- My plan was to create a
kikuchipy.detectors
module withEBSDDetector
andProjectionCentre
(pattern centre) classes, and akikuchipy.projections
module with aGnomonic
class. TheEBSDDetector.projection
attribute would be set toGnomonic
.Do these modules and classes overlap with any ideas anyone else has? I'm not interested in writing code specifically to project bands onto a TEM detector, however I can work with someone who is.
The only thing that comes to mind about this is that we also have a pyxem.detectors
module, which defines pyFAI
Detector
objects for azimuthal integration.
It sounds like your EBSDDetector
might incorporate aspects of the experimental geometry, which is something we need to decide how to do best in both transmission ED and XRD - it would be nice if this were harmonized, but I wouldn't let it hold you up!
The key point is that internally these should both rely on the same kinematical (structure factor) model, which we can then commit some real effort to making effective. I think this should be what is currently
simulate_kinematical_scattering
which should also be offered to users for when they have more interesting cases (that they still want to simulate kinematically).
Hopefully that's what #102 is going to do, right? At least at first pass, or you mean something else?
And you're saying that we should have one diffraction generator that takes both the crystalline and non-crystalline cases mentioned above where a structure factor is evaluated?
I think AtomicDiffractionGenerator is probably okay as is right now.
My only issue with this one is the name, all of our simulation options are based on atomistic models... FFTDiffractionGenerator
?
The key point is that internally these should both rely on the same kinematical (structure factor) model, which we can then commit some real effort to making effective. I think this should be what is currently
simulate_kinematical_scattering
which should also be offered to users for when they have more interesting cases (that they still want to simulate kinematically).Hopefully that's what #102 is going to do, right? At least at first pass, or you mean something else?
And you're saying that we should have one diffraction generator that takes both the crystalline and non-crystalline cases mentioned above where a structure factor is evaluated?
Yeah, #102 is the first step in this certainly. I think what I'm suggesting is that we start thinking in the terms laid out by #102. So yes, there will be a kinematical simulator that deals with gaussian/planar probes and any arrangements of atoms, then we wrap this to give the "common" cases, here just single-crystal and powder.
I think AtomicDiffractionGenerator is probably okay as is right now.
My only issue with this one is the name, all of our simulation options are based on atomistic models...
FFTDiffractionGenerator
?
Yep, I will do that alongside #98
Yeah, #102 is the first step in this certainly. I think what I'm suggesting is that we start thinking in the terms laid out by #102. So yes, there will be a kinematical simulator that deals with gaussian/planar probes and any arrangements of atoms, then we wrap this to give the "common" cases, here just single-crystal and powder.
Ok - just don't forget that we evaluate the Structure Factor for k = g only in the current crystalline / powder case, and you could convolve the answer with a top hat to get a "Bessel probe" solution. But in the non-crystalline case you have to evaluate the Structure Factor for all k on the detector and we've done it by multiplying in by the probe function keeping everything in direct space.
They probably could all use the same code though as you say.
I haven't fully understood the "generator architecture"... but I think I have an idea of how to set up a geometrical/kinematical EBSD simulation in kikuchipy (or diffsims):
orix.crystal_map.Phase
, ReciprocalLatticePoint
(Miller indices) and EBSDDetector
(width, height, projection/pattern center (PC), detector tilt, sample tilt [fits best here, I think]). The detector needs to be a class, since it stores so many parameters conveniently.DiffractionGenerator
object. Acceleration voltage for kinematical simulation, this should be obtained from the ReciprocalLatticePoint
object.orix.quaternion.Orientation
to a method to obtain a DiffractionSimulation
, storing gnomonic coordinates of Miller indices on the detector as pole lines, also zone axes.sim_as_signal
in pyxem. Preferrably HyperSpy markers should be easily created from the DiffractionSimulation
to overlay experimental and/or dynamically simulated (with EMsoft/Bruker DynamicS) EBSD patterns.What I would like to facilitate is easy adjustements of stuff and immediately visualize the change by just a few lines of code, like changing the detector parameters like PC in the Detector
class, the orientations etc.
The detector class is important for coordinate transformations of planes in the unit cell to lines on the detector. Is there some part of the code for projecting spots onto a TEM diffraction detector that could be abstracted out as its own detector class, so that we could replace the EBSDDetector
with this TEMDetector
(or whatever) and project lines onto this instead?
The detector class is important for coordinate transformations of planes in the unit cell to lines on the detector. Is there some part of the code for projecting spots onto a TEM diffraction detector that could be abstracted out as its own detector class, so that we could replace the
EBSDDetector
with thisTEMDetector
(or whatever) and project lines onto this instead?
Not yet, but there is likely to be in future. Just one small point, I think acclerating_voltage should be provided to a DiffractionGenerator
directly rather than as be attached to a given ReciprocalLatticePoint
It seems to me like the code and peoples interests have moved on beyond this discussion, especially after the introducting of a new simulations module. I'm closing for now, please re-open if I shouldn't have.
In #111 @hakonanes asked about where the new
ReciprocalLatticePoint
orCrystalPlane
class will be used indiffsims
. This reminded me that we need to look at the overall architecture for different types of diffraction simulation indiffsims
, which follows on from an offline conversation with @pc494 and @JoonatanL.To summarize the current types of simulators in
diffsims
, we have:The
calculate_ed_data
method ofDiffractionGenerator
computes a spot electron diffraction pattern by evaluating the Structure Factor Fhkl for relevant crystal planes, code is here:https://github.com/pyxem/diffsims/blob/848279682ca77e296e7bfb6b27991ceed1cc137e/diffsims/generators/diffraction_generator.py#L93
The
calculate_profile_data
method ofDiffractionGenerator
computes a one dimensional electron (powder type) electron diffraction pattern based on evaluating the Structure Factor Fhkl for relevant families of crystal planes, code is here:https://github.com/pyxem/diffsims/blob/848279682ca77e296e7bfb6b27991ceed1cc137e/diffsims/generators/diffraction_generator.py#L179
The
calculate_ed_data
method ofAtomicDiffractionGenerator
computes a single crystal spot/disk like electron diffraction pattern for a specified probe function and crystal structure by evaluating the FFT of the crystal potential and probe function. This is similar to one slice of a multislice code, code is here:https://github.com/pyxem/diffsims/blob/848279682ca77e296e7bfb6b27991ceed1cc137e/diffsims/generators/diffraction_generator.py#L326
The
simulate_kinematic_scattering
function computes a single-crystal electron diffraction pattern for an arbitrary arrangement of atoms under either plane wave or Gaussian probe illumination by evaluating the structure factor of the arbitrary atomic arrangment. In othe words the atomic scattering factor of every atom in the user defined object is summed to simulate diffraction, code is here:https://github.com/pyxem/diffsims/blob/848279682ca77e296e7bfb6b27991ceed1cc137e/diffsims/utils/sim_utils.py#L296
The last two approaches are very helpful because they take account of the object shape properly if you're simulating diffraction from a nanocrystal and they can also be used to simulate scattering from non-crystalline or defective materials. The FFT approach has some advantages in terms of computational efficiency, but direct summation of atomic scattering factors has the advantage that arbitrarily small displacements of atomic coordinates are easy to incorporate.
In short, I think we want all of these as well as adding:
Clearly the API here is a total mess and I think we should tear it up and start again after #111 is merged and we re-evaluate these simulators in any case.
I think the people mentioned above have some interest in this and hopefully this helps let everyone know some stuff that is probably only in my head right now.
In writing this down, it strikes me that @CSSFRancis might have some interest too.