Esempio n. 1
0
def getSourcesInTheROI(ra, dec, roi, met):
    roi = float(roi)
    #config = fermiatSUlib.Configuration()
    # xml = readXml.SourceModel(config['FGL_XML_CATALOG'])
    # fglSources = {k: v for k, v in xml.srcList.iteritems() if k.find("2FGL")>=0}

    #Open the FITS file, keeping only certain classes of sources
    f = pyfits.open(os.environ['FERMISOURCECATALOG'])
    fglFITS = f['LAT_Point_Source_Catalog'].data
    f.close()

    classesToKeep = FGL_CLASSES

    def filtering(x):
        if (x.field('CLASS1') in classesToKeep):
            return True
        else:
            return False
        pass

    pass

    fglSources = filter(filtering, fglFITS)
    sources = []
    for src in fglSources:
        try:
            thisRA = float(src.field("RAJ2000"))
            thisDec = float(src.field("DEJ2000"))
            thisDistance = getAngularDistance(float(ra), float(dec), thisRA,
                                              thisDec)
        except:
            #Extended sources
            continue
        if (thisDistance <= roi):
            if (src.field('ASSOC1') != ""):
                k = "%s\n(%s)" % (src.field("ASSOC1"), src.field("CLASS1"))
            else:
                k = "%s\n(%s)" % (src.field("Source_Name"),
                                  src.field("CLASS1"))
            sources.append([k, thisRA, thisDec, thisDistance])
    pass

    #Now add the Sun, if it is inside the ROI
    sundir = sunpos.getSunPosition(met)
    ra_sun, dec_sun = (sundir.ra(), sundir.dec())
    sunDistance = getAngularDistance(float(ra), float(dec), ra_sun, dec_sun)
    if (sunDistance <= roi):
        k = "Sun pos. at\ntrigger time"
        sources.append([k, ra_sun, dec_sun, sunDistance])
    pass
    return sources
Esempio n. 2
0
def get_coverage(ft2file, ligo_map_file, met_t1, met_t2, theta_cut,
                 zenith_cut):
    ft2data = pyfits.getdata(ft2file)

    ligo_map = hp.read_map(ligo_map_file)

    ligo_ra, ligo_dec = pix_to_sky(range(ligo_map.shape[0]), 512)

    # Filter out pixels with too low probability to gain speed

    interesting_idx = (ligo_map > 1e-7)

    print("Kept %s pixels for considerations in LIGO map" %
          np.sum(interesting_idx))

    # Get entries from the FT2 file every 10 s (cadence)

    start, ra_scz, dec_scz, ra_zenith, dec_zenith = _gtmktime(ft2data,
                                                              met_t1,
                                                              met_t2,
                                                              cadence=30)

    print("\nCoverage will be computed from %.1f to %.1f\n" %
          (start.min(), start.max()))

    coverage = np.zeros_like(start)

    for i, (t, rz, dz, rz2, dz2) in enumerate(
            zip(start, ra_scz, dec_scz, ra_zenith, dec_zenith)):
        # Get the angular distance between the current pointing and
        # all the LIGO pixels

        d = getAngularDistance(rz, dz, ligo_ra[interesting_idx],
                               ligo_dec[interesting_idx])

        zenith = getAngularDistance(rz2, dz2, ligo_ra[interesting_idx],
                                    ligo_dec[interesting_idx])

        # Select the LIGO pixels within the LAT FOV

        idx = (d < theta_cut) & (zenith < zenith_cut)

        coverage[i] = np.sum(ligo_map[interesting_idx][idx])

        sys.stdout.write("\r%.1f percent completed" %
                         ((i + 1) / float(coverage.shape[0]) * 100.0))

    sys.stdout.write("\n")

    return start, coverage
        else:

            n_entries = int(n_entries)

            stop_time = args.met_stop

        log.info(
            "Computing angular distance between pointing in the pointing history and "
            "desired position (%s, %s)..." % (args.ra, args.dec))

        # Compute angular distance between desired (RA, Dec) and the pointing of the LAT

        ra_scz, dec_scz = f['SC_DATA'].data.field(
            "RA_SCZ"), f['SC_DATA'].data.field("DEC_SCZ")

        ang_dis = getAngularDistance(args.ra, args.dec, ra_scz, dec_scz)

        # Find the time where the distance was at its minimum (keeping some margin to later select the data)
        min_idx = ang_dis[:-n_entries].argmin()

        time_of_min_distance = f['SC_DATA'].data.field("START")[min_idx]

        log.info("At MET = %.3f the distance between the pointing and the "
                 "input position was %.3f deg" %
                 (time_of_min_distance, ang_dis[min_idx]))

        # Now create a new FT2 file with the pointing fixed at the desired position

        new_sc_table = pyfits.BinTableHDU(f['SC_DATA'].data[min_idx:min_idx +
                                                            n_entries])
Esempio n. 4
0
def run(**kwargs):
  if(len(kwargs.keys())==0):
    #Nothing specified, the user needs just help!
    thisCommand.getHelp()
    return
  pass
  
  #Get parameters values
  thisCommand.setParValuesFromDictionary(kwargs)
  try:
    eventfile                   = thisCommand.getParValue('filteredeventfile')
    rspfile                     = thisCommand.getParValue('rspfile')
    ft2file                     = thisCommand.getParValue('ft2file')
    xmlmodel                    = thisCommand.getParValue('xmlmodel')
    tsltcube                    = thisCommand.getParValue('tsltcube')
    tsexpomap                   = thisCommand.getParValue('tsexpomap')
    tsmap                       = thisCommand.getParValue('tsmap')
    step                        = float(thisCommand.getParValue('step'))
    side                        = thisCommand.getParValue('side')
    if(side=='auto'):
      side                      = None
#    showmodelimage              = thisCommand.getParValue('showmodelimage')
#    optimize                    = thisCommand.getParValue('optimizeposition')
#    tsmin                       = float(thisCommand.getParValue('tsmin'))
#    skymap                      = thisCommand.getParValue('skymap')
    clobber                     = _yesOrNoToBool(thisCommand.getParValue('clobber'))
    verbose                     = _yesOrNoToBool(thisCommand.getParValue('verbose'))
    figure                      = thisCommand.getParValue('figure')
  except KeyError as err:
    print("\n\nERROR: Parameter %s not found or incorrect! \n\n" %(err.args[0]))
    
    #Print help
    print thisCommand.getHelp()
    return
  pass
  
  from GtBurst import dataHandling
  from GtBurst.angularDistance import getAngularDistance
  
  origra                      = float(dataHandling._getParamFromXML(xmlmodel,'RA'))
  origdec                     = float(dataHandling._getParamFromXML(xmlmodel,'DEC'))
  sourceName                  = dataHandling._getParamFromXML(xmlmodel,'OBJECT')
  
  #Verify that TS map, if provided, is compatible with the position in the XML
  if(tsexpomap is not None and tsexpomap!=''):
    if(os.path.exists(tsexpomap)):
      header                  = pyfits.getheader(tsexpomap)
      ra,dec                  = (float(header.get('CRVAL1')),float(header.get('CRVAL2')))
      angdist                 = getAngularDistance(origra,origdec,ra,dec)
      if(angdist > 0.1):
        print("Provided exposure map has a different center. Will compute it again.")
        tsexpomap             = None
    else:
      print("Provided exposure map does not exist. Will compute it again.")
      tsexpomap               = None
  
  LATdata                     = dataHandling.LATData(eventfile,rspfile,ft2file)
  tsmap                       = LATdata.makeTSmap(xmlmodel,sourceName,step,side,tsmap,tsltcube,tsexpomap)
  tsltcube                    = LATdata.livetimeCube
  tsexpomap                   = LATdata.exposureMap
  
  ra,dec,tsmax                = dataHandling.findMaximumTSmap(tsmap,tsexpomap)
  
  print("\nCoordinates of the maximum of the TS map in the allowed region (TS = %.1f):" %(tsmax))
  print("(R.A., Dec.)              = (%6.3f, %6.3f)\n" %(ra,dec))
  print("Distance from ROI center  = %6.3f\n\n" %(getAngularDistance(origra,origdec,ra,dec)))

  if(figure is not None):
    from GtBurst import aplpy   
    #Display the TS map    
    figure.clear()
    tsfig                       = aplpy.FITSFigure(tsmap,convention='calabretta',figure=figure)
    tsfig.set_tick_labels_font(size='small')
    tsfig.set_axis_labels_font(size='small')
    tsfig.show_colorscale(cmap='gist_heat',aspect='auto')
    tsfig.show_markers([ra], [dec], edgecolor='green', facecolor='none', marker='o', s=10, alpha=0.5)
    # Modify the tick labels for precision and format
    tsfig.tick_labels.set_xformat('ddd.dd')
    tsfig.tick_labels.set_yformat('ddd.dd')
    
    # Display a grid and tweak the properties
    tsfig.show_grid()
    
    figure.canvas.draw()
  pass
  
  return 'tsmap', tsmap, 'tsmap_ra', ra, 'tsmap_dec', dec, 'tsmap_maxTS', tsmax, 'tsltcube', tsltcube, 'tsexpomap', tsexpomap
