Example #1
0
    def __init__(self,**kwargs):

        keyword_options.process(self, kwargs)

        if self.binfile is None: raise PointlikeException("binfile must be specified.")
        if self.ltcube is None: raise PointlikeException("ltcube must be specified.")
            
        self.binfile = path.expand(self.binfile)
        self.ltcube = path.expand(self.ltcube)

        if self.ft1files is None and not os.path.exists(self.binfile):
            raise PointlikeException('An FT1 file must be specified if the binfile does not exist.')

        ltfile_exists = self.ltcube is not None and os.path.exists(self.ltcube)
        if self.ft2files is None and not ltfile_exists:
            raise PointlikeException('No FT2 or livetime file provided! Must pass at least one of these.')

        # If string, expand it out
        if isinstance(self.ft1files,types.StringType):
            self.ft1files = [path.expand(self.ft1files)]
        elif self.ft1files is None:
            pass
        else:
            self.ft1files = map(path.expand,self.ft1files)

        if isinstance(self.ft2files,types.StringType):
            self.ft2files = [path.expand(self.ft2files)]
        elif self.ft2files is None:
            pass
        else:
            self.ft2files = map(path.expand,self.ft2files)
Example #2
0
    def __init__(self, file='%s/jvalue_table.pkl' % basedir, **kwargs):
        """ This class returns the angular profile of the line-of-sight integral
        through the Einasto density profile squared. This spatial model is normalized
        such that the integral over the emission radius is 1. To retrieve a physical
        description, it is necessary to multiply the spatial distribution by the factors
        rhos**2 * rs * self.scalefactor.

        The pickle input file is created with the CVS controlled script:
        user/mdwood/python/dsph/jtable.py

           >>> sigma = 1
           >>> r = np.logspace(0.1,1,4)
           >>> profile = Einasto(sigma=sigma)
           >>> print profile.at_r_in_deg(r)
           [  4.30828635e+01   2.78006838e+00   8.42642147e-02   1.01894909e-03]
        
        """

        infile = path.expand(file)
        data = pickle.load(open(infile, 'r'))
        r_in_degrees = data['psi']
        sigmas = data['sigma']
        pdf2d = data['einasto']

        super(Einasto, self).__init__(r_in_degrees, sigmas, pdf2d, **kwargs)
Example #3
0
    def __init__(self, file='%s/jvalue_table.pkl' % basedir, **kwargs):
        """ This class returns the angular profile of the line-of-sight integral
        through the Burkert density profile squared. This spatial model is normalized
        such that the integral over the emission radius is 1. To retrieve a physical
        description, it is necessary to multiply the spatial distribution by the factors
        rhos**2 * rs * self.scalefactor.

        The pickle input file is created with the CVS controlled script:
        user/mdwood/python/dsph/jtable.py

           >>> sigma = 1
           >>> r = np.logspace(0.1,1,4)
           >>> profile = Burkert(sigma=sigma)
           >>> print profile.at_r_in_deg(r)
           [  1.39250630e+02   1.22157313e+01   6.14035455e-01   2.42861785e-02]
            
        """

        infile = path.expand(file)
        data = pickle.load(open(infile, 'r'))
        r_in_degrees = data['psi']
        sigmas = data['sigma']
        pdf2d = data['burkert']

        super(Burkert, self).__init__(r_in_degrees, sigmas, pdf2d, **kwargs)
Example #4
0
 def __init__(self, srcid_dir='$FERMI/catalog/srcid', **kwargs):
     """
     Arguments:
        srcid_dir : Path to a directory containing a subfolders 'cat',
                    containing counterpart catalogs, and 'classes',
                    containing python modules describing the catalogs.
     Keyword Arguments:
        catalog_dir: Path to counterpart catalogs, overriding 'srcid_dir/cat'
        class_dir: Path to directory containing class modules,
                   overriding 'srcid_dir/classes'
        verbosity : int, 0 for no output, 1 for normal output, 2 for extra output
        quiet: bool, deprecated, set verbosity = 0
     """
     keyword_options.process(self, kwargs)
     self.srcid_dir = path.expand(srcid_dir)
     if self.catalog_dir is not None:
         self.catalog_dir = path.expand(self.catalog_dir)
     else:
         self.catalog_dir = os.path.join(self.srcid_dir, 'cat')
     if self.class_dir is not None:
         self.class_dir = path.expand(self.class_dir)
     else:
         self.class_dir = os.path.join(self.srcid_dir, 'cat')
     assert os.path.exists(
         self.class_dir), 'class_dir, %s, does not exist' % self.class_dir
     if self.quiet: self.verbosity = 0
     if not self.srcid_dir in sys.path:
         sys.path.insert(0, self.srcid_dir)
     self.class_list = None
     try:
         global classes
         import classes
         self.class_list = classes.__all__
         if self.verbosity:
             print('Available counterpart classes are:\n%s' %
                   (' '.join(self.class_list or [''])))
     except ImportError:
         raise SrcidError('Cannot find class modules to import.')
     self.catalogs = {}
     self.sources = {}
