def query_galcoords(gal_lon,
                    gal_lat,
                    filtersystem='sloan_2mass',
                    field_deg2=1.0,
                    usebinaries=True,
                    extinction_sigma=0.1,
                    magnitude_limit=26.0,
                    maglim_filtercol=4,
                    trilegal_version=1.6,
                    extraparams=None,
                    forcefetch=False,
                    cachedir='~/.astrobase/trilegal-cache',
                    verbose=True,
                    timeout=60.0,
                    refresh=150.0,
                    maxtimeout=700.0):
    '''This queries the TRILEGAL model form, downloads results, and parses them.

    Parameters
    ----------

    gal_lon,gal_lat : float
        These are the center galactic longitude and latitude in degrees.

    filtersystem : str
        This is a key in the TRILEGAL_FILTER_SYSTEMS dict. Use the function
        :py:func:`astrobase.services.trilegal.list_trilegal_filtersystems` to
        see a nicely formatted table with the key and description for each of
        these.

    field_deg2 : float
        The area of the simulated field in square degrees.

    usebinaries : bool
        If this is True, binaries will be present in the model results.

    extinction_sigma : float
        This is the applied std dev around the `Av_extinction` value for the
        galactic coordinates requested.

    magnitude_limit : float
        This is the limiting magnitude of the simulation in the
        `maglim_filtercol` band index of the filter system chosen.

    maglim_filtercol : int
        The index in the filter system list of the magnitude limiting band.

    trilegal_version : float
        This is the the version of the TRILEGAL form to use. This can usually be
        left as-is.

    extraparams : dict or None
        This is a dict that can be used to override parameters of the model
        other than the basic ones used for input to this function. All
        parameters are listed in `TRILEGAL_DEFAULT_PARAMS` above. See:

        http://stev.oapd.inaf.it/cgi-bin/trilegal

        for explanations of these parameters.

    forcefetch : bool
        If this is True, the query will be retried even if cached results for
        it exist.

    cachedir : str
        This points to the directory where results will be downloaded.

    verbose : bool
        If True, will indicate progress and warn of any issues.

    timeout : float
        This sets the amount of time in seconds to wait for the service to
        respond to our initial request.

    refresh : float
        This sets the amount of time in seconds to wait before checking if the
        result file is available. If the results file isn't available after
        `refresh` seconds have elapsed, the function will wait for `refresh`
        seconds continuously, until `maxtimeout` is reached or the results file
        becomes available.

    maxtimeout : float
        The maximum amount of time in seconds to wait for a result to become
        available after submitting our query request.

    Returns
    -------

    dict
        This returns a dict of the form::

            {'params':the input param dict used,
             'extraparams':any extra params used,
             'provenance':'cached' or 'new download',
             'tablefile':the path on disk to the downloaded model text file}

    '''

    # these are the default parameters
    inputparams = copy.deepcopy(TRILEGAL_INPUT_PARAMS)

    # update them with the input params
    inputparams['binary_kind'] = '1' if usebinaries else '0'
    inputparams['extinction_sigma'] = '%.2f' % extinction_sigma
    inputparams['field'] = '%.2f' % field_deg2
    inputparams['icm_lim'] = str(maglim_filtercol)
    inputparams['mag_lim'] = '%.2f' % magnitude_limit
    inputparams['trilegal_version'] = str(trilegal_version)

    # get the coordinates
    inputparams['gc_l'] = '%.3f' % gal_lon
    inputparams['gc_b'] = '%.3f' % gal_lat

    # check if the area is less than 10 deg^2
    if field_deg2 > 10.0:
        LOGERROR("can't have an area > 10 square degrees")
        return None

    # get the extinction parameter. this is by default A[inf] in V. we'll use
    # the value from SF11 generated by the 2MASS DUST service
    extinction_info = dust.extinction_query(gal_lon,
                                            gal_lat,
                                            coordtype='galactic',
                                            forcefetch=forcefetch,
                                            verbose=verbose,
                                            timeout=timeout)
    try:
        Av_infinity = extinction_info['Amag']['CTIO V']['sf11']
        inputparams['extinction_infty'] = '%.5f' % Av_infinity
    except Exception as e:
        LOGEXCEPTION(
            'could not get A_V_SF11 from 2MASS DUST '
            'for Galactic coords: (%.3f, %.3f), '
            'using default value of %s' % (gal_lon, gal_lat,
                                           inputparams['extinction_infty'])
        )


    # get the filter system table
    if filtersystem in TRILEGAL_FILTER_SYSTEMS:
        inputparams['photsys_file'] = (
            TRILEGAL_FILTER_SYSTEMS[filtersystem]['table']
        )
    else:
        LOGERROR('filtersystem name: %s is not in the table of known '
                 'filter systems.\n'
                 'Try the trilegal.list_trilegal_filtersystems() function '
                 'to see all available filter systems.' % filtersystem)
        return None

    # override the complete form param dict now with our params
    trilegal_params = copy.deepcopy(TRILEGAL_DEFAULT_PARAMS)
    trilegal_params.update(inputparams)

    # override the final params with any extraparams
    if extraparams and isinstance(extraparams, dict):
        trilegal_params.update(extraparams)

    # see if the cachedir exists
    if '~' in cachedir:
        cachedir = os.path.expanduser(cachedir)
    if not os.path.exists(cachedir):
        os.makedirs(cachedir)

    # generate the cachefname and look for it
    cachekey = repr(inputparams)
    cachekey = hashlib.sha256(cachekey.encode()).hexdigest()
    cachefname = os.path.join(cachedir, '%s.txt.gz' % cachekey)
    provenance = 'cache'

    lockfile = os.path.join(cachedir, 'LOCK-%s' % cachekey)

    # run the query if results not found in the cache
    if forcefetch or (not os.path.exists(cachefname)):

        # first, check if a query like this is running already
        if os.path.exists(lockfile):
            with open(lockfile,'r') as infd:
                lock_contents = infd.read()
            lock_contents = lock_contents.replace('\n','')

            LOGERROR('this query appears to be active since %s'
                     'in another instance, not running it again' %
                     lock_contents)
            return None

        else:
            with open(lockfile,'w') as outfd:
                outfd.write(datetime.utcnow().isoformat())

        provenance = 'new download'

        try:

            if verbose:
                LOGINFO('submitting TRILEGAL request for input params: %s'
                        % repr(inputparams))

            posturl = TRILEGAL_POSTURL.format(formversion=trilegal_version)

            req = requests.post(posturl,
                                data=trilegal_params,
                                timeout=timeout)
            resp = req.text

            # get the URL of the result file
            resultfile = TRILEGAL_REGEX.search(resp)

            if resultfile:

                resultfile = resultfile[0]
                waitdone = False
                timeelapsed = 0.0

                resultfileurl = '%s/%s' % (
                    TRILEGAL_BASEURL,
                    resultfile.replace('a href=..','')
                )

                if verbose:
                    LOGINFO(
                        'request submitted sucessfully, waiting for results...'
                    )

                # wait for 2 minutes, then try to download the result file
                while not waitdone:

                    if timeelapsed > maxtimeout:
                        LOGERROR('TRILEGAL timed out after waiting for results,'
                                 ' request was: '
                                 '%s' % repr(inputparams))
                        # remove the lock file
                        if os.path.exists(lockfile):
                            os.remove(lockfile)
                        return None

                    time.sleep(refresh)
                    timeelapsed = timeelapsed + refresh

                    try:

                        resreq = requests.get(resultfileurl)
                        resreq.raise_for_status()

                        if verbose:
                            LOGINFO('TRILEGAL completed, retrieving results...')

                        # stream the response to the output cache file
                        with gzip.open(cachefname,'wb') as outfd:
                            for chunk in resreq.iter_content(chunk_size=65536):
                                outfd.write(chunk)

                        tablefname = cachefname
                        waitdone = True
                        if verbose:
                            LOGINFO('done.')

                    except Exception as e:

                        if verbose:
                            LOGINFO('elapsed time: %.1f, result file: %s '
                                    'not ready yet...'
                                    % (timeelapsed, resultfileurl))
                        continue

            else:

                LOGERROR('no result file URL found in TRILEGAL output, '
                         'this is probably an error with the input. '
                         'HTML of error page follows:\n')
                LOGINFO(resp)
                # remove the lock file
                if os.path.exists(lockfile):
                    os.remove(lockfile)
                return None


        except requests.exceptions.Timeout as e:
            LOGERROR('TRILEGAL submission timed out, '
                     'site is probably down. Request was: '
                     '%s' % repr(inputparams))
            return None

        except Exception as e:
            LOGEXCEPTION('TRILEGAL request failed for '
                         '%s' % repr(inputparams))
            return None

        finally:

            # remove the lock file
            if os.path.exists(lockfile):
                os.remove(lockfile)


    # otherwise, get the file from the cache
    else:

        if verbose:
            LOGINFO('getting cached TRILEGAL model result for '
                    'request: %s' %
                    (repr(inputparams)))

        tablefname = cachefname


    # return a dict pointing to the result file
    # we'll parse this later
    resdict = {'params':inputparams,
               'extraparams':extraparams,
               'provenance':provenance,
               'tablefile':tablefname}

    return resdict
