<EOL>if fast_mode is True:<EOL><INDENT>skyview_lookup = False<EOL>skyview_timeout = <NUM_LIT><EOL>skyview_retry_failed = False<EOL>dust_timeout = <NUM_LIT><EOL>gaia_submit_timeout = <NUM_LIT><EOL>gaia_max_timeout = <NUM_LIT><EOL>gaia_submit_tries = <NUM_LIT:2><EOL>complete_query_later = False<EOL>search_simbad = False<EOL><DEDENT>elif isinstance(fast_mode, (int, float)) and fast_mode > <NUM_LIT:0.0>:<EOL><INDENT>skyview_lookup = True<EOL>skyview_timeout = fast_mode<EOL>skyview_retry_failed = False<EOL>dust_timeout = fast_mode<EOL>gaia_submit_timeout = <NUM_LIT>*fast_mode<EOL>gaia_max_timeout = fast_mode<EOL>gaia_submit_tries = <NUM_LIT:2><EOL>complete_query_later = False<EOL>search_simbad = False<EOL><DEDENT>else:<EOL><INDENT>skyview_lookup = True<EOL>skyview_timeout = <NUM_LIT><EOL>skyview_retry_failed = True<EOL>dust_timeout = <NUM_LIT><EOL>search_simbad = True<EOL><DEDENT>if (isinstance(objectinfo, dict) and<EOL>('<STR_LIT>' in objectinfo or '<STR_LIT>' in objectinfo) and<EOL>'<STR_LIT>' in objectinfo and '<STR_LIT>' in objectinfo and<EOL>objectinfo['<STR_LIT>'] and objectinfo['<STR_LIT>']):<EOL><INDENT>if '<STR_LIT>' not in objectinfo:<EOL><INDENT>objectid = objectinfo['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>objectid = objectinfo['<STR_LIT>']<EOL><DEDENT>if verbose and skyview_lookup:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(objectid, objectinfo['<STR_LIT>'], objectinfo['<STR_LIT>']))<EOL><DEDENT>elif verbose and not skyview_lookup:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(objectid, objectinfo['<STR_LIT>'], objectinfo['<STR_LIT>']))<EOL><DEDENT>try:<EOL><INDENT>if skyview_lookup:<EOL><INDENT>try:<EOL><INDENT>finder, finderheader = skyview_stamp(<EOL>objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>'],<EOL>convolvewith=finderconvolve,<EOL>verbose=verbose,<EOL>flip=False,<EOL>cachedir=findercachedir,<EOL>timeout=skyview_timeout,<EOL>retry_failed=skyview_retry_failed,<EOL>)<EOL><DEDENT>except OSError as e:<EOL><INDENT>if not fast_mode:<EOL><INDENT>LOGERROR(<EOL>'<STR_LIT>'<EOL>)<EOL>finder, finderheader = skyview_stamp(<EOL>objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>'],<EOL>convolvewith=finderconvolve,<EOL>verbose=verbose,<EOL>flip=False,<EOL>cachedir=findercachedir,<EOL>forcefetch=True,<EOL>timeout=skyview_timeout,<EOL>retry_failed=False  <EOL>)<EOL><DEDENT><DEDENT>finderfig = plt.figure(figsize=(<NUM_LIT:3>,<NUM_LIT:3>),dpi=plotdpi)<EOL>finderwcs = WCS(finderheader)<EOL>ax = finderfig.add_subplot(<NUM_LIT>, frameon=False)<EOL>ax.imshow(finder, cmap=findercmap, origin='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>finder, finderheader, finderfig, finderwcs = (<EOL>None, None, None, None<EOL>)<EOL><DEDENT>if (lclistpkl is not None and<EOL>nbrradiusarcsec is not None and<EOL>nbrradiusarcsec > <NUM_LIT:0.0>):<EOL><INDENT>if isinstance(lclistpkl, str) and os.path.exists(lclistpkl):<EOL><INDENT>if lclistpkl.endswith('<STR_LIT>'):<EOL><INDENT>infd = gzip.open(lclistpkl,'<STR_LIT:rb>')<EOL><DEDENT>else:<EOL><INDENT>infd = open(lclistpkl,'<STR_LIT:rb>')<EOL><DEDENT>lclist = pickle.load(infd)<EOL>infd.close()<EOL><DEDENT>elif isinstance(lclistpkl, dict):<EOL><INDENT>lclist = lclistpkl<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>lclist = dict()<EOL><DEDENT>if '<STR_LIT>' not in lclist:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (objectid, lclistpkl))<EOL>neighbors = None<EOL>kdt = None<EOL><DEDENT>else:<EOL><INDENT>kdt = lclist['<STR_LIT>']<EOL>obj_cosdecl = np.cos(np.radians(objectinfo['<STR_LIT>']))<EOL>obj_sindecl = np.sin(np.radians(objectinfo['<STR_LIT>']))<EOL>obj_cosra = np.cos(np.radians(objectinfo['<STR_LIT>']))<EOL>obj_sinra = np.sin(np.radians(objectinfo['<STR_LIT>']))<EOL>obj_xyz = np.column_stack((obj_cosra*obj_cosdecl,<EOL>obj_sinra*obj_cosdecl,<EOL>obj_sindecl))<EOL>match_xyzdist = (<EOL><NUM_LIT> * np.sin(np.radians(nbrradiusarcsec/<NUM_LIT>)/<NUM_LIT>)<EOL>)<EOL>matchdists, matchinds = kdt.query(<EOL>obj_xyz,<EOL>k=maxnumneighbors+<NUM_LIT:1>,  <EOL>distance_upper_bound=match_xyzdist<EOL>)<EOL>mdsorted = np.argsort(matchdists[<NUM_LIT:0>])<EOL>matchdists = matchdists[<NUM_LIT:0>][mdsorted]<EOL>matchinds = matchinds[<NUM_LIT:0>][mdsorted]<EOL>neighbors = []<EOL>nbrind = <NUM_LIT:0><EOL>for md, mi in zip(matchdists, matchinds):<EOL><INDENT>if np.isfinite(md) and md > <NUM_LIT:0.0>:<EOL><INDENT>if skyview_lookup:<EOL><INDENT>pixcoords = finderwcs.all_world2pix(<EOL>np.array([[lclist['<STR_LIT>']['<STR_LIT>'][mi],<EOL>lclist['<STR_LIT>']['<STR_LIT>'][mi]]]),<EOL><NUM_LIT:0><EOL>)<EOL>thisnbr = {<EOL>'<STR_LIT>':(<EOL>lclist['<STR_LIT>']['<STR_LIT>'][mi]<EOL>),<EOL>'<STR_LIT>':lclist['<STR_LIT>']['<STR_LIT>'][mi],<EOL>'<STR_LIT>':lclist['<STR_LIT>']['<STR_LIT>'][mi],<EOL>'<STR_LIT>':pixcoords[<NUM_LIT:0>,<NUM_LIT:0>],<EOL>'<STR_LIT>':<NUM_LIT> - pixcoords[<NUM_LIT:0>,<NUM_LIT:1>],<EOL>'<STR_LIT>':_xyzdist_to_distarcsec(md),<EOL>'<STR_LIT>': lclist['<STR_LIT>']['<STR_LIT>'][mi]<EOL>}<EOL>neighbors.append(thisnbr)<EOL>nbrind = nbrind+<NUM_LIT:1><EOL>annotatex = pixcoords[<NUM_LIT:0>,<NUM_LIT:0>]<EOL>annotatey = pixcoords[<NUM_LIT:0>,<NUM_LIT:1>]<EOL>if ((<NUM_LIT> - annotatex) > <NUM_LIT>):<EOL><INDENT>offx = annotatex + <NUM_LIT><EOL>xha = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>offx = annotatex - <NUM_LIT><EOL>xha = '<STR_LIT>'<EOL><DEDENT>if ((<NUM_LIT> - annotatey) > <NUM_LIT>):<EOL><INDENT>offy = annotatey - <NUM_LIT><EOL>yha = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>offy = annotatey + <NUM_LIT><EOL>yha = '<STR_LIT>'<EOL><DEDENT>ax.annotate('<STR_LIT>' % nbrind,<EOL>(annotatex, annotatey),<EOL>xytext=(offx, offy),<EOL>arrowprops={'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT:width>':<NUM_LIT:1.0>,<EOL>'<STR_LIT>':<NUM_LIT:1.0>,<EOL>'<STR_LIT>':<NUM_LIT:0.1>,<EOL>'<STR_LIT>':<NUM_LIT:0.0>},<EOL>color='<STR_LIT>',<EOL>horizontalalignment=xha,<EOL>verticalalignment=yha)<EOL><DEDENT>else:<EOL><INDENT>thisnbr = {<EOL>'<STR_LIT>':(<EOL>lclist['<STR_LIT>']['<STR_LIT>'][mi]<EOL>),<EOL>'<STR_LIT>':lclist['<STR_LIT>']['<STR_LIT>'][mi],<EOL>'<STR_LIT>':lclist['<STR_LIT>']['<STR_LIT>'][mi],<EOL>'<STR_LIT>':<NUM_LIT:0.0>,<EOL>'<STR_LIT>':<NUM_LIT:0.0>,<EOL>'<STR_LIT>':_xyzdist_to_distarcsec(md),<EOL>'<STR_LIT>': lclist['<STR_LIT>']['<STR_LIT>'][mi]<EOL>}<EOL>neighbors.append(thisnbr)<EOL>nbrind = nbrind+<NUM_LIT:1><EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>neighbors = None<EOL>kdt = None<EOL><DEDENT>if skyview_lookup:<EOL><INDENT>ax.set_xticks([])<EOL>ax.set_yticks([])<EOL>object_pixcoords = finderwcs.all_world2pix(<EOL>[[objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>']]],<EOL><NUM_LIT:0><EOL>)<EOL>ax.axvline(<EOL>x=object_pixcoords[<NUM_LIT:0>,<NUM_LIT:0>],<EOL>ymin=<NUM_LIT>,<EOL>ymax=<NUM_LIT>,<EOL>linewidth=<NUM_LIT:1>,<EOL>color='<STR_LIT:b>'<EOL>)<EOL>ax.axhline(<EOL>y=object_pixcoords[<NUM_LIT:0>,<NUM_LIT:1>],<EOL>xmin=<NUM_LIT>,<EOL>xmax=<NUM_LIT>,<EOL>linewidth=<NUM_LIT:1>,<EOL>color='<STR_LIT:b>'<EOL>)<EOL>ax.set_frame_on(False)<EOL>finderpng = StrIO()<EOL>finderfig.savefig(finderpng,<EOL>bbox_inches='<STR_LIT>',<EOL>pad_inches=<NUM_LIT:0.0>, format='<STR_LIT>')<EOL>plt.close()<EOL>finderpng.seek(<NUM_LIT:0>)<EOL>finderb64 = base64.b64encode(finderpng.read())<EOL>finderpng.close()<EOL><DEDENT>else:<EOL><INDENT>finderb64 = None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(objectid, objectinfo['<STR_LIT>'], objectinfo['<STR_LIT>']))<EOL>finderb64 = None<EOL>neighbors = None<EOL>kdt = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>finderb64 = None<EOL>neighbors = None<EOL>kdt = None<EOL><DEDENT>if isinstance(objectinfo, dict):<EOL><INDENT>if '<STR_LIT>' not in objectinfo and '<STR_LIT>' in objectinfo:<EOL><INDENT>objectid = objectinfo['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = objectid<EOL><DEDENT>elif '<STR_LIT>' in objectinfo:<EOL><INDENT>objectid = objectinfo['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>objectid = os.urandom(<NUM_LIT:12>).hex()[:<NUM_LIT:7>]<EOL>objectinfo['<STR_LIT>'] = objectid<EOL>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>nbrfeat = neighbor_gaia_features(<EOL>objectinfo,<EOL>kdt,<EOL>nbrradiusarcsec,<EOL>verbose=False,<EOL>gaia_submit_timeout=gaia_submit_timeout,<EOL>gaia_submit_tries=gaia_submit_tries,<EOL>gaia_max_timeout=gaia_max_timeout,<EOL>gaia_mirror=gaia_mirror,<EOL>complete_query_later=complete_query_later,<EOL>search_simbad=search_simbad<EOL>)<EOL>objectinfo.update(nbrfeat)<EOL>if ( ('<STR_LIT>' not in objectinfo) or<EOL>( ('<STR_LIT>' in objectinfo) and<EOL>( (objectinfo['<STR_LIT>'] is None) or<EOL>(not np.isfinite(objectinfo['<STR_LIT>'])) ) ) ):<EOL><INDENT>if '<STR_LIT>' in nbrfeat['<STR_LIT>']:<EOL><INDENT>objectinfo['<STR_LIT>'] = nbrfeat['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = nbrfeat['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = '<STR_LIT>'<EOL>if verbose:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>objectinfo['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT>if ( ('<STR_LIT>' not in objectinfo) or<EOL>( ('<STR_LIT>' in objectinfo) and<EOL>( (objectinfo['<STR_LIT>'] is None) or<EOL>(not np.isfinite(objectinfo['<STR_LIT>'])) ) ) ):<EOL><INDENT>if '<STR_LIT>' in nbrfeat['<STR_LIT>']:<EOL><INDENT>objectinfo['<STR_LIT>'] = nbrfeat['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = nbrfeat['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = '<STR_LIT>'<EOL>if verbose:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>objectinfo['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT>if '<STR_LIT>' in objectinfo['<STR_LIT>']:<EOL><INDENT>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = (<EOL>objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>)<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL>objectinfo['<STR_LIT>'] = objectinfo['<STR_LIT>'][<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>objectinfo['<STR_LIT>'] = None<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL>objectinfo['<STR_LIT>'] = np.nan<EOL><DEDENT>if ('<STR_LIT>' in objectinfo and<EOL>objectinfo['<STR_LIT>'] is not None and<EOL>np.isfinite(objectinfo['<STR_LIT>']) and<EOL>'<STR_LIT>' in objectinfo and<EOL>objectinfo['<STR_LIT>'] is not None and<EOL>np.isfinite(objectinfo['<STR_LIT>'])):<EOL><INDENT>try:<EOL><INDENT>ticres = tic_conesearch(objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>'],<EOL>radius_arcmin=<NUM_LIT>/<NUM_LIT>,<EOL>verbose=verbose,<EOL>timeout=gaia_max_timeout,<EOL>maxtries=gaia_submit_tries)<EOL>if ticres is not None:<EOL><INDENT>with open(ticres['<STR_LIT>'],'<STR_LIT:r>') as infd:<EOL><INDENT>ticinfo = json.load(infd)<EOL><DEDENT>if ('<STR_LIT:data>' in ticinfo and<EOL>len(ticinfo['<STR_LIT:data>']) > <NUM_LIT:0> and<EOL>isinstance(ticinfo['<STR_LIT:data>'][<NUM_LIT:0>], dict)):<EOL><INDENT>objectinfo['<STR_LIT>'] = str(ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>'])<EOL>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT:version>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT:d>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>if (objectinfo['<STR_LIT>'] is not None and<EOL>np.isfinite(objectinfo['<STR_LIT>']) and<EOL>objectinfo['<STR_LIT>'] is not None and<EOL>np.isfinite(objectinfo['<STR_LIT>'])):<EOL><INDENT>objectinfo['<STR_LIT>'] = (<EOL>magnitudes.absolute_gaia_magnitude(<EOL>objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>']<EOL>)<EOL>)<EOL><DEDENT><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL>objectinfo['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT>if ('<STR_LIT>' not in objectinfo or<EOL>('<STR_LIT>' in objectinfo and<EOL>(objectinfo['<STR_LIT>'] is None or<EOL>not np.isfinite(objectinfo['<STR_LIT>'])))):<EOL><INDENT>objectinfo['<STR_LIT>'] = ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>objectinfo['<STR_LIT>'] = (<EOL>ticinfo['<STR_LIT:data>'][<NUM_LIT:0>]['<STR_LIT>']<EOL>)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>']))<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>'],<EOL>objectinfo['<STR_LIT>']))<EOL><DEDENT><DEDENT>coordfeat = coord_features(objectinfo)<EOL>colorfeat = color_features(objectinfo,<EOL>deredden=deredden_object,<EOL>custom_bandpasses=custom_bandpasses,<EOL>dust_timeout=dust_timeout)<EOL>colorclass = color_classification(colorfeat, coordfeat)<EOL>objectinfo.update(colorfeat)<EOL>objectinfo.update(coordfeat)<EOL>objectinfo.update(colorclass)<EOL>checkplotdict = {'<STR_LIT>':objectid,<EOL>'<STR_LIT>':neighbors,<EOL>'<STR_LIT>':objectinfo,<EOL>'<STR_LIT>':finderb64,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':normto,<EOL>'<STR_LIT>':normmingap}<EOL>checkplotdict['<STR_LIT>']['<STR_LIT>'] = None<EOL><DEDENT>else:<EOL><INDENT>checkplotdict = {'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':[],<EOL>'<STR_LIT>':[],<EOL>'<STR_LIT>':[],<EOL>'<STR_LIT>':[],<EOL>'<STR_LIT>':[],<EOL>'<STR_LIT>':[],<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None<EOL>},<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':normto,<EOL>'<STR_LIT>':normmingap}<EOL><DEDENT>if isinstance(varinfo, dict):<EOL><INDENT>checkplotdict['<STR_LIT>'] = varinfo<EOL><DEDENT>else:<EOL><INDENT>checkplotdict['<STR_LIT>'] = {<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>}<EOL><DEDENT>return checkplotdict<EOL>

