lsst-camera-dh / ghosts

Simulate Rubin LSST ghosts image
Other
0 stars 0 forks source link

Implement interface to handle a batoid telescope geometry in terms of a set of position and rotation matrices #10

Closed bregeon closed 2 years ago

bregeon commented 2 years ago

a batoid telescope is a batoid object defined as a CompoundOptic, that is basically accessible as dictionaries and lists of parameters:

CompoundOptic([CompoundOptic([Lens([RefractiveInterface(Sphere(2.824), obscuration=ObscNegation(ObscCircle(0.775)), name='L1_entrance', coordSys=CoordSys(array([0.        , 0.        , 3.39747259]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099))), RefractiveInterface(Sphere(5.021), obscuration=ObscNegation(ObscCircle(0.775)), name='L1_exit', coordSys=CoordSys(array([0.        , 0.        , 3.47970259]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099)), outMedium=Air(69.328, 293.15, 1.067))], name='L1', coordSys=CoordSys(array([0.        , 0.        , 3.39747259]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067)), Lens([RefractiveInterface(Plane(), obscuration=ObscNegation(ObscCircle(0.551)), name='L2_entrance', coordSys=CoordSys(array([0.        , 0.        , 3.89234461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099))), RefractiveInterface(Asphere(2.529, -1.57, array([ 0.      , -0.001656])), obscuration=ObscNegation(ObscCircle(0.551)), name='L2_exit', coordSys=CoordSys(array([0.        , 0.        , 3.92234461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099)), outMedium=Air(69.328, 293.15, 1.067))], name='L2', coordSys=CoordSys(array([0.        , 0.        , 3.89234461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067)), Lens([RefractiveInterface(Sphere(5.632), obscuration=ObscNegation(ObscCircle(0.375)), name='Filter_entrance', coordSys=CoordSys(array([0.        , 0.        , 4.27192461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099))), RefractiveInterface(Sphere(5.606), obscuration=ObscNegation(ObscCircle(0.375)), name='Filter_exit', coordSys=CoordSys(array([0.        , 0.        , 4.28982461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099)), outMedium=Air(69.328, 293.15, 1.067))], name='Filter', coordSys=CoordSys(array([0.        , 0.        , 4.27192461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067)), Lens([RefractiveInterface(Quadric(3.169, -0.962), obscuration=ObscNegation(ObscCircle(0.361)), name='L3_entrance', coordSys=CoordSys(array([0.        , 0.        , 4.34092461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099))), RefractiveInterface(Sphere(-13.36), obscuration=ObscNegation(ObscCircle(0.361)), name='L3_exit', coordSys=CoordSys(array([0.        , 0.        , 4.40092461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=SellmeierMedium((0.6961663, 0.4079426, 0.8974794, 0.00467914825849, 0.013512063073959999, 97.93400253792099)), outMedium=Air(69.328, 293.15, 1.067))], name='L3', coordSys=CoordSys(array([0.        , 0.        , 4.34092461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067)), Detector(Plane(), obscuration=ObscNegation(ObscCircle(0.4)), name='Detector', coordSys=CoordSys(array([0.        , 0.        , 4.42942461]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067))], name='LSSTCamera', coordSys=CoordSys(array([0.        , 0.        , 3.39747259]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067))], name='LSST', coordSys=CoordSys(array([0., 0., 0.]), array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])), inMedium=Air(69.328, 293.15, 1.067), outMedium=Air(69.328, 293.15, 1.067))

when simulating a given telescope geometry, how should I store that information and how do I get simple set of "alignment" constants from that?

bregeon commented 2 years ago

Simple alignment constants are easily retrieved through the batoid interface:

> rotated_telescope['L1'].coordSys.origin

(array([0.        , 0.        , 3.39747259]),

> rotated_telescope['L1'].coordSys.rot
 array([[ 0.9998477 ,  0.        ,  0.01745241],
        [ 0.        ,  1.        ,  0.        ],
        [-0.01745241,  0.        ,  0.9998477 ]]))
bregeon commented 2 years ago

I have defined a kind of GEOM_DICT, similar to the BEAM_CONFIG dict:

GEOM_DICT = {'L1': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
                          'L2': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
                          'L3': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]}}

where the shift vector is just the shifts along x, y and z. and the rotations vector contains the Euler rotation angles, around x, y, z.

bregeon commented 2 years ago

The idea would then be to have a set of geometry configurations that could be stored in a separate pandas.DataFrame. Beam configurations should also be numbered and stored in another separate pandas.DataFrame. The spots data data frame would then only report a column for the beam config number and one for the geom config number.

bregeon commented 2 years ago

Need to add an id:

GEOM_CONFIG_0 = {'geom_id': 0,
                 'L1': {'shift': [0.0, 0.0, 0.0], 'rotations': [0., 0., 0.]},
                 'L2': {'shift': [0.0, 0.0, 0.0], 'rotations': [0., 0., 0.]},
                 'L3': {'shift': [0.0, 0.0, 0.0], 'rotations': [0., 0., 0.]},
                 'Filter': {'shift': [0.0, 0.0, 0.0], 'rotations': [0., 0., 0.]},
                 'Detector': {'shift': [0.0, 0.0, 0.0], 'rotations': [0., 0., 0.]}}
gd0 = pd.DataFrame(data=GEOM_CONFIG_0)
geom_id L1 L2 L3 Filter Detector
0 [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0]
0 [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0]
bregeon commented 2 years ago
gc = pd.concat([gd0, gd, gd2])
gc.sort_values('geom_id')
geom_id L1 L2 L3 Filter Detector
0 [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0]
0 [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0] [0.0, 0.0, 0.0]
1 NaN [0.1, 0.0, 0.0] NaN NaN NaN
100 [0.001, 0.001, 0.001] [0.001, 0.001, 0.001] [0.001, 0.001, 0.001] NaN NaN
100 [0.1, 0.1, 0.1] [0.1, 0.1, 0.1] [0.1, 0.1, 0.1] NaN NaN
bregeon commented 2 years ago

newf=gc[gc['geom_id']==100]

geom_id L1 L2 L3 Filter Detector
100 [0.001, 0.001, 0.001] [0.001, 0.001, 0.001] [0.001, 0.001, 0.001] NaN NaN
100 [0.1, 0.1, 0.1] [0.1, 0.1, 0.1] [0.1, 0.1, 0.1] NaN NaN
bregeon commented 2 years ago
# get shifts dict way
> gc[gc['geom_id']==100]['L1']['shift']
[0.001, 0.001, 0.001]

To dictionnary:

> h=newf.to_dict()

{'geom_id': {'shift': 100, 'rotations': 100},
 'L1': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
 'L2': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
 'L3': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
 'Filter': {'shift': nan, 'rotations': nan},
 'Detector': {'shift': nan, 'rotations': nan}}

Fixing the geom_id:

h['geom_id']=h['geom_id']['shift']

{'geom_id': 100,
 'L1': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
 'L2': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
 'L3': {'shift': [0.001, 0.001, 0.001], 'rotations': [0.1, 0.1, 0.1]},
 'Filter': {'shift': nan, 'rotations': nan},
 'Detector': {'shift': nan, 'rotations': nan}}