def all_collections(self, collid=None):
        """
        Retrieve all collections and subcollections. Works for top-level collections
        or for a specific collection. Works at all collection depths.
        """
        all_collections = []

        def subcoll(clct):
            """ recursively add collections to a flat master list """
            all_collections.append(clct)
            if clct["meta"].get("numCollections", 0) > 0:
                # add collection to master list & recur with all child
                # collections
                [
                    subcoll(c)
                    for c in self.everything(self.collections_sub(clct["data"]["key"]))
                ]

        # select all top-level collections or a specific collection and
        # children
        if collid:
            toplevel = [self.collection(collid)]
        else:
            toplevel = self.everything(self.collections_top())
        [subcoll(collection) for collection in toplevel]
        return all_collections

def all_collections ( self , collid = None ) : all_collections = [ ] def subcoll ( clct ) : all_collections . append ( clct ) if clct [ "meta" ] . get ( "numCollections" , 0 ) > 0 : [ subcoll ( c ) for c in self . everything ( self . collections_sub ( clct [ "data" ] [ "key" ] ) ) ] if collid : toplevel = [ self . collection ( collid ) ] else : toplevel = self . everything ( self . collections_top ( ) ) [ subcoll ( collection ) for collection in toplevel ] return all_collections

Retrieve all collections and subcollections . Works for top - level collections or for a specific collection . Works at all collection depths .


def collections_sub(self, collection, **kwargs):
        """ Get subcollections for a specific collection
        """
        query_string = "/{t}/{u}/collections/{c}/collections".format(
            u=self.library_id, t=self.library_type, c=collection.upper()
        )
        return self._build_query(query_string)

def collections_sub ( self , collection , ** kwargs ) : query_string = "/{t}/{u}/collections/{c}/collections" . format ( u = self . library_id , t = self . library_type , c = collection . upper ( ) ) return self . _build_query ( query_string )


def everything(self, query):
        """
        Retrieve all items in the library for a particular query
        This method will override the 'limit' parameter if it's been set
        """
        try:
            items = []
            items.extend(query)
            while self.links.get("next"):
                items.extend(self.follow())
        except TypeError:
            # we have a bibliography object ughh
            items = copy.deepcopy(query)
            while self.links.get("next"):
                items.entries.extend(self.follow().entries)
        return items

def everything ( self , query ) : try : items = [ ] items . extend ( query ) while self . links . get ( "next" ) : items . extend ( self . follow ( ) ) except TypeError : items = copy . deepcopy ( query ) while self . links . get ( "next" ) : items . entries . extend ( self . follow ( ) . entries ) return items

Retrieve all items in the library for a particular query This method will override the limit parameter if it s been set


def _json_processor(self, retrieved):
        """ Format and return data from API calls which return Items
        """
        json_kwargs = {}
        if self.preserve_json_order:
            json_kwargs["object_pairs_hook"] = OrderedDict
        # send entries to _tags_data if there's no JSON
        try:
            items = [
                json.loads(e["content"][0]["value"], **json_kwargs)
                for e in retrieved.entries
            ]
        except KeyError:
            return self._tags_data(retrieved)
        return items

def _json_processor ( self , retrieved ) : json_kwargs = { } if self . preserve_json_order : json_kwargs [ "object_pairs_hook" ] = OrderedDict try : items = [ json . loads ( e [ "content" ] [ 0 ] [ "value" ] , ** json_kwargs ) for e in retrieved . entries ] except KeyError : return self . _tags_data ( retrieved ) return items


def _csljson_processor(self, retrieved):
        """ Return a list of dicts which are dumped CSL JSON
        """
        items = []
        json_kwargs = {}
        if self.preserve_json_order:
            json_kwargs["object_pairs_hook"] = OrderedDict
        for csl in retrieved.entries:
            items.append(json.loads(csl["content"][0]["value"], **json_kwargs))
        self.url_params = None
        return items

def _csljson_processor ( self , retrieved ) : items = [ ] json_kwargs = { } if self . preserve_json_order : json_kwargs [ "object_pairs_hook" ] = OrderedDict for csl in retrieved . entries : items . append ( json . loads ( csl [ "content" ] [ 0 ] [ "value" ] , ** json_kwargs ) ) self . url_params = None return items


def _bib_processor(self, retrieved):
        """ Return a list of strings formatted as HTML bibliography entries
        """
        items = []
        for bib in retrieved.entries:
            items.append(bib["content"][0]["value"])
        self.url_params = None
        return items

def _bib_processor ( self , retrieved ) : items = [ ] for bib in retrieved . entries : items . append ( bib [ "content" ] [ 0 ] [ "value" ] ) self . url_params = None return items


def _citation_processor(self, retrieved):
        """ Return a list of strings formatted as HTML citation entries
        """
        items = []
        for cit in retrieved.entries:
            items.append(cit["content"][0]["value"])
        self.url_params = None
        return items

def _citation_processor ( self , retrieved ) : items = [ ] for cit in retrieved . entries : items . append ( cit [ "content" ] [ 0 ] [ "value" ] ) self . url_params = None return items


def item_template(self, itemtype):
        """ Get a template for a new item
        """
        # if we have a template and it hasn't been updated since we stored it
        template_name = "item_template_" + itemtype
        query_string = "/items/new?itemType={i}".format(i=itemtype)
        if self.templates.get(template_name) and not self._updated(
            query_string, self.templates[template_name], template_name
        ):
            return copy.deepcopy(self.templates[template_name]["tmplt"])
        # otherwise perform a normal request and cache the response
        retrieved = self._retrieve_data(query_string)
        return self._cache(retrieved, template_name)

def item_template ( self , itemtype ) : template_name = "item_template_" + itemtype query_string = "/items/new?itemType={i}" . format ( i = itemtype ) if self . templates . get ( template_name ) and not self . _updated ( query_string , self . templates [ template_name ] , template_name ) : return copy . deepcopy ( self . templates [ template_name ] [ "tmplt" ] ) retrieved = self . _retrieve_data ( query_string ) return self . _cache ( retrieved , template_name )


def _attachment(self, payload, parentid=None):
        """
        Create attachments
        accepts a list of one or more attachment template dicts
        and an optional parent Item ID. If this is specified,
        attachments are created under this ID
        """
        attachment = Zupload(self, payload, parentid)
        res = attachment.upload()
        return res

def _attachment ( self , payload , parentid = None ) : attachment = Zupload ( self , payload , parentid ) res = attachment . upload ( ) return res

Create attachments accepts a list of one or more attachment template dicts and an optional parent Item ID . If this is specified attachments are created under this ID


def show_condition_operators(self, condition):
        """ Show available operators for a given saved search condition """
        # dict keys of allowed operators for the current condition
        permitted_operators = self.savedsearch.conditions_operators.get(condition)
        # transform these into values
        permitted_operators_list = set(
            [self.savedsearch.operators.get(op) for op in permitted_operators]
        )
        return permitted_operators_list

def show_condition_operators ( self , condition ) : permitted_operators = self . savedsearch . conditions_operators . get ( condition ) permitted_operators_list = set ( [ self . savedsearch . operators . get ( op ) for op in permitted_operators ] ) return permitted_operators_list


def delete_saved_search(self, keys):
        """ Delete one or more saved searches by passing a list of one or more
        unique search keys
        """
        headers = {"Zotero-Write-Token": token()}
        headers.update(self.default_headers())
        req = requests.delete(
            url=self.endpoint
            + "/{t}/{u}/searches".format(t=self.library_type, u=self.library_id),
            headers=headers,
            params={"searchKey": ",".join(keys)},
        )
        self.request = req
        try:
            req.raise_for_status()
        except requests.exceptions.HTTPError:
            error_handler(req)
        return req.status_code

def delete_saved_search ( self , keys ) : headers = { "Zotero-Write-Token" : token ( ) } headers . update ( self . default_headers ( ) ) req = requests . delete ( url = self . endpoint + "/{t}/{u}/searches" . format ( t = self . library_type , u = self . library_id ) , headers = headers , params = { "searchKey" : "," . join ( keys ) } , ) self . request = req try : req . raise_for_status ( ) except requests . exceptions . HTTPError : error_handler ( req ) return req . status_code


def add_tags(self, item, *tags):
        """
        Add one or more tags to a retrieved item,
        then update it on the server
        Accepts a dict, and one or more tags to add to it
        Returns the updated item from the server
        """
        # Make sure there's a tags field, or add one
        try:
            assert item["data"]["tags"]
        except AssertionError:
            item["data"]["tags"] = list()
        for tag in tags:
            item["data"]["tags"].append({"tag": "%s" % tag})
        # make sure everything's OK
        assert self.check_items([item])
        return self.update_item(item)

def add_tags ( self , item , * tags ) : try : assert item [ "data" ] [ "tags" ] except AssertionError : item [ "data" ] [ "tags" ] = list ( ) for tag in tags : item [ "data" ] [ "tags" ] . append ( { "tag" : "%s" % tag } ) assert self . check_items ( [ item ] ) return self . update_item ( item )

Add one or more tags to a retrieved item then update it on the server Accepts a dict and one or more tags to add to it Returns the updated item from the server


def fields_types(self, tname, qstring, itemtype):
        """ Retrieve item fields or creator types
        """
        # check for a valid cached version
        template_name = tname + itemtype
        query_string = qstring.format(i=itemtype)
        if self.templates.get(template_name) and not self._updated(
            query_string, self.templates[template_name], template_name
        ):
            return self.templates[template_name]["tmplt"]
        # otherwise perform a normal request and cache the response
        retrieved = self._retrieve_data(query_string)
        return self._cache(retrieved, template_name)

def fields_types ( self , tname , qstring , itemtype ) : template_name = tname + itemtype query_string = qstring . format ( i = itemtype ) if self . templates . get ( template_name ) and not self . _updated ( query_string , self . templates [ template_name ] , template_name ) : return self . templates [ template_name ] [ "tmplt" ] retrieved = self . _retrieve_data ( query_string ) return self . _cache ( retrieved , template_name )


def item_fields(self):
        """ Get all available item fields
        """
        # Check for a valid cached version
        if self.templates.get("item_fields") and not self._updated(
            "/itemFields", self.templates["item_fields"], "item_fields"
        ):
            return self.templates["item_fields"]["tmplt"]
        query_string = "/itemFields"
        # otherwise perform a normal request and cache the response
        retrieved = self._retrieve_data(query_string)
        return self._cache(retrieved, "item_fields")

def item_fields ( self ) : if self . templates . get ( "item_fields" ) and not self . _updated ( "/itemFields" , self . templates [ "item_fields" ] , "item_fields" ) : return self . templates [ "item_fields" ] [ "tmplt" ] query_string = "/itemFields" retrieved = self . _retrieve_data ( query_string ) return self . _cache ( retrieved , "item_fields" )


def update_item(self, payload, last_modified=None):
        """
        Update an existing item
        Accepts one argument, a dict containing Item data
        """
        to_send = self.check_items([payload])[0]
        if last_modified is None:
            modified = payload["version"]
        else:
            modified = last_modified
        ident = payload["key"]
        headers = {"If-Unmodified-Since-Version": str(modified)}
        headers.update(self.default_headers())
        req = requests.patch(
            url=self.endpoint
            + "/{t}/{u}/items/{id}".format(
                t=self.library_type, u=self.library_id, id=ident
            ),
            headers=headers,
            data=json.dumps(to_send),
        )
        self.request = req
        try:
            req.raise_for_status()
        except requests.exceptions.HTTPError:
            error_handler(req)
        return True

def update_item ( self , payload , last_modified = None ) : to_send = self . check_items ( [ payload ] ) [ 0 ] if last_modified is None : modified = payload [ "version" ] else : modified = last_modified ident = payload [ "key" ] headers = { "If-Unmodified-Since-Version" : str ( modified ) } headers . update ( self . default_headers ( ) ) req = requests . patch ( url = self . endpoint + "/{t}/{u}/items/{id}" . format ( t = self . library_type , u = self . library_id , id = ident ) , headers = headers , data = json . dumps ( to_send ) , ) self . request = req try : req . raise_for_status ( ) except requests . exceptions . HTTPError : error_handler ( req ) return True

Update an existing item Accepts one argument a dict containing Item data


def update_items(self, payload):
        """
        Update existing items
        Accepts one argument, a list of dicts containing Item data
        """
        to_send = [self.check_items([p])[0] for p in payload]
        headers = {}
        headers.update(self.default_headers())
        # the API only accepts 50 items at a time, so we have to split
        # anything longer
        for chunk in chunks(to_send, 50):
            req = requests.post(
                url=self.endpoint
                + "/{t}/{u}/items/".format(t=self.library_type, u=self.library_id),
                headers=headers,
                data=json.dumps(chunk),
            )
            self.request = req
            try:
                req.raise_for_status()
            except requests.exceptions.HTTPError:
                error_handler(req)
            return True

