def calc_direct_beam_intensity(self, height): """ Calculates the intensity of the suns beam at the given height with just extinction. This is needed for the Scattering source term. Parameters: height (float): Height where the direct beam is evaluated [m]. Returns: I_dir (float): The intensity of the direct beam at that height. """ if type(height) not in [int, float]: raise TypeError('The height must be a non-negative real number') if height < 0: raise ValueError('The height cannot be negative') idx, height = f.argclosest(height, self.height_array, return_value = True) angle = (self.sun_elevation + 90) % 180 tau = 0 for lvl in np.arange(len(self.height_array)-1,idx-1,-1): tau += (self.absorption_coeff_field[lvl] + \ self.scattering_coeff_field[lvl] * self.use_scat) * \ self.swiping_height / np.cos(np.deg2rad(angle)) I_dir = self.sun_intensity * np.exp(- tau) return I_dir
def set_receiver(self, height, elevation, azimuth): """Sets the position (closest to the model grid) and viewing angle of the receiver e.g. where and in which direction the radiation field is evaluated. The function converts the angle into the radiation transport direction. Parameters: height (float): Height of the receiver (must be positive) [km]. elevation (float): The elevation angle the receiver is looking at. Must be between 0 (up) and 180 (down) [deg]. azimuth (float): The azimuth angle the receiver is looking at. Must be between 0 and 360 [deg]. """ if type(height) not in [int, float]: raise TypeError('The height must be a non-negative real number') if height < 0: raise ValueError('The height cannot be negative') if type(elevation) not in [int, float]: raise TypeError('An angle must be a real number between 0 and 180') if elevation < 0 or elevation > 180: raise ValueError('The elevation cannot be negative or greater 180') if elevation == 90: raise ValueError('The elevation can not be 90') if type(azimuth) not in [int, float]: raise TypeError('An angle must be a real number between 0 and 360') if azimuth < 0 or azimuth >= 360: raise ValueError('The azimuth cannot be negative or >= 360') idx, height = f.argclosest(f.km2m(height), self.height_array, return_value = True) self.receiver_height = height self.receiver_elevation = (elevation + 90) % 180 self.receiver_azimuth = (azimuth + 180) % 360
def set_atmosheric_temp_profile(self): """DocString""" self.temp_field = np.empty((len(self.height_array))) temp_profile_height, temp_profile = f.readin_tempprofile() for idx, height in enumerate(self.height_array): self.temp_field[idx] = temp_profile[f.argclosest(height, f.km2m(temp_profile_height))] return self.temp_field
def extinction_term(self, intensity, height): """Clalculates the extinction term based on the given intensity and the absorbtion and scattering coefficent at the given height. """ id = f.argclosest(height, self.height_array) k = self.absorption_coeff_field[id] + \ self.use_scat * self.scattering_coeff_field[id] I_ext = intensity * np.exp(-k * self.swiping_height) return I_ext
def get_atmoshperic_profiles(self): """ Returns atm fields of the absorption and scattering coefficent depending on the readin_densprofile """ self.absorption_coeff_field = np.empty((len(self.height_array))) self.scattering_coeff_field = np.empty((len(self.height_array))) dens_profile_height, dens_profile = f.readin_densprofile() for idx, height in enumerate(self.height_array): dens = dens_profile[f.argclosest(height, f.km2m(dens_profile_height))] print(dens) self.absorption_coeff_field[idx] = dens * self.ABSORPTION_CROSS_SEC self.scattering_coeff_field[idx] = dens * self.scattering_cross_sec return self.absorption_coeff_field, self.scattering_coeff_field
def create_receiver_viewing_field(self): """creates an empty array where the field will be evaluated""" height = self.receiver_height angle = (self.receiver_elevation + 90) % 180 # revert in viewing direct idx = f.argclosest(self.receiver_height, self.height_array) if angle < 90: # from rec (at idx) to TOA (len(h.a.)) height_at_rad_field = np.arange(self.height_array[-1], height - \ self.swiping_height, -self.swiping_height) elif angle > 90: # from ground (at 0) to rec (at idx) height_at_rad_field = np.arange(0, height + self.swiping_height, self.swiping_height) return height_at_rad_field
def scattering_source_term(self, height): idx, height = f.argclosest(height, self.height_array, return_value = True) angle = f.calc_scattering_angle(self.sun_elevation, self.receiver_elevation,self.sun_azimuth, self.receiver_azimuth) # setting the phase function according to the selected scattering type if self.scat_type: phase_func = f.rayleigh_phasematrix(angle, stokes_dim = 1) else: phase_func = f.henyey_greenstein_phasefunc(angle, g = 0.7) I_scat = (1 - np.exp(-self.scattering_coeff_field[idx] * self.swiping_height)) * \ RT_model_1D.calc_direct_beam_intensity(self, height) *\ phase_func return I_scat
def plank_source_term(self, height): idx, height = f.argclosest(height, self.height_array, return_value = True) temp = self.temp_field[idx] return f.plank_wavelength(self.wavelength, temp)