Esempio n. 5
0
def run(**kwargs):
    if (len(kwargs.keys()) == 0):
        #Nothing specified, the user needs just help!
        thisCommand.getHelp()
        return
    pass

    #Get parameters values
    thisCommand.setParValuesFromDictionary(kwargs)
    try:
        eventfile = thisCommand.getParValue('filteredeventfile')
        rspfile = thisCommand.getParValue('rspfile')
        ft2file = thisCommand.getParValue('ft2file')
        xmlmodel = thisCommand.getParValue('xmlmodel')
        tsltcube = thisCommand.getParValue('tsltcube')
        tsexpomap = thisCommand.getParValue('tsexpomap')
        tsmap = thisCommand.getParValue('tsmap')
        step = float(thisCommand.getParValue('step'))
        side = thisCommand.getParValue('side')
        if (side == 'auto'):
            side = None


#    showmodelimage              = thisCommand.getParValue('showmodelimage')
#    optimize                    = thisCommand.getParValue('optimizeposition')
#    tsmin                       = float(thisCommand.getParValue('tsmin'))
#    skymap                      = thisCommand.getParValue('skymap')
        clobber = _yesOrNoToBool(thisCommand.getParValue('clobber'))
        verbose = _yesOrNoToBool(thisCommand.getParValue('verbose'))
        figure = thisCommand.getParValue('figure')
    except KeyError as err:
        print("\n\nERROR: Parameter %s not found or incorrect! \n\n" %
              (err.args[0]))

        #Print help
        print thisCommand.getHelp()
        return
    pass

    from GtBurst import dataHandling
    from GtBurst.angularDistance import getAngularDistance

    origra = float(dataHandling._getParamFromXML(xmlmodel, 'RA'))
    origdec = float(dataHandling._getParamFromXML(xmlmodel, 'DEC'))
    sourceName = dataHandling._getParamFromXML(xmlmodel, 'OBJECT')

    #Verify that TS map, if provided, is compatible with the position in the XML
    if (tsexpomap is not None and tsexpomap != ''):
        if (os.path.exists(tsexpomap)):
            header = pyfits.getheader(tsexpomap)
            ra, dec = (float(header.get('CRVAL1')),
                       float(header.get('CRVAL2')))
            angdist = getAngularDistance(origra, origdec, ra, dec)
            if (angdist > 0.1):
                print(
                    "Provided exposure map has a different center. Will compute it again."
                )
                tsexpomap = None
        else:
            print(
                "Provided exposure map does not exist. Will compute it again.")
            tsexpomap = None

    LATdata = dataHandling.LATData(eventfile, rspfile, ft2file)
    tsmap = LATdata.makeTSmap(xmlmodel, sourceName, step, side, tsmap,
                              tsltcube, tsexpomap)
    tsltcube = LATdata.livetimeCube
    tsexpomap = LATdata.exposureMap

    ra, dec, tsmax = dataHandling.findMaximumTSmap(tsmap, tsexpomap)

    print(
        "\nCoordinates of the maximum of the TS map in the allowed region (TS = %.1f):"
        % (tsmax))
    print("(R.A., Dec.)              = (%6.3f, %6.3f)\n" % (ra, dec))
    print("Distance from ROI center  = %6.3f\n\n" %
          (getAngularDistance(origra, origdec, ra, dec)))

    if (figure is not None):
        from GtBurst import aplpy
        #Display the TS map
        figure.clear()
        tsfig = aplpy.FITSFigure(tsmap, convention='calabretta', figure=figure)
        tsfig.set_tick_labels_font(size='small')
        tsfig.set_axis_labels_font(size='small')
        tsfig.show_colorscale(cmap='gist_heat', aspect='auto')
        tsfig.show_markers([ra], [dec],
                           edgecolor='green',
                           facecolor='none',
                           marker='o',
                           s=10,
                           alpha=0.5)
        # Modify the tick labels for precision and format
        tsfig.tick_labels.set_xformat('ddd.dd')
        tsfig.tick_labels.set_yformat('ddd.dd')

        # Display a grid and tweak the properties
        tsfig.show_grid()

        figure.canvas.draw()
    pass

    return 'tsmap', tsmap, 'tsmap_ra', ra, 'tsmap_dec', dec, 'tsmap_maxTS', tsmax, 'tsltcube', tsltcube, 'tsexpomap', tsexpomap