def update_items ( self , payload ) : to_send = [ self . check_items ( [ p ] ) [ 0 ] for p in payload ] headers = { } headers . update ( self . default_headers ( ) ) for chunk in chunks ( to_send , 50 ) : req = requests . post ( url = self . endpoint + "/{t}/{u}/items/" . format ( t = self . library_type , u = self . library_id ) , headers = headers , data = json . dumps ( chunk ) , ) self . request = req try : req . raise_for_status ( ) except requests . exceptions . HTTPError : error_handler ( req ) return True

Update existing items Accepts one argument a list of dicts containing Item data


def _validate(self, conditions):
        """ Validate saved search conditions, raising an error if any contain invalid operators """
        allowed_keys = set(self.searchkeys)
        operators_set = set(self.operators.keys())
        for condition in conditions:
            if set(condition.keys()) != allowed_keys:
                raise ze.ParamNotPassed(
                    "Keys must be all of: %s" % ", ".join(self.searchkeys)
                )
            if condition.get("operator") not in operators_set:
                raise ze.ParamNotPassed(
                    "You have specified an unknown operator: %s"
                    % condition.get("operator")
                )
            # dict keys of allowed operators for the current condition
            permitted_operators = self.conditions_operators.get(
                condition.get("condition")
            )
            # transform these into values
            permitted_operators_list = set(
                [self.operators.get(op) for op in permitted_operators]
            )
            if condition.get("operator") not in permitted_operators_list:
                raise ze.ParamNotPassed(
                    "You may not use the '%s' operator when selecting the '%s' condition. \nAllowed operators: %s"
                    % (
                        condition.get("operator"),
                        condition.get("condition"),
                        ", ".join(list(permitted_operators_list)),
                    )
                )

Validate saved search conditions raising an error if any contain invalid operators


def upload(self):
        """
        File upload functionality

        Goes through upload steps 0 - 3 (private class methods), and returns
        a dict noting success, failure, or unchanged
        (returning the payload entries with that property as a list for each status)
        """
        result = {"success": [], "failure": [], "unchanged": []}
        self._create_prelim()
        for item in self.payload:
            if "key" not in item:
                result["failure"].append(item)
                continue
            attach = str(self.basedir.joinpath(item["filename"]))
            authdata = self._get_auth(attach, item["key"], md5=item.get("md5", None))
            # no need to keep going if the file exists
            if authdata.get("exists"):
                result["unchanged"].append(item)
                continue
            self._upload_file(authdata, attach, item["key"])
            result["success"].append(item)
        return result

def upload ( self ) : result = { "success" : [ ] , "failure" : [ ] , "unchanged" : [ ] } self . _create_prelim ( ) for item in self . payload : if "key" not in item : result [ "failure" ] . append ( item ) continue attach = str ( self . basedir . joinpath ( item [ "filename" ] ) ) authdata = self . _get_auth ( attach , item [ "key" ] , md5 = item . get ( "md5" , None ) ) if authdata . get ( "exists" ) : result [ "unchanged" ] . append ( item ) continue self . _upload_file ( authdata , attach , item [ "key" ] ) result [ "success" ] . append ( item ) return result


def split_multiline(value):
    """Split a multiline string into a list, excluding blank lines."""
    return [element for element in (line.strip() for line in value.split('\n'))
            if element]

def split_multiline ( value ) : return [ element for element in ( line . strip ( ) for line in value . split ( '\n' ) ) if element ]

Split a multiline string into a list excluding blank lines .


def split_elements(value):
    """Split a string with comma or space-separated elements into a list."""
    items = [v.strip() for v in value.split(',')]
    if len(items) == 1:
        items = value.split()
    return items

def split_elements ( value ) : items = [ v . strip ( ) for v in value . split ( ',' ) ] if len ( items ) == 1 : items = value . split ( ) return items

Split a string with comma or space - separated elements into a list .


def eval_environ(value):
    """Evaluate environment markers."""
    def eval_environ_str(value):
        parts = value.split(';')
        if len(parts) < 2:
            return value
        expr = parts[1].lstrip()
        if not re.match("^((\\w+(\\.\\w+)?|'.*?'|\".*?\")\\s+"
                        '(in|==|!=|not in)\\s+'
                        "(\\w+(\\.\\w+)?|'.*?'|\".*?\")"
                        '(\\s+(or|and)\\s+)?)+$', expr):
            raise ValueError('bad environment marker: %r' % expr)
        expr = re.sub(r"(platform\.\w+)", r"\1()", expr)
        return parts[0] if eval(expr) else ''

    if isinstance(value, list):
        new_value = []
        for element in value:
            element = eval_environ_str(element)
            if element:
                new_value.append(element)
    elif isinstance(value, str):
        new_value = eval_environ_str(value)
    else:
        new_value = value

    return new_value

def
eval_environ
(
value
)
:
def
eval_environ_str
(
value
)
:
parts
=
value
.
split
(
';'
)
if
len
(
parts
)
<
2
:
return
value
expr
=
parts
[
1
]
.
lstrip
(
)
if
not
re
.
match
(
"^((\\w+(\\.\\w+)?|'.*?'|\".*?\")\\s+"
'(in|==|!=|not in)\\s+'
"(\\w+(\\.\\w+)?|'.*?'|\".*?\")"
'(\\s+(or|and)\\s+)?)+$'
,
expr
)
:
raise
ValueError
(
'bad environment marker: %r'
%
expr
)
expr
=
re
.
sub
(
r"(platform\.\w+)"
,
r"\1()"
,
expr
)
return
parts
[
0
]
if
eval
(
expr
)
else
''
if
isinstance
(
value
,
list
)
:
new_value
=
[
]
for
element
in
value
:
element
=
eval_environ_str
(
element
)
if
element
:
new_value
.
append
(
element
)
elif
isinstance
(
value
,
str
)
:
new_value
=
eval_environ_str
(
value
)
else
:
new_value
=
value
return
new_value


def get_cfg_value(config, section, option):
    """Get configuration value."""
    try:
        value = config[section][option]
    except KeyError:
        if (section, option) in MULTI_OPTIONS:
            return []
        else:
            return ''
    if (section, option) in MULTI_OPTIONS:
        value = split_multiline(value)
    if (section, option) in ENVIRON_OPTIONS:
        value = eval_environ(value)
    return value

def get_cfg_value ( config , section , option ) : try : value = config [ section ] [ option ] except KeyError : if ( section , option ) in MULTI_OPTIONS : return [ ] else : return '' if ( section , option ) in MULTI_OPTIONS : value = split_multiline ( value ) if ( section , option ) in ENVIRON_OPTIONS : value = eval_environ ( value ) return value


def set_cfg_value(config, section, option, value):
    """Set configuration value."""
    if isinstance(value, list):
        value = '\n'.join(value)
    config[section][option] = value

def set_cfg_value ( config , section , option , value ) : if isinstance ( value , list ) : value = '\n' . join ( value ) config [ section ] [ option ] = value


def cfg_to_args(config):
    """Compatibility helper to use setup.cfg in setup.py."""
    kwargs = {}
    opts_to_args = {
        'metadata': [
            ('name', 'name'),
            ('author', 'author'),
            ('author-email', 'author_email'),
            ('maintainer', 'maintainer'),
            ('maintainer-email', 'maintainer_email'),
            ('home-page', 'url'),
            ('summary', 'description'),
            ('description', 'long_description'),
            ('download-url', 'download_url'),
            ('classifier', 'classifiers'),
            ('platform', 'platforms'),
            ('license', 'license'),
            ('keywords', 'keywords'),
        ],
        'files': [
            ('packages_root', 'package_dir'),
            ('packages', 'packages'),
            ('modules', 'py_modules'),
            ('scripts', 'scripts'),
            ('package_data', 'package_data'),
            ('data_files', 'data_files'),
        ],
    }

    opts_to_args['metadata'].append(('requires-dist', 'install_requires'))
    if IS_PY2K and not which('3to2'):
        kwargs['setup_requires'] = ['3to2']
    kwargs['zip_safe'] = False

    for section in opts_to_args:
        for option, argname in opts_to_args[section]:
            value = get_cfg_value(config, section, option)
            if value:
                kwargs[argname] = value

    if 'long_description' not in kwargs:
        kwargs['long_description'] = read_description_file(config)

    if 'package_dir' in kwargs:
        kwargs['package_dir'] = {'': kwargs['package_dir']}

    if 'keywords' in kwargs:
        kwargs['keywords'] = split_elements(kwargs['keywords'])

    if 'package_data' in kwargs:
        kwargs['package_data'] = get_package_data(kwargs['package_data'])

    if 'data_files' in kwargs:
        kwargs['data_files'] = get_data_files(kwargs['data_files'])

    kwargs['version'] = get_version()

    if not IS_PY2K:
        kwargs['test_suite'] = 'test'

    return kwargs

def cfg_to_args ( config ) : kwargs = { } opts_to_args = { 'metadata' : [ ( 'name' , 'name' ) , ( 'author' , 'author' ) , ( 'author-email' , 'author_email' ) , ( 'maintainer' , 'maintainer' ) , ( 'maintainer-email' , 'maintainer_email' ) , ( 'home-page' , 'url' ) , ( 'summary' , 'description' ) , ( 'description' , 'long_description' ) , ( 'download-url' , 'download_url' ) , ( 'classifier' , 'classifiers' ) , ( 'platform' , 'platforms' ) , ( 'license' , 'license' ) , ( 'keywords' , 'keywords' ) , ] , 'files' : [ ( 'packages_root' , 'package_dir' ) , ( 'packages' , 'packages' ) , ( 'modules' , 'py_modules' ) , ( 'scripts' , 'scripts' ) , ( 'package_data' , 'package_data' ) , ( 'data_files' , 'data_files' ) , ] , } opts_to_args [ 'metadata' ] . append ( ( 'requires-dist' , 'install_requires' ) ) if IS_PY2K and not which ( '3to2' ) : kwargs [ 'setup_requires' ] = [ '3to2' ] kwargs [ 'zip_safe' ] = False for section in opts_to_args : for option , argname in opts_to_args [ section ] : value = get_cfg_value ( config , section , option ) if value : kwargs [ argname ] = value if 'long_description' not in kwargs : kwargs [ 'long_description' ] = read_description_file ( config ) if 'package_dir' in kwargs : kwargs [ 'package_dir' ] = { '' : kwargs [ 'package_dir' ] } if 'keywords' in kwargs : kwargs [ 'keywords' ] = split_elements ( kwargs [ 'keywords' ] ) if 'package_data' in kwargs : kwargs [ 'package_data' ] = get_package_data ( kwargs [ 'package_data' ] ) if 'data_files' in kwargs : kwargs [ 'data_files' ] = get_data_files ( kwargs [ 'data_files' ] ) kwargs [ 'version' ] = get_version ( ) if not IS_PY2K : kwargs [ 'test_suite' ] = 'test' return kwargs

Compatibility helper to use setup . cfg in setup . py .


def run_3to2(args=None):
    """Convert Python files using lib3to2."""
    args = BASE_ARGS_3TO2 if args is None else BASE_ARGS_3TO2 + args
    try:
        proc = subprocess.Popen(['3to2'] + args, stderr=subprocess.PIPE)
    except OSError:
        for path in glob.glob('*.egg'):
            if os.path.isdir(path) and path not in sys.path:
                sys.path.append(path)
        try:
            from lib3to2.main import main as lib3to2_main
        except ImportError:
            raise OSError('3to2 script is unavailable.')
        else:
            if lib3to2_main('lib3to2.fixes', args):
                raise Exception('lib3to2 parsing error')
    else:
        # HACK: workaround for 3to2 never returning non-zero
        # when using the -j option.
        num_errors = 0
        while proc.poll() is None:
            line = proc.stderr.readline()
            sys.stderr.write(line)
            num_errors += line.count(': ParseError: ')
        if proc.returncode or num_errors:
            raise Exception('lib3to2 parsing error')

def
run_3to2
(
args
=
)
:
args
=
BASE_ARGS_3TO2
if
args
is
else
BASE_ARGS_3TO2
+
args
try
:
proc
=
subprocess
.
Popen
(
[
'3to2'
]
+
args
,
stderr
=
subprocess
.
PIPE
)
except
OSError
:
for
path
in
glob
.
glob
(
'*.egg'
)
:
if
os
.
path
.
isdir
(
path
)
and
path
not
in
sys
.
path
:
sys
.
path
.
append
(
path
)
try
:
from
lib3to2
.
main
import
main
as
lib3to2_main
except
ImportError
:
raise
OSError
(
'3to2 script is unavailable.'
)
else
:
if
lib3to2_main
(
'lib3to2.fixes'
,
args
)
:
raise
Exception
(
'lib3to2 parsing error'
)
else
:
num_errors
=
0
while
proc
.
poll
(
)
is
:
line
=
proc
.
stderr
.
readline
(
)
sys
.
stderr
.
write
(
line
)
num_errors
+=
line
.
count
(
': ParseError: '
)
if
proc
.
returncode
or
num_errors
:
raise
Exception
(
'lib3to2 parsing error'
)