This returns the finder chart and object information as a dict.

    Parameters
    ----------

    objectinfo : dict or None
        If provided, this is a dict containing information on the object whose
        light curve is being processed. This function will then be able to look
        up and download a finder chart for this object and write that to the
        output checkplotdict. External services such as GAIA, SIMBAD, TIC@MAST,
        etc. will also be used to look up this object by its coordinates, and
        will add in information available from those services.

        The `objectinfo` dict must be of the form and contain at least the keys
        described below::

            {'objectid': the name of the object,
             'ra': the right ascension of the object in decimal degrees,
             'decl': the declination of the object in decimal degrees,
             'ndet': the number of observations of this object}

        You can also provide magnitudes and proper motions of the object using
        the following keys and the appropriate values in the `objectinfo`
        dict. These will be used to calculate colors, total and reduced proper
        motion, etc. and display these in the output checkplot PNG::

            'pmra' -> the proper motion in mas/yr in right ascension,
            'pmdecl' -> the proper motion in mas/yr in declination,
            'umag'  -> U mag		 -> colors: U-B, U-V, U-g
            'bmag'  -> B mag		 -> colors: U-B, B-V
            'vmag'  -> V mag		 -> colors: U-V, B-V, V-R, V-I, V-K
            'rmag'  -> R mag		 -> colors: V-R, R-I
            'imag'  -> I mag		 -> colors: g-I, V-I, R-I, B-I
            'jmag'  -> 2MASS J mag	 -> colors: J-H, J-K, g-J, i-J
            'hmag'  -> 2MASS H mag	 -> colors: J-H, H-K
            'kmag'  -> 2MASS Ks mag	 -> colors: g-Ks, H-Ks, J-Ks, V-Ks
            'sdssu' -> SDSS u mag	 -> colors: u-g, u-V
            'sdssg' -> SDSS g mag	 -> colors: g-r, g-i, g-K, u-g, U-g, g-J
            'sdssr' -> SDSS r mag	 -> colors: r-i, g-r
            'sdssi' -> SDSS i mag	 -> colors: r-i, i-z, g-i, i-J, i-W1
            'sdssz' -> SDSS z mag	 -> colors: i-z, z-W2, g-z
            'ujmag' -> UKIRT J mag	 -> colors: J-H, H-K, J-K, g-J, i-J
            'uhmag' -> UKIRT H mag	 -> colors: J-H, H-K
            'ukmag' -> UKIRT K mag	 -> colors: g-K, H-K, J-K, V-K
            'irac1' -> Spitzer IRAC1 mag -> colors: i-I1, I1-I2
            'irac2' -> Spitzer IRAC2 mag -> colors: I1-I2, I2-I3
            'irac3' -> Spitzer IRAC3 mag -> colors: I2-I3
            'irac4' -> Spitzer IRAC4 mag -> colors: I3-I4
            'wise1' -> WISE W1 mag	 -> colors: i-W1, W1-W2
            'wise2' -> WISE W2 mag	 -> colors: W1-W2, W2-W3
            'wise3' -> WISE W3 mag	 -> colors: W2-W3
            'wise4' -> WISE W4 mag	 -> colors: W3-W4

        If you have magnitude measurements in other bands, use the
        `custom_bandpasses` kwarg to pass these in.

        If this is None, no object information will be incorporated into the
        checkplot (kind of making it effectively useless for anything other than
        glancing at the phased light curves at various 'best' periods from the
        period-finder results).

    varinfo : dict or None
        If this is None, a blank dict of the form below will be added to the
        checkplotdict::

            {'objectisvar': None -> variability flag (None indicates unset),
             'vartags': CSV str containing variability type tags from review,
             'varisperiodic': None -> periodic variability flag (None -> unset),
             'varperiod': the period associated with the periodic variability,
             'varepoch': the epoch associated with the periodic variability}

        If you provide a dict matching this format in this kwarg, this will be
        passed unchanged to the output checkplotdict produced.

    findercmap : str or matplotlib.cm.ColorMap object
        The Colormap object to use for the finder chart image.

    finderconvolve : astropy.convolution.Kernel object or None
        If not None, the Kernel object to use for convolving the finder image.

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    normto : {'globalmedian', 'zero'} or a float
        This is specified as below::

            'globalmedian' -> norms each mag to global median of the LC column
            'zero'         -> norms each mag to zero
            a float        -> norms each mag to this specified float value.

    normmingap : float
        This defines how much the difference between consecutive measurements is
        allowed to be to consider them as parts of different timegroups. By
        default it is set to 4.0 days.

    deredden_object : bool
        If this is True, will use the 2MASS DUST service to get extinction
        coefficients in various bands, and then try to deredden the magnitudes
        and colors of the object already present in the checkplot's objectinfo
        dict.

    custom_bandpasses : dict
        This is a dict used to provide custom bandpass definitions for any
        magnitude measurements in the objectinfo dict that are not automatically
        recognized by :py:func:`astrobase.varclass.starfeatures.color_features`.

    lclistpkl : dict or str
        If this is provided, must be a dict resulting from reading a catalog
        produced by the `lcproc.catalogs.make_lclist` function or a str path
        pointing to the pickle file produced by that function. This catalog is
        used to find neighbors of the current object in the current light curve
        collection. Looking at neighbors of the object within the radius
        specified by `nbrradiusarcsec` is useful for light curves produced by
        instruments that have a large pixel scale, so are susceptible to
        blending of variability and potential confusion of neighbor variability
        with that of the actual object being looked at. If this is None, no
        neighbor lookups will be performed.

    nbrradiusarcsec : float
        The radius in arcseconds to use for a search conducted around the
        coordinates of this object to look for any potential confusion and
        blending of variability amplitude caused by their proximity.

    maxnumneighbors : int
        The maximum number of neighbors that will have their light curves and
        magnitudes noted in this checkplot as potential blends with the target
        object.

    plotdpi : int
        The resolution in DPI of the plots to generate in this function
        (e.g. the finder chart, etc.)

    findercachedir : str
        The path to the astrobase cache directory for finder chart downloads
        from the NASA SkyView service.

    verbose : bool
        If True, will indicate progress and warn about potential problems.

    gaia_submit_timeout : float
        Sets the timeout in seconds to use when submitting a request to look up
        the object's information to the GAIA service. Note that if `fast_mode`
        is set, this is ignored.

    gaia_submit_tries : int
        Sets the maximum number of times the GAIA services will be contacted to
        obtain this object's information. If `fast_mode` is set, this is
        ignored, and the services will be contacted only once (meaning that a
        failure to respond will be silently ignored and no GAIA data will be
        added to the checkplot's objectinfo dict).

    gaia_max_timeout : float
        Sets the timeout in seconds to use when waiting for the GAIA service to
        respond to our request for the object's information. Note that if
        `fast_mode` is set, this is ignored.

    gaia_mirror : str
        This sets the GAIA mirror to use. This is a key in the
        `services.gaia.GAIA_URLS` dict which defines the URLs to hit for each
        mirror.

    fast_mode : bool or float
        This runs the external catalog operations in a "fast" mode, with short
        timeouts and not trying to hit external catalogs that take a long time
        to respond.

        If this is set to True, the default settings for the external requests
        will then become::

            skyview_lookup = False
            skyview_timeout = 10.0
            skyview_retry_failed = False
            dust_timeout = 10.0
            gaia_submit_timeout = 7.0
            gaia_max_timeout = 10.0
            gaia_submit_tries = 2
            complete_query_later = False
            search_simbad = False

        If this is a float, will run in "fast" mode with the provided timeout
        value in seconds and the following settings::

            skyview_lookup = True
            skyview_timeout = fast_mode
            skyview_retry_failed = False
            dust_timeout = fast_mode
            gaia_submit_timeout = 0.66*fast_mode
            gaia_max_timeout = fast_mode
            gaia_submit_tries = 2
            complete_query_later = False
            search_simbad = False

    complete_query_later : bool
        If this is True, saves the state of GAIA queries that are not yet
        complete when `gaia_max_timeout` is reached while waiting for the GAIA
        service to respond to our request. A later call for GAIA info on the
        same object will attempt to pick up the results from the existing query
        if it's completed. If `fast_mode` is True, this is ignored.

    Returns
    -------

    dict
        A checkplotdict is returned containing the objectinfo and varinfo dicts,
        ready to use with the functions below to add in light curve plots,
        phased LC plots, xmatch info, etc.


This publishes a JSON message to a topic.

TODO: finish this


if not client:<EOL><INDENT>if (service_account_json is not None and<EOL>os.path.exists(service_account_json)):<EOL><INDENT>client = storage.Client.from_service_account_json(<EOL>service_account_json<EOL>)<EOL><DEDENT>else:<EOL><INDENT>client = storage.Client()<EOL><DEDENT><DEDENT>try:<EOL><INDENT>bucket = client.get_bucket(bucketname)<EOL>blob = bucket.get_blob(filename)<EOL>blob.download_to_filename(local_file)<EOL>return local_file<EOL><DEDENT>except Exception as e:<EOL><INDENT>for alt_extension in altexts:<EOL><INDENT>split_ext = os.path.splitext(filename)<EOL>check_file = split_ext[<NUM_LIT:0>] + alt_extension<EOL>try:<EOL><INDENT>bucket = client.get_bucket(bucket)<EOL>blob = bucket.get_blob(check_file)<EOL>blob.download_to_filename(<EOL>local_file.replace(split_ext[-<NUM_LIT:1>],<EOL>alt_extension)<EOL>)<EOL>return local_file.replace(split_ext[-<NUM_LIT:1>],<EOL>alt_extension)<EOL><DEDENT>except Exception as e:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>' % (bucket, filename))<EOL>if raiseonfail:<EOL><INDENT>raise<EOL><DEDENT>return None<EOL><DEDENT>

This gets a single file from a Google Cloud Storage bucket.

    Parameters
    ----------

    bucketname : str
        The name of the GCS bucket to download the file from.

    filename : str
        The full name of the file to download, including all prefixes.

    local_file : str
        Path to where the downloaded file will be stored.

    altexts : None or list of str
        If not None, this is a list of alternate extensions to try for the file
        other than the one provided in `filename`. For example, to get anything
        that's an .sqlite where .sqlite.gz is expected, use altexts=[''] to
        strip the .gz.

    client : google.cloud.storage.Client instance
        The instance of the Client to use to perform the download operation. If
        this is None, a new Client will be used. If this is None and
        `service_account_json` points to a downloaded JSON file with GCS
        credentials, a new Client with the provided credentials will be used. If
        this is not None, the existing Client instance will be used.

    service_account_json : str
        Path to a downloaded GCS credentials JSON file.

    raiseonfail : bool
        If True, will re-raise whatever Exception caused the operation to fail
        and break out immediately.

    Returns
    -------

    str
        Path to the downloaded filename or None if the download was
        unsuccessful.


This deletes GCE worker nodes.

TODO: finish this


This synchronously pulls a single message from a pubsub topic.

TODO: finish this


tmids_obsd, t_starts, t_ends = (<EOL>given_lc_get_transit_tmids_tstarts_tends(<EOL>time, flux, err_flux, blsfit_savpath=blsfit_savpath,<EOL>trapfit_savpath=trapfit_savpath, magsarefluxes=magsarefluxes,<EOL>nworkers=nworkers, sigclip=sigclip, extra_maskfrac=extra_maskfrac<EOL>)<EOL>)<EOL>in_transit = np.zeros_like(time).astype(bool)<EOL>for t_start, t_end in zip(t_starts, t_ends):<EOL><INDENT>this_transit = ( (time > t_start) & (time < t_end) )<EOL>in_transit |= this_transit<EOL><DEDENT>out_of_transit = ~in_transit<EOL>if in_out_transit_savpath:<EOL><INDENT>_in_out_transit_plot(time, flux, in_transit, out_of_transit,<EOL>in_out_transit_savpath)<EOL><DEDENT>return time[out_of_transit], flux[out_of_transit], err_flux[out_of_transit]<EOL>

This gets the out-of-transit light curve points.

    Relevant during iterative masking of transits for multiple planet system
    search.

    Parameters
    ----------

    time,flux,err_flux : np.array
        The input flux time-series measurements and their associated measurement
        errors

    blsfit_savpath : str or None
        If provided as a str, indicates the path of the fit plot to make for a
        simple BLS model fit to the transit using the obtained period and epoch.

    trapfit_savpath : str or None
        If provided as a str, indicates the path of the fit plot to make for a
        trapezoidal transit model fit to the transit using the obtained period
        and epoch.

    in_out_transit_savpath : str or None
        If provided as a str, indicates the path of the plot file that will be
        made for a plot showing the in-transit points and out-of-transit points
        tagged separately.

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    magsarefluxes : bool
        This is by default True for this function, since it works on fluxes only
        at the moment.

    nworkers : int
        The number of parallel BLS period-finder workers to use.

    extra_maskfrac : float
        This is the separation (N) from in-transit points you desire, in units
        of the transit duration. `extra_maskfrac = 0` if you just want points
        inside transit, otherwise::

            t_starts = t_Is - N*tdur, t_ends = t_IVs + N*tdur

        Thus setting N=0.03 masks slightly more than the guessed transit
        duration.

    Returns
    -------

    (times_oot, fluxes_oot, errs_oot) : tuple of np.array
        The `times`, `flux`, `err_flux` values from the input at the time values
        out-of-transit are returned.


if magsarefluxes:<EOL><INDENT>if not np.isclose(np.nanmedian(modelmags), <NUM_LIT:1>, atol=atol_normalization):<EOL><INDENT>raise AssertionError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise NotImplementedError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>if not transitdepth:<EOL><INDENT>transitdepth = np.abs(np.max(modelmags) - np.min(modelmags))<EOL><DEDENT>if not len(mags) == len(modelmags):<EOL><INDENT>from scipy.interpolate import interp1d<EOL>fn = interp1d(modeltimes, modelmags, kind='<STR_LIT>', bounds_error=True,<EOL>fill_value=np.nan)<EOL>modelmags = fn(times)<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>')<EOL><DEDENT><DEDENT>subtractedmags = mags - modelmags<EOL>if isinstance(indsforrms, np.ndarray):<EOL><INDENT>subtractedrms = np.std(subtractedmags[indsforrms])<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>')<EOL><DEDENT><DEDENT>else:<EOL><INDENT>subtractedrms = np.std(subtractedmags)<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>')<EOL><DEDENT><DEDENT>def _get_npoints_in_transit(modelmags):<EOL><INDENT>if np.nanmedian(modelmags) == <NUM_LIT:1>:<EOL><INDENT>return len(modelmags[(modelmags != <NUM_LIT:1>)])<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError<EOL><DEDENT><DEDENT>if not npoints_in_transit:<EOL><INDENT>npoints_in_transit = _get_npoints_in_transit(modelmags)<EOL><DEDENT>snr = np.sqrt(npoints_in_transit) * transitdepth/subtractedrms<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'.format(npoints_in_transit) +<EOL>'<STR_LIT>'.format(transitdepth) +<EOL>'<STR_LIT>'.format(subtractedrms) +<EOL>'<STR_LIT>'.format(snr))<EOL><DEDENT>return snr, transitdepth, subtractedrms<EOL>

