Пример #1
0
def pretty_plot(map_path, ra, dec, cand_name='name'):

    # loading relevant info
    prob = hp.read_map(map_path)
    ipix = np.argmax(prob)
    npix = len(prob)
    nside = hp.npix2nside(npix)
    theta, phi = hp.pix2ang(nside, ipix)

    # getting the center
    ra_max = np.rad2deg(phi)
    dec_max = np.rad2deg(0.5 * np.pi - theta) - 10
    center = str(int(SkyCoord(
        ra_max, dec_max, unit='deg').ra.hms.h)) + 'h ' + str(
            int(SkyCoord(ra_max, dec_max, unit='deg').dec.dms.d)) + 'd'
    sky_area_per_pix = 4 * 180**2 / np.pi / npix
    area_95 = np.sum(np.cumsum(-np.sort(-prob)) <= 0.95) * sky_area_per_pix
    area_50 = np.sum(np.cumsum(-np.sort(-prob)) <= 0.5) * sky_area_per_pix
    print('AREA 50% ', area_50)
    print('AREA 95% ', area_95)

    #plotting
    fig = plt.figure()
    ax = plt.axes(projection='astro globe', center=center)
    ax.imshow_hpx(prob, cmap='cylon')
    cl = postprocess.find_greedy_credible_levels(prob) * 100
    ax.contour_hpx(cl,
                   levels=[50, 95],
                   colors=['black', 'black'],
                   linewidths=[0.5, 0.5])
    ax.grid()
    ax.scatter(ra,
               dec,
               marker='*',
               color='blue',
               transform=ax.get_transform('world'),
               zorder=10)
    ax.set_title(
        fits.open(map_path)[0].header['OBJECT'] + ' / ' +
        str(fits.open(map_path)[0].header['TRIGTIME']) + ' \n' + cand_name)

    return fig
Пример #2
0
def contour(localization_name, dateobs):
    localization = models.Localization.query.filter_by(
        dateobs=dateobs, localization_name=localization_name).one()

    # Calculate credible levels.
    prob = localization.flat_2d
    cls = 100 * postprocess.find_greedy_credible_levels(prob)

    # Construct contours and return as a GeoJSON feature collection.
    levels = [50, 90]
    paths = postprocess.contour(cls, levels, degrees=True, simplify=True)
    center = postprocess.posterior_max(prob)
    localization.contour = {
        'type': 'FeatureCollection',
        'features': [
            {
                'type': 'Feature',
                'geometry': {
                    'type': 'Point',
                    'coordinates': [center.ra.deg, center.dec.deg]
                },
                'properties': {
                    'credible_level': 0
                }
            }
        ] + [
            {
                'type': 'Feature',
                'properties': {
                    'credible_level': level
                },
                'geometry': {
                    'type': 'MultiLineString',
                    'coordinates': path
                }
            }
            for level, path in zip(levels, paths)
        ]
    }
    models.db.session.merge(localization)
    models.db.session.commit()
Пример #3
0
def do_getfields(healpix,
                 FOV=60 / 3600.0,
                 ra=None,
                 dec=None,
                 radius=None,
                 level=None,
                 names=None):
    from ligo.skymap import postprocess
    import matplotlib

    ras, decs = list(float(r) for r in ra), list(float(d) for d in dec)

    if (not level is None):
        cls = 100 * postprocess.find_greedy_credible_levels(healpix)
        paths = postprocess.contour(cls, [level], degrees=True, simplify=True)
        paths = paths[0]

        pts = np.vstack((ras, decs)).T
        idx = np.zeros((len(ras)))
        for path in paths:
            polygon = matplotlib.path.Path(path)
            check = polygon.contains_points(pts)
            check = list(map(int, check))
            idx = np.maximum(idx, check)
        idx = np.where(idx == 1)[0]
        ras, decs = np.array(ras), np.array(decs)
        ras, decs = ras[idx], decs[idx]
    print(
        f"-> Sources included in the {level}% probability contour: {len(ras)}/{len(ra)}"
    )
    if (not names is None) and (len(ras) > 0):
        names = np.array(names)
        names_out = names[idx]
        print(f"-> Specifically: {list(x for x in names_out)}")
    else:
        names_out = []
    #for rr, dd, nn in zip(ras, decs, names_out):
    #    print(f"{nn}, {rr}, {dd}")
    print("number of candidates: ", len(names_out))
    return ras, decs, names_out
