예제 #1
0
def test_cam_to_tel():
    from ctapipe.coordinates import CameraFrame, TelescopeFrame

    # Coordinates in any fram can be given as a numpy array of the xyz positions
    # e.g. in this case the position on pixels in the camera
    pix_x = [1] * u.m
    pix_y = [1] * u.m

    focal_length = 15 * u.m

    # first define the camera frame
    camera_coord = CameraFrame(pix_x, pix_y, focal_length=focal_length)

    # then use transform to function to convert to a new system
    # making sure to give the required values for the conversion
    # (these are not checked yet)
    telescope_coord = camera_coord.transform_to(TelescopeFrame())
    assert telescope_coord.x[0] == (1 / 15) * u.rad

    # check rotation
    camera_coord = CameraFrame(pix_x, pix_y, focal_length=focal_length)
    telescope_coord_rot = camera_coord.transform_to(TelescopeFrame())
    assert telescope_coord_rot.y[0] - (1 / 15) * u.rad < 1e-6 * u.rad

    # The Transform back
    camera_coord2 = telescope_coord.transform_to(
        CameraFrame(focal_length=focal_length)
    )

    # Check separation
    assert camera_coord.separation_3d(camera_coord2)[0] == 0 * u.m
예제 #2
0
def test_cam_to_tel():
    from ctapipe.coordinates import CameraFrame, TelescopeFrame

    # Coordinates in any fram can be given as a numpy array of the xyz positions
    # e.g. in this case the position on pixels in the camera
    pix_x = [1] * u.m
    pix_y = [1] * u.m

    focal_length = 15 * u.m

    # first define the camera frame
    camera_coord = CameraFrame(pix_x, pix_y, focal_length=focal_length)

    # then use transform to function to convert to a new system
    # making sure to give the required values for the conversion
    # (these are not checked yet)
    telescope_coord = camera_coord.transform_to(TelescopeFrame())
    assert telescope_coord.x[0] == (1 / 15) * u.rad

    # check rotation
    camera_coord = CameraFrame(pix_x, pix_y, focal_length=focal_length)
    telescope_coord_rot = camera_coord.transform_to(TelescopeFrame())
    assert telescope_coord_rot.y[0] - (1 / 15) * u.rad < 1e-6 * u.rad

    # The Transform back
    camera_coord2 = telescope_coord.transform_to(
        CameraFrame(focal_length=focal_length))

    # Check separation
    assert camera_coord.separation_3d(camera_coord2)[0] == 0 * u.m
예제 #3
0
def cam_to_nom():
    pix = [np.ones(2048),np.ones(2048),np.zeros(2048)] * u.m
    camera_coord = CameraFrame(pix,focal_length = 15*u.m)
    # In this case we bypass the telescope system
    nom_coord = camera_coord.transform_to(NominalFrame(pointing_direction=[70*u.deg,180*u.deg],array_direction=[75*u.deg,180*u.deg]))
    alt_az = camera_coord.transform_to(HorizonFrame(pointing_direction=[70*u.deg,180*u.deg],array_direction=[75*u.deg,180*u.deg]))

    print("Nominal Coordinate",nom_coord)
def cam_to_nom():
    pix = [np.ones(2048), np.ones(2048), np.zeros(2048)] * u.m
    camera_coord = CameraFrame(pix, focal_length=15 * u.m)
    # In this case we bypass the telescope system
    nom_coord = camera_coord.transform_to(
        NominalFrame(pointing_direction=[70 * u.deg, 180 * u.deg],
                     array_direction=[75 * u.deg, 180 * u.deg]))
    alt_az = camera_coord.transform_to(
        HorizonFrame(pointing_direction=[70 * u.deg, 180 * u.deg],
                     array_direction=[75 * u.deg, 180 * u.deg]))

    print("Nominal Coordinate", nom_coord)
예제 #5
0
def test_array_draw():
    filename = get_dataset("gamma_test.simtel.gz")
    cam_geom = {}

    source = hessio_event_source(filename, max_events=2)
    r1 = HESSIOR1Calibrator()
    dl0 = CameraDL0Reducer()

    calibrator = CameraDL1Calibrator()

    for event in source:
        array_pointing = SkyCoord(
            event.mcheader.run_array_direction[1] * u.rad,
            event.mcheader.run_array_direction[0] * u.rad,
            frame=AltAz)
        # array_view = ArrayPlotter(instrument=event.inst,
        #                          system=TiltedGroundFrame(
        # pointing_direction=array_pointing))

        hillas_dict = {}
        r1.calibrate(event)
        dl0.reduce(event)
        calibrator.calibrate(event)  # calibrate the events

        # store MC pointing direction for the array

        for tel_id in event.dl0.tels_with_data:

            pmt_signal = event.dl1.tel[tel_id].image[0]
            geom = deepcopy(event.inst.subarray.tel[tel_id].camera)
            fl = event.inst.subarray.tel[tel_id].optics.equivalent_focal_length

            # Transform the pixels positions into nominal coordinates
            camera_coord = CameraFrame(x=geom.pix_x,
                                       y=geom.pix_y,
                                       z=np.zeros(geom.pix_x.shape) * u.m,
                                       focal_length=fl,
                                       rotation=90 * u.deg - geom.cam_rotation)
            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=array_pointing,
                             pointing_direction=array_pointing))

            geom.pix_x = nom_coord.x
            geom.pix_y = nom_coord.y

            mask = tailcuts_clean(geom,
                                  pmt_signal,
                                  picture_thresh=10.,
                                  boundary_thresh=5.)

            try:
                moments = hillas_parameters(geom, pmt_signal * mask)
                hillas_dict[tel_id] = moments
                nom_coord = NominalPlotter(hillas_parameters=hillas_dict,
                                           draw_axes=True)
                nom_coord.draw_array()

            except HillasParameterizationError as e:
                print(e)
                continue
def test_camera_telescope_transform():
    camera_coord = CameraFrame(x=1*u.m, y=2*u.m, z=0*u.m)
    print(camera_coord)

    telescope_coord = camera_coord.transform_to(TelescopeFrame)
    print(telescope_coord)

    camera_coord2 = telescope_coord.transform_to(CameraFrame)
    print(camera_coord2)
예제 #7
0
def test_camera_telescope_transform():
    camera_coord = CameraFrame(x=1 * u.m, y=2 * u.m, z=0 * u.m)
    print(camera_coord)

    telescope_coord = camera_coord.transform_to(TelescopeFrame)
    print(telescope_coord)

    camera_coord2 = telescope_coord.transform_to(CameraFrame)
    print(camera_coord2)
예제 #8
0
def test_array_draw():
    filename = get_dataset("gamma_test.simtel.gz")
    cam_geom = {}

    source = hessio_event_source(filename, max_events=2)
    r1 = HessioR1Calibrator(None, None)
    dl0 = CameraDL0Reducer(None, None)

    calibrator = CameraDL1Calibrator(None, None)

    for event in source:
        array_pointing = SkyCoord(event.mcheader.run_array_direction[1] * u.rad,
                                  event.mcheader.run_array_direction[0] * u.rad,
                                  frame=AltAz)
        # array_view = ArrayPlotter(instrument=event.inst,
        #                          system=TiltedGroundFrame(
        # pointing_direction=array_pointing))

        hillas_dict = {}
        r1.calibrate(event)
        dl0.reduce(event)
        calibrator.calibrate(event)  # calibrate the events

        # store MC pointing direction for the array

        for tel_id in event.dl0.tels_with_data:

            pmt_signal = event.dl1.tel[tel_id].image[0]
            geom = event.inst.subarray.tel[tel_id].camera
            fl = event.inst.subarray.tel[tel_id].optics.effective_focal_length

            # Transform the pixels positions into nominal coordinates
            camera_coord = CameraFrame(x=geom.pix_x, y=geom.pix_y,
                                       z=np.zeros(geom.pix_x.shape) * u.m,
                                       focal_length=fl,
                                       rotation=90 * u.deg - geom.cam_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=array_pointing,
                             pointing_direction=array_pointing))

            mask = tailcuts_clean(geom, pmt_signal,
                                  picture_thresh=10., boundary_thresh=5.)

            try:
                moments = hillas_parameters(nom_coord.x,
                                            nom_coord.y,
                                            pmt_signal * mask)
                hillas_dict[tel_id] = moments
                nom_coord = NominalPlotter(hillas_parameters=hillas_dict,
                                           draw_axes=True)
                nom_coord.draw_array()

            except HillasParameterizationError as e:
                print(e)
                continue