def write_py2k_header(file_list):
    """Write Python 2 shebang and add encoding cookie if needed."""
    if not isinstance(file_list, list):
        file_list = [file_list]

    python_re = re.compile(br"^(#!.*\bpython)(.*)([\r\n]+)$")
    coding_re = re.compile(br"coding[:=]\s*([-\w.]+)")
    new_line_re = re.compile(br"([\r\n]+)$")
    version_3 = LooseVersion('3')

    for file in file_list:
        if not os.path.getsize(file):
            continue

        rewrite_needed = False
        python_found = False
        coding_found = False
        lines = []

        f = open(file, 'rb')
        try:
            while len(lines) < 2:
                line = f.readline()
                match = python_re.match(line)
                if match:
                    python_found = True
                    version = LooseVersion(match.group(2).decode() or '2')
                    try:
                        version_test = version >= version_3
                    except TypeError:
                        version_test = True
                    if version_test:
                        line = python_re.sub(br"\g<1>2\g<3>", line)
                        rewrite_needed = True
                elif coding_re.search(line):
                    coding_found = True
                lines.append(line)
            if not coding_found:
                match = new_line_re.search(lines[0])
                newline = match.group(1) if match else b"\n"
                line = b"# -*- coding: utf-8 -*-" + newline
                lines.insert(1 if python_found else 0, line)
                rewrite_needed = True
            if rewrite_needed:
                lines += f.readlines()
        finally:
            f.close()

        if rewrite_needed:
            f = open(file, 'wb')
            try:
                f.writelines(lines)
            finally:
                f.close()

def
write_py2k_header
(
file_list
)
:
if
not
isinstance
(
file_list
,
list
)
:
file_list
=
[
file_list
]
python_re
=
re
.
compile
(
br"^(#!.*\bpython)(.*)([\r\n]+)$"
)
coding_re
=
re
.
compile
(
br"coding[:=]\s*([-\w.]+)"
)
new_line_re
=
re
.
compile
(
br"([\r\n]+)$"
)
version_3
=
LooseVersion
(
'3'
)
for
file
in
file_list
:
if
not
os
.
path
.
getsize
(
file
)
:
continue
rewrite_needed
=
False
python_found
=
False
coding_found
=
False
lines
=
[
]
f
=
open
(
file
,
'rb'
)
try
:
while
len
(
lines
)
<
2
:
line
=
f
.
readline
(
)
match
=
python_re
.
match
(
line
)
if
match
:
python_found
=
True
version
=
LooseVersion
(
match
.
group
(
2
)
.
decode
(
)
or
'2'
)
try
:
version_test
=
version
>=
version_3
except
TypeError
:
version_test
=
True
if
version_test
:
line
=
python_re
.
sub
(
br"\g<1>2\g<3>"
,
line
)
rewrite_needed
=
True
elif
coding_re
.
search
(
line
)
:
coding_found
=
True
lines
.
append
(
line
)
if
not
coding_found
:
match
=
new_line_re
.
search
(
lines
[
0
]
)
newline
=
match
.
group
(
1
)
if
match
else
b"\n"
line
=
b"# -*- coding: utf-8 -*-"
+
newline
lines
.
insert
(
1
if
python_found
else
0
,
line
)
rewrite_needed
=
True
if
rewrite_needed
:
lines
+=
f
.
readlines
(
)
finally
:
f
.
close
(
)
if
rewrite_needed
:
f
=
open
(
file
,
'wb'
)
try
:
f
.
writelines
(
lines
)
finally
:
f
.
close
(
)

Write Python 2 shebang and add encoding cookie if needed .


def get_version():
    """Get LanguageTool version."""
    version = _get_attrib().get('version')
    if not version:
        match = re.search(r"LanguageTool-?.*?(\S+)$", get_directory())
        if match:
            version = match.group(1)
    return version

def get_version ( ) : version = _get_attrib ( ) . get ( 'version' ) if not version : match = re . search ( r"LanguageTool-?.*?(\S+)$" , get_directory ( ) ) if match : version = match . group ( 1 ) return version


def get_languages() -> set:
    """Get supported languages."""
    try:
        languages = cache['languages']
    except KeyError:
        languages = LanguageTool._get_languages()
        cache['languages'] = languages
    return languages

def get_languages ( ) -> set : try : languages = cache [ 'languages' ] except KeyError : languages = LanguageTool . _get_languages ( ) cache [ 'languages' ] = languages return languages


def get_directory():
    """Get LanguageTool directory."""
    try:
        language_check_dir = cache['language_check_dir']
    except KeyError:
        def version_key(string):
            return [int(e) if e.isdigit() else e
                    for e in re.split(r"(\d+)", string)]

        def get_lt_dir(base_dir):
            paths = [
                path for path in
                glob.glob(os.path.join(base_dir, 'LanguageTool*'))
                if os.path.isdir(path)
            ]
            return max(paths, key=version_key) if paths else None

        base_dir = os.path.dirname(sys.argv[0])
        language_check_dir = get_lt_dir(base_dir)
        if not language_check_dir:
            try:
                base_dir = os.path.dirname(os.path.abspath(__file__))
            except NameError:
                pass
            else:
                language_check_dir = get_lt_dir(base_dir)
            if not language_check_dir:
                raise PathError("can't find LanguageTool directory in {!r}"
                                .format(base_dir))
        cache['language_check_dir'] = language_check_dir
    return language_check_dir


def set_directory(path=None):
    """Set LanguageTool directory."""
    old_path = get_directory()
    terminate_server()
    cache.clear()
    if path:
        cache['language_check_dir'] = path
        try:
            get_jar_info()
        except Error:
            cache['language_check_dir'] = old_path
            raise

def set_directory ( path = None ) : old_path = get_directory ( ) terminate_server ( ) cache . clear ( ) if path : cache [ 'language_check_dir' ] = path try : get_jar_info ( ) except Error : cache [ 'language_check_dir' ] = old_path raise


def check(self, text: str, srctext=None) -> [Match]:
        """Match text against enabled rules."""
        root = self._get_root(self._url, self._encode(text, srctext))
        return [Match(e.attrib) for e in root if e.tag == 'error']

def check ( self , text : str , srctext = None ) -> [ Match ] : root = self . _get_root ( self . _url , self . _encode ( text , srctext ) ) return [ Match ( e . attrib ) for e in root if e . tag == 'error' ]


def get_newest_possible_languagetool_version():
    """Return newest compatible version.

    >>> version = get_newest_possible_languagetool_version()
    >>> version in [JAVA_6_COMPATIBLE_VERSION,
    ...             JAVA_7_COMPATIBLE_VERSION,
    ...             LATEST_VERSION]
    True

    """
    java_path = find_executable('java')
    if not java_path:
        # Just ignore this and assume an old version of Java. It might not be
        # found because of a PATHEXT-related issue
        # (https://bugs.python.org/issue2200).
        return JAVA_6_COMPATIBLE_VERSION

    output = subprocess.check_output([java_path, '-version'],
                                     stderr=subprocess.STDOUT,
                                     universal_newlines=True)

    java_version = parse_java_version(output)

    if java_version >= (1, 8):
        return LATEST_VERSION
    elif java_version >= (1, 7):
        return JAVA_7_COMPATIBLE_VERSION
    elif java_version >= (1, 6):
        warn('language-check would be able to use a newer version of '
             'LanguageTool if you had Java 7 or newer installed')
        return JAVA_6_COMPATIBLE_VERSION
    else:
        raise SystemExit(
            'You need at least Java 6 to use language-check')


def get_common_prefix(z):
    """Get common directory in a zip file if any."""
    name_list = z.namelist()
    if name_list and all(n.startswith(name_list[0]) for n in name_list[1:]):
        return name_list[0]
    return None

def get_common_prefix ( z ) : name_list = z . namelist ( ) if name_list and all ( n . startswith ( name_list [ 0 ] ) for n in name_list [ 1 : ] ) : return name_list [ 0 ] return None

Get common directory in a zip file if any .


def _process_events(self, events):
        """Process events from proactor."""
        for f, callback, transferred, key, ov in events:
            try:
                self._logger.debug('Invoking event callback {}'.format(callback))
                value = callback(transferred, key, ov)
            except OSError:
                self._logger.warning('Event callback failed', exc_info=sys.exc_info())
            else:
                f.set_result(value)

def
_process_events
(
self
,
events
)
:
for
f
,
callback
,
transferred
,
key
,
ov
in
events
:
try
:
self
.
_logger
.
debug
(
'Invoking event callback {}'
.
format
(
callback
)
)
value
=
callback
(
transferred
,
key
,
ov
)
except
OSError
:
self
.
_logger
.
warning
(
'Event callback failed'
,
exc_info
=
sys
.
exc_info
(
)
)
else
:
f
.
set_result
(
value
)


def asyncClose(fn):
    """Allow to run async code before application is closed."""
    @functools.wraps(fn)
    def wrapper(*args, **kwargs):
        f = asyncio.ensure_future(fn(*args, **kwargs))
        while not f.done():
            QApplication.instance().processEvents()

    return wrapper

def asyncClose ( fn ) : @ functools . wraps ( fn ) def wrapper ( * args , ** kwargs ) : f = asyncio . ensure_future ( fn ( * args , ** kwargs ) ) while not f . done ( ) : QApplication . instance ( ) . processEvents ( ) return wrapper

Allow to run async code before application is closed .


def asyncSlot(*args):
    """Make a Qt async slot run on asyncio loop."""
    def outer_decorator(fn):
        @Slot(*args)
        @functools.wraps(fn)
        def wrapper(*args, **kwargs):
            asyncio.ensure_future(fn(*args, **kwargs))
        return wrapper
    return outer_decorator

def asyncSlot ( * args ) : def outer_decorator ( fn ) : @ Slot ( * args ) @ functools . wraps ( fn ) def wrapper ( * args , ** kwargs ) : asyncio . ensure_future ( fn ( * args , ** kwargs ) ) return wrapper return outer_decorator

Make a Qt async slot run on asyncio loop .


def with_logger(cls):
    """Class decorator to add a logger to a class."""
    attr_name = '_logger'
    cls_name = cls.__qualname__
    module = cls.__module__
    if module is not None:
        cls_name = module + '.' + cls_name
    else:
        raise AssertionError
    setattr(cls, attr_name, logging.getLogger(cls_name))
    return cls

def with_logger ( cls ) : attr_name = '_logger' cls_name = cls . __qualname__ module = cls . __module__ if module is not None : cls_name = module + '.' + cls_name else : raise AssertionError setattr ( cls , attr_name , logging . getLogger ( cls_name ) ) return cls

Class decorator to add a logger to a class .


def _process_event(self, key, mask):
        """Selector has delivered us an event."""
        self._logger.debug('Processing event with key {} and mask {}'.format(key, mask))
        fileobj, (reader, writer) = key.fileobj, key.data
        if mask & selectors.EVENT_READ and reader is not None:
            if reader._cancelled:
                self.remove_reader(fileobj)
            else:
                self._logger.debug('Invoking reader callback: {}'.format(reader))
                reader._run()
        if mask & selectors.EVENT_WRITE and writer is not None:
            if writer._cancelled:
                self.remove_writer(fileobj)
            else:
                self._logger.debug('Invoking writer callback: {}'.format(writer))
                writer._run()


def addSources(self, *sources):
        """Add more ASN.1 MIB source repositories.

        MibCompiler.compile will invoke each of configured source objects
        in order of their addition asking each to fetch MIB module specified
        by name.

        Args:
            sources: reader object(s)

        Returns:
            reference to itself (can be used for call chaining)

        """
        self._sources.extend(sources)

        debug.logger & debug.flagCompiler and debug.logger(
            'current MIB source(s): %s' % ', '.join([str(x) for x in self._sources]))

        return self

def
addSources
(
self
,
*
sources
)
:
self
.
_sources
.
extend
(
sources
)
debug
.
logger
&
debug
.
flagCompiler
and
debug
.
logger
(
'current MIB source(s): %s'
%
', '
.
join
(
[
str
(
x
)
for
x
in
self
.
_sources
]
)
)
return
self

Add more ASN . 1 MIB source repositories .


def addSearchers(self, *searchers):
        """Add more transformed MIBs repositories.

        MibCompiler.compile will invoke each of configured searcher objects
        in order of their addition asking each if already transformed MIB
        module already exists and is more recent than specified.

        Args:
            searchers: searcher object(s)

        Returns:
            reference to itself (can be used for call chaining)

        """
        self._searchers.extend(searchers)

        debug.logger & debug.flagCompiler and debug.logger(
            'current compiled MIBs location(s): %s' % ', '.join([str(x) for x in self._searchers]))

        return self