Пример #4
0
    def plot_skymap(self,
                    maxpts=None,
                    trials=5,
                    jobs=1,
                    enable_multiresolution=True,
                    objid=None,
                    instruments=None,
                    geo=False,
                    dpi=600,
                    transparent=False,
                    colorbar=False,
                    contour=[50, 90],
                    annotate=True,
                    cmap='cylon',
                    load_pickle=False):
        """ Generate a fits file and sky map from a result

        Code adapted from ligo.skymap.tool.ligo_skymap_from_samples and
        ligo.skymap.tool.plot_skymap. Note, the use of this additionally
        required the installation of ligo.skymap.

        Parameters
        ----------
        maxpts: int
            Maximum number of samples to use, if None all samples are used
        trials: int
            Number of trials at each clustering number
        jobs: int
            Number of multiple threads
        enable_multiresolution: bool
            Generate a multiresolution HEALPix map (default: True)
        objid: str
            Event ID to store in FITS header
        instruments: str
            Name of detectors
        geo: bool
            Plot in geographic coordinates (lat, lon) instead of RA, Dec
        dpi: int
            Resolution of figure in fots per inch
        transparent: bool
            Save image with transparent background
        colorbar: bool
            Show colorbar
        contour: list
            List of contour levels to use
        annotate: bool
            Annotate image with details
        cmap: str
            Name of the colormap to use
        load_pickle: bool, str
            If true, load the cached pickle file (default name), or the
            pickle-file give as a path.
        """

        try:
            from astropy.time import Time
            from ligo.skymap import io, version, plot, postprocess, bayestar, kde
            import healpy as hp
        except ImportError as e:
            logger.info("Unable to generate skymap: error {}".format(e))
            return

        check_directory_exists_and_if_not_mkdir(self.outdir)

        logger.info('Reading samples for skymap')
        data = self.posterior

        if maxpts is not None and maxpts < len(data):
            logger.info('Taking random subsample of chain')
            data = data.sample(maxpts)

        default_obj_filename = os.path.join(
            self.outdir, '{}_skypost.obj'.format(self.label))

        if load_pickle is False:
            try:
                pts = data[['ra', 'dec', 'luminosity_distance']].values
                confidence_levels = kde.Clustered2Plus1DSkyKDE
                distance = True
            except KeyError:
                logger.warning(
                    "The results file does not contain luminosity_distance")
                pts = data[['ra', 'dec']].values
                confidence_levels = kde.Clustered2DSkyKDE
                distance = False

            logger.info('Initialising skymap class')
            skypost = confidence_levels(pts, trials=trials, jobs=jobs)
            logger.info('Pickling skymap to {}'.format(default_obj_filename))
            with open(default_obj_filename, 'wb') as out:
                pickle.dump(skypost, out)

        else:
            if isinstance(load_pickle, str):
                obj_filename = load_pickle
            else:
                obj_filename = default_obj_filename
            logger.info('Reading from pickle {}'.format(obj_filename))
            with open(obj_filename, 'rb') as file:
                skypost = pickle.load(file)
            skypost.jobs = jobs
            distance = isinstance(skypost, kde.Clustered2Plus1DSkyKDE)

        logger.info('Making skymap')
        hpmap = skypost.as_healpix()
        if not enable_multiresolution:
            hpmap = bayestar.rasterize(hpmap)

        hpmap.meta.update(io.fits.metadata_for_version_module(version))
        hpmap.meta['creator'] = "bilby"
        hpmap.meta['origin'] = 'LIGO/Virgo'
        hpmap.meta['gps_creation_time'] = Time.now().gps
        hpmap.meta['history'] = ""
        if objid is not None:
            hpmap.meta['objid'] = objid
        if instruments:
            hpmap.meta['instruments'] = instruments
        if distance:
            hpmap.meta['distmean'] = np.mean(data['luminosity_distance'])
            hpmap.meta['diststd'] = np.std(data['luminosity_distance'])

        try:
            time = data['geocent_time']
            hpmap.meta['gps_time'] = time.mean()
        except KeyError:
            logger.warning('Cannot determine the event time from geocent_time')

        fits_filename = os.path.join(self.outdir,
                                     "{}_skymap.fits".format(self.label))
        logger.info('Saving skymap fits-file to {}'.format(fits_filename))
        io.write_sky_map(fits_filename, hpmap, nest=True)

        skymap, metadata = io.fits.read_sky_map(fits_filename, nest=None)
        nside = hp.npix2nside(len(skymap))

        # Convert sky map from probability to probability per square degree.
        deg2perpix = hp.nside2pixarea(nside, degrees=True)
        probperdeg2 = skymap / deg2perpix

        if geo:
            obstime = Time(metadata['gps_time'], format='gps').utc.isot
            ax = plt.axes(projection='geo degrees mollweide', obstime=obstime)
        else:
            ax = plt.axes(projection='astro hours mollweide')
        ax.grid()

        # Plot sky map.
        vmax = probperdeg2.max()
        img = ax.imshow_hpx((probperdeg2, 'ICRS'),
                            nested=metadata['nest'],
                            vmin=0.,
                            vmax=vmax,
                            cmap=cmap)

        # Add colorbar.
        if colorbar:
            cb = plot.colorbar(img)
            cb.set_label(r'prob. per deg$^2$')

        if contour is not None:
            confidence_levels = 100 * postprocess.find_greedy_credible_levels(
                skymap)
            contours = ax.contour_hpx((confidence_levels, 'ICRS'),
                                      nested=metadata['nest'],
                                      colors='k',
                                      linewidths=0.5,
                                      levels=contour)
            fmt = r'%g\%%' if rcParams['text.usetex'] else '%g%%'
            plt.clabel(contours, fmt=fmt, fontsize=6, inline=True)

        # Add continents.
        if geo:
            geojson_filename = os.path.join(os.path.dirname(plot.__file__),
                                            'ne_simplified_coastline.json')
            with open(geojson_filename, 'r') as geojson_file:
                geoms = json.load(geojson_file)['geometries']
            verts = [
                coord for geom in geoms for coord in zip(*geom['coordinates'])
            ]
            plt.plot(*verts,
                     color='0.5',
                     linewidth=0.5,
                     transform=ax.get_transform('world'))

        # Add a white outline to all text to make it stand out from the background.
        plot.outline_text(ax)

        if annotate:
            text = []
            try:
                objid = metadata['objid']
            except KeyError:
                pass
            else:
                text.append('event ID: {}'.format(objid))
            if contour:
                pp = np.round(contour).astype(int)
                ii = np.round(
                    np.searchsorted(np.sort(confidence_levels), contour) *
                    deg2perpix).astype(int)
                for i, p in zip(ii, pp):
                    text.append(u'{:d}% area: {:d} deg$^2$'.format(p, i))
            ax.text(1, 1, '\n'.join(text), transform=ax.transAxes, ha='right')

        filename = os.path.join(self.outdir,
                                "{}_skymap.png".format(self.label))
        logger.info("Generating 2D projected skymap to {}".format(filename))
        safe_save_figure(fig=plt.gcf(), filename=filename, dpi=dpi)
