signature:
def _pkl_finder_objectinfo ( objectinfo , varinfo , findercmap , finderconvolve , sigclip , normto , normmingap , deredden_object = True , custom_bandpasses = None , lclistpkl = None , nbrradiusarcsec = 30.0 , maxnumneighbors = 5 , plotdpi = 100 , findercachedir = '~/.astrobase/stamp-cache' , verbose = True , gaia_submit_timeout = 10.0 , gaia_submit_tries = 3 , gaia_max_timeout = 180.0 , gaia_mirror = None , fast_mode = False , complete_query_later = True ) :
    '''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 .'''

implementation:
# optional mode to hit external services and fail fast if they timeout
if fast_mode is True :
    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
elif isinstance ( fast_mode , ( int , float ) ) and fast_mode > 0.0 :
    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
else :
    skyview_lookup = True
    skyview_timeout = 10.0
    skyview_retry_failed = True
    dust_timeout = 10.0
    search_simbad = True
if ( isinstance ( objectinfo , dict ) and ( 'objectid' in objectinfo or 'hatid' in objectinfo ) and 'ra' in objectinfo and 'decl' in objectinfo and objectinfo [ 'ra' ] and objectinfo [ 'decl' ] ) :
    if 'objectid' not in objectinfo :
        objectid = objectinfo [ 'hatid' ]
    else :
        objectid = objectinfo [ 'objectid' ]
    if verbose and skyview_lookup :
        LOGINFO ( 'adding in object information and ' 'finder chart for %s at RA: %.3f, DEC: %.3f' % ( objectid , objectinfo [ 'ra' ] , objectinfo [ 'decl' ] ) )
    elif verbose and not skyview_lookup :
        LOGINFO ( 'adding in object information ' 'for %s at RA: %.3f, DEC: %.3f. ' 'skipping finder chart because skyview_lookup = False' % ( objectid , objectinfo [ 'ra' ] , objectinfo [ 'decl' ] ) )
    # get the finder chart
    try :
        if skyview_lookup :
            try : # generate the finder chart
                finder , finderheader = skyview_stamp ( objectinfo [ 'ra' ] , objectinfo [ 'decl' ] , convolvewith = finderconvolve , verbose = verbose , flip = False , cachedir = findercachedir , timeout = skyview_timeout , retry_failed = skyview_retry_failed , )
            except OSError as e :
                if not fast_mode :
                    LOGERROR ( 'finder image appears to be corrupt, retrying...' )
                    # generate the finder chart
                    finder , finderheader = skyview_stamp ( objectinfo [ 'ra' ] , objectinfo [ 'decl' ] , convolvewith = finderconvolve , verbose = verbose , flip = False , cachedir = findercachedir , forcefetch = True , timeout = skyview_timeout , retry_failed = False # do not start an infinite loop
                    )
            finderfig = plt . figure ( figsize = ( 3 , 3 ) , dpi = plotdpi )
            # initialize the finder WCS
            finderwcs = WCS ( finderheader )
            # use the WCS transform for the plot
            ax = finderfig . add_subplot ( 111 , frameon = False )
            ax . imshow ( finder , cmap = findercmap , origin = 'lower' )
        else :
            finder , finderheader , finderfig , finderwcs = ( None , None , None , None )
        # skip down to after nbr stuff for the rest of the finderchart . . .
        # search around the target ' s location and get its neighbors if
        # lclistpkl is provided and it exists
        if ( lclistpkl is not None and nbrradiusarcsec is not None and nbrradiusarcsec > 0.0 ) : # if lclistpkl is a string , open it as a pickle
            if isinstance ( lclistpkl , str ) and os . path . exists ( lclistpkl ) :
                if lclistpkl . endswith ( '.gz' ) :
                    infd = gzip . open ( lclistpkl , 'rb' )
                else :
                    infd = open ( lclistpkl , 'rb' )
                lclist = pickle . load ( infd )
                infd . close ( )
            # otherwise , if it ' s a dict , we get it directly
            elif isinstance ( lclistpkl , dict ) :
                lclist = lclistpkl
            # finally , if it ' s nothing we recognize , ignore it
            else :
                LOGERROR ( 'could not understand lclistpkl kwarg, ' 'not getting neighbor info' )
                lclist = dict ( )
            # check if we have a KDTree to use
            # if we don ' t , skip neighbor stuff
            if 'kdtree' not in lclist :
                LOGERROR ( 'neighbors within %.1f arcsec for %s could ' 'not be found, no kdtree in lclistpkl: %s' % ( objectid , lclistpkl ) )
                neighbors = None
                kdt = None
            # otherwise , do neighbor processing
            else :
                kdt = lclist [ 'kdtree' ]
                obj_cosdecl = np . cos ( np . radians ( objectinfo [ 'decl' ] ) )
                obj_sindecl = np . sin ( np . radians ( objectinfo [ 'decl' ] ) )
                obj_cosra = np . cos ( np . radians ( objectinfo [ 'ra' ] ) )
                obj_sinra = np . sin ( np . radians ( objectinfo [ 'ra' ] ) )
                obj_xyz = np . column_stack ( ( obj_cosra * obj_cosdecl , obj_sinra * obj_cosdecl , obj_sindecl ) )
                match_xyzdist = ( 2.0 * np . sin ( np . radians ( nbrradiusarcsec / 3600.0 ) / 2.0 ) )
                matchdists , matchinds = kdt . query ( obj_xyz , k = maxnumneighbors + 1 , # get maxnumneighbors + tgt
                distance_upper_bound = match_xyzdist )
                # sort by matchdist
                mdsorted = np . argsort ( matchdists [ 0 ] )
                matchdists = matchdists [ 0 ] [ mdsorted ]
                matchinds = matchinds [ 0 ] [ mdsorted ]
                # luckily , the indices to the kdtree are the same as that
                # for the objects ( I think )
                neighbors = [ ]
                nbrind = 0
                for md , mi in zip ( matchdists , matchinds ) :
                    if np . isfinite ( md ) and md > 0.0 :
                        if skyview_lookup : # generate the xy for the finder we ' ll use a
                        # HTML5 canvas and these pixcoords to highlight
                        # each neighbor when we mouse over its row in
                        # the neighbors tab
                        # we use coord origin = 0 here and not the usual
                        # 1 because we ' re annotating a numpy array
                            pixcoords = finderwcs . all_world2pix ( np . array ( [ [ lclist [ 'objects' ] [ 'ra' ] [ mi ] , lclist [ 'objects' ] [ 'decl' ] [ mi ] ] ] ) , 0 )
                            # each elem is { ' objectid ' ,
                            # ' ra ' , ' decl ' ,
                            # ' xpix ' , ' ypix ' ,
                            # ' dist ' , ' lcfpath ' }
                            thisnbr = { 'objectid' : ( lclist [ 'objects' ] [ 'objectid' ] [ mi ] ) , 'ra' : lclist [ 'objects' ] [ 'ra' ] [ mi ] , 'decl' : lclist [ 'objects' ] [ 'decl' ] [ mi ] , 'xpix' : pixcoords [ 0 , 0 ] , 'ypix' : 300.0 - pixcoords [ 0 , 1 ] , 'dist' : _xyzdist_to_distarcsec ( md ) , 'lcfpath' : lclist [ 'objects' ] [ 'lcfname' ] [ mi ] }
                            neighbors . append ( thisnbr )
                            nbrind = nbrind + 1
                            # put in a nice marker for this neighbor into
                            # the overall finder chart
                            annotatex = pixcoords [ 0 , 0 ]
                            annotatey = pixcoords [ 0 , 1 ]
                            if ( ( 300.0 - annotatex ) > 50.0 ) :
                                offx = annotatex + 30.0
                                xha = 'center'
                            else :
                                offx = annotatex - 30.0
                                xha = 'center'
                            if ( ( 300.0 - annotatey ) > 50.0 ) :
                                offy = annotatey - 30.0
                                yha = 'center'
                            else :
                                offy = annotatey + 30.0
                                yha = 'center'
                            ax . annotate ( 'N%s' % nbrind , ( annotatex , annotatey ) , xytext = ( offx , offy ) , arrowprops = { 'facecolor' : 'blue' , 'edgecolor' : 'blue' , 'width' : 1.0 , 'headwidth' : 1.0 , 'headlength' : 0.1 , 'shrink' : 0.0 } , color = 'blue' , horizontalalignment = xha , verticalalignment = yha )
                        else :
                            thisnbr = { 'objectid' : ( lclist [ 'objects' ] [ 'objectid' ] [ mi ] ) , 'ra' : lclist [ 'objects' ] [ 'ra' ] [ mi ] , 'decl' : lclist [ 'objects' ] [ 'decl' ] [ mi ] , 'xpix' : 0.0 , 'ypix' : 0.0 , 'dist' : _xyzdist_to_distarcsec ( md ) , 'lcfpath' : lclist [ 'objects' ] [ 'lcfname' ] [ mi ] }
                            neighbors . append ( thisnbr )
                            nbrind = nbrind + 1
        # if there are no neighbors , set the ' neighbors ' key to None
        else :
            neighbors = None
            kdt = None
        if skyview_lookup : # finish up the finder chart after neighbors are processed
            ax . set_xticks ( [ ] )
            ax . set_yticks ( [ ] )
            # add a reticle pointing to the object ' s coordinates
            # we use coord origin = 0 here and not the usual
            # 1 because we ' re annotating a numpy array
            object_pixcoords = finderwcs . all_world2pix ( [ [ objectinfo [ 'ra' ] , objectinfo [ 'decl' ] ] ] , 0 )
            ax . axvline ( # x = 150.0,
            x = object_pixcoords [ 0 , 0 ] , ymin = 0.375 , ymax = 0.45 , linewidth = 1 , color = 'b' )
            ax . axhline ( # y = 150.0,
            y = object_pixcoords [ 0 , 1 ] , xmin = 0.375 , xmax = 0.45 , linewidth = 1 , color = 'b' )
            ax . set_frame_on ( False )
            # this is the output instance
            finderpng = StrIO ( )
            finderfig . savefig ( finderpng , bbox_inches = 'tight' , pad_inches = 0.0 , format = 'png' )
            plt . close ( )
            # encode the finderpng instance to base64
            finderpng . seek ( 0 )
            finderb64 = base64 . b64encode ( finderpng . read ( ) )
            # close the stringio buffer
            finderpng . close ( )
        else :
            finderb64 = None
    except Exception as e :
        LOGEXCEPTION ( 'could not fetch a DSS stamp for this ' 'object %s using coords (%.3f,%.3f)' % ( objectid , objectinfo [ 'ra' ] , objectinfo [ 'decl' ] ) )
        finderb64 = None
        neighbors = None
        kdt = None