Esempio n. 6
0
 def cutout(filename, ra_or_l, dec_or_b, coordsys, radius, outfile, clobber=True):
     """
     Inputs:
         file  - .fits filename or pyfits HDUList. If HDU is 3d (data-cube), the 3rd dimension
                 (the one which is not a sky coordinate) will be kept untouched. Dimensions > 3
                 are not supported
         ra_or_l,dec_or_b - Longitude and latitude of the center of the new image. The longitude
                            coordinate (R.A. or L) goes from 0 to 360, while the latitude coordinate
                            goes from -90 to 90.
         coordsys - Coordinate system for the center of the new image ('galactic' or 'equatorial')
         radius - radius of the region of interest (deg)
         outfile - output file
         clobber - overwrite the file if existing? (True or False)
     """
     
     if coordsys not in ['equatorial','galactic']:
       raise ValueError("Unknown coordinate system '%s'" %(coordsys))
     
     if(ra_or_l < 0 or ra_or_l > 360):
       raise RuntimeError("The longitude coordinate must be 0 < longitude < 360")
     
     if(dec_or_b < -90 or dec_or_b > 90):
       raise RuntimeError("The latitude coordinate must be -90 < latitude < 90")
         
     with pyfits.open(filename) as f:
       
       if(f[0].data.ndim==3):
         isCube                     = True
       elif(f[0].data.ndim==2):
         isCube                     = False
       else:
         raise RuntimeError("Do not know how to handle a cube with %s dimensions" %(f[0].data.shape[0]))
       pass
       
       head                         = f[0].header.copy()
       
       cd1                          = head.get('CDELT1') if head.get('CDELT1') else head.get('CD1_1')
       cd2                          = head.get('CDELT2') if head.get('CDELT2') else head.get('CD2_2')
       if cd1 is None or cd2 is None:
           raise Exception("Missing CD or CDELT keywords in header")
       
       wcs                         = pywcs.WCS(head)
       
       #Ensure that the center is expressed in the same coordinate system as the original
       #image
       if coordsys=='equatorial' and wcs.wcs.lngtyp=='GLON':
       
             #Convert RA,Dec in Galactic coordinates
             sdir                        = SkyDir(ra_or_l,dec_or_b,SkyDir.EQUATORIAL)
             xc,yc                       = (sdir.l(),sdir.b())
       
       elif coordsys=='galactic' and wcs.wcs.lngtyp=='RA':
             
             #Convert L,B in Equatorial coordinates
             sdir                        = SkyDir(ra_or_l,dec_or_b,SkyDir.EQUATORIAL)
             xc,yc                       = (sdir.ra(),sdir.dec())
 
       else:
       
            #Image and input are in the same system already
            xc,yc                        = (ra_or_l,dec_or_b)
       
       pass
       
       #Find the pixel corresponding to the center
       if(isCube):
         #Data cube
         coord                      = numpy.array([[xc],[yc],[1]]).T
         xx,yy,z                    = wcs.wcs_sky2pix(coord,0)[0]
         shapez,shapey,shapex       = f[0].data.shape
         
         #Compute the sky coordinates of all pixels 
         #(will use them later for the angular distance)
         
         #The code below is much faster, but does the same thing as this
         #one here:
         
         #coord                        = numpy.zeros((shapex*shapey,3))
         #h                            = 0
         #for i in range(shapex):
         #  for j in range(shapey):
         #    coord[h]                 = [i+1,j+1,1]
         #    h                       += 1
         
         coord                        = numpy.ones((shapex*shapey,3))
         firstColBase                 = numpy.arange(shapex)+1
         firstColumn                  = numpy.repeat(firstColBase,shapey)
         secondColumn                 = numpy.array(range(shapey)*shapex)+1
         coord[:,0]                   = firstColumn
         coord[:,1]                   = secondColumn
                         
         #Note that pix2sky always return the latitude from 0 to 360 deg
         res                          = wcs.wcs_pix2sky(coord,1)
         ras                          = res[:,0]
         decs                         = res[:,1]
         
       else:
         #Normal image
         coord                       = numpy.array([[xc],[yc]]).T
         xx,yy                       = wcs.wcs_sky2pix(coord,0)[0]
         shapey,shapex               = f[0].data.shape
         
         #Compute the sky coordinates of all pixels 
         #(will use them later for the angular distance)
         coord                        = numpy.ones((shapex*shapey,2))
         firstColBase                 = numpy.arange(shapex)+1
         firstColumn                  = numpy.repeat(firstColBase,shapey)
         secondColumn                 = numpy.array(range(shapey)*shapex)+1
         coord[:,0]                   = firstColumn
         coord[:,1]                   = secondColumn
                         
         #Note that pix2sky always return the latitude from 0 to 360 deg
         res                          = wcs.wcs_pix2sky(coord,1)
         ras                          = res[:,0]
         decs                         = res[:,1]
       pass
         
       print("Center is (%s,%s) pixel, (%s,%s) sky" %(xx,yy,xc,yc))
       
       #Cannot deal with fractional pixel
       if(xx - int(xx) >= 1e-4):
         print("Approximating the X pixel: %s -> %s" %(xx,int(xx)))
         xx                          = int(xx)
       if(yy - int(yy) >= 1e-4):
         print("Approximating the Y pixel: %s -> %s" %(yy,int(yy)))
         yy                          = int(yy)
       pass
       
       #Now select the pixels to keep
       #Pre-select according to a bounding box
       #(huge gain of speed in the computation of distances)
       ra_min_,ra_max_,dec_min_,dec_max_,pole = getBoundingCoordinates(xc,yc,radius)
       
       if(pole):
         #Nothing we can really do, except masking out (zeroing) all the useless parts
         print("\nOne of the poles is within the region. Cannot cut the image. I will zero-out useless parts")
         img                           = f[0].data
         
         #Find the pixel corresponding to (xc,yc-radius)
         coord                         = numpy.array([[xc],[yc-radius],[1]]).T
         res                           = wcs.wcs_sky2pix(coord,0)[0]
         mask_ymax                     = int(numpy.ceil(res[1]))
         
         #Now find the pixel corresponding to (xc,yc+radius)
         coord                         = numpy.array([[xc],[yc+radius-180.0],[1]]).T
         res                           = wcs.wcs_sky2pix(coord,0)[0]
         mask_ymin                     = int(numpy.floor(res[1]))
                 
         img[:,mask_ymin:mask_ymax,:]  = img[:,mask_ymin:mask_ymax,:]*0.0
         
       else:
         if(ra_min_ > ra_max_):
           #Circular inversion (ex: ra_min_ = 340.0 and ra_max_ = 20.0)
           idx                         = (ra_min_ <= ras) | (ras <= ra_max_)
         else:
           idx                         = (ra_min_ <= ras) & (ras <= ra_max_)
         pass
         
         if(dec_min_ > dec_max_):
           #Circular inversion (ex: ra_min_ = 340.0 and ra_max_ = 20.0)
           idx                         = ((dec_min_ <= decs) | (decs <= dec_max_)) & idx
         else:
           idx                         = ((dec_min_ <= decs) & (decs <= dec_max_)) & idx
         pass
               
         ras                           = ras[idx]
         decs                          = decs[idx]
         
         #Compute all angular distances of remaining pixels
         distances                     = getAngularDistance(xc,yc,ras,decs)
         
         #Select all pixels within the provided radius
         idx                           = (distances <= radius)
         selected_ras                  = ras[idx]
         selected_decs                 = decs[idx]
                 
         #Now transform back into pixels values
         if(isCube):
           
           coord                      = numpy.vstack([selected_ras,selected_decs,[1]*selected_ras.shape[0]]).T
                     
         else:
           
           coord                      = numpy.vstack([selected_ras,selected_decs]).T
         
         pass
         
         res                        = wcs.wcs_sky2pix(coord,0)
         
         #Now check if the range of x is not continuous (i.e., we are
         #wrapping around the borders)
         uniquex                    = numpy.unique(res[:,0])
         deltas                     = uniquex[1:]-uniquex[:-1]
         if(deltas.max()>1):
           #We are wrapping around the borders
           # |-------x1             x2-------|
           #We want to express x2 as a negative index starting
           #from the right border, and set it as xmin.
           #Then we set x1 as xmax.
           #This way the .take method below will start accumulating
           #the image from x2 to the right border |, then from the left
           #border | to x1, in this order
           #Find x2
           x2id                     = deltas.argmax()+1
           x2                       = int(uniquex[x2id])
           x1                       = int(uniquex[x2id-1])
           xmin                     = x2-shapex
           xmax                     = x1
           
           ymin,ymax                = (int(res[:,1].min()),int(res[:,1].max()))
           
         else:          
         
           xmin,xmax,ymin,ymax      = (int(res[:,0].min()),int(res[:,0].max()),int(res[:,1].min()),int(res[:,1].max()))
         
         pass        
         
         print("X range -> %s - %s" %(xmin,xmax))
         print("Y range -> %s - %s" %(ymin,ymax))
         print("Input image shape is ([z],y,x) = %s" %(str(f[0].shape)))
         
         #Using the mode='wrap' option we wrap around the edges of the image,
         #if ymin is negative
         if(isCube):
           
           img                        = f[0].data.take(range(ymin,ymax),mode='wrap', axis=1).take(range(xmin,xmax),mode='wrap',axis=2)
         
         else:
           
           img                        = f[0].data.take(range(ymin,ymax),mode='wrap', axis=0).take(range(xmin,xmax),mode='wrap',axis=1)
         
         pass
         
         #Put the origin of the projection in the right place
         #in the new image
         head['CRPIX1']               -= xmin
         head['CRPIX2']               -= ymin
         
         #Update the length of the axis
         head['NAXIS1']               = int(xmax-xmin)
         head['NAXIS2']               = int(ymax-ymin)
     
         if head.get('NAXIS1') == 0 or head.get('NAXIS2') == 0:
             raise ValueError("Map has a 0 dimension: %i,%i." % (head.get('NAXIS1'),head.get('NAXIS2')))
       pass
       
       newfile = pyfits.PrimaryHDU(data=img,header=head)
       
       newfile.writeto(outfile,clobber=clobber)
       #Append the other extension, if present
       for i in range(1,len(f)):
         pyfits.append(outfile,f[i].data,header=f[i].header)
     
     pass #Close the input file
     
     #Now re-open the output file and fix the wcs 
     #by moving the reference pixel to the 1,1 pixel
     #This guarantee that no pixel will be at a distance larger than 180 deg
     #from the reference pixel, which would confuse downstream software
     if(not pole):
       with pyfits.open(outfile,'update') as outf:
         head                         = outf[0].header
         #Get the 
         newwcs                          = pywcs.WCS(head)
         
         #Find the sky coordinates of the 1,1 pixel
         if(isCube):
           #Data cube
           coord                       = numpy.array([[1],[1],[1]]).T
           sx,sy,z                     = newwcs.wcs_pix2sky(coord,1)[0]
         else:
           #Normal image
           coord                       = numpy.array([[1],[1]]).T
           sx,sy                       = newwcs.wcs_pix2sky(coord,1)[0]
         pass
                 
         head['CRPIX1']                = 1
         head['CRVAL1']                = sx
       
       
     pass