Пример #5
0
 def credible_levels_2d(self):
     return find_greedy_credible_levels(self.flat_2d)
Пример #6
0
gwtc1 = CWD + '/gwtc1-skymaps'
#gwtc2 = CWD+'/all_skymaps'
all_files = os.listdir(gwtc1)
fnames = []
for file in all_files:
    if file.endswith('.fits'):
        fnames.append(file)

#can remove the loop if you just want one file, in that case you give the filename instead of the loop
# ras = []
# decs = []
for fname in fnames:
    print('processing ' + fname + '...')
    fits_file = gwtc1 + '/' + fname
    skymap, metadata = fits.read_sky_map(fits_file, nest=None)
    cls = 100 * postprocess.find_greedy_credible_levels(skymap)
    contour_levels = [50, 90, 99]

    #this was for Jamie trying to find the 'center' of the contours, ignore it
    # mx = np.max(skymap)
    # mean = np.mean(skymap)
    # std = np.std(skymap)
    # idx = np.where(skymap == mx)

    # print(mx, idx)
    # print('mean: {}'.format(mean))
    # print('std: {}'.format(std))

    # dec, ra= IndexToDeclRa(idx)
    # print('ra=',ra, 'dec=',dec)
    # ras.append(np.radians(ra[0]))
Пример #7
0
def process_gcn(payload, root):
    if write_event:
        event_log = open(logfile, 'a+')
    # Respond only to 'test' events.
    # VERY IMPORTANT! Replace with the following code
    # to respond to only real 'observation' events.
    print("starting process")
    print(datetime.utcnow())
    if write_event:
        event_log.write("starting process")
        event_log.write('\n')
        event_log.write(root.attrib['role'])
        event_log.write('\n')
    print(root.attrib['role'])

    """ Uncomment when we only want to do real observations
    if root.attrib['role'] != 'observation':
       return
    """

    # Read all of the VOEvent parameters from the "What" section.

    params = {elem.attrib['name']:
                  elem.attrib['value']
              for elem in root.iterfind('.//Param')}

    # Respond only to 'CBC' events. Change 'CBC' to "Burst'
    # to respond to only unmodeled burst events.
    print(params['Group'])
    if write_event:
        event_log.write(params['Group'])
        event_log.write('\n')
    if params['Group'] != 'CBC':
        print('not CBC')
        return
    if params['AlertType'] != 'Preliminary':
        print('not Preliminary')
        return
    if 'Pkt_Ser_Num' in params:  # Test events send same event twice, only choose first one.
        check = float(params['Pkt_Ser_Num'])
        if check > 1.1:
            return

    """ COMPLETE TO DEFINE WHICH EVENTS WE ARE LOOKING FOR
    if 'BNS' in params:
       check = float(params['BNS'])
       if  check < 50.0:
          print("not BNS event, skipping")
          return
    else:
       print("not BNS event, skipping")
       return
    """
    # Print all parameters.
    for key, value in params.items():
        print(key, '=', value)
        if write_event:
            event_log.writelines(str(key + '=' + value))

    if 'skymap_fits' in params:
        # Read the HEALPix sky map and the FITS header.i
        skymap, header = hp.read_map(params['skymap_fits'], h=True, verbose=False)
        header = dict(header)

        # Print some values from the FITS header.
        print('Distance =', header['DISTMEAN'], '+/-', header['DISTSTD'])
        if write_event:
            event_log.writelines('Distance =' + str(header['DISTMEAN']) + '+/-' + str(header['DISTSTD']))
            event_log.write('\n')

        # write event information to SQL
        datadict = {'gracedb_id': [params['GraceID']], 'link': [params['EventPage']], 'dist': [header['DISTMEAN']],
                    'dist_err': [header['DISTSTD']]}
        sql_engine = sql.create_engine(connect_string)
        headers = ['gracedb_id', 'link', 'dist', 'dist_err']
        dtypes = {'gracedb_id': 'str', 'link': 'str', 'dist': 'float64', 'dist_err': 'float64'}
        df = pd.DataFrame.from_dict(datadict)
        df.to_sql('events', sql_engine, if_exists='append', index=False)

        # get event ID back
        query = "select * from events ORDER BY 'ID' DESC"
        df = pd.read_sql_query(query, sql_engine)
        event = df['ID'].iloc[-1]

        credible_levels = find_greedy_credible_levels(skymap)

        if send_slack:
            slackmsg = ""
            for key, value in params.items():
                slackmsg = slackmsg + str(key) + '=' + str(value) + '\n'

            slack_client.chat_postMessage(channel=SLACK_CHANNEL, text=slackmsg)
        # get df of galaxies from SQL
        query = "select * from galaxies"
        galaxies = pd.read_sql_query(query, sql_engine)
        gal_ipix = getPixel(skymap, galaxies['ra'], galaxies['dec'])
        """
        offset = ephem.Observer()
        offset.lat = '0.0'
        offset.long = '180'
        offset.date = datetime.utcnow()
        offangle = float(offset.sidereal_time() * 180 / np.pi)
        """
        if plot_map:
            #ax = plt.axes(projection=ccrs.Mollweide(central_longitude=-1 * offangle))
            ax = plt.axes(projection=ccrs.Mollweide())
            ax.stock_img()

        galaxies['credible'] = credible_levels[gal_ipix]
        banana_galaxies = galaxies[(galaxies.credible <= prob_check)]
        banana_galaxies.sort_values(by=['credible'], inplace=True)

        #get list of observatories from SQL
        query = "select * from observers"
        observatories = pd.read_sql_query(query, sql_engine)
        #Find Sun RA/DEC
        sun = ephem.Sun()
        #setup pyephem observer
        telescope = ephem.Observer()
        telescope.date = datetime.utcnow()
        #create a copy of galaxy list in case it ends up depleted
        galaxy_list = copy.deepcopy(banana_galaxies)
        galaxy_list = galaxy_list.values.tolist()
        galaxy_depleted = False
        slackmsg = ''
        matches = []
        slack_count = 0
        for x in range(0, len(observatories)):
            extra_matches = []
            # Check if all galaxies have been assigned, if so start assigning duplicates
            if len(galaxy_list) == 0:
                galaxy_list = copy.deepcopy(banana_galaxies)
                galaxy_list = galaxy_list.values.tolist()
                galaxy_depeleted = True
            telescope.lat = str(observatories['lat'][x]).strip()
            telescope.long = str(observatories['lon'][x]).strip()
            sun.compute(telescope)
            # if sun is up, observatory can be skipped
            if check_sun:
                if sun.alt > max_sun:
                    # print(str(observatories['Code'][x]) + " skipped, Sun is up")
                    continue
            for i in range(0, len(galaxy_list)):
                star = ephem.FixedBody()
                star._ra = ephem.degrees(str(galaxy_list[i][2]))
                star._dec = ephem.degrees(str(galaxy_list[i][3]))
                star.compute(telescope)

                # if the first object is more than 20 degrees below elevation, unlikely any objects will be higher than 45 degrees
                if check_minalt:
                    if star.alt < min_alt:
                        # print(str(observatories['Code'][x]) + " skipped " + str(star.alt) + " is less than -20 degrees")
                        break
                # assign galaxy to observer
                if star.alt > max_alt:
                    matches.append(
                        {'event_id': event, 'obs_ID': observatories['ID'][x], 'galaxy_id': galaxy_list[i][0]})
                    # print(galaxy_list[i])
                    listing = WEBSITE_URL+'/observe?key=' + str(
                        observatories['key'][x]) + '&event=' + str(event) + '&obs=' + str(
                        observatories['ID'][x]) + '&gal=' + str(galaxy_list[i][0]) + '&ra=' + str(
                        galaxy_list[i][2]) + '&dec=' + str(galaxy_list[i][3]) + '&fov=' + str(observatories['fov'][x])
                    print(listing)
                    if write_event:
                        event_log.writelines(listing)
                        event_log.write('\n')
                    #only writing the first 5 urls to slack
                    if send_slack:
                        if slack_count < 5:
                            slack_count += 1
                            slackmsg = slackmsg + listing + '\n'
                    #find extra galaxies within FOV
                    j = i+1
                    y = []
                    print(len(galaxy_list[j:]))
                    if galinfov:
                        for z in range(j,len(galaxy_list)):
                            extra = ephem.FixedBody()
                            extra._ra = ephem.degrees(str(galaxy_list[z][2]))
                            extra._dec = ephem.degrees(str(galaxy_list[z][3]))
                            extra.compute(telescope)
                            sep = float(ephem.separation(star,extra))*180/np.pi
                            if sep < 0.5/2:
                            #if sep < observatories['fov'][x]/2:
                                extra_matches.append({'event_id': event, 'obs_ID': observatories['ID'][x], 'galaxy_id': galaxy_list[z][0]})
                                print(z,sep,ephem.separation(star,extra))
                                y.append(z)
                    if len(y)>1:
                        print(y)
                        y.reverse()
                        for k in y:
                            del galaxy_list[k]
                            
                    # print(str(observatories['ID'][x]) + " " + observatories['name'][x].strip()[15:] + " at Lat:" +str(telescope.lat) + ",Lon:" + str(telescope.lon) + " gets galaxy " + str(galaxy_list[i][1]) + ' ra='+str(star.ra) + ' dec=' + str(star.dec) + ' alt='+str(star.alt))
                    del galaxy_list[i]
                    if plot_map:
                        plt.scatter(telescope.lon * 180 / np.pi, telescope.lat * 180 / np.pi, color='red',
                                    transform=ccrs.Geodetic())
                    break
            if len(extra_matches) > 0:
                extra_matches = pd.DataFrame(extra_matches)
                extra_matches.to_sql('matches_extra', sql_engine, if_exists='append', index=False)
        matches = pd.DataFrame(matches)
        matches.to_sql('matches', sql_engine, if_exists='append', index=False)
        event_log.close()
        if send_slack:
            if len(slackmsg) > 0:
                slack_client.chat_postMessage(channel=SLACK_CHANNEL, text=slackmsg)
                if galaxy_depleted:
                    text = "All" + str(len(banana_galaxies)) + " galaxies assigned"
                    query = "update events set assigned = " + str(len(banana_galaxies)) + ", possible = " + str(
                        len(banana_galaxies)) + " where ID = " + str(event)
                else:
                    text = str(len(banana_galaxies) - len(galaxy_list)) + " galaxies assigned out of " + str(
                        len(banana_galaxies))
                    query = "update events set assigned = " + str(
                        len(banana_galaxies) - len(galaxy_list)) + ", possible = " + str(
                        len(banana_galaxies)) + " where ID = " + str(event)
                    slack_client.chat_postMessage(channel=SLACK_CHANNEL, text=text)
                sql_engine.execute(query)
            else:
                slack_client.chat_postMessage(channel=SLACK_CHANNEL, text="No Galaxies Assigned")
        if plot_map:
            ax.add_feature(Nightshade(datetime.utcnow(), alpha=0.2))
            plt.title("Map of Observable Sites")
            plt.savefig("map.png")
            if send_slack:
                slack_client.files_upload(channels=SLACK_CHANNEL, file="map.png", title=params['GraceID'])
        filename = download_file(params['skymap_fits'], cache=True)
        skyplot([filename, '--annotate', '--geo', '--contour', '50', '90'])
        plt.savefig("hp.png")
        if send_slack:
            slack_client.files_upload(channels=SLACK_CHANNEL, file="hp.png", title=params['GraceID'])
        return