# if we don ' t have ra , dec info , then everything is none up to this point
else :
    finderb64 = None
    neighbors = None
    kdt = None
# end of finder chart operations
# now that we have the finder chart , get the rest of the object
# information
# get the rest of the features , these don ' t necessarily rely on ra , dec and
# should degrade gracefully if these aren ' t provided
if isinstance ( objectinfo , dict ) :
    if 'objectid' not in objectinfo and 'hatid' in objectinfo :
        objectid = objectinfo [ 'hatid' ]
        objectinfo [ 'objectid' ] = objectid
    elif 'objectid' in objectinfo :
        objectid = objectinfo [ 'objectid' ]
    else :
        objectid = os . urandom ( 12 ) . hex ( ) [ : 7 ]
        objectinfo [ 'objectid' ] = objectid
        LOGWARNING ( 'no objectid found in objectinfo dict, ' 'making up a random one: %s' )
    # get the neighbor features and GAIA info
    nbrfeat = neighbor_gaia_features ( objectinfo , kdt , nbrradiusarcsec , verbose = False , gaia_submit_timeout = gaia_submit_timeout , gaia_submit_tries = gaia_submit_tries , gaia_max_timeout = gaia_max_timeout , gaia_mirror = gaia_mirror , complete_query_later = complete_query_later , search_simbad = search_simbad )
    objectinfo . update ( nbrfeat )
    # see if the objectinfo dict has pmra / pmdecl entries . if it doesn ' t ,
    # then we ' ll see if the nbrfeat dict has pmra / pmdecl from GAIA . we ' ll
    # set the appropriate provenance keys as well so we know where the PM
    # came from
    if ( ( 'pmra' not in objectinfo ) or ( ( 'pmra' in objectinfo ) and ( ( objectinfo [ 'pmra' ] is None ) or ( not np . isfinite ( objectinfo [ 'pmra' ] ) ) ) ) ) :
        if 'ok' in nbrfeat [ 'gaia_status' ] :
            objectinfo [ 'pmra' ] = nbrfeat [ 'gaia_pmras' ] [ 0 ]
            objectinfo [ 'pmra_err' ] = nbrfeat [ 'gaia_pmra_errs' ] [ 0 ]
            objectinfo [ 'pmra_source' ] = 'gaia'
            if verbose :
                LOGWARNING ( 'pmRA not found in provided objectinfo dict, ' 'using value from GAIA' )
    else :
        objectinfo [ 'pmra_source' ] = 'light curve'
    if ( ( 'pmdecl' not in objectinfo ) or ( ( 'pmdecl' in objectinfo ) and ( ( objectinfo [ 'pmdecl' ] is None ) or ( not np . isfinite ( objectinfo [ 'pmdecl' ] ) ) ) ) ) :
        if 'ok' in nbrfeat [ 'gaia_status' ] :
            objectinfo [ 'pmdecl' ] = nbrfeat [ 'gaia_pmdecls' ] [ 0 ]
            objectinfo [ 'pmdecl_err' ] = nbrfeat [ 'gaia_pmdecl_errs' ] [ 0 ]
            objectinfo [ 'pmdecl_source' ] = 'gaia'
            if verbose :
                LOGWARNING ( 'pmDEC not found in provided objectinfo dict, ' 'using value from GAIA' )
    else :
        objectinfo [ 'pmdecl_source' ] = 'light curve'
    # update GAIA info so it ' s available at the first level
    if 'ok' in objectinfo [ 'gaia_status' ] :
        objectinfo [ 'gaiaid' ] = objectinfo [ 'gaia_ids' ] [ 0 ]
        objectinfo [ 'gaiamag' ] = objectinfo [ 'gaia_mags' ] [ 0 ]
        objectinfo [ 'gaia_absmag' ] = objectinfo [ 'gaia_absolute_mags' ] [ 0 ]
        objectinfo [ 'gaia_parallax' ] = objectinfo [ 'gaia_parallaxes' ] [ 0 ]
        objectinfo [ 'gaia_parallax_err' ] = ( objectinfo [ 'gaia_parallax_errs' ] [ 0 ] )
        objectinfo [ 'gaia_pmra' ] = objectinfo [ 'gaia_pmras' ] [ 0 ]
        objectinfo [ 'gaia_pmra_err' ] = objectinfo [ 'gaia_pmra_errs' ] [ 0 ]
        objectinfo [ 'gaia_pmdecl' ] = objectinfo [ 'gaia_pmdecls' ] [ 0 ]
        objectinfo [ 'gaia_pmdecl_err' ] = objectinfo [ 'gaia_pmdecl_errs' ] [ 0 ]
    else :
        objectinfo [ 'gaiaid' ] = None
        objectinfo [ 'gaiamag' ] = np . nan
        objectinfo [ 'gaia_absmag' ] = np . nan
        objectinfo [ 'gaia_parallax' ] = np . nan
        objectinfo [ 'gaia_parallax_err' ] = np . nan
        objectinfo [ 'gaia_pmra' ] = np . nan
        objectinfo [ 'gaia_pmra_err' ] = np . nan
        objectinfo [ 'gaia_pmdecl' ] = np . nan
        objectinfo [ 'gaia_pmdecl_err' ] = np . nan
    # get the object ' s TIC information
    if ( 'ra' in objectinfo and objectinfo [ 'ra' ] is not None and np . isfinite ( objectinfo [ 'ra' ] ) and 'decl' in objectinfo and objectinfo [ 'decl' ] is not None and np . isfinite ( objectinfo [ 'decl' ] ) ) :
        try :
            ticres = tic_conesearch ( objectinfo [ 'ra' ] , objectinfo [ 'decl' ] , radius_arcmin = 5.0 / 60.0 , verbose = verbose , timeout = gaia_max_timeout , maxtries = gaia_submit_tries )
            if ticres is not None :
                with open ( ticres [ 'cachefname' ] , 'r' ) as infd :
                    ticinfo = json . load ( infd )
                if ( 'data' in ticinfo and len ( ticinfo [ 'data' ] ) > 0 and isinstance ( ticinfo [ 'data' ] [ 0 ] , dict ) ) :
                    objectinfo [ 'ticid' ] = str ( ticinfo [ 'data' ] [ 0 ] [ 'ID' ] )
                    objectinfo [ 'tessmag' ] = ticinfo [ 'data' ] [ 0 ] [ 'Tmag' ]
                    objectinfo [ 'tic_version' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'version' ] )
                    objectinfo [ 'tic_distarcsec' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'dstArcSec' ] )
                    objectinfo [ 'tessmag_origin' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'TESSflag' ] )
                    objectinfo [ 'tic_starprop_origin' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'SPFlag' ] )
                    objectinfo [ 'tic_lumclass' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'lumclass' ] )
                    objectinfo [ 'tic_teff' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'Teff' ] )
                    objectinfo [ 'tic_teff_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_Teff' ] )
                    objectinfo [ 'tic_logg' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'logg' ] )
                    objectinfo [ 'tic_logg_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_logg' ] )
                    objectinfo [ 'tic_mh' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'MH' ] )
                    objectinfo [ 'tic_mh_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_MH' ] )
                    objectinfo [ 'tic_radius' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'rad' ] )
                    objectinfo [ 'tic_radius_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_rad' ] )
                    objectinfo [ 'tic_mass' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'mass' ] )
                    objectinfo [ 'tic_mass_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_mass' ] )
                    objectinfo [ 'tic_density' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'rho' ] )
                    objectinfo [ 'tic_density_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_rho' ] )
                    objectinfo [ 'tic_luminosity' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'lum' ] )
                    objectinfo [ 'tic_luminosity_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_lum' ] )
                    objectinfo [ 'tic_distancepc' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'd' ] )
                    objectinfo [ 'tic_distancepc_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_d' ] )
                    # fill in any missing info using the TIC entry
                    if ( 'gaiaid' not in objectinfo or ( 'gaiaid' in objectinfo and ( objectinfo [ 'gaiaid' ] is None ) ) ) :
                        objectinfo [ 'gaiaid' ] = ticinfo [ 'data' ] [ 0 ] [ 'GAIA' ]
                    if ( 'gaiamag' not in objectinfo or ( 'gaiamag' in objectinfo and ( objectinfo [ 'gaiamag' ] is None or not np . isfinite ( objectinfo [ 'gaiamag' ] ) ) ) ) :
                        objectinfo [ 'gaiamag' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'GAIAmag' ] )
                        objectinfo [ 'gaiamag_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_GAIAmag' ] )
                    if ( 'gaia_parallax' not in objectinfo or ( 'gaia_parallax' in objectinfo and ( objectinfo [ 'gaia_parallax' ] is None or not np . isfinite ( objectinfo [ 'gaia_parallax' ] ) ) ) ) :
                        objectinfo [ 'gaia_parallax' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'plx' ] )
                        objectinfo [ 'gaia_parallax_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_plx' ] )
                        if ( objectinfo [ 'gaiamag' ] is not None and np . isfinite ( objectinfo [ 'gaiamag' ] ) and objectinfo [ 'gaia_parallax' ] is not None and np . isfinite ( objectinfo [ 'gaia_parallax' ] ) ) :
                            objectinfo [ 'gaia_absmag' ] = ( magnitudes . absolute_gaia_magnitude ( objectinfo [ 'gaiamag' ] , objectinfo [ 'gaia_parallax' ] ) )
                    if ( 'pmra' not in objectinfo or ( 'pmra' in objectinfo and ( objectinfo [ 'pmra' ] is None or not np . isfinite ( objectinfo [ 'pmra' ] ) ) ) ) :
                        objectinfo [ 'pmra' ] = ticinfo [ 'data' ] [ 0 ] [ 'pmRA' ]
                        objectinfo [ 'pmra_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_pmRA' ] )
                        objectinfo [ 'pmra_source' ] = 'TIC'
                    if ( 'pmdecl' not in objectinfo or ( 'pmdecl' in objectinfo and ( objectinfo [ 'pmdecl' ] is None or not np . isfinite ( objectinfo [ 'pmdecl' ] ) ) ) ) :
                        objectinfo [ 'pmdecl' ] = ticinfo [ 'data' ] [ 0 ] [ 'pmDEC' ]
                        objectinfo [ 'pmdecl_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_pmDEC' ] )
                        objectinfo [ 'pmdecl_source' ] = 'TIC'
                    if ( 'bmag' not in objectinfo or ( 'bmag' in objectinfo and ( objectinfo [ 'bmag' ] is None or not np . isfinite ( objectinfo [ 'bmag' ] ) ) ) ) :
                        objectinfo [ 'bmag' ] = ticinfo [ 'data' ] [ 0 ] [ 'Bmag' ]
                        objectinfo [ 'bmag_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_Bmag' ] )
                    if ( 'vmag' not in objectinfo or ( 'vmag' in objectinfo and ( objectinfo [ 'vmag' ] is None or not np . isfinite ( objectinfo [ 'vmag' ] ) ) ) ) :
                        objectinfo [ 'vmag' ] = ticinfo [ 'data' ] [ 0 ] [ 'Vmag' ]
                        objectinfo [ 'vmag_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_Vmag' ] )
                    if ( 'sdssu' not in objectinfo or ( 'sdssu' in objectinfo and ( objectinfo [ 'sdssu' ] is None or not np . isfinite ( objectinfo [ 'sdssu' ] ) ) ) ) :
                        objectinfo [ 'sdssu' ] = ticinfo [ 'data' ] [ 0 ] [ 'umag' ]
                        objectinfo [ 'sdssu_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_umag' ] )
                    if ( 'sdssg' not in objectinfo or ( 'sdssg' in objectinfo and ( objectinfo [ 'sdssg' ] is None or not np . isfinite ( objectinfo [ 'sdssg' ] ) ) ) ) :
                        objectinfo [ 'sdssg' ] = ticinfo [ 'data' ] [ 0 ] [ 'gmag' ]
                        objectinfo [ 'sdssg_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_gmag' ] )
                    if ( 'sdssr' not in objectinfo or ( 'sdssr' in objectinfo and ( objectinfo [ 'sdssr' ] is None or not np . isfinite ( objectinfo [ 'sdssr' ] ) ) ) ) :
                        objectinfo [ 'sdssr' ] = ticinfo [ 'data' ] [ 0 ] [ 'rmag' ]
                        objectinfo [ 'sdssr_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_rmag' ] )
                    if ( 'sdssi' not in objectinfo or ( 'sdssi' in objectinfo and ( objectinfo [ 'sdssi' ] is None or not np . isfinite ( objectinfo [ 'sdssi' ] ) ) ) ) :
                        objectinfo [ 'sdssi' ] = ticinfo [ 'data' ] [ 0 ] [ 'imag' ]
                        objectinfo [ 'sdssi_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_imag' ] )
                    if ( 'sdssz' not in objectinfo or ( 'sdssz' in objectinfo and ( objectinfo [ 'sdssz' ] is None or not np . isfinite ( objectinfo [ 'sdssz' ] ) ) ) ) :
                        objectinfo [ 'sdssz' ] = ticinfo [ 'data' ] [ 0 ] [ 'zmag' ]
                        objectinfo [ 'sdssz_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_zmag' ] )
                    if ( 'jmag' not in objectinfo or ( 'jmag' in objectinfo and ( objectinfo [ 'jmag' ] is None or not np . isfinite ( objectinfo [ 'jmag' ] ) ) ) ) :
                        objectinfo [ 'jmag' ] = ticinfo [ 'data' ] [ 0 ] [ 'Jmag' ]
                        objectinfo [ 'jmag_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_Jmag' ] )
                    if ( 'hmag' not in objectinfo or ( 'hmag' in objectinfo and ( objectinfo [ 'hmag' ] is None or not np . isfinite ( objectinfo [ 'hmag' ] ) ) ) ) :
                        objectinfo [ 'hmag' ] = ticinfo [ 'data' ] [ 0 ] [ 'Hmag' ]
                        objectinfo [ 'hmag_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_Hmag' ] )
                    if ( 'kmag' not in objectinfo or ( 'kmag' in objectinfo and ( objectinfo [ 'kmag' ] is None or not np . isfinite ( objectinfo [ 'kmag' ] ) ) ) ) :
                        objectinfo [ 'kmag' ] = ticinfo [ 'data' ] [ 0 ] [ 'Kmag' ]
                        objectinfo [ 'kmag_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_Kmag' ] )
                    if ( 'wise1' not in objectinfo or ( 'wise1' in objectinfo and ( objectinfo [ 'wise1' ] is None or not np . isfinite ( objectinfo [ 'wise1' ] ) ) ) ) :
                        objectinfo [ 'wise1' ] = ticinfo [ 'data' ] [ 0 ] [ 'w1mag' ]
                        objectinfo [ 'wise1_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_w1mag' ] )
                    if ( 'wise2' not in objectinfo or ( 'wise2' in objectinfo and ( objectinfo [ 'wise2' ] is None or not np . isfinite ( objectinfo [ 'wise2' ] ) ) ) ) :
                        objectinfo [ 'wise2' ] = ticinfo [ 'data' ] [ 0 ] [ 'w2mag' ]
                        objectinfo [ 'wise2_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_w2mag' ] )
                    if ( 'wise3' not in objectinfo or ( 'wise3' in objectinfo and ( objectinfo [ 'wise3' ] is None or not np . isfinite ( objectinfo [ 'wise3' ] ) ) ) ) :
                        objectinfo [ 'wise3' ] = ticinfo [ 'data' ] [ 0 ] [ 'w3mag' ]
                        objectinfo [ 'wise3_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_w3mag' ] )
                    if ( 'wise4' not in objectinfo or ( 'wise4' in objectinfo and ( objectinfo [ 'wise4' ] is None or not np . isfinite ( objectinfo [ 'wise4' ] ) ) ) ) :
                        objectinfo [ 'wise4' ] = ticinfo [ 'data' ] [ 0 ] [ 'w4mag' ]
                        objectinfo [ 'wise4_err' ] = ( ticinfo [ 'data' ] [ 0 ] [ 'e_w4mag' ] )
            else :
                LOGERROR ( 'could not look up TIC ' 'information for object: %s ' 'at (%.3f, %.3f)' % ( objectinfo [ 'objectid' ] , objectinfo [ 'ra' ] , objectinfo [ 'decl' ] ) )
        except Exception as e :
            LOGEXCEPTION ( 'could not look up TIC ' 'information for object: %s ' 'at (%.3f, %.3f)' % ( objectinfo [ 'objectid' ] , objectinfo [ 'ra' ] , objectinfo [ 'decl' ] ) )
    # try to get the object ' s coord features
    coordfeat = coord_features ( objectinfo )
    # get the color features
    colorfeat = color_features ( objectinfo , deredden = deredden_object , custom_bandpasses = custom_bandpasses , dust_timeout = dust_timeout )
    # get the object ' s color classification
    colorclass = color_classification ( colorfeat , coordfeat )
    # update the objectinfo dict with everything
    objectinfo . update ( colorfeat )
    objectinfo . update ( coordfeat )
    objectinfo . update ( colorclass )
    # put together the initial checkplot pickle dictionary
    # this will be updated by the functions below as appropriate
    # and will written out as a gzipped pickle at the end of processing
    checkplotdict = { 'objectid' : objectid , 'neighbors' : neighbors , 'objectinfo' : objectinfo , 'finderchart' : finderb64 , 'sigclip' : sigclip , 'normto' : normto , 'normmingap' : normmingap }
    # add the objecttags key to objectinfo
    checkplotdict [ 'objectinfo' ] [ 'objecttags' ] = None