Example #5
0
    def __init__(self, catalog, **kwargs):
        keyword_options.process(self, kwargs)

        print "Opening catalog from %s" % catalog

        if self.latextdir is None:
            if (not os.environ.has_key('LATEXTDIR')
                    or not exists(path.expand(os.environ['LATEXTDIR']))):
                raise Exception(
                    dedent("""
                            Since environment variable $LATEXTDIR does 
                            not exist, the paramter latextdir must
                            be passed into this object."""))

            else:
                self.latextdir = os.environ['LATEXTDIR']
        else:
            os.environ['LATEXTDIR'] = path.expand(self.latextdir)

        self.catalog = catalog

        self.__make_sources__()
Example #6
0
    def _setup_files(self):
        """
        use glob and expand to expand wildcards and convert to absolute paths (in backward-compatible manner)
        """
        if type(self.ft1files) == types.StringType:
            self.ft1files = glob.glob(path.expand(self.ft1files))
            self.ft1files.sort()
        if type(self.ft2files) == types.StringType:
            self.ft2files = glob.glob(path.expand(self.ft2files))
            self.ft2files.sort()

        # check explicit files
        for filelist in [self.ft1files, self.ft2files]:
            if filelist is not None and len(
                    filelist) > 0 and not os.path.exists(filelist[0]):
                raise PixelDataException(
                    'PixelData setup: file name or path "%s" not found' %
                    filelist[0])
        if type(self.binfile) == types.StringType:
            self.binfile = path.expand(self.binfile)
        if type(self.ltcube) == types.StringType:
            self.ltcube = path.expand(self.ltcube)
Example #7
0
    def __init__(self,  *args, **kwargs):
        import pyLikelihood

        # the DMFitFunction must exist before __init__ is called because
        # the __init__ will call setp().
        self.dmf=pyLikelihood.DMFitFunction()
        super(DMFitFunction,self).__init__(*args,**kwargs)

        # unbound all parameters in gtlike
        for n in np.append(self.param_names,['norm','bratio','channel0','channel1']):
            self.dmf.getParam(n).setBounds(-float('inf'),float('inf'))

        # Integrated flux calculation energy cutoff
        self.ecut = None

        self.dmf.readFunction(path.expand(self.file))
        self._update() # update all parameters in DMFitFunction
Example #8
0
    def get_roi(name,
                center,
                point_sources,
                diffuse_sources,
                emin=1e2,
                emax=1e5,
                binsperdec=2):

        simdir = path.expand('$SIMDIR/%s' % name)

        if not os.path.exists(simdir):
            os.makedirs(simdir)

        ft1 = '%s/ft1.fits' % simdir
        ft2 = '%s/ft2.fits' % simdir

        ds = DataSpecification(ft1files=ft1,
                               ft2files=ft2,
                               ltcube='%s/ltcube.fits' % simdir,
                               binfile='%s/binfile.fits' % simdir)

        sa = SpectralAnalysisMC(
            ds,
            seed=0,
            emin=emin,
            emax=emax,
            irf='P7SOURCE_V6',
            binsperdec=binsperdec,
            mc_energy=True,
            tstart=0,
            tstop=604800,  # 7 days
            quiet=not PointlikeTest.VERBOSE,
            roi_dir=center,
            maxROI=5,
            minROI=5,
            savedir='%s/gtobssim' % simdir)

        roi = sa.roi(roi_dir=center,
                     point_sources=point_sources,
                     diffuse_sources=diffuse_sources)

        return roi
Example #9
0
    def test_ff(self):
        """ Simulate from a filefunction object and test that the best
        fit flux
            is consistent with the simulated flux. """
        name = 'ff'

        model = PowerLaw(index=2)
        model.set_flux(1e-6)
        simdir = path.expand('$SIMDIR/%s' % name)
        if not os.path.exists(simdir):
            os.makedirs(simdir)

        filename = abspath(join(simdir, 'file_function.txt'))
        model.save_profile(filename, 10, 1e6)
        ff = FileFunction(file=filename)

        center = SkyDir(0, 0)
        ps = PointSource(name='source', skydir=center, model=ff)
        point_sources = [ps]
        diffuse_sources = None
        roi = PointlikeTest.get_roi(name,
                                    center,
                                    point_sources,
                                    diffuse_sources,
                                    emin=1e2,
                                    emax=1e5,
                                    binsperdec=4)

        if PointlikeTest.VERBOSE:
            roi.print_summary()
            print roi

        roi.fit(use_gradient=PointlikeTest.USE_GRADIENT)

        if PointlikeTest.VERBOSE:
            roi.print_summary()
            print roi

        fit, error = ff.i_flux(1e2, 1e5, error=True)
        true = model.i_flux(1e2, 1e5, error=False)
        self.assertPull(fit, true, error, 'flux')