Esempio n. 7
0
def run(**kwargs):
    if (len(kwargs.keys()) == 0):
        #Nothing specified, the user needs just help!
        thisCommand.getHelp()
        return
    pass

    #Get parameters values
    thisCommand.setParValuesFromDictionary(kwargs)
    try:
        eventfile = thisCommand.getParValue('filteredeventfile')
        rspfile = thisCommand.getParValue('rspfile')
        ft2file = thisCommand.getParValue('ft2file')
        expomap = thisCommand.getParValue('expomap')
        ltcube = thisCommand.getParValue('ltcube')
        xmlmodel = thisCommand.getParValue('xmlmodel')
        showmodelimage = thisCommand.getParValue('showmodelimage')
        optimize = thisCommand.getParValue('optimizeposition')
        spectralfiles = thisCommand.getParValue('spectralfiles')
        tsmin = float(thisCommand.getParValue('tsmin'))
        skymap = thisCommand.getParValue('skymap')
        liketype = thisCommand.getParValue('liketype')
        clobber = _yesOrNoToBool(thisCommand.getParValue('clobber'))
        verbose = _yesOrNoToBool(thisCommand.getParValue('verbose'))

        figure = thisCommand.getParValue('figure')
    except KeyError as err:
        print("\n\nERROR: Parameter %s not found or incorrect! \n\n" %
              (err.args[0]))

        #Print help
        print thisCommand.getHelp()
        return
    pass

    from GtBurst import dataHandling
    from GtBurst.angularDistance import getAngularDistance

    LATdata = dataHandling.LATData(eventfile, rspfile, ft2file)
    try:
        if (liketype == 'unbinned'):
            outfilelike, sources = LATdata.doUnbinnedLikelihoodAnalysis(
                xmlmodel, tsmin, expomap=expomap, ltcube=ltcube)
        else:
            #Generation of spectral files and optimization of the position is
            #not supported yet for binned analysis

            if (spectralfiles == 'yes'):

                print(
                    "\nWARNING: you specified spectralfiles=yes, but the generation of spectral files is not supported for binned analysis\n"
                )
                spectralfiles = 'no'

            if (optimize == 'yes'):

                print(
                    "\nWARNING: you specified optimize=yes, but position optimization is not supported for binned analysis\n"
                )
                optimize = 'no'

            outfilelike, sources = LATdata.doBinnedLikelihoodAnalysis(
                xmlmodel, tsmin, expomap=expomap, ltcube=ltcube)
    except GtBurstException as gt:
        raise gt
    except:
        raise

    #Transfer information on the source from the input to the output XML
    irf = dataHandling._getParamFromXML(xmlmodel, 'IRF')
    ra = dataHandling._getParamFromXML(xmlmodel, 'RA')
    dec = dataHandling._getParamFromXML(xmlmodel, 'DEC')
    name = dataHandling._getParamFromXML(xmlmodel, 'OBJECT')

    try:
        grb = filter(lambda x: x.name.lower().find(name.lower()) >= 0,
                     sources)[0]
        grb_TS = grb.TS
    except:
        #A model without GRB
        print("\nWarning: no GRB in the model!")
        grb_TS = -1
    pass

    if (irf == None):
        print(
            "\n\nWARNING: could not read IRF from XML file. Be sure you know what you are doing..."
        )
    else:
        dataHandling._writeParamIntoXML(outfilelike,
                                        IRF=irf,
                                        OBJECT=name,
                                        RA=ra,
                                        DEC=dec)
    pass

    if (spectralfiles == 'yes'):
        phafile, rspfile, bakfile = LATdata.doSpectralFiles(outfilelike)
    pass

    localizationMessage = ''
    bestra = ''
    bestdec = ''
    poserr = ''
    distance = ''
    if (optimize == 'yes'):
        sourceName = name

        #If the TS for the source is above tsmin, optimize its position
        #grb                       = filter(lambda x:x.name.lower().find(sourceName.lower())>=0,sources)[0]
        if (math.ceil(grb_TS) >= tsmin):
            try:
                bestra, bestdec, poserr = LATdata.optimizeSourcePosition(
                    outfilelike, sourceName)
            except:
                raise GtBurstException(
                    207,
                    "gtfindsrc execution failed. Were the source detected in the likelihood step?"
                )
            else:
                localizationMessage += "\nNew localization from gtfindsrc:\n\n"
                localizationMessage += "(R.A., Dec)                     = (%6.3f, %6.3f)\n" % (
                    bestra, bestdec)
                localizationMessage += "68 %s containment radius        = %6.3f\n" % (
                    '%', poserr)
                localizationMessage += "90 %s containment radius        = %6.3f\n" % (
                    '%', 1.41 * poserr)
                distance = getAngularDistance(float(ra), float(dec),
                                              float(bestra), float(bestdec))
                localizationMessage += "Distance from initial position  = %6.3f\n\n" % (
                    distance)
                localizationMessage += "NOTE: this new localization WILL NOT be used by default. If you judge"
                localizationMessage += " it is a better localization than the one you started with, update the"
                localizationMessage += " coordinates yourself and re-run the likelihood\n"
        pass
    pass

    if (figure != None and skymap != None and showmodelimage == 'yes'):

        #Now produce the binned exposure map (needed in order to display the fitted model as an image)
        modelmapfile = LATdata.makeModelSkyMap(outfilelike)

        #Display point sources in the image, and report in the table
        #all 2FGL sources with TS > 9 + always the GRB, independently of its TS
        detectedSources = []
        grbFlux = 1e-13
        for src in sources:
            weight = 'bold'

            if (src.type == 'PointSource'):
                if (src.TS > 4):
                    detectedSources.append(src)
                    if (src.name.find('2FGL') < 0):
                        #GRB
                        grbFlux = src.flux
                pass
            pass
        pass

        #Display the counts map
        from GtBurst import aplpy
        import matplotlib.pyplot as plt

        figure.clear()
        orig = aplpy.FITSFigure(skymap,
                                convention='calabretta',
                                figure=figure,
                                subplot=[0.1, 0.1, 0.45, 0.7])
        vmax = max(pyfits.open(skymap)[0].data.flatten())
        nEvents = numpy.sum(pyfits.open(skymap)[0].data)
        telapsed = pyfits.open(eventfile)[0].header['TSTOP'] - pyfits.open(
            eventfile)[0].header['TSTART']
        orig.set_tick_labels_font(size='small')
        orig.set_axis_labels_font(size='small')
        orig.show_colorscale(cmap='gist_heat',
                             vmin=0.1,
                             vmax=max(vmax, 0.11),
                             stretch='log',
                             aspect='auto')
        # Modify the tick labels for precision and format
        orig.tick_labels.set_xformat('ddd.dd')
        orig.tick_labels.set_yformat('ddd.dd')

        # Display a grid and tweak the properties
        orig.show_grid()

        #Renormalize the modelmapfile to the flux of the grb
        f = pyfits.open(modelmapfile, 'update')
        f[0].data = f[0].data / numpy.max(f[0].data) * nEvents / telapsed
        print(numpy.max(f[0].data))
        f.close()

        img = aplpy.FITSFigure(modelmapfile,
                               convention='calabretta',
                               figure=figure,
                               subplot=[0.55, 0.1, 0.4, 0.7])
        img.set_tick_labels_font(size='small')
        img.set_axis_labels_font(size='small')
        #vmax                     = max(pyfits.open(modelmapfile)[0].data.flatten())
        img.show_colorscale(cmap='gist_heat', aspect='auto', stretch='log')

        for src in detectedSources:
            img.add_label(float(src.ra),
                          float(src.dec),
                          "%s\n(ts = %i)" % (src.name, int(math.ceil(src.TS))),
                          relative=False,
                          weight=weight,
                          color='green',
                          size='small')
        pass

        # Modify the tick labels for precision and format
        img.tick_labels.set_xformat('ddd.dd')
        img.tick_labels.set_yformat('ddd.dd')

        # Display a grid and tweak the properties
        img.show_grid()

        #ax                        = figure.add_axes([0.1,0.72,0.85,0.25],frame_on=False)
        #ax.xaxis.set_visible(False)
        #ax.yaxis.set_visible(False)
        #col_labels                =['Source Name','TS','Energy flux','Photon index']
        #table_vals                = map(lambda x:[x.name,"%i" %(int(math.ceil(x.TS))),
        #                                          "%s +/- %s" % (x.flux,x.fluxError),
        #                                          "%s +/- %s" % (x.photonIndex,x.photonIndexError)],detectedSources)
        #
        #if(len(table_vals)>0):
        #  the_table                 = ax.table(cellText=table_vals,
        #                                        colLabels=col_labels,
        #                                       loc='upper center')

        figure.canvas.draw()
        figure.savefig("likelihood_results.png")
    pass

    if (figure != None):

        #Assume we have an X server running
        #Now display the results
        likemsg = "Log(likelihood) = %s" % (LATdata.logL)
        displayResults(
            figure.canvas._tkcanvas, LATdata.resultsStrings + "\n" + likemsg +
            "\n" + localizationMessage)

    print(localizationMessage)

    return 'likexmlresults', outfilelike, 'TS', grb_TS, 'bestra', bestra, 'bestdec', bestdec, 'poserr', poserr, 'distance', distance, 'sources', sources