# if there ' s no objectinfo , we can ' t do anything .
else : # empty objectinfo dict
    checkplotdict = { 'objectid' : None , 'neighbors' : None , 'objectinfo' : { 'available_bands' : [ ] , 'available_band_labels' : [ ] , 'available_dereddened_bands' : [ ] , 'available_dereddened_band_labels' : [ ] , 'available_colors' : [ ] , 'available_color_labels' : [ ] , 'bmag' : None , 'bmag-vmag' : None , 'decl' : None , 'hatid' : None , 'hmag' : None , 'imag-jmag' : None , 'jmag-kmag' : None , 'jmag' : None , 'kmag' : None , 'ndet' : None , 'network' : None , 'objecttags' : None , 'pmdecl' : None , 'pmdecl_err' : None , 'pmra' : None , 'pmra_err' : None , 'propermotion' : None , 'ra' : None , 'rpmj' : None , 'sdssg' : None , 'sdssi' : None , 'sdssr' : None , 'stations' : None , 'twomassid' : None , 'ucac4id' : None , 'vmag' : None } , 'finderchart' : None , 'sigclip' : sigclip , 'normto' : normto , 'normmingap' : normmingap }
# end of objectinfo processing
# add the varinfo dict
if isinstance ( varinfo , dict ) :
    checkplotdict [ 'varinfo' ] = varinfo
else :
    checkplotdict [ 'varinfo' ] = { 'objectisvar' : None , 'vartags' : None , 'varisperiodic' : None , 'varperiod' : None , 'varepoch' : None , }
return checkplotdict


signature:
def _pkl_periodogram ( lspinfo , plotdpi = 100 , override_pfmethod = None ) :
    '''This returns the periodogram plot PNG as base64 , plus info as a dict .
 Parameters
 lspinfo : dict
 This is an lspinfo dict containing results from a period - finding
 function . If it ' s from an astrobase period - finding function in
 periodbase , this will already be in the correct format . To use external
 period - finder results with this function , the ` lspinfo ` dict must be of
 the following form , with at least the keys listed below : :
 { ' periods ' : np . array of all periods searched by the period - finder ,
 ' lspvals ' : np . array of periodogram power value for each period ,
 ' bestperiod ' : a float value that is the period with the highest
 peak in the periodogram , i . e . the most - likely actual
 period ,
 ' method ' : a three - letter code naming the period - finder used ; must
 be one of the keys in the
 ` astrobase . periodbase . METHODLABELS ` dict ,
 ' nbestperiods ' : a list of the periods corresponding to periodogram
 peaks ( ` nbestlspvals ` below ) to annotate on the
 periodogram plot so they can be called out
 visually ,
 ' nbestlspvals ' : a list of the power values associated with
 periodogram peaks to annotate on the periodogram
 plot so they can be called out visually ; should be
 the same length as ` nbestperiods ` above }
 ` nbestperiods ` and ` nbestlspvals ` must have at least 5 elements each ,
 e . g . describing the five ' best ' ( highest power ) peaks in the
 periodogram .
 plotdpi : int
 The resolution in DPI of the output periodogram plot to make .
 override _ pfmethod : str or None
 This is used to set a custom label for this periodogram
 method . Normally , this is taken from the ' method ' key in the input
 ` lspinfo ` dict , but if you want to override the output method name ,
 provide this as a string here . This can be useful if you have multiple
 results you want to incorporate into a checkplotdict from a single
 period - finder ( e . g . if you ran BLS over several period ranges
 separately ) .
 Returns
 dict
 Returns a dict that contains the following items : :
 { methodname : { ' periods ' : the period array from lspinfo ,
 ' lspval ' : the periodogram power array from lspinfo ,
 ' bestperiod ' : the best period from lspinfo ,
 ' nbestperiods ' : the ' nbestperiods ' list from lspinfo ,
 ' nbestlspvals ' : the ' nbestlspvals ' list from lspinfo ,
 ' periodogram ' : base64 encoded string representation of
 the periodogram plot } }
 The dict is returned in this format so it can be directly incorporated
 under the period - finder ' s label ` methodname ` in a checkplotdict , using
 Python ' s dict ` update ( ) ` method .'''