def
addSearchers
(
self
,
*
searchers
)
:
self
.
_searchers
.
extend
(
searchers
)
debug
.
logger
&
debug
.
flagCompiler
and
debug
.
logger
(
'current compiled MIBs location(s): %s'
%
', '
.
join
(
[
str
(
x
)
for
x
in
self
.
_searchers
]
)
)
return
self

Add more transformed MIBs repositories .


def addBorrowers(self, *borrowers):
        """Add more transformed MIBs repositories to borrow MIBs from.

        Whenever MibCompiler.compile encounters MIB module which neither of
        the *searchers* can find or fetched ASN.1 MIB module can not be
        parsed (due to syntax errors), these *borrowers* objects will be
        invoked in order of their addition asking each if already transformed
        MIB can be fetched (borrowed).

        Args:
            borrowers: borrower object(s)

        Returns:
            reference to itself (can be used for call chaining)

        """
        self._borrowers.extend(borrowers)

        debug.logger & debug.flagCompiler and debug.logger(
            'current MIB borrower(s): %s' % ', '.join([str(x) for x in self._borrowers]))

        return self

def
addBorrowers
(
self
,
*
borrowers
)
:
self
.
_borrowers
.
extend
(
borrowers
)
debug
.
logger
&
debug
.
flagCompiler
and
debug
.
logger
(
'current MIB borrower(s): %s'
%
', '
.
join
(
[
str
(
x
)
for
x
in
self
.
_borrowers
]
)
)
return
self

Add more transformed MIBs repositories to borrow MIBs from .


def AIC(N, rho, k):
    r"""Akaike Information Criterion

    :param rho: rho at order k
    :param N: sample size
    :param k: AR order.

    If k is the AR order and N the size of the sample, then Akaike criterion is

    .. math:: AIC(k) = \log(\rho_k) + 2\frac{k+1}{N}

    ::

        AIC(64, [0.5,0.3,0.2], [1,2,3])

    :validation: double checked versus octave.
    """
    from numpy import log, array
    #k+1 #todo check convention. agrees with octave

    res = N * log(array(rho)) + 2.* (array(k)+1)
    return res

def AIC ( N , rho , k ) : r from numpy import log , array res = N * log ( array ( rho ) ) + 2. * ( array ( k ) + 1 ) return res


def AICc(N, rho, k, norm=True):
    r"""corrected Akaike information criterion

    .. math:: AICc(k) = log(\rho_k) + 2 \frac{k+1}{N-k-2}

    :validation: double checked versus octave.
    """
    from numpy import log, array
    p = k  #todo check convention. agrees with octave
    res = log(rho) + 2. * (p+1) / (N-p-2)
    return res

def AICc ( N , rho , k , norm = True ) : r from numpy import log , array p = k res = log ( rho ) + 2. * ( p + 1 ) / ( N - p - 2 ) return res

r corrected Akaike information criterion


def KIC(N, rho, k):
    r"""Kullback information criterion

    .. math:: KIC(k) = log(\rho_k) + 3 \frac{k+1}{N}

    :validation: double checked versus octave.
    """
    from numpy import log, array
    res = log(rho) + 3. * (k+1.) /float(N)
    return res

def KIC ( N , rho , k ) : r from numpy import log , array res = log ( rho ) + 3. * ( k + 1. ) / float ( N ) return res


def AKICc(N, rho, k):
    r"""approximate corrected Kullback information

    .. math:: AKICc(k) = log(rho_k) + \frac{p}{N*(N-k)} + (3-\frac{k+2}{N})*\frac{k+1}{N-k-2}

    """
    from numpy import log, array
    p = k
    res = log(rho) + p/N/(N-p) + (3.-(p+2.)/N) * (p+1.) / (N-p-2.)
    return res

def AKICc ( N , rho , k ) : r from numpy import log , array p = k res = log ( rho ) + p / N / ( N - p ) + ( 3. - ( p + 2. ) / N ) * ( p + 1. ) / ( N - p - 2. ) return res

r approximate corrected Kullback information


def FPE(N,rho, k=None):
    r"""Final prediction error criterion

    .. math:: FPE(k) = \frac{N + k + 1}{N - k - 1} \rho_k

    :validation: double checked versus octave.

    """
    #k #todo check convention. agrees with octave
    fpe = rho * (N + k + 1.) / (N- k -1)
    return fpe

def FPE ( N , rho , k = None ) : r fpe = rho * ( N + k + 1. ) / ( N - k - 1 ) return fpe


def MDL(N, rho, k):
    r"""Minimum Description Length

    .. math:: MDL(k) = N log \rho_k + p \log N

    :validation: results
    """
    from numpy import log
    #p = arange(1, len(rho)+1)
    mdl = N* log(rho) + k * log(N)
    return mdl

def MDL ( N , rho , k ) : r from numpy import log mdl = N * log ( rho ) + k * log ( N ) return mdl


def aic_eigen(s, N):
    r"""AIC order-selection using eigen values

    :param s: a list of `p` sorted eigen values
    :param N: the size of the input data. To be defined precisely.

    :return:
        * an array containing the AIC values

    Given :math:`n` sorted eigen values :math:`\lambda_i` with
    :math:`0 <= i < n`, the proposed criterion from Wax and Kailath (1985)
    is:

    .. math:: AIC(k) = -2(n-k)N \ln \frac{g(k)}{a(k)} + 2k(2n-k)

    where the arithmetic sum :math:`a(k)` is:

    .. math:: a(k) = \sum_{i=k+1}^{n}\lambda_i

    and the geometric sum :math:`g(k)` is:

    .. math:: g(k) = \prod_{i=k+1}^{n} \lambda_i^{-(n-k)}

    The number of relevant sinusoids in the signal subspace is determined by
    selecting the minimum of `AIC`.

    .. seealso:: :func:`~spectrum.eigenfreq.eigen`
    .. todo:: define precisely the input parameter N. Should be the input
       data length but when using correlation matrix (SVD), I suspect it
       should be the length of the correlation matrix rather than the
       original data.

    :References:
        * [Marple]_ Chap 13,
        * [Wax]_
    """
    import numpy as np

    kaic = []
    n = len(s)
    for k in range(0, n-1):
        ak = 1./(n-k) * np.sum(s[k+1:])
        gk = np.prod(s[k+1:]**(1./(n-k)))
        kaic.append( -2.*(n-k)*N * np.log(gk/ak) + 2.*k*(2.*n-k))

    return kaic

def aic_eigen ( s , N ) : r import numpy as np kaic = [ ] n = len ( s ) for k in range ( 0 , n - 1 ) : ak = 1. / ( n - k ) * np . sum ( s [ k + 1 : ] ) gk = np . prod ( s [ k + 1 : ] ** ( 1. / ( n - k ) ) ) kaic . append ( - 2. * ( n - k ) * N * np . log ( gk / ak ) + 2. * k * ( 2. * n - k ) ) return kaic

r AIC order - selection using eigen values


def mdl_eigen(s, N):
    r"""MDL order-selection using eigen values

    :param s: a list of `p` sorted eigen values
    :param N: the size of the input data. To be defined precisely.

    :return:
        * an array containing the AIC values

    .. math:: MDL(k) = (n-k)N \ln \frac{g(k)}{a(k)} + 0.5k(2n-k) log(N)

    .. seealso:: :func:`aic_eigen` for details

    :References:
        * [Marple]_ Chap 13,
        * [Wax]_
    """
    import numpy as np
    kmdl = []
    n = len(s)
    for k in range(0, n-1):
        ak = 1./(n-k) * np.sum(s[k+1:])
        gk = np.prod(s[k+1:]**(1./(n-k)))
        kmdl.append( -(n-k)*N * np.log(gk/ak) + 0.5*k*(2.*n-k)*np.log(N))
    return kmdl

def mdl_eigen ( s , N ) : r import numpy as np kmdl = [ ] n = len ( s ) for k in range ( 0 , n - 1 ) : ak = 1. / ( n - k ) * np . sum ( s [ k + 1 : ] ) gk = np . prod ( s [ k + 1 : ] ** ( 1. / ( n - k ) ) ) kmdl . append ( - ( n - k ) * N * np . log ( gk / ak ) + 0.5 * k * ( 2. * n - k ) * np . log ( N ) ) return kmdl

r MDL order - selection using eigen values


def generate_gallery_rst(app):
    """Generate the Main examples gallery reStructuredText

    Start the sphinx-gallery configuration and recursively scan the examples
    directories in order to populate the examples gallery
    """
    try:
        plot_gallery = eval(app.builder.config.plot_gallery)
    except TypeError:
        plot_gallery = bool(app.builder.config.plot_gallery)

    gallery_conf.update(app.config.sphinx_gallery_conf)
    gallery_conf.update(plot_gallery=plot_gallery)
    gallery_conf.update(abort_on_example_error=app.builder.config.abort_on_example_error)

    # this assures I can call the config in other places
    app.config.sphinx_gallery_conf = gallery_conf
    app.config.html_static_path.append(glr_path_static())

    clean_gallery_out(app.builder.outdir)

    examples_dirs = gallery_conf['examples_dirs']
    gallery_dirs = gallery_conf['gallery_dirs']

    if not isinstance(examples_dirs, list):
        examples_dirs = [examples_dirs]
    if not isinstance(gallery_dirs, list):
        gallery_dirs = [gallery_dirs]

    mod_examples_dir = os.path.relpath(gallery_conf['mod_example_dir'],
                                       app.builder.srcdir)
    seen_backrefs = set()

    for examples_dir, gallery_dir in zip(examples_dirs, gallery_dirs):
        examples_dir = os.path.relpath(examples_dir,
                                       app.builder.srcdir)
        gallery_dir = os.path.relpath(gallery_dir,
                                      app.builder.srcdir)

        for workdir in [examples_dir, gallery_dir, mod_examples_dir]:
            if not os.path.exists(workdir):
                os.makedirs(workdir)

        # we create an index.rst with all examples
        fhindex = open(os.path.join(gallery_dir, 'index.rst'), 'w')
        # Here we don't use an os.walk, but we recurse only twice: flat is
        # better than nested.
        fhindex.write(generate_dir_rst(examples_dir, gallery_dir, gallery_conf,
                                       seen_backrefs))
        for directory in sorted(os.listdir(examples_dir)):
            if os.path.isdir(os.path.join(examples_dir, directory)):
                src_dir = os.path.join(examples_dir, directory)
                target_dir = os.path.join(gallery_dir, directory)
                fhindex.write(generate_dir_rst(src_dir, target_dir,
                                               gallery_conf,
                                               seen_backrefs))
        fhindex.flush()

def generate_gallery_rst ( app ) : try : plot_gallery = eval ( app . builder . config . plot_gallery ) except TypeError : plot_gallery = bool ( app . builder . config . plot_gallery ) gallery_conf . update ( app . config . sphinx_gallery_conf ) gallery_conf . update ( plot_gallery = plot_gallery ) gallery_conf . update ( abort_on_example_error = app . builder . config . abort_on_example_error ) app . config . sphinx_gallery_conf = gallery_conf app . config . html_static_path . append ( glr_path_static ( ) ) clean_gallery_out ( app . builder . outdir ) examples_dirs = gallery_conf [ 'examples_dirs' ] gallery_dirs = gallery_conf [ 'gallery_dirs' ] if not isinstance ( examples_dirs , list ) : examples_dirs = [ examples_dirs ] if not isinstance ( gallery_dirs , list ) : gallery_dirs = [ gallery_dirs ] mod_examples_dir = os . path . relpath ( gallery_conf [ 'mod_example_dir' ] , app . builder . srcdir ) seen_backrefs = set ( ) for examples_dir , gallery_dir in zip ( examples_dirs , gallery_dirs ) : examples_dir = os . path . relpath ( examples_dir , app . builder . srcdir ) gallery_dir = os . path . relpath ( gallery_dir , app . builder . srcdir ) for workdir in [ examples_dir , gallery_dir , mod_examples_dir ] : if not os . path . exists ( workdir ) : os . makedirs ( workdir ) fhindex = open ( os . path . join ( gallery_dir , 'index.rst' ) , 'w' ) fhindex . write ( generate_dir_rst ( examples_dir , gallery_dir , gallery_conf , seen_backrefs ) ) for directory in sorted ( os . listdir ( examples_dir ) ) : if os . path . isdir ( os . path . join ( examples_dir , directory ) ) : src_dir = os . path . join ( examples_dir , directory ) target_dir = os . path . join ( gallery_dir , directory ) fhindex . write ( generate_dir_rst ( src_dir , target_dir , gallery_conf , seen_backrefs ) ) fhindex . flush ( )