Example #10
0
    def __init__(self, file='%s/jvalue_table.pkl' % basedir, **kwargs):
        """ This class returns the angular profile of the line-of-sight integral
        through the NFW density profile squared. This spatial model is normalized
        such that the integral over the emission radius is 1. To retrieve a physical
        description, it is necessary to multiply the spatial distribution by the factors
        rhos**2 * rs * self.scalefactor.

        WARNING: Referring to INST_DIR is trouble if pointlike you are pointing
        to a HEAD of pointlike not in INST_DIR

        The pickle input file is created with the CVS controlled script:
        user/mdwood/python/dsph/jtable.py
        
           >>> sigma = 1
           >>> r = np.logspace(0.1,1,4)
           >>> profile = NFW(sigma=sigma)
           >>> print profile.at_r_in_deg(r)
           [  3.46679557e+01   2.73145672e+00   1.51607416e-01   6.68125546e-03]

        Note, previously this wouldn't raise an exception:
            >>> np.allclose(profile.default_limits[-1],[0.01, 15])
            True
            >>> profile['sigma'] = 0.009
            Traceback (most recent call last):
                ...
            SpatialModelException: sigma=0.009 is lower than the lower limit=0.01:
            >>> profile['sigma'] = 15.001
            Traceback (most recent call last):
                ...
            SpatialModelException: sigma=15.001 is larger than the upper limit=15.0:

        """

        infile = path.expand(file)
        data = pickle.load(open(infile, 'r'))
        r_in_degrees = data['psi']
        sigmas = data['sigma']
        pdf2d = data['nfw']

        super(NFW, self).__init__(r_in_degrees, sigmas, pdf2d, **kwargs)
Example #11
0
    def __extended_models__(self):
        """ Read in the extended source spatial models
            from the catalog. """

        f = pyfits.open(path.expand(self.catalog))

        if "Ignore" in f['EXTENDEDSOURCES'].columns.names:
            sourceMask = f['EXTENDEDSOURCES'].data.field("Ignore") == False
            extended = f['EXTENDEDSOURCES'].data[sourceMask]
        else:
            extended = f['EXTENDEDSOURCES'].data
        #self.extended_names = np.char.strip(extended.field('Source_Name'))
        #self.extended_nicknames = np.char.replace(self.extended_names,' ','')
        self.extended_names = np.asarray(
            [x.strip() for x in extended.field('Source_Name')])
        self.extended_nicknames = np.asarray(
            [x.replace(' ', '') for x in self.extended_names])

        ras = extended.field('RAJ2000')
        decs = extended.field('DEJ2000')
        forms = extended.field('Model_Form')
        majors = extended.field('Model_SemiMajor')
        minors = extended.field('Model_SemiMinor')
        posangs = extended.field('Model_PosAng')

        # The xml filename for the extended sources.
        templates = extended.field('Spatial_Filename').astype(str)
        f.close()

        # SpatialModel object for each extended source.
        self.extended_models = []

        for name,form,ra,dec,major,minor,posang,template in \
                zip(self.extended_nicknames,forms,ras,decs,majors,minors,posangs,templates):
            center = SkyDir(float(ra), float(dec))
            if form == 'Disk':
                if major == minor and posang == 0:
                    self.extended_models.append(Disk(p=[major], center=center))
                else:
                    self.extended_models.append(
                        EllipticalDisk(p=[major, minor, posang],
                                       center=center))
            elif form == '2D Gaussian':
                if major == minor and posang == 0:
                    self.extended_models.append(
                        Gaussian(p=[major / Gaussian.x68], center=center))
                else:
                    self.extended_models.append(
                        EllipticalGaussian(p=[
                            major / Gaussian.x68, minor / Gaussian.x68, posang
                        ],
                                           center=center))
            else:
                self.extended_models.append(
                    SpatialMap(
                        file=self.kluge_template_to_file_name(template)))

            # remember the fits file template in case the XML needs to be saved out.
            # (for gtlike compatability)
            self.extended_models[
                -1].original_template = self.kluge_template_to_file_name(
                    template)
            self.extended_models[
                -1].original_parameters = self.extended_models[-1].p.copy()

        self.extended_models = np.asarray(self.extended_models)