Calculate the total SNR of a transit assuming gaussian uncertainties.

    `modelmags` gets interpolated onto the cadence of `mags`. The noise is
    calculated as the 1-sigma std deviation of the residual (see below).

    Following Carter et al. 2009::

        Q = sqrt( Γ T ) * δ / σ

    for Q the total SNR of the transit in the r->0 limit, where::

        r = Rp/Rstar,
        T = transit duration,
        δ = transit depth,
        σ = RMS of the lightcurve in transit.
        Γ = sampling rate

    Thus Γ * T is roughly the number of points obtained during transit.
    (This doesn't correctly account for the SNR during ingress/egress, but this
    is a second-order correction).

    Note this is the same total SNR as described by e.g., Kovacs et al. 2002,
    their Equation 11.

    NOTE: this only works with fluxes at the moment.

    Parameters
    ----------

    times,mags : np.array
        The input flux time-series to process.

    modeltimes,modelmags : np.array
        A transiting planet model, either from BLS, a trapezoid model, or a
        Mandel-Agol model.

    atol_normalization : float
        The absolute tolerance to which the median of the passed model fluxes
        must be equal to 1.

    indsforrms : np.array
        A array of bools of `len(mags)` used to select points for the RMS
        measurement. If not passed, the RMS of the entire passed timeseries is
        used as an approximation. Genearlly, it's best to use out of transit
        points, so the RMS measurement is not model-dependent.

    magsarefluxes : bool
        Currently forced to be True because this function only works with
        fluxes.

    verbose : bool
        If True, indicates progress and warns about problems.

    transitdepth : float or None
        If the transit depth is known, pass it in here. Otherwise, it is
        calculated assuming OOT flux is 1.

    npoints_in_transits : int or None
        If the number of points in transit is known, pass it in here. Otherwise,
        the function will guess at this value.

    Returns
    -------

    (snr, transit_depth, noise) : tuple
        The returned tuple contains the calculated SNR, transit depth, and noise
        of the residual lightcurve calculated using the relation described
        above.


