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 BeamTree 
  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, shortRef 
 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 return ["Tree: {", 53 "Root beam: %s" %(self.Root.Ref if not settings.short\ 54 else shortRef(self.Root.Ref)), 55 "Number of beams: %s" %str(self.numberOfBeams()), 56 "}"]
57
58 - def beamList(self):
59 '''Returns the string representation the tree of beams. 60 61 ''' 62 before = ["Tree: Root beam = %s {" %str(self.Root.Ref)] 63 after = ["}"] 64 return formatter(before + self.beamLines() + after)
65
66 - def beamLines(self):
67 '''Returns the list of lines necessary to print the list of beams. 68 69 ''' 70 if self.Root is not None: 71 ans = self.Root.lines() 72 if self.R is not None: 73 ans = ans + self.R.beamLines() 74 if self.T is not None: 75 ans = ans + self.T.beamLines() 76 return ans 77 return list()
78
79 - def numberOfBeams(self):
80 '''Return the total number of beams.''' 81 if self.Root is None: 82 return 0 83 return 1 + (self.R.numberOfBeams() if self.R is not None else 0)\ 84 + (self.T.numberOfBeams() if self.T is not None else 0)
85
86 - def outputLines(self):
87 '''Return the list of lines to write the output of simulation.''' 88 sList = list() 89 if self.Root is not None and (self.Root.N == 1 or not settings.short): 90 beam = self.Root 91 Ref = beam.Ref if not settings.short else shortRef(beam.Ref) 92 sph = rectToSph(beam.Dir) 93 if beam.Length == 0.: 94 sList = ["(%s, %s) [open] %s {" % (beam.Optic, beam.Face, Ref)] 95 else: 96 if self.R is None and self.T is None: 97 sList = ["(%s, %s) %sm [end] (%s, %s) %s {" \ 98 % (beam.Optic, beam.Face, str(beam.Length), 99 beam.TargetOptic, beam.TargetFace, Ref)] 100 else: 101 sList = ["(%s, %s) %sm (%s, %s) %s {" \ 102 % (beam.Optic, beam.Face, str(beam.Length), 103 beam.TargetOptic, beam.TargetFace, Ref)] 104 105 sList = sList + ["Waist Pos: (%s, %s)m" \ 106 %(str(beam.DWx), str(beam.DWy)), 107 "Waist Size: (%s, %s)mm" \ 108 %(str(beam.Wx/mm), str(beam.Wy/mm)), 109 "Direction: (%s, %s)deg" %(str(sph[0]/deg), 110 str(sph[1]/deg)), 111 "}"] 112 if self.R is not None: 113 sList = sList + self.R.outputLines() 114 if self.T is not None: 115 sList = sList + self.T.outputLines() 116 117 return sList
118 119 #Beware this is a global scope function not a method of the BeamTree class
120 -def treeOfBeam(srcBeam, optList, order, threshold):
121 '''Function to calculate the tree of daughter beams of srcBeam. 122 123 srcBeam: Input beam. [GaussianBeam] 124 optList: List of optical components of the setup. [list of OpticalComponent] 125 order: order of simulation. [integer] 126 threshold: power threshold for daughter beams. [float] 127 128 Returns a BeamTree. 129 130 ''' 131 if len(optList) == 0: 132 # No optics 133 return BeamTree(Root = srcBeam) 134 135 if srcBeam is None: 136 # leaf of the tree 137 return None 138 139 BRef = srcBeam.Ref if not settings.short else shortRef(srcBeam.Ref) 140 141 # stuff used for clipping 142 clippingOpts = ["Mirror", "ThinLens", "ThickLens", "BeamDump", "Special"] 143 waist = max(srcBeam.IWx, 144 srcBeam.IWy) 145 146 # initialize 147 dist = settings.inf 148 finalOpt = None 149 150 # look for closest impact 151 for opt in optList: 152 dicoisHit = opt.isHit(srcBeam) 153 if dicoisHit['isHit'] and dicoisHit['distance'] < dist: 154 dist = dicoisHit['distance'] 155 finalOpt = opt 156 157 # anti-clipping calculations! 158 if settings.antiClip: 159 for opt in optList: 160 if opt.Name in clippingOpts and not opt is finalOpt: 161 # determine intersection with larger optic 162 HClipDic = linePlaneInter(srcBeam.Pos, srcBeam.Dir, 163 opt.HRCenter, opt.HRNorm, 164 opt.Dia + 2 * settings.clipFactor * waist) 165 166 AClipDic = linePlaneInter(srcBeam.Pos, srcBeam.Dir, 167 opt.ARCenter, - opt.HRNorm, 168 opt.Dia + 2 * settings.clipFactor * waist) 169 170 # it hit the enlarged surface but is outside 171 Hif = HClipDic['isHit'] and HClipDic['distance'] < dist \ 172 and np.linalg.norm(HClipDic['intersection point'] \ 173 - opt.HRCenter) > opt.Dia/2. 174 175 Aif = AClipDic['isHit'] and AClipDic['distance'] < dist \ 176 and np.linalg.norm(AClipDic['intersection point'] \ 177 - opt.ARCenter) > opt.Dia/2. 178 if Hif or Aif and (srcBeam.N == 1. or not settings.short): 179 print "theia: Warning: Anti-clipping of beam %s on %s."\ 180 %(BRef, opt.Ref) 181 182 if finalOpt is None: 183 # no interaction 184 if settings.info and (srcBeam.N == 1. or not settings.short): 185 print "theia: Info: Reached open beam %s." % BRef 186 return BeamTree(Root = srcBeam) 187 188 # get parameters of this closest impact 189 finalisHit = finalOpt.isHit(srcBeam) 190 finalHit = finalOpt.hit(srcBeam, order = order, threshold = threshold) 191 192 # determine if there was clipping 193 isClipped = False # if there is clipping during the interaction 194 if not finalisHit['face'] == 'Side' and finalOpt.Name in clippingOpts: 195 center = { 'HR': finalOpt.HRCenter, 196 'AR': finalOpt.ARCenter}[finalisHit['face']] 197 distance = np.linalg.norm(finalisHit['intersection point'] - center) 198 isClipped = distance + settings.clipFactor * waist > finalOpt.Dia/2. 199 200 #warn for clipping 201 if isClipped and settings.warning\ 202 and (srcBeam.N == 1. or not settings.short): 203 print "theia: Warning: Clipping of beam %s on (%s, %s)."\ 204 %(BRef, finalOpt.Ref, finalisHit['face']) 205 206 return BeamTree(Root = srcBeam, 207 T = treeOfBeam(finalHit['t'], optList, order, threshold), 208 R = treeOfBeam(finalHit['r'], optList, order, threshold))
209