Example #12
0
def get_diffuse_source(spatialModel='ConstantValue',
                              spatialModelFile=None,
                              spectralModel='PowerLaw',
                              spectralModelFile=None,
                              name=None,
                              diffdir = None):

    """ Return a DiffuseSource instance suitable for
         instantiating a child of ROIDiffuseModel.

         NB -- don't support front/back distinction atm.

         The list of supported models is currently very short, but covers
         the usual cases for modeling diffuse backgrounds.  Additional
         use cases can be developed on an ad hoc basis.
         
         Arguments:
         
         spatialModel -- an XML-style keyword.  Valid options are
                               1) ConstantValue (isotropic)
                               2) MapCubeFunction (from a FITS file)
                               
         spatialModelFile -- if a mapcube is specified, its location
         
         spectralModel -- This can be either an XML-style keyword or an
                                instance of Model.
                                If an XML-style keyword, valid options are
                                1) FileFunction
                                2) PowerLaw
                                3) Constant
                               
         spectralModelFile -- if a tabular function is specified,
                                     its location

         name -- a name for the ol' model

         
         diffdir -- if the XML files specify paths relative to some
                        directory, set this variable appropriately
    """

    if (diffdir is not None):
        if spatialModelFile is not None:
            spatialModelFile = os.path.join(diffdir,spatialModelFile)
        if spectralModelFile is not None:
            spectralModelFile = os.path.join(diffdir,spectralModelFile)

    # check input sanity
    if not isinstance(spectralModel,Model):
        if (spectralModelFile is not None):
            if not os.path.exists(path.expand(spectralModelFile)):
                raise Exception('Could not find the ASCII file specified for FileFunction')
        elif not (spectralModel == 'PowerLaw' or spectralModel == 'Constant'):
            raise NotImplementedError,'Must provide one of the understood spectral models.'
        else:
            pass

    if spatialModel=='MapCubeFunction':
        if (spatialModelFile is None) or (not os.path.exists(path.expand(spatialModelFile))):
            raise Exception('Could not find the FITS file specified for MapCubeFunction (file = %s).' % spatialModelFile)
    elif spatialModel != 'ConstantValue':
        raise NotImplementedError,'Must provide one of the understood spatial models.'
    else:
        pass                  

    ston = Singleton2()
    dmodel = None; smodel = None


    # deal with isotropic models
    if spatialModel=='ConstantValue':
        if isinstance(spectralModel,Model):
            smodel=spectralModel
            dmodel=IsotropicConstant()
        elif spectralModelFile is not None:
            smodel = FileFunction(normalization=1, file=spectralModelFile)
            dmodel = IsotropicConstant()
        elif spectralModel == 'PowerLaw':
            # use Sreekumar-like defaults
            smodel = PowerLaw(index=2.1)
            smodel.set_flux(1.5e-5, emin=100, emax=N.inf)

            dmodel = IsotropicConstant()
        else:
            raise Exception("Unable to parse input.")

    # deal with mapcubes
    else:
        if spectralModel == 'FileFunction':
            dmodel1 = IsotropicSpectrum(spectralModelFile)
            dmodel2 = ston.add(DiffuseFunction,spatialModelFile,spatialModelFile)
            dmodel  = CompositeSkySpectrum(dmodel1,dmodel2)
            dmodel.saveme1 = dmodel1; dmodel.saveme2 = dmodel2
            smodel  = Constant()
        else:
            dmodel = ston.add(DiffuseFunction,path.expand(spatialModelFile),path.expand(spatialModelFile))
            dmodel.filename=spatialModelFile
            if spectralModel == 'PowerLaw':
                smodel = ScalingPowerLaw()
            elif spectralModel == 'Constant':
                smodel = Constant()
            else:
                smodel = spectralModel

    if (dmodel is None) or (smodel is None):
         raise Exception('Was unable to parse input.')

    return DiffuseSource(dmodel,smodel,name)
