signature:
def clustdealer ( pairdealer , optim ) :
    """return optim clusters given iterators , and whether it got all or not"""

implementation:
ccnt = 0
chunk = [ ]
while ccnt < optim : # # try refreshing taker , else quit
    try :
        taker = itertools . takewhile ( lambda x : x [ 0 ] != "//\n" , pairdealer )
        oneclust = [ "" . join ( taker . next ( ) ) ]
    except StopIteration : # LOGGER . debug ( ' last chunk % s ' , chunk )
        return 1 , chunk
    # # load one cluster
    while 1 :
        try :
            oneclust . append ( "" . join ( taker . next ( ) ) )
        except StopIteration :
            break
    chunk . append ( "" . join ( oneclust ) )
    ccnt += 1
return 0 , chunk


signature:
def progressbar ( njobs , finished , msg = "" , spacer = "  " ) :
    """prints a progress bar"""

implementation:
if njobs :
    progress = 100 * ( finished / float ( njobs ) )
else :
    progress = 100
hashes = '#' * int ( progress / 5. )
nohash = ' ' * int ( 20 - len ( hashes ) )
if not ipyrad . __interactive__ :
    msg = msg . rsplit ( "|" , 2 ) [ 0 ]
args = [ spacer , hashes + nohash , int ( progress ) , msg ]
print ( "\r{}[{}] {:>3}% {} " . format ( * args ) , end = "" )
sys . stdout . flush ( )


signature:
def get_threaded_view ( ipyclient , split = True ) :
    """gets optimum threaded view of ids given the host setup"""

implementation:
# # engine ids
# # e . g . , [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8]
eids = ipyclient . ids
# # get host names
# # e . g . , [ ' a ' , ' a ' , ' b ' , ' b ' , ' a ' , ' c ' , ' c ' , ' c ' , ' c ' ]
dview = ipyclient . direct_view ( )
hosts = dview . apply_sync ( socket . gethostname )
# # group ids into a dict by their hostnames
# # e . g . , { a : [ 0 , 1 , 4 ] , b : [ 2 , 3 ] , c : [ 5 , 6 , 7 , 8 ] }
hostdict = defaultdict ( list )
for host , eid in zip ( hosts , eids ) :
    hostdict [ host ] . append ( eid )
# # Now split threads on the same host into separate proc if there are many
hostdictkeys = hostdict . keys ( )
for key in hostdictkeys :
    gids = hostdict [ key ]
    maxt = len ( gids )
    if len ( gids ) >= 4 :
        maxt = 2
    # # if 4 nodes and 4 ppn , put one sample per host
    if ( len ( gids ) == 4 ) and ( len ( hosts ) >= 4 ) :
        maxt = 4
    if len ( gids ) >= 6 :
        maxt = 3
    if len ( gids ) >= 8 :
        maxt = 4
    if len ( gids ) >= 16 :
        maxt = 4
    # # split ids into groups of maxt
    threaded = [ gids [ i : i + maxt ] for i in xrange ( 0 , len ( gids ) , maxt ) ]
    lth = len ( threaded )
    # # if anything was split ( lth > 1 ) update hostdict with new proc
    if lth > 1 :
        hostdict . pop ( key )
        for hostid in range ( lth ) :
            hostdict [ str ( key ) + "_" + str ( hostid ) ] = threaded [ hostid ]
# # make sure split numbering is correct
# threaded = hostdict . values ( )
# assert len ( ipyclient . ids ) < = len ( list ( itertools . chain ( * threaded ) ) )
LOGGER . info ( "threaded_view: %s" , dict ( hostdict ) )
return hostdict


signature:
def detect_cpus ( ) :
    """Detects the number of CPUs on a system . This is better than asking
 ipyparallel since ipp has to wait for Engines to spin up ."""

implementation:
# Linux , Unix and MacOS :
if hasattr ( os , "sysconf" ) :
    if os . sysconf_names . has_key ( "SC_NPROCESSORS_ONLN" ) : # Linux & Unix :
        ncpus = os . sysconf ( "SC_NPROCESSORS_ONLN" )
        if isinstance ( ncpus , int ) and ncpus > 0 :
            return ncpus
    else : # OSX :
        return int ( os . popen2 ( "sysctl -n hw.ncpu" ) [ 1 ] . read ( ) )
# Windows :
if os . environ . has_key ( "NUMBER_OF_PROCESSORS" ) :
    ncpus = int ( os . environ [ "NUMBER_OF_PROCESSORS" ] )
    if ncpus > 0 :
        return ncpus
return 1


signature:
def _call_structure ( mname , ename , sname , name , workdir , seed , ntaxa , nsites , kpop , rep ) :
    """make the subprocess call to structure"""

implementation:
# # create call string
outname = os . path . join ( workdir , "{}-K-{}-rep-{}" . format ( name , kpop , rep ) )
cmd = [ "structure" , "-m" , mname , "-e" , ename , "-K" , str ( kpop ) , "-D" , str ( seed ) , "-N" , str ( ntaxa ) , "-L" , str ( nsites ) , "-i" , sname , "-o" , outname ]
# # call the shell function
proc = subprocess . Popen ( cmd , stdout = subprocess . PIPE , stderr = subprocess . STDOUT )
comm = proc . communicate ( )
# # cleanup
oldfiles = [ mname , ename , sname ]
for oldfile in oldfiles :
    if os . path . exists ( oldfile ) :
        os . remove ( oldfile )
return comm


signature:
def _get_clumpp_table ( self , kpop , max_var_multiple , quiet ) :
    """private function to clumpp results"""

implementation:
# # concat results for k = x
reps , excluded = _concat_reps ( self , kpop , max_var_multiple , quiet )
if reps :
    ninds = reps [ 0 ] . inds
    nreps = len ( reps )
else :
    ninds = nreps = 0
if not reps :
    return "no result files found"
clumphandle = os . path . join ( self . workdir , "tmp.clumppparams.txt" )
self . clumppparams . kpop = kpop
self . clumppparams . c = ninds
self . clumppparams . r = nreps
with open ( clumphandle , 'w' ) as tmp_c :
    tmp_c . write ( self . clumppparams . _asfile ( ) )
# # create CLUMPP args string
outfile = os . path . join ( self . workdir , "{}-K-{}.outfile" . format ( self . name , kpop ) )
indfile = os . path . join ( self . workdir , "{}-K-{}.indfile" . format ( self . name , kpop ) )
miscfile = os . path . join ( self . workdir , "{}-K-{}.miscfile" . format ( self . name , kpop ) )
cmd = [ "CLUMPP" , clumphandle , "-i" , indfile , "-o" , outfile , "-j" , miscfile , "-r" , str ( nreps ) , "-c" , str ( ninds ) , "-k" , str ( kpop ) ]
# # call clumpp
proc = subprocess . Popen ( cmd , stderr = subprocess . STDOUT , stdout = subprocess . PIPE )
_ = proc . communicate ( )
# # cleanup
for rfile in [ indfile , miscfile ] :
    if os . path . exists ( rfile ) :
        os . remove ( rfile )
# # parse clumpp results file
ofile = os . path . join ( self . workdir , "{}-K-{}.outfile" . format ( self . name , kpop ) )
if os . path . exists ( ofile ) :
    csvtable = pd . read_csv ( ofile , delim_whitespace = True , header = None )
    table = csvtable . loc [ : , 5 : ]
    # # apply names to cols and rows
    table . columns = range ( table . shape [ 1 ] )
    table . index = self . labels
    if not quiet :
        sys . stderr . write ( "[K{}] {}/{} results permuted across replicates (max_var={}).\n" . format ( kpop , nreps , nreps + excluded , max_var_multiple ) )
    return table
else :
    sys . stderr . write ( "No files ready for {}-K-{} in {}\n" . format ( self . name , kpop , self . workdir ) )
    return


signature:
def _concat_reps ( self , kpop , max_var_multiple , quiet , ** kwargs ) :
    """Combine structure replicates into a single indfile ,
 returns nreps , ninds . Excludes reps with too high of
 variance ( set with max _ variance _ multiplier ) to exclude
 runs that did not converge ."""

implementation:
# # make an output handle
outf = os . path . join ( self . workdir , "{}-K-{}.indfile" . format ( self . name , kpop ) )
# # combine replicates and write to indfile
excluded = 0
reps = [ ]
with open ( outf , 'w' ) as outfile :
    repfiles = glob . glob ( os . path . join ( self . workdir , self . name + "-K-{}-rep-*_f" . format ( kpop ) ) )
    # # get result as a Rep object
    for rep in repfiles :
        result = Rep ( rep , kpop = kpop )
        reps . append ( result )
    # # exclude results with variance NX above ( min )
    newreps = [ ]
    if len ( reps ) > 1 :
        min_var_across_reps = np . min ( [ i . var_lnlik for i in reps ] )
    else :
        min_var_across_reps = reps [ 0 ] . var_lnlik
    # # iterate over reps
    for rep in reps : # # store result w / o filtering
        if not max_var_multiple :
            newreps . append ( rep )
            outfile . write ( rep . stable )
        # # use max - var - multiple as a filter for convergence
        else : # print (
        # rep . var _ lnlik ,
        # min _ var _ across _ reps ,
        # rep . var _ lnlik / min _ var _ across _ reps ,
        # max _ var _ multiple )
        # # e . g . , repvar is 1.05X minvar . We keep it if maxvar < = 1.05
            if ( rep . var_lnlik / min_var_across_reps ) <= max_var_multiple :
                newreps . append ( rep )
                outfile . write ( rep . stable )
            else :
                excluded += 1
return newreps , excluded


signature:
def _get_evanno_table ( self , kpops , max_var_multiple , quiet ) :
    """Calculates Evanno method K value scores for a series
 of permuted clumpp results ."""

implementation:
# # iterate across k - vals
kpops = sorted ( kpops )
replnliks = [ ]
for kpop in kpops : # # concat results for k = x
    reps , excluded = _concat_reps ( self , kpop , max_var_multiple , quiet )
    # # report if some results were excluded
    if excluded :
        if not quiet :
            sys . stderr . write ( "[K{}] {} reps excluded (not converged) see 'max_var_multiple'.\n" . format ( kpop , excluded ) )
    if reps :
        ninds = reps [ 0 ] . inds
        nreps = len ( reps )
    else :
        ninds = nreps = 0
    if not reps :
        print "no result files found"
    # # all we really need is the lnlik
    replnliks . append ( [ i . est_lnlik for i in reps ] )
# # compare lnlik and var of results
if len ( replnliks ) > 1 :
    lnmean = [ np . mean ( i ) for i in replnliks ]
    lnstds = [ np . std ( i , ddof = 1 ) for i in replnliks ]
else :
    lnmean = replnliks
    lnstds = np . nan
tab = pd . DataFrame ( index = kpops , data = { "Nreps" : [ len ( i ) for i in replnliks ] , "lnPK" : [ 0 ] * len ( kpops ) , "lnPPK" : [ 0 ] * len ( kpops ) , "deltaK" : [ 0 ] * len ( kpops ) , "estLnProbMean" : lnmean , "estLnProbStdev" : lnstds , } )
# # calculate Evanno ' s
for kpop in kpops [ 1 : ] :
    tab . loc [ kpop , "lnPK" ] = tab . loc [ kpop , "estLnProbMean" ] - tab . loc [ kpop - 1 , "estLnProbMean" ]
