Beispiel #1
0
 def plec():
     index, a, b = ce.PLEC_Index, ce.PLEC_Expfactor, ce.PLEC_Exp_Index
     cutoff = (1 / a)**(1 / b)
     prefactor = flux * np.exp(a * pivot**b)
     return Models.PLSuperExpCutoff(p=[prefactor, index, cutoff, b],
                                    e0=pivot,
                                    free=free)
Beispiel #2
0
    def lookup(self, name):
        """ return an ExtendedSource object by name, None if not found """
        aname = self.alias.get(name,name) #alias will be the new name
        try:
            i = list(self.names).index(name)
        except ValueError:
            return None
        source = self.sources[i]
        # make a new object copied from original
        if source.model.name=='BrokenPowerLaw': #convert this
            model = Models.LogParabola()
        else: model = source.model
        if model.name=='LogParabola': 
           model.free[-1]=False # E_break ne free

        ### seems to be necessary for some models created from 
        if model.mappers[0].__class__.__name__== 'LimitMapper':
            print 'wrong mappers: converting model for source %s, model %s' % (name, model.name)
            model = eval('Models.%s(p=%s)' % (model.name, list(model.get_all_parameters())))
        extsource = sources.ExtendedSource(name=self.realname(aname), 
            skydir=source.skydir,
            model = model, 
            dmodel= source.spatial_model
            )
        if extsource.model.name=='LogParabola': 
            assert sum( extsource.model.free)<4, 'E_break is free?'
        return extsource  
Beispiel #3
0
def fit_isotropic(roi, nbands=8, folder='isotropic_fit'):
    """ fit only the front and back"""
    from uw.like import Models
    iso_source = roi.get_source('isotrop')
    old_model=iso_source.model.copy()
    roi.sources.set_model(Models.FrontBackConstant(), 'isotrop')
    iso_model=iso_source.model
    roi.reinitialize()

    cx = []
    for eband in range(nbands):
        print '*** Energy Band {}: iso counts {}'.format( eband,
                                [t[1].counts.round() for t in roi[2*eband:2*eband+2]])
        roi.select(eband)
        iso_model[0]=1; iso_model[1]=1
        roi.fit([0,1]); 
        u = iso_model.get_all_parameters();
        cx.append(u)
    roi.select()
    roi.sources.set_model(old_model)
    if folder is not None:
        if not os.path.exists(folder): os.mkdir(folder)
        filename= '{}/{}.pickle'.format(folder, roi.name)
        pickle.dump(np.array(cx), open(filename, 'w'))
        print 'wrote file {}'.format(filename)
    return np.array(cx)
Beispiel #4
0
    def __init__(self, cat_entry):
        """return a Pandas.DataFrame for the band flux information
        cat_entry: pandas.Series object
        
        Adds columns with conversion to differential energy flux, in eV units
        """
        cols = 'Flux Unc_Flux Index Npred Sqrt_TS'.split()
        t = [cat_entry[cname + '_Band'] for cname in cols]
        bf = pd.DataFrame(t, index=cols).T

        # add columns with energy flux
        # evaluate energy flux = e**2 * df/de at geometric mean, assuming powerlaw
        # convert to units eV/(cm**2 * s)
        eb = energy_bounds
        r = BandFlux.conversion_factors(eb.LowerEnergy, eb.UpperEnergy,
                                        bf.Index)
        bf['eflux'] = bf.Flux * r
        bf['eflux_unc'] = (bf.Unc_Flux) * r
        self.bf = bf
        # construct the spectral model object if info is there
        # TODO: deal with exponential
        s = cat_entry
        #self.name = cat_entry['Source_Name']
        self.model = None
        self.nickname = cat_entry['NickName']
        if 'Flux_Density' in cat_entry:
            if s['SpectrumType'] == 'LogParabola':
                self.model = Models.LogParabola(
                    [
                        s['Flux_Density'], s['Spectral_Index'], s['beta'],
                        s['Pivot_Energy']
                    ],
                    free=[True, True, False, False])