def _epd_function(coeffs, fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd):

return (coeffs[<NUM_LIT:0>]*fsv*fsv +<EOL>coeffs[<NUM_LIT:1>]*fsv +<EOL>coeffs[<NUM_LIT:2>]*fdv*fdv +<EOL>coeffs[<NUM_LIT:3>]*fdv +<EOL>coeffs[<NUM_LIT:4>]*fkv*fkv +<EOL>coeffs[<NUM_LIT:5>]*fkv +<EOL>coeffs[<NUM_LIT:6>] +<EOL>coeffs[<NUM_LIT:7>]*fsv*fdv +<EOL>coeffs[<NUM_LIT:8>]*fsv*fkv +<EOL>coeffs[<NUM_LIT:9>]*fdv*fkv +<EOL>coeffs[<NUM_LIT:10>]*np.sin(<NUM_LIT:2>*pi_value*xcc) +<EOL>coeffs[<NUM_LIT:11>]*np.cos(<NUM_LIT:2>*pi_value*xcc) +<EOL>coeffs[<NUM_LIT:12>]*np.sin(<NUM_LIT:2>*pi_value*ycc) +<EOL>coeffs[<NUM_LIT>]*np.cos(<NUM_LIT:2>*pi_value*ycc) +<EOL>coeffs[<NUM_LIT>]*np.sin(<NUM_LIT:4>*pi_value*xcc) +<EOL>coeffs[<NUM_LIT:15>]*np.cos(<NUM_LIT:4>*pi_value*xcc) +<EOL>coeffs[<NUM_LIT:16>]*np.sin(<NUM_LIT:4>*pi_value*ycc) +<EOL>coeffs[<NUM_LIT>]*np.cos(<NUM_LIT:4>*pi_value*ycc) +<EOL>coeffs[<NUM_LIT>]*bgv +<EOL>coeffs[<NUM_LIT>]*bge +<EOL>coeffs[<NUM_LIT:20>]*iha +<EOL>coeffs[<NUM_LIT>]*izd)<EOL>

This is the EPD function to fit using a smoothed mag-series.


def smooth_magseries_savgol(mags, windowsize, polyorder=<NUM_LIT:2>):

smoothed = savgol_filter(mags, windowsize, polyorder)<EOL>return smoothed<EOL>

This smooths the magseries with a Savitsky-Golay filter.

    Parameters
    ----------

    mags : np.array
        The input mags/flux time-series to smooth.

    windowsize : int
        This is a odd integer containing the smoothing window size.

    polyorder : int
        This is an integer containing the polynomial degree order to use when
        generating the Savitsky-Golay filter.

    Returns
    -------

    np.array
        The smoothed mag/flux time-series array.


def epd_magseries(times, mags, errs,<EOL>fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd,<EOL>magsarefluxes=False,<EOL>epdsmooth_sigclip=<NUM_LIT>,<EOL>epdsmooth_windowsize=<NUM_LIT>,<EOL>epdsmooth_func=smooth_magseries_savgol,<EOL>epdsmooth_extraparams=None):

finind = np.isfinite(times) & np.isfinite(mags) & np.isfinite(errs)<EOL>ftimes, fmags, ferrs = times[::][finind], mags[::][finind], errs[::][finind]<EOL>ffsv, ffdv, ffkv, fxcc, fycc, fbgv, fbge, fiha, fizd = (<EOL>fsv[::][finind],<EOL>fdv[::][finind],<EOL>fkv[::][finind],<EOL>xcc[::][finind],<EOL>ycc[::][finind],<EOL>bgv[::][finind],<EOL>bge[::][finind],<EOL>iha[::][finind],<EOL>izd[::][finind],<EOL>)<EOL>stimes, smags, serrs, separams = sigclip_magseries_with_extparams(<EOL>times, mags, errs,<EOL>[fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd],<EOL>sigclip=epdsmooth_sigclip,<EOL>magsarefluxes=magsarefluxes<EOL>)<EOL>sfsv, sfdv, sfkv, sxcc, sycc, sbgv, sbge, siha, sizd = separams<EOL>if isinstance(epdsmooth_extraparams, dict):<EOL><INDENT>smoothedmags = epdsmooth_func(smags,<EOL>epdsmooth_windowsize,<EOL>**epdsmooth_extraparams)<EOL><DEDENT>else:<EOL><INDENT>smoothedmags = epdsmooth_func(smags, epdsmooth_windowsize)<EOL><DEDENT>initcoeffs = np.zeros(<NUM_LIT>)<EOL>leastsqfit = leastsq(_epd_residual,<EOL>initcoeffs,<EOL>args=(smoothedmags,<EOL>sfsv, sfdv, sfkv, sxcc,<EOL>sycc, sbgv, sbge, siha, sizd),<EOL>full_output=True)<EOL>if leastsqfit[-<NUM_LIT:1>] in (<NUM_LIT:1>,<NUM_LIT:2>,<NUM_LIT:3>,<NUM_LIT:4>):<EOL><INDENT>fitcoeffs = leastsqfit[<NUM_LIT:0>]<EOL>epdfit = _epd_function(fitcoeffs,<EOL>ffsv, ffdv, ffkv, fxcc, fycc,<EOL>fbgv, fbge, fiha, fizd)<EOL>epdmags = npmedian(fmags) + fmags - epdfit<EOL>retdict = {'<STR_LIT>':ftimes,<EOL>'<STR_LIT>':epdmags,<EOL>'<STR_LIT>':ferrs,<EOL>'<STR_LIT>':fitcoeffs,<EOL>'<STR_LIT>':leastsqfit,<EOL>'<STR_LIT>':epdfit,<EOL>'<STR_LIT>':npmedian(epdmags),<EOL>'<STR_LIT>':npmedian(npabs(epdmags - npmedian(epdmags)))}<EOL>return retdict<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return None<EOL><DEDENT>

Detrends a magnitude series using External Parameter Decorrelation.

    Requires a set of external parameters similar to those present in HAT light
    curves. At the moment, the HAT light-curve-specific external parameters are:

    - S: the 'fsv' column in light curves,
    - D: the 'fdv' column in light curves,
    - K: the 'fkv' column in light curves,
    - x coords: the 'xcc' column in light curves,
    - y coords: the 'ycc' column in light curves,
    - background value: the 'bgv' column in light curves,
    - background error: the 'bge' column in light curves,
    - hour angle: the 'iha' column in light curves,
    - zenith distance: the 'izd' column in light curves

    S, D, and K are defined as follows:

    - S -> measure of PSF sharpness (~1/sigma^2 sosmaller S = wider PSF)
    - D -> measure of PSF ellipticity in xy direction
    - K -> measure of PSF ellipticity in cross direction

    S, D, K are related to the PSF's variance and covariance, see eqn 30-33 in
    A. Pal's thesis: https://arxiv.org/abs/0906.3486

    NOTE: The errs are completely ignored and returned unchanged (except for
    sigclip and finite filtering).

    Parameters
    ----------

    times,mags,errs : np.array
        The input mag/flux time-series to detrend.

    fsv : np.array
        Array containing the external parameter `S` of the same length as times.

    fdv : np.array
        Array containing the external parameter `D` of the same length as times.

    fkv : np.array
        Array containing the external parameter `K` of the same length as times.

    xcc : np.array
        Array containing the external parameter `x-coords` of the same length as
        times.

    ycc : np.array
        Array containing the external parameter `y-coords` of the same length as
        times.

    bgv : np.array
        Array containing the external parameter `background value` of the same
        length as times.

    bge : np.array
        Array containing the external parameter `background error` of the same
        length as times.

    iha : np.array
        Array containing the external parameter `hour angle` of the same length
        as times.

    izd : np.array
        Array containing the external parameter `zenith distance` of the same
        length as times.

    magsarefluxes : bool
        Set this to True if `mags` actually contains fluxes.

    epdsmooth_sigclip : float or int or sequence of two floats/ints or None
        This specifies how to sigma-clip the input LC before fitting the EPD
        function to it.

        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    epdsmooth_windowsize : int
        This is the number of LC points to smooth over to generate a smoothed
        light curve that will be used to fit the EPD function.

    epdsmooth_func : Python function
        This sets the smoothing filter function to use. A Savitsky-Golay filter
        is used to smooth the light curve by default. The functions that can be
        used with this kwarg are listed in `varbase.trends`. If you want to use
        your own function, it MUST have the following signature::

                def smoothfunc(mags_array, window_size, **extraparams)

        and return a numpy array of the same size as `mags_array` with the
        smoothed time-series. Any extra params can be provided using the
        `extraparams` dict.

    epdsmooth_extraparams : dict
        This is a dict of any extra filter params to supply to the smoothing
        function.

    Returns
    -------

    dict
        Returns a dict of the following form::

            {'times':the input times after non-finite elems removed,
             'mags':the EPD detrended mag values (the EPD mags),
             'errs':the errs after non-finite elems removed,
             'fitcoeffs':EPD fit coefficient values,
             'fitinfo':the full tuple returned by scipy.leastsq,
             'fitmags':the EPD fit function evaluated at times,
             'mags_median': this is median of the EPD mags,
             'mags_mad': this is the MAD of EPD mags}