Esempio n. 8
0
    def cutout(filename,
               ra_or_l,
               dec_or_b,
               coordsys,
               radius,
               outfile,
               clobber=True):
        """
        Inputs:
            file  - .fits filename or pyfits HDUList. If HDU is 3d (data-cube), the 3rd dimension
                    (the one which is not a sky coordinate) will be kept untouched. Dimensions > 3
                    are not supported
            ra_or_l,dec_or_b - Longitude and latitude of the center of the new image. The longitude
                               coordinate (R.A. or L) goes from 0 to 360, while the latitude coordinate
                               goes from -90 to 90.
            coordsys - Coordinate system for the center of the new image ('galactic' or 'equatorial')
            radius - radius of the region of interest (deg)
            outfile - output file
            clobber - overwrite the file if existing? (True or False)
        """

        if coordsys not in ['equatorial', 'galactic']:
            raise ValueError("Unknown coordinate system '%s'" % (coordsys))

        if (ra_or_l < 0 or ra_or_l > 360):
            raise RuntimeError(
                "The longitude coordinate must be 0 < longitude < 360")

        if (dec_or_b < -90 or dec_or_b > 90):
            raise RuntimeError(
                "The latitude coordinate must be -90 < latitude < 90")

        with pyfits.open(filename) as f:

            if (f[0].data.ndim == 3):
                isCube = True
            elif (f[0].data.ndim == 2):
                isCube = False
            else:
                raise RuntimeError(
                    "Do not know how to handle a cube with %s dimensions" %
                    (f[0].data.shape[0]))
            pass

            head = f[0].header.copy()

            cd1 = head.get('CDELT1') if head.get('CDELT1') else head.get(
                'CD1_1')
            cd2 = head.get('CDELT2') if head.get('CDELT2') else head.get(
                'CD2_2')
            if cd1 is None or cd2 is None:
                raise Exception("Missing CD or CDELT keywords in header")

            wcs = pywcs.WCS(head)

            #Ensure that the center is expressed in the same coordinate system as the original
            #image
            if coordsys == 'equatorial' and wcs.wcs.lngtyp == 'GLON':

                #Convert RA,Dec in Galactic coordinates
                sdir = SkyDir(ra_or_l, dec_or_b, SkyDir.EQUATORIAL)
                xc, yc = (sdir.l(), sdir.b())

            elif coordsys == 'galactic' and wcs.wcs.lngtyp == 'RA':

                #Convert L,B in Equatorial coordinates
                sdir = SkyDir(ra_or_l, dec_or_b, SkyDir.EQUATORIAL)
                xc, yc = (sdir.ra(), sdir.dec())

            else:

                #Image and input are in the same system already
                xc, yc = (ra_or_l, dec_or_b)

            pass

            #Find the pixel corresponding to the center
            if (isCube):
                #Data cube
                coord = numpy.array([[xc], [yc], [1]]).T
                xx, yy, z = wcs.wcs_sky2pix(coord, 0)[0]
                shapez, shapey, shapex = f[0].data.shape

                #Compute the sky coordinates of all pixels
                #(will use them later for the angular distance)

                #The code below is much faster, but does the same thing as this
                #one here:

                #coord                        = numpy.zeros((shapex*shapey,3))
                #h                            = 0
                #for i in range(shapex):
                #  for j in range(shapey):
                #    coord[h]                 = [i+1,j+1,1]
                #    h                       += 1

                coord = numpy.ones((shapex * shapey, 3))
                firstColBase = numpy.arange(shapex) + 1
                firstColumn = numpy.repeat(firstColBase, shapey)
                secondColumn = numpy.array(range(shapey) * shapex) + 1
                coord[:, 0] = firstColumn
                coord[:, 1] = secondColumn

                #Note that pix2sky always return the latitude from 0 to 360 deg
                res = wcs.wcs_pix2sky(coord, 1)
                ras = res[:, 0]
                decs = res[:, 1]

            else:
                #Normal image
                coord = numpy.array([[xc], [yc]]).T
                xx, yy = wcs.wcs_sky2pix(coord, 0)[0]
                shapey, shapex = f[0].data.shape

                #Compute the sky coordinates of all pixels
                #(will use them later for the angular distance)
                coord = numpy.ones((shapex * shapey, 2))
                firstColBase = numpy.arange(shapex) + 1
                firstColumn = numpy.repeat(firstColBase, shapey)
                secondColumn = numpy.array(range(shapey) * shapex) + 1
                coord[:, 0] = firstColumn
                coord[:, 1] = secondColumn

                #Note that pix2sky always return the latitude from 0 to 360 deg
                res = wcs.wcs_pix2sky(coord, 1)
                ras = res[:, 0]
                decs = res[:, 1]
            pass

            print("Center is (%s,%s) pixel, (%s,%s) sky" % (xx, yy, xc, yc))

            #Cannot deal with fractional pixel
            if (xx - int(xx) >= 1e-4):
                print("Approximating the X pixel: %s -> %s" % (xx, int(xx)))
                xx = int(xx)
            if (yy - int(yy) >= 1e-4):
                print("Approximating the Y pixel: %s -> %s" % (yy, int(yy)))
                yy = int(yy)
            pass

            #Now select the pixels to keep
            #Pre-select according to a bounding box
            #(huge gain of speed in the computation of distances)
            ra_min_, ra_max_, dec_min_, dec_max_, pole = getBoundingCoordinates(
                xc, yc, radius)

            if (pole):
                #Nothing we can really do, except masking out (zeroing) all the useless parts
                print(
                    "\nOne of the poles is within the region. Cannot cut the image. I will zero-out useless parts"
                )
                img = f[0].data

                #Find the pixel corresponding to (xc,yc-radius)
                coord = numpy.array([[xc], [yc - radius], [1]]).T
                res = wcs.wcs_sky2pix(coord, 0)[0]
                mask_ymax = int(numpy.ceil(res[1]))

                #Now find the pixel corresponding to (xc,yc+radius)
                coord = numpy.array([[xc], [yc + radius - 180.0], [1]]).T
                res = wcs.wcs_sky2pix(coord, 0)[0]
                mask_ymin = int(numpy.floor(res[1]))

                img[:,
                    mask_ymin:mask_ymax, :] = img[:,
                                                  mask_ymin:mask_ymax, :] * 0.0

            else:
                if (ra_min_ > ra_max_):
                    #Circular inversion (ex: ra_min_ = 340.0 and ra_max_ = 20.0)
                    idx = (ra_min_ <= ras) | (ras <= ra_max_)
                else:
                    idx = (ra_min_ <= ras) & (ras <= ra_max_)
                pass

                if (dec_min_ > dec_max_):
                    #Circular inversion (ex: ra_min_ = 340.0 and ra_max_ = 20.0)
                    idx = ((dec_min_ <= decs) | (decs <= dec_max_)) & idx
                else:
                    idx = ((dec_min_ <= decs) & (decs <= dec_max_)) & idx
                pass

                ras = ras[idx]
                decs = decs[idx]

                #Compute all angular distances of remaining pixels
                distances = getAngularDistance(xc, yc, ras, decs)

                #Select all pixels within the provided radius
                idx = (distances <= radius)
                selected_ras = ras[idx]
                selected_decs = decs[idx]

                #Now transform back into pixels values
                if (isCube):

                    coord = numpy.vstack([
                        selected_ras, selected_decs,
                        [1] * selected_ras.shape[0]
                    ]).T

                else:

                    coord = numpy.vstack([selected_ras, selected_decs]).T

                pass

                res = wcs.wcs_sky2pix(coord, 0)

                #Now check if the range of x is not continuous (i.e., we are
                #wrapping around the borders)
                uniquex = numpy.unique(res[:, 0])
                deltas = uniquex[1:] - uniquex[:-1]
                if (deltas.max() > 1):
                    #We are wrapping around the borders
                    # |-------x1             x2-------|
                    #We want to express x2 as a negative index starting
                    #from the right border, and set it as xmin.
                    #Then we set x1 as xmax.
                    #This way the .take method below will start accumulating
                    #the image from x2 to the right border |, then from the left
                    #border | to x1, in this order
                    #Find x2
                    x2id = deltas.argmax() + 1
                    x2 = int(uniquex[x2id])
                    x1 = int(uniquex[x2id - 1])
                    xmin = x2 - shapex
                    xmax = x1

                    ymin, ymax = (int(res[:, 1].min()), int(res[:, 1].max()))

                else:

                    xmin, xmax, ymin, ymax = (int(res[:, 0].min()),
                                              int(res[:, 0].max()),
                                              int(res[:, 1].min()),
                                              int(res[:, 1].max()))

                pass

                print("X range -> %s - %s" % (xmin, xmax))
                print("Y range -> %s - %s" % (ymin, ymax))
                print("Input image shape is ([z],y,x) = %s" %
                      (str(f[0].shape)))

                #Using the mode='wrap' option we wrap around the edges of the image,
                #if ymin is negative
                if (isCube):

                    img = f[0].data.take(range(ymin, ymax),
                                         mode='wrap',
                                         axis=1).take(range(xmin, xmax),
                                                      mode='wrap',
                                                      axis=2)

                else:

                    img = f[0].data.take(range(ymin, ymax),
                                         mode='wrap',
                                         axis=0).take(range(xmin, xmax),
                                                      mode='wrap',
                                                      axis=1)

                pass

                #Put the origin of the projection in the right place
                #in the new image
                head['CRPIX1'] -= xmin
                head['CRPIX2'] -= ymin

                #Update the length of the axis
                head['NAXIS1'] = int(xmax - xmin)
                head['NAXIS2'] = int(ymax - ymin)

                if head.get('NAXIS1') == 0 or head.get('NAXIS2') == 0:
                    raise ValueError("Map has a 0 dimension: %i,%i." %
                                     (head.get('NAXIS1'), head.get('NAXIS2')))
            pass

            newfile = pyfits.PrimaryHDU(data=img, header=head)

            newfile.writeto(outfile, clobber=clobber)
            #Append the other extension, if present
            for i in range(1, len(f)):
                pyfits.append(outfile, f[i].data, header=f[i].header)

        pass  #Close the input file

        #Now re-open the output file and fix the wcs
        #by moving the reference pixel to the 1,1 pixel
        #This guarantee that no pixel will be at a distance larger than 180 deg
        #from the reference pixel, which would confuse downstream software
        if (not pole):
            with pyfits.open(outfile, 'update') as outf:
                head = outf[0].header
                #Get the
                newwcs = pywcs.WCS(head)

                #Find the sky coordinates of the 1,1 pixel
                if (isCube):
                    #Data cube
                    coord = numpy.array([[1], [1], [1]]).T
                    sx, sy, z = newwcs.wcs_pix2sky(coord, 1)[0]
                else:
                    #Normal image
                    coord = numpy.array([[1], [1]]).T
                    sx, sy = newwcs.wcs_pix2sky(coord, 1)[0]
                pass

                head['CRPIX1'] = 1
                head['CRVAL1'] = sx

        pass