Beispiel #5
0
    def __init__(self, roi, nbands, folder):
        """ fit the front and back"""
        from uw.like import Models
        iso_source = roi.get_source('isotrop')
        old_model = iso_source.model.copy()
        roi.sources.set_model(Models.FrontBackConstant(), 'isotrop')
        iso_model = iso_source.model
        roi.reinitialize()

        cx = []
        dx = []
        for eband in range(nbands):
            roi.select(eband)
            print '*** Energy Band {}: iso counts {}'.format(
                eband, [t[1].counts.round() for t in roi.selected])

            iso_model[0] = 1
            iso_model[1] = 1
            n = len(roi.selected)
            roi.fit(range(n))
            u = iso_model.get_all_parameters()
            du = np.array([iso_model.error(i) for i in range(2)])

            cx.append(u)
            dx.append(du)
        roi.select()
        roi.sources.set_model(old_model)
        if folder is not None:
            if not os.path.exists(folder): os.mkdir(folder)
            filename = '{}/{}.pickle'.format(folder, roi.name)
            pickle.dump(dict(val=cx, err=dx), open(filename, 'w'))
            print 'wrote file {}'.format(filename)
        self.val = cx
        self.err = dx
Beispiel #6
0
 def __call__(self, s):
     sdir = s.skydir
     if hasattr(s, 'spatial_model') and s.spatial_model is not None:
         return True
     for i, t in enumerate(self.sdir):
         dist = np.degrees(t.difference(sdir))
         if dist < self.tol and s.ts > self.ts_min:
             self.tags[i] = True
             self.assoc[i] = (s.name, dist, s.ts)
             if self.rename and s.name != self.psr_names[i]:
                 print 'Skymodel: renaming %s(%d) to %s' % (
                     s.name, s.index, self.psr_names[i])
                 s.name = self.psr_names[i]
             if s.model.name == 'ExpCutoff': return True
             flux = s.model[0]
             if flux > 1e-18:
                 print 'Skymodel: replacing model for: %s(%d): pulsar name: %s' % (
                     s.name, s.index, self.psr_names[i])
                 s.model = Models.ExpCutoff()
                 s.free = s.model.free.copy()
             else:
                 print 'Apparent pulsar %s(%d), %s, is very weak, flux=%.2e <1e-13: leave as powerlaw' % (
                     s.name, s.index, self.psr_names[i], flux)
             return True
     if s.model.name == 'ExpCutoff':
         print 'Skymodel setup warning: %s (%d) not in LAT pulsar list, should not be expcutoff' % (
             s.name, s.index)
     return True
Beispiel #7
0
 def model(st, flux, index, beta, pivot, cutoff, b):
     if st == 'PowerLaw':
         return Models.PowerLaw(p=[flux, index], e0=pivot)
     elif st == 'PLSuperExpCutoff':
         prefactor = flux * np.exp((pivot / cutoff)**b)
         return Models.PLSuperExpCutoff(p=[prefactor, index, cutoff, b],
                                        e0=pivot)
     elif st == 'PLExpCutoff':
         prefactor = flux * np.exp((pivot / cutoff))
         return Models.PLSuperExpCutoff(
             p=[prefactor, index, cutoff, 1.0], e0=pivot)
     elif st == 'LogParabola':
         return Models.LogParabola(p=[flux, index, beta, pivot])
     elif st == 'PowerLaw2':  ### same as PowerLaw in table
         return Models.PowerLaw(p=[flux, index], e0=pivot)
     else:
         raise Exception(
             'unexpected spectrum type {}, source name {}'.format(
                 st, name))
Beispiel #8
0
def pmodel(source):
    """ create a pointlike model from a Series object from DataFrame row
    """
    expandbits = lambda x: [(x & 2**i) != 0 for i in range(4)]

    modelname, freebits, e0, norm, norm_unc, pindex, pindex_unc, index2,index2_unc, cutoff, cutoff_unc=\
        [source[x] for x in 'modelname freebits e0 flux flux_unc pindex pindex_unc index2 index2_unc cutoff cutoff_unc'.split()]
    free = expandbits(freebits)
    errors = [norm_unc, pindex_unc]
    if modelname == 'LogParabola':
        if np.abs(index2) < 2e-3:
            modelname = 'PowerLaw'
            model = Models.PowerLaw(p=[norm, pindex], e0=e0)
        else:
            # if index2<0:
            #     print  'Source %s has beta (%.2f) <0: setting to 0.' % (  source.name, index2, )
            #     index2=0
            model = Models.LogParabola(p=[norm, pindex, index2, e0])
            model.free[-1] = False
            errors.append(index2_unc)
    elif modelname == 'PLSuperExpCutoff':
        prefactor = np.exp(-(e0 / cutoff)**index2)
        model = Models.PLSuperExpCutoff(
            p=[norm / prefactor, pindex, cutoff, index2], e0=e0)
        errors[0] /= prefactor
        errors += [cutoff_unc, index2_unc]
    elif modelname == 'ExpCutoff':
        prefactor = np.exp(-(e0 / cutoff))
        model = Models.PLSuperExpCutoff(
            p=[norm / prefactor, pindex, cutoff, 0.], e0=e0)
        model.free[3] == False
        errors[0] /= prefactor
        errors += [cutoff_unc]
    else:
        raise Exception('model "%s" not recognized' % modelname)
    map(model.set_error, range(len(errors)), errors)
    model.free[:] = free[:model.len()]
    return model