implementation:
# get the appropriate plot ylabel
pgramylabel = PLOTYLABELS [ lspinfo [ 'method' ] ]
# get the periods and lspvals from lspinfo
periods = lspinfo [ 'periods' ]
lspvals = lspinfo [ 'lspvals' ]
bestperiod = lspinfo [ 'bestperiod' ]
nbestperiods = lspinfo [ 'nbestperiods' ]
nbestlspvals = lspinfo [ 'nbestlspvals' ]
# open the figure instance
pgramfig = plt . figure ( figsize = ( 7.5 , 4.8 ) , dpi = plotdpi )
# make the plot
plt . plot ( periods , lspvals )
plt . xscale ( 'log' , basex = 10 )
plt . xlabel ( 'Period [days]' )
plt . ylabel ( pgramylabel )
plottitle = '%s - %.6f d' % ( METHODLABELS [ lspinfo [ 'method' ] ] , bestperiod )
plt . title ( plottitle )
# show the best five peaks on the plot
for xbestperiod , xbestpeak in zip ( nbestperiods , nbestlspvals ) :
    plt . annotate ( '%.6f' % xbestperiod , xy = ( xbestperiod , xbestpeak ) , xycoords = 'data' , xytext = ( 0.0 , 25.0 ) , textcoords = 'offset points' , arrowprops = dict ( arrowstyle = "->" ) , fontsize = '14.0' )
# make a grid
plt . grid ( color = '#a9a9a9' , alpha = 0.9 , zorder = 0 , linewidth = 1.0 , linestyle = ':' )
# this is the output instance
pgrampng = StrIO ( )
pgramfig . savefig ( pgrampng , # bbox _ inches = ' tight ' ,
pad_inches = 0.0 , format = 'png' )
plt . close ( )
# encode the finderpng instance to base64
pgrampng . seek ( 0 )
pgramb64 = base64 . b64encode ( pgrampng . read ( ) )
# close the stringio buffer
pgrampng . close ( )
if not override_pfmethod : # this is the dict to return
    checkplotdict = { lspinfo [ 'method' ] : { 'periods' : periods , 'lspvals' : lspvals , 'bestperiod' : bestperiod , 'nbestperiods' : nbestperiods , 'nbestlspvals' : nbestlspvals , 'periodogram' : pgramb64 , } }
else : # this is the dict to return
    checkplotdict = { override_pfmethod : { 'periods' : periods , 'lspvals' : lspvals , 'bestperiod' : bestperiod , 'nbestperiods' : nbestperiods , 'nbestlspvals' : nbestlspvals , 'periodogram' : pgramb64 , } }
return checkplotdict


signature:
def _pkl_magseries_plot ( stimes , smags , serrs , plotdpi = 100 , magsarefluxes = False ) :
    '''This returns the magseries plot PNG as base64 , plus arrays as dict .
 Parameters
 stimes , smags , serrs : np . array
 The mag / flux time - series arrays along with associated errors . These
 should all have been run through nan - stripping and sigma - clipping
 beforehand .
 plotdpi : int
 The resolution of the plot to make in DPI .
 magsarefluxes : bool
 If True , indicates the input time - series is fluxes and not mags so the
 plot y - axis direction and range can be set appropriately .
 Returns
 dict
 A dict of the following form is returned : :
 { ' magseries ' : { ' plot ' : base64 encoded str representation of the
 magnitude / flux time - series plot ,
 ' times ' : the ` stimes ` array ,
 ' mags ' : the ` smags ` array ,
 ' errs ' : the ' serrs ' array } }
 The dict is returned in this format so it can be directly incorporated
 in a checkplotdict , using Python ' s dict ` update ( ) ` method .'''

implementation:
scaledplottime = stimes - npmin ( stimes )
# open the figure instance
magseriesfig = plt . figure ( figsize = ( 7.5 , 4.8 ) , dpi = plotdpi )
plt . plot ( scaledplottime , smags , marker = 'o' , ms = 2.0 , ls = 'None' , mew = 0 , color = 'green' , rasterized = True )
# flip y axis for mags
if not magsarefluxes :
    plot_ylim = plt . ylim ( )
    plt . ylim ( ( plot_ylim [ 1 ] , plot_ylim [ 0 ] ) )
# set the x axis limit
plt . xlim ( ( npmin ( scaledplottime ) - 2.0 , npmax ( scaledplottime ) + 2.0 ) )
# make a grid
plt . grid ( color = '#a9a9a9' , alpha = 0.9 , zorder = 0 , linewidth = 1.0 , linestyle = ':' )
# make the x and y axis labels
plot_xlabel = 'JD - %.3f' % npmin ( stimes )
if magsarefluxes :
    plot_ylabel = 'flux'
else :
    plot_ylabel = 'magnitude'
plt . xlabel ( plot_xlabel )
plt . ylabel ( plot_ylabel )
# fix the yaxis ticks ( turns off offset and uses the full
# value of the yaxis tick )
plt . gca ( ) . get_yaxis ( ) . get_major_formatter ( ) . set_useOffset ( False )
plt . gca ( ) . get_xaxis ( ) . get_major_formatter ( ) . set_useOffset ( False )
# this is the output instance
magseriespng = StrIO ( )
magseriesfig . savefig ( magseriespng , # bbox _ inches = ' tight ' ,
pad_inches = 0.05 , format = 'png' )
plt . close ( )
# encode the finderpng instance to base64
magseriespng . seek ( 0 )
magseriesb64 = base64 . b64encode ( magseriespng . read ( ) )
# close the stringio buffer
magseriespng . close ( )
checkplotdict = { 'magseries' : { 'plot' : magseriesb64 , 'times' : stimes , 'mags' : smags , 'errs' : serrs } }
return checkplotdict


signature:
def _pkl_phased_magseries_plot ( checkplotdict , lspmethod , periodind , stimes , smags , serrs , varperiod , varepoch , lspmethodind = 0 , phasewrap = True , phasesort = True , phasebin = 0.002 , minbinelems = 7 , plotxlim = ( - 0.8 , 0.8 ) , plotdpi = 100 , bestperiodhighlight = None , xgridlines = None , xliminsetmode = False , magsarefluxes = False , directreturn = False , overplotfit = None , verbose = True , override_pfmethod = None ) :
    '''This returns the phased magseries plot PNG as base64 plus info as a dict .
 Parameters
 checkplotdict : dict
 This is an existing checkplotdict to update . If it ' s None or
 ` directreturn ` = True , then the generated dict result for this magseries
 plot will be returned directly .
 lspmethod : str
 lspmethod is a string indicating the type of period - finding algorithm
 that produced the period . If this is not in
 ` astrobase . plotbase . METHODSHORTLABELS ` , it will be used verbatim . In
 most cases , this will come directly from the lspinfo dict produced by a
 period - finder function .
 periodind : int
 This is the index of the current periodogram period being operated
 on : :
 If = = 0 - > best period and ` bestperiodhighlight ` is applied if not
 None
 If > 0 - > some other peak of the periodogram
 If = = - 1 - > special mode w / no periodogram labels and enabled
 highlight
 stimes , smags , serrs : np . array
 The mag / flux time - series arrays along with associated errors . These
 should all have been run through nan - stripping and sigma - clipping
 beforehand .
 varperiod : float or None
 The period to use for this phased light curve plot tile .
 varepoch : ' min ' or float or list of lists or None
 The epoch to use for this phased light curve plot tile . If this is a
 float , will use the provided value directly . If this is ' min ' , will
 automatically figure out the time - of - minimum of the phased light
 curve . If this is None , will use the mimimum value of ` stimes ` as the
 epoch of the phased light curve plot . If this is a list of lists , will
 use the provided value of ` lspmethodind ` to look up the current
 period - finder method and the provided value of ` periodind ` to look up
 the epoch associated with that method and the current period . This is
 mostly only useful when ` twolspmode ` is True .
 phasewrap : bool
 If this is True , the phased time - series will be wrapped around
 phase 0.0.
 phasesort : bool
 If True , will sort the phased light curve in order of increasing phase .
 phasebin : float
 The bin size to use to group together measurements closer than this
 amount in phase . This is in units of phase . If this is a float , a
 phase - binned version of the phased light curve will be overplotted on
 top of the regular phased light curve .
 minbinelems : int
 The minimum number of elements required per phase bin to include it in
 the phased LC plot .
 plotxlim : sequence of two floats or None
 The x - range ( min , max ) of the phased light curve plot . If None , will be
 determined automatically .
 plotdpi : int
 The resolution of the output plot PNGs in dots per inch .
 bestperiodhighlight : str or None
 If not None , this is a str with a matplotlib color specification to use
 as the background color to highlight the phased light curve plot of the
 ' best ' period and epoch combination . If None , no highlight will be
 applied .
 xgridlines : list of floats or None
 If this is provided , must be a list of floats corresponding to the phase
 values where to draw vertical dashed lines as a means of highlighting
 these .
 xliminsetmode : bool
 If this is True , the generated phased light curve plot will use the
 values of ` plotxlim ` as the main plot x - axis limits ( i . e . zoomed - in if
 ` plotxlim ` is a range smaller than the full phase range ) , and will show
 the full phased light curve plot as an smaller inset . Useful for
 planetary transit light curves .
 magsarefluxes : bool
 If True , indicates the input time - series is fluxes and not mags so the
 plot y - axis direction and range can be set appropriately .
 directreturn : bool
 If this set to True , will return only the dict corresponding to the
 phased LC plot for the input ` periodind ` and ` lspmethod ` and not return
 this result embedded in a checkplotdict .
 overplotfit : dict
 If this is provided , it must be a dict of the form returned by one of
 the astrobase . lcfit . fit _ XXXXX _ magseries functions . This can be used to
 overplot a light curve model fit on top of the phased light curve plot
 returned by this function . The ` overplotfit ` dict has the following
 form , including at least the keys listed here : :
 { ' fittype ' : str : name of fit method ,
 ' fitchisq ' : float : the chi - squared value of the fit ,
 ' fitredchisq ' : float : the reduced chi - squared value of the fit ,
 ' fitinfo ' : { ' fitmags ' : array : model mags or fluxes from fit function } ,
 ' magseries ' : { ' times ' : array : times where the fitmags are evaluated } }
 ` fitmags ` and ` times ` should all be of the same size . The input
 ` overplotfit ` dict is copied over to the checkplotdict for each specific
 phased LC plot to save all of this information for use later .
 verbose : bool
 If True , will indicate progress and warn about problems .
 override _ pfmethod : str or None
 This is used to set a custom label for the periodogram method . Normally ,
 this is taken from the ' method ' key in the input ` lspinfo ` dict , but if
 you want to override the output method name , provide this as a string
 here . This can be useful if you have multiple results you want to
 incorporate into a checkplotdict from a single period - finder ( e . g . if
 you ran BLS over several period ranges separately ) .
 Returns
 dict
 Returns a dict of the following form : :
 { lspmethod : { ' plot ' : the phased LC plot as base64 str ,
 ' period ' : the period used for this phased LC ,
 ' epoch ' : the epoch used for this phased LC ,
 ' phase ' : phase value array ,
 ' phasedmags ' : mags / fluxes sorted in phase order ,
 ' binphase ' : array of binned phase values ,
 ' binphasedmags ' : mags / fluxes sorted in binphase order ,
 ' phasewrap ' : value of the input ` phasewrap ` kwarg ,
 ' phasesort ' : value of the input ` phasesort ` kwarg ,
 ' phasebin ' : value of the input ` phasebin ` kwarg ,
 ' minbinelems ' : value of the input ` minbinelems ` kwarg ,
 ' plotxlim ' : value of the input ` plotxlim ` kwarg ,
 ' lcfit ' : the provided ` overplotfit ` dict } }
 The dict is in this form because we can use Python dicts ' ` update ( ) `
 method to update an existing checkplotdict . If ` returndirect ` is True ,
 only the inner dict is returned .'''