Esempio n. 9
0
    def getXmlForSourcesInTheROI(self, ra, dec, rad, output, exposure):
        # Loop the tree and remove all sources more than rad away from the center
        # of the ROI
        root = self.tree.getroot()
        srcs = 0
        for source in root.findall('source'):
            spatialModel = source.findall('spatialModel')[0]

            # Remove point sources which cannot contribute any photon given the exposure
            aeff = 0.6e4  # cm2

            if (source.get('type') == 'PointSource'):

                try:

                    npred = float(source.get('Flux1000')) * exposure * aeff

                except TypeError:

                    # This is not a 3FGL source, so it has no Flux1000 attribute. Keep it

                    continue

                if npred < 0.1:
                    root.remove(source)
                    continue

            if (source.get('type') == 'PointSource'):
                # Get coordinates of this point source
                coords = {}
                for p in spatialModel.iter('parameter'):
                    coords[p.get('name').lower()] = float(p.get('value'))
                pass
                thisRa = coords['ra']
                thisDec = coords['dec']

                thisDist = getAngularDistance(ra, dec, thisRa, thisDec)

                # Remove the source if the distance is above the requested radius,
                # or if the distance is below 0.01 (i.e., the source under analysis
                # is the same as the current one)

                if (float(thisDist) >= float(rad)):
                    # Remove this source
                    root.remove(source)
                elif (float(thisDist) <= 0.01):
                    print("\nWARNING: Auto-removed source %s\n" %
                          (source.get('name')))
                    root.remove(source)
                else:
                    print("Keeping point source %s (%4.2f deg away)..." %
                          (source.get('name'), float(thisDist)))
                    # Fix all parameters
                    specModel = source.findall('spectrum')[0]
                    for p in specModel.findall('parameter'):
                        p.set('free', '0')
                    pass
                    srcs += 1
            elif (source.get('type') == 'DiffuseSource'):
                # Get coordinates of the center of this diffuse source

                try:

                    thisRa = float(source.get('RA'))
                    thisDec = float(source.get('DEC'))

                except TypeError:

                    # This is not a 3FGL source, keep it and continue

                    continue

                thisDist = getAngularDistance(ra, dec, thisRa, thisDec)

                # Remove source if its center is more than twice its size out of the ROI
                if (float(thisDist) >=
                        float(rad) + 2 * float(source.get('Extension'))):
                    root.remove(source)
                else:
                    # Fix all parameters
                    specModel = source.findall('spectrum')[0]
                    for p in specModel.findall('parameter'):
                        p.set('free', '0')
                    pass
                    # Now correct the name of the FITS template so that the likelihood
                    # will find it
                    spatialModel = source.findall('spatialModel')[0]
                    filename = spatialModel.get('file')
                    templatesPath = os.path.join(
                        os.path.join(getDataPath(), 'templates'))
                    newFilename = os.path.abspath(
                        os.path.join(templatesPath, filename))
                    spatialModel.set('file', '%s' % newFilename)
                    srcs += 1
                    print(
                        "Keeping diffuse source %s (%4.2f deg away) using template %s..."
                        % (source.get('name'), float(thisDist), newFilename))
            else:
                print("WTF")
                raise
        pass
        print("Kept %s point sources from the FGL catalog" % (srcs))
        self.tree.write(output)