Пример #8
0
def update_skymap(grb_dic, output_dic, conf_dic):
    """
    Function to download skymap and fill the missing info in grb_dic
    This will also initiate gwemopt

    :param grb_dic: dictionary with GRB related infos
    :param output_dic: dictionary with output architecture
    :param conf_dic: dictionary with info for selection
    :return: parms, updated param dictionary after loading skymap
    :return: map_struct, internal gwemopt structure filled when loading skymap
    avoid to reload it later
    """

    # initiate gwemopt dictionary configuration
    # need to use absolute path
    dir_path = os.path.dirname(os.path.abspath(__file__)) + "/"

    grb_dic["skymap"]["nside"] = conf_dic["nside_flat"]
    params = utils_too.init_gwemopt_observation_plan(
        dir_path + conf_dic["config_gwemopt"])

    # include in it full path to sky map fits file in the dictionary
    params["skymap"] = grb_dic["skymap"]

    # include nside from the sky map file

    params["nside"] = grb_dic["skymap"]["nside"]

    # update it with GRB specific part
    params = update_gwemoptconfig(grb_dic, conf_dic, params)

    # close the fits file
    # hdul.close()

    print("Loading skymap...")
    # read map to compute error regions
    map_struct = gwemopt.utils.read_skymap(params,
                                           is3D=params["do3D"],
                                           map_struct=params['map_struct'])

    # error regions
    i = np.flipud(np.argsort(params['map_struct']['prob']))
    credible_levels = find_greedy_credible_levels(
        params['map_struct']['prob'][i])
    cr50 = np.round(
        np.sum(credible_levels <= 0.5) *
        hp.nside2pixarea(grb_dic["skymap"]["nside"], degrees=True), 1)
    cr90 = np.round(
        np.sum(credible_levels <= 0.9) *
        hp.nside2pixarea(grb_dic["skymap"]["nside"], degrees=True), 1)

    # sorted_credible_levels = np.cumsum(grb_dic["skymap"]["probdensity"][i])
    # credible_levels = np.empty_like(sorted_credible_levels)

    idx50 = map_struct["cumprob"] < 0.50
    cr50 = len(map_struct["cumprob"][idx50])
    idx90 = map_struct["cumprob"] < 0.90
    cr90 = len(map_struct["cumprob"][idx90])
    grb_dic["50cr"] = cr50
    grb_dic["90cr"] = cr90

    return params, map_struct