for kpop in kpops [ 1 : - 1 ] :
    tab . loc [ kpop , "lnPPK" ] = abs ( tab . loc [ kpop + 1 , "lnPK" ] - tab . loc [ kpop , "lnPK" ] )
    tab . loc [ kpop , "deltaK" ] = ( abs ( tab . loc [ kpop + 1 , "estLnProbMean" ] - 2.0 * tab . loc [ kpop , "estLnProbMean" ] + tab . loc [ kpop - 1 , "estLnProbMean" ] ) / tab . loc [ kpop , "estLnProbStdev" ] )
# # return table
return tab


signature:
def result_files ( self ) :
    """returns a list of files that have finished structure"""

implementation:
reps = OPJ ( self . workdir , self . name + "-K-*-rep-*_f" )
repfiles = glob . glob ( reps )
return repfiles


signature:
def run ( self , kpop , nreps , ipyclient = None , seed = 12345 , force = False , quiet = False , ) :
    """submits a job to run on the cluster and returns an asynchronous result
 object . K is the number of populations , randomseed if not set will be
 randomly drawn , ipyclient if not entered will raise an error . If nreps
 is set then multiple jobs will be started from new seeds , each labeled
 by its replicate number . If force = True then replicates will be overwritten ,
 otherwise , new replicates will be created starting with the last file N
 found in the workdir .
 Parameters :
 kpop : ( int )
 The MAXPOPS parameter in structure , i . e . , the number of populations
 assumed by the model ( K ) .
 nreps : ( int ) :
 Number of independent runs starting from distinct seeds .
 ipyclient : ( ipyparallel . Client Object )
 An ipyparallel client connected to an ipcluster instance . This is
 used to manage parallel jobs . If not present a single job will
 run and block until finished ( i . e . , code is not parallel ) .
 seed : ( int ) :
 Random number seed used for subsampling unlinked SNPs if a mapfile
 is linked to the Structure Object .
 force : ( bool ) :
 If force is true then old replicates are removed and new reps start
 from rep - 0 . Otherwise , new reps start at end of existing rep numbers .
 quiet : ( bool )
 Whether to print number of jobs submitted to stderr
 Example :
 import ipyparallel as ipp
 import ipyrad . analysis as ipa
 # # get parallel client
 ipyclient = ipp . Client ( )
 # # get structure object
 s = ipa . structure (
 name = " test " ,
 data = " mydata . str " ,
 mapfile = " mydata . snps . map " ,
 workdir = " structure - results " ,
 # # modify some basic params
 s . mainparams . numreps = 100000
 s . mainparams . burnin = 10000
 # # submit many jobs
 for kpop in [ 3 , 4 , 5 ] :
 s . run (
 kpop = kpop ,
 nreps = 10,
 ipyclient = ipyclient ,
 # # block until all jobs finish
 ipyclient . wait ( )"""

implementation:
# # initiate starting seed
np . random . seed ( seed )
# # check for stuructre here
proc = subprocess . Popen ( [ "which" , "structure" ] , stdout = subprocess . PIPE , stderr = subprocess . STDOUT ) . communicate ( )
if not proc :
    raise Exception ( "structure is not installed: run `conda install structure -c ipyrad`" )
# # start load balancer
if ipyclient :
    lbview = ipyclient . load_balanced_view ( )
# # remove old jobs with this same name
handle = OPJ ( self . workdir , self . name + "-K-{}-*" . format ( kpop ) )
oldjobs = glob . glob ( handle )
if force or ( not oldjobs ) :
    for job in oldjobs :
        os . remove ( job )
    repstart = 0
    repend = nreps
else :
    repstart = max ( [ int ( i . split ( "-" ) [ - 1 ] [ : - 2 ] ) for i in oldjobs ] )
    repend = repstart + nreps
# # check that there is a ipcluster instance running
for rep in xrange ( repstart , repend ) : # # sample random seed for this rep
    self . extraparams . seed = np . random . randint ( 0 , 1e9 , 1 ) [ 0 ]
    # # prepare files ( randomly subsamples snps if mapfile )
    mname , ename , sname = self . write_structure_files ( kpop , rep )
    args = [ mname , ename , sname , self . name , self . workdir , self . extraparams . seed , self . ntaxa , self . nsites , kpop , rep ]
    if ipyclient : # # call structure
        async = lbview . apply ( _call_structure , * ( args ) )
        self . asyncs . append ( async )
    else :
        if not quiet :
            sys . stderr . write ( "submitted 1 structure job [{}-K-{}]\n" . format ( self . name , kpop ) )
        comm = _call_structure ( * args )
        return comm
if ipyclient :
    if not quiet :
        sys . stderr . write ( "submitted {} structure jobs [{}-K-{}]\n" . format ( nreps , self . name , kpop ) )


signature:
def write_structure_files ( self , kpop , rep = 1 ) :
    """Prepares input files for running structure . Users typically do not need
 to call this function since it is called internally by . run ( ) . But it
 is optionally available here in case users wish to generate files and
 run structure separately ."""

implementation:
# # check params
self . mainparams . numreps = int ( self . mainparams . numreps )
self . mainparams . burnin = int ( self . mainparams . burnin )
# # write tmp files for the job . Rando avoids filename conflict .
mname = OPJ ( self . workdir , "tmp-{}-{}-{}.mainparams.txt" . format ( self . name , kpop , rep ) )
ename = OPJ ( self . workdir , "tmp-{}-{}-{}.extraparams.txt" . format ( self . name , kpop , rep ) )
sname = OPJ ( self . workdir , "tmp-{}-{}-{}.strfile.txt" . format ( self . name , kpop , rep ) )
tmp_m = open ( mname , 'w' )
tmp_e = open ( ename , 'w' )
tmp_s = open ( sname , 'w' )
# # write params files
tmp_m . write ( self . mainparams . _asfile ( ) )
tmp_e . write ( self . extraparams . _asfile ( ) )
# # subsample SNPs as unlinked if a mapfile is present .
# # & write pop data to the tmp _ s file if present
assert len ( self . popdata ) == len ( self . labels ) , "popdata list must be the same length as the number of taxa"
with open ( self . data ) as ifile :
    _data = ifile . readlines ( )
    # # header
    header = np . array ( [ i . strip ( ) . split ( "\t" ) [ : 5 ] for i in _data ] )
    # # seqdata
    seqdata = np . array ( [ i . strip ( ) . split ( "\t" ) [ 5 : ] for i in _data ] )
    # # enter popdata into seqfile if present in self
    if any ( self . popdata ) : # # set popdata in header
        header [ : : 2 , 1 ] = self . popdata
        header [ 1 : : 2 , 1 ] = self . popdata
        # # set flag to all 1s if user entered popdata but no popflag
        if not any ( self . popflag ) :
            self . popflag = [ 1 for i in self . popdata ]
            header [ : , 2 ] = 1
        else :
            header [ : : 2 , 2 ] = self . popflag
            header [ 1 : : 2 , 2 ] = self . popflag
    # # subsample SNPs if mapfile is present
    if isinstance ( self . maparr , np . ndarray ) :
        seqdata = seqdata [ : , self . _subsample ( ) ]
    # # write fullstr
    fullstr = np . concatenate ( [ header , seqdata ] , axis = 1 )
    np . savetxt ( tmp_s , fullstr , delimiter = "\t" , fmt = "%s" )
# # close tmp files
tmp_m . close ( )
tmp_e . close ( )
tmp_s . close ( )
return mname , ename , sname


signature:
def get_clumpp_table ( self , kvalues , max_var_multiple = 0 , quiet = False ) :
    """Returns a dictionary of results tables for making structure barplots .
 This calls the same functions used in get _ evanno _ table ( ) to call
 CLUMPP to permute replicates .
 Parameters :
 kvalues : list or int
 A kvalue or list of kvalues to run CLUMPP on and return a
 results table .
 max _ var _ multiple : int
 A multiplier value to use as a filter for convergence of runs .
 Default = 0 = no filtering . As an example , if 10 replicates
 were run then the variance of the run with the minimum variance is
 used as a benchmark . If other runs have a variance that is N times
 greater then that run will be excluded . Remember , if replicate runs
 sampled different distributions of SNPs then it is not unexpected that
 they will have very different variances . However , you may still want
 to exclude runs with very high variance since they likely have
 not converged .
 Returns :
 table : dict or pd . DataFrame
 A dictionary of dataframes with admixture proportions ."""

implementation:
# # do not allow bad vals
if max_var_multiple :
    if max_var_multiple < 1 :
        raise ValueError ( 'max_var_multiple must be >1' )
if isinstance ( kvalues , int ) :
    return _get_clumpp_table ( self , kvalues , max_var_multiple , quiet )
else :
    tabledict = { }
    for kpop in kvalues :
        table = _get_clumpp_table ( self , kpop , max_var_multiple , quiet )
        tabledict [ kpop ] = table
    return tabledict


signature:
def get_evanno_table ( self , kvalues , max_var_multiple = 0 , quiet = False ) :
    """Calculates the Evanno table from results files for tests with
 K - values in the input list kvalues . The values lnPK , lnPPK ,
 and deltaK are calculated . The max _ var _ multiplier arg can be used
 to exclude results files based on variance of the likelihood as a
 proxy for convergence .
 Parameters :
 kvalues : list
 The list of K - values for which structure was run for this object .
 e . g . , kvalues = [ 3 , 4 , 5]
 max _ var _ multiple : int
 A multiplier value to use as a filter for convergence of runs .
 Default = 0 = no filtering . As an example , if 10 replicates
 were run then the variance of the run with the minimum variance is
 used as a benchmark . If other runs have a variance that is N times
 greater then that run will be excluded . Remember , if replicate runs
 sampled different distributions of SNPs then it is not unexpected that
 they will have very different variances . However , you may still want
 to exclude runs with very high variance since they likely have
 not converged .
 quiet : bool
 Suppresses printed messages about convergence .
 Returns :
 table : pandas . DataFrame
 A data frame with LPK , LNPPK , and delta K . The latter is typically
 used to find the best fitting value of K . But be wary of over
 interpreting a single best K value ."""

implementation:
# # do not allow bad vals
if max_var_multiple :
    if max_var_multiple < 1 :
        raise ValueError ( 'max_variance_multiplier must be >1' )
table = _get_evanno_table ( self , kvalues , max_var_multiple , quiet )
return table


signature:
def parse ( self , psearch , dsearch ) :
    """parse an _ f structure output file"""

implementation:
stable = ""
with open ( self . repfile ) as orep :
    dat = orep . readlines ( )
    for line in dat : # # stat lines
        if "Estimated Ln Prob of Data" in line :
            self . est_lnlik = float ( line . split ( ) [ - 1 ] )
        if "Mean value of ln likelihood" in line :
            self . mean_lnlik = float ( line . split ( ) [ - 1 ] )
        if "Variance of ln likelihood" in line :
            self . var_lnlik = float ( line . split ( ) [ - 1 ] )
        if "Mean value of alpha" in line :
            self . alpha = float ( line . split ( ) [ - 1 ] )
        # # matrix lines
        nonline = psearch . search ( line )
        popline = dsearch . search ( line )
        # if " ) : " in line :
        if nonline : # # check if sample is supervised . . .
            abc = line . strip ( ) . split ( )
            outstr = "{}{}{}" . format ( " " . join ( [ abc [ 0 ] , abc [ 0 ] , abc [ 2 ] , abc [ 0 ] . split ( '.' ) [ 0 ] ] ) , " :  " , " " . join ( abc [ 4 : ] ) )
            self . inds += 1
            stable += outstr + "\n"
        elif popline : # # check if sample is supervised . . .
            abc = line . strip ( ) . split ( )
            prop = [ "0.000" ] * self . kpop
            pidx = int ( abc [ 3 ] ) - 1
            prop [ pidx ] = "1.000"
            outstr = "{}{}{}" . format ( " " . join ( [ abc [ 0 ] , abc [ 0 ] , abc [ 2 ] , abc [ 0 ] . split ( '.' ) [ 0 ] ] ) , " :  " , " " . join ( prop ) )
            self . inds += 1
            stable += outstr + "\n"
    stable += "\n"