Example #13
0
class DMFitFunction(Model):
    """ Wrap gtlike's DMFitFunction interface. 
    
        N.B. The bug Sheridan reported that the set_flux function 
        was not working should now be fixed:
        
            >>> model = DMFitFunction()
            >>> model.set_flux(1e-7, emin=1e3, emax=1e5)
            >>> print '%g' % model.i_flux(emin=1e3, emax=1e5)
            1e-07

        Test the getters and setters

            >>> model['sigmav']=3.14
            >>> print '%g' % model['sigmav']
            3.14

        There was previously a bug in set_parameters, 
        lets see if its fixed:

            >>> model.set_parameters(np.log10([5,500]))
            >>> print '%g' % model['sigmav']
            5
            >>> print '%g' % model['mass']
            500

        Note, the parameters which are not directly fit (like bratio) get set correctly:

            >>> model = DMFitFunction(bratio=2)
            >>> print model.dmf.getParam('bratio').getTrueValue()
            2.0
            >>> model = DMFitFunction(bratio=3)
            >>> print model.dmf.getParam('bratio').getTrueValue()
            3.0

        Test a few hard coded values, to make sure the function values are correct:

            >>> model = DMFitFunction(sigmav=1e-26, mass=100,
            ... channel0=4, channel1=1, bratio=1, norm=2.5e17)

            >>> model = DMFitFunction(norm=2.5e17, sigmav=1e-26, channel0=4,channel1=1,mass=100,bratio=1.0)

        These points agree with the fortran code.

            >>> e = [1, 10, 100, 1000, 10000, 100000 , 1000000]
            >>> dnde = [ 9.55801576e-18, 2.04105211e-16,  4.43719263e-16, 1.00123992e-16, 1.44911940e-18, 0.0, 0.0 ]
            >>> print np.allclose(model(e), dnde)
            True

         TODO: The limits of integration when calculating the flux should be
         limited by the DM particle mass. Otherwise, this can lead to numerical
         instability in the fit.
    """
    default_p = [1e-25, 100.]
    default_extra_params = dict(norm=1e18, bratio=1.0, channel0=1, channel1=1)
    param_names = ['sigmav', 'mass']
    default_mappers = [LogMapper, LogMapper]
    # ST >= 09-31-00
    gammamc_dif = '$(INST_DIR)/data/Likelihood/gammamc_dif.dat'
    if not os.path.exists(path.expand(gammamc_dif)):
        gammamc_dif = '$(INST_DIR)/Likelihood/src/dmfit/gammamc_dif.dat'
    if not os.path.exists(path.expand(gammamc_dif)):
        gammamc_dif = '$(BASE_DIR)/data/Likelihood/gammamc_dif.dat'
    default_extra_attrs = OrderedDict((('file', gammamc_dif), ))

    gtlike = dict(name='DMFitFunction',
                  param_names=['sigmav', 'mass'],
                  extra_param_names=dict(norm='norm',
                                         bratio='bratio',
                                         channel0='channel0',
                                         channel1='channel1'),
                  topointlike=[operator.pos, operator.pos],
                  togtlike=[operator.pos, operator.pos])

    default_limits = dict(sigmav=LimitMapper(0, 1e-19, 1e-25),
                          mass=LimitMapper(1, 1e4, 1))
    default_oomp_limits = ['sigmav']

    channel_mapping = {
        1: ["e+e-", "ee"],
        2: ["mu+mu-", "mumu", "musrc"],
        3: ["tau+tau-", "tautau", "tausrc"],
        4: ["bb-bar", "bb", "bbbar", "bbsrc"],
        5: ["tt-bar", "tt"],
        6: ["gluons", "gg"],
        7: ["W+W-", "w+w-", "ww", "wwsrc"],
        8: ["ZZ", "zz"],
        9: ["cc-bar", "cc"],
        10: ["uu-bar", "uu"],
        11: ["dd-bar", "dd"],
        12: ["ss-bar", "ss"],
    }

    channel_tex = {
        1: r'$e^{+}e^{-}$',
        2: r'$\mu^{+}\mu^{-}$',
        3: r'$\tau^{+}\tau^{-}$',
        4: r'$b \bar b$',
        5: r'$t \bar t$',
        6: r'$gg$',
        7: r'$W^{+}W^{-}$',
        8: r'$ZZ$',
        9: r'$c \bar c$',
        10: r'$u \bar u$',
        11: r'$d \bar d$',
        12: r'$s \bar s$',
    }

    @staticmethod
    def channel2int(s):
        for k, v in DMFitFunction.channel_mapping.items():
            if s in v: return k
        else: raise ValueError("Can't find value %s" % s)

    @staticmethod
    def channel2tex(ch):
        if ch in DMFitFunction.channel_tex.keys():
            return DMFitFunction.channel_tex[ch]
        elif ch in DMFitFunction.channels():
            return DMFitFunction.channel_tex[DMFitFunction.channel2int(ch)]
        else:
            raise ValueError("Can't find channel %s" % ch)

    @staticmethod
    def int2channel(i):
        return DMFitFunction.channel_mapping[i][0]

    @staticmethod
    def channels():
        """ Return all available DMFit channel strings """
        return [
            s for channel in DMFitFunction.channel_mapping.values()
            for s in channel
        ]

    def full_name(self):
        return '%s, norm=%.2g, bratio=%.1f channel0=%d, channel1=%d' % (
            self.pretty_name, self.norm, self.bratio, self.channel0,
            self.channel1)

    def __getstate__(self):
        d = copy.copy(self.__dict__)
        del d['dmf']
        return d

    def __setstate__(self, state):
        self.__dict__ = state
        self._update()

    def _update(self):
        """ Update the DMFitFunction internally.
            This function should be called
            automatically when necessary.
        """
        if not hasattr(self, 'dmf'):
            import pyLikelihood
            self.dmf = pyLikelihood.DMFitFunction()

        for i, param_name in enumerate(self.param_names):
            self.dmf.setParam(param_name, self[param_name])

        # Set the parameters which are not fixed explicitly
        self.dmf.setParam('norm', self.norm)
        self.dmf.setParam('bratio', self.bratio)
        self.dmf.setParam('channel0', self.channel0)
        self.dmf.setParam('channel1', self.channel1)

        # Set flux integration energy cut to slightly higher than the mass
        self.ecut = 1.1 * self['mass'] * 1e3  # Energy cutoff (MeV)

    def __init__(self, *args, **kwargs):
        import pyLikelihood

        # Parse channel strings
        if isinstance(kwargs.get('channel0', None), basestring):
            kwargs['channel0'] = self.channel2int(kwargs['channel0'])
        if isinstance(kwargs.get('channel1', None), basestring):
            kwargs['channel1'] = self.channel2int(kwargs['channel1'])

        # the DMFitFunction must exist before __init__ is called because
        # the __init__ will call setp().
        self.dmf = pyLikelihood.DMFitFunction()
        super(DMFitFunction, self).__init__(*args, **kwargs)

        # unbound all parameters in gtlike
        for n in np.append(self.param_names,
                           ['norm', 'bratio', 'channel0', 'channel1']):
            self.dmf.getParam(n).setBounds(-float('inf'), float('inf'))

        # Integrated flux calculation energy cutoff
        self.ecut = None

        self.dmf.readFunction(path.expand(self.file))
        self._update()  # update all parameters in DMFitFunction

    def setp(self, *args, **kwargs):
        super(DMFitFunction, self).setp(*args, **kwargs)
        self._update()

    def set_parameters(self, *args, **kwargs):
        super(DMFitFunction, self).set_parameters(*args, **kwargs)
        self._update()

    def set_all_parameters(self, *args, **kwargs):
        super(DMFitFunction, self).set_all_parameters(*args, **kwargs)
        self._update()

    @staticmethod
    def call_pylike_spectrum(spectrum, e):
        """ Method to call a pylikelihood spectrum given
            either a python numer or a numpy array. """
        from pyLikelihood import dArg
        if isinstance(e, collections.Iterable):
            return np.asarray([spectrum(dArg(i)) for i in e])
        else:
            return spectrum(dArg(e))

    def __call__(self, e):
        """ Return energy in MeV. This could be vectorized. """
        return DMFitFunction.call_pylike_spectrum(self.dmf, e)