예제 #9
0
 def get_nominal(self, tel_id):
     if not tel_id in self.nominal_geom_dict:
         camera_geom = self.get_camera(tel_id)
         pix_x, pix_y = self.inst.pixel_pos[tel_id]
         foclen = self.inst.optical_foclen[tel_id]
         camera_coord = CameraFrame(x=pix_x, y=pix_y, focal_length=foclen,
                                    rotation=-1 * camera_geom.cam_rotation)
         nom_coord = camera_coord.transform_to(self.nom_system)
         geom = CameraGeometry(camera_geom.cam_id, camera_geom.pix_id,
                               nom_coord.x, nom_coord.y,
                               None, camera_geom.pix_type,
                               camera_geom.pix_rotation,
                               camera_geom.cam_rotation,
                               camera_geom.neighbors, False)
         self.nominal_geom_dict[tel_id] = geom
     return self.nominal_geom_dict[tel_id]
예제 #10
0
def camera_to_horizontal(x, y, alt_pointing, az_pointing, focal_length):
    with warnings.catch_warnings():
        warnings.simplefilter("ignore", MissingFrameAttributeWarning)

        altaz = AltAz()
        tel_pointing = SkyCoord(
            alt=u.Quantity(alt_pointing, u.deg, copy=False),
            az=u.Quantity(az_pointing, u.deg, copy=False),
            frame=altaz,
        )
        camera_coordinates = CameraFrame(
            x=u.Quantity(x, u.m, copy=False),
            y=u.Quantity(y, u.m, copy=False),
            focal_length=u.Quantity(focal_length, u.m, copy=False),
            telescope_pointing=tel_pointing,
        )

        horizontal_coordinates = camera_coordinates.transform_to(altaz)
        return horizontal_coordinates.alt.to_value(u.deg), horizontal_coordinates.az.to_value(u.deg)
예제 #11
0
def cam_to_tel():

    # Coordinates in any fram can be given as a numpy array of the xyz positions
    # e.g. in this case the position on pixels in the camera
    pix = [np.ones(2048),np.ones(2048),np.zeros(2048)] * u.m
    # first define the camera frame
    camera_coord = CameraFrame(pix,focal_length=15*u.m,rotation=0*u.deg)

    # then use transform to function to convert to a new system
    # making sure to give the required values for the conversion (these are not checked yet)
    telescope_coord = camera_coord.transform_to(TelescopeFrame())

    # Print coordinates in the new frame
    print("Telescope Coordinate",telescope_coord)

    # Transforming back is then easy
    camera_coord2 = telescope_coord.transform_to(CameraFrame(focal_length=15*u.m,rotation=0*u.deg))

    # We can easily check the distance between 2 coordinates in the same frame
    # In this case they should be the same
    print("Separation",np.sum(camera_coord.separation_3d(camera_coord2)))
예제 #12
0
def cam_to_tel():

    # Coordinates in any fram can be given as a numpy array of the xyz positions
    # e.g. in this case the position on pixels in the camera
    pix = [np.ones(2048), np.ones(2048), np.zeros(2048)] * u.m
    # first define the camera frame
    camera_coord = CameraFrame(pix)

    # then use transform to function to convert to a new system
    # making sure to give the required values for the conversion (these are not checked yet)
    telescope_coord = camera_coord.transform_to(
        TelescopeFrame(focal_length=15 * u.m, rotation=0 * u.deg))

    # Print cordinates in the new frame
    print("Telescope Coordinate", telescope_coord)

    # Transforming back is then easy
    camera_coord2 = telescope_coord.transform_to(CameraFrame())

    # We can easily check the distance between 2 coordinates in the same frame
    # In this case they should be the same
    print("Separation", np.sum(camera_coord.separation_3d(camera_coord2)))