Пример #9
0

## Test if a Sky Location is in the 90% Credible Region
i = np.flipud(np.argsort(hpx))
sorted_credible_levels = np.cumsum(hpx[i])
credible_levels = np.empty_like(sorted_credible_levels)
credible_levels[i] = sorted_credible_levels
credible_levels

## N.B. !!
## Observe that the values in the resulting credible level map vary
## inversely with probability density: the most probable pixel is
## assigned to the credible level 0.0, and the least likely pixel is
## assigned the credible level 1.0.

credible_levels = find_greedy_credible_levels(hpx)
credible_levels

## To check if the pixel that we identified in the previous section is
## within the 90% credible level, simply test if the value of the
## credible level map is less than or equal to 0.9 at that pixel:
credible_levels[ipix]
credible_levels[ipix] <=0.9

##Find the Area of the 90% Credible Region
## Since we just found the credible level map, it’s easy to compute
## the 90% credible area by counting the number of pixels inside the
## 90% credible region and multiplying by the area per pixel.

## In the Python expression below, note that (credible_levels <= 0.9)
## evaluates to a binary array; when it is summed over, true values
Пример #10
0
print('S190828j/bayestar.fits.gz read-in...')
print()
print()

#hpx, header = hp.read_map(inputdata, h=True)

S190828l_npix = len(S190828l_prob)
S190828j_npix = len(S190828j_prob)

