vaipatel / morphops

Geometric Morphometrics in Python
https://morphops.readthedocs.io/en/latest/
MIT License
27 stars 4 forks source link

Scaling in GPA #9

Closed ethancohen123 closed 4 years ago

ethancohen123 commented 4 years ago

Is it possible to remove the scalling in the gpa function ? The size of the shapes I want to analyse matter for the analysis Thanks

vaipatel commented 4 years ago

Hi,

I'm wondering if you just need to make sure that the aligned landmark sets have their original scales. If so I can offer a slightly un-pretty albeit one-line workaround.

First, ensure that you run gpa with do_scaling=False which is the default. This will make it so that

Now if you just execute the line remove_scale(gpa_result['aligned'], gpa_result['b']), you will be dividing the unitized and aligned landmark sets by the inverses of their scales, which will effectively multiply these aligned landmark sets by their original scales. This should scale them back to their original scales.

Here's a short snippet:

import numpy as np
import morphops as mops

# Make a dataset
A = [[0,0],[2,0],[2,2],[1,3],[0,2]]
B = [[0.1,-0.1],[2,0],[2.3,1.8],[1,3],[0.4,2]]
C = [[-0.1,-0.1],[2.1,0],[2,1.8],[0.9,3.1],[-0.4,2.1]]

# Get the scale of the centered dataset - only needed for later np.allclose verification
centered_ABC = mops.remove_position([A,B,C])
orig_scales = mops.get_scale(centered_ABC)

# Do GPA on the dataset with `do_scaling=False`
gpa_result = mops.gpa([A,B,C])

# One line workaround
aligned_and_rescaled = mops.remove_scale(gpa_result['aligned'], gpa_result['b']))

# Check that the orig_scales and aligned_and_rescaled scales are the same
print(np.allclose(orig_scales, mops.get_scale(aligned_and_rescaled)))

And if you need the new sum of squared differences you can run lmk_util.ssqd(aligned_and_rescaled).

Would something like this work for your application?

ethancohen123 commented 4 years ago

Yes that works perfectly , thanks ! 👍