def test_sphere_cart(): """ Tests the spherical <-> cartesian transform functions """ from astropy.utils import NumpyRNGContext from astropy.coordinates import spherical_to_cartesian, cartesian_to_spherical x, y, z = spherical_to_cartesian(1, 0, 0) assert_allclose(x, 1) assert_allclose(y, 0) assert_allclose(z, 0) x, y, z = spherical_to_cartesian(0, 1, 1) assert_allclose(x, 0) assert_allclose(y, 0) assert_allclose(z, 0) x, y, z = spherical_to_cartesian(5, 0, np.arcsin(4. / 5.)) assert_allclose(x, 3) assert_allclose(y, 4) assert_allclose(z, 0) r, lat, lon = cartesian_to_spherical(0, 1, 0) assert_allclose(r, 1) assert_allclose(lat, 0 * u.deg) assert_allclose(lon, np.pi / 2 * u.rad) # test round-tripping with NumpyRNGContext(13579): x, y, z = np.random.randn(3, 5) r, lat, lon = cartesian_to_spherical(x, y, z) x2, y2, z2 = spherical_to_cartesian(r, lat, lon) assert_allclose(x, x2) assert_allclose(y, y2) assert_allclose(z, z2)
galcen_frame = utils.galcen['frame'] for infile, outfile in zip(infiles, outfiles): endpts = pd.read_csv(infile, index_col=0) # nominal stream pole (using most likely values) lon, lat, dist = [], [], [] for name, pts in endpts.iterrows(): lon.append([pts['lon' + str(i + 1)] for i in range(2)]) lat.append([pts['lat' + str(i + 1)] for i in range(2)]) dist.append([pts['dist' + str(i + 1)] for i in range(2)]) pts = SkyCoord(lon*u.deg, lat*u.deg,\ distance=dist*u.kpc, frame=pts['frame']) endpts['length'] = pts[:, 0].separation(pts[:, 1]).deg pts = pts.transform_to(galcen_frame) r_MW, b_MW, l_MW = coord.cartesian_to_spherical(pts.x, pts.y, pts.z) pts_MW = SkyCoord(l=l_MW, b=b_MW, frame='galactic') l, b = [], [] for stream in pts_MW: stream = stream.transform_to(coord.ICRS) pole = pole_from_endpoints(stream[0], stream[1]) pole = pole.transform_to(coord.Galactic) l.append(pole.l) b.append(pole.b) poles_MW = SkyCoord(l=l, b=b, frame='galactic') endpts['dist_gal'] = np.mean(r_MW, axis=1) # Monte Carlo sampling for stream normals N_up = int(N * 1.1) lon_arr = [] lat_arr = []
def predict(self, hillas_dict, inst, pointing_alt, pointing_az): ''' The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict: dict dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description pointing_alt: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing altitude pointing_az: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing azimuth Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 ''' # filter warnings for missing obs time. this is needed because MC data has no obs time warnings.filterwarnings(action='ignore', category=MissingFrameAttributeWarning) # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}".format( len(hillas_dict))) self.initialize_hillas_planes(hillas_dict, inst.subarray, pointing_alt, pointing_az) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() alt = u.Quantity(list(pointing_alt.values())) az = u.Quantity(list(pointing_az.values())) if np.any(alt != alt[0]) or np.any(az != az[0]): warnings.warn('Divergent pointing not supported') telescope_pointing = SkyCoord(alt=alt[0], az=az[0], frame=AltAz()) # core position estimate using a geometric approach core_pos = self.estimate_core_position(hillas_dict, telescope_pointing) # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max() # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. result.alt, result.az = lat, -lon result.core_x = core_pos[0] result.core_y = core_pos[1] result.core_uncert = np.nan result.tel_ids = [h for h in hillas_dict.keys()] result.average_intensity = np.mean( [h.intensity for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def convert_out_position(x, y, inr, c, cent, time): """convert outputs position on WFC-as built model to those on the PFS coordinates. Parameters ---------- x : `float`, input position in x-axis y : `float`, input position in y-axis inr : `float` Instrument rotator angle in unit of degree. c : `DCoeff` class Distortion Coefficients cent : `np.ndarray`, (2, 1) The center of input coordinates in the same unit of as xyin. time : `str` Observation time UTC in format of %Y-%m-%d %H:%M:%S Returns ------- xx : `float`, converted position in x-axis yy : `float`, converted position in y-axis """ # convert pixel to mm: mcs_pfi if c.mode == 'pfi_mcs' or c.mode == 'pfi_mcs_wofe': xx, yy = mm_to_pixel(x, y, cent) # Rotation to PFI coordinates elif c.mode == 'sky_pfi' or c.mode == 'sky_pfi_hsc': xx, yy = rotation(x, y, inr, rot_off=DCoeff.inr_pfi) yy = -1.*yy elif c.mode == 'mcs_pfi': xx, yy = rotation(x, y, 0., rot_off=DCoeff.inr_pfi) elif c.mode == 'pfi_sky': # WFC to Ra-Dec # Set Observation Site (Subaru) tel = EarthLocation.of_site('Subaru') obs_time = Time(time) aref_file = mypath+'data/Refraction_data_635nm.txt' atm_ref = np.loadtxt(aref_file) atm_interp = ipol.splrep(atm_ref[:, 0], atm_ref[:, 1], s=0) # Ra-Dec to Az-El (Center) coord_cent = SkyCoord(cent[0], cent[1], unit=u.deg) altaz_cent = coord_cent.transform_to(AltAz(obstime=obs_time, location=tel)) az0 = altaz_cent.az.deg el0 = altaz_cent.alt.deg # offset frame in WFC center = SkyCoord(0., 0., unit=u.deg) aframe = center.skyoffset_frame() coord = SkyCoord(x, y, frame=aframe, unit=u.deg, obstime=obs_time, location=tel) logging.info("Az-El of the FoV center (%s %s)", az0, el0) r = R.from_euler('ZYZ', [az0, -1*el0, 0.], degrees=True) xc, yc, zc = ascor.spherical_to_cartesian(1., np.deg2rad(y), np.deg2rad(x)) xyz = np.vstack((xc, yc, zc)).T logging.info("(%s)", xyz.shape) logging.info("(%s)", r.as_rotvec()) azel = r.apply(xyz) rs, lats, lons = ascor.cartesian_to_spherical(azel[:, 0], azel[:, 1], azel[:, 2]) az = np.array(np.rad2deg(lons)) el = np.array(np.rad2deg(lats)) # eld = el - ipol.splev(90.-el, atm_interp)/3600. # Az-El to Ra-Dec (Targets) coord = SkyCoord(alt=el, az=az, frame='altaz', unit=u.deg, obstime=obs_time, location=tel) radec = coord.transform_to('icrs') xx = radec.ra.deg yy = radec.dec.deg else: xx = x yy = y return xx, yy
def get_detector_centers_with_time(self,t): deter_name = self.detectors.name_list center_f = self.detectors.center_function if center_f is not None and self.time_band is not None: ra_t_all = [] dec_t_all = [] index_all = [] try: n_=len(t) t = np.array(t) tband = t.max()-t.min() tband_sl = self.time_band[1] - self.time_band[0] if tband<=tband_sl+2: t[t<=self.time_band[0]] = self.time_band[0]+0.00001 t[t>=self.time_band[1]] = self.time_band[1]-0.00001 else: t[t<=self.time_band[0]] = np.nan t[t>=self.time_band[1]] = np.nan for index_,deteri in enumerate(deter_name): index_all.append(index_) xf,yf,zf = center_f[deteri] x = xf(t) y = yf(t) z = zf(t) position = cartesian_to_spherical(x,y,z) ra_t = position[2].deg dec_t = position[1].deg ra_t_all.append(list(ra_t)) dec_t_all.append(list(dec_t)) ra_t_all = np.array(ra_t_all).T dec_t_all = np.array(dec_t_all).T center = SkyCoord(ra = ra_t_all,dec = dec_t_all,frame='icrs', unit='deg') return center,[index_all]*n_ except (TypeError): if (t<=self.time_band[0]): if (self.time_band[0]-t<=1): t = self.time_band[0]+0.00001 else: t = np.nan if t>=self.time_band[1]: if (t-self.time_band[0]<=1): t = self.time_band[1]-0.00001 else: t = np.nan for index_,deteri in enumerate(deter_name): index_all.append(index_) xf,yf,zf = center_f[deteri] x = xf(t) y = yf(t) z = zf(t) position = cartesian_to_spherical(x,y,z) ra_t = position[2].deg dec_t = position[1].deg ra_t_all.append(ra_t) dec_t_all.append(dec_t) center = SkyCoord(ra = ra_t_all,dec = dec_t_all,frame='icrs', unit='deg') return center,index_all else: return None
def get_median_lonlat(lon, lat): "lon, lat in degrees" x, y, z = spherical_to_cartesian(1, (lat / 180. * np.pi), (lon / 180. * np.pi)) r, lat, lon = cartesian_to_spherical(np.median(x), np.median(y), np.median(z)) return lon, lat
def _predict(self, event, hillas_dict, subarray, array_pointing, telescopes_pointings): """ The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict: dict dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description array_pointing: SkyCoord[AltAz] pointing direction of the array telescopes_pointings: dict[SkyCoord[AltAz]] dictionary of pointing direction per each telescope Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 InvalidWidthException if any width is np.nan or 0 """ # filter warnings for missing obs time. this is needed because MC data has no obs time warnings.filterwarnings(action="ignore", category=MissingFrameAttributeWarning) # Here we perform some basic quality checks BEFORE applying reconstruction # This should be substituted by a DL1 QualityQuery specific to this # reconstructor # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}".format( len(hillas_dict))) # check for np.nan or 0 width's as these screw up weights if any( [np.isnan(hillas_dict[tel]["width"].value) for tel in hillas_dict]): raise InvalidWidthException( "A HillasContainer contains an ellipse of width==np.nan") if any([hillas_dict[tel]["width"].value == 0 for tel in hillas_dict]): raise InvalidWidthException( "A HillasContainer contains an ellipse of width==0") hillas_planes, psi_core_dict = self.initialize_hillas_planes( hillas_dict, subarray, telescopes_pointings, array_pointing) # algebraic direction estimate direction, err_est_dir = self.estimate_direction(hillas_planes) # array pointing is needed to define the tilted frame core_pos = self.estimate_core_position(event, hillas_dict, array_pointing, psi_core_dict, hillas_planes) # container class for reconstructed showers _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max(hillas_planes) # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. # that's why lon get's a sign result = ReconstructedGeometryContainer( alt=lat, az=-lon, core_x=core_pos[0], core_y=core_pos[1], tel_ids=[h for h in hillas_dict.keys()], average_intensity=np.mean( [h.intensity for h in hillas_dict.values()]), is_valid=True, alt_uncert=err_est_dir, az_uncert=err_est_dir, h_max=h_max, ) return result
def mcone_gaussblobs(ralim,declim,zlim,n=20000,ufrac=0.7,ncen=500,cradlim=None, rand_elong=False,fix_nmemb=False,random_state=None, doplot=False,colorize=False,cosmo=None,oformat='table'): ''' Generate a mock light cone of random 3D points with added gaussian blobs or "clusters" These clusters are distributed randomly over the cone and can have either fixed or random sizes within a given interval. They can alse be randomly elongated along xyz axes. The nr. of memebers of each cluster can be either fixed or proportional to its extension (really?) The fraction of uniform (non-clustered) points (``ufrac``) can be specified, leaving (1-ufrac)*n points that are distributed among ``ncen`` clusters Parameters ---------- ralim : list (ra0, ra1) RA limits [deg] declim : list (dec0, dec1) DEC limits [deg] zlim : list (z0, z1) Redshift limits npts : integer Total number of points in the cone. Default 20000 ufrac : float Fraction of uniformly distributed points (i.e. non-clustered objects) ncen : integer Number of clusters cradlim : float or list of form [rmin,rmax] Size of clusters in Mpc. In reality it corresponds to 2*sigma of the gaussians. If float, all clusters have the same size. If a list, sizes are chosen randomly between the given limits. If None, defaults to [0.5,25] rand_elong : bool If True, clusters are randomly deformed along xyz axes by a factor of 3 fix_nmemb : bool If True, all clusters have the same nr of members random_state : integer Seed for random number generator doplot : bool If True, generate a plane polar and a ra-dec plot docolorize : bool If True, points for centers and cluster members are colored differently cosmo : astropy cosmology object If None, defaults to a flat LambdaCDM with H_0=100 and Om=0.3 oformat : string Select output format as * 'table' : astropy table. Default * 'array' : numpy array Notes ----- The exact nr of uniform (non-clustered) points is added at the end to complete ``n`` total points Returns ---------- kone : astropy.table / array of shape (nobj_in_cone,7) Table or array of 7 columns [ra,dec,redshift,comdis(redshift),x,y,z] ''' if random_state is not None: np.random.seed(seed=random_state) if cradlim is None : cradlim = [0.5,25.] if cosmo is None: cosmo = FlatLambdaCDM(H0=100, Om0=0.3) nunif = np.int(ufrac*n) # Desided nr of uniform sources nnotunif = n-nunif # Desired nr of sources in clusters # Randomly pick ncen centers for the clusters ----------------------------- Cra,Cdec = uniform_sky(ralim,declim,n=ncen) Cred = (zlim[1]-zlim[0])*np.random.random(ncen) + zlim[0] Cx,Cy,Cz = rdz2xyz(Cra,Cdec,Cred,cosmo) # Set a fixed or random radius within a the input range ------------------ if isinstance(cradlim,list): Crad = (cradlim[1]-cradlim[0])*np.random.random_sample(ncen) + cradlim[0] else: Crad = np.asarray([cradlim]*ncen) Crad = Crad/2. # inout radius is 2*std, so get std for multivariate_normal() # Set the number of members of each cluster ------------------------------ if fix_nmemb: k = np.int(1.0*nnotunif/ncen) #same nr for all clusters Cmem = [k]*ncen else : uu = np.random.randint(4,nnotunif+1,ncen-1) tt = np.append(uu,[4,nnotunif+1]) tt.sort() Cmem = np.diff(tt) # n_members by some proportionality to extension # Generate clusters ----------------------------------------------------- print 'Generating clusters...' for i in range(ncen): print ' |--',i,Cra[i],Cdec[i],Cred[i],Crad[i],Cmem[i] # Real space center for the 3D gaussian (center of cluster) mm = np.array([Cx[i],Cy[i],Cz[i]]) # Real space std for the 3D gaussian (sort of size of cluster) if rand_elong : efac = np.random.random(3)*3. else : efac = np.ones(3) stdx = Crad[i]*efac[0] stdy = Crad[i]*efac[1] stdz = Crad[i]*efac[2] cv = np.array([[stdx,0.,0.],[0.,stdy,0.],[0.,0.,stdz]]) # Number of members of the cluster #nmem = np.int(1.0*nnotunif/ncen) #same nr for all clusters nmem = Cmem[i] # Finally generate the cluster if Cmem[i] > 0: m=np.random.multivariate_normal(mm,cv,nmem) if i == 0 : abc = m else: abc = np.concatenate((abc,m),axis=0) x1,y1,z1 = abc[:,0],abc[:,1],abc[:,2] # Convert clusters from (x,y,z) to (ra,dec,redshift) --------------------- ttt = cartesian_to_spherical(x1,y1,z1) comd1,dec1,ra1 = ttt[0].value,ttt[1].value*180./np.pi,ttt[2].value*180./np.pi tmpz = np.linspace(0.,zlim[1]+7.,500) tmpd = cosmo.comoving_distance(tmpz).value reds1 = np.interp(comd1,tmpd,tmpz,left=-1., right=-1.) if (reds1<0).any(): raise Exception('Problem with redshifts!') # Cut clusters to desired ra,dec,redshift window ------------------------ idx,=np.where( (ra1>ralim[0]) & (ra1<ralim[1]) & (dec1>declim[0]) & (dec1<declim[1]) & (reds1>zlim[0]) & (reds1<zlim[1]) ) ra1,dec1,reds1=ra1[idx],dec1[idx],reds1[idx] ncpop=len(ra1) # this is the effective nr of clustered objects in the cone # Add uniform background points to complete n objects -------------------- nback = n-ncen-ncpop ra2,dec2 = uniform_sky(ralim,declim,n=nback) reds2 = (zlim[1]-zlim[0])*np.random.random(nback) + zlim[0] x2,y2,z2 = rdz2xyz(ra2,dec2,reds2,cosmo) #print 'n,nunif,nnotunif,ncen,ncpop,nback',n,nunif,nnotunif,ncen,ncpop,nback print 'Results' print ' |--Nr of clusters :',ncen print ' |--Nr of cluster members :',ncpop print ' |--Nr of non-cluster objects :',nback print ' |--Total nr of objects in cone :',n # Join everything and do plot -------------------------------------------- ra = np.concatenate([Cra,ra1,ra2]) dec = np.concatenate([Cdec,dec1,dec2]) reds = np.concatenate([Cred,reds1,reds2]) distC = cosmo.comoving_distance(Cred).value dist1 = cosmo.comoving_distance(reds1).value dist2 = cosmo.comoving_distance(reds2).value dist = np.concatenate([distC,dist1,dist2]) x = np.concatenate([Cx,x1,x2]) y = np.concatenate([Cy,y1,y2]) z = np.concatenate([Cz,z1,z2]) if colorize: c2,c1,cc = 'k','b','r' spts, scen = 0.2, 20 else: c2,c1,cc = 'k','k','k' spts, scen = 0.2, 0.2 if doplot: #x,y=raz2xy(ra,z) #plt.scatter(x,y,s=0.4) #c=z,cmap='jet' #plt.scatter(ra,dec,s=spts,c=z) x2,y2=raz2xy(ra2,reds2) x1,y1=raz2xy(ra1,reds1) xC,yC=raz2xy(Cra,Cred) plt.scatter(x2,y2,s=spts,color=c2) plt.scatter(x1,y1,s=spts,color=c1) plt.scatter(xC,yC,s=scen,color=cc) plt.figure() plt.scatter(ra2,dec2,s=spts,color=c2) plt.scatter(ra1,dec1,s=spts,color=c1) plt.scatter(Cra,Cdec,s=scen,color=cc) plt.axis('equal') # Choose ouput format ---------------------------------------------------- kone = np.asarray(zip(ra,dec,reds,dist,x,y,z)) if oformat == 'table' : cols = ['ra','dec','z','comd','px','py','pz'] kone = Table(data=kone, names=cols) return kone
#--------------------------------------------------------------- #Moments cinetiques integre et moment absolu integre et stockage #--------------------------------------------------------------- J_int += J_shell J_abs_int += J_shell_abs J_int_tab[s] = J_int J_abs_int_tab[s] = J_abs_int #--------------------------------- #Directions de moments et stockage #--------------------------------- if direction_J == True: (rayon, theta, phi) = coord.cartesian_to_spherical(moment_shell_x, moment_shell_y, moment_shell_z) phi = phi.value if theta.value >= 0.: theta = np.pi / 2. - theta.value else: theta = np.pi / 2. + theta.value dir_theta[s] = theta * 180 / np.pi #theta en degre dir_phi[s] = phi * 180 / np.pi #phi en degre #-------------------------------- #Trace des differentes quantites #-------------------------------- plt.semilogy(radius_shell, V_rot_stock, marker='.', color='midnightblue',
def predict(self, hillas_dict, inst, array_pointing, telescopes_pointings=None): """ The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict: dict dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description array_pointing: SkyCoord[AltAz] pointing direction of the array telescopes_pointings: dict[SkyCoord[AltAz]] dictionary of pointing direction per each telescope Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 InvalidWidthException if any width is np.nan or 0 """ # filter warnings for missing obs time. this is needed because MC data has no obs time warnings.filterwarnings(action='ignore', category=MissingFrameAttributeWarning) # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}".format( len(hillas_dict))) # check for np.nan or 0 width's as these screw up weights if any( [np.isnan(hillas_dict[tel]['width'].value) for tel in hillas_dict]): raise InvalidWidthException( "A HillasContainer contains an ellipse of width==np.nan") if any([hillas_dict[tel]['width'].value == 0 for tel in hillas_dict]): raise InvalidWidthException( "A HillasContainer contains an ellipse of width==0") # use the single telescope pointing also for parallel pointing: code is more general if telescopes_pointings is None: telescopes_pointings = { tel_id: array_pointing for tel_id in hillas_dict.keys() } else: self.divergent_mode = True self.corrected_angle_dict = {} self.initialize_hillas_planes(hillas_dict, inst.subarray, telescopes_pointings, array_pointing) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() # array pointing is needed to define the tilted frame core_pos = self.estimate_core_position(hillas_dict, array_pointing) # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max() # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. result.alt, result.az = lat, -lon result.core_x = core_pos[0] result.core_y = core_pos[1] result.core_uncert = np.nan result.tel_ids = [h for h in hillas_dict.keys()] result.average_intensity = np.mean( [h.intensity for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def polygon_centroid(vertices): ''' Calculate the centroid of a spherical polygon over a unit sphere. Usage: inertia = polygon_centroid(vertices) Inputs: vertices -> [float 2d array] Vertices of the spherical polygon in form of [[lat_0,lon_0],..,[lat_n,lon_n]] with unit of degrees. Vertices can be arranged either counterclockwise or clockwise. Outputs: lat,lon,depth -> [float array with 3 elements] centroid location with lat and lon in degrees, and depth less than 1 Note: The spherical polygon has a latitude range of [-90°,90°] and a longitude range of [-180°,180°] or [0°,360°]. ''' N = len(vertices) # Initialize the 3 components of the centroid coordinate sumx, sumy, sumz = np.zeros(3) for i in range(N - 1): p1 = np.radians(vertices[i]) p2 = np.radians(vertices[i + 1]) pdlon = p2[1] - p1[1] if pdlon < -np.pi: p2[1] = p2[1] + 2 * np.pi if pdlon > np.pi: p2[1] = p2[1] - 2 * np.pi # If two adjacent vertices are close enough(coincident), do nothing. if np.abs(pdlon) < 1e-6: continue c1, c2, c3 = integrate_coeffs(p1, p2) # Calculate the centroid coordinate sx = dblquad(fx, p1[1], p2[1], fs_low, fs_up) sy = dblquad(fy, p1[1], p2[1], fs_low, fs_up) sz = dblquad(fz, p1[1], p2[1], fs_low, fs_up) sumx += sx[0] sumy += sy[0] sumz += sz[0] excess = polygon_excess(vertices) # For counterclockwise arrangement if excess > 0 and excess < 2 * np.pi: centroidx = sumx / excess centroidy = sumy / excess centroidz = sumz / excess if excess >= 2 * np.pi: centroidx = -sumx / (4 * np.pi - excess) centroidy = -sumy / (4 * np.pi - excess) centroidz = -sumz / (4 * np.pi - excess) # For clockwise arrangement if excess < 0 and excess > -2 * np.pi: centroidx = sumx / excess centroidy = sumy / excess centroidz = sumz / excess if excess <= -2 * np.pi: centroidx = sumx / (4 * np.pi + excess) centroidy = sumy / (4 * np.pi + excess) centroidz = sumz / (4 * np.pi + excess) r, lat, lon = cartesian_to_spherical(centroidx, centroidy, centroidz) depth = 1 - r lat, lon = lat.to(u.deg).value, lon.to(u.deg).value return np.array([lat, lon, depth])
def cart2spher(r): ans = cartesian_to_spherical(r[:, 0], r[:, 1], r[:, 2]) theta = ((np.pi / 2 * u.radian - ans[1][0])).to('deg').value phi = ans[2][0].to('deg').value return theta, phi
def make_frame(t): n = int(t/dt) ax.clear() ax.set_title(str(n)) #map = Basemap(projection=projection,lat_0=lat_0,lon_0 = lon_0,resolution = 'l',area_thresh=1000.0,celestial=True,ax = ax) index_,centor = index_list[n],centor_list[n] if source: #ra, dec = map(source.ra.value, source.dec.value) ax.plot(source.ra.value, source.dec.value, '*', color='#f36c21', markersize=20., transform=ccrs.Geodetic()) if points: ax.plot(points.ra.value, points.dec.value, '*', color='#c7a252', markersize=20., transform=ccrs.Geodetic()) if show_bodies and sc_pos is not None: postion, r, lon, lat = earth_points_list[n] lat[lat > 88.0] = 88.0 lat[lat < -88.0] = -88.0 #lon, lat = map(lon, lat) earth = Polygon(list(zip(lon, lat))[::-1], facecolor='#90d7ec', edgecolor='#90d7ec', linewidth=2, alpha=1, transform=ccrs.Geodetic()) ax.add_patch(earth) #ax.add_patch(mpatches.Circle(xy=[postion.ra.value, postion.dec.value], radius=r, # color='#90d7ec', alpha=0.3, transform=ccrs.Geodetic(), # zorder=0)) if time is not None: earth_r = get_body_barycentric('earth',time[n]) moon_r = get_body_barycentric('moon',time[n]) r_e_m = moon_r - earth_r r = sc_pos[n] - np.array([r_e_m.x.value,r_e_m.y.value,r_e_m.z.value])*u.km moon_point_d = cartesian_to_spherical(-r[0],-r[1],-r[2]) moon_ra,moon_dec = moon_point_d[2].deg,moon_point_d[1].deg moon_point = SkyCoord(moon_ra,moon_dec,frame='icrs', unit='deg') ax.plot(moon_point.ra.deg,moon_point.dec.deg,'o',color = '#72777b',markersize = 20,transform=ccrs.Geodetic()) ax.text(moon_point.ra.deg,moon_point.dec.deg,'moon',size = 20,transform=ccrs.Geodetic(),va = 'center',ha='center') if show_bodies and time is not None: tmp_sun = get_sun(time[n]) sun_position = SkyCoord(tmp_sun.ra.deg,tmp_sun.dec.deg,unit='deg', frame='icrs') ax.plot(sun_position.ra.value,sun_position.dec.value ,'o',color = '#ffd400', markersize=40,transform=ccrs.Geodetic()) ax.text(sun_position.ra.value,sun_position.dec.value,'sun',size = 20,transform=ccrs.Geodetic(),va = 'center',ha='center') fovs = get_fov(centor,radius) for i,v in enumerate(index_): r,ra,dec = fovs[i] dec[dec > 88.0] = 88.0 dec[dec < -88.0] = -88.0 detec = Polygon(list(zip(ra,dec))[::-1],facecolor=color_list[v],edgecolor=color_list[v],linewidth=2, alpha=0.5,transform=ccrs.Geodetic()) ax.add_patch(detec) #ra_x,dec_y = map(centor[i].ra.value+2.5,centor[i].dec.value-1) ax.text(centor[i].ra.value, centor[i].dec.value,str(name_list[v]), color=color_list[v], size=22,transform=ccrs.Geodetic(),va = 'center',ha='center') ax.gridlines(xlocs=xticks, ylocs=yticks) lats_y_ticke = ax.projection.transform_points(ccrs.Geodetic(),lats_x+lon_0+180.0, lats_y*1.1) lats_y_x = lats_y_ticke[:,0]*0.86 lats_y_y = lats_y_ticke[:,1] proj_xyz = ax.projection.transform_points(ccrs.Geodetic(),np.array([0,30]), np.array([0,0])) dx_ = np.abs(proj_xyz[0][0]-proj_xyz[1][0]) for indexi,i in enumerate(lons_x): ax.text(i,lons_y[indexi],r'$%d^{\circ}$'%i,transform = ccrs.Geodetic(),size = 20) for indexi,i in enumerate(lats_y): ax.text(lats_y_x[indexi]+dx_,lats_y_y[indexi],r'$%d^{\circ}$'%i,size = 20,ha = 'right',va = 'center') ax.set_global() ax.invert_xaxis() #n = n + 1 return mplfig_to_npimage(fig)
def detector_plot(self,radius = 10.0,source=None,points = None,good = False,highlight = None, highlight_color = '#f26522', lon_0 = 180,ax = None,show_bodies = False,avoid_pole = True,time =None, style = 'A',index = 0,size = 1): #pole = SkyCoord([0, 0], [90, -90], frame='icrs', unit='deg') if ax is None: fig = plt.figure(figsize = (20,10)) ax = fig.add_subplot(1,1,1,projection=ccrs.Mollweide(central_longitude=lon_0),facecolor = '#f6f5ec') xticks = list(range(-180, 180, 30)) yticks = list(range(-90, 90, 15)) lons_x = np.arange(0,360,30) lons_y = np.zeros(lons_x.size) lats_y = np.arange(-75,76,15) lats_x = np.zeros(lats_y.size) ax.gridlines(xlocs=xticks, ylocs=yticks) lats_y_ticke = ax.projection.transform_points(ccrs.Geodetic(),lats_x+lon_0+180.0, lats_y*1.1) lats_y_x = lats_y_ticke[:,0]*0.86 lats_y_y = lats_y_ticke[:,1] proj_xyz = ax.projection.transform_points(ccrs.Geodetic(),np.array([0,30]), np.array([0,0])) dx_ = np.abs(proj_xyz[0][0]-proj_xyz[1][0]) for indexi,i in enumerate(lons_x): ax.text(i,lons_y[indexi],r'$%d^{\circ}$'%i,transform = ccrs.Geodetic(),size = 20*size) for indexi,i in enumerate(lats_y): ax.text(lats_y_x[indexi]+dx_,lats_y_y[indexi],r'$%d^{\circ}$'%i,size = 20*size,ha = 'right',va = 'center') ax.set_global() ax.invert_xaxis() if time is not None: utc = self.Time_transition.met_to_utc(time) ax.set_title(str(utc.fits),size = 20*size) else: ax.set_title(str(index),size = 20*size) if good and source : if time is not None and self.met_time is not None: index_,centor = self.get_good_detector_centers_with_time(time,source=source) else: index_,centor = self.get_good_detector_centers(source,index = [index]) index_ = index_[0] centor = centor[0] else: if time is not None: centor,index_ = self.get_detector_centers_with_time(time) else: index_ = self.get_detector_index(index=[index])[0] centor = self.get_detector_centers(index = [index])[0] if show_bodies and self.sc_pos is not None : #print('plot_earth!') if time is not None and self.met_time is not None: postion, r, lon, lat = self.get_earth_point_with_time(time) else: postion, r, lon, lat = self.get_earth_point(index=[index])[0] if avoid_pole: lat[lat>88.0]=88.0 lat[lat<-88.0]=-88.0 #print(lat) #ax.plot( lon, lat,'-',color = 'k',transform=ccrs.Geodetic(),linewidth=5) earth = Polygon(list(zip(lon, lat))[::-1], facecolor='#90d7ec', edgecolor='#90d7ec', linewidth=2*size, alpha=1,transform=ccrs.Geodetic()) ax.add_patch(earth) #ax.add_patch(mpatches.Circle(xy=[postion.ra.value,postion.dec.value],transform=ccrs.Geodetic(), radius=r, color='#90d7ec', alpha=1, zorder=0)) if self.time is not None: if time is not None: time_utc = self.Time_transition.met_to_utc(time) earth_r = get_body_barycentric('earth', time_utc) moon_r = get_body_barycentric('moon',time_utc ) else: earth_r = get_body_barycentric('earth', self.time[index]) moon_r = get_body_barycentric('moon', self.time[index]) r_e_m = moon_r - earth_r if time is not None: x_f, y_f, z_f = self.sc_pos_f x = x_f(time) y = y_f(time) z = z_f(time) r = -np.array([x,y,z])*self.pos_unit - np.array([r_e_m.x.value, r_e_m.y.value, r_e_m.z.value]) * u.km else: r = self.sc_pos[index] - np.array([r_e_m.x.value, r_e_m.y.value, r_e_m.z.value]) * u.km moon_point_d = cartesian_to_spherical(-r[0], -r[1], -r[2]) moon_ra, moon_dec = moon_point_d[2].deg, moon_point_d[1].deg moon_point = SkyCoord(moon_ra, moon_dec, frame='icrs', unit='deg') #moon_ra, moon_dec = map(moon_point.ra.deg, moon_point.dec.deg) ax.plot(moon_point.ra.deg, moon_point.dec.deg, 'o', color='#72777b', markersize=20*size,transform=ccrs.Geodetic()) ax.text(moon_point.ra.deg, moon_point.dec.deg, 'moon', size=20*size,transform=ccrs.Geodetic(),va = 'center',ha='center') if show_bodies and self.time is not None: if time is not None: time_utc = self.Time_transition.met_to_utc(time) tmp_sun = get_sun(time_utc) else: tmp_sun = get_sun(self.time[index]) sun_position = SkyCoord(tmp_sun.ra.deg, tmp_sun.dec.deg, unit='deg', frame='icrs') ax.plot(sun_position.ra.value, sun_position.dec.value, 'o', color='#ffd400', markersize=40*size,transform=ccrs.Geodetic()) ax.text(sun_position.ra.value, sun_position.dec.value, 'sun', size=20*size,transform=ccrs.Geodetic(),va = 'center',ha='center') fovs = self.get_fov(centor, radius) for i,v in enumerate(index_): r,ra,dec = fovs[i] name_ = self.detectors.name_list[v] if avoid_pole: dec[dec>88.0]=88.0 dec[dec<-88.0]=-88.0 if highlight is not None: if name_ in highlight: color_ = highlight_color else: color_ = self.detectors.color_list[v] else: color_ = self.detectors.color_list[v] detec = Polygon(list(zip(ra,dec))[::-1],facecolor=color_,edgecolor=color_,linewidth=2*size, alpha=0.5,transform=ccrs.Geodetic()) ax.add_patch(detec) plt.text(centor[i].ra.value, centor[i].dec.value,str(name_), color=self.detectors.color_list[v], size=22*size,transform=ccrs.Geodetic(),va = 'center',ha='center') if source: ax.plot(source.ra.value, source.dec.value, '*', color='#f36c21', markersize=20.*size,transform=ccrs.Geodetic()) if points: ax.plot(points.ra.value, points.dec.value, '*', color='#c7a252', markersize=20.*size,transform=ccrs.Geodetic()) return ax
def detector_plot(self, radius=10.0, source=None, points=None, good=False, projection='moll', lat_0=0, lon_0=180, ax=None, show_bodies=False, style='A', index=None): pole = SkyCoord([0, 0], [90, -90], frame='icrs', unit='deg') if ax is None: fig = plt.figure(figsize=(20, 10)) ax = fig.add_subplot(1, 1, 1) ax.set_title(str(index)) map = Basemap(projection=projection, lat_0=lat_0, lon_0=lon_0, resolution='l', area_thresh=1000.0, celestial=True, ax=ax) if good and source: index_, centor = self.get_good_detector_centers(source, index=[index]) index_ = index_[0] centor = centor[0] else: index_ = self.get_detector_index(index=[index])[0] centor = self.get_detector_centers(index=[index])[0] if show_bodies and self.sc_pos is not None: #print('plot_earth!') if projection in ['moll']: postion, r, lon, lat = self.get_earth_point(index=[index])[0] lon_lis, lat_lis = get_poly(postion, r, lon, lat, pole, lon_0) for i in range(len(lon_lis)): x, y = map(lon_lis[i], lat_lis[i]) earth = Polygon(list(zip(x, y)), facecolor='#90d7ec', edgecolor='#90d7ec', linewidth=0, alpha=1) ax.add_patch(earth) else: postion, r, lon, lat = self.get_earth_point(index=[index])[0] lon, lat = map(lon, lat) earth = Polygon(list(zip(lon, lat)), facecolor='#90d7ec', edgecolor='#90d7ec', linewidth=2, alpha=1) ax.add_patch(earth) if self.time is not None: #print(self.time) earth_r = get_body_barycentric('earth', self.time[index]) moon_r = get_body_barycentric('moon', self.time[index]) r_e_m = moon_r - earth_r r = self.sc_pos[index] - np.array( [r_e_m.x.value, r_e_m.y.value, r_e_m.z.value]) * u.km moon_point_d = cartesian_to_spherical(-r[0], -r[1], -r[2]) moon_ra, moon_dec = moon_point_d[2].deg, moon_point_d[1].deg moon_point = SkyCoord(moon_ra, moon_dec, frame='icrs', unit='deg') moon_ra, moon_dec = map(moon_point.ra.deg, moon_point.dec.deg) map.plot(moon_ra, moon_dec, 'o', color='#72777b', markersize=20) plt.text(moon_ra, moon_dec - 800000, 'moon', size=20) if show_bodies and self.time is not None: tmp_sun = get_sun(self.time[index]) sun_position = SkyCoord(tmp_sun.ra.deg, tmp_sun.dec.deg, unit='deg', frame='icrs') sun_ra, sun_dec = map(sun_position.ra.value, sun_position.dec.value) map.plot(sun_ra, sun_dec, 'o', color='#ffd400', markersize=40) plt.text(sun_ra - 550000, sun_dec - 200000, 'sun', size=20) fovs = self.get_fov(centor, radius) if projection in ['moll']: for i, v in enumerate(index_): r, ra, dec = fovs[i] lon_lis, lat_lis = get_poly(centor[i], r, ra, dec, pole, lon_0) #print(str(self.detectors.name_list[v])) #print(lon_lis, lat_lis) for ij in range(len(lon_lis)): x, y = map(lon_lis[ij], lat_lis[ij]) detec = Polygon(list(zip(x, y)), facecolor=self.detectors.color_list[v], edgecolor=self.detectors.color_list[v], linewidth=2, alpha=0.5) ax.add_patch(detec) ra_x, dec_y = map(centor[i].ra.value + 2.5, centor[i].dec.value - 1) plt.text(ra_x, dec_y, str(self.detectors.name_list[v]), color=self.detectors.color_list[v], size=22) else: for i, v in enumerate(index_): r, ra, dec = fovs[i] detec = Polygon(list(zip(ra, dec)), facecolor=self.detectors.color_list[v], edgecolor=self.detectors.color_list[v], linewidth=2, alpha=0.5) ax.add_patch(detec) ra_x, dec_y = map(centor[i].ra.value + 2.5, centor[i].dec.value - 1) plt.text(ra_x, dec_y, str(self.detectors.name_list[v]), color=self.detectors.color_list[v], size=22) if source: ra, dec = map(source.ra.value, source.dec.value) map.plot(ra, dec, '*', color='#f36c21', markersize=20.) if points: ra, dec = map(points.ra.value, points.dec.value) map.plot(ra, dec, '*', color='#c7a252', markersize=20.) if projection == 'moll': az1 = np.arange(0, 360, 30) zen1 = np.zeros(az1.size) + 2 azname = [] for i in az1: azname.append(r'${\/%s\/^{\circ}}$' % str(i)) x1, y1 = map(az1, zen1) for index1, value in enumerate(az1): plt.text(x1[index1], y1[index1], azname[index1], size=20) map.drawmeridians(np.arange(0, 360, 30), dashes=[1, 0], color='#d9d6c3') map.drawparallels(np.arange(-90, 90, 15), dashes=[1, 0], labels=[1, 0, 0, 1], color='#d9d6c3', size=20) map.drawmapboundary(fill_color='#f6f5ec') return map
def make_frame(t): n = int(t / dt) ax.clear() ax.set_title(str(n)) map = Basemap(projection=projection, lat_0=lat_0, lon_0=lon_0, resolution='l', area_thresh=1000.0, celestial=True, ax=ax) index_, centor = index_list[n], centor_list[n] if source: ra, dec = map(source.ra.value, source.dec.value) map.plot(ra, dec, '*', color='#f36c21', markersize=20.) if points: ra, dec = map(points.ra.value, points.dec.value) map.plot(ra, dec, '*', color='#c7a252', markersize=20.) if show_bodies and sc_pos is not None: if projection in ['moll']: postion, r, lon, lat = earth_points_list[n] lon_lis, lat_lis = get_poly(postion, r, lon, lat, pole, lon_0) for i in range(len(lon_lis)): x, y = map(lon_lis[i], lat_lis[i]) earth = Polygon(list(zip(x, y)), facecolor='#90d7ec', edgecolor='#90d7ec', linewidth=0, alpha=1) ax.add_patch(earth) else: postion, r, lon, lat = earth_points_list[n] lon, lat = map(lon, lat) earth = Polygon(list(zip(lon, lat)), facecolor='#90d7ec', edgecolor='#90d7ec', linewidth=2, alpha=1) ax.add_patch(earth) if time is not None: earth_r = get_body_barycentric('earth', time[n]) moon_r = get_body_barycentric('moon', time[n]) r_e_m = moon_r - earth_r r = sc_pos[n] - np.array( [r_e_m.x.value, r_e_m.y.value, r_e_m.z.value]) * u.km moon_point_d = cartesian_to_spherical(-r[0], -r[1], -r[2]) moon_ra, moon_dec = moon_point_d[2].deg, moon_point_d[ 1].deg moon_point = SkyCoord(moon_ra, moon_dec, frame='icrs', unit='deg') moon_ra, moon_dec = map(moon_point.ra.deg, moon_point.dec.deg) map.plot(moon_ra, moon_dec, 'o', color='#72777b', markersize=20) plt.text(moon_ra, moon_dec - 800000, 'moon', size=20) if show_bodies and time is not None: tmp_sun = get_sun(time[n]) sun_position = SkyCoord(tmp_sun.ra.deg, tmp_sun.dec.deg, unit='deg', frame='icrs') sun_ra, sun_dec = map(sun_position.ra.value, sun_position.dec.value) map.plot(sun_ra, sun_dec, 'o', color='#ffd400', markersize=40) plt.text(sun_ra - 550000, sun_dec - 200000, 'sun', size=20) fovs = get_fov(centor, radius) if projection in ['moll']: for i, v in enumerate(index_): r, ra, dec = fovs[i] lon_lis, lat_lis = get_poly(centor[i], r, ra, dec, pole, lon_0) for ij in range(len(lon_lis)): x, y = map(lon_lis[ij], lat_lis[ij]) detec = Polygon(list(zip(x, y)), facecolor=color_list[v], edgecolor=color_list[v], linewidth=2, alpha=0.5) ax.add_patch(detec) ra_x, dec_y = map(centor[i].ra.value + 2.5, centor[i].dec.value - 1) plt.text(ra_x, dec_y, str(name_list[v]), color=color_list[v], size=22) else: for i, v in enumerate(index_): r, ra, dec = fovs[i] detec = Polygon(list(zip(ra, dec)), facecolor=color_list[v], edgecolor=color_list[v], linewidth=2, alpha=0.5) ax.add_patch(detec) ra_x, dec_y = map(centor[i].ra.value + 2.5, centor[i].dec.value - 1) plt.text(ra_x, dec_y, str(name_list[v]), color=color_list[v], size=22) if projection == 'moll': az1 = np.arange(0, 360, 30) zen1 = np.zeros(az1.size) + 2 azname = [] for i in az1: azname.append(r'${\/%s\/^{\circ}}$' % str(i)) x1, y1 = map(az1, zen1) for index1, value in enumerate(az1): plt.text(x1[index1], y1[index1], azname[index1], size=20) map.drawmeridians(np.arange(0, 360, 30), dashes=[1, 0], color='#d9d6c3') map.drawparallels(np.arange(-90, 90, 15), dashes=[1, 0], labels=[1, 0, 0, 1], color='#d9d6c3', size=20) map.drawmapboundary(fill_color='#f6f5ec') n = n + 1 return mplfig_to_npimage(fig)
def predict(self, hillas_dict, inst, pointing_alt, pointing_az, seed_pos=(0, 0)): """The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict : python dictionary dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description pointing_alt: pointing_az: seed_pos : python tuple shape (2) tuple with a possible seed for the core position fit (e.g. CoG of all telescope images) Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 """ # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}".format( len(hillas_dict))) self.inititialize_hillas_planes(hillas_dict, inst.subarray, pointing_alt, pointing_az) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() # core position estimate using a geometric approach core_pos = self.estimate_core_position(hillas_dict) # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max() # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. result.alt, result.az = lat, -lon result.core_x = core_pos[0] result.core_y = core_pos[1] result.core_uncert = np.nan result.tel_ids = [h for h in hillas_dict.keys()] result.average_size = np.mean( [h.intensity for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
def mcone_filam(ralim,declim,zlim,npts=80000,nvoids=2000,nstep=100,rmin=None, b=150.,repmethod='rotation',cosmo=None,oformat='table'): ''' Generate a mock light cone of random 3D points emulating filamentary structure To create filaments, the algorithm evolves a set of random points over a sphere, pushing them away in small steps from a random set of void centers. In each step, the coordinates are contracted a bit towards the origin. Then, the sphere is chopped into a cube. This cube is then stacked in 3D along the desired observation cone with as many cubes as needed. This can generate artificial strucure so each cube can be : (1) Copied as is (``repmethod='copy'``). This will likely introduce artificial patterns. (2) Randomly rotated and mirrored (``repmethod='rotation'``) (3) Generated randomly, so each box is uniquely random (``repmethod='fullrandom'``). Naturally this is slower Parameters ---------- ralim : list (ra0, ra1) RA limits [deg] declim : list (dec0, dec1) DEC limits [deg] zlim : list (z0, z1) Redshift limits npts : integer Number of points in the initial unit sphere. Default 20000 nvoids : integer Number of voids in the initial unit sphere. Default 1000 nsteps : integer Number of steps that points move away from void. In general, less steps means softer and weaker filaments. Default 100 rmin : float After box is created, remove 1 member of each pair closer than rmin [Mpc] b : float Box size in Mpc. Default 300 repmethod : string Repetition method for the boxes along the cone volume * 'copy' : the same box is repeated * 'rotation' : the same box is repeated but rotated and mirrored. Default * 'fullrandom' : generate unique random boxes each time cosmo : astropy cosmology object If not given, defaults to a flat LambdaCDM with H_0=100 and Om=0.3 oformat : string Select output format as * 'table' : astropy table. Default * 'array' : numpy array Notes ----- The box is always unit size, which is then scaled to any meaningfull size by ``b``. The units depend on your intepretation. A choice of ``nvoids=2000`` and ``b=150`` gets a box of 150 Mpc with voids and filaments of size similar to real ones. In general : * For a fixed ``b``, the larger ``nsteps`` the stronger the features * For a fixed ``b``, The larger ``nvoids`` the smaller the structure * Smaller structure means more points can be included to trace small scales without getting unrealistic features. It is hard to estimate a priori how many points will fall inside the observation cone. Just give a try and change ``npts`` accordingly. Returns ---------- kone : astropy.table / array of shape (nobj_in_cone,7) Table or array of 7 columns [ra,dec,redshift,comdis(redshift),x,y,z] ''' if cosmo is None: cosmo = FlatLambdaCDM(H0=100, Om0=0.3) # Get (ra/dec/z) into units of radians and comov_Mpc --------------------- #torad = np.pi/180 #ra0, ra1 = ralim[0]*torad, ralim[1]*torad #dec0,dec1 = declim[0]*torad, declim[1]*torad d0 = cosmo.comoving_distance(zlim[0]).value d1 = cosmo.comoving_distance(zlim[1]).value # Build unit cube with filaments, scaled by b ---------------------------- xyz = filament_box(npts=npts,nvoids=nvoids,nstep=nstep,rmin=rmin,b=b) # Fill observation cone with cubes --------------------------------------- xyza = fill_cone(ralim,declim,zlim,xyz=xyz,b=b,repmethod=repmethod, npts=npts,nvoids=nvoids,nstep=nstep,rmin=rmin,cosmo=cosmo) # Prune points outside the exact observation cone ------------------------ x,y,z = xyza[:,0],xyza[:,1],xyza[:,2] ttt = cartesian_to_spherical(x,y,z) comd = ttt[0].value dec = ttt[1].value*180./np.pi ra = ttt[2].value*180./np.pi idx, = np.where( (ra>ralim[0]) & (ra<ralim[1]) & (dec>declim[0]) & (dec<declim[1]) & (comd>d0) & (comd<d1)) nobj = len(idx) print 'Results' print ' |-- Prunned objects outside intersecting cubes :',len(ra)-nobj print ' |-- Total points inside light cone :',nobj print '-------------------------------------------------------------' # Transform comdis to redshift interpolating over a list ----------------- tmpz = np.linspace(0.,zlim[1]+7.,500) tmpd = cosmo.comoving_distance(tmpz).value redsh = np.interp(comd[idx],tmpd,tmpz,left=-1., right=-1.) if (redsh<0).any(): raise Exception('Problem with redshifts!') # Choose ouput format ---------------------------------------------------- kone = np.asarray(zip(ra[idx],dec[idx],redsh,comd[idx],x[idx],y[idx],z[idx])) if oformat == 'table' : cols = ['ra','dec','z','comd','px','py','pz'] kone = Table(data=kone, names=cols) return kone
def detector_plot(self, radius=10.0, source=None, points=None, good=False, projection='moll', lat_0=0, lon_0=180, ax=None, show_bodies=False): if ax is None: fig = plt.figure(figsize=(20, 10)) ax = fig.add_subplot(111) map = Basemap(projection=projection, lat_0=lat_0, lon_0=lon_0, resolution='l', area_thresh=1000.0, celestial=True, ax=ax) fovs = self.get_fov(radius) if good and source: index, centor = self.get_good_detector_centers(source) else: index = self.get_detector_index() centor = self.get_detector_centers() if source: ra, dec = map(source.ra.value, source.dec.value) map.plot(ra, dec, '*', color='#f36c21', markersize=20.) if points: ra, dec = map(points.ra.value, points.dec.value) map.plot(ra, dec, '*', color='#c7a252', markersize=20.) for i in index: print(fovs[i]) ra, dec = fovs[i] ra, dec = map(ra, dec) map.plot(ra, dec, '.', color='#74787c', markersize=3) x, y = map(centor[i].icrs.ra.value, centor[i].icrs.dec.value) plt.text(x - 200000, y - 200000, str(i), color='#74787c', size=22) if show_bodies and self.sc_pos is not None: earth_points = self.get_earth_point() lon, lat = earth_points.ra.value, earth_points.dec.value lon, lat = map(lon, lat) map.plot(lon, lat, ',', color="#0C81F9", alpha=0.1, markersize=4.5) if self.time is not None: earth_r = get_body_barycentric('earth', self.time) moon_r = get_body_barycentric('moon', self.time) r_e_m = moon_r - earth_r r = self.sc_pos - np.array( [r_e_m.x.value, r_e_m.y.value, r_e_m.z.value]) * u.km moon_point_d = cartesian_to_spherical(-r[0], -r[1], -r[2]) moon_ra, moon_dec = moon_point_d[2].deg, moon_point_d[1].deg moon_point = SkyCoord(moon_ra, moon_dec, frame='icrs', unit='deg') moon_ra, moon_dec = map(moon_point.ra.deg, moon_point.dec.deg) map.plot(moon_ra, moon_dec, 'o', color='#72777b', markersize=20) plt.text(moon_ra, moon_dec - 800000, 'moon', size=20) if show_bodies and self.time is not None: tmp_sun = get_sun(self.time) sun_position = SkyCoord(tmp_sun.ra.deg, tmp_sun.dec.deg, unit='deg', frame='icrs') sun_ra, sun_dec = map(sun_position.ra.value, sun_position.dec.value) map.plot(sun_ra, sun_dec, 'o', color='#ffd400', markersize=40) plt.text(sun_ra - 550000, sun_dec - 200000, 'sun', size=20) if projection == 'moll': az1 = np.arange(0, 360, 30) zen1 = np.zeros(az1.size) + 2 azname = [] for i in az1: azname.append(r'${\/%s\/^{\circ}}$' % str(i)) x1, y1 = map(az1, zen1) for index, value in enumerate(az1): plt.text(x1[index], y1[index], azname[index], size=20) map.drawmeridians(np.arange(0, 360, 30), dashes=[1, 0], color='#d9d6c3') map.drawparallels(np.arange(-90, 90, 15), dashes=[1, 0], labels=[1, 0, 0, 1], color='#d9d6c3', size=20) map.drawmapboundary(fill_color='#f6f5ec')
import numpy as np from astropy.coordinates import cartesian_to_spherical # make a realization of field in 3D data = np.loadtxt('../voids_real/pixel_data.dat') loc = data[:, :3] ixs = data[:, -1] skewers = np.unique(ixs) # put back to the correct locations shift = np.loadtxt('../voids_real/shift_xyz.dat') rot = np.loadtxt('../voids_real/rot_matrix.dat') loc += shift loc = np.dot(np.linalg.inv(rot), loc.T).T # convert to spherical coordinates sphere = cartesian_to_spherical(*loc.T) r = sphere[0].value ra = sphere[1].value # sample a few points out of it as signal # add noise to the points
def _coords(x, y, z, output): r, lat, lon = coord.cartesian_to_spherical(x, y, z) r *= const.R_sun lon += output._lon0 + 180 * u.deg coords = coord.SkyCoord(lon, lat, r, frame=output.coordinate_frame) return coords
def predict(self, hillas_dict, inst, pointing_alt, pointing_az): ''' The function you want to call for the reconstruction of the event. It takes care of setting up the event and consecutively calls the functions for the direction and core position reconstruction. Shower parameters not reconstructed by this class are set to np.nan Parameters ----------- hillas_dict: dict dictionary with telescope IDs as key and HillasParametersContainer instances as values inst : ctapipe.io.InstrumentContainer instrumental description pointing_alt: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing altitude pointing_az: dict[astropy.coordinates.Angle] dict mapping telescope ids to pointing azimuth Raises ------ TooFewTelescopesException if len(hillas_dict) < 2 ''' # filter warnings for missing obs time. this is needed because MC data has no obs time warnings.filterwarnings(action='ignore', category=MissingFrameAttributeWarning) # stereoscopy needs at least two telescopes if len(hillas_dict) < 2: raise TooFewTelescopesException( "need at least two telescopes, have {}" .format(len(hillas_dict))) self.initialize_hillas_planes( hillas_dict, inst.subarray, pointing_alt, pointing_az ) # algebraic direction estimate direction, err_est_dir = self.estimate_direction() alt = u.Quantity(list(pointing_alt.values())) az = u.Quantity(list(pointing_az.values())) if np.any(alt != alt[0]) or np.any(az != az[0]): warnings.warn('Divergent pointing not supported') telescope_pointing = SkyCoord(alt=alt[0], az=az[0], frame=HorizonFrame()) # core position estimate using a geometric approach core_pos = self.estimate_core_position(hillas_dict, telescope_pointing) # container class for reconstructed showers result = ReconstructedShowerContainer() _, lat, lon = cartesian_to_spherical(*direction) # estimate max height of shower h_max = self.estimate_h_max() # astropy's coordinates system rotates counter-clockwise. # Apparently we assume it to be clockwise. result.alt, result.az = lat, -lon result.core_x = core_pos[0] result.core_y = core_pos[1] result.core_uncert = np.nan result.tel_ids = [h for h in hillas_dict.keys()] result.average_intensity = np.mean([h.intensity for h in hillas_dict.values()]) result.is_valid = True result.alt_uncert = err_est_dir result.az_uncert = np.nan result.h_max = h_max result.h_max_uncert = np.nan result.goodness_of_fit = np.nan return result
theta2 = np.empty(N_tot, dtype=np.float32) phi2 = np.empty(N_tot, dtype=np.float32) conv = np.pi / 180. NFW.random_nfw(N_part, conc, rDelta, r, theta2, phi2) r_halos = np.sqrt(plc.pos[:, 0][groupsinplane]**2 + plc.pos[:, 1][groupsinplane]**2 + plc.pos[:, 2][groupsinplane]**2) pos_halos = np.transpose( ap.spherical_to_cartesian(r_halos, plc.theta[groupsinplane] * conv, plc.phi[groupsinplane] * conv)) pos_part = np.transpose( ap.spherical_to_cartesian(r, np.pi / 2.0 - theta2, phi2)) ang_h = np.transpose( ap.cartesian_to_spherical(pos_halos[:, 0], pos_halos[:, 1], pos_halos[:, 2])) final_pos = np.repeat(pos_halos, N_part, axis=0) + pos_part final_ang = np.transpose( ap.cartesian_to_spherical(final_pos[:, 0], final_pos[:, 1], final_pos[:, 2])) print(" Updating mass maps") pixels = hp.pixelfunc.ang2pix( hp.pixelfunc.npix2nside(params.npixels), np.pi / 2.0 - final_ang[:, 1], final_ang[:, 2]) deltai += np.bincount(pixels, minlength=params.npixels) else: plc = rp.plc(params.pinplcfile) groupsinplane = (plc.redshift <= z2) & (plc.redshift > z1)