return median_filter(mags, size=windowsize, mode='<STR_LIT>')<EOL>

This smooths the magseries with a median filter that reflects the array
    at the boundary.

    See https://docs.scipy.org/doc/scipy/reference/tutorial/ndimage.html for
    details.

    Parameters
    ----------

    mags : np.array
        The input mags/flux time-series to smooth.

    windowsize : int
        This is a odd integer containing the smoothing window size.

    Returns
    -------

    np.array
        The smoothed mag/flux time-series array.


def _epd_residual(coeffs, mags, fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd):

f = _epd_function(coeffs, fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd)<EOL>residual = mags - f<EOL>return residual<EOL>

This is the residual function to minimize using scipy.optimize.leastsq.


def _epd_residual2(coeffs,<EOL>times, mags, errs,<EOL>fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd):

This is the residual function to minimize using
    scipy.optimize.least_squares.

    This variant is for :py:func:`.epd_magseries_extparams`.


return medfilt(mags, windowsize)<EOL>

This smooths the magseries with a simple median filter.

    This function pads with zeros near the boundary, see:

    https://stackoverflow.com/questions/24585706/scipy-medfilt-wrong-result

    Typically this is bad.

    Parameters
    ----------

    mags : np.array
        The input mags/flux time-series to smooth.

    windowsize : int
        This is a odd integer containing the smoothing window size.

    Returns
    -------

    np.array
        The smoothed mag/flux time-series array.


def _autocorr_func2(mags, lag, maglen, magmed, magstd):

lagindex = nparange(<NUM_LIT:0>,maglen-lag)<EOL>products = (mags[lagindex] - magmed) * (mags[lagindex+lag] - magmed)<EOL>autocovarfunc = npsum(products)/lagindex.size<EOL>varfunc = npsum(<EOL>(mags[lagindex] - magmed)*(mags[lagindex] - magmed)<EOL>)/mags.size<EOL>acorr = autocovarfunc/varfunc<EOL>return acorr<EOL>

This is an alternative function to calculate the autocorrelation.

This version is from (first definition):

https://en.wikipedia.org/wiki/Correlogram#Estimation_of_autocorrelations

Parameters
----------

mags : np.array
    This is the magnitudes array. MUST NOT have any nans.

lag : float
    The specific lag value to calculate the auto-correlation for. This MUST
    be less than total number of observations in `mags`.

maglen : int
    The number of elements in the `mags` array.

magmed : float
    The median of the `mags` array.

magstd : float
    The standard deviation of the `mags` array.

Returns
-------

float
    The auto-correlation at this specific `lag` value.


def _autocorr_func1(mags, lag, maglen, magmed, magstd):

lagindex = nparange(<NUM_LIT:1>,maglen-lag)<EOL>products = (mags[lagindex] - magmed) * (mags[lagindex+lag] - magmed)<EOL>acorr = (<NUM_LIT:1.0>/((maglen - lag)*magstd)) * npsum(products)<EOL>return acorr<EOL>

Calculates the autocorr of mag series for specific lag.

    This version of the function is taken from: Kim et al. (`2011
    <https://dx.doi.org/10.1088/0004-637X/735/2/68>`_)

    Parameters
    ----------

    mags : np.array
        This is the magnitudes array. MUST NOT have any nans.

    lag : float
        The specific lag value to calculate the auto-correlation for. This MUST
        be less than total number of observations in `mags`.

    maglen : int
        The number of elements in the `mags` array.

    magmed : float
        The median of the `mags` array.

    magstd : float
        The standard deviation of the `mags` array.

    Returns
    -------

    float
        The auto-correlation at this specific `lag` value.