예제 #13
0
def analyze_muon_event(event, params=None, geom_dict=None):
    """
    Generic muon event analyzer. 

    Parameters
    ----------
    event : ctapipe dl1 event container


    Returns
    -------
    muonringparam, muonintensityparam : MuonRingParameter and MuonIntensityParameter container event

    """
    # Declare a dict to define the muon cuts (ASTRI and SCT missing)
    muon_cuts = {}

    names = ['LST:LSTCam','MST:NectarCam','MST:FlashCam','MST-SCT:SCTCam','SST-1M:DigiCam','SST-GCT:CHEC','SST-ASTRI:ASTRICam']
    TailCuts = [(5,7),(5,7),(10,12),(5,7),(5,7),(5,7),(5,7)] #10,12?
    impact = [(0.2,0.9),(0.1,0.95),(0.2,0.9),(0.2,0.9),(0.1,0.95),(0.1,0.95),(0.1,0.95)]
    ringwidth = [(0.04,0.08),(0.02,0.1),(0.01,0.1),(0.02,0.1),(0.01,0.5),(0.02,0.2),(0.02,0.2)]
    TotalPix = [1855.,1855.,1764.,11328.,1296.,2048.,2368.]#8% (or 6%) as limit
    MinPix = [148.,148.,141.,680.,104.,164.,142.]
    #Need to either convert from the pixel area in m^2 or check the camera specs
    AngPixelWidth = [0.1,0.2,0.18,0.067,0.24,0.2,0.17] #Found from TDRs (or the pixel area)
    hole_rad = []#Need to check and implement
    cam_rad = [2.26,3.96,3.87,4.,4.45,2.86,5.25]#Found from the field of view calculation
    sec_rad = [0.*u.m,0.*u.m,0.*u.m,2.7*u.m,0.*u.m,1.*u.m,1.8*u.m]
    sct = [False,False,False,True,False,True,True]


    muon_cuts = {'Name':names,'TailCuts':TailCuts,'Impact':impact,'RingWidth':ringwidth,'TotalPix':TotalPix,'MinPix':MinPix,'CamRad':cam_rad,'SecRad':sec_rad,'SCT':sct,'AngPixW':AngPixelWidth}
    #print(muon_cuts)

    muonringlist = []#[None] * len(event.dl0.tels_with_data)
    muonintensitylist = []#[None] * len(event.dl0.tels_with_data)
    tellist = []
    #for tid in event.dl0.tels_with_data:
    #    tellist.append(tid)
    muon_event_param = {'TelIds':tellist,'MuonRingParams':muonringlist,'MuonIntensityParams':muonintensitylist}
    #muonringparam = None
    #muonintensityparam = None

    for telid in event.dl0.tels_with_data:

        #print("Analysing muon event for tel",telid)
        muonringparam = None
        muonintensityparam = None
        #idx = muon_event_param['TelIds'].index(telid)

        x, y = event.inst.pixel_pos[telid]

        #image = event.dl1.tel[telid].calibrated_image
        image = event.dl1.tel[telid].image[0]

        # Get geometry
        geom = None
        if geom_dict is not None and telid in geom_dict:
            geom = geom_dict[telid]
        else:
            log.debug("[calib] Guessing camera geometry")
            geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                        event.inst.optical_foclen[telid])
            log.debug("[calib] Camera geometry found")
            if geom_dict is not None:
                geom_dict[telid] = geom


        teldes = event.inst.subarray.tel[telid]
        dict_index = muon_cuts['Name'].index(str(teldes))
        #print('found an index of',dict_index,'for camera',geom.cam_id)

        #tailcuts = (5.,7.)
        tailcuts = muon_cuts['TailCuts'][dict_index]

        #print("Tailcuts are",tailcuts[0],tailcuts[1])

        #rot_angle = 0.*u.deg
        #if event.inst.optical_foclen[telid] > 10.*u.m and event.dl0.tel[telid].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

        clean_mask = tailcuts_clean(geom,image,picture_thresh=tailcuts[0],boundary_thresh=tailcuts[1])
        camera_coord = CameraFrame(x=x,y=y,z=np.zeros(x.shape)*u.m, focal_length = event.inst.optical_foclen[telid], rotation=geom.pix_rotation)

        #print("Camera",geom.cam_id,"focal length",event.inst.optical_foclen[telid],"rotation",geom.pix_rotation)
        #TODO: correct this hack for values over 90
        altval = event.mcheader.run_array_direction[1]
        if (altval > np.pi/2.):
            altval = np.pi/2.

        altaz = HorizonFrame(alt=altval*u.rad,az=event.mcheader.run_array_direction[0]*u.rad)
        nom_coord = camera_coord.transform_to(NominalFrame(array_direction=altaz,pointing_direction=altaz))

        
        x = nom_coord.x.to(u.deg)
        y = nom_coord.y.to(u.deg)

        img = image*clean_mask
        noise = 5.
        weight = img / (img+noise)

        muonring = ChaudhuriKunduRingFitter(None)

        #print("img:",np.sum(image),"mask:",np.sum(clean_mask), "x=",x,"y=",y)
        if not sum(img):#Nothing left after tail cuts
            continue
        muonringparam = muonring.fit(x,y,image*clean_mask)
        #muonringparam = muonring.fit(x,y,weight)
        dist = np.sqrt(np.power(x-muonringparam.ring_center_x,2) + np.power(y-muonringparam.ring_center_y,2))
        ring_dist = np.abs(dist-muonringparam.ring_radius)
        muonringparam = muonring.fit(x,y,img*(ring_dist<muonringparam.ring_radius*0.4))

        dist = np.sqrt(np.power(x-muonringparam.ring_center_x,2) + np.power(y-muonringparam.ring_center_y,2))
        ring_dist = np.abs(dist-muonringparam.ring_radius)

        #print("1: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam = muonring.fit(x,y,img*(ring_dist<muonringparam.ring_radius*0.4))
        #print("2: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam.tel_id = telid
        muonringparam.run_id = event.dl0.run_id
        muonringparam.event_id = event.dl0.event_id
        dist_mask = np.abs(dist-muonringparam.ring_radius)<muonringparam.ring_radius*0.4

        rad = list()
        cx = list()
        cy = list()
        
        mc_x = event.mc.core_x
        mc_y = event.mc.core_y
        pix_im = image*dist_mask
        nom_dist = np.sqrt(np.power(muonringparam.ring_center_x,2)+np.power(muonringparam.ring_center_y,2))
        #numpix = event.dl0.tel[telid].num_pixels

        minpix = muon_cuts['MinPix'][dict_index]#0.06*numpix #or 8%

        mir_rad = np.sqrt(event.inst.mirror_dish_area[telid]/(np.pi))#need to consider units? (what about hole? Area is then less...)


        #Camera containment radius -  better than nothing - guess pixel diameter of 0.11, all cameras are perfectly circular   cam_rad = np.sqrt(numpix*0.11/(2.*np.pi))

        if(np.sum(pix_im>tailcuts[0])>0.1*minpix and np.sum(pix_im)>minpix and nom_dist < muon_cuts['CamRad'][dict_index]*u.deg and muonringparam.ring_radius<1.5*u.deg and muonringparam.ring_radius>1.*u.deg):

            #Guess HESS is 0.16 
            #sec_rad = 0.*u.m
            #sct = False
            #if numpix == 2048 and mir_rad > 2.*u.m and mir_rad < 2.1*u.m:
            #    sec_rad = 1.*u.m
            #    sct = True

            #Store muon ring parameters (passing cuts stage 1)
            #muonringlist[idx] = muonringparam
            tellist.append(telid)
            muonringlist.append(muonringparam)
            muonintensitylist.append(None)
            #embed()

            ctel = MuonLineIntegrate(mir_rad,0.2*u.m,pixel_width=muon_cuts['AngPixW'][dict_index]*u.deg,sct_flag=muon_cuts['SCT'][dict_index], secondary_radius=muon_cuts['SecRad'][dict_index])
          
            if (image.shape[0] == muon_cuts['TotalPix'][dict_index]):
                muonintensityoutput = ctel.fit_muon(muonringparam.ring_center_x,muonringparam.ring_center_y,muonringparam.ring_radius,x[dist_mask],y[dist_mask],image[dist_mask])

                muonintensityoutput.tel_id = telid
                muonintensityoutput.run_id = event.dl0.run_id
                muonintensityoutput.event_id = event.dl0.event_id
                muonintensityoutput.mask = dist_mask

                print("Tel",telid,"Impact parameter = ",muonintensityoutput.impact_parameter,"mir_rad",mir_rad,"ring_width=",muonintensityoutput.ring_width)

                #if(muonintensityoutput.impact_parameter > muon_cuts['Impact'][dict_index][1]*mir_rad or muonintensityoutput.impact_parameter < muon_cuts['Impact'][dict_index][0]*mir_rad):
                #    print("Failed on impact parameter low cut",muon_cuts['Impact'][dict_index][0]*mir_rad,"high cut",muon_cuts['Impact'][dict_index][1]*mir_rad,"for",geom.cam_id)
                #if(muonintensityoutput.ring_width > muon_cuts['RingWidth'][dict_index][1]*u.deg or muonintensityoutput.ring_width < muon_cuts['RingWidth'][dict_index][0]*u.deg):
                #    print("Failed on ring width low cut",muon_cuts['RingWidth'][dict_index][0]*u.deg,"high cut",muon_cuts['RingWidth'][dict_index][1]*u.deg,"for ",geom.cam_id)

                #print("Cuts <",muon_cuts["Impact"][dict_index][1]*mir_rad,"cuts >",muon_cuts['Impact'][dict_index][0]*u.m,'ring_width < ',muon_cuts['RingWidth'][dict_index][1]*u.deg,'ring_width >',muon_cuts['RingWidth'][dict_index][0]*u.deg)
                if( muonintensityoutput.impact_parameter < muon_cuts['Impact'][dict_index][1]*mir_rad and muonintensityoutput.impact_parameter > muon_cuts['Impact'][dict_index][0]*u.m and muonintensityoutput.ring_width < muon_cuts['RingWidth'][dict_index][1]*u.deg and muonintensityoutput.ring_width > muon_cuts['RingWidth'][dict_index][0]*u.deg ):
                    muonintensityparam = muonintensityoutput
                    idx = tellist.index(telid)
                    muonintensitylist[idx] = muonintensityparam
                    print("Muon in tel",telid,"# tels in event=",len(event.dl0.tels_with_data))
                else:
                    continue

        #print("Fitted ring centre (2):",muonringparam.ring_center_x,muonringparam.ring_center_y)

    #return muonringparam, muonintensityparam
    return muon_event_param
예제 #14
0
        table = "CameraTable_VersionFeb2016_TelID"

        for tel_id in container.dl0.tels_with_data:

            x, y = event.meta.pixel_pos[tel_id]
            if geom == 0:
                geom = io.CameraGeometry.guess(x, y,event.meta.optical_foclen[tel_id])
            image = apply_mc_calibration(event.dl0.tel[tel_id].adc_sums[0], tel_id)
            if image.shape[0] >1000:
                continue
            clean_mask = tailcuts_clean(geom,image,1,picture_thresh=5,boundary_thresh=7)

            camera_coord = CameraFrame(x=x,y=y,z=np.zeros(x.shape)*u.m)

            nom_coord = camera_coord.transform_to(NominalFrame(array_direction=[container.mc.alt,container.mc.az],
                                                       pointing_direction=[container.mc.alt,container.mc.az],
                                                       focal_length=tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==tel_id]['FL'][0]*u.m))

            x = nom_coord.x.to(u.deg)
            y = nom_coord.y.to(u.deg)

            img = image*clean_mask
            noise = 5
            weight = img / (img+noise)

            centre_x,centre_y,radius = chaudhuri_kundu_circle_fit(x,y,image*clean_mask)
            dist = np.sqrt(np.power(x-centre_x,2) + np.power(y-centre_y,2))
            ring_dist = np.abs(dist-radius)
            centre_x,centre_y,radius = chaudhuri_kundu_circle_fit(x,y,image*(ring_dist<radius*0.3))

            dist = np.sqrt(np.power(x-centre_x,2) + np.power(y-centre_y,2))