def query_galcoords(gal_lon,
                    gal_lat,
                    filtersystem='sloan_2mass',
                    field_deg2=1.0,
                    usebinaries=True,
                    extinction_sigma=0.1,
                    magnitude_limit=26.0,
                    maglim_filtercol=4,
                    trilegal_version=1.6,
                    extraparams=None,
                    forcefetch=False,
                    cachedir='~/.astrobase/trilegal-cache',
                    verbose=True,
                    timeout=60.0,
                    refresh=150.0,
                    maxtimeout=700.0):
    '''This queries the TRILEGAL model form, downloads results, and parses them.

    Parameters
    ----------

    gal_lon,gal_lat : float
        These are the center galactic longitude and latitude in degrees.

    filtersystem : str
        This is a key in the TRILEGAL_FILTER_SYSTEMS dict. Use the function
        :py:func:`astrobase.services.trilegal.list_trilegal_filtersystems` to
        see a nicely formatted table with the key and description for each of
        these.

    field_deg2 : float
        The area of the simulated field in square degrees.

    usebinaries : bool
        If this is True, binaries will be present in the model results.

    extinction_sigma : float
        This is the applied std dev around the `Av_extinction` value for the
        galactic coordinates requested.

    magnitude_limit : float
        This is the limiting magnitude of the simulation in the
        `maglim_filtercol` band index of the filter system chosen.

    maglim_filtercol : int
        The index in the filter system list of the magnitude limiting band.

    trilegal_version : float
        This is the the version of the TRILEGAL form to use. This can usually be
        left as-is.

    extraparams : dict or None
        This is a dict that can be used to override parameters of the model
        other than the basic ones used for input to this function. All
        parameters are listed in `TRILEGAL_DEFAULT_PARAMS` above. See:

        http://stev.oapd.inaf.it/cgi-bin/trilegal

        for explanations of these parameters.

    forcefetch : bool
        If this is True, the query will be retried even if cached results for
        it exist.

    cachedir : str
        This points to the directory where results will be downloaded.

    verbose : bool
        If True, will indicate progress and warn of any issues.

    timeout : float
        This sets the amount of time in seconds to wait for the service to
        respond to our initial request.

    refresh : float
        This sets the amount of time in seconds to wait before checking if the
        result file is available. If the results file isn't available after
        `refresh` seconds have elapsed, the function will wait for `refresh`
        seconds continuously, until `maxtimeout` is reached or the results file
        becomes available.

    maxtimeout : float
        The maximum amount of time in seconds to wait for a result to become
        available after submitting our query request.

    Returns
    -------

    dict
        This returns a dict of the form::

            {'params':the input param dict used,
             'extraparams':any extra params used,
             'provenance':'cached' or 'new download',
             'tablefile':the path on disk to the downloaded model text file}

    '''

    # these are the default parameters
    inputparams = copy.deepcopy(TRILEGAL_INPUT_PARAMS)

    # update them with the input params
    inputparams['binary_kind'] = '1' if usebinaries else '0'
    inputparams['extinction_sigma'] = '%.2f' % extinction_sigma
    inputparams['field'] = '%.2f' % field_deg2
    inputparams['icm_lim'] = str(maglim_filtercol)
    inputparams['mag_lim'] = '%.2f' % magnitude_limit
    inputparams['trilegal_version'] = str(trilegal_version)

    # get the coordinates
    inputparams['gc_l'] = '%.3f' % gal_lon
    inputparams['gc_b'] = '%.3f' % gal_lat

    # check if the area is less than 10 deg^2
    if field_deg2 > 10.0:
        LOGERROR("can't have an area > 10 square degrees")
        return None

    # get the extinction parameter. this is by default A[inf] in V. we'll use
    # the value from SF11 generated by the 2MASS DUST service
    extinction_info = dust.extinction_query(gal_lon,
                                            gal_lat,
                                            coordtype='galactic',
                                            forcefetch=forcefetch,
                                            verbose=verbose,
                                            timeout=timeout)
    try:
        Av_infinity = extinction_info['Amag']['CTIO V']['sf11']
        inputparams['extinction_infty'] = '%.5f' % Av_infinity
    except Exception as e:
        LOGEXCEPTION(
            'could not get A_V_SF11 from 2MASS DUST '
            'for Galactic coords: (%.3f, %.3f), '
            'using default value of %s' % (gal_lon, gal_lat,
                                           inputparams['extinction_infty'])
        )


    # get the filter system table
    if filtersystem in TRILEGAL_FILTER_SYSTEMS:
        inputparams['photsys_file'] = (
            TRILEGAL_FILTER_SYSTEMS[filtersystem]['table']
        )
    else:
        LOGERROR('filtersystem name: %s is not in the table of known '
                 'filter systems.\n'
                 'Try the trilegal.list_trilegal_filtersystems() function '
                 'to see all available filter systems.' % filtersystem)
        return None

    # override the complete form param dict now with our params
    trilegal_params = copy.deepcopy(TRILEGAL_DEFAULT_PARAMS)
    trilegal_params.update(inputparams)

    # override the final params with any extraparams
    if extraparams and isinstance(extraparams, dict):
        trilegal_params.update(extraparams)

    # see if the cachedir exists
    if '~' in cachedir:
        cachedir = os.path.expanduser(cachedir)
    if not os.path.exists(cachedir):
        os.makedirs(cachedir)

    # generate the cachefname and look for it
    cachekey = repr(inputparams)
    cachekey = hashlib.sha256(cachekey.encode()).hexdigest()
    cachefname = os.path.join(cachedir, '%s.txt.gz' % cachekey)
    provenance = 'cache'

    lockfile = os.path.join(cachedir, 'LOCK-%s' % cachekey)

    # run the query if results not found in the cache
    if forcefetch or (not os.path.exists(cachefname)):

        # first, check if a query like this is running already
        if os.path.exists(lockfile):
            with open(lockfile,'r') as infd:
                lock_contents = infd.read()
            lock_contents = lock_contents.replace('\n','')

            LOGERROR('this query appears to be active since %s'
                     'in another instance, not running it again' %
                     lock_contents)
            return None

        else:
            with open(lockfile,'w') as outfd:
                outfd.write(datetime.utcnow().isoformat())

        provenance = 'new download'

        try:

            if verbose:
                LOGINFO('submitting TRILEGAL request for input params: %s'
                        % repr(inputparams))

            posturl = TRILEGAL_POSTURL.format(formversion=trilegal_version)

            req = requests.post(posturl,
                                data=trilegal_params,
                                timeout=timeout)
            resp = req.text

            # get the URL of the result file
            resultfile = TRILEGAL_REGEX.search(resp)

            if resultfile:

                resultfile = resultfile[0]
                waitdone = False
                timeelapsed = 0.0

                resultfileurl = '%s/%s' % (
                    TRILEGAL_BASEURL,
                    resultfile.replace('a href=..','')
                )

                if verbose:
                    LOGINFO(
                        'request submitted sucessfully, waiting for results...'
                    )

                # wait for 2 minutes, then try to download the result file
                while not waitdone:

                    if timeelapsed > maxtimeout:
                        LOGERROR('TRILEGAL timed out after waiting for results,'
                                 ' request was: '
                                 '%s' % repr(inputparams))
                        # remove the lock file
                        if os.path.exists(lockfile):
                            os.remove(lockfile)
                        return None

                    time.sleep(refresh)
                    timeelapsed = timeelapsed + refresh

                    try:

                        resreq = requests.get(resultfileurl)
                        resreq.raise_for_status()

                        if verbose:
                            LOGINFO('TRILEGAL completed, retrieving results...')

                        # stream the response to the output cache file
                        with gzip.open(cachefname,'wb') as outfd:
                            for chunk in resreq.iter_content(chunk_size=65536):
                                outfd.write(chunk)

                        tablefname = cachefname
                        waitdone = True
                        if verbose:
                            LOGINFO('done.')

                    except Exception as e:

                        if verbose:
                            LOGINFO('elapsed time: %.1f, result file: %s '
                                    'not ready yet...'
                                    % (timeelapsed, resultfileurl))
                        continue

            else:

                LOGERROR('no result file URL found in TRILEGAL output, '
                         'this is probably an error with the input. '
                         'HTML of error page follows:\n')
                LOGINFO(resp)
                # remove the lock file
                if os.path.exists(lockfile):
                    os.remove(lockfile)
                return None


        except requests.exceptions.Timeout as e:
            LOGERROR('TRILEGAL submission timed out, '
                     'site is probably down. Request was: '
                     '%s' % repr(inputparams))
            return None

        except Exception as e:
            LOGEXCEPTION('TRILEGAL request failed for '
                         '%s' % repr(inputparams))
            return None

        finally:

            # remove the lock file
            if os.path.exists(lockfile):
                os.remove(lockfile)


    # otherwise, get the file from the cache
    else:

        if verbose:
            LOGINFO('getting cached TRILEGAL model result for '
                    'request: %s' %
                    (repr(inputparams)))

        tablefname = cachefname


    # return a dict pointing to the result file
    # we'll parse this later
    resdict = {'params':inputparams,
               'extraparams':extraparams,
               'provenance':provenance,
               'tablefile':tablefname}

    return resdict