Example #14
0
def load(filename,**kwargs):
    """ Factory method to return a ROIAnalysis object
        that has been saved to a file. 
        
        Any additional kwargs is used to modify DataSpecification, SpectralAnalysis,
        and ROIAnalysis objects."""
    if isinstance(filename, basestring):
        d=cPickle.load(open(path.expand(filename),'r'))
    elif isinstance(filename, dict):
        d=filename
    else:
        raise Exception("Unknown ROI file %s" % filename)

    # restore previous LATEXTDIR if it is not already set
    if not os.environ.has_key('LATEXTDIR') and d['LATEXTDIR'] not in [None,{}]:
        os.environ['LATEXTDIR']=d['LATEXTDIR'] 

    # SpatialMap objects may fail to load if LATEXTDIR wasn't previously
    # set. If so, try again.
    if N.any([hasattr(ds,'spatial_model') and \
              hasattr(ds.spatial_model,'skyfun') \
              and ds.spatial_model.skyfun is None 
              for ds in d['diffuse_sources']]):
        d=cPickle.load(open(path.expand(filename),'r'))

    from . pointspec import DataSpecification,SpectralAnalysis
    from . roi_analysis import ROIAnalysis

    xmlfile=None
    point_sources = d['point_sources']
    diffuse_sources = d['diffuse_sources']

    for k,v in kwargs.items():

        keys=lambda x: [ i[0] for i in x]

        if k in keys(DataSpecification.defaults):
            d['DataSpecification'][k]=v
        elif k in keys(SpectralAnalysis.defaults):
            # allow changing the ROIAnalysis parameters when
            d['SpectralAnalysis'][k]=v
        elif k in keys(ROIAnalysis.defaults):
            d['ROIAnalysis'][k]=v
        elif k == 'xmlfile':
            xmlfile = v
        elif k == 'point_sources':
            point_sources = v
        elif k == 'diffuse_sources':
            diffuse_sources = v
        else:
            raise Exception("Unknown argument %s to function load" % k)

    # backwards compatability
    for ps in point_sources: 
        if hasattr(ps.model,'p'): ps.model._p=ps.model.p
    for ds in diffuse_sources: 
        if hasattr(ds.smodel,'p'): ds.smodel._p=ds.smodel.p

    ds=DataSpecification(**d['DataSpecification'])
    sa=SpectralAnalysis(ds,**d['SpectralAnalysis'])
    roi=sa.roi(roi_dir=d['roi_dir'],
               xmlfile=xmlfile,
               point_sources=point_sources,
               diffuse_sources=diffuse_sources,
               **d['ROIAnalysis'])

    # add in localization stuff, kinda ugly
    if d.has_key('localization'):
        roi.qform=d['localization']['qform']
        roi.ldir=d['localization']['ldir']
        roi.lsigma=d['localization']['lsigma']
        roi.delta_loc_logl=d['localization']['delta_loc_logl']

    # load back any potential custom stuff
    if d.has_key('extra'): roi.extra = d['extra']

    # just to be safe
    roi.__update_state__()

    return roi