return stable


signature:
def _call_raxml ( command_list ) :
    """call the command as sps"""

implementation:
proc = subprocess . Popen ( command_list , stderr = subprocess . STDOUT , stdout = subprocess . PIPE )
comm = proc . communicate ( )
return comm


signature:
def _command_list ( self ) :
    """build the command list"""

implementation:
cmd = [ self . params . binary , "-f" , str ( self . params . f ) , "-T" , str ( self . params . T ) , "-m" , str ( self . params . m ) , "-N" , str ( self . params . N ) , "-x" , str ( self . params . x ) , "-p" , str ( self . params . p ) , "-n" , str ( self . params . n ) , "-w" , str ( self . params . w ) , "-s" , str ( self . params . s ) , ]
# # add ougroups
if self . params . o :
    cmd += [ "-o" ]
    cmd += [ "," . join ( self . params . o ) ]
return cmd


signature:
def run ( self , ipyclient = None , quiet = False , force = False , block = False , ) :
    """Submits raxml job to run . If no ipyclient object is provided then
 the function will block until the raxml run is finished . If an ipyclient
 is provided then the job is sent to a remote engine and an asynchronous
 result object is returned which can be queried or awaited until it finishes .
 Parameters
 ipyclient :
 Not yet supported . . .
 quiet :
 suppress print statements
 force :
 overwrite existing results files with this job name .
 block :
 will block progress in notebook until job finishes , even if job
 is running on a remote ipyclient ."""

implementation:
# # stop before trying in raxml
if force :
    for key , oldfile in self . trees :
        if os . path . exists ( oldfile ) :
            os . remove ( oldfile )
if os . path . exists ( self . trees . info ) :
    print ( "Error: set a new name for this job or use Force flag.\nFile exists: {}" . format ( self . trees . info ) )
    return
# # TODO : add a progress bar tracker here . It could even read it from
# # the info file that is being written .
# # submit it
if not ipyclient :
    proc = _call_raxml ( self . _command_list )
    self . stdout = proc [ 0 ]
    self . stderr = proc [ 1 ]
else : # # find all hosts and submit job to the host with most available engines
    lbview = ipyclient . load_balanced_view ( )
    self . async = lbview . apply ( _call_raxml , self . _command_list )
# # initiate random seed
if not quiet :
    if not ipyclient : # # look for errors
        if "Overall execution time" not in self . stdout :
            print ( "Error in raxml run\n" + self . stdout )
        else :
            print ( "job {} finished successfully" . format ( self . params . n ) )
    else :
        print ( "job {} submitted to cluster" . format ( self . params . n ) )


signature:
def _get_binary ( self ) :
    """find binaries available"""

implementation:
# # check for binary
backup_binaries = [ "raxmlHPC-PTHREADS" , "raxmlHPC-PTHREADS-SSE3" ]
# # check user binary first , then backups
for binary in [ self . params . binary ] + backup_binaries :
    proc = subprocess . Popen ( [ "which" , self . params . binary ] , stdout = subprocess . PIPE , stderr = subprocess . STDOUT ) . communicate ( )
    # # update the binary
    if proc :
        self . params . binary = binary
# # if none then raise error
if not proc [ 0 ] :
    raise Exception ( BINARY_ERROR . format ( self . params . binary ) )


signature:
def share_matrix ( locifile , tree = None , nameorder = None ) :
    """returns a matrix of shared RAD - seq data
 Parameters :
 locifile ( str ) :
 Path to a ipyrad . loci file .
 tree ( str ) :
 Path to Newick file or a Newick string representation of
 a tree . If used , names will be ordered by the ladderized
 tip order .
 nameorder ( list ) :
 If a tree is not provided you can alternatively enter
 the sample order as a list here . The tree argument will
 override this argument .
 Returns :
 matrix ( numpy . array ) :
 A uint64 numpy array of the number of shared loci between
 all pairs of samples ."""

implementation:
# # load in the loci data
with open ( locifile , 'r' ) as locidata :
    loci = locidata . read ( ) . split ( "|\n" ) [ : - 1 ]
# # load in the tree from a string
if tree :
    tree = ete . Tree ( tree )
    tree . ladderize ( )
    snames = tree . get_leaf_names ( )
    lxs , names = _getarray ( loci , snames )
elif nameorder :
    lxs , names = _getarray ( loci , nameorder )
else :
    raise IOError ( "must provide either tree or nameorder argument" )
# # get share matrix
share = _countmatrix ( lxs )
return share


signature:
def _getarray ( loci , snames ) :
    """parse loci list and return presence / absence matrix
 ordered by the tips on the tree or list of names ."""

implementation:
# # make an empty matrix
lxs = np . zeros ( ( len ( snames ) , len ( loci ) ) , dtype = np . uint64 )
# # fill the matrix
for loc in xrange ( len ( loci ) ) :
    for seq in loci [ loc ] . split ( "\n" ) :
        if "//" not in seq :
            lxs [ snames . index ( seq . split ( ) [ 0 ] [ : ] ) , loc ] += 1
return lxs , snames


signature:
def batch ( baba , ipyclient = None , ) :
    """distributes jobs to the parallel client"""

implementation:
# # parse args
handle = baba . data
taxdicts = baba . tests
mindicts = baba . params . mincov
nboots = baba . params . nboots
# # if ms generator make into reusable list
sims = 0
if isinstance ( handle , types . GeneratorType ) :
    handle = list ( handle )
    sims = 1
else : # # expand locifile path to full path
    handle = os . path . realpath ( handle )
# # parse taxdicts into names and lists if it a dictionary
# if isinstance ( taxdicts , dict ) :
# names , taxdicts = taxdicts . keys ( ) , taxdicts . values ( )
# else :
# names = [ ]
names = [ ]
if isinstance ( taxdicts , dict ) :
    taxdicts = [ taxdicts ]
# # an array to hold results ( len ( taxdicts ) , nboots )
tot = len ( taxdicts )
resarr = np . zeros ( ( tot , 7 ) , dtype = np . float64 )
bootsarr = np . zeros ( ( tot , nboots ) , dtype = np . float64 )
paneldict = { }
# # TODO : Setup a wrapper to find and cleanup ipyclient
# # define the function and parallelization to use ,
# # if no ipyclient then drops back to using multiprocessing .
if not ipyclient : # ipyclient = ip . core . parallel . get _ client ( * * self . _ ipcluster )
    raise IPyradError ( "you must enter an ipyparallel.Client() object" )
else :
    lbview = ipyclient . load_balanced_view ( )
# # submit jobs to run on the cluster queue
start = time . time ( )
asyncs = { }
idx = 0
# # prepare data before sending to engines
# # if it ' s a str ( locifile ) then parse it here just once .
if isinstance ( handle , str ) :
    with open ( handle , 'r' ) as infile :
        loci = infile . read ( ) . strip ( ) . split ( "|\n" )
if isinstance ( handle , list ) :
    pass
# sims ( )
# # iterate over tests ( repeats mindicts if fewer than taxdicts )
itests = iter ( taxdicts )
imdict = itertools . cycle ( [ mindicts ] )
# for test , mindict in zip ( taxdicts , itertools . cycle ( [ mindicts ] ) ) :
for i in xrange ( len ( ipyclient ) ) : # # next entries unless fewer than len ipyclient , skip
    try :
        test = next ( itests )
        mindict = next ( imdict )
    except StopIteration :
        continue
    # # if it ' s sim data then convert to an array
    if sims :
        loci = _msp_to_arr ( handle , test )
        args = ( loci , test , mindict , nboots )
        print ( "not yet implemented" )
        # asyncs [ idx ] = lbview . apply _ async ( dstat , * args )
    else :
        args = [ loci , test , mindict , nboots ]
        asyncs [ idx ] = lbview . apply ( dstat , * args )
    idx += 1
# # block until finished , print progress if requested .
finished = 0
try :
    while 1 :
        keys = [ i for ( i , j ) in asyncs . items ( ) if j . ready ( ) ]
        # # check for failures
        for job in keys :
            if not asyncs [ job ] . successful ( ) :
                raise IPyradWarningExit ( " error: {}: {}" . format ( job , asyncs [ job ] . exception ( ) ) )
            # # enter results for successful jobs
            else :
                _res , _bot = asyncs [ job ] . result ( )
                # # store D4 results
                if _res . shape [ 0 ] == 1 :
                    resarr [ job ] = _res . T . as_matrix ( ) [ : , 0 ]
                    bootsarr [ job ] = _bot
                # # or store D5 results
                else :
                    paneldict [ job ] = _res . T
                # # remove old job
                del asyncs [ job ]
                finished += 1
                # # submit next job if there is one .
                try :
                    test = next ( itests )
                    mindict = next ( imdict )
                    if sims :
                        loci = _msp_to_arr ( handle , test )
                        args = ( loci , test , mindict , nboots )
                        print ( "not yet implemented" )
                        # asyncs [ idx ] = lbview . apply _ async ( dstat , * args )
                    else :
                        args = [ loci , test , mindict , nboots ]
                        asyncs [ idx ] = lbview . apply ( dstat , * args )
                    idx += 1
                except StopIteration :
                    pass
        # # count finished and break if all are done .
        # fin = idx - len ( asyncs )
        elap = datetime . timedelta ( seconds = int ( time . time ( ) - start ) )
        printstr = " calculating D-stats  | {} | "
        progressbar ( tot , finished , printstr . format ( elap ) , spacer = "" )
        time . sleep ( 0.1 )
        if not asyncs :
            print ( "" )
            break
except KeyboardInterrupt as inst : # # cancel all jobs ( ipy & multiproc modes ) and then raise error
    try :
        ipyclient . abort ( )
    except Exception :
        pass
    raise inst
# # dress up resarr as a Pandas DataFrame if 4 - part test
if len ( test ) == 4 :
    if not names :
        names = range ( len ( taxdicts ) )
    # print ( " resarr " )
    # print ( resarr )
    resarr = pd . DataFrame ( resarr , index = names , columns = [ "dstat" , "bootmean" , "bootstd" , "Z" , "ABBA" , "BABA" , "nloci" ] )
    # # sort results and bootsarr to match if test names were supplied
    resarr = resarr . sort_index ( )
    order = [ list ( resarr . index ) . index ( i ) for i in names ]
    bootsarr = bootsarr [ order ]
    return resarr , bootsarr
else : # # order results dfs
    listres = [ ]
    for key in range ( len ( paneldict ) ) :
        listres . append ( paneldict [ key ] )
    # # make into a multi - index dataframe
    ntests = len ( paneldict )
    multi_index = [ np . array ( [ [ i ] * 3 for i in range ( ntests ) ] ) . flatten ( ) , np . array ( [ 'p3' , 'p4' , 'shared' ] * ntests ) , ]
    resarr = pd . DataFrame ( data = pd . concat ( listres ) . as_matrix ( ) , index = multi_index , columns = listres [ 0 ] . columns , )
    return resarr , None


signature:
def dstat ( inarr , taxdict , mindict = 1 , nboots = 1000 , name = 0 ) :
    """private function to perform a single D - stat test"""