def setup(app):
    """Setup sphinx-gallery sphinx extension"""
    app.add_config_value('plot_gallery', True, 'html')
    app.add_config_value('abort_on_example_error', False, 'html')
    app.add_config_value('sphinx_gallery_conf', gallery_conf, 'html')
    app.add_stylesheet('gallery.css')

    app.connect('builder-inited', generate_gallery_rst)

    app.connect('build-finished', embed_code_links)

def setup ( app ) : app . add_config_value ( 'plot_gallery' , True , 'html' ) app . add_config_value ( 'abort_on_example_error' , False , 'html' ) app . add_config_value ( 'sphinx_gallery_conf' , gallery_conf , 'html' ) app . add_stylesheet ( 'gallery.css' ) app . connect ( 'builder-inited' , generate_gallery_rst ) app . connect ( 'build-finished' , embed_code_links )


def CORRELATION(x, y=None, maxlags=None, norm='unbiased'):
    r"""Correlation function

    This function should give the same results as :func:`xcorr` but it
    returns the positive lags only. Moreover the algorithm does not use
    FFT as compared to other algorithms.

    :param array x: first data array of length N
    :param array y: second data array of length N. If not specified, computes the
        autocorrelation.
    :param int maxlags: compute cross correlation between [0:maxlags]
        when maxlags is not specified, the range of lags is [0:maxlags].
    :param str norm: normalisation in ['biased', 'unbiased', None, 'coeff']

        * *biased*   correlation=raw/N,
        * *unbiased* correlation=raw/(N-`|lag|`)
        * *coeff*    correlation=raw/(rms(x).rms(y))/N
        * None       correlation=raw

    :return:
        * a numpy.array correlation sequence,  r[1,N]
        * a float for the zero-lag correlation,  r[0]

    The *unbiased* correlation has the form:

    .. math::

        \hat{r}_{xx} = \frac{1}{N-m}T \sum_{n=0}^{N-m-1} x[n+m]x^*[n] T

    The *biased* correlation differs by the front factor only:

    .. math::

        \check{r}_{xx} = \frac{1}{N}T \sum_{n=0}^{N-m-1} x[n+m]x^*[n] T

    with :math:`0\leq m\leq N-1`.

    .. doctest::

        >>> from spectrum import CORRELATION
        >>> x = [1,2,3,4,5]
        >>> res = CORRELATION(x,x, maxlags=0, norm='biased')
        >>> res[0]
        11.0

    .. note:: this function should be replaced by :func:`xcorr`.

    .. seealso:: :func:`xcorr`
    """
    assert norm in ['unbiased','biased', 'coeff', None]
    #transform lag into list if it is an integer
    x = np.array(x)
    if y is None:
        y = x
    else:
        y = np.array(y)

    # N is the max of x and y
    N = max(len(x), len(y))
    if len(x) < N:
        x = y.copy()
        x.resize(N)
    if len(y) < N:
        y = y.copy()
        y.resize(N)

    #default lag is N-1
    if maxlags is None:
        maxlags = N - 1
    assert maxlags < N, 'lag must be less than len(x)'

    realdata = np.isrealobj(x) and np.isrealobj(y)
    #create an autocorrelation array with same length as lag
    if realdata == True:
        r = np.zeros(maxlags, dtype=float)
    else:
        r = np.zeros(maxlags, dtype=complex)

    if norm == 'coeff':
        rmsx = pylab_rms_flat(x)
        rmsy = pylab_rms_flat(y)

    for k in range(0, maxlags+1):
        nk = N - k - 1

        if realdata == True:
            sum = 0
            for j in range(0, nk+1):
                sum = sum + x[j+k] * y[j]
        else:
            sum = 0. + 0j
            for j in range(0, nk+1):
                sum = sum + x[j+k] * y[j].conjugate()
        if k == 0:
            if norm in ['biased', 'unbiased']:
                r0 = sum/float(N)
            elif norm is None:
                r0 = sum
            else:
                r0 =  1.
        else:
            if norm == 'unbiased':
                r[k-1] = sum / float(N-k)
            elif norm == 'biased':
                r[k-1] = sum / float(N)
            elif norm is None:
                r[k-1] = sum
            elif norm == 'coeff':
                r[k-1] =  sum/(rmsx*rmsy)/float(N)

    r = np.insert(r, 0, r0)
    return r

def
CORRELATION
(
x
,
y
=
,
maxlags
=
,
norm
=
'unbiased'
)
:
r
assert
norm
in
[
'unbiased'
,
'biased'
,
'coeff'
,
]
x
=
np
.
array
(
x
)
if
y
is
:
y
=
x
else
:
y
=
np
.
array
(
y
)
N
=
max
(
len
(
x
)
,
len
(
y
)
)
if
len
(
x
)
<
N
:
x
=
y
.
copy
(
)
x
.
resize
(
N
)
if
len
(
y
)
<
N
:
y
=
y
.
copy
(
)
y
.
resize
(
N
)
if
maxlags
is
:
maxlags
=
N
1
assert
maxlags
<
N
,
'lag must be less than len(x)'
realdata
=
np
.
isrealobj
(
x
)
and
np
.
isrealobj
(
y
)
if
realdata
==
True
:
r
=
np
.
zeros
(
maxlags
,
dtype
=
float
)
else
:
r
=
np
.
zeros
(
maxlags
,
dtype
=
complex
)
if
norm
==
'coeff'
:
rmsx
=
pylab_rms_flat
(
x
)
rmsy
=
pylab_rms_flat
(
y
)
for
k
in
range
(
0
,
maxlags
+
1
)
:
nk
=
N
k
1
if
realdata
==
True
:
sum
=
0
for
j
in
range
(
0
,
nk
+
1
)
:
sum
=
sum
+
x
[
j
+
k
]
*
y
[
j
]
else
:
sum
=
0.
+
0j
for
j
in
range
(
0
,
nk
+
1
)
:
sum
=
sum
+
x
[
j
+
k
]
*
y
[
j
]
.
conjugate
(
)
if
k
==
0
:
if
norm
in
[
'biased'
,
'unbiased'
]
:
r0
=
sum
/
float
(
N
)
elif
norm
is
:
r0
=
sum
else
:
r0
=
1.
else
:
if
norm
==
'unbiased'
:
r
[
k
1
]
=
sum
/
float
(
N
k
)
elif
norm
==
'biased'
:
r
[
k
1
]
=
sum
/
float
(
N
)
elif
norm
is
:
r
[
k
1
]
=
sum
elif
norm
==
'coeff'
:
r
[
k
1
]
=
sum
/
(
rmsx
*
rmsy
)
/
float
(
N
)
r
=
np
.
insert
(
r
,
0
,
r0
)
return
r


def xcorr(x, y=None, maxlags=None, norm='biased'):
    """Cross-correlation using numpy.correlate

    Estimates the cross-correlation (and autocorrelation) sequence of a random
    process of length N. By default, there is no normalisation and the output
    sequence of the cross-correlation has a length 2*N+1.

    :param array x: first data array of length N
    :param array y: second data array of length N. If not specified, computes the
        autocorrelation.
    :param int maxlags: compute cross correlation between [-maxlags:maxlags]
        when maxlags is not specified, the range of lags is [-N+1:N-1].
    :param str option: normalisation in ['biased', 'unbiased', None, 'coeff']

    The true cross-correlation sequence is

    .. math:: r_{xy}[m] = E(x[n+m].y^*[n]) = E(x[n].y^*[n-m])

    However, in practice, only a finite segment of one realization of the
    infinite-length random process is available.

    The correlation is estimated using numpy.correlate(x,y,'full').
    Normalisation is handled by this function using the following cases:

        * 'biased': Biased estimate of the cross-correlation function
        * 'unbiased': Unbiased estimate of the cross-correlation function
        * 'coeff': Normalizes the sequence so the autocorrelations at zero
           lag is 1.0.

    :return:
        * a numpy.array containing the cross-correlation sequence (length 2*N-1)
        * lags vector

    .. note:: If x and y are not the same length, the shorter vector is
        zero-padded to the length of the longer vector.

    .. rubric:: Examples

    .. doctest::

        >>> from spectrum import xcorr
        >>> x = [1,2,3,4,5]
        >>> c, l = xcorr(x,x, maxlags=0, norm='biased')
        >>> c
        array([ 11.])

    .. seealso:: :func:`CORRELATION`.
    """
    N = len(x)
    if y is None:
        y = x
    assert len(x) == len(y), 'x and y must have the same length. Add zeros if needed'

    if maxlags is None:
        maxlags = N-1
        lags = np.arange(0, 2*N-1)
    else:
        assert maxlags <= N, 'maxlags must be less than data length'
        lags = np.arange(N-maxlags-1, N+maxlags)

    res = np.correlate(x, y, mode='full')

    if norm == 'biased':
        Nf = float(N)
        res = res[lags] / float(N)    # do not use /= !!
    elif norm == 'unbiased':
        res = res[lags] / (float(N)-abs(np.arange(-N+1, N)))[lags]
    elif norm == 'coeff':
        Nf = float(N)
        rms = pylab_rms_flat(x) * pylab_rms_flat(y)
        res = res[lags] / rms / Nf
    else:
        res = res[lags]

    lags = np.arange(-maxlags, maxlags+1)
    return res, lags

Cross - correlation using numpy . correlate


def MINEIGVAL(T0, T, TOL):
    """Finds the minimum eigenvalue of a Hermitian Toeplitz matrix

    The classical power method is used together with a  fast  Toeplitz
    equation solution routine.  The eigenvector is normalized to unit length.

    :param T0: Scalar corresponding to real matrix element t(0)
    :param T: Array of  M  complex matrix elements t(1),...,t(M) C            from the left column of the Toeplitz matrix
    :param TOL: Real scalar tolerance; routine exits when [ EVAL(k) - EVAL(k-1) ]/EVAL(k-1) < TOL , where the index k denotes the iteration number.

    :return:
        * EVAL - Real scalar denoting the minimum eigenvalue of matrix
        * EVEC - Array of  M  complex eigenvector elements associated

    .. note::
     * External array T must be dimensioned >= M
     * array EVEC must be >= M+1
     *  Internal array E must be dimensioned >= M+1 .

     * **dependencies**
        *  :meth:`spectrum.toeplitz.HERMTOEP`
    """
    M = len(T)
    eigval = 10
    eigvalold = 1
    eigvec  = numpy.zeros(M+1, dtype=complex)
    for k in range(0,M+1):
        eigvec[k] = 1+0j
    it=0
    #print 'initialisation',T0, T, eigval, eigvec
    maxit = 15
    while abs(eigvalold-eigval)>TOL*eigvalold and it<maxit:
        it=it+1
        eigvalold = eigval
        #print 'iteration ',it, 'eigvalold=',eigvalold, 'eigval=', eigval

        eig = toeplitz.HERMTOEP(T0, T, eigvec)
        SUM = 0
        save =0.+0j
        for k in range(0, M+1):
            SUM = SUM + eig[k].real**2+eig[k].imag**2
            save = save +eig[k]*eigvec[k].conjugate()
        SUM=1./SUM
        eigval = save.real*SUM
        for k in range(0,M+1):
            eigvec[k] = SUM * eig[k]
    if it==maxit:
        print('warning reached max number of iteration (%s)' % maxit)
    return eigval, eigvec


def morlet(lb, ub, n):
    r"""Generate the Morlet waveform

    The Morlet waveform is defined as follows:

    .. math:: w[x] = \cos{5x}  \exp^{-x^2/2}

    :param lb: lower bound
    :param ub: upper bound
    :param int n: waveform data samples

    .. plot::
        :include-source:
        :width: 80%

        from spectrum import morlet
        from pylab import plot
        plot(morlet(0,10,100))

    """
    if n <= 0:
        raise ValueError("n must be strictly positive")

    x = numpy.linspace(lb, ub, n)
    psi = numpy.cos(5*x) * numpy.exp(-x**2/2.)
    return psi

def
morlet
(
lb
,
ub
,
n
)
:
r
if
n
<=
0
:
raise
ValueError
(
"n must be strictly positive"
)
x
=
numpy
.
linspace
(
lb
,
ub
,
n
)
psi
=
numpy
.
cos
(
5
*
x
)
*
numpy
.
exp
(
x
**
2
/
2.
)
return
psi


