Open tjlane opened 9 hours ago
I like the idea of having "limited scope, defined content" objects that can be used to simplify the maintenance of certain code. Big picture, I think something like Map
could be very useful for providing Amplitudes/Phases/HKLs/crystal metadata (optionally uncertainties) in a way that downstream code can use.
My main design concern is with regard to subclassing DataSet
. In general, that opens up a lot of corner cases that can lead to "reversions" from Map
-->parent (DataSet
), which will require a lot of overloading of methods to correct. Given that the purposes of this Map
class are more restricted than the general-purpose DataSet
, I think there are two options that could simplify our lives:
rs.DataSet
to simplify implementation:This could look something like this, and we can also provide :
class Map:
millers : n x 3 np array
amplitudes : n np array
phases : n np array
uncertainties : None or n np array
cell : gemmi.UnitCell
spacegroup : gemmi.SpaceGroup
...
rs.DataSet
as an attribute. Use methods to access underlying content
class Map:
_dataset : rs.DataSet
...
def getters/setters
...
I think these sorts of implementations will be easier to maintain than starting with a general-purpose object and restricting its use. I'm not sure of all the intended uses (and I haven't yet dug into much of the meteor
code), so I don't have a great sense of what's best
In
meteor
, we found it very useful to implement aMap
class. I actually tried to avoid doing this, but eventually found it necessary to keep the rest of the code clean/sane. Otherwise, you start to pass around a huge number of column labels, and the entire thing becomes a crazy bookkeeping exercise.We have an implementation that should be considered a functional prototype, not a final version: https://github.com/rs-station/meteor/blob/main/meteor/rsmap.py
The current implementation has a good interface, but the implementation is sub-optimal. It is basically a subclass of
rs.DataSet
that restricts the columns, only allowing amplitudes, phases, uncertainties, and H/K/L. This has a big downside in that it can affect inheritedpandas.DataFrame
orrs.DataSet
methods in unexpected ways, making for a less than ideal user and developer experience.That said, such a class could be generally useful to
rs
users, so it would be great to push a better version of this "upstream" intors
, and havemeteor
simply use that implementation.what is a
Map
?We can conceptualize it as a special case of an
rs.DataSet
, where you flag specific columns as:And you can only have ONE of each of these special columns. This opens up a lot of nice logic: converting to real space and back, comparing two map objects (think of a scaling function:
scale(map1, map2)
), etc. The simple big feature is that by declaring which columns are amplitudes/phases at the time of instantiation, you get around having to keep track of column label names.what decisions do we face?
First, feedback would be appreciated as to if we want to implement a
Map
object inrs
. I am a yes vote on this. But obviously we need some consensus before proceeding.If we decide to do it, we need to decide on a general implementation strategy. Here are the possibilities as I see them -- if I didn't have the imagination to come up with a good option, please speak up!
rs.DataSet
and simply annotate what columns are amplitudes, phases, uncertainties. Place dtype requirements on these columns. The instance, though, can have other, unrelated columns (this differs from current implementation). This is probably the simplest model to implement.rs.DataSet
, be strict about what columns are allowed. Aggressively test inherited methods to ensure they work.These appear in my order of preference. Each model has advantages and disadvantages, though. Feedback wanted.
@JBGreisman @kmdalton @alisiafadini