Beispiel #9
0
def fit_diffuse(roi, nbands=8, select=[0,1,2], restore=False, folder='diffuse_fit'):
    """
    Perform indpendent fits to the gal, iso_front, and iso_back for each of the first nbands bands
    select: None or list of variables
    """
    from uw.like import Models
    # freeze all free sources, thaw gal and iso
    roi.thaw('Norm', 'ring')
    iso_model =roi.sources.find_source('isotrop').model.copy()
    roi.sources.set_model(Models.FrontBackConstant(), 'isotrop')
    roi.reinitialize()
    
    # do the fitting
    dpars=[]
    energies = []
    for ie in range(nbands):
        roi.select(ie); 
        roi.fit(select, ignore_exception=True)
        energies.append(int(roi.energies[0]))
        dpars.append( roi.sources.parameters.get_parameters()[:3])
    t =np.power(10, dpars)
    df = pd.DataFrame(t, columns=['gal iso_front iso_back'.split()])
    df.index=energies
    
    if restore:
        # does not seem to work, comment this out for now
        # restore sources
        roi.sources.diffuse_normalization *= df
        for s,f in zip(free_sources, saved_free):
            s.model.free=f
        roi.sources.find_source('ring').model.free[0]=False
        roi.sources.set_model(iso_model, 'isotrop')
        roi.reinitialize()
        roi.select()
        roi.fit() # needed to restore gradient, at least.
        
        # update the pickle file
        write_pickle(roi)
    elif folder is not None:
        # simply save results
        if not os.path.exists(folder):
            os.mkdir(folder)
        filename= '{}/{}.pickle'.format(folder, roi.name)
        pickle.dump(df, open(filename, 'w'))
        print 'wrote file {}'.format(filename)
    return df
Beispiel #10
0
 def lp():
     index, beta = ce.LP_Index, ce.LP_beta
     return Models.LogParabola(p=[flux, index, beta, pivot],
                               free=free)
Beispiel #11
0
def ExpCutoff(*pars):
    model = Models.ExpCutoff(p=pars, free=[True, True, False])
    return model
Beispiel #12
0
def PLSuperExpCutoff(*pars):
    model = Models.PLSuperExpCutoff(p=pars, free=[True, True, False, False])
    return model
Beispiel #13
0
def ExpCutoff(*pars):
    model = Models.ExpCutoff(p=pars, free=[True, True, False])
    sources.set_default_bounds(model)
    return model
Beispiel #14
0
def PLSuperExpCutoff(*pars):
    model = Models.PLSuperExpCutoff(p=pars, free={True, True, False, False})
    sources.set_default_bounds(model)
    return model
Beispiel #15
0
def LogParabola(*pars):
    model = Models.LogParabola(p=pars, free=[True, True, False, False])
    sources.set_default_bounds(model)
    return model
Beispiel #16
0
def PowerLaw(*pars):
    model = Models.PowerLaw(p=pars)
    sources.set_default_bounds(model)
    return model
Beispiel #17
0
def LogParabola(*pars, **kw):
    m = Models.LogParabola(p=pars, **kw)
    m.free[3] = False
    return m
Beispiel #18
0
def PowerLaw(*pars):
    model = Models.PowerLaw(p=pars)
    return model
Beispiel #19
0
def FBconstant(f, b, **kw):
    return Models.FrontBackConstant(f, b, **kw)
Beispiel #20
0
def Constant(*pars, **kw):
    return Models.Constant(p=pars, **kw)
