Beispiel #1
0
 def __init__(self, x=None, y=None, file=None):
     super(Spectrum, self).__init__()
     """Initialised with x and y which are array-like data of the same length. x must have units of wavelength (that is in nanometers), y can an arbitrary units. However, if the Spectrum is representing an absorption coefficient y must have units of (1/m)."""
     
     if file != None:
         
         try:
             data = np.loadtxt(file)
         except Exception as e:
             print "Failed to load data from file, %s", str(file)
             print e
             exit(1)
         
         self.x = np.array(data[:,0], dtype=np.float32)
         self.y = np.array(data[:,1], dtype=np.float32)
     
     elif (x != None and y != None):
         self.x = np.array(x, dtype=np.float32)
         self.y = np.array(y, dtype=np.float32)
     
     else:
         # We need to make some data up -- i.e. flat over the full model range
         self.x = np.array([200, 500, 750, 4000], dtype=np.float32)
         self.y = np.array([0, 0, 0, 0], dtype=np.float32)
     
     
     if len(self.x) == 0:
         # We need to make some data up -- i.e. flat over the full model range
         self.x = np.array([200, 500, 750, 4000], dtype=np.float32)
         self.y = np.array([0, 0, 0, 0], dtype=np.float32)
         
     elif len(self.x) == 1:
         # We have a harder time at making up some data
         xval = self.x[0]
         yval = self.y[0]
         bins = np.arange(np.floor( self.x[0] - 1), np.ceil(self.x[0] + 2))
         indx = np.where(bins==xval)[0][0]
         self.x = np.array(bins, dtype=np.float32)
         self.y = np.zeros(len(self.x), dtype=np.float32)
         self.y[indx] = np.array(yval, dtype=np.float32)
     
     # Make the 'spectrum'
     self.spectrum = interp1d(self.x, self.y, bounds_error=False, fill_value=0.0)
     
     # Make the pdf for wavelength lookups
     try:
         # Convert the (x,y) point pairs to a histogram of bins and frequencies
         bins = np.hstack([self.x, 2*self.x[-1] - self.x[-2]])
     except IndexError:
         print "Index Error from array, ", self.x
     
     cdf  = np.cumsum(self.y)
     pdf  = cdf/max(cdf)
     pdf  = np.hstack([0,pdf[:]])
     self.pdf_lookup = interp1d(bins, pdf, bounds_error=False, fill_value=0.0)
     self.pdfinv_lookup = interp1d(pdf, bins, bounds_error=False, fill_value=0.0)
Beispiel #2
0
 def __init__(self, x=None, y=None, file=None):
     super(Spectrum, self).__init__()
     """Initialised with x and y which are array-like data of the same length. x must have units of wavelength (that is in nanometers), y can an arbitrary units. However, if the Spectrum is representing an absorption coefficient y must have units of (1/m)."""
     
     if file != None:
         
         try:
             data = np.loadtxt(file)
         except Exception as e:
             print "Failed to load data from file, %s", str(file)
             print e
             exit(1)
         
         self.x = data[:,0]
         self.y = data[:,1]
     
     elif (x != None and y != None):
         self.x = np.array(x)
         self.y = np.array(y)
     
     else:
         # We need to make some data up -- i.e. flat over the full model range
         self.x = np.array([200, 500, 750, 4000])
         self.y = np.array([0, 0, 0, 0])
     
     
     if len(self.x) == 0:
         # We need to make some data up -- i.e. flat over the full model range
         self.x = np.array([200, 500, 750, 4000])
         self.y = np.array([0, 0, 0, 0])
         
     elif len(self.x) == 1:
         # We have a harder time at making up some data
         xval = self.x[0]
         yval = self.y[0]
         bins = np.arange(np.floor( self.x[0] - 1), np.ceil(self.x[0] + 2))
         indx = np.where(bins==xval)[0][0]
         self.x = np.array(bins)
         self.y = np.zeros(len(self.x))
         self.y[indx] = yval
     
     # Make the 'spectrum'
     self.spectrum = interp1d(self.x, self.y, bounds_error=False, fill_value=0.0)
     
     # Make the pdf for wavelength lookups
     try:
         # Convert the (x,y) point pairs to a histogram of bins and frequencies
         bins = np.hstack([self.x, 2*self.x[-1] - self.x[-2]])
     except IndexError:
         print "Index Error from array, ", self.x
     
     cdf  = np.cumsum(self.y)
     pdf  = cdf/max(cdf)
     pdf  = np.hstack([0,pdf[:]])
     self.pdf_lookup = interp1d(bins, pdf, bounds_error=False, fill_value=0.0)
     self.pdfinv_lookup = interp1d(pdf, bins, bounds_error=False, fill_value=0.0)
