Ticket #10282 (closed: fixed)

Opened 6 years ago

Last modified 5 years ago

Create a Scatterer class that can be used for structure factor calculation

Reported by: Michael Wedel Owned by: Michael Wedel
Priority: major Milestone: Release 3.3
Component: Framework Keywords:
Cc: anders.markvardsen@… Blocked By: #10464
Blocking: #10262, #10283 Tester: Anders Markvardsen

Description

As part of the efforts for #10262, I want to be able to calculate the structure factor for a given reciprocal lattice vector. For this purpose, a Scatterer-class should be defined. It will contain the following information:

  • Element or Isotope (for information purposes only).
  • Scattering length
  • Fractional coordinates

Then, it will have a method to calculate the structure factor for a reciprocal lattice vector, with this formula, where b is the coherent scattering length, h is the vector and r is the coordinate-triplet (note that it is a complex number):

F_hkl = b * exp(i * h * r)

There should be a factory that creates scatterers from the element symbol (Data from Sears, 2003, http://dx.doi.org/10.1080/10448639208218770).

Then there has to be a class that is composed of an arbitrary number of scatterers, so that the structure factor for a given h may be calculated by summation over all scatterers in the unit cell.

Attachments

Mantid-Crystallography.pdf (3.4 KB) - added by Michael Wedel 6 years ago.
Crystallography-alternative.pdf (3.3 KB) - added by Michael Wedel 6 years ago.
Mantid-Crystallography-II.pdf (3.4 KB) - added by Michael Wedel 6 years ago.

Change History

comment:1 Changed 6 years ago by Michael Wedel

  • Blocking 10283 added

comment:2 Changed 6 years ago by Anders Markvardsen

  • Status changed from new to assigned

comment:3 Changed 6 years ago by Michael Wedel

I discovered Kernel::NeutronAtom, so I will use this for the implementation of Scatterer. Nevertheless, it could be useful to also have a string based creation method.

comment:4 Changed 6 years ago by Michael Wedel

  • Cc anders.markvardsen@… added

comment:5 Changed 6 years ago by Michael Wedel

  • Status changed from assigned to inprogress
Last edited 6 years ago by Michael Wedel (previous) (diff)

comment:6 Changed 6 years ago by Michael Wedel

Last edited 6 years ago by Michael Wedel (previous) (diff)

comment:7 Changed 6 years ago by Michael Wedel

Last edited 6 years ago by Michael Wedel (previous) (diff)

comment:8 Changed 6 years ago by Michael Wedel

Last edited 6 years ago by Michael Wedel (previous) (diff)

comment:9 Changed 6 years ago by Michael Wedel

Deleted old branch - turned out to be out of scope.

Last edited 6 years ago by Michael Wedel (previous) (diff)

comment:10 Changed 6 years ago by Michael Wedel

Refs #10282. Add IScatterer

Changeset: 9e3b33fb4c35cea2d6a1f6ef21dcb5704cc12456

comment:11 Changed 6 years ago by Michael Wedel

Refs #10282. Checkpointing work.

Changeset: 46443f1e80fd8e61966e5ad1a47d1a6c293083fa

comment:12 Changed 6 years ago by Michael Wedel

Refs #10282. Expanding interface of IScatterer

Changeset: 714eb0b064a5ba8c489d4804fce2bc0655df31a8

comment:13 Changed 6 years ago by Michael Wedel

Refs #10282. Removed rigid scatterer, added tests

Changeset: 67a9d3cea24aa5e11b5af56cf11aca9cbd103c18

comment:14 Changed 6 years ago by Michael Wedel

Refs #10282. Added occupancy to calculation, wrote test

Changeset: 90dbdba6d1d55189b28dd1d382dce96a65d323d6

comment:15 Changed 6 years ago by Michael Wedel

Refs #10282. Added static create method

Changeset: f69b3a344285a99cdb6f7a708ed241f3015e686d

comment:16 Changed 6 years ago by Michael Wedel

Refs #10282. Completed ScattererCollection and tests

Changeset: 81680d274ca58fe188859b531230caf14590c52c

comment:17 Changed 6 years ago by Michael Wedel

Refs #10282. Renamed ScattererCollection

Changeset: 9a802904a1b556144dabdde98ff30be2e460b6ab

comment:18 Changed 6 years ago by Michael Wedel

Refs #10282. Added documentation.

Changeset: be1467a1ee5c974284d516cfa7b962a2c11750fe

comment:19 Changed 6 years ago by Michael Wedel

  • Status changed from inprogress to verify
  • Resolution set to fixed

Notes

I tried to solve this first using the function fitting framework, introducing a new domain type etc. In the end, this turned out to be more complex than in the beginning, because I found it a bit hard to construct a composite scatterer. I'm sure this can be done anyway, wrapping the structure that I went for now.

A bit contrary to the UML diagram in #10262, IScatterer is coupled to UnitCell and SpaceGroup, because this makes many calculations much more convenient. Since the only use case I can come up with for IScatterer is structure factor calculation with a crystal structure as part of the input I think this is acceptable.

What is a bit unsolved here is convenient creation of scatterers - this will be solved in #10283, because CrystalStructure will probably be the only place where this is used, so it's unlikely these classes will be used directly by anyone.

Testing information

Not much to test except code review. There is one test in CompositeScatterer, which compares structure factors of a hypothetical structure with structure factors calculated by SHELXL, this is probably interesting to see a "usage example".

comment:20 Changed 6 years ago by Michael Wedel

Refs #10282. Change system test to parse reference operations

Changeset: bef90d54396ad185a0ba1a66d7b88dcbe668bd72

comment:21 Changed 6 years ago by Michael Wedel

Refs #10282. Remove faulty lines from reference data

Had overlooked some lines in the reference data file that just contained "-1".

Changeset: 17e96b1b9d98f4c60cfcce0239f6ef691f9d9a0a

comment:22 Changed 6 years ago by Michael Wedel

  • Status changed from verify to reopened
  • Resolution fixed deleted

comment:23 Changed 6 years ago by Michael Wedel

  • Status changed from reopened to inprogress

Refs #10282. Checkpointing work

Changeset: 7a220020e7879718699d52807b5e0114cb6267df

comment:24 Changed 6 years ago by Michael Wedel

I decided to try another thing to enable general string based construction for scatterers (which will be required for saving etc.) by utilizing Kernel::Property. PropertyManager does everything I need, I think.

comment:25 Changed 6 years ago by Michael Wedel

Refs #10282. Added conversion function between unit cell and string

For using UnitCell in PropertyWithValue, it would be necessary to change the stream operator of UnitCell, because that is only used for printing at the moment and the precision is limited to 1e-3, which is not enough for cases like powder diffraction (for example at POLDI, where lattice parameters are determined with precision better than 1e-4).

Instead of modifying the interface of UnitCell I chose to add explicit string conversion functions. It should be straightforward to change later on.

Changeset: 1672ac53b9b651ce13a8267ec0d2d62fc27df664

comment:26 Changed 6 years ago by Michael Wedel

Refs #10282. Changed IScatterer interface, added factory

IScatterer now inherits from PropertyManager. There's now also a factory for consistent creation of scatterers.

Changeset: 0b6ba9a22d268f27cecfad1de15ffc3949fabe04

comment:27 Changed 6 years ago by Michael Wedel

Refs #10282. Removing unit test

This was only meant to be added temporarily for finding a problem in a system test.

Changeset: dad21672aa463c6b4977aa06413ad2a29a610d78

comment:28 Changed 6 years ago by Michael Wedel

  • Status changed from inprogress to verify
  • Resolution set to fixed

As written in comment 25, I changed the interface to use Property/PropertyManager. This way we can write new scatterers (for example with anisotropic displacement parameters) easily. In addition I think it will be easier to write code for reading/writing crystal structures from/to files.

System test changed

Because I added Fd-3m to the space group factory for testing purposes, I discovered a problem in the system test which had to be fixed. systemtests requires merging as well.

comment:29 Changed 6 years ago by Anders Markvardsen

  • Status changed from verify to verifying
  • Tester set to Anders Markvardsen

comment:30 Changed 6 years ago by Anders Markvardsen

Some initial observations from here:

  1. Inherite from PropertyManager is this necessary?
  1. Should a scatter have knowledge of unit cell, space group and position?

Changed 6 years ago by Michael Wedel

comment:31 Changed 6 years ago by Michael Wedel

The diagram contains some (most, but not all) of the crystallography related classes in MantidGeometry and how they interact. Classes with orange background are classes that are likely to be used from "outside". PointGroup is grey, because at the moment it does not inherit from ProductOfCyclicGroups and cannot be extracted from SpaceGroup - both things will be implemented later.

Also, some more thoughts about the UnitCell/SpaceGroup dilemma after discussion with Anders:

  • Easy conclusion first: I will remove the inheritance from PropertyManager and keep it as a private member. "Composition over inheritance" - did not realize this here when I was writing the code. Additionally, it can be exchanged for something else later.
  • I still think "calculateStructureFactor" should not be implemented directly by CrystalStructure. Every change of calculation method would result in a new subclass of CrystalStructure, which seems somehow strange to me. Having an IScatterer is actually a case of the Strategy Pattern, because essentially it makes the structure factor calculation method exchangeable.
  • SpaceGroup can be moved out of IScatterer. CrystalStructure would then need to keep track of the scatterers it holds by itself. Like now, it would take a CompositeScatterer for construction, which holds n scatterers forming the asymmetric unit. Internally however, it holds a CompositeScatterer which contains all scatterers in the unit cell, with their respective position. I did not implement it this way, because there are potentially a lot more objects in CrystalStructure (think complex intermetallic compounds with 1k atoms in the cell) this way. Many calculations will be redundant (the amplitudes of the complex structure factors will be calculated for each scatterer in the cell, instead of just once for each scatterer in the asymmetric unit).
  • Unit cell could be moved out at the cost of creating another class, "Reflection", which is used instead of plain Kernel::V3D as representation of hkl. Reflection would probably hold hkl, d, F. On the other hand, a reflection may be characterized by many more things than just hkl, d and F depending on the context (think reciprocal lattice vector through orientation matrix as one example) - so at this point there is no easy solution either.
  • If we remove position also, there is nothing left in IScatterer. I did not include NeutronAtom into IScatterer, because it doesn't necessarily have to be an atom. It could be a molecule, or a particle (SANS) or some other thing that scatters neutrons.

Currently, my "favourite" solution is to "step back a bit", and rename IScatterer to IScattererInUnitCell - that would cover the scope of the ticket. IScatterer could be kept with a more or less empty interface, in case anyone would like to implement scatterers for other purposes.

comment:32 Changed 6 years ago by Michael Wedel

Had some more time to think and read briefly about other techniques that involve some sort of "scattering". The name "IScatterer" is probably too broad - I was thinking in terms of elastic Bragg scattering only. Maybe a better name for the interface could be "BraggScatterer".

Then, instead of depending on SpaceGroup, there could be a method "setEquivalentPositions" (which CrystalStructure calculates using SpaceGroup).

For removing UnitCell I still don't see an easy way.

Edit: Added diagram for suggested alternative.

Last edited 6 years ago by Michael Wedel (previous) (diff)

Changed 6 years ago by Michael Wedel

comment:33 Changed 6 years ago by Martyn Gigg

  • Blocked By 10464 added

comment:34 Changed 6 years ago by Anders Markvardsen

  • Status changed from verifying to reopened
  • Resolution fixed deleted

Design Crystallography-alternative.pdf looks good.

comment:35 Changed 6 years ago by Michael Wedel

As I tried to remove SpaceGroup from BraggScatterer, I realized it does not really work that well in terms of "anticipating what's happening" for users of the interface. When the position of the scatterer is changed, the equivalent positions are not consistent with position any more. I don't think there is a reasonable behaviour for this case. Keeping the old equivalent positions does definitely not make sense. Setting the equivalent positions to only the position that has just been assigned makes not much sense either, because that would be highly unexpected (at least to me) - multiplicity of the position would change without any apparent reason.

I will solve this by introducing another class which implements BraggScatterer and which IsotropicAtomBraggScatterer inherits from. This is the cleanest solution and it also makes CompositeBraggScatterer more simple. If anyone else would like to implement this behaviour differently, it's no problem to do so.

comment:36 Changed 6 years ago by Michael Wedel

  • Status changed from reopened to inprogress

Refs #10282. Renamed classes to fit diagram

Changeset: 53f2099856f81b399c47f0b8b1d06ac81357860f

comment:37 Changed 6 years ago by Michael Wedel

Refs #10282. Changed BraggScatterer interface

Changed the interface of BraggScatterer to be independent of UnitCell, SpaceGroup and V3D. These are handled in BraggScattererInCrystalStructure now.

Changeset: b4a8c560e19824f376753af479b9383ad4535789

comment:38 Changed 6 years ago by Michael Wedel

Notes

  • After some trials I decided not to make PropertyManager a private member of BraggScatterer, because this would require wrapping most methods of PropertyManager.
  • To remove UnitCell and SpaceGroup (and also Position) from BraggScatterer I introduced an intermediate class called BraggScattererInCrystalStructure, which has these three properties.
  • CompositeBraggScatterer is now more general and instead of declaring any properties itself, it exposes properties of member scatterers that are marked for this. BraggScattererInCrystalStructure for example marks UnitCell and SpaceGroup, which means that a CompositeBraggScatterer which contains an IsotropicAtomBraggScatterer also has those properties. When values are assigned to the composite property, the value is propagated to all members (as before).

I attached a new diagram to reflect these design changes.

Changed 6 years ago by Michael Wedel

comment:39 Changed 6 years ago by Michael Wedel

  • Status changed from inprogress to verify
  • Resolution set to fixed

comment:40 Changed 6 years ago by Anders Markvardsen

  • Status changed from verify to verifying

comment:41 Changed 6 years ago by Anders Markvardsen

  • Status changed from verifying to closed

Merge remote-tracking branch 'origin/feature/10282_create_scattering_function'

Full changeset: 36df3c6621afffdb71e0394d37d7290999145b91

comment:42 Changed 6 years ago by Anders Markvardsen

documentation of classes are clear

comment:43 Changed 6 years ago by Martyn Gigg

Merge branch 'feature/10282_create_scattering_function'

Full changeset: 0bd60496d38ca5a4cb3c6f2b8fc9cb2107d8c233

comment:44 Changed 5 years ago by Stuart Campbell

This ticket has been transferred to github issue 11124

Note: See TracTickets for help on using tickets.