implementation:
# if isinstance ( inarr , str ) :
# with open ( inarr , ' r ' ) as infile :
# inarr = infile . read ( ) . strip ( ) . split ( " | \ n " )
# # # get data as an array from loci file
# # # if loci - list then parse arr from loci
if isinstance ( inarr , list ) :
    arr , _ = _loci_to_arr ( inarr , taxdict , mindict )
# # # if it ' s an array already then go ahead
# elif isinstance ( inarr , np . ndarray ) :
# arr = inarr
# # # if it ' s a simulation object get freqs from array
# elif isinstance ( inarr , Sim ) :
# arr = _ msp _ to _ arr ( inarr , taxdict )
# elif isinstance ( inarr , types . GeneratorType ) :
# arr = _ msp _ to _ arr ( inarr , taxdict )
# elif isinstance ( inarr , list ) :
# arr = _ msp _ to _ arr ( inarr , taxdict )
# # get data from Sim object , do not digest the ms generator
# else :
# raise Exception ( " Must enter either a ' locifile ' or ' arr ' " )
# # run tests
# if len ( taxdict ) = = 4:
if arr . shape [ 1 ] == 4 : # # get results
    res , boots = _get_signif_4 ( arr , nboots )
    # # make res into a nice DataFrame
    res = pd . DataFrame ( res , columns = [ name ] , index = [ "Dstat" , "bootmean" , "bootstd" , "Z" , "ABBA" , "BABA" , "nloci" ] )
else : # # get results
    res , boots = _get_signif_5 ( arr , nboots )
    # # make int a DataFrame
    res = pd . DataFrame ( res , index = [ "p3" , "p4" , "shared" ] , columns = [ "Dstat" , "bootmean" , "bootstd" , "Z" , "ABxxA" , "BAxxA" , "nloci" ] )
return res . T , boots


signature:
def _loci_to_arr ( loci , taxdict , mindict ) :
    """return a frequency array from a loci file for all loci with taxa from
 taxdict and min coverage from mindict ."""

implementation:
# # make the array ( 4 or 5 ) and a mask array to remove loci without cov
nloci = len ( loci )
maxlen = np . max ( np . array ( [ len ( locus . split ( "\n" ) [ 0 ] ) for locus in loci ] ) )
keep = np . zeros ( nloci , dtype = np . bool_ )
arr = np . zeros ( ( nloci , 4 , maxlen ) , dtype = np . float64 )
# # six rows b / c one for each p3 , and for the fused p3 ancestor
if len ( taxdict ) == 5 :
    arr = np . zeros ( ( nloci , 6 , maxlen ) , dtype = np . float64 )
# # if not mindict , make one that requires 1 in each taxon
if isinstance ( mindict , int ) :
    mindict = { i : mindict for i in taxdict }
elif isinstance ( mindict , dict ) :
    mindict = { i : mindict [ i ] for i in taxdict }
else :
    mindict = { i : 1 for i in taxdict }
# # raise error if names are not ' p [ int ] '
allowed_names = [ 'p1' , 'p2' , 'p3' , 'p4' , 'p5' ]
if any ( [ i not in allowed_names for i in taxdict ] ) :
    raise IPyradError ( "keys in taxdict must be named 'p1' through 'p4' or 'p5'" )
# # parse key names
keys = sorted ( [ i for i in taxdict . keys ( ) if i [ 0 ] == 'p' ] )
outg = keys [ - 1 ]
# # grab seqs just for the good guys
for loc in xrange ( nloci ) : # # parse the locus
    lines = loci [ loc ] . split ( "\n" ) [ : - 1 ]
    names = [ i . split ( ) [ 0 ] for i in lines ]
    seqs = np . array ( [ list ( i . split ( ) [ 1 ] ) for i in lines ] )
    # # check that names cover the taxdict ( still need to check by site )
    covs = [ sum ( [ j in names for j in taxdict [ tax ] ] ) >= mindict [ tax ] for tax in taxdict ]
    # # keep locus
    if all ( covs ) :
        keep [ loc ] = True
        # # get the refseq
        refidx = np . where ( [ i in taxdict [ outg ] for i in names ] ) [ 0 ]
        refseq = seqs [ refidx ] . view ( np . uint8 )
        ancestral = np . array ( [ reftrick ( refseq , GETCONS2 ) [ : , 0 ] ] )
        # # freq of ref in outgroup
        iseq = _reffreq2 ( ancestral , refseq , GETCONS2 )
        arr [ loc , - 1 , : iseq . shape [ 1 ] ] = iseq
        # # enter 4 - taxon freqs
        if len ( taxdict ) == 4 :
            for tidx , key in enumerate ( keys [ : - 1 ] ) : # # get idx of names in test tax
                nidx = np . where ( [ i in taxdict [ key ] for i in names ] ) [ 0 ]
                sidx = seqs [ nidx ] . view ( np . uint8 )
                # # get freq of sidx
                iseq = _reffreq2 ( ancestral , sidx , GETCONS2 )
                # # fill it in
                arr [ loc , tidx , : iseq . shape [ 1 ] ] = iseq
        else : # # entere p5 ; and fill it in
            iseq = _reffreq2 ( ancestral , refseq , GETCONS2 )
            arr [ loc , - 1 , : iseq . shape [ 1 ] ] = iseq
            # # enter p1
            nidx = np . where ( [ i in taxdict [ 'p1' ] for i in names ] ) [ 0 ]
            sidx = seqs [ nidx ] . view ( np . uint8 )
            iseq = _reffreq2 ( ancestral , sidx , GETCONS2 )
            arr [ loc , 0 , : iseq . shape [ 1 ] ] = iseq
            # # enter p2
            nidx = np . where ( [ i in taxdict [ 'p2' ] for i in names ] ) [ 0 ]
            sidx = seqs [ nidx ] . view ( np . uint8 )
            iseq = _reffreq2 ( ancestral , sidx , GETCONS2 )
            arr [ loc , 1 , : iseq . shape [ 1 ] ] = iseq
            # # enter p3 with p4 masked , and p4 with p3 masked
            nidx = np . where ( [ i in taxdict [ 'p3' ] for i in names ] ) [ 0 ]
            nidy = np . where ( [ i in taxdict [ 'p4' ] for i in names ] ) [ 0 ]
            sidx = seqs [ nidx ] . view ( np . uint8 )
            sidy = seqs [ nidy ] . view ( np . uint8 )
            xseq = _reffreq2 ( ancestral , sidx , GETCONS2 )
            yseq = _reffreq2 ( ancestral , sidy , GETCONS2 )
            mask3 = xseq != 0
            mask4 = yseq != 0
            xseq [ mask4 ] = 0
            yseq [ mask3 ] = 0
            arr [ loc , 2 , : xseq . shape [ 1 ] ] = xseq
            arr [ loc , 3 , : yseq . shape [ 1 ] ] = yseq
            # # enter p34
            nidx = nidx . tolist ( ) + nidy . tolist ( )
            sidx = seqs [ nidx ] . view ( np . uint8 )
            iseq = _reffreq2 ( ancestral , sidx , GETCONS2 )
            arr [ loc , 4 , : iseq . shape [ 1 ] ] = iseq
# # size - down array to the number of loci that have taxa for the test
arr = arr [ keep , : , : ]
# # size - down sites to
arr = masknulls ( arr )
return arr , keep


signature:
def _get_boots ( arr , nboots ) :
    """return array of bootstrap D - stats"""

implementation:
# # hold results ( nboots , [ dstat , ] )
boots = np . zeros ( ( nboots , ) )
# # iterate to fill boots
for bidx in xrange ( nboots ) : # # sample with replacement
    lidx = np . random . randint ( 0 , arr . shape [ 0 ] , arr . shape [ 0 ] )
    tarr = arr [ lidx ]
    _ , _ , dst = _prop_dstat ( tarr )
    boots [ bidx ] = dst
# # return bootarr
return boots


signature:
def _get_signif_4 ( arr , nboots ) :
    """returns a list of stats and an array of dstat boots . Stats includes
 z - score and two - sided P - value ."""

implementation:
abba , baba , dst = _prop_dstat ( arr )
boots = _get_boots ( arr , nboots )
estimate , stddev = ( boots . mean ( ) , boots . std ( ) )
zscore = 0.
if stddev :
    zscore = np . abs ( dst ) / stddev
stats = [ dst , estimate , stddev , zscore , abba , baba , arr . shape [ 0 ] ]
return np . array ( stats ) , boots


signature:
def _get_signif_5 ( arr , nboots ) :
    """returns a list of stats and an array of dstat boots . Stats includes
 z - score and two - sided P - value ."""

implementation:
statsarr = np . zeros ( ( 3 , 7 ) , dtype = np . float64 )
bootsarr = np . zeros ( ( 3 , nboots ) )
idx = 0
for acol in [ 2 , 3 , 4 ] :
    rows = np . array ( [ 0 , 1 , acol , 5 ] )
    tarr = arr [ : , rows , : ]
    abxa , baxa , dst = _prop_dstat ( tarr )
    boots = _get_boots ( tarr , nboots )
    estimate , stddev = ( boots . mean ( ) , boots . std ( ) )
    if stddev :
        zscore = np . abs ( dst ) / stddev
    else :
        zscore = np . NaN
    stats = [ dst , estimate , stddev , zscore , abxa , baxa , arr . shape [ 0 ] ]
    statsarr [ idx ] = stats
    bootsarr [ idx ] = boots
    idx += 1
return statsarr , bootsarr


signature:
def _simulate ( self , nreps , admix = None , Ns = 500000 , gen = 20 ) :
    """Enter a baba . Tree object in which the ' tree ' attribute ( newick
 derived tree ) has edge lengths in units of generations . You can
 use the ' gen ' parameter to multiply branch lengths by a constant .
 Parameters :
 nreps : ( int )
 Number of reps ( loci ) to simulate under the demographic scenario
 tree : ( baba . Tree object )
 A baba . Tree object initialized by calling baba . Tree ( * args ) .
 admix : ( list )
 A list of admixture events to occur on the tree . Nodes must be
 reference by their index number , and events must occur in time
 intervals when edges exist . Use the . draw ( ) function of the
 baba . Tree object to see node index numbers and coalescent times .
 Ns : ( float )
 Fixed effective population size for all lineages ( may allow to vary
 in the future ) .
 gen : ( int )
 A multiplier applied to branch lengths to scale into units of
 generations . Example , if all edges on a tree were 1 then you might
 enter 50000 to multiply so that edges are 50K generations long ."""

