def gen_features_norm(data_file, lower, upper, sim_file=None):

    """
    This generates a certain set of features from photon-stream simulation
    or data files that can be used for further analyses.

    Inputs:
    data_file:          location of input data file as string
    lower:              lower limit for time slice cleaning
    upper:              upper limit for time slice cleaning
    sim_file:           location of input simulations file as string
                        default: corresponding to name of data file

    return:
    pandas data frame with features

    """

    # read in files
    if is_simulation_file(data_file):
        reader = ps.SimulationReader(
          photon_stream_path=data_file,
          mmcs_corsika_path=sim_file)
    else:
        reader = ps.EventListReader(data_file)

    # initialisation of list of dicts containing generated data
    events = list()
    border_pix = get_border_pixel_mask()
    x, y = get_pixel_coords()

    # loop for events
    for event in reader:

        lol = event.photon_stream.list_of_lists
        image = phs2image(lol, lower, upper)
        mask = facttools_cleaning(image, lol, lower, upper)


        # empty dict for values
        ev = {}
        # number of photons in biggest cluster
        ev['size'] = image[mask].sum()


        if ev['size'] > 0:

            border_ph = [(border_pix[i] and mask[i]) for i in range(1440)]
            ev['leakage'] = image[border_ph].sum()/ev['size']
            ev.update(safe_observation_info(event))
            ev.update(calc_hillas_features_image(image, mask))
            # append values from dict to list of dicts (events)
            events.append(ev)

    # save list of dicts in pandas data frame
    df = pd.DataFrame(events)
    return df
def calc_hillas_features_image(image, mask):
    """
    Safes hillas features from image to dict ev

    Inputs:
    -----------------------------------------
    image:  Number of photons per pixel (1440)
    mask:   List of pixels that survived the cleaning

    Returns:
    -----------------------------------------
    ev:     dictionary with observation infos
    """

    ev = {}
    x, y = get_pixel_coords()
    ev['n_pixel'] = mask.sum()

    # means of cluster
    ev['cog_x'] = np.average(x[mask], weights=image[mask])
    ev['cog_y'] = np.average(y[mask], weights=image[mask])

    # covariance and eigenvalues/vectors for later calculations
    cov = np.cov(x[mask], y[mask], fweights=image[mask])
    eig_vals, eig_vecs = np.linalg.eigh(cov)

    # width, length and delta
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        ev['width'], ev['length'] = np.sqrt(eig_vals)
        delta = np.arctan(eig_vecs[1, 1] / eig_vecs[0, 1])
    ev['delta'] = delta

    # rotate into main component system
    delta_x = x[mask] - ev['cog_x']
    delta_y = y[mask] - ev['cog_y']
    long = np.cos(delta) * delta_x + np.sin(delta) * delta_y
    trans = - np.sin(delta) * delta_x + np.cos(delta) * delta_y

    # higher order weights in cluster coordinates
    m3_long = np.average(long**3, weights=image[mask])
    m3_trans = np.average(trans**3, weights=image[mask])

    m4_long = np.average(long**4, weights=image[mask])
    m4_trans = np.average(trans**4, weights=image[mask])

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        ev['skewness_long'] = m3_long / ev['length']**3
        ev['skewness_trans'] = m3_trans / ev['width']**3
        ev['kurtosis_long'] = m4_long / ev['length']**4
        ev['kurtosis_trans'] = m4_trans / ev['width']**4

    return ev
Esempio n. 3
0
def test_coords_relation_to_pos_from_dataframe():

    from fact.instrument.camera import get_pixel_dataframe
    from fact.instrument.camera import get_pixel_coords
    import numpy as np

    pc = get_pixel_coords()
    pd = get_pixel_dataframe()

    assert np.allclose(pc[0], -pd.pos_Y.values * 9.5)
    assert np.allclose(pc[1], pd.pos_X.values * 9.5)