implementation:
# open the figure instance
phasedseriesfig = plt . figure ( figsize = ( 7.5 , 4.8 ) , dpi = plotdpi )
plotvarepoch = None
# figure out the epoch , if it ' s None , use the min of the time
if varepoch is None :
    plotvarepoch = npmin ( stimes )
# if the varepoch is ' min ' , then fit a spline to the light curve
# phased using the min of the time , find the fit mag minimum and use
# the time for that as the varepoch
elif isinstance ( varepoch , str ) and varepoch == 'min' :
    try :
        spfit = spline_fit_magseries ( stimes , smags , serrs , varperiod , magsarefluxes = magsarefluxes , sigclip = None , verbose = verbose )
        plotvarepoch = spfit [ 'fitinfo' ] [ 'fitepoch' ]
        if len ( plotvarepoch ) != 1 :
            plotvarepoch = plotvarepoch [ 0 ]
    except Exception as e :
        LOGERROR ( 'spline fit failed, trying SavGol fit' )
        sgfit = savgol_fit_magseries ( stimes , smags , serrs , varperiod , sigclip = None , magsarefluxes = magsarefluxes , verbose = verbose )
        plotvarepoch = sgfit [ 'fitinfo' ] [ 'fitepoch' ]
        if len ( plotvarepoch ) != 1 :
            plotvarepoch = plotvarepoch [ 0 ]
    finally :
        if plotvarepoch is None :
            LOGERROR ( 'could not find a min epoch time, ' 'using min(times) as the epoch for ' 'the phase-folded LC' )
            plotvarepoch = npmin ( stimes )
# special case with varepoch lists per each period - finder method
elif isinstance ( varepoch , list ) :
    try :
        thisvarepochlist = varepoch [ lspmethodind ]
        plotvarepoch = thisvarepochlist [ periodind ]
    except Exception as e :
        LOGEXCEPTION ( "varepoch provided in list form either doesn't match " "the length of nbestperiods from the period-finder " "result, or something else went wrong. using min(times) " "as the epoch instead" )
        plotvarepoch = npmin ( stimes )
# the final case is to use the provided varepoch directly
else :
    plotvarepoch = varepoch
if verbose :
    LOGINFO ( 'plotting %s phased LC with period %s: %.6f, epoch: %.5f' % ( lspmethod , periodind , varperiod , plotvarepoch ) )
# make the plot title based on the lspmethod
if periodind == 0 :
    plottitle = '%s best period: %.6f d - epoch: %.5f' % ( ( METHODSHORTLABELS [ lspmethod ] if lspmethod in METHODSHORTLABELS else lspmethod ) , varperiod , plotvarepoch )
elif periodind > 0 :
    plottitle = '%s peak %s: %.6f d - epoch: %.5f' % ( ( METHODSHORTLABELS [ lspmethod ] if lspmethod in METHODSHORTLABELS else lspmethod ) , periodind + 1 , varperiod , plotvarepoch )
elif periodind == - 1 :
    plottitle = '%s period: %.6f d - epoch: %.5f' % ( lspmethod , varperiod , plotvarepoch )
# phase the magseries
phasedlc = phase_magseries ( stimes , smags , varperiod , plotvarepoch , wrap = phasewrap , sort = phasesort )
plotphase = phasedlc [ 'phase' ]
plotmags = phasedlc [ 'mags' ]
# if we ' re supposed to bin the phases , do so
if phasebin :
    binphasedlc = phase_bin_magseries ( plotphase , plotmags , binsize = phasebin , minbinelems = minbinelems )
    binplotphase = binphasedlc [ 'binnedphases' ]
    binplotmags = binphasedlc [ 'binnedmags' ]
else :
    binplotphase = None
    binplotmags = None
# finally , make the phased LC plot
plt . plot ( plotphase , plotmags , marker = 'o' , ms = 2.0 , ls = 'None' , mew = 0 , color = 'gray' , rasterized = True )
# overlay the binned phased LC plot if we ' re making one
if phasebin :
    plt . plot ( binplotphase , binplotmags , marker = 'o' , ms = 4.0 , ls = 'None' , mew = 0 , color = '#1c1e57' , rasterized = True )
# if we ' re making a overplotfit , then plot the fit over the other stuff
if overplotfit and isinstance ( overplotfit , dict ) :
    fitmethod = overplotfit [ 'fittype' ]
    fitredchisq = overplotfit [ 'fitredchisq' ]
    plotfitmags = overplotfit [ 'fitinfo' ] [ 'fitmags' ]
    plotfittimes = overplotfit [ 'magseries' ] [ 'times' ]
    # phase the fit magseries
    fitphasedlc = phase_magseries ( plotfittimes , plotfitmags , varperiod , plotvarepoch , wrap = phasewrap , sort = phasesort )
    plotfitphase = fitphasedlc [ 'phase' ]
    plotfitmags = fitphasedlc [ 'mags' ]
    plotfitlabel = ( r'%s fit ${\chi}^2/{\mathrm{dof}} = %.3f$' % ( fitmethod , fitredchisq ) )
    # plot the fit phase and mags
    plt . plot ( plotfitphase , plotfitmags , 'k-' , linewidth = 3 , rasterized = True , label = plotfitlabel )
    plt . legend ( loc = 'upper left' , frameon = False )
# flip y axis for mags
if not magsarefluxes :
    plot_ylim = plt . ylim ( )
    plt . ylim ( ( plot_ylim [ 1 ] , plot_ylim [ 0 ] ) )
# set the x axis limit
if not plotxlim :
    plt . xlim ( ( npmin ( plotphase ) - 0.1 , npmax ( plotphase ) + 0.1 ) )
else :
    plt . xlim ( ( plotxlim [ 0 ] , plotxlim [ 1 ] ) )
# make a grid
ax = plt . gca ( )
if isinstance ( xgridlines , ( list , tuple ) ) :
    ax . set_xticks ( xgridlines , minor = False )
plt . grid ( color = '#a9a9a9' , alpha = 0.9 , zorder = 0 , linewidth = 1.0 , linestyle = ':' )
# make the x and y axis labels
plot_xlabel = 'phase'
if magsarefluxes :
    plot_ylabel = 'flux'
else :
    plot_ylabel = 'magnitude'
plt . xlabel ( plot_xlabel )
plt . ylabel ( plot_ylabel )
# fix the yaxis ticks ( turns off offset and uses the full
# value of the yaxis tick )
plt . gca ( ) . get_yaxis ( ) . get_major_formatter ( ) . set_useOffset ( False )
plt . gca ( ) . get_xaxis ( ) . get_major_formatter ( ) . set_useOffset ( False )
# set the plot title
plt . title ( plottitle )
# make sure the best period phased LC plot stands out
if ( periodind == 0 or periodind == - 1 ) and bestperiodhighlight :
    if MPLVERSION >= ( 2 , 0 , 0 ) :
        plt . gca ( ) . set_facecolor ( bestperiodhighlight )
    else :
        plt . gca ( ) . set_axis_bgcolor ( bestperiodhighlight )
# if we ' re making an inset plot showing the full range
if ( plotxlim and isinstance ( plotxlim , ( list , tuple ) ) and len ( plotxlim ) == 2 and xliminsetmode is True ) : # bump the ylim of the plot so that the inset can fit in this axes plot
    axesylim = plt . gca ( ) . get_ylim ( )
    if magsarefluxes :
        plt . gca ( ) . set_ylim ( axesylim [ 0 ] , axesylim [ 1 ] + 0.5 * npabs ( axesylim [ 1 ] - axesylim [ 0 ] ) )
    else :
        plt . gca ( ) . set_ylim ( axesylim [ 0 ] , axesylim [ 1 ] - 0.5 * npabs ( axesylim [ 1 ] - axesylim [ 0 ] ) )
    # put the inset axes in
    inset = inset_axes ( plt . gca ( ) , width = "40%" , height = "40%" , loc = 1 )
    # make the scatter plot for the phased LC plot
    inset . plot ( plotphase , plotmags , marker = 'o' , ms = 2.0 , ls = 'None' , mew = 0 , color = 'gray' , rasterized = True )
    if phasebin : # make the scatter plot for the phased LC plot
        inset . plot ( binplotphase , binplotmags , marker = 'o' , ms = 4.0 , ls = 'None' , mew = 0 , color = '#1c1e57' , rasterized = True )
    # show the full phase coverage
    if phasewrap :
        inset . set_xlim ( - 0.2 , 0.8 )
    else :
        inset . set_xlim ( - 0.1 , 1.1 )
    # flip y axis for mags
    if not magsarefluxes :
        inset_ylim = inset . get_ylim ( )
        inset . set_ylim ( ( inset_ylim [ 1 ] , inset_ylim [ 0 ] ) )
    # set the plot title
    inset . text ( 0.5 , 0.9 , 'full phased light curve' , ha = 'center' , va = 'center' , transform = inset . transAxes )
    # don ' t show axes labels or ticks
    inset . set_xticks ( [ ] )
    inset . set_yticks ( [ ] )
