Package theia :: Package tree :: Module beamtree
[hide private]
[frames] | no frames]

Source Code for Module theia.tree.beamtree

  1  '''Defines the BeamTree class for theia.''' 
  2   
  3  # Provides: 
  4  #   class OpticalComponent 
  5  #       __init__ 
  6  #       __str__ 
  7  #       lines 
  8  #       beamList 
  9  #       beamLines 
 10  #       numberOfBeams 
 11  #       outputLines 
 12  #   treeOfBeam 
 13   
 14  import numpy as np 
 15  from ..helpers import settings 
 16  from ..helpers.units import mm, deg 
 17  from ..helpers.tools import formatter 
 18  from ..helpers.geometry import rectToSph, linePlaneInter 
 19   
20 -class BeamTree(object):
21 ''' 22 23 BeamTree class. 24 25 A BeamTree is a binary tree which allows to keep track of the beams as they 26 are traced throughout the optical setup. The Root of the tree is a Gaussian 27 beam and the other attributes are the daughter trees and all the data of the 28 interaction producing these with the Root beam 29 30 *=== Attributes ===* 31 Name: class attribute, name of object. [string] 32 Root: beam of this node of the tree. [GaussianBeam] 33 T: beam resulting from the transmission of the Root beam. [BeamTree] 34 R: beam resulting from the reflection of the Root beam. [BeamTree] 35 36 ''' 37 Name = "BeamTree" 38
39 - def __init__(self, Root = None, 40 T = None, R = None):
41 '''BeamTree initializer.''' 42 self.Root = Root 43 self.T = T 44 self.R = R
45
46 - def __str__(self):
47 '''String representation of a BeamTree, for print(tree).''' 48 return formatter(self.lines())
49
50 - def lines(self):
51 '''Returns the list of lines necessary to print the object.''' 52 ans = [] 53 ans.append("Tree: {") 54 ans.append("Root beam: %s" %str(self.Root.Ref)) 55 ans.append("Number of beams: %s" %str(self.numberOfBeams())) 56 ans.append("}") 57 58 return ans
59
60 - def beamList(self):
61 '''Returns the string representation the tree of beams. 62 63 ''' 64 before = ["Tree: Root beam = %s {" %str(self.Root.Ref)] 65 after = ["}"] 66 return formatter(before + self.beamLines() + after)
67
68 - def beamLines(self):
69 '''Returns the list of lines necessary to print the list of beams. 70 71 ''' 72 ans = [] 73 if self.Root is not None: 74 ans = self.Root.lines() 75 if self.R is not None: 76 ans = ans + self.R.beamLines() 77 if self.T is not None: 78 ans = ans + self.T.beamLines() 79 80 return ans
81
82 - def numberOfBeams(self):
83 '''Return the total number of beams.''' 84 if self.Root is None: 85 return 0 86 87 if self.T is None and self.R is None: 88 return 1 89 elif self.T is None and self.R is not None: 90 return 1 + self.R.numberOfBeams() 91 elif self.T is not None and self.R is None: 92 return 1 + self.T.numberOfBeams() 93 else: 94 return 1 + self.T.numberOfBeams() + self.R.numberOfBeams()
95
96 - def outputLines(self):
97 '''Return the list of lines to write the output of simulation.''' 98 sList = [] 99 if self.Root is not None: 100 if self.Root.Optic is not None: 101 if self.Root.Length > 0.: 102 if self.R is not None and self.R.Root is not None: 103 sList = ['(%s, %s) %sm (%s, %s) %s {' \ 104 %(self.Root.Optic, self.Root.Face, 105 str(self.Root.Length), self.R.Root.Optic, 106 self.R.Root.Face, self.Root.Ref)] 107 elif self.T is not None and self.T.Root is not None: 108 sList = ['(%s, %s) %sm (%s, %s) %s {' \ 109 %(self.Root.Optic, self.Root.Face, 110 str(self.Root.Length), self.T.Root.Optic, 111 self.T.Root.Face, self.Root.Ref)] 112 else: 113 sList = ['(%s, %s) [end] %s {' \ 114 %(self.Root.Optic, self.Root.Face, self.Root.Ref)] 115 else: 116 sList = ['(%s, %s) [open] %s {' \ 117 %(self.Root.Optic, self.Root.Face, self.Root.Ref)] 118 else: 119 if self.Root.Length > 0.: 120 if self.R is not None and self.R.Root is not None: 121 sList = ['[InBeam] %sm (%s, %s) %s {' \ 122 %(str(self.Root.Length), self.R.Root.Optic, 123 self.R.Root.Face, self.Root.Ref)] 124 elif self.T is not None and self.T.Root is not None: 125 sList = ['[InBeam] %sm (%s, %s) %s {' \ 126 %(str(self.Root.Length), self.T.Root.Optic, 127 self.T.Root.Face, self.Root.Ref)] 128 else: 129 sList = ['[InBeam] %sm [end] %s {' \ 130 %(str(self.Root.Length), self.Root.Ref)] 131 else: 132 sList = ['[InBeam] [Open] %s {' %self.Root.Ref] 133 sList.append("Waist Pos: %sm" %str(self.Root.waistPos())) 134 sList.append("Waist Size: (%s, %s)mm" \ 135 %(str(self.Root.waistSize()[0]/mm), 136 str(self.Root.waistSize()[1]/mm))) 137 sph = rectToSph(self.Root.Dir) 138 sList.append("Direction: (%s, %s)deg" %(str(sph[0]/deg), 139 str(sph[1]/deg))) 140 sList.append('}') 141 if self.R is not None: 142 sList = sList + self.R.outputLines() 143 if self.T is not None: 144 sList = sList + self.T.outputLines() 145 146 return sList
147 148 #Beware this is a global scope function not a method of the BeamTree class
149 -def treeOfBeam(srcBeam, optList, order, threshold):
150 '''Function to calculate the tree of daughter beams of srcBeam. 151 152 srcBeam: Input beam. [GaussianBeam] 153 optList: List of optical components of the setup. [list of OpticalComponent] 154 order: order of simulation. [integer] 155 threshold: power threshold for daughter beams. [float] 156 157 Returns a BeamTree. 158 159 ''' 160 if len(optList) == 0: 161 # No optics 162 return BeamTree(Root = srcBeam) 163 164 if srcBeam is None: 165 # leaf of the tree 166 return BeamTree() 167 168 # stuff used for clipping 169 clippingOpts = ["Mirror", "ThinLens", "ThickLens"] 170 width = srcBeam.width(srcBeam.Length) 171 waist = max(width[0], 172 width[1]) 173 174 # initialize 175 dist = settings.inf 176 finalOpt = None 177 178 # look for closest impact 179 for opt in optList: 180 dicoisHit = opt.isHit(srcBeam) 181 if dicoisHit['isHit'] and dicoisHit['distance'] < dist: 182 dist = dicoisHit['distance'] 183 finalOpt = opt 184 185 # anti-clipping calculations! 186 if settings.antiClip: 187 for opt in optList: 188 if opt.Name in clippingOpts: 189 # determine intersection with larger optic 190 HClipDic = linePlaneInter(srcBeam.Pos, srcBeam.Dir, 191 opt.HRCenter, opt.HRNorm, 192 opt.Dia + 2 * settings.clipFactor * waist) 193 194 AClipDic = linePlaneInter(srcBeam.Pos, srcBeam.Dir, 195 opt.ARCenter, opt.ARNorm, 196 opt.Dia + 2 * settings.clipFactor * waist) 197 if HClipDic['isHit'] and HClipDic['distance'] < dist \ 198 or AClipDic['isHit'] and AClipDic['distance'] < dist: 199 print "theia: Warning: Anti-Clipping of beam %s on %s."\ 200 %(srcBeam.Ref, opt.Ref) 201 202 203 if finalOpt is None: 204 # no interaction 205 if settings.info: 206 print "theia: Info: Reached open beam %s." %srcBeam.Ref 207 return BeamTree(Root = srcBeam) 208 209 # get parameters of this closest impact 210 finalisHit = finalOpt.isHit(srcBeam) 211 finalHit = finalOpt.hit(srcBeam, order = order, threshold = threshold) 212 213 # determine is there was clipping 214 isClipped = False # if there is clipping during the interaction 215 if not finalisHit['face'] == 'Side' and finalOpt.Name in clippingOpts: 216 center = finalOpt.HRCenter if finalisHit['face'] == 'HR'\ 217 else finalOpt.ARCenter 218 distance = np.linalg.norm(finalisHit['intersection point'] - center) 219 isClipped = distance + settings.clipFactor * waist > finalOpt.Dia/2. 220 221 #warn for clipping 222 if isClipped and settings.warning: 223 print "theia: Warning: Clipping of beam %s on (%s, %s)."\ 224 %(srcBeam.Ref, finalOpt.Ref, finalisHit['face']) 225 226 return BeamTree(Root = srcBeam, 227 T = treeOfBeam(finalHit['t'], optList, order, threshold), 228 R = treeOfBeam(finalHit['r'], optList, order, threshold))
229