예제 #15
0
def analyze_muon_event(event, params=None, geom_dict=None):
    """
    Generic muon event analyzer. 

    Parameters
    ----------
    event : ctapipe dl1 event container


    Returns
    -------
    muonringparam, muonintensityparam : MuonRingParameter and MuonIntensityParameter container event

    """
    # Declare a dict to define the muon cuts (ASTRI and SCT missing)
    muon_cuts = {}

    names = [
        'LST:LSTCam', 'MST:NectarCam', 'MST:FlashCam', 'MST-SCT:SCTCam',
        'SST-1M:DigiCam', 'SST-GCT:CHEC', 'SST-ASTRI:ASTRICam'
    ]
    TailCuts = [(5, 7), (5, 7), (10, 12), (5, 7), (5, 7), (5, 7),
                (5, 7)]  #10,12?
    impact = [(0.2, 0.9), (0.1, 0.95), (0.2, 0.9), (0.2, 0.9), (0.1, 0.95),
              (0.1, 0.95), (0.1, 0.95)]
    ringwidth = [(0.04, 0.08), (0.02, 0.1), (0.01, 0.1), (0.02, 0.1),
                 (0.01, 0.5), (0.02, 0.2), (0.02, 0.2)]
    TotalPix = [1855., 1855., 1764., 11328., 1296., 2048.,
                2368.]  #8% (or 6%) as limit
    MinPix = [148., 148., 141., 680., 104., 164., 142.]
    #Need to either convert from the pixel area in m^2 or check the camera specs
    AngPixelWidth = [0.1, 0.2, 0.18, 0.067, 0.24, 0.2,
                     0.17]  #Found from TDRs (or the pixel area)
    hole_rad = []  #Need to check and implement
    cam_rad = [2.26, 3.96, 3.87, 4., 4.45, 2.86,
               5.25]  #Found from the field of view calculation
    sec_rad = [
        0. * u.m, 0. * u.m, 0. * u.m, 2.7 * u.m, 0. * u.m, 1. * u.m, 1.8 * u.m
    ]
    sct = [False, False, False, True, False, True, True]

    muon_cuts = {
        'Name': names,
        'TailCuts': TailCuts,
        'Impact': impact,
        'RingWidth': ringwidth,
        'TotalPix': TotalPix,
        'MinPix': MinPix,
        'CamRad': cam_rad,
        'SecRad': sec_rad,
        'SCT': sct,
        'AngPixW': AngPixelWidth
    }
    #print(muon_cuts)

    muonringlist = []  #[None] * len(event.dl0.tels_with_data)
    muonintensitylist = []  #[None] * len(event.dl0.tels_with_data)
    tellist = []
    #for tid in event.dl0.tels_with_data:
    #    tellist.append(tid)
    muon_event_param = {
        'TelIds': tellist,
        'MuonRingParams': muonringlist,
        'MuonIntensityParams': muonintensitylist
    }
    #muonringparam = None
    #muonintensityparam = None

    for telid in event.dl0.tels_with_data:

        #print("Analysing muon event for tel",telid)
        muonringparam = None
        muonintensityparam = None
        #idx = muon_event_param['TelIds'].index(telid)

        x, y = event.inst.pixel_pos[telid]

        #image = event.dl1.tel[telid].calibrated_image
        image = event.dl1.tel[telid].image[0]

        # Get geometry
        geom = None
        if geom_dict is not None and telid in geom_dict:
            geom = geom_dict[telid]
        else:
            log.debug("[calib] Guessing camera geometry")
            geom = CameraGeometry.guess(*event.inst.pixel_pos[telid],
                                        event.inst.optical_foclen[telid])
            log.debug("[calib] Camera geometry found")
            if geom_dict is not None:
                geom_dict[telid] = geom

        teldes = event.inst.subarray.tel[telid]
        dict_index = muon_cuts['Name'].index(str(teldes))
        #print('found an index of',dict_index,'for camera',geom.cam_id)

        #tailcuts = (5.,7.)
        tailcuts = muon_cuts['TailCuts'][dict_index]

        #print("Tailcuts are",tailcuts[0],tailcuts[1])

        #rot_angle = 0.*u.deg
        #if event.inst.optical_foclen[telid] > 10.*u.m and event.dl0.tel[telid].num_pixels != 1764:
        #rot_angle = -100.14*u.deg

        clean_mask = tailcuts_clean(geom,
                                    image,
                                    picture_thresh=tailcuts[0],
                                    boundary_thresh=tailcuts[1])
        camera_coord = CameraFrame(
            x=x,
            y=y,
            z=np.zeros(x.shape) * u.m,
            focal_length=event.inst.optical_foclen[telid],
            rotation=geom.pix_rotation)

        #print("Camera",geom.cam_id,"focal length",event.inst.optical_foclen[telid],"rotation",geom.pix_rotation)
        #TODO: correct this hack for values over 90
        altval = event.mcheader.run_array_direction[1]
        if (altval > np.pi / 2.):
            altval = np.pi / 2.

        altaz = HorizonFrame(alt=altval * u.rad,
                             az=event.mcheader.run_array_direction[0] * u.rad)
        nom_coord = camera_coord.transform_to(
            NominalFrame(array_direction=altaz, pointing_direction=altaz))

        x = nom_coord.x.to(u.deg)
        y = nom_coord.y.to(u.deg)

        img = image * clean_mask
        noise = 5.
        weight = img / (img + noise)

        muonring = ChaudhuriKunduRingFitter(None)

        #print("img:",np.sum(image),"mask:",np.sum(clean_mask), "x=",x,"y=",y)
        if not sum(img):  #Nothing left after tail cuts
            continue
        muonringparam = muonring.fit(x, y, image * clean_mask)
        #muonringparam = muonring.fit(x,y,weight)
        dist = np.sqrt(
            np.power(x - muonringparam.ring_center_x, 2) +
            np.power(y - muonringparam.ring_center_y, 2))
        ring_dist = np.abs(dist - muonringparam.ring_radius)
        muonringparam = muonring.fit(
            x, y, img * (ring_dist < muonringparam.ring_radius * 0.4))

        dist = np.sqrt(
            np.power(x - muonringparam.ring_center_x, 2) +
            np.power(y - muonringparam.ring_center_y, 2))
        ring_dist = np.abs(dist - muonringparam.ring_radius)

        #print("1: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam = muonring.fit(
            x, y, img * (ring_dist < muonringparam.ring_radius * 0.4))
        #print("2: x",muonringparam.ring_center_x,"y",muonringparam.ring_center_y,"radius",muonringparam.ring_radius)
        muonringparam.tel_id = telid
        muonringparam.run_id = event.dl0.run_id
        muonringparam.event_id = event.dl0.event_id
        dist_mask = np.abs(
            dist - muonringparam.ring_radius) < muonringparam.ring_radius * 0.4

        rad = list()
        cx = list()
        cy = list()

        mc_x = event.mc.core_x
        mc_y = event.mc.core_y
        pix_im = image * dist_mask
        nom_dist = np.sqrt(
            np.power(muonringparam.ring_center_x, 2) +
            np.power(muonringparam.ring_center_y, 2))
        #numpix = event.dl0.tel[telid].num_pixels

        minpix = muon_cuts['MinPix'][dict_index]  #0.06*numpix #or 8%

        mir_rad = np.sqrt(
            event.inst.mirror_dish_area[telid] / (np.pi)
        )  #need to consider units? (what about hole? Area is then less...)

        #Camera containment radius -  better than nothing - guess pixel diameter of 0.11, all cameras are perfectly circular   cam_rad = np.sqrt(numpix*0.11/(2.*np.pi))

        if (np.sum(pix_im > tailcuts[0]) > 0.1 * minpix
                and np.sum(pix_im) > minpix
                and nom_dist < muon_cuts['CamRad'][dict_index] * u.deg
                and muonringparam.ring_radius < 1.5 * u.deg
                and muonringparam.ring_radius > 1. * u.deg):

            #Guess HESS is 0.16
            #sec_rad = 0.*u.m
            #sct = False
            #if numpix == 2048 and mir_rad > 2.*u.m and mir_rad < 2.1*u.m:
            #    sec_rad = 1.*u.m
            #    sct = True

            #Store muon ring parameters (passing cuts stage 1)
            #muonringlist[idx] = muonringparam
            tellist.append(telid)
            muonringlist.append(muonringparam)
            muonintensitylist.append(None)
            #embed()

            ctel = MuonLineIntegrate(
                mir_rad,
                0.2 * u.m,
                pixel_width=muon_cuts['AngPixW'][dict_index] * u.deg,
                sct_flag=muon_cuts['SCT'][dict_index],
                secondary_radius=muon_cuts['SecRad'][dict_index])

            if (image.shape[0] == muon_cuts['TotalPix'][dict_index]):
                muonintensityoutput = ctel.fit_muon(
                    muonringparam.ring_center_x, muonringparam.ring_center_y,
                    muonringparam.ring_radius, x[dist_mask], y[dist_mask],
                    image[dist_mask])

                muonintensityoutput.tel_id = telid
                muonintensityoutput.run_id = event.dl0.run_id
                muonintensityoutput.event_id = event.dl0.event_id
                muonintensityoutput.mask = dist_mask

                print("Tel", telid, "Impact parameter = ",
                      muonintensityoutput.impact_parameter, "mir_rad", mir_rad,
                      "ring_width=", muonintensityoutput.ring_width)

                #if(muonintensityoutput.impact_parameter > muon_cuts['Impact'][dict_index][1]*mir_rad or muonintensityoutput.impact_parameter < muon_cuts['Impact'][dict_index][0]*mir_rad):
                #    print("Failed on impact parameter low cut",muon_cuts['Impact'][dict_index][0]*mir_rad,"high cut",muon_cuts['Impact'][dict_index][1]*mir_rad,"for",geom.cam_id)
                #if(muonintensityoutput.ring_width > muon_cuts['RingWidth'][dict_index][1]*u.deg or muonintensityoutput.ring_width < muon_cuts['RingWidth'][dict_index][0]*u.deg):
                #    print("Failed on ring width low cut",muon_cuts['RingWidth'][dict_index][0]*u.deg,"high cut",muon_cuts['RingWidth'][dict_index][1]*u.deg,"for ",geom.cam_id)

                #print("Cuts <",muon_cuts["Impact"][dict_index][1]*mir_rad,"cuts >",muon_cuts['Impact'][dict_index][0]*u.m,'ring_width < ',muon_cuts['RingWidth'][dict_index][1]*u.deg,'ring_width >',muon_cuts['RingWidth'][dict_index][0]*u.deg)
                if (muonintensityoutput.impact_parameter <
                        muon_cuts['Impact'][dict_index][1] * mir_rad
                        and muonintensityoutput.impact_parameter >
                        muon_cuts['Impact'][dict_index][0] * u.m
                        and muonintensityoutput.ring_width <
                        muon_cuts['RingWidth'][dict_index][1] * u.deg
                        and muonintensityoutput.ring_width >
                        muon_cuts['RingWidth'][dict_index][0] * u.deg):
                    muonintensityparam = muonintensityoutput
                    idx = tellist.index(telid)
                    muonintensitylist[idx] = muonintensityparam
                    print("Muon in tel", telid, "# tels in event=",
                          len(event.dl0.tels_with_data))
                else:
                    continue

        #print("Fitted ring centre (2):",muonringparam.ring_center_x,muonringparam.ring_center_y)

    #return muonringparam, muonintensityparam
    return muon_event_param