implementation:
# # node ages
Taus = np . array ( list ( set ( self . verts [ : , 1 ] ) ) ) * 1e4 * gen
# # The tips samples , ordered alphanumerically
# # Population IDs correspond to their indexes in pop config
ntips = len ( self . tree )
# names = { name : idx for idx , name in enumerate ( sorted ( self . tree . get _ leaf _ names ( ) ) ) }
# # rev ladderized leaf name order ( left to right on downward facing tree )
names = { name : idx for idx , name in enumerate ( self . tree . get_leaf_names ( ) [ : : - 1 ] ) }
pop_config = [ ms . PopulationConfiguration ( sample_size = 2 , initial_size = Ns ) for i in range ( ntips ) ]
# # migration matrix all zeros init
migmat = np . zeros ( ( ntips , ntips ) ) . tolist ( )
# # a list for storing demographic events
demog = [ ]
# # coalescent times
coals = sorted ( list ( set ( self . verts [ : , 1 ] ) ) ) [ 1 : ]
for ct in xrange ( len ( coals ) ) : # # check for admix event before next coalescence
# # print coals [ ct ] , nidxs , time
    nidxs = np . where ( self . verts [ : , 1 ] == coals [ ct ] ) [ 0 ]
    time = Taus [ ct + 1 ]
    # # add coalescence at each node
    for nidx in nidxs :
        node = self . tree . search_nodes ( name = str ( nidx ) ) [ 0 ]
        # # get destionation ( lowest child idx number ) , and other
        dest = sorted ( node . get_leaves ( ) , key = lambda x : x . idx ) [ 0 ]
        otherchild = [ i for i in node . children if not i . get_leaves_by_name ( dest . name ) ] [ 0 ]
        # # get source
        if otherchild . is_leaf ( ) :
            source = otherchild
        else :
            source = sorted ( otherchild . get_leaves ( ) , key = lambda x : x . idx ) [ 0 ]
        # # add coal events
        event = ms . MassMigration ( time = int ( time ) , source = names [ source . name ] , destination = names [ dest . name ] , proportion = 1.0 )
        # print ( int ( time ) , names [ source . name ] , names [ dest . name ] )
        demog . append ( event )
# # sim the data
replicates = ms . simulate ( population_configurations = pop_config , migration_matrix = migmat , demographic_events = demog , num_replicates = nreps , length = 100 , mutation_rate = 1e-8 )
return replicates


signature:
def taxon_table ( self ) :
    """Returns the . tests list of taxa as a pandas dataframe .
 By auto - generating this table from tests it means that
 the table itself cannot be modified unless it is returned
 and saved ."""

implementation:
if self . tests :
    keys = sorted ( self . tests [ 0 ] . keys ( ) )
    if isinstance ( self . tests , list ) :
        ld = [ [ ( key , i [ key ] ) for key in keys ] for i in self . tests ]
        dd = [ dict ( i ) for i in ld ]
        df = pd . DataFrame ( dd )
        return df
    else :
        return pd . DataFrame ( pd . Series ( self . tests ) ) . T
else :
    return None


signature:
def run ( self , ipyclient = None , ) :
    """Run a batch of dstat tests on a list of tests , where each test is
 a dictionary mapping sample names to { p1 - p4 } ( and sometimes p5 ) .
 Parameters modifying the behavior of the run , such as the number
 of bootstrap replicates ( nboots ) or the minimum coverage for
 loci ( mincov ) can be set in { object } . params .
 Parameters :
 ipyclient ( ipyparallel . Client object ) :
 An ipyparallel client object to distribute jobs to a cluster ."""

implementation:
self . results_table , self . results_boots = batch ( self , ipyclient )
# # skip this for 5 - part test results
if not isinstance ( self . results_table , list ) :
    self . results_table . nloci = np . nan_to_num ( self . results_table . nloci ) . astype ( int )


signature:
def plot ( self , show_test_labels = True , use_edge_lengths = True , collapse_outgroup = False , pct_tree_x = 0.5 , pct_tree_y = 0.2 , subset_tests = None , # toytree _ kwargs = None ,
* args , ** kwargs ) :
    """Draw a multi - panel figure with tree , tests , and results
 Parameters :
 height : int
 width : int
 show _ test _ labels : bool
 use _ edge _ lengths : bool
 collapse _ outgroups : bool
 pct _ tree _ x : float
 pct _ tree _ y : float
 subset _ tests : list"""

implementation:
# # check for attributes
if not self . newick :
    raise IPyradError ( "baba plot requires a newick treefile" )
if not self . tests :
    raise IPyradError ( "baba plot must have a .tests attribute" )
# # ensure tests is a list
if isinstance ( self . tests , dict ) :
    self . tests = [ self . tests ]
# # re - decompose the tree
ttree = toytree . tree ( self . newick , orient = 'down' , use_edge_lengths = use_edge_lengths , )
# # subset test to show fewer
if subset_tests != None : # tests = self . tests [ subset _ tests ]
    tests = [ self . tests [ i ] for i in subset_tests ]
    boots = self . results_boots [ subset_tests ]
else :
    tests = self . tests
    boots = self . results_boots
# # make the plot
canvas , axes , panel = baba_panel_plot ( ttree = ttree , tests = tests , boots = boots , show_test_labels = show_test_labels , use_edge_lengths = use_edge_lengths , collapse_outgroup = collapse_outgroup , pct_tree_x = pct_tree_x , pct_tree_y = pct_tree_y , * args , ** kwargs )
return canvas , axes , panel


signature:
def loci2multinex ( name , locifile , subsamples = None , outdir = None , maxloci = None , minSNPs = 1 , seed = 12345 , mcmc_burnin = int ( 1e6 ) , mcmc_ngen = int ( 2e6 ) , mcmc_sample_freq = 1000 , ) :
    """Converts loci file format to multiple nexus formatted files , one for
 each locus , and writes a mrbayes block in the nexus information . The
 mrbayes block will be set to run 2 replicate chains , for [ mcmc _ ngen ]
 generations , skipping [ burnin ] steps , and sampling every
 [ mcmc _ sample _ freq ] steps .
 Parameters :
 name : ( str )
 A prefix name for output files that will be produced
 locifile : ( str )
 A . loci file produced by ipyrad .
 maxloci : ( int )
 Limit the number of loci to the first N loci with sufficient sampling
 to be included in the analysis .
 minSNPs : ( int )
 Only include loci that have at least N parsimony informative SNPs .
 seed : ( int )
 Random seed used for resolving ambiguities .
 burnin : ( int )
 mrbayes nexus block burnin parameter used for ' sump burnin ' and ' sumt burnin ' .
 The number of generations to skip before starting parameter and tree sampling .
 mcmc _ ngen : ( int )
 mrbayes nexus block ' mcmc ngen ' and ' mcmc printfreq ' parameters . We don ' t really
 to have any info printed to screen , so these values are set equal . This is the
 length of the chains that will be run .
 mcmc _ sample _ freq : ( int )
 mrbayes nexus block ' mcmc samplefreq ' parameter . The frequency of sampling from
 the mcmc chain ."""

implementation:
# # workdir is the top level directory ( e . g . , analysis - bucky )
if outdir :
    if not os . path . exists ( outdir ) :
        os . makedirs ( outdir )
else :
    outdir = os . path . curdir
# # enforce full path names
outdir = os . path . realpath ( outdir )
# # outdir is a named directory within this ( e . g . , analysis - bucky / subs / )
outdir = os . path . join ( outdir , "bucky-{}" . format ( name ) )
if not os . path . exists ( outdir ) :
    os . makedirs ( outdir )
else : # # remove { number } . nex files in this folder
    ofiles = glob . glob ( os . path . join ( outdir , "[0-9].nex*" ) )
    for ofile in ofiles :
        os . remove ( ofile )
# # parse the locifile to a generator
with open ( locifile ) as infile :
    loci = ( i for i in infile . read ( ) . strip ( ) . split ( "|\n" ) )
# # convert subsamples to a set
if not subsamples : # # get all sample names from loci
    with open ( locifile ) as infile :
        subs = set ( ( i . split ( ) [ 0 ] for i in infile . readlines ( ) if "//" not in i ) )
else :
    subs = set ( subsamples )
# # keep track of how many loci pass
lens = len ( subs )
nlocus = 0
# # create subsampled data set
for loc in loci :
    dat = loc . split ( "\n" ) [ : - 1 ]
    # # get names and seq from locus
    names = [ i . split ( ) [ 0 ] for i in dat ]
    seqs = np . array ( [ list ( i . split ( ) [ 1 ] ) for i in dat ] )
    # # check that locus has required samples for each subtree
    if len ( set ( names ) . intersection ( set ( subs ) ) ) == lens : # # order the same way every time
        seqsamp = seqs [ [ names . index ( tax ) for tax in subs ] ]
        seqsamp = _resolveambig ( seqsamp )
        pis = _count_PIS ( seqsamp , minSNPs )
        if pis :
            nlocus += 1
            # # remove invariable columns given this subsampling
            copied = seqsamp . copy ( )
            copied [ copied == "-" ] = "N"
            rmcol = np . all ( copied == "N" , axis = 0 )
            seqsamp = seqsamp [ : , ~ rmcol ]
            # # write to a nexus file
            mdict = dict ( zip ( subs , [ i . tostring ( ) for i in seqsamp ] ) )
            nexmake ( mdict , nlocus , outdir , mcmc_burnin , mcmc_ngen , mcmc_sample_freq )
print "wrote {} nexus files to {}" . format ( nlocus , outdir )


signature:
def nexmake ( mdict , nlocus , dirs , mcmc_burnin , mcmc_ngen , mcmc_sample_freq ) :
    """function that takes a dictionary mapping names to
 sequences , and a locus number , and writes it as a NEXUS
 file with a mrbayes analysis block ."""

implementation:
# # create matrix as a string
max_name_len = max ( [ len ( i ) for i in mdict ] )
namestring = "{:<" + str ( max_name_len + 1 ) + "} {}\n"
matrix = ""
for i in mdict . items ( ) :
    matrix += namestring . format ( i [ 0 ] , i [ 1 ] )
# # write nexus block
handle = os . path . join ( dirs , "{}.nex" . format ( nlocus ) )
with open ( handle , 'w' ) as outnex :
    outnex . write ( NEXBLOCK . format ( ** { "ntax" : len ( mdict ) , "nchar" : len ( mdict . values ( ) [ 0 ] ) , "matrix" : matrix , "ngen" : mcmc_ngen , "sfreq" : mcmc_sample_freq , "burnin" : mcmc_burnin , } ) )


signature:
def call_fastq_dump_on_SRRs ( self , srr , outname , paired ) :
    """calls fastq - dump on SRRs , relabels fastqs by their accession
 names , and writes them to the workdir . Saves temp sra files
 in the designated tmp folder and immediately removes them ."""

implementation:
# # build command for fastq - dumping
fd_cmd = [ "fastq-dump" , srr , "--accession" , outname , "--outdir" , self . workdir , "--gzip" , ]
if paired :
    fd_cmd += [ "--split-files" ]
# # call fq dump command
proc = sps . Popen ( fd_cmd , stderr = sps . STDOUT , stdout = sps . PIPE )
o , e = proc . communicate ( )
# # delete the stupid temp sra file from the place
# # that it is very hard - coded to be written to , and
# # LEFT IN , for some crazy reason .
srafile = os . path . join ( self . workdir , "sra" , srr + ".sra" )
if os . path . exists ( srafile ) :
    os . remove ( srafile )


signature:
def fields_checker ( fields ) :
    """returns a fields argument formatted as a list of strings .
 and doesn ' t allow zero ."""

implementation:
# # make sure fields will work
if isinstance ( fields , int ) :
    fields = str ( fields )
if isinstance ( fields , str ) :
    if "," in fields :
        fields = [ str ( i ) for i in fields . split ( "," ) ]
    else :
        fields = [ str ( fields ) ]
elif isinstance ( fields , ( tuple , list ) ) :
    fields = [ str ( i ) for i in fields ]
else :
    raise IPyradWarningExit ( "fields not properly formatted" )
# # do not allow zero in fields
fields = [ i for i in fields if i != '0' ]
return fields