S190828l_nside = hp.npix2nside(S190828l_npix)
S190828j_nside = hp.npix2nside(S190828j_npix)

S190828l_pixarea_deg2 = hp.nside2pixarea(S190828l_nside, degrees=True)
S190828j_pixarea_deg2 = hp.nside2pixarea(S190828j_nside, degrees=True)

S190828l_credible_levels = find_greedy_credible_levels(S190828l_prob)
S190828l_npix50 = np.count_nonzero(S190828l_credible_levels <= 0.50)
S190828l_area50 = np.sum(S190828l_credible_levels <= 0.50) * hp.nside2pixarea(
    S190828l_nside, degrees=True)
S190828l_boolArr50 = (S190828l_credible_levels <= 0.50)
S190828l_result50 = np.where(S190828l_boolArr50)
S190828l_npix90 = np.count_nonzero(S190828l_credible_levels <= 0.90)
S190828l_area90 = np.sum(S190828l_credible_levels <= 0.90) * hp.nside2pixarea(
    S190828l_nside, degrees=True)
S190828l_boolArr90 = (S190828l_credible_levels <= 0.90)
S190828l_result90 = np.where(S190828l_boolArr90)
print('S190828l: npix50, area50  ', S190828l_npix50, S190828l_area50,
      '  npix90, area90  ', S190828l_npix90, S190828l_area90)