Example #15
0
def save(roi,filename):
    """ Save ROI to file. 
    
        This implementation has many limitations and is suitable only for quick hacks.

            * To keep the saved file small, this none of the model predictions are saved. After
              reloading the ROI, all of these time consuming calculations have to be redone.
            * Is fragile to the exact path of things. So you probably could not reload the ROI
              with a new version of the science tools, or after moving the location of your
              diffuse sources or anything like that.
            * Can only pickle certain kinds of diffuse sources.
            * Does not respect if a special diffuse_mapper was used to create the ROI.

        Nevertheless, it is very useful to be able to temporarily save and load an ROI. """
    self=roi

    d=collections.defaultdict(dict)

    from . pointspec import DataSpecification,SpectralAnalysis

    for i in DataSpecification.defaults:
        if len(i)==3:
            j=i[0]
            d['DataSpecification'][j]=self.sa.dataspec.__dict__[j]

    for i in SpectralAnalysis.defaults:
        if len(i)==3:
            j=i[0]
            d['SpectralAnalysis'][j]=self.sa.__dict__[j]

    d['roi_dir']=self.roi_dir
    d['point_sources']=self.psm.point_sources.tolist()
    d['diffuse_sources']=self.dsm.diffuse_sources.tolist()

    # allow storing extra stuff for custom analysis
    if hasattr(roi,'extra'): d['extra'] = roi.extra

    if self.__dict__.has_key('qform') and \
            self.__dict__.has_key('ldir') and \
            self.__dict__.has_key('lsigma') and \
            self.__dict__.has_key('delta_loc_logl'):

        # can't save out qform, but at least save qform.par
        empty_qform=Empty()
        empty_qform.par=self.qform.par

        # add in localization stuff, kinda ugly
        d['localization']={'qform':empty_qform,
                           'ldir':self.ldir,
                           'lsigma':self.lsigma,
                           'delta_loc_logl':self.delta_loc_logl}

    from . roi_analysis import ROIAnalysis

    for i in ROIAnalysis.defaults:
        if len(i)==3:
            j=i[0]
            d['ROIAnalysis'][j]=self.__dict__[j]

    d['LATEXTDIR']=os.environ['LATEXTDIR'] if os.environ.has_key('LATEXTDIR') else None

    cPickle.dump(d,open(path.expand(filename),'w'))
Example #16
0
def get_default_diffuse(diffdir=None,gfile='gll_iem_v02.fit',ifile='isotropic_iem_v02.txt', limit_parameters=False):
    """ Try to get defaults for the diffuse background sources, assumed to be 
        a MapCubeFunction/Powerlaw and ConstantValue/FileFunction
        Setting gfile or ifile to None ignores that entry.
            
            >>> gal, iso = get_default_diffuse(diffdir='$(GLAST_EXT)/diffuseModels/v2r0p1/',
            ...     gfile="ring_2year_P76_v0.fits",
            ...     ifile="isotrop_2year_P76_source_v1.txt")
            >>> print gal.smodel.name
            ScalingPowerLaw
            >>> print gal.smodel['norm']
            1.0
            >>> print gal.smodel['index']
            0.0
            >>> print gal.smodel.get_mapper('norm')
            <class 'uw.utilities.parmap.LogMapper'>
            >>> print gal.smodel.get_mapper('index')
            <class 'uw.utilities.parmap.LinearMapper'>

            >>> print iso.smodel.name
            FileFunction
            >>> print iso.smodel['Normalization']
            1.0
            >>> print iso.smodel.get_mapper('Normalization')
            <class 'uw.utilities.parmap.LogMapper'>

            >>> gal, iso = get_default_diffuse(diffdir='$(GLAST_EXT)/diffuseModels/v2r0p1/',
            ...     gfile="ring_2year_P76_v0.fits",
            ...     ifile="isotrop_2year_P76_source_v1.txt",
            ...     limit_parameters=True)
            >>> print gal.smodel.get_mapper('norm')
            LimitMapper(0.1,10,1)
            >>> print gal.smodel.get_mapper('index')
            LimitMapper(-1,1,1)
            >>> print iso.smodel.get_mapper('Normalization')
            LimitMapper(0.1,10,1)



     """
    if diffdir is None:
        diffdir = join(os.environ['EXTFILESSYS'],'galdiffuse')

    if gfile is None and ifile is None:
        raise Exception('Unable to find any diffuse sources.')

    if gfile is not None:
        gfilex = join(diffdir,gfile)
        if not os.path.exists(path.expand(gfilex)):
            raise Exception(' Galactic diffuse file "%s" not found.' %gfilex)
        else:
            gfile = get_diffuse_source('MapCubeFunction',gfilex,'PowerLaw',None,'Galactic Diffuse (%s)'%gfile)
            if limit_parameters: gfile.smodel.set_default_limits()
    if ifile is not None:
        ifilex = join(diffdir,ifile)
        if not os.path.exists(path.expand(ifilex)):
            raise Exception('isotropic diffuse file "%s" not found.'%ifilex)
        else:
            ifile = get_diffuse_source('ConstantValue',None,'FileFunction',ifilex,'Isotropic Diffuse (%s)'%ifile)
            if limit_parameters: ifile.smodel.set_default_limits()

    return [gfile, ifile]