signature:
def run ( self , force = False , ipyclient = None , name_fields = 30 , name_separator = "_" , dry_run = False ) :
    """Download the accessions into a the designated workdir .
 Parameters
 force : ( bool )
 If force = True then existing files with the same name
 will be overwritten .
 ipyclient : ( ipyparallel . Client )
 If provided , work will be distributed across a parallel
 client , otherwise download will be run on a single core .
 name _ fields : ( int , str ) :
 Provide the index of the name fields to be used as a prefix
 for fastq output files . The default is 30 , which is the
 SampleName field . Use sra . fetch _ fields to see all available
 fields and their indices . A likely alternative is 1 ( Run ) .
 If multiple are listed then they will be joined by a " _ "
 character . For example ( 29,30 ) would yield something like :
 latin - name _ sample - name ( e . g . , mus _ musculus - NR10123 ) .
 dry _ run : ( bool )
 If True then a table of file names that _ would _ be downloaded
 will be shown , but the actual files will note be downloaded ."""

implementation:
# # temporarily set directory for tmpfiles used by fastq - dump
# # if this fails then just skip it .
try : # # ensure output directory , also used as tmpdir
    if not os . path . exists ( self . workdir ) :
        os . makedirs ( self . workdir )
    # # get original directory for sra files
    # # probably / home / ncbi / public / sra by default .
    self . _set_vdbconfig_path ( )
    # # register ipyclient for cleanup
    if ipyclient :
        self . _ipcluster [ "pids" ] = { }
        for eid in ipyclient . ids :
            engine = ipyclient [ eid ]
            if not engine . outstanding :
                pid = engine . apply ( os . getpid ) . get ( )
                self . _ipcluster [ "pids" ] [ eid ] = pid
    # # submit jobs to engines or local
    self . _submit_jobs ( force = force , ipyclient = ipyclient , name_fields = name_fields , name_separator = name_separator , dry_run = dry_run , )
except IPyradWarningExit as inst :
    print ( inst )
# # exceptions to catch , cleanup and handle ipyclient interrupts
except KeyboardInterrupt :
    print ( "keyboard interrupt..." )
except Exception as inst :
    print ( "Exception in run() - {}" . format ( inst ) )
finally : # # reset working sra path
    self . _restore_vdbconfig_path ( )
    # # if it made a new sra directory then it should be empty when
    # # we are finished if all . sra files were removed . If so , then
    # # let ' s also remove the dir . if not empty , leave it .
    sradir = os . path . join ( self . workdir , "sra" )
    if os . path . exists ( sradir ) and ( not os . listdir ( sradir ) ) :
        shutil . rmtree ( sradir )
    else : # # print warning
        try :
            print ( FAILED_DOWNLOAD . format ( os . listdir ( sradir ) ) )
        except OSError as inst : # # If sra dir doesn ' t even exist something very bad is broken .
            raise IPyradWarningExit ( "Download failed. Exiting." )
        # # remove fastq file matching to cached sra file
        for srr in os . listdir ( sradir ) :
            isrr = srr . split ( "." ) [ 0 ]
            ipath = os . path . join ( self . workdir , "*_{}*.gz" . format ( isrr ) )
            ifile = glob . glob ( ipath ) [ 0 ]
            if os . path . exists ( ifile ) :
                os . remove ( ifile )
        # # remove cache of sra files
        shutil . rmtree ( sradir )
    # # cleanup ipcluster shutdown
    if ipyclient : # # send SIGINT ( 2 ) to all engines still running tasks
        try :
            ipyclient . abort ( )
            time . sleep ( 0.5 )
            for engine_id , pid in self . _ipcluster [ "pids" ] . items ( ) :
                if ipyclient . queue_status ( ) [ engine_id ] [ "tasks" ] :
                    os . kill ( pid , 2 )
                time . sleep ( 0.1 )
        except ipp . NoEnginesRegistered :
            pass
        # # clean memory space
        if not ipyclient . outstanding :
            ipyclient . purge_everything ( )
        # # uh oh , kill everything , something bad happened
        else :
            ipyclient . shutdown ( hub = True , block = False )
            ipyclient . close ( )
            print ( "\nwarning: ipcluster shutdown and must be restarted" )


signature:
def _submit_jobs ( self , force , ipyclient , name_fields , name_separator , dry_run ) :
    """Download the accessions into a the designated workdir .
 If file already exists it will only be overwritten if
 force = True . Temporary files are removed ."""

implementation:
# # get Run data with default fields ( 1,4,6,30)
df = self . fetch_runinfo ( range ( 31 ) , quiet = True )
sys . stdout . flush ( )
# # if not ipyclient then use multiprocessing
if ipyclient :
    lb = ipyclient . load_balanced_view ( )
# # if Run has samples with same name ( replicates ) then
# # we need to include the accessions in the file names
if name_fields : # # indexing requires - 1 ints
    fields = [ int ( i ) - 1 for i in fields_checker ( name_fields ) ]
    # # make accession names , no spaces allowed
    df [ 'Accession' ] = pd . Series ( df [ df . columns [ fields [ 0 ] ] ] , index = df . index )
    for field in fields [ 1 : ] :
        df . Accession += name_separator + df [ df . columns [ field ] ]
    df . Accession = [ i . replace ( " " , "_" ) for i in df . Accession ]
    # # check that names are unique
    if not df . Accession . shape [ 0 ] == df . Accession . unique ( ) . shape [ 0 ] :
        raise IPyradWarningExit ( "names are not unique:\n{}" . format ( df . Accession ) )
# # backup default naming scheme
else :
    if len ( set ( df . SampleName ) ) != len ( df . SampleName ) :
        accs = ( i + "-" + j for i , j in zip ( df . SampleName , df . Run ) )
        df . Accession = accs
    else :
        df . Accession = df . SampleName
if dry_run :
    print ( "\rThe following files will be written to: {}" . format ( self . workdir ) )
    print ( "{}\n" . format ( df . Accession ) )
else : # # iterate over and download
    asyncs = [ ]
    for idx in df . index : # # get args for this run
        srr = df . Run [ idx ]
        outname = df . Accession [ idx ]
        paired = df . spots_with_mates . values . astype ( int ) . nonzero ( ) [ 0 ] . any ( )
        fpath = os . path . join ( self . workdir , outname + ".fastq.gz" )
        # # skip if exists and not force
        skip = False
        if force :
            if os . path . exists ( fpath ) :
                os . remove ( fpath )
        else :
            if os . path . exists ( fpath ) :
                skip = True
                sys . stdout . flush ( )
                print ( "[skip] file already exists: {}" . format ( fpath ) )
        # # single job progress bar
        tidx = df . Accession . shape [ 0 ]
        # if not ipyclient :
        # # submit job to run
        if not skip :
            args = ( self , srr , outname , paired )
            if ipyclient :
                async = lb . apply_async ( call_fastq_dump_on_SRRs , * args )
                asyncs . append ( async )
            else :
                print ( "Downloading file {}/{}: {}" . format ( idx + 1 , tidx , fpath ) )
                call_fastq_dump_on_SRRs ( * args )
                sys . stdout . flush ( )
    # # progress bar while blocking parallel
    if ipyclient :
        tots = df . Accession . shape [ 0 ]
        printstr = " Downloading fastq files | {} | "
        start = time . time ( )
        while 1 :
            elapsed = datetime . timedelta ( seconds = int ( time . time ( ) - start ) )
            ready = sum ( [ i . ready ( ) for i in asyncs ] )
            progressbar ( tots , ready , printstr . format ( elapsed ) , spacer = "" )
            time . sleep ( 0.1 )
            if tots == ready :
                print ( "" )
                break
        self . _report ( tots )
        # # check for fails
        for async in asyncs :
            if not async . successful ( ) :
                raise IPyradWarningExit ( async . result ( ) )


signature:
def fetch_runinfo ( self , fields = None , quiet = False ) :
    """Call esearch to grep SRR info for a project ( SRP ) . Use the command
 sra . fetch _ fields to see available fields to be fetched . This function
 returns a DataFrame with runinfo for the selected fields .
 Parameters :
 Fields : ( tuple or list )
 The default fields returned are 1-30 . You can enter a list
 or tuple of fewer numbers to select fewer fields . Example ,
 (1,4,6,29,30 ) returns a neat dataframe with Run IDs ,
 Number of reads ( SE and PE ) , ScientificName , and SampleName ."""

implementation:
if not quiet :
    print ( "\rFetching project data..." , end = "" )
# # if no entry then fetch ( nearly ) all fields .
if fields == None :
    fields = range ( 30 )
fields = fields_checker ( fields )
# # command strings
es_cmd = [ "esearch" , "-db" , "sra" , "-query" , self . accession , ]
ef_cmd = [ "efetch" , "--format" , "runinfo" , ]
cut_cmd = [ "cut" , "-d" , "," , "-f" , "," . join ( fields ) , ]
# # pipe commands together
proc1 = sps . Popen ( es_cmd , stderr = sps . STDOUT , stdout = sps . PIPE )
proc2 = sps . Popen ( ef_cmd , stdin = proc1 . stdout , stderr = sps . STDOUT , stdout = sps . PIPE )
proc3 = sps . Popen ( cut_cmd , stdin = proc2 . stdout , stderr = sps . STDOUT , stdout = sps . PIPE )
o , e = proc3 . communicate ( )
proc2 . stdout . close ( )
proc1 . stdout . close ( )
if o :
    vals = o . strip ( ) . split ( "\n" )
    names = vals [ 0 ] . split ( "," )
    items = [ i . split ( "," ) for i in vals [ 1 : ] if i not in [ "" , vals [ 0 ] ] ]
    return pd . DataFrame ( items , columns = names )
else :
    raise IPyradWarningExit ( "no samples found in {}" . format ( self . accession ) )


signature:
def Async ( cls , token , session = None , ** options ) :
    """Returns the client in async mode ."""

implementation: return cls ( token , session = session , is_async = True , ** options )


signature:
def get_constants ( self , ** params : keys ) :
    """Get the CR Constants
 Parameters
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CONSTANTS
return self . _get_model ( url , ** params )


signature:
def get_player ( self , * tags : crtag , ** params : keys ) :
    """Get a player information
 Parameters
 \*tags: str
 Valid player tags . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + ',' . join ( tags )
return self . _get_model ( url , FullPlayer , ** params )


signature:
def get_player_verify ( self , tag : crtag , apikey : str , ** params : keys ) :
    """Check the API Key of a player .
 This endpoint has been * * restricted * * to
 certain members of the community
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 apikey : str
 The API Key in the player ' s settings
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + tag + '/verify'
params . update ( { 'token' : apikey } )
return self . _get_model ( url , FullPlayer , ** params )


signature:
def get_player_battles ( self , * tags : crtag , ** params : keys ) :
    """Get a player ' s battle log
 Parameters
 \*tags: str
 Valid player tags . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + ',' . join ( tags ) + '/battles'
return self . _get_model ( url , ** params )


signature:
def get_clan ( self , * tags : crtag , ** params : keys ) :
    """Get a clan information
 Parameters
 \*tags: str
 Valid clan tags . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN + '/' + ',' . join ( tags )
return self . _get_model ( url , FullClan , ** params )


signature:
def get_tracking_clans ( self , ** params : keys ) :
    """Get a list of clans that are being
 tracked by having either cr - api . com or
 royaleapi . com in the description
 Parameters
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN + '/tracking'
return self . _get_model ( url , ** params )


signature:
def get_clan_tracking ( self , * tags : crtag , ** params : keys ) :
    """Returns if the clan is currently being tracked
 by the API by having either cr - api . com or royaleapi . com
 in the clan description
 Parameters
 \*tags: str
 Valid clan tags . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN + '/' + ',' . join ( tags ) + '/tracking'
return self . _get_model ( url , ** params )


signature:
def get_clan_war ( self , tag : crtag , ** params : keys ) :
    """Get inforamtion about a clan ' s current clan war
 Parameters
 * tag : str
 A valid clan tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN + '/' + tag + '/war'