Beispiel #21
0
def PLSuperExpCutoff(*pars, **kw):
    return Models.PLSuperExpCutoff(p=pars, **kw)
Beispiel #22
0
def ExpCutoff(*pars, **kw):
    return Models.ExpCutoff(p=pars, **kw)
Beispiel #23
0
def PowerLaw(*pars, **kw):
    return Models.PowerLaw(p=pars, **kw)
Beispiel #24
0
def PSR_default():
    return Models.PLSuperExpCutoff(p=(1e-13, 1.25, 1500, 0.67),
                                   free=[True, True, True, False])
Beispiel #25
0
def LogParabola(*pars):
    model = Models.LogParabola(p=pars, free=[True, True, False, False])
    return model
Beispiel #26
0
 def pl():
     index, beta = ce.PL_Index, 0
     return Models.LogParabola(p=[flux, index, beta, pivot],
                               free=free)
Beispiel #27
0
    def load_auxcat(self, tol=0.2):
        """ modify the list of pointsources from entries in the auxcat: for now:
            * add it not there
            * move there, at new ra,dec
            * remove if ra<0
        
        """
        if self.auxcat is None or self.auxcat == '':
            return
        cat = self.auxcat
        if not os.path.exists(cat):
            cat = os.path.expandvars(os.path.join('$FERMI', 'catalog', cat))
        if not os.path.exists(cat):
            cat = os.path.join(self.folder, self.auxcat)
        if not os.path.exists(cat):
            raise Exception(
                'auxilliary source catalog "%s" not found locally (%s) or in $FERMI/catalog'
                % (self.auxcat, self.folder))
        ext = os.path.splitext(cat)[-1]
        if ext == '.pickle':
            ss = pd.load(cat).itertuples()
            dataframe = True
            print 'loading auxcat from DataFrame'
        elif ext == '.csv':
            cc = pd.read_csv(cat)
            cols = list(cc.columns)
            ss = cc.itertuples()
            i_eflux = cols.index('eflux') + 1
            i_pindex = cols.index('pindex') + 1
            i_e0 = cols.index('e0') + 1
            dataframe = True
            print 'loading auxcat from csv'
        else:
            ss = makerec.load(cat)
            dataframe = False
        names = [s.name for s in self.point_sources]
        sdirs = [s.skydir for s in self.point_sources]

        def check_near(sdir):
            closest = np.degrees(np.min(np.array(map(sdir.difference, sdirs))))
            return closest

        toremove = []
        print 'process auxcat %s' % cat
        for s in ss:
            if dataframe:
                # from csv: construct full model from parameters
                sname, sra, sdec = s[1:4]
                n0 = s[i_eflux] / (s[i_e0]**2 * 1e6)
                model = Models.LogParabola(p=[n0, s[i_pindex], 0., s[i_e0]])
                model.free[2:] = False
            else:  # for comatibility: default from pater
                sname, sra, sdec = s.name, s.ra, s.dec
                model = self.newmodel
                if type(self.newmodel) == types.StringType:
                    model = eval(self.newmodel)
                elif model is None:
                    pass
                else:
                    model = self.newmodel.copy(
                    )  # make sure to get a new object
            if not sname.startswith('SEED'):  # allow underscores
                sname = sname.replace('_', ' ')
            if sname not in names:
                skydir = SkyDir(float(sra), float(sdec))
                close = check_near(skydir)
                if close < tol:
                    print '\tsource %s close to another source, reject' % sname
                    continue
                index = self.hpindex(skydir)
                if model is not None:
                    model.free[
                        0] = True  # must have at least one free parameter to be set up properly in an ROI
                self.point_sources.append(
                    sources.PointSource(name=sname,
                                        skydir=skydir,
                                        index=index,
                                        model=model))
                print '\tadded new source %s at ROI %d (%.1f deg )' % (
                    sname, index, close)
            else:
                print '\t source %s is in the model:' % sname,  # will remove if ra<0' % sname
                ps = self.point_sources[names.index(sname)]
                if float(sra) <= 0:
                    toremove.append(ps)
                    print ' removed.'
                else:
                    newskydir = SkyDir(float(sra), float(sdec))
                    print 'moved from %s to %s' % (ps.skydir, newskydir)
                    ps.skydir = newskydir
        for ps in toremove:
            self.point_sources.remove(ps)