Example #17
0
    def __make_sources__(self):
        """ Make a list of all the point and extended
            sources in the catalog. """

        from .pointspec_helpers import PointSource  # Avoid circular imports

        self.__extended_models__()

        f = pyfits.open(path.expand(self.catalog))
        colnames = [x.name for x in f[1].get_coldefs()]

        if "Ignore" in colnames:
            sourceMask = f['LAT_POINT_SOURCE_CATALOG'].data.field(
                "Ignore") == False
            point = f['LAT_POINT_SOURCE_CATALOG'].data[sourceMask]
        else:
            point = f['LAT_POINT_SOURCE_CATALOG'].data
        ras = point.field('RAJ2000')
        decs = point.field('DEJ2000')
        pens = point.field('PIVOT_ENERGY')
        n0s = point.field('FLUX_DENSITY')
        inds = point.field('SPECTRAL_INDEX')
        f1000s = point.field('FLUX1000')
        cutoffs = point.field('CUTOFF')
        betas = point.field('BETA')
        stypes = point.field('SPECTRUMTYPE')
        f.close()

        # extended => is extended
        self.names, self.extendeds = self.kluge_names_extended(point)

        dirs = map(SkyDir,
                   np.asarray(ras).astype(float),
                   np.asarray(decs).astype(float))

        # Store both point and extended sources.
        self.sources = []

        # This is for the new 2FGL style catalogs
        for name,extended,stype,n0,ind,pen,cutoff,beta,f1000,dir in \
                zip(self.names,self.extendeds,stypes,n0s,inds,pens,cutoffs,betas,f1000s,dirs):

            if stype == 'PowerLaw':
                # note, np.isinf incorrectly raises annoying warning
                # http://projects.scipy.org/numpy/ticket/1500
                # This is a workaround.
                if n0 not in [-np.inf, np.inf]:
                    model = PowerLaw(norm=n0, index=ind, e0=pen)
                else:
                    # For some reason, in 2FGL the fixed extended sources don't
                    # have n0 set. So create the source from the f1000 value.
                    model = PowerLawFlux(int_flux=f1000,
                                         index=ind,
                                         emin=1e3,
                                         emax=1e5)
            elif stype == 'PowerLaw2':
                model = PowerLawFlux(int_flux=f1000,
                                     index=ind,
                                     emin=1e3,
                                     emax=1e5)
            elif stype == 'LogParabola':
                model = LogParabola(norm=n0, index=ind, beta=beta, e_break=pen)
                model.freeze('e_break')
            elif stype == 'PLExpCutoff':
                # PLExpCutoff is defined by Eq. 1 of the 2FGL paper:
                # dN/dE = K*(E/E_pivot)**-gamma * exp(-(E - E_pivot)/E_cutoff)
                # This forces a correction factor to match pointlike ExpCutoff
                norm = n0 * np.exp(pen / cutoff)
                model = ExpCutoff(norm=norm, index=ind, cutoff=cutoff, e0=pen)
            elif stype == 'PLSuperExpCutoff':
                model = PLSuperExpCutoff(norm=n0,
                                         index=ind,
                                         cutoff=cutoff,
                                         e0=pen)
            else:
                raise Exception("Unkown spectral model %s for source %s" %
                                (stype, name))

            if self.limit_parameters:
                model.set_default_limits(oomp_limits=True)

            if extended:
                spatial_model = self.__get_spatial_model__(name)
                self.sources.append(
                    ExtendedSource(name=name,
                                   model=model,
                                   spatial_model=spatial_model))
            else:
                self.sources.append(
                    PointSource(dir, name, model, leave_parameters=True))