return self . _get_model ( url , ** params )


signature:
def get_tournament ( self , tag : crtag , ** params : keys ) :
    """Get a tournament information
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOURNAMENT + '/' + tag
return self . _get_model ( url , ** params )


signature:
def search_tournaments ( self , ** params : keys ) :
    """Search for a tournament
 Parameters
 name : str
 The name of the tournament
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOURNAMENT + '/search'
return self . _get_model ( url , PartialClan , ** params )


signature:
def get_top_war_clans ( self , country_key = '' , ** params : keys ) :
    """Get a list of top clans by war
 location _ id : Optional [ str ] = ' '
 A location ID or ' ' ( global )
 See https : / / github . com / RoyaleAPI / cr - api - data / blob / master / json / regions . json
 for a list of acceptable location IDs
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOP + '/war/' + str ( country_key )
return self . _get_model ( url , PartialClan , ** params )


signature:
def get_top_players ( self , country_key = '' , ** params : keys ) :
    """Get a list of top players
 location _ id : Optional [ str ] = ' '
 A location ID or ' ' ( global )
 See https : / / github . com / RoyaleAPI / cr - api - data / blob / master / json / regions . json
 for a list of acceptable location IDs
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOP + '/players/' + str ( country_key )
return self . _get_model ( url , PartialPlayerClan , ** params )


signature:
def get_popular_clans ( self , ** params : keys ) :
    """Get a list of most queried clans
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . POPULAR + '/clans'
return self . _get_model ( url , PartialClan , ** params )


signature:
def get_popular_players ( self , ** params : keys ) :
    """Get a list of most queried players
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . POPULAR + '/players'
return self . _get_model ( url , PartialPlayerClan , ** params )


signature:
def get_popular_tournaments ( self , ** params : keys ) :
    """Get a list of most queried tournaments
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . POPULAR + '/tournament'
return self . _get_model ( url , PartialTournament , ** params )


signature:
def get_popular_decks ( self , ** params : keys ) :
    """Get a list of most queried decks
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . POPULAR + '/decks'
return self . _get_model ( url , ** params )


signature:
def get_known_tournaments ( self , ** params : tournamentfilter ) :
    """Get a list of queried tournaments
 \*\*keys: Optional[list] = None
 Filter which keys should be included in the
 response
 \*\*exclude: Optional[list] = None
 Filter which keys should be excluded from the
 response
 \*\*max: Optional[int] = None
 Limit the number of items returned in the response
 \*\*page: Optional[int] = None
 Works with max , the zero - based page of the
 items
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOURNAMENT + '/known'
return self . _get_model ( url , PartialTournament , ** params )


signature:
def get_player ( self , tag : crtag , timeout = None ) :
    """Get information about a player
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + tag
return self . _get_model ( url , FullPlayer , timeout = timeout )


signature:
def get_player_verify ( self , tag : crtag , apikey : str , timeout = None ) :
    """Check the API Key of a player .
 This endpoint has been * * restricted * * to
 certain members of the community
 Raises BadRequest if the apikey is invalid
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 apikey : str
 The API Key in the player ' s settings
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + tag + '/verifytoken'
return self . _get_model ( url , FullPlayer , timeout = timeout , method = 'POST' , json = { 'token' : apikey } )


signature:
def get_player_battles ( self , tag : crtag , ** params : keys ) :
    """Get a player ' s battle log
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*limit: Optional[int] = None
 Limit the number of items returned in the response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + tag + '/battlelog'
return self . _get_model ( url , ** params )


signature:
def get_player_chests ( self , tag : crtag , timeout : int = None ) :
    """Get information about a player ' s chest cycle
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . PLAYER + '/' + tag + '/upcomingchests'
return self . _get_model ( url , timeout = timeout )


signature:
def get_clan ( self , tag : crtag , timeout : int = None ) :
    """Get inforamtion about a clan
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN + '/' + tag
return self . _get_model ( url , FullClan , timeout = timeout )


signature:
def search_clans ( self , ** params : clansearch ) :
    """Search for a clan . At least one
 of the filters must be present
 Parameters
 name : Optional [ str ]
 The name of a clan
 ( has to be at least 3 characters long )
 locationId : Optional [ int ]
 A location ID
 minMembers : Optional [ int ]
 The minimum member count
 of a clan
 maxMembers : Optional [ int ]
 The maximum member count
 of a clan
 minScore : Optional [ int ]
 The minimum trophy score of
 a clan
 \*\*limit: Optional[int] = None
 Limit the number of items returned in the response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN
return self . _get_model ( url , PartialClan , ** params )


signature:
def get_clan_war ( self , tag : crtag , timeout : int = None ) :
    """Get inforamtion about a clan ' s current clan war
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CLAN + '/' + tag + '/currentwar'
return self . _get_model ( url , timeout = timeout )


signature:
def get_tournament ( self , tag : crtag , timeout = 0 ) :
    """Get a tournament information
 Parameters
 tag : str
 A valid tournament tag . Minimum length : 3
 Valid characters : 0289PYLQGRJCUV
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOURNAMENT + '/' + tag
return self . _get_model ( url , PartialTournament , timeout = timeout )


signature:
def search_tournaments ( self , name : str , ** params : keys ) :
    """Search for a tournament by its name
 Parameters
 name : str
 The name of a tournament
 \*\*limit: Optional[int] = None
 Limit the number of items returned in the response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . TOURNAMENT
params [ 'name' ] = name
return self . _get_model ( url , PartialTournament , ** params )


signature:
def get_all_cards ( self , timeout : int = None ) :
    """Get a list of all the cards in the game
 Parameters
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . CARDS
return self . _get_model ( url , timeout = timeout )


signature:
def get_all_locations ( self , timeout : int = None ) :
    """Get a list of all locations
 Parameters
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . LOCATIONS
return self . _get_model ( url , timeout = timeout )


signature:
def get_location ( self , location_id : int , timeout : int = None ) :
    """Get a location information
 Parameters
 location _ id : int
 A location ID
 See https : / / github . com / RoyaleAPI / cr - api - data / blob / master / json / regions . json
 for a list of acceptable location IDs
 timeout : Optional [ int ] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . LOCATIONS + '/' + str ( location_id )
return self . _get_model ( url , timeout = timeout )


signature:
def get_top_clans ( self , location_id = 'global' , ** params : keys ) :
    """Get a list of top clans by trophy
 Parameters
 location _ id : Optional [ str ] = ' global '
 A location ID or global
 See https : / / github . com / RoyaleAPI / cr - api - data / blob / master / json / regions . json
 for a list of acceptable location IDs
 \*\*limit: Optional[int] = None
 Limit the number of items returned in the response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . LOCATIONS + '/' + str ( location_id ) + '/rankings/clans'
return self . _get_model ( url , PartialClan , ** params )


signature:
def get_top_players ( self , location_id = 'global' , ** params : keys ) :
    """Get a list of top players
 Parameters
 location _ id : Optional [ str ] = ' global '
 A location ID or global
 See https : / / github . com / RoyaleAPI / cr - api - data / blob / master / json / regions . json
 for a list of acceptable location IDs
 \*\*limit: Optional[int] = None
 Limit the number of items returned in the response
 \*\*timeout: Optional[int] = None
 Custom timeout that overwrites Client . timeout"""

implementation:
url = self . api . LOCATIONS + '/' + str ( location_id ) + '/rankings/players'
return self . _get_model ( url , PartialPlayerClan , ** params )


signature:
def get_clan_image ( self , obj : BaseAttrDict ) :
    """Get the clan badge image URL
 Parameters
 obj : official _ api . models . BaseAttrDict
 An object that has the clan badge ID either in ` ` . clan . badge _ id ` ` or ` ` . badge _ id ` `
 Can be a clan or a profile for example .
 Returns str"""

implementation:
try :
    badge_id = obj . clan . badge_id
except AttributeError :
    try :
        badge_id = obj . badge_id
    except AttributeError :
        return 'https://i.imgur.com/Y3uXsgj.png'
if badge_id is None :
    return 'https://i.imgur.com/Y3uXsgj.png'
for i in self . constants . alliance_badges :
    if i . id == badge_id :
        return 'https://royaleapi.github.io/cr-api-assets/badges/' + i . name + '.png'


signature:
def get_arena_image ( self , obj : BaseAttrDict ) :
    """Get the arena image URL
 Parameters
 obj : official _ api . models . BaseAttrDict
 An object that has the arena ID in ` ` . arena . id ` `
 Can be ` ` Profile ` ` for example .
 Returns None or str"""

implementation:
badge_id = obj . arena . id
for i in self . constants . arenas :
    if i . id == badge_id :
        return 'https://royaleapi.github.io/cr-api-assets/arenas/arena{}.png' . format ( i . arena_id )


signature:
def get_card_info ( self , card_name : str ) :
    """Returns card info from constants
 Parameters
 card _ name : str
 A card name
 Returns None or Constants"""

implementation:
for c in self . constants . cards :
    if c . name == card_name :
        return c


signature:
def get_rarity_info ( self , rarity : str ) :
    """Returns card info from constants
 Parameters
 rarity : str
 A rarity name
 Returns None or Constants"""

implementation:
for c in self . constants . rarities :
    if c . name == rarity :
        return c


signature:
def get_deck_link ( self , deck : BaseAttrDict ) :
    """Form a deck link
 Parameters
 deck : official _ api . models . BaseAttrDict
 An object is a deck . Can be retrieved from ` ` Player . current _ deck ` `
 Returns str"""

implementation:
deck_link = 'https://link.clashroyale.com/deck/en?deck='
for i in deck :
    card = self . get_card_info ( i . name )
    deck_link += '{0.id};' . format ( card )
return deck_link


signature:
def get_datetime ( self , timestamp : str , unix = True ) :
    """Converts a % Y % m % dT % H % M % S . % fZ to a UNIX timestamp
 or a datetime . datetime object
 Parameters
 timestamp : str
 A timstamp in the % Y % m % dT % H % M % S . % fZ format , usually returned by the API
 in the ` ` created _ time ` ` field for example ( eg . 20180718T145906.000Z )
 unix : Optional [ bool ] = True
 Whether to return a POSIX timestamp ( seconds since epoch ) or not
 Returns int or datetime . datetime"""

implementation:
time = datetime . strptime ( timestamp , '%Y%m%dT%H%M%S.%fZ' )
if unix :
    return int ( time . timestamp ( ) )
else :
    return time


signature:
def get_clan ( self ) :
    """( a ) sync function to return clan ."""

implementation:
try :
    return self . client . get_clan ( self . clan . tag )
except AttributeError :
    try :
        return self . client . get_clan ( self . tag )
    except AttributeError :
        raise ValueError ( 'This player does not have a clan.' )


signature:
def refresh ( self ) :
    """( a ) sync refresh the data ."""

implementation:
if self . client . is_async :
    return self . _arefresh ( )
data , cached , ts , response = self . client . _request ( self . response . url , timeout = None , refresh = True )
return self . from_data ( data , cached , ts , response )


signature:
def typecasted ( func ) :
    """Decorator that converts arguments via annotations ."""