stimes, smags, serrs = sigclip_magseries(times, mags, errs,<EOL>sigclip=sigclip,<EOL>magsarefluxes=magsarefluxes)<EOL>median_mag = np.median(smags)<EOL>mintime = np.min(stimes)<EOL>iphase = (<EOL>(stimes - mintime)/whitenperiod -<EOL>np.floor((stimes - mintime)/whitenperiod)<EOL>)<EOL>phasesortind = np.argsort(iphase)<EOL>phase = iphase[phasesortind]<EOL>pmags = smags[phasesortind]<EOL>perrs = serrs[phasesortind]<EOL>ptimes = stimes[phasesortind]<EOL>wmags = pmags - _fourier_func(whitenparams, phase, pmags)<EOL>wtimeorder = np.argsort(ptimes)<EOL>wtimes = ptimes[wtimeorder]<EOL>wphase = phase[wtimeorder]<EOL>wmags = wmags[wtimeorder]<EOL>werrs = perrs[wtimeorder]<EOL>if rescaletomedian:<EOL><INDENT>wmags = wmags + median_mag<EOL><DEDENT>returndict = {'<STR_LIT>':wtimes,  <EOL>'<STR_LIT>':wphase,<EOL>'<STR_LIT>':wmags,<EOL>'<STR_LIT>':werrs,<EOL>'<STR_LIT>':whitenparams,<EOL>'<STR_LIT>':whitenperiod}<EOL>if plotfit and (isinstance(plotfit, str) or isinstance(plotfit, Strio)):<EOL><INDENT>if plotfitphasedlconly:<EOL><INDENT>plt.figure(figsize=(<NUM_LIT:10>,<NUM_LIT>))<EOL><DEDENT>else:<EOL><INDENT>plt.figure(figsize=(<NUM_LIT:16>,<NUM_LIT>))<EOL><DEDENT>if plotfitphasedlconly:<EOL><INDENT>plt.subplot(<NUM_LIT>)<EOL>plt.plot(phase,pmags,<EOL>marker='<STR_LIT:.>',<EOL>color='<STR_LIT:k>',<EOL>linestyle='<STR_LIT:None>',<EOL>markersize=<NUM_LIT>,<EOL>markeredgewidth=<NUM_LIT:0>)<EOL>if not magsarefluxes:<EOL><INDENT>plt.gca().invert_yaxis()<EOL>plt.ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.ylabel('<STR_LIT>')<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>')<EOL>plt.subplot(<NUM_LIT>)<EOL>plt.plot(wphase,wmags,<EOL>marker='<STR_LIT:.>',<EOL>color='<STR_LIT:g>',<EOL>linestyle='<STR_LIT:None>',<EOL>markersize=<NUM_LIT>,<EOL>markeredgewidth=<NUM_LIT:0>)<EOL>if not magsarefluxes:<EOL><INDENT>plt.gca().invert_yaxis()<EOL>plt.ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.ylabel('<STR_LIT>')<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.subplot(<NUM_LIT>)<EOL>plt.plot(stimes,smags,<EOL>marker='<STR_LIT:.>',<EOL>color='<STR_LIT:k>',<EOL>linestyle='<STR_LIT:None>',<EOL>markersize=<NUM_LIT>,<EOL>markeredgewidth=<NUM_LIT:0>)<EOL>if not magsarefluxes:<EOL><INDENT>plt.gca().invert_yaxis()<EOL>plt.ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.ylabel('<STR_LIT>')<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>')<EOL>plt.subplot(<NUM_LIT>)<EOL>plt.plot(wtimes,wmags,<EOL>marker='<STR_LIT:.>',<EOL>color='<STR_LIT:g>',<EOL>linestyle='<STR_LIT:None>',<EOL>markersize=<NUM_LIT>,<EOL>markeredgewidth=<NUM_LIT:0>)<EOL>if not magsarefluxes:<EOL><INDENT>plt.gca().invert_yaxis()<EOL>plt.ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.ylabel('<STR_LIT>')<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>' % whitenperiod)<EOL>plt.subplot(<NUM_LIT>)<EOL>plt.plot(phase,pmags,<EOL>marker='<STR_LIT:.>',<EOL>color='<STR_LIT:k>',<EOL>linestyle='<STR_LIT:None>',<EOL>markersize=<NUM_LIT>,<EOL>markeredgewidth=<NUM_LIT:0>)<EOL>if not magsarefluxes:<EOL><INDENT>plt.gca().invert_yaxis()<EOL>plt.ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.ylabel('<STR_LIT>')<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>')<EOL>plt.subplot(<NUM_LIT>)<EOL>plt.plot(wphase,wmags,<EOL>marker='<STR_LIT:.>',<EOL>color='<STR_LIT:g>',<EOL>linestyle='<STR_LIT:None>',<EOL>markersize=<NUM_LIT>,<EOL>markeredgewidth=<NUM_LIT:0>)<EOL>if not magsarefluxes:<EOL><INDENT>plt.gca().invert_yaxis()<EOL>plt.ylabel('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>plt.ylabel('<STR_LIT>')<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.title('<STR_LIT>')<EOL><DEDENT>plt.tight_layout()<EOL>plt.savefig(plotfit, format='<STR_LIT>', pad_inches=<NUM_LIT:0.0>)<EOL>plt.close()<EOL>if isinstance(plotfit, str) or isinstance(plotfit, Strio):<EOL><INDENT>returndict['<STR_LIT>'] = plotfit<EOL><DEDENT><DEDENT>return returndict<EOL>

Removes a periodic sinusoidal signal generated using whitenparams from
    the input magnitude time series.

    Parameters
    ----------

    times,mags,errs : np.array
        The input mag/flux time-series to prewhiten.

    whitenperiod : float
        The period of the sinusoidal signal to remove.

    whitenparams : list of floats
        This contains the Fourier amplitude and phase coefficients of the
        sinusoidal signal to remove::

            [ampl_1, ampl_2, ampl_3, ..., ampl_X,
             pha_1, pha_2, pha_3, ..., pha_X]

        where `X` is the Fourier order. These are usually the output of a
        previous Fourier fit to the light curve (from
        :py:func:`astrobase.lcfit.sinusoidal.fourier_fit_magseries` for
        example).

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    magsarefluxes : bool
        If True, will treat the input values of `mags` as fluxes for purposes of
        plotting the fit and sig-clipping.

    plotfit : str or False
        If this is a string, this function will make a plot showing the effect
        of the pre-whitening on the mag/flux time-series and write the plot to
        the path specified here.

    plotfitphasedlconly : bool
        If True, will plot only the phased LC for showing the effect of
        pre-whitening, and skip plotting the unphased LC.

    rescaletomedian : bool
        If this is True, then we add back the constant median term of the
        magnitudes to the final pre-whitened mag series.

    Returns
    -------

    dict
        Returns a dict of the form::

            {'wtimes':times array after pre-whitening,
             'wphase':phase array after pre-whitening,
             'wmags':mags array after pre-whitening,
             'werrs':errs array after pre-whitening,
             'whitenparams':the input pre-whitening params used,
             'whitenperiod':the input pre-whitening period used,
             'fitplotfile':the output plot file if plotfit was set}


def trapezoid_transit_func(transitparams, times, mags, errs,<EOL>get_ntransitpoints=False):

(transitperiod,<EOL>transitepoch,<EOL>transitdepth,<EOL>transitduration,<EOL>ingressduration) = transitparams<EOL>iphase = (times - transitepoch)/transitperiod<EOL>iphase = iphase - np.floor(iphase)<EOL>phasesortind = np.argsort(iphase)<EOL>phase = iphase[phasesortind]<EOL>ptimes = times[phasesortind]<EOL>pmags = mags[phasesortind]<EOL>perrs = errs[phasesortind]<EOL>zerolevel = np.median(pmags)<EOL>modelmags = np.full_like(phase, zerolevel)<EOL>halftransitduration = transitduration/<NUM_LIT><EOL>bottomlevel = zerolevel - transitdepth<EOL>slope = transitdepth/ingressduration<EOL>firstcontact = <NUM_LIT:1.0> - halftransitduration<EOL>secondcontact = firstcontact + ingressduration<EOL>thirdcontact = halftransitduration - ingressduration<EOL>fourthcontact = halftransitduration<EOL>ingressind = (phase > firstcontact) & (phase < secondcontact)<EOL>bottomind = (phase > secondcontact) | (phase < thirdcontact)<EOL>egressind = (phase > thirdcontact) & (phase < fourthcontact)<EOL>in_transit_points = ingressind | bottomind | egressind<EOL>n_transit_points = np.sum(in_transit_points)<EOL>modelmags[ingressind] = zerolevel - slope*(phase[ingressind] - firstcontact)<EOL>modelmags[bottomind] = bottomlevel<EOL>modelmags[egressind] = bottomlevel + slope*(phase[egressind] - thirdcontact)<EOL>if get_ntransitpoints:<EOL><INDENT>return modelmags, phase, ptimes, pmags, perrs, n_transit_points<EOL><DEDENT>else:<EOL><INDENT>return modelmags, phase, ptimes, pmags, perrs<EOL><DEDENT>

This returns a trapezoid transit-shaped function.

    Suitable for first order modeling of transit signals.

    Parameters
    ----------

    transitparams : list of float
        This contains the transiting planet trapezoid model::

            transitparams = [transitperiod (time),
                             transitepoch (time),
                             transitdepth (flux or mags),
                             transitduration (phase),
                             ingressduration (phase)]

        All of these will then have fitted values after the fit is done.

        - for magnitudes -> `transitdepth` should be < 0
        - for fluxes     -> `transitdepth` should be > 0

    times,mags,errs : np.array
        The input time-series of measurements and associated errors for which
        the transit model will be generated. The times will be used to generate
        model mags, and the input `times`, `mags`, and `errs` will be resorted
        by model phase and returned.

    Returns
    -------

    (modelmags, phase, ptimes, pmags, perrs) : tuple
        Returns the model mags and phase values. Also returns the input `times`,
        `mags`, and `errs` sorted by the model's phase.


def trapezoid_transit_residual(transitparams, times, mags, errs):

modelmags, phase, ptimes, pmags, perrs = (<EOL>trapezoid_transit_func(transitparams, times, mags, errs)<EOL>)<EOL>return (pmags - modelmags)/perrs<EOL>

This returns the residual between the modelmags and the actual mags.

Parameters
----------

transitparams : list of float
    This contains the transiting planet trapezoid model::

        transitparams = [transitperiod (time),
                         transitepoch (time),
                         transitdepth (flux or mags),
                         transitduration (phase),
                         ingressduration (phase)]

    All of these will then have fitted values after the fit is done.

    - for magnitudes -> `transitdepth` should be < 0
    - for fluxes     -> `transitdepth` should be > 0

times,mags,errs : np.array
    The input time-series of measurements and associated errors for which
    the transit model will be generated. The times will be used to generate
    model mags, and the input `times`, `mags`, and `errs` will be resorted
    by model phase and returned.

Returns
-------

np.array
    The residuals between the input `mags` and generated `modelmags`,
    weighted by the measurement errors in `errs`.


def _double_inverted_gaussian(x,<EOL>amp1, loc1, std1,<EOL>amp2, loc2, std2):

gaussian1 = -_gaussian(x,amp1,loc1,std1)<EOL>gaussian2 = -_gaussian(x,amp2,loc2,std2)<EOL>return gaussian1 + gaussian2<EOL>

This is a double inverted gaussian.

    Parameters
    ----------

    x : np.array
        The items at which the Gaussian is evaluated.

    amp1,amp2 : float
        The amplitude of Gaussian 1 and Gaussian 2.

    loc1,loc2 : float
        The central value of Gaussian 1 and Gaussian 2.

    std1,std2 : float
        The standard deviation of Gaussian 1 and Gaussian 2.

    Returns
    -------

    np.array
        Returns a double inverted Gaussian function evaluated at the items in
        `x`, using the provided parameters of `amp`, `loc`, and `std` for two
        component Gaussians 1 and 2.


def flare_model_residual(flareparams, times, mags, errs):

modelmags, _, _, _ = flare_model(flareparams, times, mags, errs)<EOL>return (mags - modelmags)/errs<EOL>

This returns the residual between model mags and the actual mags.

Parameters
----------

flareparams : list of float
    This defines the flare model::

        [amplitude,
         flare_peak_time,
         rise_gaussian_stdev,
         decay_time_constant]

    where:

    `amplitude`: the maximum flare amplitude in mags or flux. If flux, then
    amplitude should be positive. If mags, amplitude should be negative.

    `flare_peak_time`: time at which the flare maximum happens.

    `rise_gaussian_stdev`: the stdev of the gaussian describing the rise of
    the flare.

    `decay_time_constant`: the time constant of the exponential fall of the
    flare.

times,mags,errs : np.array
    The input time-series of measurements and associated errors for which
    the model will be generated. The times will be used to generate
    model mags.

Returns
-------

np.array
    The residuals between the input `mags` and generated `modelmags`,
    weighted by the measurement errors in `errs`.


def phase_magseries_with_errs(times, mags, errs, period, epoch,<EOL>wrap=True, sort=True):

<EOL>finiteind = np.isfinite(mags)<EOL>finite_times = times[finiteind]<EOL>finite_mags = mags[finiteind]<EOL>finite_errs = errs[finiteind]<EOL>magseries_phase = (<EOL>(finite_times - epoch)/period -<EOL>np.floor(((finite_times - epoch)/period))<EOL>)<EOL>outdict = {'<STR_LIT>':magseries_phase,<EOL>'<STR_LIT>':finite_mags,<EOL>'<STR_LIT>':finite_errs,<EOL>'<STR_LIT>':period,<EOL>'<STR_LIT>':epoch}<EOL>if sort:<EOL><INDENT>sortorder = np.argsort(outdict['<STR_LIT>'])<EOL>outdict['<STR_LIT>'] = outdict['<STR_LIT>'][sortorder]<EOL>outdict['<STR_LIT>'] = outdict['<STR_LIT>'][sortorder]<EOL>outdict['<STR_LIT>'] = outdict['<STR_LIT>'][sortorder]<EOL><DEDENT>if wrap:<EOL><INDENT>outdict['<STR_LIT>'] = np.concatenate((outdict['<STR_LIT>']-<NUM_LIT:1.0>,<EOL>outdict['<STR_LIT>']))<EOL>outdict['<STR_LIT>'] = np.concatenate((outdict['<STR_LIT>'],<EOL>outdict['<STR_LIT>']))<EOL>outdict['<STR_LIT>'] = np.concatenate((outdict['<STR_LIT>'],<EOL>outdict['<STR_LIT>']))<EOL><DEDENT>return outdict<EOL>

Phases a magnitude/flux time-series using a given period and epoch.

    The equation used is::

        phase = (times - epoch)/period - floor((times - epoch)/period)

    This phases the given magnitude timeseries using the given period and
    epoch. If wrap is True, wraps the result around 0.0 (and returns an array
    that has twice the number of the original elements). If sort is True,
    returns the magnitude timeseries in phase sorted order.

    Parameters
    ----------

    times,mags,errs : np.array
        The magnitude/flux time-series values and associated measurement errors
        to phase using the provided `period` and `epoch`. Non-fiinite values
        will be removed.

    period : float
        The period to use to phase the time-series.

    epoch : float
        The epoch to phase the time-series. This is usually the time-of-minimum
        or time-of-maximum of some periodic light curve
        phenomenon. Alternatively, one can use the minimum time value in
        `times`.

    wrap : bool
        If this is True, the returned phased time-series will be wrapped around
        phase 0.0, which is useful for plotting purposes. The arrays returned
        will have twice the number of input elements because of this wrapping.

    sort : bool
        If this is True, the returned phased time-series will be sorted in
        increasing phase order.

    Returns
    -------

    dict
        A dict of the following form is returned::

            {'phase': the phase values,
             'mags': the mags/flux values at each phase,
             'errs': the err values at each phase,
             'period': the input `period` used to phase the time-series,
             'epoch': the input `epoch` used to phase the time-series}


def phase_magseries(times, mags, period, epoch, wrap=True, sort=True):

<EOL>finiteind = np.isfinite(mags) & np.isfinite(times)<EOL>finite_times = times[finiteind]<EOL>finite_mags = mags[finiteind]<EOL>magseries_phase = (<EOL>(finite_times - epoch)/period -<EOL>np.floor(((finite_times - epoch)/period))<EOL>)<EOL>outdict = {'<STR_LIT>':magseries_phase,<EOL>'<STR_LIT>':finite_mags,<EOL>'<STR_LIT>':period,<EOL>'<STR_LIT>':epoch}<EOL>if sort:<EOL><INDENT>sortorder = np.argsort(outdict['<STR_LIT>'])<EOL>outdict['<STR_LIT>'] = outdict['<STR_LIT>'][sortorder]<EOL>outdict['<STR_LIT>'] = outdict['<STR_LIT>'][sortorder]<EOL><DEDENT>if wrap:<EOL><INDENT>outdict['<STR_LIT>'] = np.concatenate((outdict['<STR_LIT>']-<NUM_LIT:1.0>,<EOL>outdict['<STR_LIT>']))<EOL>outdict['<STR_LIT>'] = np.concatenate((outdict['<STR_LIT>'],<EOL>outdict['<STR_LIT>']))<EOL><DEDENT>return outdict<EOL>

Phases a magnitude/flux time-series using a given period and epoch.

    The equation used is::

        phase = (times - epoch)/period - floor((times - epoch)/period)

    This phases the given magnitude timeseries using the given period and
    epoch. If wrap is True, wraps the result around 0.0 (and returns an array
    that has twice the number of the original elements). If sort is True,
    returns the magnitude timeseries in phase sorted order.

    Parameters
    ----------

    times,mags : np.array
        The magnitude/flux time-series values to phase using the provided
        `period` and `epoch`. Non-fiinite values will be removed.

    period : float
        The period to use to phase the time-series.

    epoch : float
        The epoch to phase the time-series. This is usually the time-of-minimum
        or time-of-maximum of some periodic light curve
        phenomenon. Alternatively, one can use the minimum time value in
        `times`.

    wrap : bool
        If this is True, the returned phased time-series will be wrapped around
        phase 0.0, which is useful for plotting purposes. The arrays returned
        will have twice the number of input elements because of this wrapping.

    sort : bool
        If this is True, the returned phased time-series will be sorted in
        increasing phase order.

    Returns
    -------

    dict
        A dict of the following form is returned::

            {'phase': the phase values,
             'mags': the mags/flux values at each phase,
             'period': the input `period` used to phase the time-series,
             'epoch': the input `epoch` used to phase the time-series}


ngroups, timegroups = find_lc_timegroups(times,<EOL>mingap=mingap)<EOL>finite_ind = np.isfinite(mags)<EOL>if any(finite_ind):<EOL><INDENT>global_mag_median = np.median(mags[finite_ind])<EOL>for tgind, tg in enumerate(timegroups):<EOL><INDENT>finite_ind = np.isfinite(mags[tg])<EOL>group_median = np.median((mags[tg])[finite_ind])<EOL>if magsarefluxes:<EOL><INDENT>mags[tg] = mags[tg]/group_median<EOL><DEDENT>else:<EOL><INDENT>mags[tg] = mags[tg] - group_median<EOL><DEDENT>if debugmode:<EOL><INDENT>LOGDEBUG('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(tgind,<EOL>len(mags[tg]),<EOL>len(finite_ind),<EOL>group_median))<EOL><DEDENT><DEDENT>if isinstance(normto, str) and normto == '<STR_LIT>':<EOL><INDENT>if magsarefluxes:<EOL><INDENT>mags = mags * global_mag_median<EOL><DEDENT>else:<EOL><INDENT>mags = mags + global_mag_median<EOL><DEDENT><DEDENT>elif isinstance(normto, float):<EOL><INDENT>if magsarefluxes:<EOL><INDENT>mags = mags * normto<EOL><DEDENT>else:<EOL><INDENT>mags = mags + normto<EOL><DEDENT><DEDENT>return times, mags<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return None, None<EOL><DEDENT>

This normalizes the magnitude time-series to a specified value.

    This is used to normalize time series measurements that may have large time
    gaps and vertical offsets in mag/flux measurement between these
    'timegroups', either due to instrument changes or different filters.

    NOTE: this works in-place! The mags array will be replaced with normalized
    mags when this function finishes.

    Parameters
    ----------

    times,mags : array-like
        The times (assumed to be some form of JD) and mags (or flux)
        measurements to be normalized.

    mingap : float
        This defines how much the difference between consecutive measurements is
        allowed to be to consider them as parts of different timegroups. By
        default it is set to 4.0 days.

    normto : {'globalmedian', 'zero'} or a float
        Specifies the normalization type::

          'globalmedian' -> norms each mag to the global median of the LC column
          'zero'         -> norms each mag to zero
          a float        -> norms each mag to this specified float value.

    magsarefluxes : bool
        Indicates if the input `mags` array is actually an array of flux
        measurements instead of magnitude measurements. If this is set to True,
        then:

        - if `normto` is 'zero', then the median flux is divided from each
          observation's flux value to yield normalized fluxes with 1.0 as the
          global median.

        - if `normto` is 'globalmedian', then the global median flux value
          across the entire time series is multiplied with each measurement.

        - if `norm` is set to a `float`, then this number is multiplied with the
          flux value for each measurement.

    debugmode : bool
        If this is True, will print out verbose info on each timegroup found.

    Returns
    -------

    times,normalized_mags : np.arrays
        Normalized magnitude values after normalization. If normalization fails
        for some reason, `times` and `normalized_mags` will both be None.


This queries the SIMBAD TAP service for a list of object names near the
    coords. This is effectively a "reverse" name resolver (i.e. this does the
    opposite of SESAME).

    Parameters
    ----------

    racenter,declcenter : float
        The cone-search center coordinates in decimal degrees

    searchradiusarcsec : float
        The radius in arcseconds to search around the center coordinates.

    simbad_mirror : str
        This is the key used to select a SIMBAD mirror from the
        `SIMBAD_URLS` dict above. If set, the specified mirror will be used. If
        None, a random mirror chosen from that dict will be used.

    returnformat : {'csv','votable','json'}
        The returned file format to request from the GAIA catalog service.

    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.

    maxtries : int
        The maximum number of tries (across all mirrors tried) to make to either
        submit the request or download the results, before giving up.

    complete_query_later : bool
        If set to True, a submitted query that does not return a result before
        `maxtimeout` has passed will be cancelled but its input request
        parameters and the result URL provided by the service will be saved. If
        this function is then called later with these same input request
        parameters, it will check if the query finally finished and a result is
        available. If so, will download the results instead of submitting a new
        query. If it's not done yet, will start waiting for results again. To
        force launch a new query with the same request parameters, set the
        `forcefetch` kwarg to True.

    Returns
    -------

    dict
        This returns a dict of the following form::

            {'params':dict of the input params used for the query,
             'provenance':'cache' or 'new download',
             'result':path to the file on disk with the downloaded data table}


<EOL>inputparams = TAP_PARAMS.copy()<EOL>inputparams['<STR_LIT>'] = querystr[::]<EOL>if returnformat in RETURN_FORMATS:<EOL><INDENT>inputparams['<STR_LIT>'] = returnformat<EOL><DEDENT>else:<EOL><INDENT>LOGWARNING('<STR_LIT>' %<EOL>returnformat)<EOL>inputparams['<STR_LIT>'] = '<STR_LIT>'<EOL><DEDENT>if '<STR_LIT>' in cachedir:<EOL><INDENT>cachedir = os.path.expanduser(cachedir)<EOL><DEDENT>if not os.path.exists(cachedir):<EOL><INDENT>os.makedirs(cachedir)<EOL><DEDENT>xcachekey = '<STR_LIT:->'.join([repr(inputparams[x])<EOL>for x in sorted(inputparams.keys())])<EOL>cachekey = hashlib.sha256(xcachekey.encode()).hexdigest()<EOL>cachefname = os.path.join(<EOL>cachedir,<EOL>'<STR_LIT>' % (cachekey, RETURN_FORMATS[returnformat])<EOL>)<EOL>provenance = '<STR_LIT>'<EOL>incomplete_qpklf = os.path.join(<EOL>cachedir,<EOL>'<STR_LIT>' % cachekey<EOL>)<EOL>if (not forcefetch and<EOL>complete_query_later and<EOL>os.path.exists(incomplete_qpklf)):<EOL><INDENT>with open(incomplete_qpklf, '<STR_LIT:rb>') as infd:<EOL><INDENT>incomplete_qinfo = pickle.load(infd)<EOL><DEDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL>waitdone = False<EOL>timeelapsed = <NUM_LIT:0.0><EOL>simbad_mirror = incomplete_qinfo['<STR_LIT>']<EOL>status_url = incomplete_qinfo['<STR_LIT>']<EOL>phasekeyword = incomplete_qinfo['<STR_LIT>']<EOL>resultkeyword = incomplete_qinfo['<STR_LIT>']<EOL>while not waitdone:<EOL><INDENT>if timeelapsed > maxtimeout:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(maxtimeout,<EOL>repr(inputparams),<EOL>status_url))<EOL>return None<EOL><DEDENT>try:<EOL><INDENT>resreq = requests.get(status_url,<EOL>timeout=timeout)<EOL>resreq.raise_for_status()<EOL>resxml = parseString(resreq.text)<EOL>jobstatuselem = (<EOL>resxml.getElementsByTagName(phasekeyword)[<NUM_LIT:0>]<EOL>)<EOL>jobstatus = jobstatuselem.firstChild.toxml()<EOL>if jobstatus == '<STR_LIT>':<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>waitdone = True<EOL><DEDENT>elif jobstatus != '<STR_LIT>':<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (timeelapsed, jobstatus, status_url))<EOL><DEDENT>time.sleep(refresh)<EOL>timeelapsed = timeelapsed + refresh<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(status_url,<EOL>resreq.text))<EOL>os.remove(incomplete_qpklf)<EOL>return None<EOL><DEDENT><DEDENT>except requests.exceptions.Timeout as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams), status_url)<EOL>)<EOL>return None<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams),<EOL>status_url,<EOL>resreq.text)<EOL>)<EOL>os.remove(incomplete_qpklf)<EOL>return None<EOL><DEDENT><DEDENT>LOGINFO('<STR_LIT>')<EOL>result_url_elem = resxml.getElementsByTagName(resultkeyword)[<NUM_LIT:0>]<EOL>result_url = result_url_elem.getAttribute('<STR_LIT>')<EOL>result_nrows = result_url_elem.getAttribute('<STR_LIT>')<EOL>try:<EOL><INDENT>resreq = requests.get(result_url, timeout=timeout)<EOL>resreq.raise_for_status()<EOL>if cachefname.endswith('<STR_LIT>'):<EOL><INDENT>with gzip.open(cachefname,'<STR_LIT:wb>') as outfd:<EOL><INDENT>for chunk in resreq.iter_content(chunk_size=<NUM_LIT>):<EOL><INDENT>outfd.write(chunk)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>with open(cachefname,'<STR_LIT:wb>') as outfd:<EOL><INDENT>for chunk in resreq.iter_content(chunk_size=<NUM_LIT>):<EOL><INDENT>outfd.write(chunk)<EOL><DEDENT><DEDENT><DEDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>' % result_nrows)<EOL><DEDENT>tablefname = cachefname<EOL>provenance = '<STR_LIT>'<EOL>resdict = {'<STR_LIT>':inputparams,<EOL>'<STR_LIT>':provenance,<EOL>'<STR_LIT:result>':tablefname}<EOL>os.remove(incomplete_qpklf)<EOL>return resdict<EOL><DEDENT>except requests.exceptions.Timeout as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams), result_url)<EOL>)<EOL>return None<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams),<EOL>result_url,<EOL>resreq.status_code)<EOL>)<EOL>os.remove(incomplete_qpklf)<EOL>return None<EOL><DEDENT><DEDENT>if forcefetch or (not os.path.exists(cachefname)):<EOL><INDENT>provenance = '<STR_LIT>'<EOL>time.sleep(random.randint(<NUM_LIT:1>,jitter))<EOL>jobid = '<STR_LIT>' % time.time()<EOL>inputparams['<STR_LIT>'] = jobid<EOL>inputparams['<STR_LIT>'] = '<STR_LIT>'<EOL>try:<EOL><INDENT>waitdone = False<EOL>timeelapsed = <NUM_LIT:0.0><EOL>if simbad_mirror is not None and simbad_mirror in SIMBAD_URLS:<EOL><INDENT>tapurl = SIMBAD_URLS[simbad_mirror]['<STR_LIT:url>']<EOL>resultkeyword = SIMBAD_URLS[simbad_mirror]['<STR_LIT>']<EOL>phasekeyword = SIMBAD_URLS[simbad_mirror]['<STR_LIT>']<EOL>randkey = simbad_mirror<EOL>if '<STR_LIT>' in querystr:<EOL><INDENT>inputparams['<STR_LIT>'] = (<EOL>querystr.format(<EOL>table=SIMBAD_URLS[simbad_mirror]['<STR_LIT>']<EOL>)<EOL>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>randkey = random.choice(list(SIMBAD_URLS.keys()))<EOL>tapurl = SIMBAD_URLS[randkey]['<STR_LIT:url>']<EOL>resultkeyword = SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>phasekeyword = SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>if '<STR_LIT>' in querystr:<EOL><INDENT>inputparams['<STR_LIT>'] = (<EOL>querystr.format(<EOL>table=SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>)<EOL>)<EOL><DEDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>' % tapurl)<EOL><DEDENT><DEDENT>if verbose:<EOL><INDENT>LOGINFO(<EOL>'<STR_LIT>'<EOL>% repr(inputparams)<EOL>)<EOL><DEDENT>mirrorok = False<EOL>ntries = <NUM_LIT:1><EOL>while (not mirrorok):<EOL><INDENT>if ntries > maxtries:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>maxtries)<EOL>return None<EOL><DEDENT>try:<EOL><INDENT>req = requests.post(tapurl,<EOL>data=inputparams,<EOL>timeout=timeout)<EOL>resp_status = req.status_code<EOL>req.raise_for_status()<EOL>mirrorok = True<EOL><DEDENT>except requests.exceptions.HTTPError as e:<EOL><INDENT>LOGWARNING(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% tapurl<EOL>)<EOL>mirrorok = False<EOL>remainingmirrors = list(SIMBAD_URLS.keys())<EOL>waittime = random.choice(range(<NUM_LIT:1>,<NUM_LIT:6>))<EOL>time.sleep(waittime)<EOL>randkey = remainingmirrors[<NUM_LIT:0>]<EOL>tapurl = SIMBAD_URLS[randkey]['<STR_LIT:url>']<EOL>resultkeyword = SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>phasekeyword = SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>if '<STR_LIT>' in querystr:<EOL><INDENT>inputparams['<STR_LIT>'] = (<EOL>querystr.format(<EOL>table=SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>)<EOL>)<EOL><DEDENT><DEDENT>except requests.exceptions.Timeout as e:<EOL><INDENT>LOGWARNING(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>)<EOL>mirrorok = False<EOL>remainingmirrors = list(SIMBAD_URLS.keys())<EOL>waittime = random.choice(range(<NUM_LIT:1>,<NUM_LIT:6>))<EOL>time.sleep(waittime)<EOL>randkey = remainingmirrors[<NUM_LIT:0>]<EOL>tapurl = SIMBAD_URLS[randkey]['<STR_LIT:url>']<EOL>resultkeyword = SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>phasekeyword = SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>if '<STR_LIT>' in querystr:<EOL><INDENT>inputparams['<STR_LIT>'] = (<EOL>querystr.format(<EOL>table=SIMBAD_URLS[randkey]['<STR_LIT>']<EOL>)<EOL>)<EOL><DEDENT><DEDENT>ntries = ntries + <NUM_LIT:1><EOL><DEDENT>status_url = req.url<EOL>resxml = parseString(req.text)<EOL>jobstatuselem = resxml.getElementsByTagName(phasekeyword)<EOL>if jobstatuselem:<EOL><INDENT>jobstatuselem = jobstatuselem[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>' % phasekeyword)<EOL>LOGERROR('<STR_LIT:%s>' % req.txt)<EOL>req.close()<EOL>return None<EOL><DEDENT>jobstatus = jobstatuselem.firstChild.toxml()<EOL>if jobstatus == '<STR_LIT>':<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>waitdone = True<EOL><DEDENT><DEDENT>elif jobstatus == '<STR_LIT>':<EOL><INDENT>if verbose:<EOL><INDENT>LOGERROR(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams),<EOL>status_url,<EOL>req.text)<EOL>)<EOL>return None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' % jobstatus<EOL>)<EOL><DEDENT>while not waitdone:<EOL><INDENT>if timeelapsed > maxtimeout:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(maxtimeout,<EOL>repr(inputparams),<EOL>status_url,<EOL>jobstatus))<EOL>if complete_query_later and jobstatus in ('<STR_LIT>',<EOL>'<STR_LIT>'):<EOL><INDENT>incomplete_qpklf = os.path.join(<EOL>cachedir,<EOL>'<STR_LIT>' % cachekey<EOL>)<EOL>with open(incomplete_qpklf, '<STR_LIT:wb>') as outfd:<EOL><INDENT>savedict = inputparams.copy()<EOL>savedict['<STR_LIT>'] = status_url<EOL>savedict['<STR_LIT>'] = jobstatus<EOL>savedict['<STR_LIT>'] = simbad_mirror<EOL>savedict['<STR_LIT>'] = phasekeyword<EOL>savedict['<STR_LIT>'] = resultkeyword<EOL>pickle.dump(savedict,<EOL>outfd,<EOL>pickle.HIGHEST_PROTOCOL)<EOL><DEDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>jobstatus)<EOL><DEDENT>return None<EOL><DEDENT>time.sleep(refresh)<EOL>timeelapsed = timeelapsed + refresh<EOL>try:<EOL><INDENT>resreq = requests.get(status_url, timeout=timeout)<EOL>resreq.raise_for_status()<EOL>resxml = parseString(resreq.text)<EOL>jobstatuselem = (<EOL>resxml.getElementsByTagName(phasekeyword)[<NUM_LIT:0>]<EOL>)<EOL>jobstatus = jobstatuselem.firstChild.toxml()<EOL>if jobstatus == '<STR_LIT>':<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>waitdone = True<EOL><DEDENT>else:<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (timeelapsed, jobstatus, status_url))<EOL><DEDENT>continue<EOL><DEDENT><DEDENT>except requests.exceptions.Timeout as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams), status_url)<EOL>)<EOL>return None<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams),<EOL>status_url,<EOL>resreq.text)<EOL>)<EOL>return None<EOL><DEDENT><DEDENT><DEDENT>result_url_elem = resxml.getElementsByTagName(resultkeyword)[<NUM_LIT:0>]<EOL>result_url = result_url_elem.getAttribute('<STR_LIT>')<EOL>result_nrows = result_url_elem.getAttribute('<STR_LIT>')<EOL>try:<EOL><INDENT>resreq = requests.get(result_url, timeout=timeout)<EOL>resreq.raise_for_status()<EOL>if cachefname.endswith('<STR_LIT>'):<EOL><INDENT>with gzip.open(cachefname,'<STR_LIT:wb>') as outfd:<EOL><INDENT>for chunk in resreq.iter_content(chunk_size=<NUM_LIT>):<EOL><INDENT>outfd.write(chunk)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>with open(cachefname,'<STR_LIT:wb>') as outfd:<EOL><INDENT>for chunk in resreq.iter_content(chunk_size=<NUM_LIT>):<EOL><INDENT>outfd.write(chunk)<EOL><DEDENT><DEDENT><DEDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>' % result_nrows)<EOL><DEDENT>tablefname = cachefname<EOL><DEDENT>except requests.exceptions.Timeout as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams), result_url)<EOL>)<EOL>return None<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams),<EOL>result_url,<EOL>resreq.status_code)<EOL>)<EOL>return None<EOL><DEDENT><DEDENT>except requests.exceptions.HTTPError as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>'<EOL>'<STR_LIT>' % (resp_status,<EOL>repr(inputparams)))<EOL>return None<EOL><DEDENT>except requests.exceptions.Timeout as e:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT:%s>' % repr(inputparams))<EOL>return None<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>'<EOL>'<STR_LIT:%s>' % repr(inputparams))<EOL>if '<STR_LIT>' in locals():<EOL><INDENT>LOGERROR('<STR_LIT>' % req.text)<EOL><DEDENT>return None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(repr(inputparams)))<EOL><DEDENT>tablefname = cachefname<EOL>try:<EOL><INDENT>infd = gzip.open(cachefname,'<STR_LIT:rb>')<EOL>simbad_objectnames = np.genfromtxt(<EOL>infd,<EOL>names=True,<EOL>delimiter='<STR_LIT:U+002C>',<EOL>dtype='<STR_LIT>',<EOL>usecols=(<NUM_LIT:0>,<NUM_LIT:1>,<NUM_LIT:2>,<NUM_LIT:3>,<NUM_LIT:4>,<NUM_LIT:5>,<NUM_LIT:6>,<NUM_LIT:7>,<NUM_LIT:8>),<EOL>comments='<STR_LIT:?>',  <EOL>)<EOL>infd.close()<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>'<EOL>'<STR_LIT>' % cachefname)<EOL>return tap_query(querystr,<EOL>simbad_mirror=simbad_mirror,<EOL>returnformat=returnformat,<EOL>forcefetch=True,<EOL>cachedir=cachedir,<EOL>verbose=verbose,<EOL>timeout=timeout,<EOL>refresh=refresh,<EOL>maxtimeout=maxtimeout)<EOL><DEDENT><DEDENT>resdict = {'<STR_LIT>':inputparams,<EOL>'<STR_LIT>':provenance,<EOL>'<STR_LIT:result>':tablefname}<EOL>return resdict<EOL>