예제 #16
0
            angpixwidth = pixwidth / (
                teloptconfigdict['focallengths'][dictindex]) * (
                    180. / np.pi) * (u.deg / u.m)  # This is not correct...
            # print('Area of the pixel is:',geom.pix_area,'approx width as',
            # pixwidth,angpixwidth)
            # 1/0

            camera_coord = CameraFrame(x=x, y=y, z=np.zeros(x.shape) * u.m)
            optics = event.inst.subarray.tel[tel_id].optics
            foclen = optics.equivalent_focal_length
            frame = NominalFrame(
                array_direction=[container.mc.alt, container.mc.az],
                pointing_direction=[container.mc.alt, container.mc.az],
                focal_length=foclen)

            nom_coord = camera_coord.transform_to(frame)

            x = nom_coord.x.to(u.deg)
            y = nom_coord.y.to(u.deg)

            img = image * clean_mask
            noise = 5
            weight = img / (img + noise)

            circlefitter = ChaudhuriKunduRingFitter()

            ringoutparams = circlefitter.fit(x, y, image * clean_mask)
            # print('RingOutParams',ringoutparams)
            centre_x = ringoutparams.ring_center_x
            centre_y = ringoutparams.ring_center_y
            radius = ringoutparams.ring_radius
예제 #17
0
                                          dictindex]) * (180. / np.pi) * (
                          u.deg / u.m)  # This is not correct...
            # print('Area of the pixel is:',geom.pix_area,'approx width as',
            # pixwidth,angpixwidth)
            # 1/0

            camera_coord = CameraFrame(x=x, y=y, z=np.zeros(x.shape) * u.m)
            optics = event.inst.subarray.tel[tel_id].optics
            foclen = optics.effective_focal_length
            frame = NominalFrame(array_direction=[container.mc.alt,
                                                  container.mc.az],
                                 pointing_direction=[container.mc.alt,
                                                     container.mc.az],
                                 focal_length=foclen)

            nom_coord = camera_coord.transform_to(frame)

            x = nom_coord.x.to(u.deg)
            y = nom_coord.y.to(u.deg)

            img = image * clean_mask
            noise = 5
            weight = img / (img + noise)

            circlefitter = ChaudhuriKunduRingFitter()

            ringoutparams = circlefitter.fit(x, y, image * clean_mask)
            # print('RingOutParams',ringoutparams)
            centre_x = ringoutparams.ring_center_x
            centre_y = ringoutparams.ring_center_y
            radius = ringoutparams.ring_radius
예제 #18
0
                plt.pause(0.01)
                if args.write:
                    plt.savefig('CT{:03d}_EV{:010d}_S{:02d}.png'
                                .format(args.tel, event.dl0.event_id, ii))
        else:
            # display integrated event:
            im = event.dl0.tel[args.tel].adc_sums[args.channel]
            im = apply_mc_calibration(im, args.tel)
            disp.image = im

            if args.hillas:
                clean_mask = reco.cleaning.tailcuts_clean(geom,im,1,picture_thresh=10,boundary_thresh=5)
                camera_coord = CameraFrame(x=x,y=y,z=np.zeros(x.shape)*u.m)

                nom_coord = camera_coord.transform_to(NominalFrame(array_direction=[70*u.deg,0*u.deg],
                                                           pointing_direction=[70*u.deg,0*u.deg],
                                                           focal_length=tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==args.tel]['FL'][0]*u.m))

                image = np.asanyarray(im * clean_mask, dtype=np.float64)

                nom_x = nom_coord.x
                nom_y = nom_coord.y

                hillas = reco.hillas_parameters(x,y,im * clean_mask)
                hillas_nom = reco.hillas_parameters(nom_x,nom_y,im * clean_mask)

                print (hillas)
                print (hillas_nom)

                disp.image = im * clean_mask
                disp.overlay_moments(hillas, color='seagreen', linewidth=3)