Esempio n. 10
0
    def getXmlForSourcesInTheROI(self, ra, dec, rad, output, exposure):
        # Loop the tree and remove all sources more than rad away from the center
        # of the ROI
        root = self.tree.getroot()
        srcs = 0
        for source in root.findall('source'):
            spatialModel = source.findall('spatialModel')[0]

            # Remove point sources which cannot contribute any photon given the exposure
            aeff = 0.6e4  # cm2

            if (source.get('type') == 'PointSource'):

                try:

                    npred = float(source.get('Flux1000')) * exposure * aeff

                except TypeError:

                    # This is not a 3FGL source, so it has no Flux1000 attribute. Keep it

                    continue

                if npred < 0.1:
                    root.remove(source)
                    continue

            if (source.get('type') == 'PointSource'):
                # Get coordinates of this point source
                coords = {}
                for p in spatialModel.iter('parameter'):
                    coords[p.get('name').lower()] = float(p.get('value'))
                pass
                thisRa = coords['ra']
                thisDec = coords['dec']

                thisDist = getAngularDistance(ra, dec, thisRa, thisDec)

                # Remove the source if the distance is above the requested radius,
                # or if the distance is below 0.01 (i.e., the source under analysis
                # is the same as the current one)

                if (float(thisDist) >= float(rad)):
                    # Remove this source
                    root.remove(source)
                elif (float(thisDist) <= 0.01):
                    print("\nWARNING: Auto-removed source %s\n" % (source.get('name')))
                    root.remove(source)
                else:
                    print("Keeping point source %s (%4.2f deg away)..." % (source.get('name'), float(thisDist)))
                    # Fix all parameters
                    specModel = source.findall('spectrum')[0]
                    for p in specModel.findall('parameter'):
                        p.set('free', '0')
                    pass
                    srcs += 1
            elif (source.get('type') == 'DiffuseSource'):
                # Get coordinates of the center of this diffuse source

                try:

                    thisRa = float(source.get('RA'))
                    thisDec = float(source.get('DEC'))

                except TypeError:

                    # This is not a 3FGL source, keep it and continue

                    continue

                thisDist = getAngularDistance(ra, dec, thisRa, thisDec)

                # Remove source if its center is more than twice its size out of the ROI
                if (float(thisDist) >= float(rad) + 2 * float(source.get('Extension'))):
                    root.remove(source)
                else:
                    # Fix all parameters
                    specModel = source.findall('spectrum')[0]
                    for p in specModel.findall('parameter'):
                        p.set('free', '0')
                    pass
                    # Now correct the name of the FITS template so that the likelihood
                    # will find it
                    spatialModel = source.findall('spatialModel')[0]
                    filename = spatialModel.get('file')
                    templatesPath = os.path.join(os.path.join(getDataPath(), 'templates'))
                    newFilename = os.path.abspath(os.path.join(templatesPath, filename))
                    spatialModel.set('file', '%s' % newFilename)
                    srcs += 1
                    print("Keeping diffuse source %s (%4.2f deg away) using template %s..." % (
                    source.get('name'), float(thisDist), newFilename))
            else:
                print("WTF")
                raise
        pass
        print("Kept %s point sources from the FGL catalog" % (srcs))
        self.tree.write(output)