This queries the SIMBAD TAP service using the ADQL query string provided.

    Parameters
    ----------

    querystr : str
        This is the ADQL query string. See:
        http://www.ivoa.net/documents/ADQL/2.0 for the specification.

    simbad_mirror : str
        This is the key used to select a SIMBAD mirror from the
        `SIMBAD_URLS` dict above. If set, the specified mirror will be used. If
        None, a random mirror chosen from that dict will be used.

    returnformat : {'csv','votable','json'}
        The returned file format to request from the GAIA catalog service.

    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.

    maxtries : int
        The maximum number of tries (across all mirrors tried) to make to either
        submit the request or download the results, before giving up.

    complete_query_later : bool
        If set to True, a submitted query that does not return a result before
        `maxtimeout` has passed will be cancelled but its input request
        parameters and the result URL provided by the service will be saved. If
        this function is then called later with these same input request
        parameters, it will check if the query finally finished and a result is
        available. If so, will download the results instead of submitting a new
        query. If it's not done yet, will start waiting for results again. To
        force launch a new query with the same request parameters, set the
        `forcefetch` kwarg to True.

    jitter : float
        This is used to control the scale of the random wait in seconds before
        starting the query. Useful in parallelized situations.

    Returns
    -------

    dict
        This returns a dict of the following form::

            {'params':dict of the input params used for the query,
             'provenance':'cache' or 'new download',
             'result':path to the file on disk with the downloaded data table}


This runs the TRILEGAL query for decimal equatorial coordinates.

    Parameters
    ----------

    ra,decl : float
        These are the center equatorial coordinates in decimal 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. This is in the
        Galactic coordinate system.

    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}