# this is the output instance
phasedseriespng = StrIO ( )
phasedseriesfig . savefig ( phasedseriespng , # bbox _ inches = ' tight ' ,
pad_inches = 0.0 , format = 'png' )
plt . close ( )
# encode the finderpng instance to base64
phasedseriespng . seek ( 0 )
phasedseriesb64 = base64 . b64encode ( phasedseriespng . read ( ) )
# close the stringio buffer
phasedseriespng . close ( )
# this includes a fitinfo dict if one is provided in overplotfit
retdict = { 'plot' : phasedseriesb64 , 'period' : varperiod , 'epoch' : plotvarepoch , 'phase' : plotphase , 'phasedmags' : plotmags , 'binphase' : binplotphase , 'binphasedmags' : binplotmags , 'phasewrap' : phasewrap , 'phasesort' : phasesort , 'phasebin' : phasebin , 'minbinelems' : minbinelems , 'plotxlim' : plotxlim , 'lcfit' : overplotfit , }
# if we ' re returning stuff directly , i . e . not being used embedded within
# the checkplot _ dict function
if directreturn or checkplotdict is None :
    return retdict
# this requires the checkplotdict to be present already , we ' ll just update
# it at the appropriate lspmethod and periodind
else :
    if override_pfmethod :
        checkplotdict [ override_pfmethod ] [ periodind ] = retdict
    else :
        checkplotdict [ lspmethod ] [ periodind ] = retdict
    return checkplotdict


signature:
def prewhiten_magseries ( times , mags , errs , whitenperiod , whitenparams , sigclip = 3.0 , magsarefluxes = False , plotfit = None , plotfitphasedlconly = True , rescaletomedian = True ) :
    '''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 }'''

implementation:
stimes , smags , serrs = sigclip_magseries ( times , mags , errs , sigclip = sigclip , magsarefluxes = magsarefluxes )
median_mag = np . median ( smags )
# phase the mag series using the given period and epoch = min ( stimes )
mintime = np . min ( stimes )
# calculate the unsorted phase , then sort it
iphase = ( ( stimes - mintime ) / whitenperiod - np . floor ( ( stimes - mintime ) / whitenperiod ) )
phasesortind = np . argsort ( iphase )
# these are the final quantities to use for the Fourier fits
phase = iphase [ phasesortind ]
pmags = smags [ phasesortind ]
perrs = serrs [ phasesortind ]
# get the times sorted in phase order ( useful to get the fit mag minimum
# with respect to phase - - the light curve minimum )
ptimes = stimes [ phasesortind ]
# now subtract the harmonic series from the phased LC
# these are still in phase order
wmags = pmags - _fourier_func ( whitenparams , phase , pmags )
# resort everything by time order
wtimeorder = np . argsort ( ptimes )
wtimes = ptimes [ wtimeorder ]
wphase = phase [ wtimeorder ]
wmags = wmags [ wtimeorder ]
werrs = perrs [ wtimeorder ]
if rescaletomedian :
    wmags = wmags + median_mag
