Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:50

0001 #!/usr/bin/env python
0002 #
0003 # Copyright (c) 2019 Opticks Team. All Rights Reserved.
0004 #
0005 # This file is part of Opticks
0006 # (see https://bitbucket.org/simoncblyth/opticks).
0007 #
0008 # Licensed under the Apache License, Version 2.0 (the "License"); 
0009 # you may not use this file except in compliance with the License.  
0010 # You may obtain a copy of the License at
0011 #
0012 #   http://www.apache.org/licenses/LICENSE-2.0
0013 #
0014 # Unless required by applicable law or agreed to in writing, software 
0015 # distributed under the License is distributed on an "AS IS" BASIS, 
0016 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
0017 # See the License for the specific language governing permissions and 
0018 # limitations under the License.
0019 #
0020 
0021 """
0022 sphere.py : SphereReflect intersection, polarization calculation and spatial plot
0023 =====================================================================================
0024 
0025 
0026 """
0027 import os, sys, logging, numpy as np
0028 log = logging.getLogger(__name__)
0029 
0030 from mpl_toolkits.mplot3d import Axes3D
0031 import matplotlib.pyplot as plt
0032 
0033 from opticks.ana.base import opticks_main
0034 from opticks.ana.nbase import vnorm
0035 from opticks.ana.evt import Evt, costheta_, cross_, norm_
0036 from opticks.ana.boundary import Boundary   
0037 
0038 deg = np.pi/180.
0039 
0040 
0041 class SphereReflect(object):
0042     def __init__(self, sel):
0043     
0044         p0 = sel.rpost_(0)[:,:3]
0045         p1 = sel.rpost_(1)[:,:3]
0046         p_in = p1 - p0  
0047 
0048         pp = sel.rpost_(1)[:,:3]
0049         pl = sel.rpost_(2)[:,:3]
0050         p_out = pl - pp
0051 
0052         e0 = sel.rpol_(0)
0053         e1 = sel.rpol_(1)
0054 
0055         self.p0 = p0
0056         self.p1 = p1
0057         self.pl = pl
0058         self.p_in = p_in
0059         self.p_out = p_out
0060 
0061         self.e0 = e0
0062         self.e1 = e1
0063 
0064 
0065     def check_radius(self):
0066         """
0067         Asymmetric wider distribution than expected, from ~99 to 101.4 until
0068         fixed sphere positioning, when get expected symmetry
0069 
0070         ::
0071 
0072             In [50]: r.min()
0073             Out[50]: 99.96880356309731
0074 
0075             In [51]: r.max()
0076             Out[51]: 100.03083354506256
0077 
0078             In [53]: np.average(r)
0079             Out[53]: 100.00002525999686
0080 
0081 
0082         """
0083         #r = np.linalg.norm(self.p1, 2, 1)
0084         r = vnorm(self.p1)
0085         log.info("r min/max %s %s " % (r.min(), r,max() )) 
0086 
0087         plt.hist(r, bins=100)
0088 
0089         return r 
0090 
0091     def intersection(self):
0092         """
0093         """
0094         origin = np.array([0,0,0])
0095         radius = 100.
0096 
0097         direction = np.array([1,0,0])
0098 
0099         ray_origin = self.p0
0100         ray_direction = np.tile(direction, len(ray_origin)).reshape(-1,3)
0101         center = np.tile(origin, len(ray_origin)).reshape(-1,3)
0102 
0103         O = ray_origin - center 
0104         D = ray_direction
0105 
0106         b = np.sum( O*D, axis=1 )
0107         c = np.sum( O*O, axis=1 ) - radius*radius
0108 
0109         disc = b*b-c    # hmm potential unhealthy subtraction of two large values
0110 
0111         #assert np.all(disc > 0)   
0112 
0113         msk = disc > 0 
0114 
0115         sdisc = np.sqrt(disc)
0116         root1 = -b -sdisc
0117 
0118         p1c = root1[:,None]*ray_direction + ray_origin
0119 
0120         nrm = (O + D*root1[:,None])/radius
0121 
0122         return p1c, nrm, msk 
0123 
0124 
0125     def check_surface_normal(self):
0126         """
0127 
0128         In [187]: nnrm = np.linalg.norm(nrm, 2, 1)
0129 
0130         In [188]: nnrm[sr.msk].min()
0131         Out[188]: 0.99999999999999667
0132 
0133         In [189]: nnrm[sr.msk].max()
0134         Out[189]: 1.0000000000000033
0135 
0136         """
0137         sr = self
0138         p1c, nrm, msk = sr.intersection()
0139         #nnrm = np.linalg.norm(nrm, 2, 1)
0140         nnrm = vnorm(nrm)
0141  
0142 
0143     def check_intersection(self):
0144         """
0145 
0146             In [155]: sr.mdp1[:,0].min()
0147             Out[155]: -1.7650434697386426
0148 
0149             In [156]: sr.mdp1[:,0].max()
0150             Out[156]: 1.8097476126588909
0151 
0152             plt.hist(sr.dp1[sr.msk], bins=100)     # sharp zero spike
0153 
0154         """
0155         sr = self
0156 
0157         p1c, nrm, msk = sr.intersection()
0158         p1 = self.p1
0159 
0160         rperp = np.sqrt(np.sum( p1[:,1:3]*p1[:,1:3] , axis=1))
0161         dp1 = p1c - p1
0162         mdp1 = dp1[msk]
0163 
0164         self.p1c = p1c
0165         self.msk = msk
0166         self.dp1 = dp1
0167         self.mdp1 = mdp1
0168         self.rperp = rperp
0169 
0170         nrm = norm_(p1c)                                    # surface normal at intersection points 
0171         #inc = np.tile( [1,0,0], len(nrm) ).reshape(-1,3)    # directions of squadron incident along +X
0172 
0173         idir = norm_(self.p_in)
0174         ndir = norm_(self.p_out) 
0175         trans = np.cross(idir, nrm )                          # direction perpendicular to plane of incidence, A_trans
0176         paral = norm_(np.cross( ndir, trans ))   # exit basis
0177 
0178         self.nrm = nrm
0179         self.idir = idir
0180         self.ndir = ndir 
0181         self.trans = trans
0182         self.paral = paral
0183 
0184         #sr = self
0185         #plt.hist2d(sr.rperp[sr.msk], sr.mdp1[:,0], bins=100)   # largest deviations are tangential
0186 
0187 
0188 
0189 
0190     def check_polarization(self):
0191         """
0192         Direction of incident rays and reflection/transmission rays together 
0193         with surface normal allow the orthonormal bases at each stage to be calculated. 
0194         With which the polarisation can be projected upon to see if it makes sense.
0195 
0196         Polarized in direction of photon(not real) will that mess things up?::
0197 
0198             In [78]: e0 = sel.recpolarization(0)
0199 
0200             In [79]: e1 = sel.recpolarization(1)
0201 
0202             In [80]: e0
0203             Out[80]: 
0204             array([[ 1.,  0.,  0.],
0205                    [ 1.,  0.,  0.],
0206                    [ 1.,  0.,  0.],
0207                    ..., 
0208                    [ 1.,  0.,  0.],
0209                    [ 1.,  0.,  0.],
0210                    [ 1.,  0.,  0.]])
0211 
0212             In [81]: e1
0213             Out[81]: 
0214             array([[ 0.843, -0.528, -0.11 ],
0215                    [-0.386, -0.835, -0.386],
0216                    [-0.52 ,  0.819, -0.252],
0217                    ..., 
0218                    [-0.071, -0.15 , -0.984],
0219                    [-0.236, -0.898, -0.378],
0220                    [-0.362, -0.598, -0.717]])
0221 
0222             In [82]: paral
0223             Out[82]: 
0224             array([[ 0.841, -0.531, -0.108],
0225                    [ 0.385,  0.838,  0.387],
0226                    [ 0.517, -0.817,  0.255],
0227                    ..., 
0228                    [ 0.072,  0.148,  0.986],
0229                    [ 0.238,  0.896,  0.374],
0230                    [ 0.363,  0.598,  0.715]])
0231 
0232             In [83]: np.sum( e1*paral , axis=1)
0233             Out[83]: array([ 1.   , -0.997, -1.002, ..., -0.998, -1.002, -1.001])
0234 
0235             In [84]: trans
0236             Out[84]: 
0237             array([[ 0.   ,  0.095, -0.469],
0238                    [ 0.   ,  0.411, -0.89 ],
0239                    [-0.   ,  0.287,  0.92 ],
0240                    ..., 
0241                    [ 0.   ,  0.988, -0.148],
0242                    [ 0.   ,  0.383, -0.916],
0243                    [ 0.   ,  0.754, -0.631]])
0244 
0245             In [85]: np.sum(e1*trans, axis=1)
0246             Out[85]: array([ 0.002,  0.001,  0.003, ..., -0.002,  0.003,  0.001])
0247 
0248         """
0249         pass
0250 
0251     def check_incident_sphere_pol(self):
0252         """
0253         ::
0254 
0255             In [14]: xyz = evt_g4.p.rpost_(0)[:,:3]
0256 
0257             In [16]: xyz[:,2] = 0 
0258 
0259             In [17]: xyz
0260             Out[17]: 
0261             A([[-42.7747, -26.7342,   0.    ],
0262                    [ 88.5891, -44.203 ,   0.    ],
0263                    [-63.3198, -62.6606,   0.    ],
0264                    ..., 
0265                    [-77.2729,  22.1198,   0.    ],
0266                    [ 57.7898,  29.7739,   0.    ],
0267                    [-86.3918,   1.8311,   0.    ]])
0268 
0269             In [18]: norm_(xyz)
0270             Out[18]: 
0271             A([[-0.848 , -0.53  ,  0.    ],
0272                    [ 0.8948, -0.4465,  0.    ],
0273                    [-0.7108, -0.7034,  0.    ],
0274                    ..., 
0275                    [-0.9614,  0.2752,  0.    ],
0276                    [ 0.889 ,  0.458 ,  0.    ],
0277                    [-0.9998,  0.0212,  0.    ]])
0278 
0279             In [19]: evt_g4.p.rpol_(0)
0280             Out[19]: 
0281             array([[-0.8504, -0.5276,  0.    ],
0282                    [ 0.8976, -0.4488,  0.    ],
0283                    [-0.7087, -0.7008,  0.    ],
0284                    ..., 
0285                    [-0.9606,  0.2756,  0.    ],
0286                    [ 0.8898,  0.4567,  0.    ],
0287                    [-1.    ,  0.0236,  0.    ]])
0288 
0289             In [20]: evt_g4.s.rpol_(0)
0290             Out[20]: 
0291             array([[ 0.5276, -0.8504,  0.    ],
0292                    [ 0.4488,  0.8976,  0.    ],
0293                    [ 0.7008, -0.7087,  0.    ],
0294                    ..., 
0295                    [-0.2756, -0.9606,  0.    ],
0296                    [-0.4567,  0.8898,  0.    ],
0297                    [-0.0236, -1.    ,  0.    ]])
0298 
0299         """ 
0300         pass
0301 
0302 
0303 
0304 
0305 
0306     def spatial(self):
0307         """
0308         Initial observation of asymmetry,  
0309 
0310         *FIXED: THE SPHERE WAS OFFSET (-1,1): A HANGOVER TO AVOID LEAKY TRIANGLE CRACKS*
0311         after placing sphere at origin no asymmetry apparent
0312 
0313         ::
0314 
0315             In [44]: r.min()
0316             Out[44]: 99.96880356309731
0317 
0318             In [45]: r.max()
0319             Out[45]: 100.03083354506256
0320 
0321  
0322         """
0323         fig = plt.figure()
0324 
0325         x0 = self.p0[:,0]
0326         y0 = self.p0[:,1]
0327         z0 = self.p0[:,2]
0328 
0329         x1 = self.p1[:,0]
0330         y1 = self.p1[:,1]
0331         z1 = self.p1[:,2]
0332 
0333 
0334         nr = 2
0335         nc = 3 
0336         nb = 100 
0337 
0338         ax = fig.add_subplot(nr,nc,1)
0339         plt.hist2d(x0, y0, bins=nb) 
0340         ax.set_xlabel("x0 y0")  
0341 
0342         ax = fig.add_subplot(nr,nc,2)
0343         plt.hist2d(x0, z0, bins=nb)  
0344         ax.set_xlabel("x0 z0")  
0345 
0346         ax = fig.add_subplot(nr,nc,3)
0347         plt.hist2d(y0, z0, bins=nb)  
0348         ax.set_xlabel("y0 z0")  
0349 
0350 
0351         ax = fig.add_subplot(nr,nc,4)
0352         plt.hist2d(x1, y1, bins=nb)  # xy: not symmetric, seems -Y tangentials favored over +Y tangentials 
0353         ax.set_xlabel("x1 y1")  
0354 
0355         ax = fig.add_subplot(nr,nc,5)
0356         plt.hist2d(x1, z1, bins=nb)  # xz: only 0:-100 as only half illuminated
0357         ax.set_xlabel("x1 z1")  
0358 
0359         ax = fig.add_subplot(nr,nc,6)
0360         plt.hist2d(y1, z1, bins=nb)  # yz: looks symmetric
0361         ax.set_xlabel("y1 z1")  
0362 
0363 
0364 
0365 
0366 if __name__ == '__main__':
0367 
0368     args = opticks_main(tag="-5", det="rainbow", src="torch")
0369 
0370 
0371     plt.ion()
0372     plt.close()
0373 
0374     boundary = Boundary("Vacuum///MainH2OHale")
0375 
0376 
0377     seqs = ["TO BR SA"]
0378 
0379     #evt = Evt(tag="-6", det="rainbow", seqs=seqs, label="P G4")
0380 
0381     tag = args.tag
0382     if tag == "-6":
0383         label = "P G4"
0384     elif tag == "-5":
0385         label = "S G4"
0386     elif tag == "5":
0387         label = "S Op"
0388     elif tag == "6":
0389         label = "P Op"
0390     else:
0391         label = "label?"
0392 
0393 
0394     try:
0395         evt = Evt(tag=tag, det=args.det, src=args.src, seqs=seqs, label=label, args=args )
0396     except IOError as err:
0397         log.fatal(err)
0398         sys.exit(args.mrc)
0399 
0400     log.info("loaded %s " % repr(evt))
0401 
0402     sr = SphereReflect(evt)
0403 
0404     p1 = sr.p1
0405 
0406     sr.spatial()
0407 
0408     #sr.check_intersection()
0409 
0410 
0411 
0412