예제 #19
0
def plot_muon_event(event, muonparams, args=None):

    if muonparams['MuonRingParams'] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))

        colorbar = None
        colorbar2 = None

        #for tel_id in event.dl0.tels_with_data:
        for tel_id in muonparams['TelIds']:
            idx = muonparams['TelIds'].index(tel_id)

            if not muonparams['MuonRingParams'][idx]:
                continue

            #otherwise...
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event)
            image = event.dl1.tel[tel_id].image[0]
            geom = event.inst.subarray.tel[tel_id].camera

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            clean_mask = tailcuts_clean(geom, image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams['MuonRingParams'][idx].ring_center_x**2. +
                                muonparams['MuonRingParams'][idx].ring_center_y**2.)

            muon_phi = np.arctan(muonparams['MuonRingParams'][idx].ring_center_y /
                                 muonparams['MuonRingParams'][idx].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams['MuonRingParams'][idx].ring_center_x,
                                        y=muonparams['MuonRingParams'][idx].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(CameraFrame(
                pointing_direction=altaz,
                focal_length=event.inst.optical_foclen[tel_id],
                rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams['MuonRingParams'][idx].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px, y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz,
                             pointing_direction=altaz)
            )

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(np.power( px - muonparams['MuonRingParams'][idx].ring_center_x, 2)
                           + np.power(py - muonparams['MuonRingParams'][idx].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams['MuonRingParams'][idx].ring_radius)
            pixRmask = ring_dist < muonparams['MuonRingParams'][idx].ring_radius * 0.4

            #if muonparams[1] is not None:
            if muonparams['MuonIntensityParams'][idx] is not None:
                signals *= muonparams['MuonIntensityParams'][idx].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            cmin = min(signals)
            if not cmin:
                cmin = 1.
            if not cmaxmin:
                cmaxmin = 1.

            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(cmin) / cmaxmin, 'black'),
                           (2.0 * np.abs(cmin) / cmaxmin, 'blue'),
                           (2.5 * np.abs(cmin) / cmaxmin, 'green'),
                           (1, 'yellow')]
            )
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid, ringrad_camcoord.value,
                                ringrad_camcoord.value, 0., 0., color="red")


            if muonparams['MuonIntensityParams'][idx] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)

                ringwidthfrac = muonparams['MuonIntensityParams'][idx].ring_width / muonparams['MuonRingParams'][idx].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid, ringrad_inner.value,
                                     ringrad_inner.value, 0., 0.,
                                     color="magenta")
                camera1.add_ellipse(centroid, ringrad_outer.value,
                                    ringrad_outer.value, 0., 0., color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams['MuonIntensityParams'][idx].prediction


                if len(pred) != np.sum(muonparams['MuonIntensityParams'][idx].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams['MuonIntensityParams'][idx].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams['MuonIntensityParams'][idx].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                if np.isnan(max(plotpred)) or np.isnan(min(plotpred)):
                    print("nan prediction, skipping...")
                    continue

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.

                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c', [(0 / c2maxmin, 'darkblue'),
                                (np.abs(min(plotpred)) / c2maxmin, 'black'),
                                (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                                (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                                (1, 'yellow')]
                )
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter


            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            #fig.savefig(str(args.output_path) + "_" +
            #            str(event.dl0.event_id) + '.png')


            plt.close()
예제 #20
0
def plot_muon_event(event, muonparams, geom_dict=None, args=None):

    if muonparams[0] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))
        # if args.display:
        #    plt.show(block=False)
        #pp = PdfPages(args.output_path) if args.output_path is not None else None
        # pp = None #For now, need to correct this

        colorbar = None
        colorbar2 = None

        for tel_id in event.dl0.tels_with_data:
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event, geom_dict)
            #image = event.dl1.tel[tel_id].calibrated_image
            image = event.dl1.tel[tel_id].image[0]
            # Get geometry
            geom = None
            if geom_dict is not None and tel_id in geom_dict:
                geom = geom_dict[tel_id]
            else:
                #log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id],
                                            event.inst.optical_foclen[tel_id])
                #log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[tel_id] = geom

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            #print("Using Tail Cuts:",tailcuts)
            clean_mask = tailcuts_clean(geom, image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams[0].ring_center_x**2. +
                                muonparams[0].ring_center_y**2.)

            muon_phi = np.arctan(muonparams[0].ring_center_y /
                                 muonparams[0].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams[0].ring_center_x,
                                        y=muonparams[0].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(CameraFrame(
                pointing_direction=altaz,
                focal_length=event.inst.optical_foclen[tel_id],
                rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams[0].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            #rot_angle = 0.*u.deg
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and event.dl0.tel[tel_id].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px, y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz,
                             pointing_direction=altaz)
            )
            #,focal_length = event.inst.optical_foclen[tel_id])) # tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==telid]['FL'][0]*u.m))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(np.power( px - muonparams[0].ring_center_x, 2)
                           + np.power(py - muonparams[0].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams[0].ring_radius)
            pixRmask = ring_dist < muonparams[0].ring_radius * 0.4

            if muonparams[1] is not None:
                signals *= muonparams[1].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            if not cmaxmin:
                cmaxmin = 1.
            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(min(signals)) / cmaxmin, 'black'),
                           (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                           (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                           (1, 'yellow')]
            )
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid, ringrad_camcoord.value,
                                ringrad_camcoord.value, 0., 0., color="red")