implementation:
signature = inspect . signature ( func ) . parameters . items ( )
@ wraps ( func )
def wrapper ( * args , ** kwargs ) :
    args = list ( args )
    new_args = [ ]
    new_kwargs = { }
    for _ , param in signature :
        converter = param . annotation
        if converter is inspect . _empty :
            converter = lambda a : a
            # do nothing
        if param . kind is param . POSITIONAL_OR_KEYWORD :
            if args :
                to_conv = args . pop ( 0 )
                new_args . append ( converter ( to_conv ) )
        elif param . kind is param . VAR_POSITIONAL :
            for a in args :
                new_args . append ( converter ( a ) )
        else :
            for k , v in kwargs . items ( ) :
                nk , nv = converter ( k , v )
                new_kwargs [ nk ] = nv
    return func ( * new_args , ** new_kwargs )
return wrapper


signature:
def coerce_annotation ( ann , namespace ) :
    '''Validate that the annotation has the correct namespace ,
 and is well - formed .
 If the annotation is not of the correct namespace , automatic conversion
 is attempted .
 Parameters
 ann : jams . Annotation
 The annotation object in question
 namespace : str
 The namespace pattern to match ` ann ` against
 Returns
 ann _ coerced : jams . Annotation
 The annotation coerced to the target namespace
 Raises
 NamespaceError
 If ` ann ` does not match the proper namespace
 SchemaError
 If ` ann ` fails schema validation
 See Also
 jams . nsconvert . convert'''

implementation:
ann = convert ( ann , namespace )
ann . validate ( strict = True )
return ann


signature:
def beat ( ref , est , ** kwargs ) :
    r'''Beat tracking evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . beat . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations
 > > > ref _ ann = ref _ jam . search ( namespace = ' beat ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' beat ' ) [ 0]
 > > > scores = jams . eval . beat ( ref _ ann , est _ ann )'''

implementation:
namespace = 'beat'
ref = coerce_annotation ( ref , namespace )
est = coerce_annotation ( est , namespace )
ref_times , _ = ref . to_event_values ( )
est_times , _ = est . to_event_values ( )
return mir_eval . beat . evaluate ( ref_times , est_times , ** kwargs )


signature:
def chord ( ref , est , ** kwargs ) :
    r'''Chord evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . chord . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations
 > > > ref _ ann = ref _ jam . search ( namespace = ' chord ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' chord ' ) [ 0]
 > > > scores = jams . eval . chord ( ref _ ann , est _ ann )'''

implementation:
namespace = 'chord'
ref = coerce_annotation ( ref , namespace )
est = coerce_annotation ( est , namespace )
ref_interval , ref_value = ref . to_interval_values ( )
est_interval , est_value = est . to_interval_values ( )
return mir_eval . chord . evaluate ( ref_interval , ref_value , est_interval , est_value , ** kwargs )


signature:
def hierarchy_flatten ( annotation ) :
    '''Flatten a multi _ segment annotation into mir _ eval style .
 Parameters
 annotation : jams . Annotation
 An annotation in the ` multi _ segment ` namespace
 Returns
 hier _ intervalss : list
 A list of lists of intervals , ordered by increasing specificity .
 hier _ labels : list
 A list of lists of labels , ordered by increasing specificity .'''

implementation:
intervals , values = annotation . to_interval_values ( )
ordering = dict ( )
for interval , value in zip ( intervals , values ) :
    level = value [ 'level' ]
    if level not in ordering :
        ordering [ level ] = dict ( intervals = list ( ) , labels = list ( ) )
    ordering [ level ] [ 'intervals' ] . append ( interval )
    ordering [ level ] [ 'labels' ] . append ( value [ 'label' ] )
levels = sorted ( list ( ordering . keys ( ) ) )
hier_intervals = [ ordering [ level ] [ 'intervals' ] for level in levels ]
hier_labels = [ ordering [ level ] [ 'labels' ] for level in levels ]
return hier_intervals , hier_labels


signature:
def hierarchy ( ref , est , ** kwargs ) :
    r'''Multi - level segmentation evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . hierarchy . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations
 > > > ref _ ann = ref _ jam . search ( namespace = ' multi _ segment ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' multi _ segment ' ) [ 0]
 > > > scores = jams . eval . hierarchy ( ref _ ann , est _ ann )'''

implementation:
namespace = 'multi_segment'
ref = coerce_annotation ( ref , namespace )
est = coerce_annotation ( est , namespace )
ref_hier , ref_hier_lab = hierarchy_flatten ( ref )
est_hier , est_hier_lab = hierarchy_flatten ( est )
return mir_eval . hierarchy . evaluate ( ref_hier , ref_hier_lab , est_hier , est_hier_lab , ** kwargs )


signature:
def tempo ( ref , est , ** kwargs ) :
    r'''Tempo evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . tempo . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations
 > > > ref _ ann = ref _ jam . search ( namespace = ' tempo ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' tempo ' ) [ 0]
 > > > scores = jams . eval . tempo ( ref _ ann , est _ ann )'''

implementation:
ref = coerce_annotation ( ref , 'tempo' )
est = coerce_annotation ( est , 'tempo' )
ref_tempi = np . asarray ( [ o . value for o in ref ] )
ref_weight = ref . data [ 0 ] . confidence
est_tempi = np . asarray ( [ o . value for o in est ] )
return mir_eval . tempo . evaluate ( ref_tempi , ref_weight , est_tempi , ** kwargs )


signature:
def melody ( ref , est , ** kwargs ) :
    r'''Melody extraction evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . melody . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations
 > > > ref _ ann = ref _ jam . search ( namespace = ' pitch _ contour ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' pitch _ contour ' ) [ 0]
 > > > scores = jams . eval . melody ( ref _ ann , est _ ann )'''

implementation:
namespace = 'pitch_contour'
ref = coerce_annotation ( ref , namespace )
est = coerce_annotation ( est , namespace )
ref_times , ref_p = ref . to_event_values ( )
est_times , est_p = est . to_event_values ( )
ref_freq = np . asarray ( [ p [ 'frequency' ] * ( - 1 ) ** ( ~ p [ 'voiced' ] ) for p in ref_p ] )
est_freq = np . asarray ( [ p [ 'frequency' ] * ( - 1 ) ** ( ~ p [ 'voiced' ] ) for p in est_p ] )
return mir_eval . melody . evaluate ( ref_times , ref_freq , est_times , est_freq , ** kwargs )


signature:
def pattern_to_mireval ( ann ) :
    '''Convert a pattern _ jku annotation object to mir _ eval format .
 Parameters
 ann : jams . Annotation
 Must have ` namespace = ' pattern _ jku ' `
 Returns
 patterns : list of list of tuples
 - ` patterns [ x ] ` is a list containing all occurrences of pattern x
 - ` patterns [ x ] [ y ] ` is a list containing all notes for
 occurrence y of pattern x
 - ` patterns [ x ] [ y ] [ z ] ` contains a time - note tuple
 ` ( time , midi note ) `'''

implementation:
# It ' s easier to work with dictionaries , since we can ' t assume
# sequential pattern or occurrence identifiers
patterns = defaultdict ( lambda : defaultdict ( list ) )
# Iterate over the data in interval - value format
for time , observation in zip ( * ann . to_event_values ( ) ) :
    pattern_id = observation [ 'pattern_id' ]
    occurrence_id = observation [ 'occurrence_id' ]
    obs = ( time , observation [ 'midi_pitch' ] )
    # Push this note observation into the correct pattern / occurrence
    patterns [ pattern_id ] [ occurrence_id ] . append ( obs )
# Convert to list - list - tuple format for mir _ eval
return [ list ( _ . values ( ) ) for _ in six . itervalues ( patterns ) ]


signature:
def pattern ( ref , est , ** kwargs ) :
    r'''Pattern detection evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . pattern . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations
 > > > ref _ ann = ref _ jam . search ( namespace = ' pattern _ jku ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' pattern _ jku ' ) [ 0]
 > > > scores = jams . eval . pattern ( ref _ ann , est _ ann )'''

implementation:
namespace = 'pattern_jku'
ref = coerce_annotation ( ref , namespace )
est = coerce_annotation ( est , namespace )
ref_patterns = pattern_to_mireval ( ref )
est_patterns = pattern_to_mireval ( est )
return mir_eval . pattern . evaluate ( ref_patterns , est_patterns , ** kwargs )


signature:
def transcription ( ref , est , ** kwargs ) :
    r'''Note transcription evaluation
 Parameters
 ref : jams . Annotation
 Reference annotation object
 est : jams . Annotation
 Estimated annotation object
 kwargs
 Additional keyword arguments
 Returns
 scores : dict
 Dictionary of scores , where the key is the metric name ( str ) and
 the value is the ( float ) score achieved .
 See Also
 mir _ eval . transcription . evaluate
 Examples
 > > > # Load in the JAMS objects
 > > > ref _ jam = jams . load ( ' reference . jams ' )
 > > > est _ jam = jams . load ( ' estimated . jams ' )
 > > > # Select the first relevant annotations . You can use any annotation
 > > > # type that can be converted to pitch _ contour ( such as pitch _ midi )
 > > > ref _ ann = ref _ jam . search ( namespace = ' pitch _ contour ' ) [ 0]
 > > > est _ ann = est _ jam . search ( namespace = ' note _ hz ' ) [ 0]
 > > > scores = jams . eval . transcription ( ref _ ann , est _ ann )'''

implementation:
namespace = 'pitch_contour'
ref = coerce_annotation ( ref , namespace )
est = coerce_annotation ( est , namespace )
ref_intervals , ref_p = ref . to_interval_values ( )
est_intervals , est_p = est . to_interval_values ( )
ref_pitches = np . asarray ( [ p [ 'frequency' ] * ( - 1 ) ** ( ~ p [ 'voiced' ] ) for p in ref_p ] )
est_pitches = np . asarray ( [ p [ 'frequency' ] * ( - 1 ) ** ( ~ p [ 'voiced' ] ) for p in est_p ] )
return mir_eval . transcription . evaluate ( ref_intervals , ref_pitches , est_intervals , est_pitches , ** kwargs )


signature:
def add_namespace ( filename ) :
    '''Add a namespace definition to our working set .
 Namespace files consist of partial JSON schemas defining the behavior
 of the ` value ` and ` confidence ` fields of an Annotation .
 Parameters
 filename : str
 Path to json file defining the namespace object'''

implementation:
with open ( filename , mode = 'r' ) as fileobj :
    __NAMESPACE__ . update ( json . load ( fileobj ) )


signature:
def namespace ( ns_key ) :
    '''Construct a validation schema for a given namespace .
 Parameters
 ns _ key : str
 Namespace key identifier ( eg , ' beat ' or ' segment _ tut ' )
 Returns
 schema : dict
 JSON schema of ` namespace `'''

implementation:
if ns_key not in __NAMESPACE__ :
    raise NamespaceError ( 'Unknown namespace: {:s}' . format ( ns_key ) )
sch = copy . deepcopy ( JAMS_SCHEMA [ 'definitions' ] [ 'SparseObservation' ] )
for key in [ 'value' , 'confidence' ] :
    try :
        sch [ 'properties' ] [ key ] = __NAMESPACE__ [ ns_key ] [ key ]
    except KeyError :
        pass
return sch


signature:
def namespace_array ( ns_key ) :
    '''Construct a validation schema for arrays of a given namespace .
 Parameters
 ns _ key : str
 Namespace key identifier
 Returns
 schema : dict
 JSON schema of ` namespace ` observation arrays'''

implementation:
obs_sch = namespace ( ns_key )
obs_sch [ 'title' ] = 'Observation'
sch = copy . deepcopy ( JAMS_SCHEMA [ 'definitions' ] [ 'SparseObservationList' ] )
sch [ 'items' ] = obs_sch
return sch