Beispiel #3
0
    def trace(self, photon, free_pathlength):
        '''Will apply absorption and emission probabilities to the photon along its free path in the present geometrical container and return the result photon for tracing. See help(material.trace) for how this is done for a single material because the same principle applies. The ensemble absorption coefficient is found for the specified photon to determine if absorption occurs. The absorbed material its self is found at random from a distrubution weighted by each of the component absorption coefficients. The resultant photon is returned with possibily with a new position, direction and wavelength. If the photon is absorbed and not emitted the photon is retuned but its active property is set to False. '''

        # Clear state using for collecting statistics
        photon.absorber_material = None
        photon.emitter_material = None

        absorptions = self.all_absorption_coefficients(photon.wavelength)
        absorption_coefficient = absorptions.sum()
        sampled_pathlength = -np.log(
            1 - np.random.uniform()) / absorption_coefficient

        #Absorption occurs.
        if (sampled_pathlength < free_pathlength):
            # Move photon along path to the absorption point
            photon.absorption_counter = photon.absorption_counter + 1
            photon.position = photon.position + sampled_pathlength * photon.direction

            # Find the absorption material
            count = len(self.materials)
            bins = range(0, count + 1)
            cdf = np.cumsum(absorptions)
            pdf = cdf / max(cdf)
            pdf = np.hstack([0, pdf[:]])
            pdfinv_lookup = interp1d(pdf,
                                     bins,
                                     bounds_error=False,
                                     fill_value=0.0)
            absorber_index = int(np.floor(pdfinv_lookup(np.random.uniform())))
            material = self.materials[absorber_index]
            photon.material = material
            photon.absorber_material = material
            self.emission = material.emission
            self.absorption = material.absorption
            self.quantum_efficiency = material.quantum_efficiency

            #Emission occurs.
            if (np.random.uniform() < material.quantum_efficiency):
                print "   * Re-emitted *"
                photon.reabs = photon.reabs + 1
                photon.emitter_material = material
                photon = material.emission(
                    photon
                )  # Generates a new photon with red-shifted wavelength, new direction and polariation (if included in simulation)
                return photon

            else:
                print "   * Photon Lost *"
                #Emission does not occur. Now set active = False ans return
                photon.active = False
                return photon

        else:

            #Absorption does not occur. The photon reaches the edge, update it's position and return
            photon.position = photon.position + free_pathlength * photon.direction
            return photon
Beispiel #4
0
 def trace(self, photon, free_pathlength):
     '''Will apply absorption and emission probabilities to the photon along its free path in the present geometrical container and return the result photon for tracing. See help(material.trace) for how this is done for a single material because the same principle applies. The ensemble absorption coefficient is found for the specified photon to determine if absorption occurs. The absorbed material its self is found at random from a distrubution weighted by each of the component absorption coefficients. The resultant photon is returned with possibily with a new position, direction and wavelength. If the photon is absorbed and not emitted the photon is retuned but its active property is set to False. '''
     
     # Clear state using for collecting statistics
     photon.absorber_material = None
     photon.emitter_material = None
     
     absorptions = self.all_absorption_coefficients(photon.wavelength)
     absorption_coefficient = absorptions.sum()
     sampled_pathlength = -np.log(1 - np.random.uniform())/absorption_coefficient
     
     #Absorption occurs.
     if (sampled_pathlength < free_pathlength):
         # Move photon along path to the absorption point
         photon.absorption_counter = photon.absorption_counter + 1
         photon.position = photon.position + sampled_pathlength * photon.direction
         
         # Find the absorption material
         count = len(self.materials)
         bins = range(0, count+1)
         cdf  = np.cumsum(absorptions)
         pdf  = cdf/max(cdf)
         pdf  = np.hstack([0,pdf[:]])
         pdfinv_lookup = interp1d(pdf, bins, bounds_error=False, fill_value=0.0)
         absorber_index = int(np.floor(pdfinv_lookup(np.random.uniform())))
         material = self.materials[absorber_index]
         photon.material = material
         photon.absorber_material = material
         self.emission = material.emission
         self.absorption = material.absorption
         self.quantum_efficiency = material.quantum_efficiency
         
         
         #Emission occurs.
         if (np.random.uniform() < material.quantum_efficiency):
             print "   * Re-emitted *"
             photon.reabs = photon.reabs + 1
             photon.emitter_material = material
             photon = material.emission(photon) # Generates a new photon with red-shifted wavelength, new direction and polariation (if included in simulation)
             return photon
             
         else:
             print "   * Photon Lost *"
             #Emission does not occur. Now set active = False ans return
             photon.active = False
             return photon
             
     else:
         
         #Absorption does not occur. The photon reaches the edge, update it's position and return
         photon.position = photon.position + free_pathlength * photon.direction
         return photon