def calc_delta_delta(event, mask):

    x, y = get_pixel_coords()

    # if 'source_position_zd' not in df.columns:
    frame = AltAz(location=LOCATION, obstime=to_astropy_time(pd.to_datetime(event.observation_info.time)))

    crab_altaz = crab.transform_to(frame)

    source_position_zd_phs = crab_altaz.zen.deg
    source_position_az_phs = crab_altaz.az.deg

    source_x, source_y = horizontal_to_camera(
       source_position_zd_phs,
       source_position_az_phs,
       event.zd,
       event.az,
    )

    # safe x, y and t components of Photons. shape = (#photons,3)
    xyt = event.photon_stream.point_cloud
    lol = event.photon_stream.list_of_lists
    x, y, t = xyt.T
    x = np.rad2deg(x) / camera_distance_mm_to_deg(1)
    y = np.rad2deg(y) / camera_distance_mm_to_deg(1)

    cleaned_pix = np.zeros(len(x), dtype=bool)
    for i in range(len(lol)):
        if mask[i]:
            for j in range(len(lol[i])):
                cleaned_pix[i] = True


    cog_x = np.mean(x[cleaned_pix])
    cog_y = np.mean(y[cleaned_pix])

    true_delta = np.arctan2(cog_y - source_y, cog_x - source_x)

    delta = calc_delta(phs2image(event.photon_stream.list_of_lists), mask)
    delta_delta = true_delta - delta
    if delta_delta < -np.pi/2:
        delta_delta += 2 * np.pi

    return delta_delta
Esempio n. 5
0
def main(inputfile, output, threshold):
    df = pd.read_csv(inputfile)

    x, y = get_pixel_coords()
    df['x'] = x
    df['y'] = y
    df['r'] = np.sqrt(df.x**2 + df.y**2)

    psf = df.sigma.values
    psf[df.A.values < threshold] = np.nan

    sigma = np.ma.masked_invalid(df.sigma.values)
    cmap = plt.get_cmap('viridis')
    cmap.set_bad('lightgray')
    camera(sigma, cmap=cmap)

    df = df.query('A >= @threshold')

    plt.show()

    xplot = np.linspace(0, 190, 2)

    # only fit the main star going through the camera center
    df = df.loc[(df.y < 30) & (df.y > -30)].dropna()

    a, b = np.polyfit(df.r.values, df.sigma.values, deg=1)

    fig, ax = plt.subplots()

    ax.scatter('r', 'sigma', data=df)
    ax.plot(xplot, a * xplot + b, color='C1', label='Linear regression')

    ax.set_xlabel(r'$d \,\, / \,\, \mathrm{mm}$')
    ax.set_ylabel(r'$\sigma \,\, / \,\, \mathrm{mm}$')

    fig.tight_layout()
    if output:
        fig.savefig(output, dpi=300)
    else:
        plt.show()
Esempio n. 6
0
mpl.rcParams['backend'] = 'pgf'
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.unicode'] = True
mpl.rcParams['font.size'] = 9
mpl.rcParams['legend.fontsize'] = 'medium'
mpl.rcParams['xtick.labelsize'] = 8
mpl.rcParams['ytick.labelsize'] = 8
mpl.rcParams['pgf.rcfonts'] = False
mpl.rcParams['pgf.texsystem'] = 'lualatex'
mpl.rcParams['pgf.preamble'] = '\input{/net/nfshome/home/ksedlaczek/phs_analysis/header-matplotlib.tex}'

picture_thresh = 5
boundary_thresh = 2
x, y = get_pixel_coords()

crab = SkyCoord.from_name('Crab Nebula')

@click.command()
@click.argument('method', required=True)
@click.argument('path', required=True)
@click.argument('file', required=True)
@click.argument('feat', required=True)
@click.option('-n', '--number', default=130, type=int, help='Number of events to plot')
def main(method, path, file, feat, number):

    border_pix = get_border_pixel_mask()

    print("Reading in facttools dl1 file...")
    t = Table.read('/net/big-tank/POOL/projects/fact/photon-stream/facttools/crab/{}_dl1.fits'.format(file))
Esempio n. 7
0
import photon_stream as ps
import numpy as np
import scipy
import pandas as pd
import warnings
from fact.instrument import camera_distance_mm_to_deg
from fact.instrument.camera import get_border_pixel_mask, get_pixel_coords

az_offset_between_magnetic_and_geographic_north = -0.12217305
pix_x, pix_y = get_pixel_coords()


def phs2image(lol, lower=0, upper=7000):
    """
    Delete time slices at beginning and end of the event and return an image for Photon Stream events.

    Inputs:
    lol:   Photon Stream list of photon arrival times per pixel

    Optional:
    lower:    lower limit of range of time slices to return
    upper:    upper limit of range of time slices to return

    return:
    image:          Array with number of photons within time-slice intervall [lower, upper] in every of the 1440 pixels

    """

    image = np.array([
        np.sum((lower <= np.array(l)) & (np.array(l) < upper))
        for l in lol