S190828j_credible_levels = find_greedy_credible_levels(S190828j_prob)
S190828j_npix50 = np.count_nonzero(S190828j_credible_levels <= 0.50)
Пример #11
0
def load_healpix_map(outdir,
                     fitsoutname='skymap.fits.gz',
                     radecs=[],
                     contour=None,
                     annotate=True,
                     inset=False):
    # Load skymap
    skymap, metadata = io.fits.read_sky_map(os.path.join(outdir, fitsoutname),
                                            nest=None)

    # Convert sky map from probability to probability per square degree.
    nside = hp.npix2nside(len(skymap))
    deg2perpix = hp.nside2pixarea(nside, degrees=True)
    probperdeg2 = skymap / deg2perpix

    # Projection type
    ax = plt.axes(projection='astro hours mollweide')
    ax.grid()

    # Plot sky map.
    vmax = probperdeg2.max()
    img = ax.imshow_hpx((probperdeg2, 'ICRS'),
                        nested=metadata['nest'],
                        vmin=0.,
                        vmax=vmax)

    # Add colorbar.
    cb = plot.colorbar(img)
    cb.set_label(r'Prob. per deg²')

    if contour:
        # Add contours.
        cls = 100 * postprocess.find_greedy_credible_levels(skymap)
        cs = ax.contour_hpx((cls, 'ICRS'),
                            nested=metadata['nest'],
                            colors='k',
                            linewidths=0.5,
                            levels=contour)
        fmt = r'%g\%%' if rcParams['text.usetex'] else '%g%%'
        plt.clabel(cs, fmt=fmt, fontsize=6, inline=True)

    # # Add markers (e.g., for injections or external triggers).
    # for ra, dec in radecs:
    #     ax.plot_coord(
    #         SkyCoord(ra, dec, unit='deg'), '*',
    #         markerfacecolor='white', markeredgecolor='black', markersize=10)

    # Try to add a zoom inset
    if inset:
        ra, dec = radecs
        center = SkyCoord(ra * u.deg, dec * u.deg)
        ax_inset = plt.axes([0.59, 0.3, 0.4, 0.4],
                            projection='astro zoom',
                            center=center,
                            radius=10 * u.deg)
        for key in ['ra', 'dec']:
            ax_inset.coords[key].set_ticklabel_visible(False)
            ax_inset.coords[key].set_ticks_visible(False)
        ax.grid()
        ax.mark_inset_axes(ax_inset)
        ax.connect_inset_axes(ax_inset, 'upper left')
        ax.connect_inset_axes(ax_inset, 'lower left')
        ax_inset.scalebar((0.1, 0.1), 5 * u.deg).label()
        ax_inset.compass(0.9, 0.1, 0.2)

        ax_inset.imshow_hpx((probperdeg2, 'ICRS'),
                            nested=metadata['nest'],
                            vmin=0.,
                            vmax=vmax)  # , cmap='cylon')
        ax_inset.plot(center.ra.deg,
                      center.dec.deg,
                      transform=ax_inset.get_transform('world'),
                      marker=plot.reticle(),
                      color='white',
                      markersize=30,
                      markeredgewidth=3)

    # Add a white outline to all text to make it stand out from the background.
    plot.outline_text(ax)
    ax.grid()

    if annotate:
        text = []
        try:
            objid = metadata['objid']
        except KeyError:
            pass
        else:
            text.append('event ID: {}'.format(objid))
        if contour:
            pp = np.round(contour).astype(int)
            ii = np.round(np.searchsorted(np.sort(cls), contour) *
                          deg2perpix).astype(int)
            for i, p in zip(ii, pp):
                # FIXME: use Unicode symbol instead of TeX '$^2$'
                # because of broken fonts on Scientific Linux 7.
                text.append(u'{:d}% area: {:d} deg²'.format(p,
                                                            i,
                                                            grouping=True))
        ax.text(1, 1, '\n'.join(text), transform=ax.transAxes, ha='right')

    plt.show()