def chirp(t, f0=0., t1=1., f1=100., form='linear', phase=0):
    r"""Evaluate a chirp signal at time t.

    A chirp signal is a frequency swept cosine wave.

    .. math:: a = \pi  (f_1 - f_0) / t_1
    .. math:: b = 2  \pi  f_0
    .. math:: y = \cos\left( \pi\frac{f_1-f_0}{t_1}  t^2 + 2\pi f_0 t + \rm{phase} \right)

    :param array t: times at which to evaluate the chirp signal
    :param float f0: frequency at time t=0 (Hz)
    :param float t1: time t1
    :param float f1: frequency at time t=t1 (Hz)
    :param str form: shape of frequency sweep in ['linear', 'quadratic', 'logarithmic']
    :param float phase: phase shift at t=0

    The parameter **form** can be:

        * 'linear'      :math:`f(t) = (f_1-f_0)(t/t_1) + f_0`
        * 'quadratic'   :math:`f(t) = (f_1-f_0)(t/t_1)^2 + f_0`
        * 'logarithmic' :math:`f(t) = (f_1-f_0)^{(t/t_1)} + f_0`

    Example:

    .. plot::
        :include-source:
        :width: 80%

        from spectrum import chirp
        from pylab import linspace, plot
        t = linspace(0, 1, 1000)
        y = chirp(t, form='linear')
        plot(y)
        y = chirp(t, form='quadratic')
        plot(y, 'r')

    """
    valid_forms = ['linear', 'quadratic', 'logarithmic']
    if form not in valid_forms:
        raise ValueError("Invalid form. Valid form are %s"
            % valid_forms)
    t = numpy.array(t)
    phase = 2. * pi * phase / 360.
    if form == "linear":
        a = pi * (f1 - f0)/t1
        b = 2. * pi * f0
        y = numpy.cos(a * t**2 + b*t + phase)
    elif form == "quadratic":
        a = (2/3. * pi * (f1-f0)/t1/t1)
        b = 2. * pi * f0
        y = numpy.cos(a*t**3 + b * t + phase)
    elif form == "logarithmic":
        a = 2. * pi * t1/numpy.log(f1-f0)
        b = 2. * pi * f0
        x = (f1-f0)**(1./t1)
        y = numpy.cos(a * x**t + b * t + phase)

    return y

def
chirp
(
t
,
f0
=
0.
,
t1
=
1.
,
f1
=
100.
,
form
=
'linear'
,
phase
=
0
)
:
r
valid_forms
=
[
'linear'
,
'quadratic'
,
'logarithmic'
]
if
form
not
in
valid_forms
:
raise
ValueError
(
"Invalid form. Valid form are %s"
%
valid_forms
)
t
=
numpy
.
array
(
t
)
phase
=
2.
*
pi
*
phase
/
360.
if
form
==
"linear"
:
a
=
pi
*
(
f1
f0
)
/
t1
b
=
2.
*
pi
*
f0
y
=
numpy
.
cos
(
a
*
t
**
2
+
b
*
t
+
phase
)
elif
form
==
"quadratic"
:
a
=
(
2
/
3.
*
pi
*
(
f1
f0
)
/
t1
/
t1
)
b
=
2.
*
pi
*
f0
y
=
numpy
.
cos
(
a
*
t
**
3
+
b
*
t
+
phase
)
elif
form
==
"logarithmic"
:
a
=
2.
*
pi
*
t1
/
numpy
.
log
(
f1
f0
)
b
=
2.
*
pi
*
f0
x
=
(
f1
f0
)
**
(
1.
/
t1
)
y
=
numpy
.
cos
(
a
*
x
**
t
+
b
*
t
+
phase
)
return
y


def mexican(lb, ub, n):
    r"""Generate the mexican hat wavelet

    The Mexican wavelet is:

    .. math:: w[x] = \cos{5x}  \exp^{-x^2/2}

    :param lb: lower bound
    :param ub: upper bound
    :param int n: waveform data samples
    :return: the waveform

    .. plot::
        :include-source:
        :width: 80%

        from spectrum import mexican
        from pylab import plot
        plot(mexican(0, 10, 100))

    """
    if n <= 0:
        raise ValueError("n must be strictly positive")

    x = numpy.linspace(lb, ub, n)
    psi = (1.-x**2.) * (2./(numpy.sqrt(3.)*pi**0.25)) * numpy.exp(-x**2/2.)
    return psi

def
mexican
(
lb
,
ub
,
n
)
:
r
if
n
<=
0
:
raise
ValueError
(
"n must be strictly positive"
)
x
=
numpy
.
linspace
(
lb
,
ub
,
n
)
psi
=
(
1.
x
**
2.
)
*
(
2.
/
(
numpy
.
sqrt
(
3.
)
*
pi
**
0.25
)
)
*
numpy
.
exp
(
x
**
2
/
2.
)
return
psi


def ac2poly(data):
    """Convert autocorrelation sequence to prediction polynomial

    :param array data:    input data (list or numpy.array)
    :return:
        * AR parameters
        * noise variance

    This is an alias to::

        a, e, c = LEVINSON(data)

    :Example:

    .. doctest::

        >>> from spectrum import ac2poly
        >>> from numpy import array
        >>> r = [5, -2, 1.01]
        >>> ar, e = ac2poly(r)
        >>> ar
        array([ 1.  ,  0.38, -0.05])
        >>> e
        4.1895000000000007

    """
    a, e, _c = LEVINSON(data)
    a = numpy.insert(a, 0, 1)
    return a, e

def ac2poly ( data ) : a , e , _c = LEVINSON ( data ) a = numpy . insert ( a , 0 , 1 ) return a , e


def rc2poly(kr, r0=None):
    """convert reflection coefficients to prediction filter polynomial

    :param k: reflection coefficients

    """
    # Initialize the recursion
    from .levinson import levup
    p = len(kr)              #% p is the order of the prediction polynomial.
    a = numpy.array([1, kr[0]])           #% a is a true polynomial.
    e = numpy.zeros(len(kr))

    if r0 is None:
        e0 = 0
    else:
        e0 = r0

    e[0] = e0 * (1. - numpy.conj(numpy.conjugate(kr[0])*kr[0]))

    # Continue the recursion for k=2,3,...,p, where p is the order of the
    # prediction polynomial.

    for k in range(1, p):
        [a, e[k]] = levup(a, kr[k], e[k-1])

    efinal = e[-1]
    return a, efinal

def rc2poly ( kr , r0 = None ) : from . levinson import levup p = len ( kr ) a = numpy . array ( [ 1 , kr [ 0 ] ] ) e = numpy . zeros ( len ( kr ) ) if r0 is None : e0 = 0 else : e0 = r0 e [ 0 ] = e0 * ( 1. - numpy . conj ( numpy . conjugate ( kr [ 0 ] ) * kr [ 0 ] ) ) for k in range ( 1 , p ) : [ a , e [ k ] ] = levup ( a , kr [ k ] , e [ k - 1 ] ) efinal = e [ - 1 ] return a , efinal


def rc2ac(k, R0):
    """Convert reflection coefficients to autocorrelation sequence.

    :param k: reflection coefficients
    :param R0: zero-lag autocorrelation
    :returns: the autocorrelation sequence

    .. seealso:: :func:`ac2rc`, :func:`poly2rc`, :func:`ac2poly`, :func:`poly2rc`, :func:`rc2poly`.

    """
    [a,efinal] = rc2poly(k, R0)
    R, u, kr, e = rlevinson(a, efinal)
    return R

def rc2ac ( k , R0 ) : [ a , efinal ] = rc2poly ( k , R0 ) R , u , kr , e = rlevinson ( a , efinal ) return R

Convert reflection coefficients to autocorrelation sequence .


def rc2is(k):
    """Convert reflection coefficients to inverse sine parameters.

    :param k: reflection coefficients
    :return: inverse sine parameters

    .. seealso:: :func:`is2rc`, :func:`rc2poly`, :func:`rc2acC`, :func:`rc2lar`.

    Reference: J.R. Deller, J.G. Proakis, J.H.L. Hansen, "Discrete-Time
       Processing of Speech Signals", Prentice Hall, Section 7.4.5.

    """
    assert numpy.isrealobj(k), 'Inverse sine parameters not defined for complex reflection coefficients.'
    if max(numpy.abs(k)) >= 1:
        raise ValueError('All reflection coefficients should have magnitude less than unity.')

    return (2/numpy.pi)*numpy.arcsin(k)

Convert reflection coefficients to inverse sine parameters .


def rc2lar(k):
    """Convert reflection coefficients to log area ratios.

    :param k: reflection coefficients
    :return: inverse sine parameters

    The log area ratio is defined by G = log((1+k)/(1-k)) , where the K
    parameter is the reflection coefficient.

    .. seealso:: :func:`lar2rc`, :func:`rc2poly`, :func:`rc2ac`, :func:`rc2ic`.

    :References:
       [1] J. Makhoul, "Linear Prediction: A Tutorial Review," Proc. IEEE, Vol.63, No.4, pp.561-580, Apr 1975.

    """
    assert numpy.isrealobj(k), 'Log area ratios not defined for complex reflection coefficients.'
    if max(numpy.abs(k)) >= 1:
        raise ValueError('All reflection coefficients should have magnitude less than unity.')

    # Use the relation, atanh(x) = (1/2)*log((1+k)/(1-k))
    return -2 * numpy.arctanh(-numpy.array(k))

Convert reflection coefficients to log area ratios .


def lar2rc(g):
    """Convert log area ratios to reflection coefficients.

    :param g:  log area ratios
    :returns: the reflection coefficients

    .. seealso: :func:`rc2lar`, :func:`poly2rc`, :func:`ac2rc`, :func:`is2rc`.

    :References:
       [1] J. Makhoul, "Linear Prediction: A Tutorial Review," Proc. IEEE,  Vol.63, No.4, pp.561-580, Apr 1975.

    """
    assert numpy.isrealobj(g), 'Log area ratios not defined for complex reflection coefficients.'
    # Use the relation, tanh(x) = (1-exp(2x))/(1+exp(2x))
    return -numpy.tanh(-numpy.array(g)/2)

Convert log area ratios to reflection coefficients .


def lsf2poly(lsf):
    """Convert line spectral frequencies to prediction filter coefficients

    returns a vector a containing the prediction filter coefficients from a vector lsf of line spectral frequencies.

    .. doctest::

        >>> from spectrum import lsf2poly
        >>> lsf = [0.7842 ,   1.5605  ,  1.8776 ,   1.8984,    2.3593]
        >>> a = lsf2poly(lsf)

    # array([  1.00000000e+00,   6.14837835e-01,   9.89884967e-01,
    # 9.31594056e-05,   3.13713832e-03,  -8.12002261e-03 ])

    .. seealso:: poly2lsf, rc2poly, ac2poly, rc2is
    """
    #   Reference: A.M. Kondoz, "Digital Speech: Coding for Low Bit Rate Communications
    #   Systems" John Wiley & Sons 1994 ,Chapter 4

    # Line spectral frequencies must be real.

    lsf = numpy.array(lsf)

    if max(lsf) > numpy.pi or min(lsf) < 0:
        raise ValueError('Line spectral frequencies must be between 0 and pi.')

    p = len(lsf) # model order

    # Form zeros using the LSFs and unit amplitudes
    z  = numpy.exp(1.j * lsf)

    # Separate the zeros to those belonging to P and Q
    rQ = z[0::2]
    rP = z[1::2]

    # Include the conjugates as well
    rQ = numpy.concatenate((rQ, rQ.conjugate()))
    rP = numpy.concatenate((rP, rP.conjugate()))

    # Form the polynomials P and Q, note that these should be real
    Q  = numpy.poly(rQ);
    P  = numpy.poly(rP);

    # Form the sum and difference filters by including known roots at z = 1 and
    # z = -1

    if p%2:
        # Odd order: z = +1 and z = -1 are roots of the difference filter, P1(z)
        P1 = numpy.convolve(P, [1, 0, -1])
        Q1 = Q
    else:
        # Even order: z = -1 is a root of the sum filter, Q1(z) and z = 1 is a
        # root of the difference filter, P1(z)
        P1 = numpy.convolve(P, [1, -1])
        Q1 = numpy.convolve(Q, [1,  1])

    # Prediction polynomial is formed by averaging P1 and Q1

    a = .5 * (P1+Q1)
    return a[0:-1:1]


def poly2lsf(a):
    """Prediction polynomial to line spectral frequencies.

    converts the prediction polynomial specified by A,
    into the corresponding line spectral frequencies, LSF.
    normalizes the prediction polynomial by A(1).

    .. doctest::

        >>> from spectrum import poly2lsf
        >>> a = [1.0000,  0.6149, 0.9899, 0.0000 ,0.0031, -0.0082]
        >>> lsf = poly2lsf(a)
        >>> lsf =  array([0.7842, 1.5605, 1.8776, 1.8984, 2.3593])

    .. seealso:: lsf2poly, poly2rc, poly2qc, rc2is
    """

    #Line spectral frequencies are not defined for complex polynomials.

    # Normalize the polynomial

    a = numpy.array(a)
    if a[0] != 1:
        a/=a[0]

    if max(numpy.abs(numpy.roots(a))) >= 1.0:
        error('The polynomial must have all roots inside of the unit circle.');

    # Form the sum and differnce filters

    p  = len(a)-1   # The leading one in the polynomial is not used
    a1 = numpy.concatenate((a, numpy.array([0])))
    a2 = a1[-1::-1]
    P1 = a1 - a2        # Difference filter
    Q1 = a1 + a2        # Sum Filter

    # If order is even, remove the known root at z = 1 for P1 and z = -1 for Q1
    # If odd, remove both the roots from P1

    if p%2: # Odd order
        P, r = deconvolve(P1,[1, 0 ,-1])
        Q = Q1
    else:          # Even order
        P, r = deconvolve(P1, [1, -1])
        Q, r = deconvolve(Q1, [1,  1])

    rP  = numpy.roots(P)
    rQ  = numpy.roots(Q)

    aP  = numpy.angle(rP[1::2])
    aQ  = numpy.angle(rQ[1::2])

    lsf = sorted(numpy.concatenate((-aP,-aQ)))

    return lsf

