def sampleGC(self, phase_angles): """ Sample the fitted great circle and return RA/dec of points for the given phase angles. Arguments: phase_angles: [ndarray] An array of phase angles (degrees). Return: ra, dec: [ndarrays] Arrays of RA and Dec (degrees). """ # Sample the great circle x_array, y_array, z_array = greatCircle(np.radians(phase_angles), self.theta0, self.phi0) if isinstance(x_array, float): x_array = [x_array] y_array = [y_array] z_array = [z_array] # Compute RA/Dec of every points ra_array = [] dec_array = [] for x, y, z in zip(x_array, y_array, z_array): ra, dec = vector2RaDec(np.array([x, y, z])) ra_array.append(ra) dec_array.append(dec) return np.array(ra_array), np.array(dec_array)
def fitGC(self): """ Fits great circle to observations. """ self.cartesian_points = [] self.ra_array = np.array(self.ra_array) self.dec_array = np.array(self.dec_array) for ra, dec in zip(self.ra_array, self.dec_array): vect = vectNorm(raDec2Vector(ra, dec)) self.cartesian_points.append(vect) self.cartesian_points = np.array(self.cartesian_points) # Set begin and end pointing vectors self.beg_vect = self.cartesian_points[0] self.end_vect = self.cartesian_points[-1] # Compute alt of the begining and the last point self.beg_azim, self.beg_alt = raDec2AltAz(self.ra_array[0], self.dec_array[0], self.jd_array[0], \ self.lat, self.lon) self.end_azim, self.end_alt = raDec2AltAz(self.ra_array[-1], self.dec_array[-1], self.jd_array[-1], \ self.lat, self.lon) # Fit a great circle through observations x_arr, y_arr, z_arr = self.cartesian_points.T coeffs, self.theta0, self.phi0 = fitGreatCircle(x_arr, y_arr, z_arr) # Calculate the plane normal self.normal = np.array([coeffs[0], coeffs[1], -1.0]) # Norm the normal vector to unit length self.normal = vectNorm(self.normal) # Compute RA/Dec of the normal direction self.normal_ra, self.normal_dec = vector2RaDec(self.normal) # Take pointing directions of the beginning and the end of the meteor self.meteor_begin_cartesian = vectNorm(self.cartesian_points[0]) self.meteor_end_cartesian = vectNorm(self.cartesian_points[-1]) # Compute angular distance between begin and end (radians) self.ang_be = angularSeparationVect(self.beg_vect, self.end_vect) # Compute meteor duration in seconds self.duration = (self.jd_array[-1] - self.jd_array[0])*86400.0 # Set the reference JD as the JD of the beginning self.jdt_ref = self.jd_array[0] # Compute the solar longitude of the beginning (degrees) self.lasun = np.degrees(jd2SolLonSteyaert(self.jdt_ref))
def estimateMeteorHeight(config, meteor_obj, shower): """ Estimate the height of a meteor from single station give a candidate shower. Arguments: config: [Config instance] meteor_obj: [MeteorSingleStation instance] shower: [Shower instance] Return: ht: [float] Estimated height in meters. """ ### Compute all needed values in alt/az coordinates ### # Compute beginning point vector in alt/az beg_ra, beg_dec = vector2RaDec(meteor_obj.beg_vect) beg_azim, beg_alt = raDec2AltAz(beg_ra, beg_dec, meteor_obj.jdt_ref, meteor_obj.lat, meteor_obj.lon) beg_vect_horiz = raDec2Vector(beg_azim, beg_alt) # Compute end point vector in alt/az end_ra, end_dec = vector2RaDec(meteor_obj.end_vect) end_azim, end_alt = raDec2AltAz(end_ra, end_dec, meteor_obj.jdt_ref, meteor_obj.lat, meteor_obj.lon) end_vect_horiz = raDec2Vector(end_azim, end_alt) # Compute radiant vector in alt/az radiant_azim, radiant_alt = raDec2AltAz(shower.ra, shower.dec, meteor_obj.jdt_ref, meteor_obj.lat, \ meteor_obj.lon) radiant_vector_horiz = raDec2Vector(radiant_azim, radiant_alt) # Reject the pairing if the radiant is below the horizon if radiant_alt < 0: return -1 # Get distance from Earth's centre to the position given by geographical coordinates for the # observer's latitude earth_radius = EARTH.EQUATORIAL_RADIUS / np.sqrt( 1.0 - (EARTH.E**2) * np.sin(np.radians(config.latitude))**2) # Compute the distance from Earth's centre to the station (including the sea level height of the station) re_dist = earth_radius + config.elevation ### ### # Compute the distance the meteor traversed during its duration (meters) dist = shower.v_init * meteor_obj.duration # Compute the angle between the begin and the end point of the meteor (rad) ang_beg_end = np.arccos( np.dot(vectNorm(beg_vect_horiz), vectNorm(end_vect_horiz))) # Compute the angle between the radiant vector and the begin point (rad) ang_beg_rad = np.arccos( np.dot(vectNorm(radiant_vector_horiz), -vectNorm(beg_vect_horiz))) # Compute the distance from the station to the begin point (meters) dist_beg = dist * np.sin(ang_beg_rad) / np.sin(ang_beg_end) # Compute the height using the law of cosines ht = np.sqrt(dist_beg**2 + re_dist**2 - 2 * dist_beg * re_dist * np.cos(np.radians(90 + meteor_obj.beg_alt))) ht -= earth_radius ht = abs(ht) return ht
def estimateMeteorHeight(meteor_obj, shower): """ Estimate the height of a meteor from single station give a candidate shower. Arguments: meteor_obj: [MeteorSingleStation instance] shower: [Shower instance] Return: ht: [float] Estimated height in meters. """ ### Compute all needed values in alt/az coordinates ### # Compute beginning point vector in alt/az beg_ra, beg_dec = vector2RaDec(meteor_obj.beg_vect) beg_azim, beg_alt = raDec2AltAz(beg_ra, beg_dec, meteor_obj.jdt_ref, meteor_obj.lat, meteor_obj.lon) beg_vect_horiz = raDec2Vector(beg_azim, beg_alt) # Compute end point vector in alt/az end_ra, end_dec = vector2RaDec(meteor_obj.end_vect) end_azim, end_alt = raDec2AltAz(end_ra, end_dec, meteor_obj.jdt_ref, meteor_obj.lat, meteor_obj.lon) end_vect_horiz = raDec2Vector(end_azim, end_alt) # Compute normal vector in alt/az normal_azim, normal_alt = raDec2AltAz(meteor_obj.normal_ra, meteor_obj.normal_dec, meteor_obj.jdt_ref, \ meteor_obj.lat, meteor_obj.lon) normal_horiz = raDec2Vector(normal_azim, normal_alt) # Compute radiant vector in alt/az radiant_azim, radiant_alt = raDec2AltAz(shower.ra, shower.dec, meteor_obj.jdt_ref, meteor_obj.lat, \ meteor_obj.lon) radiant_vector_horiz = raDec2Vector(radiant_azim, radiant_alt) # Reject the pairing if the radiant is below the horizon if radiant_alt < 0: return -1 ### ### # Compute cartesian coordinates of the pointing at the beginning of the meteor pt = vectNorm(beg_vect_horiz) # Compute reference vector perpendicular to the plane normal and the radiant vec = vectNorm(np.cross(normal_horiz, radiant_vector_horiz)) # Compute angles between the reference vector and the pointing dot_vb = np.dot(vec, beg_vect_horiz) dot_ve = np.dot(vec, end_vect_horiz) dot_vp = np.dot(vec, pt) # Compute distance to the radiant intersection line r_mag = 1.0 / (dot_vb**2) r_mag += 1.0 / (dot_ve**2) r_mag += -2 * np.cos(meteor_obj.ang_be) / (dot_vb * dot_ve) r_mag = np.sqrt(r_mag) r_mag = shower.v_init * meteor_obj.duration / r_mag pt_mag = r_mag / dot_vp # Compute the height ht = pt_mag**2 + EARTH.EQUATORIAL_RADIUS**2 \ - 2*pt_mag*EARTH.EQUATORIAL_RADIUS*np.cos(np.radians(90 - meteor_obj.beg_alt)) ht = np.sqrt(ht) ht -= EARTH.EQUATORIAL_RADIUS ht = abs(ht) return ht