def query_galcoords ( gal_lon , gal_lat , filtersystem = 'sloan_2mass' , field_deg2 = 1.0 , usebinaries = True , extinction_sigma = 0.1 , magnitude_limit = 26.0 , maglim_filtercol = 4 , trilegal_version = 1.6 , extraparams = None , forcefetch = False , cachedir = '~/.astrobase/trilegal-cache' , verbose = True , timeout = 60.0 , refresh = 150.0 , maxtimeout = 700.0 ) : # these are the default parameters inputparams = copy . deepcopy ( TRILEGAL_INPUT_PARAMS ) # update them with the input params inputparams [ 'binary_kind' ] = '1' if usebinaries else '0' inputparams [ 'extinction_sigma' ] = '%.2f' % extinction_sigma inputparams [ 'field' ] = '%.2f' % field_deg2 inputparams [ 'icm_lim' ] = str ( maglim_filtercol ) inputparams [ 'mag_lim' ] = '%.2f' % magnitude_limit inputparams [ 'trilegal_version' ] = str ( trilegal_version ) # get the coordinates inputparams [ 'gc_l' ] = '%.3f' % gal_lon inputparams [ 'gc_b' ] = '%.3f' % gal_lat # check if the area is less than 10 deg^2 if field_deg2 > 10.0 : LOGERROR ( "can't have an area > 10 square degrees" ) return None # get the extinction parameter. this is by default A[inf] in V. we'll use # the value from SF11 generated by the 2MASS DUST service extinction_info = dust . extinction_query ( gal_lon , gal_lat , coordtype = 'galactic' , forcefetch = forcefetch , verbose = verbose , timeout = timeout ) try : Av_infinity = extinction_info [ 'Amag' ] [ 'CTIO V' ] [ 'sf11' ] inputparams [ 'extinction_infty' ] = '%.5f' % Av_infinity except Exception as e : LOGEXCEPTION ( 'could not get A_V_SF11 from 2MASS DUST ' 'for Galactic coords: (%.3f, %.3f), ' 'using default value of %s' % ( gal_lon , gal_lat , inputparams [ 'extinction_infty' ] ) ) # get the filter system table if filtersystem in TRILEGAL_FILTER_SYSTEMS : inputparams [ 'photsys_file' ] = ( TRILEGAL_FILTER_SYSTEMS [ filtersystem ] [ 'table' ] ) else : LOGERROR ( 'filtersystem name: %s is not in the table of known ' 'filter systems.\n' 'Try the trilegal.list_trilegal_filtersystems() function ' 'to see all available filter systems.' % filtersystem ) return None # override the complete form param dict now with our params trilegal_params = copy . deepcopy ( TRILEGAL_DEFAULT_PARAMS ) trilegal_params . update ( inputparams ) # override the final params with any extraparams if extraparams and isinstance ( extraparams , dict ) : trilegal_params . update ( extraparams ) # see if the cachedir exists if '~' in cachedir : cachedir = os . path . expanduser ( cachedir ) if not os . path . exists ( cachedir ) : os . makedirs ( cachedir ) # generate the cachefname and look for it cachekey = repr ( inputparams ) cachekey = hashlib . sha256 ( cachekey . encode ( ) ) . hexdigest ( ) cachefname = os . path . join ( cachedir , '%s.txt.gz' % cachekey ) provenance = 'cache' lockfile = os . path . join ( cachedir , 'LOCK-%s' % cachekey ) # run the query if results not found in the cache if forcefetch or ( not os . path . exists ( cachefname ) ) : # first, check if a query like this is running already if os . path . exists ( lockfile ) : with open ( lockfile , 'r' ) as infd : lock_contents = infd . read ( ) lock_contents = lock_contents . replace ( '\n' , '' ) LOGERROR ( 'this query appears to be active since %s' 'in another instance, not running it again' % lock_contents ) return None else : with open ( lockfile , 'w' ) as outfd : outfd . write ( datetime . utcnow ( ) . isoformat ( ) ) provenance = 'new download' try : if verbose : LOGINFO ( 'submitting TRILEGAL request for input params: %s' % repr ( inputparams ) ) posturl = TRILEGAL_POSTURL . format ( formversion = trilegal_version ) req = requests . post ( posturl , data = trilegal_params , timeout = timeout ) resp = req . text # get the URL of the result file resultfile = TRILEGAL_REGEX . search ( resp ) if resultfile : resultfile = resultfile [ 0 ] waitdone = False timeelapsed = 0.0 resultfileurl = '%s/%s' % ( TRILEGAL_BASEURL , resultfile . replace ( 'a href=..' , '' ) ) if verbose : LOGINFO ( 'request submitted sucessfully, waiting for results...' ) # wait for 2 minutes, then try to download the result file while not waitdone : if timeelapsed > maxtimeout : LOGERROR ( 'TRILEGAL timed out after waiting for results,' ' request was: ' '%s' % repr ( inputparams ) ) # remove the lock file if os . path . exists ( lockfile ) : os . remove ( lockfile ) return None time . sleep ( refresh ) timeelapsed = timeelapsed + refresh try : resreq = requests . get ( resultfileurl ) resreq . raise_for_status ( ) if verbose : LOGINFO ( 'TRILEGAL completed, retrieving results...' ) # stream the response to the output cache file with gzip . open ( cachefname , 'wb' ) as outfd : for chunk in resreq . iter_content ( chunk_size = 65536 ) : outfd . write ( chunk ) tablefname = cachefname waitdone = True if verbose : LOGINFO ( 'done.' ) except Exception as e : if verbose : LOGINFO ( 'elapsed time: %.1f, result file: %s ' 'not ready yet...' % ( timeelapsed , resultfileurl ) ) continue else : LOGERROR ( 'no result file URL found in TRILEGAL output, ' 'this is probably an error with the input. ' 'HTML of error page follows:\n' ) LOGINFO ( resp ) # remove the lock file if os . path . exists ( lockfile ) : os . remove ( lockfile ) return None except requests . exceptions . Timeout as e : LOGERROR ( 'TRILEGAL submission timed out, ' 'site is probably down. Request was: ' '%s' % repr ( inputparams ) ) return None except Exception as e : LOGEXCEPTION ( 'TRILEGAL request failed for ' '%s' % repr ( inputparams ) ) return None finally : # remove the lock file if os . path . exists ( lockfile ) : os . remove ( lockfile ) # otherwise, get the file from the cache else : if verbose : LOGINFO ( 'getting cached TRILEGAL model result for ' 'request: %s' % ( repr ( inputparams ) ) ) tablefname = cachefname # return a dict pointing to the result file # we'll parse this later resdict = { 'params' : inputparams , 'extraparams' : extraparams , 'provenance' : provenance , 'tablefile' : tablefname } return resdict
This queries the TRILEGAL model form, downloads results, and parses them.

    Parameters
    ----------

    gal_lon,gal_lat : float
        These are the center galactic longitude and latitude in degrees.

    filtersystem : str
        This is a key in the TRILEGAL_FILTER_SYSTEMS dict. Use the function
        :py:func:`astrobase.services.trilegal.list_trilegal_filtersystems` to
        see a nicely formatted table with the key and description for each of
        these.

    field_deg2 : float
        The area of the simulated field in square degrees.

    usebinaries : bool
        If this is True, binaries will be present in the model results.

    extinction_sigma : float
        This is the applied std dev around the `Av_extinction` value for the
        galactic coordinates requested.

    magnitude_limit : float
        This is the limiting magnitude of the simulation in the
        `maglim_filtercol` band index of the filter system chosen.

    maglim_filtercol : int
        The index in the filter system list of the magnitude limiting band.

    trilegal_version : float
        This is the the version of the TRILEGAL form to use. This can usually be
        left as-is.

    extraparams : dict or None
        This is a dict that can be used to override parameters of the model
        other than the basic ones used for input to this function. All
        parameters are listed in `TRILEGAL_DEFAULT_PARAMS` above. See:

        http://stev.oapd.inaf.it/cgi-bin/trilegal

        for explanations of these parameters.

    forcefetch : bool
        If this is True, the query will be retried even if cached results for
        it exist.

    cachedir : str
        This points to the directory where results will be downloaded.

    verbose : bool
        If True, will indicate progress and warn of any issues.

    timeout : float
        This sets the amount of time in seconds to wait for the service to
        respond to our initial request.

    refresh : float
        This sets the amount of time in seconds to wait before checking if the
        result file is available. If the results file isn't available after
        `refresh` seconds have elapsed, the function will wait for `refresh`
        seconds continuously, until `maxtimeout` is reached or the results file
        becomes available.

    maxtimeout : float
        The maximum amount of time in seconds to wait for a result to become
        available after submitting our query request.

    Returns
    -------

    dict
        This returns a dict of the form::

            {'params':the input param dict used,
             'extraparams':any extra params used,
             'provenance':'cached' or 'new download',
             'tablefile':the path on disk to the downloaded model text file}
This queries the TRILEGAL model form downloads results and parses them .