# prepare the returndict
returndict = { 'wtimes' : wtimes , # these are in the new time order
'wphase' : wphase , 'wmags' : wmags , 'werrs' : werrs , 'whitenparams' : whitenparams , 'whitenperiod' : whitenperiod }
# make the fit plot if required
if plotfit and ( isinstance ( plotfit , str ) or isinstance ( plotfit , Strio ) ) :
    if plotfitphasedlconly :
        plt . figure ( figsize = ( 10 , 4.8 ) )
    else :
        plt . figure ( figsize = ( 16 , 9.6 ) )
    if plotfitphasedlconly : # phased series before whitening
        plt . subplot ( 121 )
        plt . plot ( phase , pmags , marker = '.' , color = 'k' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC before pre-whitening' )
        # phased series after whitening
        plt . subplot ( 122 )
        plt . plot ( wphase , wmags , marker = '.' , color = 'g' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC after pre-whitening' )
    else : # time series before whitening
        plt . subplot ( 221 )
        plt . plot ( stimes , smags , marker = '.' , color = 'k' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'JD' )
        plt . title ( 'LC before pre-whitening' )
        # time series after whitening
        plt . subplot ( 222 )
        plt . plot ( wtimes , wmags , marker = '.' , color = 'g' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'JD' )
        plt . title ( 'LC after pre-whitening with period: %.6f' % whitenperiod )
        # phased series before whitening
        plt . subplot ( 223 )
        plt . plot ( phase , pmags , marker = '.' , color = 'k' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC before pre-whitening' )
        # phased series after whitening
        plt . subplot ( 224 )
        plt . plot ( wphase , wmags , marker = '.' , color = 'g' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC after pre-whitening' )
    plt . tight_layout ( )
    plt . savefig ( plotfit , format = 'png' , pad_inches = 0.0 )
    plt . close ( )
    if isinstance ( plotfit , str ) or isinstance ( plotfit , Strio ) :
        returndict [ 'fitplotfile' ] = plotfit
return returndict


signature:
def gls_prewhiten ( times , mags , errs , fourierorder = 3 , # 3rd order series to start with
initfparams = None , startp_gls = None , endp_gls = None , stepsize = 1.0e-4 , autofreq = True , sigclip = 30.0 , magsarefluxes = False , nbestpeaks = 5 , nworkers = 4 , plotfits = None ) :
    '''Iterative pre - whitening of a magnitude series using the L - S periodogram .
 This finds the best period , fits a fourier series with the best period , then
 whitens the time series with the best period , and repeats until ` nbestpeaks `
 are done .
 Parameters
 times , mags , errs : np . array
 The input mag / flux time - series to iteratively pre - whiten .
 fourierorder : int
 The Fourier order of the sinusoidal signal to fit to the time - series and
 iteratively remove .
 initfparams : list or None
 If this is provided , should be a list of Fourier amplitudes and phases
 in the following format : :
 [ 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 ) . You MUST provide ONE of ` fourierorder ` and ` initfparams ` , but
 not both . If both are provided or both are None , a sinusoidal signal of
 Fourier order 3 will be used by default .
 startp _ gls , endp _ gls : float or None
 If these are provided , will serve as input to the Generalized
 Lomb - Scargle function that will attempt to find the best ` nbestpeaks `
 periods in the time - series . These set the minimum and maximum period to
 search for in the time - series .
 stepsize : float
 The step - size in frequency to use when constructing a frequency grid for
 the period search .
 autofreq : bool
 If this is True , the value of ` stepsize ` will be ignored and the
 : py : func : ` astrobase . periodbase . get _ frequency _ grid ` function will be used
 to generate a frequency grid based on ` startp ` , and ` endp ` . If these are
 None as well , ` startp ` will be set to 0.1 and ` endp ` will be set to
 ` times . max ( ) - times . min ( ) ` .
 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 the input measurement values in ` mags ` and ` errs ` are in fluxes , set
 this to True .
 nbestpeaks : int
 The number of ' best ' peaks to return from the periodogram results ,
 starting from the global maximum of the periodogram peak values .
 nworkers : int
 The number of parallel workers to use when calculating the periodogram .
 plotfits : None or str
 If this is a str , should indicate the file to which a plot of the
 successive iterations of pre - whitening will be written to . This will
 contain a row of plots indicating the before / after states of the light
 curves for each round of pre - whitening .
 Returns
 ( bestperiods , plotfile ) : tuple
 This returns a list of the best periods ( with the " highest " peak in the
 periodogram ) after each round of pre - whitening is done . If plotfit is a
 str , will also return the path to the generated plot file .'''

implementation:
stimes , smags , serrs = sigclip_magseries ( times , mags , errs , sigclip = sigclip , magsarefluxes = magsarefluxes )
# now start the cycle by doing an GLS on the initial timeseries
gls = pgen_lsp ( stimes , smags , serrs , magsarefluxes = magsarefluxes , startp = startp_gls , endp = endp_gls , autofreq = autofreq , sigclip = sigclip , stepsize = stepsize , nworkers = nworkers )
LOGINFO ( 'round %s: period = %.6f' % ( 0 , gls [ 'bestperiod' ] ) )
if plotfits and isinstance ( plotfits , str ) :
    plt . figure ( figsize = ( 20 , 6 * nbestpeaks ) )
    nplots = nbestpeaks + 1
    # periodogram
    plt . subplot ( nplots , 3 , 1 )
    plt . plot ( gls [ 'periods' ] , gls [ 'lspvals' ] )
    plt . xlabel ( 'period [days]' )
    plt . ylabel ( 'GLS power' )
    plt . xscale ( 'log' )
    plt . title ( 'round 0, best period = %.6f' % gls [ 'bestperiod' ] )
    # unphased LC
    plt . subplot ( nplots , 3 , 2 )
    plt . plot ( stimes , smags , linestyle = 'none' , marker = 'o' , ms = 1.0 , rasterized = True )
    if not magsarefluxes :
        plt . gca ( ) . invert_yaxis ( )
        plt . ylabel ( 'magnitude' )
    else :
        plt . ylabel ( 'flux' )
    plt . xlabel ( 'JD' )
    plt . title ( 'unphased LC before whitening' )
    # phased LC
    plt . subplot ( nplots , 3 , 3 )
    phased = phase_magseries ( stimes , smags , gls [ 'bestperiod' ] , stimes . min ( ) )
    plt . plot ( phased [ 'phase' ] , phased [ 'mags' ] , linestyle = 'none' , marker = 'o' , ms = 1.0 , rasterized = True )
    if not magsarefluxes :
        plt . ylabel ( 'magnitude' )
        plt . gca ( ) . invert_yaxis ( )
    else :
        plt . ylabel ( 'flux' )
    plt . xlabel ( 'phase' )
    plt . title ( 'phased LC before whitening: P = %.6f' % gls [ 'bestperiod' ] )
# set up the initial times , mags , errs , period
wtimes , wmags , werrs = stimes , smags , serrs
wperiod = gls [ 'bestperiod' ]
# start the best periods list
bestperiods = [ ]
# now go through the rest of the cycles
for fitind in range ( nbestpeaks ) :
    wfseries = fourier_fit_magseries ( wtimes , wmags , werrs , wperiod , fourierorder = fourierorder , fourierparams = initfparams , magsarefluxes = magsarefluxes , sigclip = sigclip )
    wffitparams = wfseries [ 'fitinfo' ] [ 'finalparams' ]
    wseries = prewhiten_magseries ( wtimes , wmags , werrs , wperiod , wffitparams , magsarefluxes = magsarefluxes , sigclip = sigclip )
    LOGINFO ( 'round %s: period = %.6f' % ( fitind + 1 , wperiod ) )
    bestperiods . append ( wperiod )
    # update the mag series with whitened version
    wtimes , wmags , werrs = ( wseries [ 'wtimes' ] , wseries [ 'wmags' ] , wseries [ 'werrs' ] )
    # redo the periodogram
    wgls = pgen_lsp ( wtimes , wmags , werrs , magsarefluxes = magsarefluxes , startp = startp_gls , endp = endp_gls , autofreq = autofreq , sigclip = sigclip , stepsize = stepsize , nworkers = nworkers )
    wperiod = wgls [ 'bestperiod' ]
    bestperiods . append ( wperiod )
    # make plots if requested
    if plotfits and isinstance ( plotfits , str ) : # periodogram
        plt . subplot ( nplots , 3 , 4 + fitind * 3 )
        plt . plot ( wgls [ 'periods' ] , wgls [ 'lspvals' ] )
        plt . xlabel ( 'period [days]' )
        plt . ylabel ( 'LSP power' )
        plt . xscale ( 'log' )
        plt . title ( 'round %s, best period = %.6f' % ( fitind + 1 , wgls [ 'bestperiod' ] ) )
        # unphased LC
        plt . subplot ( nplots , 3 , 5 + fitind * 3 )
        plt . plot ( wtimes , wmags , linestyle = 'none' , marker = 'o' , ms = 1.0 , rasterized = True )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'flux' )
        plt . xlabel ( 'JD' )
        plt . title ( 'unphased LC after whitening' )
        # phased LC
        plt . subplot ( nplots , 3 , 6 + fitind * 3 )
        wphased = phase_magseries ( wtimes , wmags , wperiod , stimes . min ( ) )
        plt . plot ( wphased [ 'phase' ] , wphased [ 'mags' ] , linestyle = 'none' , marker = 'o' , ms = 1.0 , rasterized = True )
        if not magsarefluxes :
            plt . ylabel ( 'magnitude' )
            plt . gca ( ) . invert_yaxis ( )
        else :
            plt . ylabel ( 'flux' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC after whitening: P = %.6f' % wperiod )
# in the end , write out the plot
if plotfits and isinstance ( plotfits , str ) :
    plt . subplots_adjust ( hspace = 0.2 , wspace = 0.4 )
    plt . savefig ( plotfits , bbox_inches = 'tight' )
    plt . close ( 'all' )
    return bestperiods , os . path . abspath ( plotfits )
else :
    return bestperiods


signature:
def mask_signal ( times , mags , errs , signalperiod , signalepoch , magsarefluxes = False , maskphases = ( 0 , 0 , 0.5 , 1.0 ) , maskphaselength = 0.1 , plotfit = None , plotfitphasedlconly = True , sigclip = 30.0 ) :
    '''This removes repeating signals in the magnitude time series .
 Useful for masking planetary transit signals in light curves to search for
 other variability .
 A small worked example of using this and ` prewhiten _ magseries ` above :
 https : / / github . com / waqasbhatti / astrobase / issues / 77 # issuecomment - 463803558
 Parameters
 times , mags , errs : np . array
 The input mag / flux time - series to run the masking on .
 signalperiod : float
 The period of the signal to mask .
 signalepoch : float
 The epoch of the signal to mask .
 magsarefluxes : bool
 Set to True if ` mags ` is actually an array of fluxes .
 maskphases : sequence of floats
 This defines which phase values will be masked . For each item in this
 sequence , this function will mask a length of phase given by
 ` maskphaselength ` centered on each ` maskphases ` value , and remove all LC
 points in these regions from the light curve .
 maskphaselength : float
 The length in phase to mask for each phase value provided in
 ` maskphases ` .
 plotfit : str or None
 If provided as a str , indicates the output plot file .
 plotfitphasedlconly : bool
 If True , will only plot the effect of masking the signal as requested on
 the phased LC . If False , will also plot the unphased LC .
 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 .'''

implementation:
stimes , smags , serrs = sigclip_magseries ( times , mags , errs , sigclip = sigclip , magsarefluxes = magsarefluxes )
# now phase the light curve using the period and epoch provided
phases = ( ( stimes - signalepoch ) / signalperiod - np . floor ( ( stimes - signalepoch ) / signalperiod ) )
# mask the requested phases using the mask length ( in phase units )
# this gets all the masks into one array
masks = np . array ( [ ( np . abs ( phases - x ) > maskphaselength ) for x in maskphases ] )
# this flattens the masks to a single array for all combinations
masks = np . all ( masks , axis = 0 )
# apply the mask to the times , mags , and errs
mphases = phases [ masks ]
mtimes = stimes [ masks ]
mmags = smags [ masks ]
merrs = serrs [ masks ]
returndict = { 'mphases' : mphases , 'mtimes' : mtimes , 'mmags' : mmags , 'merrs' : merrs }
# make the fit plot if required
if plotfit and isinstance ( plotfit , str ) or isinstance ( plotfit , Strio ) :
    if plotfitphasedlconly :
        plt . figure ( figsize = ( 10 , 4.8 ) )
    else :
        plt . figure ( figsize = ( 16 , 9.6 ) )
    if plotfitphasedlconly : # phased series before whitening
        plt . subplot ( 121 )
        plt . plot ( phases , smags , marker = '.' , color = 'k' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC before signal masking' )
        # phased series after whitening
        plt . subplot ( 122 )
        plt . plot ( mphases , mmags , marker = '.' , color = 'g' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC after signal masking' )
    else : # time series before whitening
        plt . subplot ( 221 )
        plt . plot ( stimes , smags , marker = '.' , color = 'k' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'JD' )
        plt . title ( 'LC before signal masking' )
        # time series after whitening
        plt . subplot ( 222 )
        plt . plot ( mtimes , mmags , marker = '.' , color = 'g' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'JD' )
        plt . title ( 'LC after signal masking' )
        # phased series before whitening
        plt . subplot ( 223 )
        plt . plot ( phases , smags , marker = '.' , color = 'k' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC before signal masking' )
        # phased series after whitening
        plt . subplot ( 224 )
        plt . plot ( mphases , mmags , marker = '.' , color = 'g' , linestyle = 'None' , markersize = 2.0 , markeredgewidth = 0 )
        if not magsarefluxes :
            plt . gca ( ) . invert_yaxis ( )
            plt . ylabel ( 'magnitude' )
        else :
            plt . ylabel ( 'fluxes' )
        plt . xlabel ( 'phase' )
        plt . title ( 'phased LC after signal masking' )
    plt . tight_layout ( )
    plt . savefig ( plotfit , format = 'png' , pad_inches = 0.0 )
    plt . close ( )
    if isinstance ( plotfit , str ) or isinstance ( plotfit , Strio ) :
        returndict [ 'fitplotfile' ] = plotfit
return returndict


signature:
def main ( ) :
    '''This launches the server . The current script args are shown below : :
 Usage : checkplotserver [ OPTIONS ]
 Options :
 - - help show this help information
 checkplotserver . py options :
 - - assetpath Sets the asset ( server images , css , js , DB )
 path for checkplotserver .
 ( default < astrobase install dir >
 / astrobase / cpserver / cps - assets )
 - - baseurl Set the base URL of the checkplotserver .
 This is useful when you ' re running
 checkplotserver on a remote machine and are
 reverse - proxying more than one instances of
 it so you can access them using HTTP from
 outside on different base URLs like
 / cpserver1 / , / cpserver2 / , etc . If this is
 set , all URLs will take the form
 [ baseurl ] / . . . , instead of / . . . ( default / )
 - - checkplotlist The path to the checkplot - filelist . json file
 listing checkplots to load and serve . If
 this is not provided , checkplotserver will
 look for a checkplot - pickle - flist . json in
 the directory that it was started in
 - - debugmode start up in debug mode if set to 1 . ( default
 - - maxprocs Number of background processes to use for
 saving / loading checkplot files and running
 light curves tools ( default 2)
 - - port Run on the given port . ( default 5225)
 - - readonly Run the server in readonly mode . This is
 useful for a public - facing instance of
 checkplotserver where you just want to allow
 collaborators to review objects but not edit
 them . ( default False )
 - - serve Bind to given address and serve content .
 ( default 127.0.0.1)
 - - sharedsecret a file containing a cryptographically secure
 string that is used to authenticate requests
 that come into the special standalone mode .
 - - standalone This starts the server in standalone mode .
 ( default 0)
 tornado / log . py options :
 - - log - file - max - size max size of log files before rollover
 ( default 100000)
 - - log - file - num - backups number of log files to keep ( default 10)
 - - log - file - prefix = PATH Path prefix for log files . Note that if you
 are running multiple tornado processes ,
 log _ file _ prefix must be different for each
 of them ( e . g . include the port number )
 - - log - rotate - interval The interval value of timed rotating
 ( default 1)
 - - log - rotate - mode The mode of rotating files ( time or size )
 ( default size )
 - - log - rotate - when specify the type of TimedRotatingFileHandler
 interval other options : ( ' S ' , ' M ' , ' H ' , ' D ' ,
 ' W0 ' - ' W6 ' ) ( default midnight )
 - - log - to - stderr Send log output to stderr ( colorized if
 possible ) . By default use stderr if
 - - log _ file _ prefix is not set and no other
 logging is configured .
 - - logging = debug | info | warning | error | none
 Set the Python log level . If ' none ' , tornado
 won ' t touch the logging configuration .
 ( default info )'''

implementation:
# parse the command line
tornado . options . parse_command_line ( )
DEBUG = True if options . debugmode == 1 else False
# get a logger
LOGGER = logging . getLogger ( 'checkplotserver' )
if DEBUG :
    LOGGER . setLevel ( logging . DEBUG )
else :
    LOGGER . setLevel ( logging . INFO )
# # SET UP CONFIG # #
MAXPROCS = options . maxprocs
ASSETPATH = options . assetpath
BASEURL = options . baseurl
# # PERSISTENT CHECKPLOT EXECUTOR # #
EXECUTOR = ProcessPoolExecutor ( MAXPROCS )
# # CHECK IF WE ' RE IN STANDALONE MODE # #
if options . standalone :
    if ( ( not options . sharedsecret ) or ( options . sharedsecret and not os . path . exists ( options . sharedsecret ) ) ) :
        LOGGER . error ( 'Could not find a shared secret file to use in \n' 'standalone mode. Generate one using: \n\n' 'python3 -c "import secrets; ' 'print(secrets.token_urlsafe(32))" ' '> secret-key-file.txt\n\nSet user-only ro ' 'permissions on the generated file (chmod 400)' )
        sys . exit ( 1 )
    elif options . sharedsecret and os . path . exists ( options . sharedsecret ) : # check if this file is readable / writeable by user only
        fileperm = oct ( os . stat ( options . sharedsecret ) [ stat . ST_MODE ] )
        if fileperm == '0100400' or fileperm == '0o100400' :
            with open ( options . sharedsecret , 'r' ) as infd :
                SHAREDSECRET = infd . read ( ) . strip ( '\n' )
                # this is the URLSpec for the standalone Handler
                standalonespec = ( r'/standalone' , cphandlers . StandaloneHandler , { 'executor' : EXECUTOR , 'secret' : SHAREDSECRET } )
        else :
            LOGGER . error ( 'permissions on the shared secret file ' 'should be 0100400' )
            sys . exit ( 1 )
    else :
        LOGGER . error ( 'could not find the specified ' 'shared secret file: %s' % options . sharedsecret )
        sys . exit ( 1 )
    # only one handler in standalone mode
    HANDLERS = [ standalonespec ]
# if we ' re not in standalone mode , proceed normally
else :
    if not BASEURL . endswith ( '/' ) :
        BASEURL = BASEURL + '/'
    READONLY = options . readonly
    if READONLY :
        LOGGER . warning ( 'checkplotserver running in readonly mode.' )
    # this is the directory checkplotserver . py was executed from . used to
    # figure out checkplot locations
    CURRENTDIR = os . getcwd ( )
    # if a checkplotlist is provided , then load it . NOTE : all paths in this
    # file are relative to the path of the checkplotlist file itself .
    cplistfile = options . checkplotlist
    # if the provided cplistfile is OK
    if cplistfile and os . path . exists ( cplistfile ) :
        with open ( cplistfile , 'r' ) as infd :
            CHECKPLOTLIST = json . load ( infd )
        LOGGER . info ( 'using provided checkplot list file: %s' % cplistfile )
    # if a cplist is provided , but doesn ' t exist
    elif cplistfile and not os . path . exists ( cplistfile ) :
        helpmsg = ( "Couldn't find the file %s\n" "NOTE: To make a checkplot list file, " "try running the following command:\n" "python %s pkl " "/path/to/folder/where/the/checkplot.pkl.gz/files/are" % ( cplistfile , os . path . join ( modpath , 'checkplotlist.py' ) ) )
        LOGGER . error ( helpmsg )
        sys . exit ( 1 )
    # finally , if no cplistfile is provided at all , search for a
    # checkplot - filelist . json in the current directory
    else :
        LOGGER . warning ( 'No checkplot list file provided!\n' '(use --checkplotlist=... for this, ' 'or use --help to see all options)\n' 'looking for checkplot-filelist.json in the ' 'current directory %s ...' % CURRENTDIR )
        # this is for single checkplot lists
        if os . path . exists ( os . path . join ( CURRENTDIR , 'checkplot-filelist.json' ) ) :
            cplistfile = os . path . join ( CURRENTDIR , 'checkplot-filelist.json' )
            with open ( cplistfile , 'r' ) as infd :
                CHECKPLOTLIST = json . load ( infd )
            LOGGER . info ( 'using checkplot list file: %s' % cplistfile )
        # this is for chunked checkplot lists
        elif os . path . exists ( os . path . join ( CURRENTDIR , 'checkplot-filelist-00.json' ) ) :
            cplistfile = os . path . join ( CURRENTDIR , 'checkplot-filelist-00.json' )
            with open ( cplistfile , 'r' ) as infd :
                CHECKPLOTLIST = json . load ( infd )
            LOGGER . info ( 'using checkplot list file: %s' % cplistfile )
        # if we can ' t find a checkplot list , bail out
        else :
            helpmsg = ( "No checkplot file list JSON found, " "can't continue without one.\n" "Did you make a checkplot list file? " "To make one, try running the following command:\n" "checkplotlist pkl " "/path/to/folder/where/the/checkplot.pkl.gz/files/are" )
            LOGGER . error ( helpmsg )
            sys . exit ( 1 )
    # # URL HANDLERS FOR NORMAL MODE # #
    HANDLERS = [ # index page
    ( r'{baseurl}' . format ( baseurl = BASEURL ) , cphandlers . IndexHandler , { 'currentdir' : CURRENTDIR , 'assetpath' : ASSETPATH , 'cplist' : CHECKPLOTLIST , 'cplistfile' : cplistfile , 'executor' : EXECUTOR , 'readonly' : READONLY , 'baseurl' : BASEURL } ) , # loads and interacts with checkplot pickles
    ( r'{baseurl}cp/?(.*)' . format ( baseurl = BASEURL ) , cphandlers . CheckplotHandler , { 'currentdir' : CURRENTDIR , 'assetpath' : ASSETPATH , 'cplist' : CHECKPLOTLIST , 'cplistfile' : cplistfile , 'executor' : EXECUTOR , 'readonly' : READONLY } ) , # loads and interacts with the current checkplot list JSON file
    ( r'{baseurl}list' . format ( baseurl = BASEURL ) , cphandlers . CheckplotListHandler , { 'currentdir' : CURRENTDIR , 'assetpath' : ASSETPATH , 'cplist' : CHECKPLOTLIST , 'cplistfile' : cplistfile , 'executor' : EXECUTOR , 'readonly' : READONLY } ) , # light curve variability and period - finding tool endpoints
    ( r'{baseurl}tools/?(.*)' . format ( baseurl = BASEURL ) , cphandlers . LCToolHandler , { 'currentdir' : CURRENTDIR , 'assetpath' : ASSETPATH , 'cplist' : CHECKPLOTLIST , 'cplistfile' : cplistfile , 'executor' : EXECUTOR , 'readonly' : READONLY } ) , # download any file in the current base directory , mostly used for
    # downloading checkplot pickles and updated checkplot list JSONs
    ( r'{baseurl}download/(.*)' . format ( baseurl = BASEURL ) , tornado . web . StaticFileHandler , { 'path' : CURRENTDIR } ) ]
# # APPLICATION SETUP # #
app = tornado . web . Application ( handlers = HANDLERS , static_path = ASSETPATH , template_path = ASSETPATH , static_url_prefix = '{baseurl}static/' . format ( baseurl = BASEURL ) , compress_response = True , debug = DEBUG , )
# start up the HTTP server and our application . xheaders = True turns on
# X - Forwarded - For support so we can see the remote IP in the logs
http_server = tornado . httpserver . HTTPServer ( app , xheaders = True )
# # start the server # #
# make sure the port we ' re going to listen on is ok
# inspired by how Jupyter notebook does this
portok = False
serverport = options . port
maxtrys = 5
thistry = 0
while not portok and thistry < maxtrys :
    try :
        http_server . listen ( serverport , options . serve )
        portok = True
    except socket . error as e :
        LOGGER . warning ( '%s:%s is already in use, trying port %s' % ( options . serve , serverport , serverport + 1 ) )
        serverport = serverport + 1
if not portok :
    LOGGER . error ( 'could not find a free port after 5 tries, giving up' )
    sys . exit ( 1 )
LOGGER . info ( 'started checkplotserver. listening on http://%s:%s%s' % ( options . serve , serverport , BASEURL ) )
# register the signal callbacks
signal . signal ( signal . SIGINT , _recv_sigint )
signal . signal ( signal . SIGTERM , _recv_sigint )
# start the IOLoop and begin serving requests
try :
    tornado . ioloop . IOLoop . instance ( ) . start ( )
except KeyboardInterrupt :
    LOGGER . info ( 'received Ctrl-C: shutting down...' )
    tornado . ioloop . IOLoop . instance ( ) . stop ( )
    # close down the processpool
EXECUTOR . shutdown ( )
time . sleep ( 3 )


signature:
def find_lc_timegroups ( lctimes , mingap = 4.0 ) :
    '''Finds gaps in the provided time - series and indexes them into groups .
 This finds the gaps in the provided ` lctimes ` array , so we can figure out
 which times are for consecutive observations and which represent gaps
 between seasons or observing eras .
 Parameters
 lctimes : array - like
 This contains the times to analyze for gaps ; assumed to be some form of
 Julian date .
 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 .
 Returns
 tuple
 A tuple of the form : ` ( ngroups , [ slice ( start _ ind _ 1 , end _ ind _ 1 ) , . . . ] ) `
 is returned . This contains the number of groups as the first element ,
 and a list of Python ` slice ` objects for each time - group found . These
 can be used directly to index into the array of times to quickly get
 measurements associated with each group .'''

implementation:
lc_time_diffs = np . diff ( lctimes )
group_start_indices = np . where ( lc_time_diffs > mingap ) [ 0 ]
if len ( group_start_indices ) > 0 :
    group_indices = [ ]
    for i , gindex in enumerate ( group_start_indices ) :
        if i == 0 :
            group_indices . append ( slice ( 0 , gindex + 1 ) )
        else :
            group_indices . append ( slice ( group_start_indices [ i - 1 ] + 1 , gindex + 1 ) )
    # at the end , add the slice for the last group to the end of the times
    # array
    group_indices . append ( slice ( group_start_indices [ - 1 ] + 1 , len ( lctimes ) ) )
# if there ' s no large gap in the LC , then there ' s only one group to worry
# about
else :
    group_indices = [ slice ( 0 , len ( lctimes ) ) ]
return len ( group_indices ) , group_indices


signature:
def normalize_magseries ( times , mags , mingap = 4.0 , normto = 'globalmedian' , magsarefluxes = False , debugmode = False ) :
    '''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 .'''

implementation:
ngroups , timegroups = find_lc_timegroups ( times , mingap = mingap )
# find all the non - nan indices
finite_ind = np . isfinite ( mags )
if any ( finite_ind ) : # find the global median
    global_mag_median = np . median ( mags [ finite_ind ] )
    # go through the groups and normalize them to the median for
    # each group
    for tgind , tg in enumerate ( timegroups ) :
        finite_ind = np . isfinite ( mags [ tg ] )
        # find this timegroup ' s median mag and normalize the mags in
        # it to this median
        group_median = np . median ( ( mags [ tg ] ) [ finite_ind ] )
        if magsarefluxes :
            mags [ tg ] = mags [ tg ] / group_median
        else :
            mags [ tg ] = mags [ tg ] - group_median
        if debugmode :
            LOGDEBUG ( 'group %s: elems %s, ' 'finite elems %s, median mag %s' % ( tgind , len ( mags [ tg ] ) , len ( finite_ind ) , group_median ) )
    # now that everything is normalized to 0.0 , add the global median
    # offset back to all the mags and write the result back to the dict
    if isinstance ( normto , str ) and normto == 'globalmedian' :
        if magsarefluxes :
            mags = mags * global_mag_median
        else :
            mags = mags + global_mag_median
    # if the normto is a float , add everything to that float and return
    elif isinstance ( normto , float ) :
        if magsarefluxes :
            mags = mags * normto
        else :
            mags = mags + normto
    # anything else just returns the normalized mags as usual
    return times , mags
else :
    LOGERROR ( 'measurements are all nan!' )
    return None , None