Esempio n. 11
0
def run(**kwargs):
  if(len(kwargs.keys())==0):
    #Nothing specified, the user needs just help!
    thisCommand.getHelp()
    return
  pass
  
  #Get parameters values
  thisCommand.setParValuesFromDictionary(kwargs)
  try:
    eventfile                   = thisCommand.getParValue('filteredeventfile')
    rspfile                     = thisCommand.getParValue('rspfile')
    ft2file                     = thisCommand.getParValue('ft2file')
    expomap                     = thisCommand.getParValue('expomap')
    ltcube                      = thisCommand.getParValue('ltcube')
    xmlmodel                    = thisCommand.getParValue('xmlmodel')
    showmodelimage              = thisCommand.getParValue('showmodelimage')
    optimize                    = thisCommand.getParValue('optimizeposition')
    spectralfiles               = thisCommand.getParValue('spectralfiles')
    tsmin                       = float(thisCommand.getParValue('tsmin'))
    skymap                      = thisCommand.getParValue('skymap')
    liketype                    = thisCommand.getParValue('liketype')
    clobber                     = _yesOrNoToBool(thisCommand.getParValue('clobber'))
    verbose                     = _yesOrNoToBool(thisCommand.getParValue('verbose'))
    flemin                      = thisCommand.getParValue('flemin')
    flemax                      = thisCommand.getParValue('flemax')
    clul                        = float(thisCommand.getParValue('clul'))
    
    figure                      = thisCommand.getParValue('figure')
  except KeyError as err:
    print("\n\nERROR: Parameter %s not found or incorrect! \n\n" %(err.args[0]))
    
    #Print help
    print thisCommand.getHelp()
    return
  pass
  
  assert clul < 1.0, "The confidence level for the upper limit (clul) must be < 1"
  
  from GtBurst import dataHandling
  from GtBurst.angularDistance import getAngularDistance
  
  LATdata                     = dataHandling.LATData(eventfile,rspfile,ft2file)
  try:
    if(liketype=='unbinned'):
      outfilelike, sources        = LATdata.doUnbinnedLikelihoodAnalysis(xmlmodel,tsmin,expomap=expomap,ltcube=ltcube,emin=flemin,emax=flemax, clul=clul)
    else:
      #Generation of spectral files and optimization of the position is
      #not supported yet for binned analysis
      
      if(spectralfiles=='yes'):
      
        print("\nWARNING: you specified spectralfiles=yes, but the generation of spectral files is not supported for binned analysis\n")
        spectralfiles               = 'no'
      
      if(optimize=='yes'):
      
        print("\nWARNING: you specified optimize=yes, but position optimization is not supported for binned analysis\n") 
        optimize                    = 'no'
      
      outfilelike, sources        = LATdata.doBinnedLikelihoodAnalysis(xmlmodel,tsmin,expomap=expomap,ltcube=ltcube,emin=flemin,emax=flemax, clul=clul)
  except GtBurstException as gt:
    raise gt
  except:
    raise
  
  #Transfer information on the source from the input to the output XML
  irf                         = dataHandling._getParamFromXML(xmlmodel,'IRF')
  ra                          = dataHandling._getParamFromXML(xmlmodel,'RA')
  dec                         = dataHandling._getParamFromXML(xmlmodel,'DEC')
  name                        = dataHandling._getParamFromXML(xmlmodel,'OBJECT')
  
  try:
    grb                         = filter(lambda x:x.name.lower().find(name.lower())>=0,sources)[0]
    grb_TS                      = grb.TS
  except:
    #A model without GRB
    print("\nWarning: no GRB in the model!")
    grb_TS                      = -1
  pass
  
  if(irf is None):
    print("\n\nWARNING: could not read IRF from XML file. Be sure you know what you are doing...")
  else:
    dataHandling._writeParamIntoXML(outfilelike,IRF=irf,OBJECT=name,RA=ra,DEC=dec)
  pass

  
  if(spectralfiles=='yes'):
    phafile,rspfile,bakfile   = LATdata.doSpectralFiles(outfilelike)
  pass
  
  localizationMessage         = ''
  bestra                      = ''
  bestdec                     = ''
  poserr                      = ''
  distance                    = ''
  if(optimize=='yes'):
    sourceName                = name
    
    #If the TS for the source is above tsmin, optimize its position
    #grb                       = filter(lambda x:x.name.lower().find(sourceName.lower())>=0,sources)[0]
    if(math.ceil(grb_TS) >= tsmin):
      try:
        bestra,bestdec,poserr = LATdata.optimizeSourcePosition(outfilelike,sourceName)
      except:
        raise GtBurstException(207,"gtfindsrc execution failed. Were the source detected in the likelihood step?")
      else:
        localizationMessage += "\nNew localization from gtfindsrc:\n\n"
        localizationMessage += "(R.A., Dec)                     = (%6.3f, %6.3f)\n" %(bestra,bestdec)
        localizationMessage += "68 %s containment radius        = %6.3f\n" %('%',poserr)
        localizationMessage += "90 %s containment radius        = %6.3f\n" %('%',1.41*poserr)
        distance             = getAngularDistance(float(ra),float(dec),float(bestra),float(bestdec))
        localizationMessage += "Distance from initial position  = %6.3f\n\n" %(distance)
        localizationMessage += "NOTE: this new localization WILL NOT be used by default. If you judge"
        localizationMessage += " it is a better localization than the one you started with, update the"
        localizationMessage += " coordinates yourself and re-run the likelihood\n"
    pass
  pass
  
  if(figure is not None and skymap is not None and showmodelimage=='yes'):
    
    #Now produce the binned exposure map (needed in order to display the fitted model as an image)
    modelmapfile              = LATdata.makeModelSkyMap(outfilelike) 
    
    #Display point sources in the image, and report in the table
    #all 3FGL sources with TS > 9 + always the GRB, independently of its TS
    detectedSources           = []
    grbFlux                   = 1e-13
    for src in sources:
      weight                  = 'bold'
      
      if(src.type=='PointSource'):
        if(src.TS > 4):
          detectedSources.append(src)
          if(src.name.find('3FGL')<0):
            #GRB
            grbFlux           = src.flux
        pass
      pass
    pass
    
    #Display the counts map
    from GtBurst import aplpy
    import matplotlib.pyplot as plt
    
    figure.clear()
    orig                     = aplpy.FITSFigure(skymap,convention='calabretta',
                                                figure=figure,subplot=[0.1,0.1,0.45,0.7])
    vmax                     = max(pyfits.open(skymap)[0].data.flatten())
    nEvents                  = numpy.sum(pyfits.open(skymap)[0].data)
    telapsed                 = pyfits.open(eventfile)[0].header['TSTOP']-pyfits.open(eventfile)[0].header['TSTART']
    orig.set_tick_labels_font(size='small')
    orig.set_axis_labels_font(size='small')
    orig.show_colorscale(cmap='gist_heat',vmin=0.1,vmax=max(vmax,0.11),stretch='log',aspect='auto')
    # Modify the tick labels for precision and format
    orig.tick_labels.set_xformat('ddd.dd')
    orig.tick_labels.set_yformat('ddd.dd')
    
    # Display a grid and tweak the properties
    orig.show_grid()
    
    #Renormalize the modelmapfile to the flux of the grb
    f                              = pyfits.open(modelmapfile,'update')
    f[0].data                      = f[0].data/numpy.max(f[0].data)*nEvents/telapsed
    print(numpy.max(f[0].data))
    f.close()
    
    img                      = aplpy.FITSFigure(modelmapfile,convention='calabretta',
                                                figure=figure,subplot=[0.55,0.1,0.4,0.7])
    img.set_tick_labels_font(size='small')
    img.set_axis_labels_font(size='small')
    #vmax                     = max(pyfits.open(modelmapfile)[0].data.flatten())
    img.show_colorscale(cmap='gist_heat',aspect='auto',stretch='log') 
    
    for src in detectedSources:
      img.add_label(float(src.ra),float(src.dec),
                    "%s\n(ts = %i)" %(src.name,int(math.ceil(src.TS))),
                    relative=False,weight=weight,
                    color='green', size='small')
    pass
    
    # Modify the tick labels for precision and format
    img.tick_labels.set_xformat('ddd.dd')
    img.tick_labels.set_yformat('ddd.dd')
    
    # Display a grid and tweak the properties
    img.show_grid()
    
    #ax                        = figure.add_axes([0.1,0.72,0.85,0.25],frame_on=False)
    #ax.xaxis.set_visible(False) 
    #ax.yaxis.set_visible(False)
    #col_labels                =['Source Name','TS','Energy flux','Photon index']
    #table_vals                = map(lambda x:[x.name,"%i" %(int(math.ceil(x.TS))),
    #                                          "%s +/- %s" % (x.flux,x.fluxError),
    #                                          "%s +/- %s" % (x.photonIndex,x.photonIndexError)],detectedSources)
    #
    #if(len(table_vals)>0):
    #  the_table                 = ax.table(cellText=table_vals,
    #                                        colLabels=col_labels,
    #                                       loc='upper center')
    
    figure.canvas.draw()
    figure.savefig("likelihood_results.png")
  pass
  
  if(figure is not None):
        
    #Assume we have an X server running
    #Now display the results
    likemsg = "Log(likelihood) = %s" %(LATdata.logL)
    displayResults(figure.canvas._tkcanvas, LATdata.resultsStrings + "\n" + likemsg + "\n" + localizationMessage)
  
  print(localizationMessage)
  
  return 'likexmlresults', outfilelike, 'TS', grb_TS, 'bestra', bestra, 'bestdec', bestdec, 'poserr', poserr, 'distance', distance,'sources', sources