#            ax1.set_title("CT {} ({}) - Mean pixel charge"
#                          .format(tel_id, geom_dict[tel_id].cam_id))

            if muonparams[1] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)
                ringwidthfrac = muonparams[
                    1].ring_width / muonparams[0].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid, ringrad_inner.value,
                                     ringrad_inner.value, 0., 0.,
                                     color="magenta")
                camera1.add_ellipse(centroid, ringrad_outer.value,
                                    ringrad_outer.value, 0., 0., color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams[1].prediction

                if len(pred) != np.sum(muonparams[1].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams[1].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams[1].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.
                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c', [(0 / c2maxmin, 'darkblue'),
                                (np.abs(min(plotpred)) / c2maxmin, 'black'),
                                (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                                (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                                (1, 'yellow')]
                )
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            fig.savefig(str(args.output_path) + "_" +
                        str(event.dl0.event_id) + '.png')

            plt.close()
예제 #21
0
def analyze_muon_event(event):
    """
    Generic muon event analyzer. 

    Parameters
    ----------
    event : ctapipe dl1 event container


    Returns
    -------
    muonringparam, muonintensityparam : MuonRingParameter 
    and MuonIntensityParameter container event

    """

    names = [
        'LST:LSTCam', 'MST:NectarCam', 'MST:FlashCam', 'MST-SCT:SCTCam',
        'SST-1M:DigiCam', 'SST-GCT:CHEC', 'SST-ASTRI:ASTRICam',
        'SST-ASTRI:CHEC'
    ]
    tail_cuts = [(5, 7), (5, 7), (10, 12), (5, 7), (5, 7), (5, 7), (5, 7),
                 (5, 7)]  # 10, 12?
    impact = [(0.2, 0.9), (0.1, 0.95), (0.2, 0.9), (0.2, 0.9), (0.1, 0.95),
              (0.1, 0.95), (0.1, 0.95), (0.1, 0.95)] * u.m
    ringwidth = [(0.04, 0.08), (0.02, 0.1), (0.01, 0.1), (0.02, 0.1),
                 (0.01, 0.5), (0.02, 0.2), (0.02, 0.2), (0.02, 0.2)] * u.deg
    total_pix = [1855., 1855., 1764., 11328., 1296., 2048., 2368., 2048]
    # 8% (or 6%) as limit
    min_pix = [148., 148., 141., 680., 104., 164., 142., 164]
    # Need to either convert from the pixel area in m^2 or check the camera specs
    ang_pixel_width = [0.1, 0.2, 0.18, 0.067, 0.24, 0.2, 0.17, 0.2, 0.163
                       ] * u.deg
    # Found from TDRs (or the pixel area)
    hole_rad = [
        0.308 * u.m, 0.244 * u.m, 0.244 * u.m, 4.3866 * u.m, 0.160 * u.m,
        0.130 * u.m, 0.171 * u.m, 0.171 * u.m
    ]  # Assuming approximately spherical hole
    cam_rad = [2.26, 3.96, 3.87, 4., 4.45, 2.86, 5.25, 2.86] * u.deg
    # Above found from the field of view calculation
    sec_rad = [
        0. * u.m, 0. * u.m, 0. * u.m, 2.7 * u.m, 0. * u.m, 1. * u.m, 1.8 * u.m,
        1.8 * u.m
    ]
    sct = [False, False, False, True, False, True, True, True]

    muon_cuts = {
        'Name': names,
        'tail_cuts': tail_cuts,
        'Impact': impact,
        'RingWidth': ringwidth,
        'total_pix': total_pix,
        'min_pix': min_pix,
        'CamRad': cam_rad,
        'SecRad': sec_rad,
        'SCT': sct,
        'AngPixW': ang_pixel_width,
        'HoleRad': hole_rad
    }
    logger.debug(muon_cuts)

    muonringlist = []  # [None] * len(event.dl0.tels_with_data)
    muonintensitylist = []  # [None] * len(event.dl0.tels_with_data)
    tellist = []
    muon_event_param = {
        'TelIds': tellist,
        'MuonRingParams': muonringlist,
        'MuonIntensityParams': muonintensitylist
    }

    for telid in event.dl0.tels_with_data:

        logger.debug("Analysing muon event for tel %d", telid)
        image = event.dl1.tel[telid].image[0]

        # Get geometry
        teldes = event.inst.subarray.tel[telid]
        geom = teldes.camera
        x, y = geom.pix_x, geom.pix_y

        dict_index = muon_cuts['Name'].index(str(teldes))
        logger.debug('found an index of %d for camera %d', dict_index,
                     geom.cam_id)

        tailcuts = muon_cuts['tail_cuts'][dict_index]
        logger.debug("Tailcuts are %s", tailcuts)

        clean_mask = tailcuts_clean(geom,
                                    image,
                                    picture_thresh=tailcuts[0],
                                    boundary_thresh=tailcuts[1])
        camera_coord = CameraFrame(
            x=x,
            y=y,
            focal_length=teldes.optics.equivalent_focal_length,
            rotation=geom.pix_rotation)

        # TODO: correct this hack for values over 90
        altval = event.mcheader.run_array_direction[1]
        if altval > np.pi / 2.:
            altval = np.pi / 2.

        altaz = HorizonFrame(alt=altval * u.rad,
                             az=event.mcheader.run_array_direction[0] * u.rad)
        nom_coord = camera_coord.transform_to(
            NominalFrame(array_direction=altaz, pointing_direction=altaz))
        x = nom_coord.x.to(u.deg)
        y = nom_coord.y.to(u.deg)

        img = image * clean_mask
        muonring = ChaudhuriKunduRingFitter(None)

        logger.debug("img: %s mask: %s, x=%s y= %s", np.sum(image),
                     np.sum(clean_mask), x, y)

        if not sum(img):  # Nothing left after tail cuts
            continue

        muonringparam = muonring.fit(x, y, image * clean_mask)

        dist = np.sqrt(
            np.power(x - muonringparam.ring_center_x, 2) +
            np.power(y - muonringparam.ring_center_y, 2))
        ring_dist = np.abs(dist - muonringparam.ring_radius)

        muonringparam = muonring.fit(
            x, y, img * (ring_dist < muonringparam.ring_radius * 0.4))

        dist = np.sqrt(
            np.power(x - muonringparam.ring_center_x, 2) +
            np.power(y - muonringparam.ring_center_y, 2))
        ring_dist = np.abs(dist - muonringparam.ring_radius)

        muonringparam = muonring.fit(
            x, y, img * (ring_dist < muonringparam.ring_radius * 0.4))

        muonringparam.tel_id = telid
        muonringparam.obs_id = event.dl0.obs_id
        muonringparam.event_id = event.dl0.event_id
        dist_mask = np.abs(
            dist - muonringparam.ring_radius) < muonringparam.ring_radius * 0.4
        pix_im = image * dist_mask
        nom_dist = np.sqrt(
            np.power(muonringparam.ring_center_x, 2) +
            np.power(muonringparam.ring_center_y, 2))

        minpix = muon_cuts['min_pix'][dict_index]  # 0.06*numpix #or 8%

        mir_rad = np.sqrt(teldes.optics.mirror_area.to("m2") / np.pi)

        # Camera containment radius -  better than nothing - guess pixel
        # diameter of 0.11, all cameras are perfectly circular   cam_rad =
        # np.sqrt(numpix*0.11/(2.*np.pi))

        if (npix_above_threshold(pix_im, tailcuts[0]) > 0.1 * minpix
                and npix_composing_ring(pix_im) > minpix
                and nom_dist < muon_cuts['CamRad'][dict_index]
                and muonringparam.ring_radius < 1.5 * u.deg
                and muonringparam.ring_radius > 1. * u.deg):
            muonringparam.ring_containment = ring_containment(
                muonringparam.ring_radius, muon_cuts['CamRad'][dict_index],
                muonringparam.ring_center_x, muonringparam.ring_center_y)

            # Guess HESS is 0.16
            # sec_rad = 0.*u.m
            # sct = False
            # if numpix == 2048 and mir_rad > 2.*u.m and mir_rad < 2.1*u.m:
            #     sec_rad = 1.*u.m
            #     sct = True
            #
            # Store muon ring parameters (passing cuts stage 1)
            # muonringlist[idx] = muonringparam

            tellist.append(telid)
            muonringlist.append(muonringparam)
            muonintensitylist.append(None)

            ctel = MuonLineIntegrate(
                mir_rad,
                hole_radius=muon_cuts['HoleRad'][dict_index],
                pixel_width=muon_cuts['AngPixW'][dict_index],
                sct_flag=muon_cuts['SCT'][dict_index],
                secondary_radius=muon_cuts['SecRad'][dict_index])

            if image.shape[0] == muon_cuts['total_pix'][dict_index]:
                muonintensityoutput = ctel.fit_muon(
                    muonringparam.ring_center_x, muonringparam.ring_center_y,
                    muonringparam.ring_radius, x[dist_mask], y[dist_mask],
                    image[dist_mask])

                muonintensityoutput.tel_id = telid
                muonintensityoutput.obs_id = event.dl0.obs_id
                muonintensityoutput.event_id = event.dl0.event_id
                muonintensityoutput.mask = dist_mask

                idx_ring = np.nonzero(pix_im)
                muonintensityoutput.ring_completeness = ring_completeness(
                    x[idx_ring],
                    y[idx_ring],
                    pix_im[idx_ring],
                    muonringparam.ring_radius,
                    muonringparam.ring_center_x,
                    muonringparam.ring_center_y,
                    threshold=30,
                    bins=30)

                dist_ringwidth_mask = np.abs(
                    dist - muonringparam.ring_radius) < (
                        muonintensityoutput.ring_width)
                pix_ringwidth_im = image * dist_ringwidth_mask
                idx_ringwidth = np.nonzero(pix_ringwidth_im)

                muonintensityoutput.ring_pix_completeness = npix_above_threshold(
                    pix_ringwidth_im[idx_ringwidth], tailcuts[0]) / len(
                        pix_im[idx_ringwidth])

                logger.debug(
                    "Tel %d Impact parameter = %s mir_rad=%s "
                    "ring_width=%s", telid,
                    muonintensityoutput.impact_parameter, mir_rad,
                    muonintensityoutput.ring_width)
                conditions = [
                    muonintensityoutput.impact_parameter * u.m <
                    muon_cuts['Impact'][dict_index][1] * mir_rad,
                    muonintensityoutput.impact_parameter >
                    muon_cuts['Impact'][dict_index][0],
                    muonintensityoutput.ring_width <
                    muon_cuts['RingWidth'][dict_index][1],
                    muonintensityoutput.ring_width >
                    muon_cuts['RingWidth'][dict_index][0]
                ]

                if all(conditions):
                    muonintensityparam = muonintensityoutput
                    idx = tellist.index(telid)
                    muonintensitylist[idx] = muonintensityparam
                    logger.debug("Muon found in tel %d,  tels in event=%d",
                                 telid, len(event.dl0.tels_with_data))
                else:
                    continue

    return muon_event_param
예제 #22
0
def plot_muon_event(event, muonparams, args=None):

    if muonparams['MuonRingParams'] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))

        colorbar = None
        colorbar2 = None

        #for tel_id in event.dl0.tels_with_data:
        for tel_id in muonparams['TelIds']:
            idx = muonparams['TelIds'].index(tel_id)

            if not muonparams['MuonRingParams'][idx]:
                continue

            #otherwise...
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event)
            image = event.dl1.tel[tel_id].image[0]
            geom = event.inst.subarray.tel[tel_id].camera

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            clean_mask = tailcuts_clean(geom,
                                        image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(
                muonparams['MuonRingParams'][idx].ring_center_x**2. +
                muonparams['MuonRingParams'][idx].ring_center_y**2.)

            muon_phi = np.arctan(
                muonparams['MuonRingParams'][idx].ring_center_y /
                muonparams['MuonRingParams'][idx].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(
                x=muonparams['MuonRingParams'][idx].ring_center_x,
                y=muonparams['MuonRingParams'][idx].ring_center_y,
                array_direction=altaz,
                pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(
                CameraFrame(pointing_direction=altaz,
                            focal_length=event.inst.optical_foclen[tel_id],
                            rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams['MuonRingParams'][idx].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px,
                                       y=py,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz, pointing_direction=altaz))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(
                np.power(px -
                         muonparams['MuonRingParams'][idx].ring_center_x, 2) +
                np.power(py -
                         muonparams['MuonRingParams'][idx].ring_center_y, 2))
            ring_dist = np.abs(dist -
                               muonparams['MuonRingParams'][idx].ring_radius)
            pixRmask = ring_dist < muonparams['MuonRingParams'][
                idx].ring_radius * 0.4

            #if muonparams[1] is not None:
            if muonparams['MuonIntensityParams'][idx] is not None:
                signals *= muonparams['MuonIntensityParams'][idx].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            cmin = min(signals)
            if not cmin:
                cmin = 1.
            if not cmaxmin:
                cmaxmin = 1.

            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(cmin) / cmaxmin, 'black'),
                           (2.0 * np.abs(cmin) / cmaxmin, 'blue'),
                           (2.5 * np.abs(cmin) / cmaxmin, 'green'),
                           (1, 'yellow')])
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid,
                                ringrad_camcoord.value,
                                ringrad_camcoord.value,
                                0.,
                                0.,
                                color="red")

            if muonparams['MuonIntensityParams'][idx] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)

                ringwidthfrac = muonparams['MuonIntensityParams'][
                    idx].ring_width / muonparams['MuonRingParams'][
                        idx].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid,
                                    ringrad_inner.value,
                                    ringrad_inner.value,
                                    0.,
                                    0.,
                                    color="magenta")
                camera1.add_ellipse(centroid,
                                    ringrad_outer.value,
                                    ringrad_outer.value,
                                    0.,
                                    0.,
                                    color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams['MuonIntensityParams'][idx].prediction

                if len(pred) != np.sum(
                        muonparams['MuonIntensityParams'][idx].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=",
                          np.sum(muonparams['MuonIntensityParams'][idx].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams['MuonIntensityParams'][idx].mask ==
                         True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                if np.isnan(max(plotpred)) or np.isnan(min(plotpred)):
                    print("nan prediction, skipping...")
                    continue

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.

                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c',
                    [(0 / c2maxmin, 'darkblue'),
                     (np.abs(min(plotpred)) / c2maxmin, 'black'),
                     (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                     (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                     (1, 'yellow')])
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            #fig.savefig(str(args.output_path) + "_" +
            #            str(event.dl0.event_id) + '.png')

            plt.close()
예제 #23
0
def plot_muon_event(event, muonparams, geom_dict=None, args=None):

    if muonparams[0] is not None:

        # Plot the muon event and overlay muon parameters
        fig = plt.figure(figsize=(16, 7))
        # if args.display:
        #    plt.show(block=False)
        #pp = PdfPages(args.output_path) if args.output_path is not None else None
        # pp = None #For now, need to correct this

        colorbar = None
        colorbar2 = None

        for tel_id in event.dl0.tels_with_data:
            npads = 2
            # Only create two pads if there is timing information extracted
            # from the calibration
            ax1 = fig.add_subplot(1, npads, 1)
            plotter = CameraPlotter(event, geom_dict)
            #image = event.dl1.tel[tel_id].calibrated_image
            image = event.dl1.tel[tel_id].image[0]
            # Get geometry
            geom = None
            if geom_dict is not None and tel_id in geom_dict:
                geom = geom_dict[tel_id]
            else:
                #log.debug("[calib] Guessing camera geometry")
                geom = CameraGeometry.guess(*event.inst.pixel_pos[tel_id],
                                            event.inst.optical_foclen[tel_id])
                #log.debug("[calib] Camera geometry found")
                if geom_dict is not None:
                    geom_dict[tel_id] = geom

            tailcuts = (5., 7.)
            # Try a higher threshold for
            if geom.cam_id == 'FlashCam':
                tailcuts = (10., 12.)

            #print("Using Tail Cuts:",tailcuts)
            clean_mask = tailcuts_clean(geom,
                                        image,
                                        picture_thresh=tailcuts[0],
                                        boundary_thresh=tailcuts[1])

            signals = image * clean_mask

            #print("Ring Centre in Nominal Coords:",muonparams[0].ring_center_x,muonparams[0].ring_center_y)
            muon_incl = np.sqrt(muonparams[0].ring_center_x**2. +
                                muonparams[0].ring_center_y**2.)

            muon_phi = np.arctan(muonparams[0].ring_center_y /
                                 muonparams[0].ring_center_x)

            rotr_angle = geom.pix_rotation
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and
            # event.dl0.tel[tel_id].num_pixels != 1764:
            if geom.cam_id == 'LSTCam' or geom.cam_id == 'NectarCam':
                #print("Resetting the rotation angle")
                rotr_angle = 0. * u.deg

            # Convert to camera frame (centre & radius)
            altaz = HorizonFrame(alt=event.mc.alt, az=event.mc.az)

            ring_nominal = NominalFrame(x=muonparams[0].ring_center_x,
                                        y=muonparams[0].ring_center_y,
                                        array_direction=altaz,
                                        pointing_direction=altaz)

            # embed()
            ring_camcoord = ring_nominal.transform_to(
                CameraFrame(pointing_direction=altaz,
                            focal_length=event.inst.optical_foclen[tel_id],
                            rotation=rotr_angle))

            centroid_rad = np.sqrt(ring_camcoord.y**2 + ring_camcoord.x**2)
            centroid = (ring_camcoord.x.value, ring_camcoord.y.value)

            ringrad_camcoord = muonparams[0].ring_radius.to(u.rad) \
                               * event.inst.optical_foclen[tel_id] * 2.  # But not FC?

            #rot_angle = 0.*u.deg
            # if event.inst.optical_foclen[tel_id] > 10.*u.m and event.dl0.tel[tel_id].num_pixels != 1764:
            #rot_angle = -100.14*u.deg

            px, py = event.inst.pixel_pos[tel_id]
            flen = event.inst.optical_foclen[tel_id]
            camera_coord = CameraFrame(x=px,
                                       y=py,
                                       z=np.zeros(px.shape) * u.m,
                                       focal_length=flen,
                                       rotation=geom.pix_rotation)

            nom_coord = camera_coord.transform_to(
                NominalFrame(array_direction=altaz, pointing_direction=altaz))
            #,focal_length = event.inst.optical_foclen[tel_id])) # tel['TelescopeTable_VersionFeb2016'][tel['TelescopeTable_VersionFeb2016']['TelID']==telid]['FL'][0]*u.m))

            px = nom_coord.x.to(u.deg)
            py = nom_coord.y.to(u.deg)

            dist = np.sqrt(
                np.power(px - muonparams[0].ring_center_x, 2) +
                np.power(py - muonparams[0].ring_center_y, 2))
            ring_dist = np.abs(dist - muonparams[0].ring_radius)
            pixRmask = ring_dist < muonparams[0].ring_radius * 0.4

            if muonparams[1] is not None:
                signals *= muonparams[1].mask

            camera1 = plotter.draw_camera(tel_id, signals, ax1)

            cmaxmin = (max(signals) - min(signals))
            if not cmaxmin:
                cmaxmin = 1.
            cmap_charge = colors.LinearSegmentedColormap.from_list(
                'cmap_c', [(0 / cmaxmin, 'darkblue'),
                           (np.abs(min(signals)) / cmaxmin, 'black'),
                           (2.0 * np.abs(min(signals)) / cmaxmin, 'blue'),
                           (2.5 * np.abs(min(signals)) / cmaxmin, 'green'),
                           (1, 'yellow')])
            camera1.pixels.set_cmap(cmap_charge)
            if not colorbar:
                camera1.add_colorbar(ax=ax1, label=" [photo-electrons]")
                colorbar = camera1.colorbar
            else:
                camera1.colorbar = colorbar
            camera1.update(True)

            camera1.add_ellipse(centroid,
                                ringrad_camcoord.value,
                                ringrad_camcoord.value,
                                0.,
                                0.,
                                color="red")

            #            ax1.set_title("CT {} ({}) - Mean pixel charge"
            #                          .format(tel_id, geom_dict[tel_id].cam_id))

            if muonparams[1] is not None:
                # continue #Comment this...(should ringwidthfrac also be *0.5?)
                ringwidthfrac = muonparams[1].ring_width / muonparams[
                    0].ring_radius
                ringrad_inner = ringrad_camcoord * (1. - ringwidthfrac)
                ringrad_outer = ringrad_camcoord * (1. + ringwidthfrac)
                camera1.add_ellipse(centroid,
                                    ringrad_inner.value,
                                    ringrad_inner.value,
                                    0.,
                                    0.,
                                    color="magenta")
                camera1.add_ellipse(centroid,
                                    ringrad_outer.value,
                                    ringrad_outer.value,
                                    0.,
                                    0.,
                                    color="magenta")
                npads = 2
                ax2 = fig.add_subplot(1, npads, npads)
                pred = muonparams[1].prediction

                if len(pred) != np.sum(muonparams[1].mask):
                    print("Warning! Lengths do not match...len(pred)=",
                          len(pred), "len(mask)=", np.sum(muonparams[1].mask))

                # Numpy broadcasting - fill in the shape
                plotpred = np.zeros(image.shape)
                plotpred[muonparams[1].mask == True] = pred

                camera2 = plotter.draw_camera(tel_id, plotpred, ax2)

                c2maxmin = (max(plotpred) - min(plotpred))
                if not c2maxmin:
                    c2maxmin = 1.
                c2map_charge = colors.LinearSegmentedColormap.from_list(
                    'c2map_c',
                    [(0 / c2maxmin, 'darkblue'),
                     (np.abs(min(plotpred)) / c2maxmin, 'black'),
                     (2.0 * np.abs(min(plotpred)) / c2maxmin, 'blue'),
                     (2.5 * np.abs(min(plotpred)) / c2maxmin, 'green'),
                     (1, 'yellow')])
                camera2.pixels.set_cmap(c2map_charge)
                if not colorbar2:
                    camera2.add_colorbar(ax=ax2, label=" [photo-electrons]")
                    colorbar2 = camera2.colorbar
                else:
                    camera2.colorbar = colorbar2
                camera2.update(True)
                plt.pause(1.)  # make shorter

            # plt.pause(0.1)
            # if pp is not None:
            #    pp.savefig(fig)
            fig.savefig(
                str(args.output_path) + "_" + str(event.dl0.event_id) + '.png')

            plt.close()