Prediction polynomial to line spectral frequencies .


def _swapsides(data):
    """todo is it really useful ?

    Swap  sides

    .. doctest::

        >>> from spectrum import swapsides
        >>> x = [-2, -1, 1, 2]
        >>> swapsides(x)
        array([ 2, -2, -1])

    """
    N = len(data)
    return np.concatenate((data[N//2+1:], data[0:N//2]))

def _swapsides ( data ) : N = len ( data ) return np . concatenate ( ( data [ N // 2 + 1 : ] , data [ 0 : N // 2 ] ) )


def twosided_2_onesided(data):
    """Convert a one-sided PSD to a twosided PSD

    In order to keep the power in the onesided PSD the same
    as in the twosided version, the onesided values are twice
    as much as in the input data (except for the zero-lag value).

    ::

        >>> twosided_2_onesided([10, 2,3,3,2,8])
        array([ 10.,   4.,   6.,   8.])

    """
    assert len(data) % 2 == 0
    N = len(data)
    psd = np.array(data[0:N//2+1]) * 2.
    psd[0] /= 2.
    psd[-1] = data[-1]
    return psd

def twosided_2_onesided ( data ) : assert len ( data ) % 2 == 0 N = len ( data ) psd = np . array ( data [ 0 : N // 2 + 1 ] ) * 2. psd [ 0 ] /= 2. psd [ - 1 ] = data [ - 1 ] return psd

Convert a one - sided PSD to a twosided PSD


def onesided_2_twosided(data):
    """Convert a two-sided PSD to a one-sided PSD

    In order to keep the power in the twosided PSD the same
    as in the onesided version, the twosided values are 2 times
    lower than the input data (except for the zero-lag and N-lag
    values).

    ::

        >>> twosided_2_onesided([10, 4, 6, 8])
        array([ 10.,   2.,   3.,   3., 2., 8.])

    """
    psd = np.concatenate((data[0:-1], cshift(data[-1:0:-1], -1)))/2.
    psd[0] *= 2.
    psd[-1] *= 2.
    return psd

def onesided_2_twosided ( data ) : psd = np . concatenate ( ( data [ 0 : - 1 ] , cshift ( data [ - 1 : 0 : - 1 ] , - 1 ) ) ) / 2. psd [ 0 ] *= 2. psd [ - 1 ] *= 2. return psd

Convert a two - sided PSD to a one - sided PSD


def twosided_2_centerdc(data):
    """Convert a two-sided PSD to a center-dc PSD"""
    N = len(data)
    # could us int() or // in python 3
    newpsd = np.concatenate((cshift(data[N//2:], 1), data[0:N//2]))
    newpsd[0] = data[-1]
    return newpsd

def twosided_2_centerdc ( data ) : N = len ( data ) newpsd = np . concatenate ( ( cshift ( data [ N // 2 : ] , 1 ) , data [ 0 : N // 2 ] ) ) newpsd [ 0 ] = data [ - 1 ] return newpsd

Convert a two - sided PSD to a center - dc PSD


def centerdc_2_twosided(data):
    """Convert a center-dc PSD to a twosided PSD"""
    N = len(data)
    newpsd = np.concatenate((data[N//2:], (cshift(data[0:N//2], -1))))
    return newpsd

def centerdc_2_twosided ( data ) : N = len ( data ) newpsd = np . concatenate ( ( data [ N // 2 : ] , ( cshift ( data [ 0 : N // 2 ] , - 1 ) ) ) ) return newpsd

Convert a center - dc PSD to a twosided PSD


def _twosided_zerolag(data, zerolag):
    """Build a symmetric vector out of stricly positive lag vector and zero-lag

    .. doctest::

        >>> data = [3,2,1]
        >>> zerolag = 4
        >>> twosided_zerolag(data, zerolag)
        array([1, 2, 3, 4, 3, 2, 1])

    .. seealso:: Same behaviour as :func:`twosided_zerolag`
    """
    res = twosided(np.insert(data, 0, zerolag))
    return res

def _twosided_zerolag ( data , zerolag ) : res = twosided ( np . insert ( data , 0 , zerolag ) ) return res

Build a symmetric vector out of stricly positive lag vector and zero - lag


def data_cosine(N=1024, A=0.1, sampling=1024., freq=200):
    r"""Return a noisy cosine at a given frequency.

    :param N:           the final data size
    :param A:           the strength of the noise
    :param float sampling: sampling frequency of the input :attr:`data`.
    :param float freq:  the frequency :math:`f_0` of the cosine.

    .. math:: x[t] = cos(2\pi t * f_0) + A w[t]

    where w[t] is a white noise of variance 1.

    .. doctest::

        >>> from spectrum import data_cosine
        >>> a = data_cosine(N=1024, sampling=1024, A=0.5, freq=100)

    """
    t = arange(0, float(N)/sampling, 1./sampling)
    x = cos(2.*pi*t*freq) + A * randn(t.size)
    return x

def data_cosine ( N = 1024 , A = 0.1 , sampling = 1024. , freq = 200 ) : r t = arange ( 0 , float ( N ) / sampling , 1. / sampling ) x = cos ( 2. * pi * t * freq ) + A * randn ( t . size ) return x

r Return a noisy cosine at a given frequency .


def data_two_freqs(N=200):
    """A simple test example with two close frequencies

    """
    nn = arange(N)
    xx = cos(0.257*pi*nn) + sin(0.2*pi*nn) + 0.01*randn(nn.size)
    return xx

def data_two_freqs ( N = 200 ) : nn = arange ( N ) xx = cos ( 0.257 * pi * nn ) + sin ( 0.2 * pi * nn ) + 0.01 * randn ( nn . size ) return xx


def spectrum_data(filename):
    """Simple utilities to retrieve data sets from """
    import os
    import pkg_resources
    info = pkg_resources.get_distribution('spectrum')
    location = info.location

    # first try develop mode
    share = os.sep.join([location, "spectrum", 'data'])
    filename2 = os.sep.join([share, filename])
    if os.path.exists(filename2):
        return filename2
    else:
        raise Exception('unknown file %s' % filename2)

def
spectrum_data
(
filename
)
:
import
os
import
pkg_resources
info
=
pkg_resources
.
get_distribution
(
'spectrum'
)
location
=
info
.
location
share
=
os
.
sep
.
join
(
[
location
,
"spectrum"
,
'data'
]
)
filename2
=
os
.
sep
.
join
(
[
share
,
filename
]
)
if
os
.
path
.
exists
(
filename2
)
:
return
filename2
else
:
raise
Exception
(
'unknown file %s'
%
filename2
)


def plot(self, **kargs):
        """Plot the data set, using the sampling information to set the x-axis
        correctly."""
        from pylab import plot, linspace, xlabel, ylabel, grid
        time = linspace(1*self.dt, self.N*self.dt, self.N)
        plot(time, self.data, **kargs)
        xlabel('Time')
        ylabel('Amplitude')
        grid(True)

def plot ( self , ** kargs ) : from pylab import plot , linspace , xlabel , ylabel , grid time = linspace ( 1 * self . dt , self . N * self . dt , self . N ) plot ( time , self . data , ** kargs ) xlabel ( 'Time' ) ylabel ( 'Amplitude' ) grid ( True )

Plot the data set using the sampling information to set the x - axis correctly .


def readwav(filename):
    """Read a WAV file and returns the data and sample rate

    ::

        from spectrum.io import readwav
        readwav()

    """
    from scipy.io.wavfile import read as readwav
    samplerate, signal = readwav(filename)
    return signal, samplerate

def readwav ( filename ) : from scipy . io . wavfile import read as readwav samplerate , signal = readwav ( filename ) return signal , samplerate


def _autocov(s, **kwargs):
    """Returns the autocovariance of signal s at all lags.

    Adheres to the definition
    sxx[k] = E{S[n]S[n+k]} = cov{S[n],S[n+k]}
    where E{} is the expectation operator, and S is a zero mean process
    """
    # only remove the mean once, if needed
    debias = kwargs.pop('debias', True)
    axis = kwargs.get('axis', -1)
    if debias:
        s = _remove_bias(s, axis)
    kwargs['debias'] = False
    return _crosscov(s, s, **kwargs)

def _autocov ( s , ** kwargs ) : debias = kwargs . pop ( 'debias' , True ) axis = kwargs . get ( 'axis' , - 1 ) if debias : s = _remove_bias ( s , axis ) kwargs [ 'debias' ] = False return _crosscov ( s , s , ** kwargs )

Returns the autocovariance of signal s at all lags .


def _remove_bias(x, axis):
    "Subtracts an estimate of the mean from signal x at axis"
    padded_slice = [slice(d) for d in x.shape]
    padded_slice[axis] = np.newaxis
    mn = np.mean(x, axis=axis)
    return x - mn[tuple(padded_slice)]


def get_docstring_and_rest(filename):
    """Separate `filename` content between docstring and the rest

    Strongly inspired from ast.get_docstring.

    Returns
    -------
    docstring: str
        docstring of `filename`
    rest: str
        `filename` content without the docstring
    """
    with open(filename) as f:
        content = f.read()

    node = ast.parse(content)
    if not isinstance(node, ast.Module):
        raise TypeError("This function only supports modules. "
                        "You provided {0}".format(node.__class__.__name__))
    if node.body and isinstance(node.body[0], ast.Expr) and \
       isinstance(node.body[0].value, ast.Str):
        docstring_node = node.body[0]
        docstring = docstring_node.value.s
        # This get the content of the file after the docstring last line
        # Note: 'maxsplit' argument is not a keyword argument in python2
        rest = content.split('\n', docstring_node.lineno)[-1]
        return docstring, rest
    else:
        raise ValueError(('Could not find docstring in file "{0}". '
                          'A docstring is required by sphinx-gallery')
                         .format(filename))

Separate filename content between docstring and the rest


def split_code_and_text_blocks(source_file):
    """Return list with source file separated into code and text blocks.

    Returns
    -------
    blocks : list of (label, content)
        List where each element is a tuple with the label ('text' or 'code'),
        and content string of block.
    """
    docstring, rest_of_content = get_docstring_and_rest(source_file)

    blocks = [('text', docstring)]

    pattern = re.compile(
        r'(?P<header_line>^#{20,}.*)\s(?P<text_content>(?:^#.*\s)*)',
        flags=re.M)

    pos_so_far = 0
    for match in re.finditer(pattern, rest_of_content):
        match_start_pos, match_end_pos = match.span()
        code_block_content = rest_of_content[pos_so_far:match_start_pos]
        text_content = match.group('text_content')
        sub_pat = re.compile('^#', flags=re.M)
        text_block_content = dedent(re.sub(sub_pat, '', text_content))
        if code_block_content.strip():
            blocks.append(('code', code_block_content))
        if text_block_content.strip():
            blocks.append(('text', text_block_content))
        pos_so_far = match_end_pos

    remaining_content = rest_of_content[pos_so_far:]
    if remaining_content.strip():
        blocks.append(('code', remaining_content))

    return blocks

Return list with source file separated into code and text blocks .


def codestr2rst(codestr, lang='python'):
    """Return reStructuredText code block from code string"""
    code_directive = "\n.. code-block:: {0}\n\n".format(lang)
    indented_block = indent(codestr, ' ' * 4)
    return code_directive + indented_block

def
codestr2rst
(
codestr
,
lang
=
'python'
)
:
code_directive
=
"\n.. code-block:: {0}\n\n"
.
format
(
lang
)
indented_block
=
indent
(
codestr
,
' '
*
4
)
return
code_directive
+
indented_block


def get_md5sum(src_file):
    """Returns md5sum of file"""

    with open(src_file, 'r') as src_data:
        src_content = src_data.read()

        # data needs to be encoded in python3 before hashing
        if sys.version_info[0] == 3:
            src_content = src_content.encode('utf-8')

        src_md5 = hashlib.md5(src_content).hexdigest()
    return src_md5

def get_md5sum ( src_file ) : with open ( src_file , 'r' ) as src_data : src_content = src_data . read ( ) if sys . version_info [ 0 ] == 3 : src_content = src_content . encode ( 'utf-8' ) src_md5 = hashlib . md5 ( src_content ) . hexdigest ( ) return src_md5


def check_md5sum_change(src_file):
    """Returns True if src_file has a different md5sum"""

    src_md5 = get_md5sum(src_file)

    src_md5_file = src_file + '.md5'
    src_file_changed = True
    if os.path.exists(src_md5_file):
        with open(src_md5_file, 'r') as file_checksum:
            ref_md5 = file_checksum.read()
        if src_md5 == ref_md5:
            src_file_changed = False

    if src_file_changed:
        with open(src_md5_file, 'w') as file_checksum:
            file_checksum.write(src_md5)

    return src_file_changed

def check_md5sum_change ( src_file ) : src_md5 = get_md5sum ( src_file ) src_md5_file = src_file + '.md5' src_file_changed = True if os . path . exists ( src_md5_file ) : with open ( src_md5_file , 'r' ) as file_checksum : ref_md5 = file_checksum . read ( ) if src_md5 == ref_md5 : src_file_changed = False if src_file_changed : with open ( src_md5_file , 'w' ) as file_checksum : file_checksum . write ( src_md5 ) return src_file_changed


def _plots_are_current(src_file, image_file):
    """Test existence of image file and no change in md5sum of
    example"""

    first_image_file = image_file.format(1)
    has_image = os.path.exists(first_image_file)
    src_file_changed = check_md5sum_change(src_file)

    return has_image and not src_file_changed


def save_figures(image_path, fig_count, gallery_conf):
    """Save all open matplotlib figures of the example code-block

    Parameters
    ----------
    image_path : str
        Path where plots are saved (format string which accepts figure number)
    fig_count : int
        Previous figure number count. Figure number add from this number

    Returns
    -------
    list of strings containing the full path to each figure
    """
    figure_list = []

    fig_managers = matplotlib._pylab_helpers.Gcf.get_all_fig_managers()
    for fig_mngr in fig_managers:
        # Set the fig_num figure as the current figure as we can't
        # save a figure that's not the current figure.
        fig = plt.figure(fig_mngr.num)
        kwargs = {}
        to_rgba = matplotlib.colors.colorConverter.to_rgba
        for attr in ['facecolor', 'edgecolor']:
            fig_attr = getattr(fig, 'get_' + attr)()
            default_attr = matplotlib.rcParams['figure.' + attr]
            if to_rgba(fig_attr) != to_rgba(default_attr):
                kwargs[attr] = fig_attr

        current_fig = image_path.format(fig_count + fig_mngr.num)
        fig.savefig(current_fig, **kwargs)
        figure_list.append(current_fig)

    if gallery_conf.get('find_mayavi_figures', False):
        from mayavi import mlab
        e = mlab.get_engine()
        last_matplotlib_fig_num = len(figure_list)
        total_fig_num = last_matplotlib_fig_num + len(e.scenes)
        mayavi_fig_nums = range(last_matplotlib_fig_num, total_fig_num)

        for scene, mayavi_fig_num in zip(e.scenes, mayavi_fig_nums):
            current_fig = image_path.format(mayavi_fig_num)
            mlab.savefig(current_fig, figure=scene)
            # make sure the image is not too large
            scale_image(current_fig, current_fig, 850, 999)
            figure_list.append(current_fig)
        mlab.close(all=True)

    return figure_list

def save_figures ( image_path , fig_count , gallery_conf ) : figure_list = [ ] fig_managers = matplotlib . _pylab_helpers . Gcf . get_all_fig_managers ( ) for fig_mngr in fig_managers : fig = plt . figure ( fig_mngr . num ) kwargs = { } to_rgba = matplotlib . colors . colorConverter . to_rgba for attr in [ 'facecolor' , 'edgecolor' ] : fig_attr = getattr ( fig , 'get_' + attr ) ( ) default_attr = matplotlib . rcParams [ 'figure.' + attr ] if to_rgba ( fig_attr ) != to_rgba ( default_attr ) : kwargs [ attr ] = fig_attr current_fig = image_path . format ( fig_count + fig_mngr . num ) fig . savefig ( current_fig , ** kwargs ) figure_list . append ( current_fig ) if gallery_conf . get ( 'find_mayavi_figures' , False ) : from mayavi import mlab e = mlab . get_engine ( ) last_matplotlib_fig_num = len ( figure_list ) total_fig_num = last_matplotlib_fig_num + len ( e . scenes ) mayavi_fig_nums = range ( last_matplotlib_fig_num , total_fig_num ) for scene , mayavi_fig_num in zip ( e . scenes , mayavi_fig_nums ) : current_fig = image_path . format ( mayavi_fig_num ) mlab . savefig ( current_fig , figure = scene ) scale_image ( current_fig , current_fig , 850 , 999 ) figure_list . append ( current_fig ) mlab . close ( all = True ) return figure_list

Save all open matplotlib figures of the example code - block


def scale_image(in_fname, out_fname, max_width, max_height):
    """Scales an image with the same aspect ratio centered in an
       image with a given max_width and max_height
       if in_fname == out_fname the image can only be scaled down
    """
    # local import to avoid testing dependency on PIL:
    try:
        from PIL import Image
    except ImportError:
        import Image
    img = Image.open(in_fname)
    width_in, height_in = img.size
    scale_w = max_width / float(width_in)
    scale_h = max_height / float(height_in)

    if height_in * scale_w <= max_height:
        scale = scale_w
    else:
        scale = scale_h

    if scale >= 1.0 and in_fname == out_fname:
        return

    width_sc = int(round(scale * width_in))
    height_sc = int(round(scale * height_in))

    # resize the image
    img.thumbnail((width_sc, height_sc), Image.ANTIALIAS)

    # insert centered
    thumb = Image.new('RGB', (max_width, max_height), (255, 255, 255))
    pos_insert = ((max_width - width_sc) // 2, (max_height - height_sc) // 2)
    thumb.paste(img, pos_insert)

    thumb.save(out_fname)
    # Use optipng to perform lossless compression on the resized image if
    # software is installed
    if os.environ.get('SKLEARN_DOC_OPTIPNG', False):
        try:
            subprocess.call(["optipng", "-quiet", "-o", "9", out_fname])
        except Exception:
            warnings.warn('Install optipng to reduce the size of the \
                          generated images')


def save_thumbnail(image_path, base_image_name, gallery_conf):
    """Save the thumbnail image"""
    first_image_file = image_path.format(1)
    thumb_dir = os.path.join(os.path.dirname(first_image_file), 'thumb')
    if not os.path.exists(thumb_dir):
        os.makedirs(thumb_dir)

    thumb_file = os.path.join(thumb_dir,
                              'sphx_glr_%s_thumb.png' % base_image_name)

    if os.path.exists(first_image_file):
        scale_image(first_image_file, thumb_file, 400, 280)
    elif not os.path.exists(thumb_file):
        # create something to replace the thumbnail
        default_thumb_file = os.path.join(glr_path_static(), 'no_image.png')
        default_thumb_file = gallery_conf.get("default_thumb_file",
                                              default_thumb_file)
        scale_image(default_thumb_file, thumb_file, 200, 140)

def save_thumbnail ( image_path , base_image_name , gallery_conf ) : first_image_file = image_path . format ( 1 ) thumb_dir = os . path . join ( os . path . dirname ( first_image_file ) , 'thumb' ) if not os . path . exists ( thumb_dir ) : os . makedirs ( thumb_dir ) thumb_file = os . path . join ( thumb_dir , 'sphx_glr_%s_thumb.png' % base_image_name ) if os . path . exists ( first_image_file ) : scale_image ( first_image_file , thumb_file , 400 , 280 ) elif not os . path . exists ( thumb_file ) : default_thumb_file = os . path . join ( glr_path_static ( ) , 'no_image.png' ) default_thumb_file = gallery_conf . get ( "default_thumb_file" , default_thumb_file ) scale_image ( default_thumb_file , thumb_file , 200 , 140 )


def execute_script(code_block, example_globals, image_path, fig_count,
                   src_file, gallery_conf):
    """Executes the code block of the example file"""
    time_elapsed = 0
    stdout = ''

    # We need to execute the code
    print('plotting code blocks in %s' % src_file)

    plt.close('all')
    cwd = os.getcwd()
    # Redirect output to stdout and
    orig_stdout = sys.stdout

    try:
        # First cd in the original example dir, so that any file
        # created by the example get created in this directory
        os.chdir(os.path.dirname(src_file))
        my_buffer = StringIO()
        my_stdout = Tee(sys.stdout, my_buffer)
        sys.stdout = my_stdout

        t_start = time()
        exec(code_block, example_globals)
        time_elapsed = time() - t_start

        sys.stdout = orig_stdout

        my_stdout = my_buffer.getvalue().strip().expandtabs()
        if my_stdout:
            stdout = CODE_OUTPUT.format(indent(my_stdout, ' ' * 4))
        os.chdir(cwd)
        figure_list = save_figures(image_path, fig_count, gallery_conf)

        # Depending on whether we have one or more figures, we're using a
        # horizontal list or a single rst call to 'image'.
        image_list = ""
        if len(figure_list) == 1:
            figure_name = figure_list[0]
            image_list = SINGLE_IMAGE % figure_name.lstrip('/')
        elif len(figure_list) > 1:
            image_list = HLIST_HEADER
            for figure_name in figure_list:
                image_list += HLIST_IMAGE_TEMPLATE % figure_name.lstrip('/')

    except Exception:
        formatted_exception = traceback.format_exc()

        print(80 * '_')
        print('%s is not compiling:' % src_file)
        print(formatted_exception)
        print(80 * '_')

        figure_list = []
        image_list = codestr2rst(formatted_exception, lang='pytb')

        # Overrides the output thumbnail in the gallery for easy identification
        broken_img = os.path.join(glr_path_static(), 'broken_example.png')
        shutil.copyfile(broken_img, os.path.join(cwd, image_path.format(1)))
        fig_count += 1  # raise count to avoid overwriting image

        # Breaks build on first example error

        if gallery_conf['abort_on_example_error']:
            raise

    finally:
        os.chdir(cwd)
        sys.stdout = orig_stdout

    print(" - time elapsed : %.2g sec" % time_elapsed)
    code_output = "\n{0}\n\n{1}\n\n".format(image_list, stdout)

    return code_output, time_elapsed, fig_count + len(figure_list)

def
execute_script
(
code_block
,
example_globals
,
image_path
,
fig_count
,
src_file
,
gallery_conf
)
:
time_elapsed
=
0
stdout
=
''
print
(
'plotting code blocks in %s'
%
src_file
)
plt
.
close
(
'all'
)
cwd
=
os
.
getcwd
(
)
orig_stdout
=
sys
.
stdout
try
:
os
.
chdir
(
os
.
path
.
dirname
(
src_file
)
)
my_buffer
=
StringIO
(
)
my_stdout
=
Tee
(
sys
.
stdout
,
my_buffer
)
sys
.
stdout
=
my_stdout
t_start
=
time
(
)
exec
(
code_block
,
example_globals
)
time_elapsed
=
time
(
)
t_start
sys
.
stdout
=
orig_stdout
my_stdout
=
my_buffer
.
getvalue
(
)
.
strip
(
)
.
expandtabs
(
)
if
my_stdout
:
stdout
=
CODE_OUTPUT
.
format
(
indent
(
my_stdout
,
' '
*
4
)
)
os
.
chdir
(
cwd
)
figure_list
=
save_figures
(
image_path
,
fig_count
,
gallery_conf
)
image_list
=
""
if
len
(
figure_list
)
==
1
:
figure_name
=
figure_list
[
0
]
image_list
=
SINGLE_IMAGE
%
figure_name
.
lstrip
(
'/'
)
elif
len
(
figure_list
)
>
1
:
image_list
=
HLIST_HEADER
for
figure_name
in
figure_list
:
image_list
+=
HLIST_IMAGE_TEMPLATE
%
figure_name
.
lstrip
(
'/'
)
except
Exception
:
formatted_exception
=
traceback
.
format_exc
(
)
print
(
80
*
'_'
)
print
(
'%s is not compiling:'
%
src_file
)
print
(
formatted_exception
)
print
(
80
*
'_'
)
figure_list
=
[
]
image_list
=
codestr2rst
(
formatted_exception
,
lang
=
'pytb'
)
broken_img
=
os
.
path
.
join
(
glr_path_static
(
)
,
'broken_example.png'
)
shutil
.
copyfile
(
broken_img
,
os
.
path
.
join
(
cwd
,
image_path
.
format
(
1
)
)
)
fig_count
+=
1
if
gallery_conf
[
'abort_on_example_error'
]
:
raise
finally
:
os
.
chdir
(
cwd
)
sys
.
stdout
=
orig_stdout
print
(
" - time elapsed : %.2g sec"
%
time_elapsed
)
code_output
=
"\n{0}\n\n{1}\n\n"
.
format
(
image_list
,
stdout
)
return
code_output
,
time_elapsed
,
fig_count
+
len
(
figure_list
)