def create_a_record(self, name, values, ttl=<NUM_LIT>, weight=None, region=None,<EOL>set_identifier=None, alias_hosted_zone_id=None,<EOL>alias_dns_name=None):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(AResourceRecordSet, **values)<EOL>

Creates and returns an A record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:keyword int weight: *For weighted record sets only*. Among resource record
    sets that have the same combination of DNS name and type, a value
    that determines what portion of traffic for the current resource
    record set is routed to the associated location. Ranges from 0-255.
:keyword str region: *For latency-based record sets*. The Amazon EC2 region
    where the resource that is specified in this resource record set
    resides.
:keyword str set_identifier: *For weighted and latency resource record
    sets only*. An identifier that differentiates among multiple
    resource record sets that have the same combination of DNS name
    and type. 1-128 chars.
:keyword str alias_hosted_zone_id: Alias A records have this specified.
    It appears to be the hosted zone ID for the ELB the Alias points at.
:keyword str alias_dns_name: Alias A records have this specified. It is
    the DNS name for the ELB that the Alias points to.
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created
    :py:class:`AResourceRecordSet <route53.resource_record_set.AResourceRecordSet>`
    instance.


def create_aaaa_record(self, name, values, ttl=<NUM_LIT>, weight=None, region=None,<EOL>set_identifier=None):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(AAAAResourceRecordSet, **values)<EOL>

Creates an AAAA record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:keyword int weight: *For weighted record sets only*. Among resource record
    sets that have the same combination of DNS name and type, a value
    that determines what portion of traffic for the current resource
    record set is routed to the associated location. Ranges from 0-255.
:keyword str region: *For latency-based record sets*. The Amazon EC2 region
    where the resource that is specified in this resource record set
    resides.
:keyword str set_identifier: *For weighted and latency resource record
    sets only*. An identifier that differentiates among multiple
    resource record sets that have the same combination of DNS name
    and type. 1-128 chars.
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created AAAAResourceRecordSet instance.


def create_cname_record(self, name, values, ttl=<NUM_LIT>, weight=None, region=None,<EOL>set_identifier=None):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(CNAMEResourceRecordSet, **values)<EOL>

Creates a CNAME record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:keyword int weight: *For weighted record sets only*. Among resource record
    sets that have the same combination of DNS name and type, a value
    that determines what portion of traffic for the current resource
    record set is routed to the associated location. Ranges from 0-255.
:keyword str region: *For latency-based record sets*. The Amazon EC2 region
    where the resource that is specified in this resource record set
    resides.
:keyword str set_identifier: *For weighted and latency resource record
    sets only*. An identifier that differentiates among multiple
    resource record sets that have the same combination of DNS name
    and type. 1-128 chars.
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created CNAMEResourceRecordSet instance.


def create_mx_record(self, name, values, ttl=<NUM_LIT>):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(MXResourceRecordSet, **values)<EOL>

Creates a MX record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created MXResourceRecordSet instance.


def create_ns_record(self, name, values, ttl=<NUM_LIT>):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(NSResourceRecordSet, **values)<EOL>

Creates a NS record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created NSResourceRecordSet instance.


def create_ptr_record(self, name, values, ttl=<NUM_LIT>):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(PTRResourceRecordSet, **values)<EOL>

Creates a PTR record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created PTRResourceRecordSet instance.


def create_spf_record(self, name, values, ttl=<NUM_LIT>):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(SPFResourceRecordSet, **values)<EOL>

Creates a SPF record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created SPFResourceRecordSet instance.


def create_srv_record(self, name, values, ttl=<NUM_LIT>):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(SRVResourceRecordSet, **values)<EOL>

Creates a SRV record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created SRVResourceRecordSet instance.


def create_txt_record(self, name, values, ttl=<NUM_LIT>, weight=None, region=None,<EOL>set_identifier=None):

self._halt_if_already_deleted()<EOL>values = locals()<EOL>del values['<STR_LIT>']<EOL>return self._add_record(TXTResourceRecordSet, **values)<EOL>

Creates a TXT record attached to this hosted zone.

:param str name: The fully qualified name of the record to add.
:param list values: A list of value strings for the record.
:keyword int ttl: The time-to-live of the record (in seconds).
:keyword int weight: *For weighted record sets only*. Among resource record
    sets that have the same combination of DNS name and type, a value
    that determines what portion of traffic for the current resource
    record set is routed to the associated location. Ranges from 0-255.
:keyword str region: *For latency-based record sets*. The Amazon EC2 region
    where the resource that is specified in this resource record set
    resides.
:keyword str set_identifier: *For weighted and latency resource record
    sets only*. An identifier that differentiates among multiple
    resource record sets that have the same combination of DNS name
    and type. 1-128 chars.
:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created TXTResourceRecordSet instance.


def connect(aws_access_key_id=None, aws_secret_access_key=None, **kwargs):

from route53.connection import Route53Connection<EOL>return Route53Connection(<EOL>aws_access_key_id,<EOL>aws_secret_access_key,<EOL>**kwargs<EOL>)<EOL>

Instantiates and returns a :py:class:`route53.connection.Route53Connection`
instance, which is how you'll start your interactions with the Route 53
API.

:keyword str aws_access_key_id: Your AWS Access Key ID
:keyword str aws_secret_access_key: Your AWS Secret Access Key

:rtype: :py:class:`route53.connection.Route53Connection`
:return: A connection to Amazon's Route 53


self.connection = connection<EOL>

:param Route53Connection connection: The connection being used with
    the transport. The connection contains their AWS credentials
    and a few other settings.


return self.connection._endpoint<EOL>

:rtype: str
:returns: The Route53 API endpoint to query against.


<EOL>new_hmac = hmac.new(<EOL>self.connection._aws_secret_access_key.encode('<STR_LIT:utf-8>'),<EOL>digestmod=hashlib.sha256<EOL>)<EOL>new_hmac.update(string_to_sign.encode('<STR_LIT:utf-8>'))<EOL>digest = new_hmac.digest()<EOL>return base64.b64encode(digest).decode('<STR_LIT:utf-8>')<EOL>

Route53 uses AWS an HMAC-based authentication scheme, involving the
signing of a date string with the user's secret access key. More details
on the specifics can be found in their documentation_.

.. documentation:: http://docs.amazonwebservices.com/Route53/latest/DeveloperGuide/RESTAuthentication.html

This method is used to sign said time string, for use in the request
headers.

:param str string_to_sign: The time string to sign.
:rtype: str
:returns: An HMAC signed string.


date_header = time.asctime(time.gmtime())<EOL>signing_key = self._hmac_sign_string(date_header)<EOL>auth_header = "<STR_LIT>" % (<EOL>self.connection._aws_access_key_id,<EOL>signing_key,<EOL>)<EOL>return {<EOL>'<STR_LIT>': auth_header,<EOL>'<STR_LIT>': date_header,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}<EOL>

Determine the headers to send along with the request. These are
pretty much the same for every request, with Route53.


def send_request(self, path, data, method):

headers = self.get_request_headers()<EOL>if method == '<STR_LIT:GET>':<EOL><INDENT>return self._send_get_request(path, data, headers)<EOL><DEDENT>elif method == '<STR_LIT:POST>':<EOL><INDENT>return self._send_post_request(path, data, headers)<EOL><DEDENT>elif method == '<STR_LIT>':<EOL><INDENT>return self._send_delete_request(path, headers)<EOL><DEDENT>else:<EOL><INDENT>raise Route53Error("<STR_LIT>" % method)<EOL><DEDENT>

All outbound requests go through this method. It defers to the
transport's various HTTP method-specific methods.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param data: The params to send along with the request.
:type data: Either a dict or bytes, depending on the request type.
:param str method: One of 'GET', 'POST', or 'DELETE'.

:rtype: str
:returns: The body of the response.


def _send_get_request(self, path, params, headers):

raise NotImplementedError<EOL>

Transport sub-classes need to override this.

Sends the GET request to the Route53 endpoint.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param dict params: Key/value pairs to send.
:param dict headers: A dict of headers to send with the request.
:rtype: str
:returns: The body of the response.


def _send_post_request(self, path, data, headers):

raise NotImplementedError<EOL>

Transport sub-classes need to override this.

Sends the POST request to the Route53 endpoint.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param data: Either a dict, or bytes.
:type data: dict or bytes
:param dict headers: A dict of headers to send with the request.
:rtype: str
:returns: The body of the response.


def _send_delete_request(self, path, headers):

raise NotImplementedError<EOL>

Transport sub-classes need to override this.

Sends the DELETE request to the Route53 endpoint.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param dict headers: A dict of headers to send with the request.
:rtype: str
:returns: The body of the response.


r = requests.get(self.endpoint + path, params=params, headers=headers)<EOL>r.raise_for_status()<EOL>return r.text<EOL>

Sends the GET request to the Route53 endpoint.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param dict params: Key/value pairs to send.
:param dict headers: A dict of headers to send with the request.
:rtype: str
:returns: The body of the response.


r = requests.post(self.endpoint + path, data=data, headers=headers)<EOL>return r.text<EOL>

Sends the POST request to the Route53 endpoint.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param data: Either a dict, or bytes.
:type data: dict or bytes
:param dict headers: A dict of headers to send with the request.
:rtype: str
:returns: The body of the response.


r = requests.delete(self.endpoint + path, headers=headers)<EOL>return r.text<EOL>

Sends the DELETE request to the Route53 endpoint.

:param str path: The path to tack on to the endpoint URL for
    the query.
:param dict headers: A dict of headers to send with the request.
:rtype: str
:returns: The body of the response.


alias_hosted_zone_id = e_alias.find('<STR_LIT>').text<EOL>alias_dns_name = e_alias.find('<STR_LIT>').text<EOL>return alias_hosted_zone_id, alias_dns_name<EOL>

Parses an Alias tag beneath a ResourceRecordSet, spitting out the two values
found within. This is specific to A records that are set to Alias.

:param lxml.etree._Element e_alias: An Alias tag beneath a ResourceRecordSet.
:rtype: tuple
:returns: A tuple in the form of ``(alias_hosted_zone_id, alias_dns_name)``.


records = []<EOL>for e_record in e_resource_records:<EOL><INDENT>for e_value in e_record:<EOL><INDENT>records.append(e_value.text)<EOL><DEDENT><DEDENT>return records<EOL>

Used to parse the various Values from the ResourceRecords tags on
most rrset types.

:param lxml.etree._Element e_resource_records: A ResourceRecords tag
    beneath a ResourceRecordSet.
:rtype: list
:returns: A list of resource record strings.


def parse_rrset(e_rrset, connection, zone_id):

<EOL>kwargs = {<EOL>'<STR_LIT>': connection,<EOL>'<STR_LIT>': zone_id,<EOL>}<EOL>rrset_type = None<EOL>for e_field in e_rrset:<EOL><INDENT>tag_name = e_field.tag.split('<STR_LIT:}>')[<NUM_LIT:1>]<EOL>field_text = e_field.text<EOL>if tag_name == '<STR_LIT>':<EOL><INDENT>rrset_type = field_text<EOL>continue<EOL><DEDENT>elif tag_name == '<STR_LIT>':<EOL><INDENT>alias_hosted_zone_id, alias_dns_name = parse_rrset_alias(e_field)<EOL>kwargs['<STR_LIT>'] = alias_hosted_zone_id<EOL>kwargs['<STR_LIT>'] = alias_dns_name<EOL>kwargs['<STR_LIT>'] = None<EOL>continue<EOL><DEDENT>elif tag_name == '<STR_LIT>':<EOL><INDENT>kwargs['<STR_LIT>'] = parse_rrset_record_values(e_field)<EOL>continue<EOL><DEDENT>kw_name = RRSET_TAG_TO_KWARG_MAP[tag_name]<EOL>kwargs[kw_name] = field_text<EOL><DEDENT>if not rrset_type:<EOL><INDENT>raise Route53Error("<STR_LIT>")<EOL><DEDENT>if '<STR_LIT>' not in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = []<EOL><DEDENT>RRSetSubclass = RRSET_TYPE_TO_RSET_SUBCLASS_MAP[rrset_type]<EOL>return RRSetSubclass(**kwargs)<EOL>

This a parser that allows the passing of any valid ResourceRecordSet
tag. It will spit out the appropriate ResourceRecordSet object for the tag.

:param lxml.etree._Element e_rrset: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:param str zone_id: The zone ID of the HostedZone these rrsets belong to.
:rtype: ResourceRecordSet
:returns: An instantiated ResourceRecordSet object.


def list_resource_record_sets_by_zone_id_parser(e_root, connection, zone_id):

<EOL>e_rrsets = e_root.find('<STR_LIT>')<EOL>for e_rrset in e_rrsets:<EOL><INDENT>yield parse_rrset(e_rrset, connection, zone_id)<EOL><DEDENT>

Parses the API responses for the
:py:meth:`route53.connection.Route53Connection.list_resource_record_sets_by_zone_id`
method.

:param lxml.etree._Element e_root: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:param str zone_id: The zone ID of the HostedZone these rrsets belong to.
:rtype: ResourceRecordSet
:returns: A generator of fully formed ResourceRecordSet instances.


if e_change_info is None:<EOL><INDENT>return e_change_info<EOL><DEDENT>status = e_change_info.find('<STR_LIT>').text<EOL>submitted_at = e_change_info.find('<STR_LIT>').text<EOL>submitted_at = parse_iso_8601_time_str(submitted_at)<EOL>return {<EOL>'<STR_LIT>': id,<EOL>'<STR_LIT>': status,<EOL>'<STR_LIT>': submitted_at<EOL>}<EOL>

Parses a ChangeInfo tag. Seen in CreateHostedZone, DeleteHostedZone,
and ChangeResourceRecordSetsRequest.

:param lxml.etree._Element e_change_info: A ChangeInfo element.
:rtype: dict
:returns: A dict representation of the change info.


e_change_info = root.find('<STR_LIT>')<EOL>return parse_change_info(e_change_info)<EOL>

Parses the API responses for the
:py:meth:`route53.connection.Route53Connection.delete_hosted_zone_by_id` method.

:param lxml.etree._Element root: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:rtype: dict
:returns: Details about the deletion.


zone = root.find('<STR_LIT>')<EOL>hosted_zone = parse_hosted_zone(zone, connection)<EOL>e_delegation_set = root.find('<STR_LIT>')<EOL>parse_delegation_set(hosted_zone, e_delegation_set)<EOL>e_change_info = root.find('<STR_LIT>')<EOL>change_info = parse_change_info(e_change_info)<EOL>return hosted_zone, change_info<EOL>

Parses the API responses for the
:py:meth:`route53.connection.Route53Connection.create_hosted_zone` method.

:param lxml.etree._Element root: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:rtype: HostedZone
:returns: The newly created HostedZone.


e_zone = root.find('<STR_LIT>')<EOL>hosted_zone =  parse_hosted_zone(e_zone, connection)<EOL>e_delegation_set = root.find('<STR_LIT>')<EOL>parse_delegation_set(hosted_zone, e_delegation_set)<EOL>return hosted_zone<EOL>

Parses the API responses for the
:py:meth:`route53.connection.Route53Connection.get_hosted_zone_by_id` method.

:param lxml.etree._Element root: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:rtype: HostedZone
:returns: The requested HostedZone.


<EOL>zones = root.find('<STR_LIT>')<EOL>for zone in zones:<EOL><INDENT>yield parse_hosted_zone(zone, connection)<EOL><DEDENT>

Parses the API responses for the
:py:meth:`route53.connection.Route53Connection.list_hosted_zones` method.

:param lxml.etree._Element root: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:rtype: HostedZone
:returns: A generator of fully formed HostedZone instances.


<EOL>kwargs = {}<EOL>for e_field in e_zone:<EOL><INDENT>tag_name = e_field.tag.split('<STR_LIT:}>')[<NUM_LIT:1>]<EOL>field_text = e_field.text<EOL>if tag_name == '<STR_LIT>':<EOL><INDENT>e_comment = e_field.find('<STR_LIT>')<EOL>kwargs['<STR_LIT>'] = e_comment.text if e_comment is not None else None<EOL>continue<EOL><DEDENT>elif tag_name == '<STR_LIT>':<EOL><INDENT>field_text = field_text.strip('<STR_LIT>')<EOL><DEDENT>kw_name = HOSTED_ZONE_TAG_TO_KWARG_MAP[tag_name]<EOL>kwargs[kw_name] = field_text<EOL><DEDENT>return HostedZone(connection, **kwargs)<EOL>

This a common parser that allows the passing of any valid HostedZone
tag. It will spit out the appropriate HostedZone object for the tag.

:param lxml.etree._Element e_zone: The root node of the etree parsed
    response from the API.
:param Route53Connection connection: The connection instance used to
    query the API.
:rtype: HostedZone
:returns: An instantiated HostedZone object.


e_nameservers = e_delegation_set.find('<STR_LIT>')<EOL>nameservers = []<EOL>for e_nameserver in e_nameservers:<EOL><INDENT>nameservers.append(e_nameserver.text)<EOL><DEDENT>zone._nameservers = nameservers<EOL>

Parses a DelegationSet tag. These often accompany HostedZone tags in
responses like CreateHostedZone and GetHostedZone.

:param HostedZone zone: An existing HostedZone instance to populate.
:param lxml.etree._Element e_delegation_set: A DelegationSet element.


<EOL>_, conf = read_latoolscfg()<EOL>if config == '<STR_LIT>':<EOL><INDENT>config = conf['<STR_LIT>']['<STR_LIT>']<EOL><DEDENT>conf = dict(conf[config])<EOL>conf['<STR_LIT>'] = config<EOL>return conf<EOL>

Read LAtools configuration file, and return parameters as dict.


config_file = pkgrs.resource_filename('<STR_LIT>', '<STR_LIT>')<EOL>cf = configparser.ConfigParser()<EOL>cf.read(config_file)<EOL>return config_file, cf<EOL>

Reads configuration, returns a ConfigParser object.

Distinct from read_configuration, which returns a dict.


loc = pkgrs.resource_filename('<STR_LIT>', '<STR_LIT>')<EOL>print(loc)<EOL>return loc<EOL>

Prints and returns the location of the latools.cfg file.


<EOL>_, conf = read_latoolscfg()<EOL>default = conf['<STR_LIT>']['<STR_LIT>']<EOL>pstr = '<STR_LIT>'<EOL>for s in conf.sections():<EOL><INDENT>if s == default:<EOL><INDENT>pstr += s + '<STR_LIT>'<EOL><DEDENT>elif s == '<STR_LIT>':<EOL><INDENT>pstr += s + '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>pstr += s + '<STR_LIT:\n>'<EOL><DEDENT>for k, v in conf[s].items():<EOL><INDENT>if k != '<STR_LIT>':<EOL><INDENT>if v[:<NUM_LIT:9>] == '<STR_LIT>':<EOL><INDENT>v = pkgrs.resource_filename('<STR_LIT>', v)<EOL><DEDENT>pstr += '<STR_LIT:U+0020>' + k + '<STR_LIT>' + v + '<STR_LIT:\n>'<EOL><DEDENT><DEDENT>pstr += '<STR_LIT:\n>'<EOL><DEDENT>print(pstr)<EOL>return<EOL>

Prints all currently defined configurations.


<EOL>conf = read_configuration()<EOL>src = pkgrs.resource_filename('<STR_LIT>', conf['<STR_LIT>'])<EOL>if destination is None:<EOL><INDENT>destination = '<STR_LIT>' + conf['<STR_LIT>'] + '<STR_LIT>'<EOL><DEDENT>if os.path.isdir(destination):<EOL><INDENT>destination += '<STR_LIT>' + conf['<STR_LIT>'] + '<STR_LIT>'<EOL><DEDENT>copyfile(src, destination)<EOL>print(src + '<STR_LIT>' + destination)<EOL>return<EOL>

Creates a copy of the default SRM table at the specified location.

Parameters
----------
destination : str
    The save location for the SRM file. If no location specified,
    saves it as 'LAtools_[config]_SRMTable.csv' in the current working
    directory.
config : str
    It's possible to set up different configurations with different
    SRM files. This specifies the name of the configuration that you
    want to copy the SRM file from. If not specified, the 'DEFAULT'
    configuration is used.


def create(config_name, srmfile=None, dataformat=None, base_on='<STR_LIT>', make_default=False):

base_config = read_configuration(base_on)<EOL>config_file, cf = read_latoolscfg()<EOL>if config_name not in cf.sections():<EOL><INDENT>cf.add_section(config_name)<EOL><DEDENT>if dataformat is None:<EOL><INDENT>dataformat = base_config['<STR_LIT>']<EOL><DEDENT>cf.set(config_name, '<STR_LIT>', dataformat)<EOL>if srmfile is None:<EOL><INDENT>srmfile = base_config['<STR_LIT>']<EOL><DEDENT>cf.set(config_name, '<STR_LIT>', srmfile)<EOL>if make_default:<EOL><INDENT>cf.set('<STR_LIT>', '<STR_LIT>', config_name)<EOL><DEDENT>with open(config_file, '<STR_LIT:w>') as f:<EOL><INDENT>cf.write(f)<EOL><DEDENT>return<EOL>

Adds a new configuration to latools.cfg.

Parameters
----------
config_name : str
    The name of the new configuration. This should be descriptive
    (e.g. UC Davis Foram Group)
srmfile : str (optional)
    The location of the srm file used for calibration.
dataformat : str (optional)
    The location of the dataformat definition to use.
base_on : str
    The name of the existing configuration to base the new one on.
    If either srm_file or dataformat are not specified, the new
    config will copy this information from the base_on config.
make_default : bool
    Whether or not to make the new configuration the default
    for future analyses. Default = False.

Returns
-------
None


config_file, cf = read_latoolscfg()<EOL>if config not in cf.sections():<EOL><INDENT>raise ValueError("<STR_LIT>".format(config))<EOL><DEDENT>if config == '<STR_LIT>':<EOL><INDENT>pstr = ('<STR_LIT>' + <EOL>'<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>pstr = ('<STR_LIT>'.format(cf['<STR_LIT>']['<STR_LIT>']) + <EOL>'<STR_LIT>'.format(config))<EOL><DEDENT>response = input(pstr + '<STR_LIT>')<EOL>if response.lower() == '<STR_LIT:y>':<EOL><INDENT>cf.set('<STR_LIT>', '<STR_LIT>', config)<EOL>with open(config_file, '<STR_LIT:w>') as f:<EOL><INDENT>cf.write(f)<EOL><DEDENT>print('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>print('<STR_LIT>')<EOL><DEDENT>


template_file = pkgrs.resource_filename('<STR_LIT>', '<STR_LIT>')<EOL>copyfile(template_file, destination)<EOL>return<EOL>

Copies a data format description JSON template to the specified location.


@wraps(func)<EOL>def wrapper(self, *args, **kwargs):<EOL><INDENT>a = func(self, *args, **kwargs)<EOL>self.log.append(func.__name__ + '<STR_LIT>'.format(args, kwargs))<EOL>return a<EOL><DEDENT>return wrapper<EOL>

Function for logging method calls and parameters


def write_logfile(log, header, file_name):

path, ext = os.path.splitext(file_name)<EOL>if ext == '<STR_LIT>':<EOL><INDENT>ext = '<STR_LIT>'<EOL><DEDENT>with open(path + ext, '<STR_LIT:w>') as f:<EOL><INDENT>f.write('<STR_LIT:\n>'.join(header))<EOL>f.write('<STR_LIT:\n>'.join(log))<EOL><DEDENT>return path + ext<EOL>

Write and analysis log to a file.

Parameters
----------
log : list
    latools.analyse analysis log
header : list
    File header lines.
file_name : str
    Destination file. If no file extension
    specified, uses '.lalog'

Returns
-------
None


dirname = os.path.dirname(log_file) + '<STR_LIT:/>'<EOL>with open(log_file, '<STR_LIT:r>') as f:<EOL><INDENT>rlog = f.readlines()<EOL><DEDENT>hashind = [i for i, n in enumerate(rlog) if '<STR_LIT:#>' in n]<EOL>pathread = re.compile('<STR_LIT>')<EOL>paths = (pathread.match(l).groups() for l in rlog[hashind[<NUM_LIT:0>] + <NUM_LIT:1>:hashind[-<NUM_LIT:1>]] if pathread.match(l))<EOL>paths = {k: os.path.join(dirname, v) for k, v in paths}<EOL>logread = re.compile('<STR_LIT>')<EOL>runargs = []<EOL>for line in rlog[hashind[<NUM_LIT:1>] + <NUM_LIT:1>:]:<EOL><INDENT>fname, args, kwargs = (logread.match(line).groups())<EOL>runargs.append((fname ,{'<STR_LIT:args>': eval(args), '<STR_LIT>': eval(kwargs)}))<EOL>if fname == '<STR_LIT>':<EOL><INDENT>runargs[-<NUM_LIT:1>][-<NUM_LIT:1>]['<STR_LIT>']['<STR_LIT>'] = '<STR_LIT>'<EOL>runargs[-<NUM_LIT:1>][-<NUM_LIT:1>]['<STR_LIT>']['<STR_LIT>'] = None<EOL>runargs[-<NUM_LIT:1>][-<NUM_LIT:1>]['<STR_LIT>']['<STR_LIT>'] = paths['<STR_LIT>']<EOL>if '<STR_LIT>' in paths:<EOL><INDENT>runargs[-<NUM_LIT:1>][-<NUM_LIT:1>]['<STR_LIT>']['<STR_LIT>'] = paths['<STR_LIT>']<EOL><DEDENT><DEDENT><DEDENT>return runargs, paths<EOL>

Reads an latools analysis.log file, and returns dicts of arguments.

Parameters
----------
log_file : str
    Path to an analysis.log file produced by latools.

Returns
-------
runargs, paths : tuple
    Two dictionaries. runargs contains all the arguments required to run each step
    of analysis in the form (function_name, {'args': (), 'kwargs': {}}). paths contains
    the locations of the data directory and the SRM database used for analysis.


el = pd.read_pickle(pkgrs.resource_filename('<STR_LIT>', '<STR_LIT>'))<EOL>if all_isotopes:<EOL><INDENT>return el.set_index('<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>def wmean(g):<EOL><INDENT>return (g.atomic_weight * g.percent).sum() / <NUM_LIT:100><EOL><DEDENT>iel = el.groupby('<STR_LIT>').apply(wmean)<EOL>iel.name = '<STR_LIT>'<EOL>return iel<EOL><DEDENT>

Loads a DataFrame of all elements and isotopes.

Scraped from https://www.webelements.com/

Returns
-------
pandas DataFrame with columns (element, atomic_number, isotope, atomic_weight, percent)


<EOL>els = elements()<EOL>parens = re.compile('<STR_LIT>')<EOL>stoich = re.compile('<STR_LIT>')<EOL>ps = parens.findall(molecule)  <EOL>rem = parens.sub('<STR_LIT>', molecule)  <EOL>m = <NUM_LIT:0><EOL>if len(ps) > <NUM_LIT:0>:<EOL><INDENT>for sub, ns in ps:<EOL><INDENT>ms = <NUM_LIT:0><EOL>for e, n in stoich.findall(sub):<EOL><INDENT>me = (els.loc[e, '<STR_LIT>'] *<EOL>els.loc[e, '<STR_LIT>'] / <NUM_LIT:100>).sum()<EOL>if n == '<STR_LIT>':<EOL><INDENT>n = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>n = int(n)<EOL><DEDENT>ms += me * n<EOL><DEDENT>if ns == '<STR_LIT>':<EOL><INDENT>ns = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>ns = int(ns)<EOL><DEDENT>m += ms * ns<EOL><DEDENT><DEDENT>for e, n in stoich.findall(rem):<EOL><INDENT>me = (els.loc[e, '<STR_LIT>'] *<EOL>els.loc[e, '<STR_LIT>'] / <NUM_LIT:100>).sum()<EOL>if n == '<STR_LIT>':<EOL><INDENT>n = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>n = int(n)<EOL><DEDENT>m += me * n<EOL><DEDENT>return m<EOL>

Returns molecular weight of molecule.

Where molecule is in standard chemical notation,
e.g. 'CO2', 'HCO3' or B(OH)4

Returns
-------
molecular_weight : float


def to_molar_ratio(massfrac_numerator, massfrac_denominator, numerator_mass, denominator_mass):

return (massfrac_numerator / numerator_mass) / (massfrac_denominator / denominator_mass)<EOL>

Converts per-mass concentrations to molar elemental ratios.

Be careful with units.

Parameters
----------
numerator_mass, denominator_mass : float or array-like
    The atomic mass of the numerator and denominator.
massfrac_numerator, massfrac_denominator : float or array-like
    The per-mass fraction of the numnerator and denominator.

Returns
-------
float or array-like : The molar ratio of elements in the material


def to_mass_fraction(molar_ratio, massfrac_denominator, numerator_mass, denominator_mass):

return molar_ratio * massfrac_denominator * numerator_mass / denominator_mass<EOL>

Converts per-mass concentrations to molar elemental ratios.

Be careful with units.

Parameters
----------
molar_ratio : float or array-like
    The molar ratio of elements.
massfrac_denominator : float or array-like
    The mass fraction of the denominator element
numerator_mass, denominator_mass : float or array-like
    The atomic mass of the numerator and denominator.

Returns
-------
float or array-like : The mass fraction of the numerator element.


def tplot(self, analytes=None, figsize=[<NUM_LIT:10>, <NUM_LIT:4>], scale='<STR_LIT>', filt=None,<EOL>ranges=False, stats=False, stat='<STR_LIT>', err='<STR_LIT>',<EOL>focus_stage=None, err_envelope=False, ax=None):

if type(analytes) is str:<EOL><INDENT>analytes = [analytes]<EOL><DEDENT>if analytes is None:<EOL><INDENT>analytes = self.analytes<EOL><DEDENT>if focus_stage is None:<EOL><INDENT>focus_stage = self.focus_stage<EOL><DEDENT>if focus_stage in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>analytes = [a for a in analytes if a != self.internal_standard]<EOL><DEDENT>if ax is None:<EOL><INDENT>fig = plt.figure(figsize=figsize)<EOL>ax = fig.add_axes([<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>])<EOL>ret = True<EOL><DEDENT>else:<EOL><INDENT>fig = ax.figure<EOL>ret = False<EOL><DEDENT>for a in analytes:<EOL><INDENT>x = self.Time<EOL>y, yerr = unpack_uncertainties(self.data[focus_stage][a])<EOL>if scale is '<STR_LIT>':<EOL><INDENT>ax.set_yscale('<STR_LIT>')<EOL>y[y == <NUM_LIT:0>] = np.nan<EOL><DEDENT>if filt:<EOL><INDENT>ind = self.filt.grab_filt(filt, a)<EOL>xf = x.copy()<EOL>yf = y.copy()<EOL>yerrf = yerr.copy()<EOL>if any(~ind):<EOL><INDENT>xf[~ind] = np.nan<EOL>yf[~ind] = np.nan<EOL>yerrf[~ind] = np.nan<EOL><DEDENT>if any(~ind):<EOL><INDENT>ax.plot(x, y, color=self.cmap[a], alpha=<NUM_LIT>, lw=<NUM_LIT>)<EOL><DEDENT>ax.plot(xf, yf, color=self.cmap[a], label=a)<EOL>if err_envelope:<EOL><INDENT>ax.fill_between(xf, yf - yerrf, yf + yerrf, color=self.cmap[a],<EOL>alpha=<NUM_LIT>, zorder=-<NUM_LIT:1>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ax.plot(x, y, color=self.cmap[a], label=a)<EOL>if err_envelope:<EOL><INDENT>ax.fill_between(x, y - yerr, y + yerr, color=self.cmap[a],<EOL>alpha=<NUM_LIT>, zorder=-<NUM_LIT:1>)<EOL><DEDENT><DEDENT>if stats and hasattr(self, '<STR_LIT>'):<EOL><INDENT>warnings.warn('<STR_LIT>')<EOL>pass<EOL><DEDENT><DEDENT>if ranges:<EOL><INDENT>for lims in self.bkgrng:<EOL><INDENT>ax.axvspan(*lims, color='<STR_LIT:k>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:1>)<EOL><DEDENT>for lims in self.sigrng:<EOL><INDENT>ax.axvspan(*lims, color='<STR_LIT:r>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:1>)<EOL><DEDENT><DEDENT>ax.text(<NUM_LIT>, <NUM_LIT>, self.sample + '<STR_LIT>' + focus_stage,<EOL>transform=ax.transAxes,<EOL>ha='<STR_LIT:left>', va='<STR_LIT>')<EOL>ax.set_xlabel('<STR_LIT>')<EOL>ax.set_xlim(np.nanmin(x), np.nanmax(x))<EOL>ud = {'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'}<EOL>if focus_stage in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>ud[focus_stage] = ud[focus_stage].format(self.internal_standard)<EOL><DEDENT>ax.set_ylabel(ud[focus_stage])<EOL>ax.legend(bbox_to_anchor=(<NUM_LIT>, <NUM_LIT:1>))<EOL>if ret:<EOL><INDENT>return fig, ax<EOL><DEDENT>

Plot analytes as a function of Time.

Parameters
----------
analytes : array_like
    list of strings containing names of analytes to plot.
    None = all analytes.
figsize : tuple
    size of final figure.
scale : str or None
   'log' = plot data on log scale
filt : bool, str or dict
    False: plot unfiltered data.
    True: plot filtered data over unfiltered data.
    str: apply filter key to all analytes
    dict: apply key to each analyte in dict. Must contain all
    analytes plotted. Can use self.filt.keydict.
ranges : bool
    show signal/background regions.
stats : bool
    plot average and error of each trace, as specified by `stat` and
    `err`.
stat : str
    average statistic to plot.
err : str
    error statistic to plot.

Returns
-------
figure, axis


def gplot(self, analytes=None, win=<NUM_LIT>, figsize=[<NUM_LIT:10>, <NUM_LIT:4>],<EOL>ranges=False, focus_stage=None, ax=None, recalc=True):

if type(analytes) is str:<EOL><INDENT>analytes = [analytes]<EOL><DEDENT>if analytes is None:<EOL><INDENT>analytes = self.analytes<EOL><DEDENT>if focus_stage is None:<EOL><INDENT>focus_stage = self.focus_stage<EOL><DEDENT>if ax is None:<EOL><INDENT>fig = plt.figure(figsize=figsize)<EOL>ax = fig.add_axes([<NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT>])<EOL>ret = True<EOL><DEDENT>else:<EOL><INDENT>fig = ax.figure<EOL>ret = False<EOL><DEDENT>x = self.Time<EOL>if recalc or not self.grads_calced:<EOL><INDENT>self.grads = calc_grads(x, self.data[focus_stage], analytes, win)<EOL>self.grads_calce = True<EOL><DEDENT>for a in analytes:<EOL><INDENT>ax.plot(x, self.grads[a], color=self.cmap[a], label=a)<EOL><DEDENT>if ranges:<EOL><INDENT>for lims in self.bkgrng:<EOL><INDENT>ax.axvspan(*lims, color='<STR_LIT:k>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:1>)<EOL><DEDENT>for lims in self.sigrng:<EOL><INDENT>ax.axvspan(*lims, color='<STR_LIT:r>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:1>)<EOL><DEDENT><DEDENT>ax.text(<NUM_LIT>, <NUM_LIT>, self.sample + '<STR_LIT>' + self.focus_stage + '<STR_LIT>',<EOL>transform=ax.transAxes,<EOL>ha='<STR_LIT:left>', va='<STR_LIT>')<EOL>ax.set_xlabel('<STR_LIT>')<EOL>ax.set_xlim(np.nanmin(x), np.nanmax(x))<EOL>ud = {'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>'}<EOL>if focus_stage in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>ud[focus_stage] = ud[focus_stage].format(self.internal_standard)<EOL><DEDENT>ax.set_ylabel(ud[focus_stage])<EOL>def yfmt(x, p):<EOL><INDENT>return '<STR_LIT>'.format(x)<EOL><DEDENT>ax.yaxis.set_major_formatter(mpl.ticker.FuncFormatter(yfmt))<EOL>ax.legend(bbox_to_anchor=(<NUM_LIT>, <NUM_LIT:1>))<EOL>ax.axhline(<NUM_LIT:0>, color='<STR_LIT:k>', lw=<NUM_LIT:1>, ls='<STR_LIT>', alpha=<NUM_LIT:0.5>)<EOL>if ret:<EOL><INDENT>return fig, ax<EOL><DEDENT>

Plot analytes gradients as a function of Time.

Parameters
----------
analytes : array_like
    list of strings containing names of analytes to plot.
    None = all analytes.
win : int
    The window over which to calculate the rolling gradient.
figsize : tuple
    size of final figure.
ranges : bool
    show signal/background regions.

Returns
-------
figure, axis


def crossplot(dat, keys=None, lognorm=True, bins=<NUM_LIT>, figsize=(<NUM_LIT:12>, <NUM_LIT:12>),<EOL>colourful=True, focus_stage=None, denominator=None,<EOL>mode='<STR_LIT>', cmap=None, **kwargs):

if keys is None:<EOL><INDENT>keys = list(dat.keys())<EOL><DEDENT>numvar = len(keys)<EOL>if figsize[<NUM_LIT:0>] < <NUM_LIT> * numvar:<EOL><INDENT>figsize = [<NUM_LIT> * numvar] * <NUM_LIT:2><EOL><DEDENT>fig, axes = plt.subplots(nrows=numvar, ncols=numvar,<EOL>figsize=(<NUM_LIT:12>, <NUM_LIT:12>))<EOL>fig.subplots_adjust(hspace=<NUM_LIT>, wspace=<NUM_LIT>)<EOL>for ax in axes.flat:<EOL><INDENT>ax.xaxis.set_visible(False)<EOL>ax.yaxis.set_visible(False)<EOL>if ax.is_first_col():<EOL><INDENT>ax.yaxis.set_ticks_position('<STR_LIT:left>')<EOL><DEDENT>if ax.is_last_col():<EOL><INDENT>ax.yaxis.set_ticks_position('<STR_LIT:right>')<EOL><DEDENT>if ax.is_first_row():<EOL><INDENT>ax.xaxis.set_ticks_position('<STR_LIT>')<EOL><DEDENT>if ax.is_last_row():<EOL><INDENT>ax.xaxis.set_ticks_position('<STR_LIT>')<EOL><DEDENT><DEDENT>if colourful:<EOL><INDENT>cmlist = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>cmlist = ['<STR_LIT>']<EOL><DEDENT>if cmap is None and mode == '<STR_LIT>':<EOL><INDENT>cmap = {k: '<STR_LIT:k>' for k in dat.keys()}<EOL><DEDENT>while len(cmlist) < len(keys):<EOL><INDENT>cmlist *= <NUM_LIT:2><EOL><DEDENT>focus = {k: nominal_values(dat[k]) for k in keys}<EOL>udict = {a: unitpicker(np.nanmean(focus[a]),<EOL>focus_stage=focus_stage,<EOL>denominator=denominator) for a in keys}<EOL>rdict = {a: (np.nanmin(focus[a] * udict[a][<NUM_LIT:0>]),<EOL>np.nanmax(focus[a] * udict[a][<NUM_LIT:0>])) for a in keys}<EOL>for i, j in tqdm(zip(*np.triu_indices_from(axes, k=<NUM_LIT:1>)), desc='<STR_LIT>',<EOL>total=sum(range(len(keys)))):<EOL><INDENT>ai = keys[i]<EOL>aj = keys[j]<EOL>pi = focus[ai] * udict[ai][<NUM_LIT:0>]<EOL>pj = focus[aj] * udict[aj][<NUM_LIT:0>]<EOL>if lognorm:<EOL><INDENT>norm = mpl.colors.LogNorm()<EOL><DEDENT>else:<EOL><INDENT>norm = None<EOL><DEDENT>if mode == '<STR_LIT>':<EOL><INDENT>pi = pi[~np.isnan(pi)]<EOL>pj = pj[~np.isnan(pj)]<EOL>axes[i, j].hist2d(pj, pi, bins,<EOL>norm=norm,<EOL>cmap=plt.get_cmap(cmlist[i]))<EOL>axes[j, i].hist2d(pi, pj, bins,<EOL>norm=norm,<EOL>cmap=plt.get_cmap(cmlist[j]))<EOL><DEDENT>elif mode == '<STR_LIT>':<EOL><INDENT>axes[i, j].scatter(pj, pi, s=<NUM_LIT:10>,<EOL>color=cmap[ai], lw=<NUM_LIT:0.5>, edgecolor='<STR_LIT:k>',<EOL>alpha=<NUM_LIT>)<EOL>axes[j, i].scatter(pi, pj, s=<NUM_LIT:10>,<EOL>color=cmap[aj], lw=<NUM_LIT:0.5>, edgecolor='<STR_LIT:k>',<EOL>alpha=<NUM_LIT>)<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>axes[i, j].set_ylim(*rdict[ai])<EOL>axes[i, j].set_xlim(*rdict[aj])<EOL>axes[j, i].set_ylim(*rdict[aj])<EOL>axes[j, i].set_xlim(*rdict[ai])<EOL><DEDENT>for a, n in zip(keys, np.arange(len(keys))):<EOL><INDENT>axes[n, n].annotate(a + '<STR_LIT:\n>' + udict[a][<NUM_LIT:1>], (<NUM_LIT:0.5>, <NUM_LIT:0.5>),<EOL>xycoords='<STR_LIT>',<EOL>ha='<STR_LIT>', va='<STR_LIT>', fontsize=<NUM_LIT:8>)<EOL>axes[n, n].set_xlim(*rdict[a])<EOL>axes[n, n].set_ylim(*rdict[a])<EOL><DEDENT>for i, j in zip(range(numvar), itertools.cycle((-<NUM_LIT:1>, <NUM_LIT:0>))):<EOL><INDENT>axes[j, i].xaxis.set_visible(True)<EOL>for label in axes[j, i].get_xticklabels():<EOL><INDENT>label.set_rotation(<NUM_LIT>)<EOL><DEDENT>axes[i, j].yaxis.set_visible(True)<EOL><DEDENT>return fig, axes<EOL>

Plot analytes against each other.

The number of plots is n**2 - n, where n = len(keys).

Parameters
----------
dat : dict
    A dictionary of key: data pairs, where data is the same
    length in each entry.
keys : optional, array_like or str
    The keys of dat to plot. Defaults to all keys.
lognorm : bool
    Whether or not to log normalise the colour scale
    of the 2D histogram.
bins : int
    The number of bins in the 2D histogram.
figsize : tuple
colourful : bool

Returns
-------
(fig, axes)


def histograms(dat, keys=None, bins=<NUM_LIT>, logy=False, cmap=None, ncol=<NUM_LIT:4>):

if keys is None:<EOL><INDENT>keys = dat.keys()<EOL><DEDENT>ncol = int(ncol)<EOL>nrow = calc_nrow(len(keys), ncol)<EOL>fig, axs = plt.subplots(nrow, <NUM_LIT:4>, figsize=[ncol * <NUM_LIT:2>, nrow * <NUM_LIT:2>])<EOL>pn = <NUM_LIT:0><EOL>for k, ax in zip(keys, axs.flat):<EOL><INDENT>tmp = nominal_values(dat[k])<EOL>x = tmp[~np.isnan(tmp)]<EOL>if cmap is not None:<EOL><INDENT>c = cmap[k]<EOL><DEDENT>else:<EOL><INDENT>c = (<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0.5>)<EOL><DEDENT>ax.hist(x, bins=bins, color=c)<EOL>if logy:<EOL><INDENT>ax.set_yscale('<STR_LIT>')<EOL>ylab = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>ylab = '<STR_LIT:n>'<EOL><DEDENT>ax.set_ylim(<NUM_LIT:1>, ax.get_ylim()[<NUM_LIT:1>])<EOL>if ax.is_first_col():<EOL><INDENT>ax.set_ylabel(ylab)<EOL><DEDENT>ax.set_yticklabels([])<EOL>ax.text(<NUM_LIT>, <NUM_LIT>, k, ha='<STR_LIT:right>', va='<STR_LIT>', transform=ax.transAxes)<EOL>pn += <NUM_LIT:1><EOL><DEDENT>for ax in axs.flat[pn:]:<EOL><INDENT>ax.set_visible(False)<EOL><DEDENT>fig.tight_layout()<EOL>return fig, axs<EOL>

Plot histograms of all items in dat.

Parameters
----------
dat : dict
    Data in {key: array} pairs.
keys : arra-like
    The keys in dat that you want to plot. If None,
    all are plotted.
bins : int
    The number of bins in each histogram (default = 25)
logy : bool
    If true, y axis is a log scale.
cmap : dict
    The colours that the different items should be. If None,
    all are grey.

Returns
-------
fig, axes


def autorange_plot(t, sig, gwin=<NUM_LIT:7>, swin=None, win=<NUM_LIT:30>,<EOL>on_mult=(<NUM_LIT>, <NUM_LIT:1.>), off_mult=(<NUM_LIT:1.>, <NUM_LIT>),<EOL>nbin=<NUM_LIT:10>, thresh=None):

if swin is None:<EOL><INDENT>swin = gwin // <NUM_LIT:2><EOL><DEDENT>sigs = fastsmooth(sig, swin)<EOL>bins = sig.size // nbin<EOL>kde_x = np.linspace(sig.min(), sig.max(), bins)<EOL>kde = gaussian_kde(sigs)<EOL>yd = kde.pdf(kde_x)<EOL>mins = findmins(kde_x, yd)  <EOL>if thresh is not None:<EOL><INDENT>mins = [thresh]<EOL><DEDENT>if len(mins) > <NUM_LIT:0>:<EOL><INDENT>bkg = sigs < (mins[<NUM_LIT:0>])  <EOL><DEDENT>else:<EOL><INDENT>bkg = np.ones(sig.size, dtype=bool)<EOL><DEDENT>fbkg = bkg<EOL>fsig = ~bkg<EOL>g = abs(fastgrad(sigs, gwin))  <EOL>zeros = bool_2_indices(fsig)<EOL>if zeros is not None:<EOL><INDENT>zeros = zeros.flatten()<EOL>lohi = []<EOL>pgs = []<EOL>excl = []<EOL>tps = []<EOL>failed = []<EOL>for z in zeros:  <EOL><INDENT>if z - win < <NUM_LIT:0>:<EOL><INDENT>lo = gwin // <NUM_LIT:2><EOL>hi = int(z + win)<EOL><DEDENT>elif z + win > (len(sig) - gwin // <NUM_LIT:2>):<EOL><INDENT>lo = int(z - win)<EOL>hi = len(sig) - gwin // <NUM_LIT:2><EOL><DEDENT>else:<EOL><INDENT>lo = int(z - win)<EOL>hi = int(z + win)<EOL><DEDENT>xs = t[lo:hi]<EOL>ys = g[lo:hi]<EOL>lohi.append([lo, hi])<EOL>mid = (hi + lo) // <NUM_LIT:2><EOL>tp = sigs[mid + <NUM_LIT:3>] > sigs[mid - <NUM_LIT:3>]  <EOL>tps.append(tp)<EOL>c = t[z]  <EOL>width = (t[<NUM_LIT:1>] - t[<NUM_LIT:0>]) * <NUM_LIT:2>  <EOL>try:<EOL><INDENT>pg, _ = curve_fit(gauss, xs, ys,<EOL>p0=(np.nanmax(ys),<EOL>c,<EOL>width),<EOL>sigma=(xs - c)**<NUM_LIT:2> + <NUM_LIT>)<EOL>pgs.append(pg)<EOL>fwhm = abs(<NUM_LIT:2> * pg[-<NUM_LIT:1>] * np.sqrt(<NUM_LIT:2> * np.log(<NUM_LIT:2>)))<EOL>if tp:<EOL><INDENT>lim = np.array([-fwhm, fwhm]) * on_mult + pg[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>lim = np.array([-fwhm, fwhm]) * off_mult + pg[<NUM_LIT:1>]<EOL><DEDENT>excl.append(lim)<EOL>fbkg[(t > lim[<NUM_LIT:0>]) & (t < lim[<NUM_LIT:1>])] = False<EOL>fsig[(t > lim[<NUM_LIT:0>]) & (t < lim[<NUM_LIT:1>])] = False<EOL>failed.append(False)<EOL><DEDENT>except RuntimeError:<EOL><INDENT>failed.append(True)<EOL>lohi.append([np.nan, np.nan])<EOL>pgs.append([np.nan, np.nan, np.nan])<EOL>excl.append([np.nan, np.nan])<EOL>tps.append(tp)<EOL>pass<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>zeros = []<EOL><DEDENT>nrows = <NUM_LIT:2> + len(zeros) // <NUM_LIT:2> + len(zeros) % <NUM_LIT:2><EOL>fig, axs = plt.subplots(nrows, <NUM_LIT:2>, figsize=(<NUM_LIT:6>, <NUM_LIT:4> + <NUM_LIT> * nrows))<EOL>ax1, ax2, ax3, ax4 = axs.flat[:<NUM_LIT:4>]<EOL>ax4.set_visible(False)<EOL>for ax in [ax1, ax3]:<EOL><INDENT>p = ax.axes.get_position()<EOL>p2 = [p.x0, p.y0, p.width * <NUM_LIT>, p.height]<EOL>ax.axes.set_position(p2)<EOL><DEDENT>p = ax3.axes.get_position()<EOL>p2 = [p.x0, p.y0 + <NUM_LIT> * p.height, p.width, p.height]<EOL>ax3.axes.set_position(p2)<EOL>p = ax2.axes.get_position()<EOL>p2 = [p.x0 + p.width * <NUM_LIT>, p.y0, p.width * <NUM_LIT>, p.height]<EOL>ax2.axes.set_position(p2)<EOL>ax1.plot(t, sig, color='<STR_LIT:k>', lw=<NUM_LIT:1>)<EOL>ax1.set_xticklabels([])<EOL>ax1.set_ylabel('<STR_LIT>')<EOL>ax3.plot(t, g, color='<STR_LIT:k>', lw=<NUM_LIT:1>)<EOL>ax3.set_xlabel('<STR_LIT>')<EOL>ax3.set_ylabel('<STR_LIT>')<EOL>ax2.fill_betweenx(kde_x, yd, color=(<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT>))<EOL>ax2.plot(yd, kde_x, color='<STR_LIT:k>')<EOL>ax2.set_ylim(ax1.get_ylim())<EOL>ax2.set_yticklabels([])<EOL>ax2.set_xlabel('<STR_LIT>')<EOL>for ax in [ax1, ax2]:<EOL><INDENT>ax.axhline(mins[<NUM_LIT:0>], color='<STR_LIT:k>', ls='<STR_LIT>', alpha=<NUM_LIT>)<EOL><DEDENT>if len(zeros) > <NUM_LIT:0>:<EOL><INDENT>for z in zeros:<EOL><INDENT>ax1.axvline(t[z], color='<STR_LIT:r>', alpha=<NUM_LIT:0.5>)<EOL>ax3.axvline(t[z], color='<STR_LIT:r>', alpha=<NUM_LIT:0.5>)<EOL><DEDENT>n = <NUM_LIT:1><EOL>for (lo, hi), lim, tp, pg, fail, ax in zip(lohi, excl, tps, pgs, failed, axs.flat[<NUM_LIT:4>:]):<EOL><INDENT>ax3.axvspan(t[lo], t[hi], color='<STR_LIT:r>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:2>)<EOL>x = t[lo:hi]<EOL>y = g[lo:hi]<EOL>ys = sig[lo:hi]<EOL>ax.scatter(x, y, color='<STR_LIT:k>', marker='<STR_LIT:x>', zorder=-<NUM_LIT:1>, s=<NUM_LIT:10>)<EOL>ax.set_yticklabels([])<EOL>ax.set_ylim(rangecalc(y))<EOL>tax = ax.twinx()<EOL>tax.plot(x, ys, color='<STR_LIT:k>', alpha=<NUM_LIT>, zorder=-<NUM_LIT:5>)<EOL>tax.set_yticklabels([])<EOL>tax.set_ylim(rangecalc(ys))<EOL>xn = np.linspace(x.min(), x.max(), <NUM_LIT:100>)<EOL>ax.plot(xn, gauss(xn, *pg), color='<STR_LIT:r>', alpha=<NUM_LIT:0.5>)<EOL>ax.axvline(pg[<NUM_LIT:1>], color='<STR_LIT:b>', alpha=<NUM_LIT:0.5>)<EOL>ax.axvspan(*lim, color='<STR_LIT:b>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:2>)<EOL>ax1.axvspan(*lim, color='<STR_LIT:b>', alpha=<NUM_LIT:0.1>, zorder=-<NUM_LIT:2>)<EOL>if tp:<EOL><INDENT>ax.text(<NUM_LIT>, <NUM_LIT>, '<STR_LIT>'.format(n), ha='<STR_LIT:left>',<EOL>va='<STR_LIT>', transform=ax.transAxes)<EOL><DEDENT>else:<EOL><INDENT>ax.text(<NUM_LIT>, <NUM_LIT>, '<STR_LIT>'.format(n), ha='<STR_LIT:right>',<EOL>va='<STR_LIT>', transform=ax.transAxes)<EOL><DEDENT>if ax.is_last_row():<EOL><INDENT>ax.set_xlabel('<STR_LIT>')<EOL><DEDENT>if ax.is_first_col():<EOL><INDENT>ax.set_ylabel('<STR_LIT>')<EOL><DEDENT>if ax.is_last_col():<EOL><INDENT>tax.set_ylabel('<STR_LIT>')<EOL><DEDENT>if fail:<EOL><INDENT>ax.axes.set_facecolor((<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT>))<EOL>ax.text(<NUM_LIT>, <NUM_LIT>, '<STR_LIT>', ha='<STR_LIT>', va='<STR_LIT>',<EOL>fontsize=<NUM_LIT:16>, color=(<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0.5>), transform=ax.transAxes)<EOL><DEDENT>n += <NUM_LIT:1><EOL><DEDENT>if len(zeros) % <NUM_LIT:2> == <NUM_LIT:1>:<EOL><INDENT>axs.flat[-<NUM_LIT:1>].set_visible = False<EOL><DEDENT><DEDENT>return fig, axs<EOL>

Function for visualising the autorange mechanism.

Parameters
----------
t : array-like
    Independent variable (usually time).
sig : array-like
    Dependent signal, with distinctive 'on' and 'off' regions.
gwin : int
    The window used for calculating first derivative.
    Defaults to 7.
swin : int
    The window ised for signal smoothing. If None, gwin // 2.
win : int
    The width (c +/- win) of the transition data subsets.
    Defaults to 20.
on_mult and off_mult : tuple, len=2
    Control the width of the excluded transition regions, which is defined
    relative to the peak full-width-half-maximum (FWHM) of the transition
    gradient. The region n * FHWM below the transition, and m * FWHM above
    the tranision will be excluded, where (n, m) are specified in `on_mult`
    and `off_mult`.
    `on_mult` and `off_mult` apply to the off-on and on-off transitions,
    respectively.
    Defaults to (1.5, 1) and (1, 1.5).
nbin : ind
    Used to calculate the number of bins in the data histogram.
    bins = len(sig) // nbin

Returns
-------
fig, axes


def calibration_plot(self, analytes=None, datarange=True, loglog=False, ncol=<NUM_LIT:3>, srm_group=None, save=True):

if isinstance(analytes, str):<EOL><INDENT>analytes = [analytes]<EOL><DEDENT>if analytes is None:<EOL><INDENT>analytes = [a for a in self.analytes if self.internal_standard not in a]<EOL><DEDENT>if srm_group is not None:<EOL><INDENT>srm_groups = {int(g): t for g, t in self.stdtab.loc[:, ['<STR_LIT>', '<STR_LIT>']].values}<EOL>try:<EOL><INDENT>gTime = srm_groups[srm_group]<EOL><DEDENT>except KeyError:<EOL><INDENT>text = ('<STR_LIT>' +<EOL>'<STR_LIT>' + <EOL>'<STR_LIT:\n>'.join(['<STR_LIT>'.format(k, v) for k, v in srm_groups.items()]))<EOL>print(text)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>gTime = None<EOL><DEDENT>ncol = int(ncol)<EOL>n = len(analytes)<EOL>nrow = calc_nrow(n + <NUM_LIT:1>, ncol)<EOL>axes = []<EOL>if not datarange:<EOL><INDENT>fig = plt.figure(figsize=[<NUM_LIT> * ncol, <NUM_LIT:3> * nrow])<EOL><DEDENT>else:<EOL><INDENT>fig = plt.figure(figsize=[<NUM_LIT> * ncol, <NUM_LIT:3> * nrow])<EOL>self.get_focus()<EOL><DEDENT>gs = mpl.gridspec.GridSpec(nrows=int(nrow), ncols=int(ncol),<EOL>hspace=<NUM_LIT>, wspace=<NUM_LIT>)<EOL>mdict = self.srm_mdict<EOL>for g, a in zip(gs, analytes):<EOL><INDENT>if not datarange:<EOL><INDENT>ax = fig.add_axes(g.get_position(fig))<EOL>axes.append((ax,))<EOL><DEDENT>else:<EOL><INDENT>f = <NUM_LIT><EOL>p0 = g.get_position(fig)<EOL>p1 = [p0.x0, p0.y0, p0.width * f, p0.height]<EOL>p2 = [p0.x0 + p0.width * f, p0.y0, p0.width * (<NUM_LIT:1> - f), p0.height]<EOL>ax = fig.add_axes(p1)<EOL>axh = fig.add_axes(p2)<EOL>axes.append((ax, axh))<EOL><DEDENT>if gTime is None:<EOL><INDENT>sub = idx[a]<EOL><DEDENT>else:<EOL><INDENT>sub = idx[a, :, :, gTime]<EOL><DEDENT>x = self.srmtabs.loc[sub, '<STR_LIT>'].values<EOL>xe = self.srmtabs.loc[sub, '<STR_LIT>'].values<EOL>y = self.srmtabs.loc[sub, '<STR_LIT>'].values<EOL>ye = self.srmtabs.loc[sub, '<STR_LIT>'].values<EOL>srm = self.srmtabs.loc[sub].index.get_level_values('<STR_LIT>')<EOL>for s, m in mdict.items():<EOL><INDENT>ind = srm == s<EOL>ax.errorbar(x[ind], y[ind], xerr=xe[ind], yerr=ye[ind],<EOL>color=self.cmaps[a], alpha=<NUM_LIT>,<EOL>lw=<NUM_LIT:0>, elinewidth=<NUM_LIT:1>, marker=m, <EOL>capsize=<NUM_LIT:0>, markersize=<NUM_LIT:5>, label='<STR_LIT:_>')<EOL><DEDENT>if not loglog:<EOL><INDENT>xmax = np.nanmax(x + xe)<EOL>ymax = np.nanmax(y + ye)<EOL>if any(x - xe < <NUM_LIT:0>):<EOL><INDENT>xmin = np.nanmin(x - xe)<EOL>xpad = (xmax - xmin) * <NUM_LIT><EOL>xlim = [xmin - xpad, xmax + xpad]<EOL><DEDENT>else:<EOL><INDENT>xlim = [<NUM_LIT:0>, xmax * <NUM_LIT>]<EOL><DEDENT>if any(y - ye < <NUM_LIT:0>):<EOL><INDENT>ymin = np.nanmin(y - ye)<EOL>ypad = (ymax - ymin) * <NUM_LIT><EOL>ylim = [ymin - ypad, ymax + ypad]<EOL><DEDENT>else:<EOL><INDENT>ylim = [<NUM_LIT:0>, ymax * <NUM_LIT>]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>xd = self.srmtabs.loc[a, '<STR_LIT>'][self.srmtabs.loc[a, '<STR_LIT>'] > <NUM_LIT:0>].values<EOL>yd = self.srmtabs.loc[a, '<STR_LIT>'][self.srmtabs.loc[a, '<STR_LIT>'] > <NUM_LIT:0>].values<EOL>xlim = [<NUM_LIT:10>**np.floor(np.log10(np.nanmin(xd))),<EOL><NUM_LIT:10>**np.ceil(np.log10(np.nanmax(xd)))]<EOL>ylim = [<NUM_LIT:10>**np.floor(np.log10(np.nanmin(yd))),<EOL><NUM_LIT:10>**np.ceil(np.log10(np.nanmax(yd)))]<EOL>if xlim[<NUM_LIT:0>] == xlim[<NUM_LIT:1>]:<EOL><INDENT>xlim[<NUM_LIT:0>] = ylim[<NUM_LIT:0>]<EOL><DEDENT>if ylim[<NUM_LIT:0>] == ylim[<NUM_LIT:1>]:<EOL><INDENT>ylim[<NUM_LIT:0>] = xlim[<NUM_LIT:0>]<EOL><DEDENT>ax.set_xscale('<STR_LIT>')<EOL>ax.set_yscale('<STR_LIT>')<EOL><DEDENT>ax.set_xlim(xlim)<EOL>ax.set_ylim(ylim)<EOL>if xlim[<NUM_LIT:0>] < <NUM_LIT:0>:<EOL><INDENT>ax.axvspan(xlim[<NUM_LIT:0>], <NUM_LIT:0>, color=(<NUM_LIT:1>,<NUM_LIT>,<NUM_LIT>), zorder=-<NUM_LIT:1>)<EOL><DEDENT>if ylim[<NUM_LIT:0>] < <NUM_LIT:0>:<EOL><INDENT>ax.axhspan(ylim[<NUM_LIT:0>], <NUM_LIT:0>, color=(<NUM_LIT:1>,<NUM_LIT>,<NUM_LIT>), zorder=-<NUM_LIT:1>)<EOL><DEDENT>if any(x < <NUM_LIT:0>) or any(y < <NUM_LIT:0>):<EOL><INDENT>ax.text(<NUM_LIT>, <NUM_LIT>, '<STR_LIT>', color='<STR_LIT:r>', weight='<STR_LIT>',<EOL>ha='<STR_LIT>', va='<STR_LIT>', rotation=<NUM_LIT>, transform=ax.transAxes, alpha=<NUM_LIT>)<EOL><DEDENT>if loglog:<EOL><INDENT>x = np.logspace(*np.log10(xlim), <NUM_LIT:100>)<EOL><DEDENT>else:<EOL><INDENT>x = np.array(xlim)<EOL><DEDENT>if gTime is None:<EOL><INDENT>coefs = self.calib_params.loc[:, a]<EOL><DEDENT>else:<EOL><INDENT>coefs = self.calib_params.loc[gTime, a]<EOL><DEDENT>m = np.nanmean(coefs['<STR_LIT:m>'])<EOL>m_nom = nominal_values(m)<EOL>if '<STR_LIT:c>' in coefs:<EOL><INDENT>c = np.nanmean(coefs['<STR_LIT:c>'])<EOL>c_nom = nominal_values(c)<EOL>ym = self.srmtabs.loc[a, '<STR_LIT>'] * m_nom + c_nom<EOL>R2 = R2calc(self.srmtabs.loc[a, '<STR_LIT>'], ym, force_zero=False)<EOL>line = x * m_nom + c_nom<EOL>label = '<STR_LIT>'.format(m)<EOL>if c > <NUM_LIT:0>:<EOL><INDENT>label += '<STR_LIT>'.format(c)<EOL><DEDENT>else:<EOL><INDENT>label += '<STR_LIT>'.format(c)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>ym = self.srmtabs.loc[a, '<STR_LIT>'] * m_nom<EOL>R2 = R2calc(self.srmtabs.loc[a, '<STR_LIT>'], ym, force_zero=True)<EOL>line = x * m_nom<EOL>label = '<STR_LIT>'.format(m)<EOL><DEDENT>ax.plot(x, line, color=(<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:0.5>), ls='<STR_LIT>')<EOL>if round(R2, <NUM_LIT:3>) == <NUM_LIT:1>:<EOL><INDENT>label = '<STR_LIT>' + label<EOL><DEDENT>else:<EOL><INDENT>label = '<STR_LIT>'.format(R2) + label<EOL><DEDENT>ax.text(<NUM_LIT>, <NUM_LIT>, pretty_element(a), transform=ax.transAxes,<EOL>weight='<STR_LIT>', va='<STR_LIT>', ha='<STR_LIT:left>', size=<NUM_LIT:12>)<EOL>ax.set_xlabel('<STR_LIT>' + self.internal_standard)<EOL>ax.set_ylabel('<STR_LIT>' + self.internal_standard)<EOL>if datarange:<EOL><INDENT>meas = nominal_values(self.focus[a])<EOL>meas = meas[~np.isnan(meas)]<EOL>if np.nanmin(meas) < ylim[<NUM_LIT:0>]:<EOL><INDENT>if loglog:<EOL><INDENT>mmeas = meas[meas > <NUM_LIT:0>]<EOL>ylim[<NUM_LIT:0>] = <NUM_LIT:10>**np.floor(np.log10(np.nanmin(mmeas)))<EOL><DEDENT>else:<EOL><INDENT>ylim[<NUM_LIT:0>] = <NUM_LIT:0><EOL><DEDENT>ax.set_ylim(ylim)<EOL><DEDENT>m95 = np.percentile(meas[~np.isnan(meas)], <NUM_LIT>) * <NUM_LIT><EOL>if m95 > ylim[<NUM_LIT:1>]:<EOL><INDENT>if loglog:<EOL><INDENT>ylim[<NUM_LIT:1>] = <NUM_LIT:10>**np.ceil(np.log10(m95))<EOL><DEDENT>else:<EOL><INDENT>ylim[<NUM_LIT:1>] = m95<EOL><DEDENT><DEDENT>if loglog:<EOL><INDENT>bins = np.logspace(*np.log10(ylim), <NUM_LIT:30>)<EOL><DEDENT>else:<EOL><INDENT>bins = np.linspace(*ylim, <NUM_LIT:30>)<EOL><DEDENT>axh.hist(meas, bins=bins, orientation='<STR_LIT>',<EOL>color=self.cmaps[a], lw=<NUM_LIT:0.5>, alpha=<NUM_LIT:0.5>)<EOL>if loglog:<EOL><INDENT>axh.set_yscale('<STR_LIT>')<EOL><DEDENT>axh.set_ylim(ylim)  <EOL>ax.set_ylim(ylim)  <EOL>axh.set_xticks([])<EOL>axh.set_yticklabels([])<EOL><DEDENT>cmax = np.nanmax(y)<EOL>if cmax / ylim[<NUM_LIT:1>] > <NUM_LIT:0.5>:<EOL><INDENT>ax.text(<NUM_LIT>, <NUM_LIT>, label, transform=ax.transAxes,<EOL>va='<STR_LIT>', ha='<STR_LIT:right>')<EOL><DEDENT>else:<EOL><INDENT>ax.text(<NUM_LIT>, <NUM_LIT>, label, transform=ax.transAxes,<EOL>va='<STR_LIT>', ha='<STR_LIT:left>')<EOL><DEDENT><DEDENT>if srm_group is None:<EOL><INDENT>title = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>title = '<STR_LIT>'.format(srm_group, gTime)<EOL><DEDENT>axes[<NUM_LIT:0>][<NUM_LIT:0>].set_title(title, loc='<STR_LIT:left>', weight='<STR_LIT>', fontsize=<NUM_LIT:12>)<EOL>ax = fig.add_axes(gs[-<NUM_LIT:1>].get_position(fig))<EOL>for lab, m in mdict.items():<EOL><INDENT>ax.scatter([],[],marker=m, label=lab, color=(<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT>))<EOL><DEDENT>ax.legend()<EOL>ax.axis('<STR_LIT>')<EOL>if save:<EOL><INDENT>fig.savefig(self.report_dir + '<STR_LIT>')<EOL><DEDENT>return fig, axes<EOL>

Plot the calibration lines between measured and known SRM values.

Parameters
----------
analytes : optional, array_like or str
    The analyte(s) to plot. Defaults to all analytes.
datarange : boolean
    Whether or not to show the distribution of the measured data
    alongside the calibration curve.
loglog : boolean
    Whether or not to plot the data on a log - log scale. This is
    useful if you have two low standards very close together,
    and want to check whether your data are between them, or
    below them.

Returns
-------
(fig, axes)


def filter_report(Data, filt=None, analytes=None, savedir=None, nbin=<NUM_LIT:5>):

if filt is None or filt == '<STR_LIT:all>':<EOL><INDENT>sets = Data.filt.sets<EOL><DEDENT>else:<EOL><INDENT>sets = {k: v for k, v in Data.filt.sets.items() if any(filt in f for f in v)}<EOL><DEDENT>regex = re.compile('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL>cm = plt.cm.get_cmap('<STR_LIT>')<EOL>ngrps = len(sets)<EOL>if analytes is None:<EOL><INDENT>analytes = Data.analytes<EOL><DEDENT>elif isinstance(analytes, str):<EOL><INDENT>analytes = [analytes]<EOL><DEDENT>axes = []<EOL>for analyte in analytes:<EOL><INDENT>if analyte != Data.internal_standard:<EOL><INDENT>fig = plt.figure()<EOL>for i in sorted(sets.keys()):<EOL><INDENT>filts = sets[i]<EOL>nfilts = np.array([re.match(regex, f).groups() for f in filts])<EOL>fgnames = np.array(['<STR_LIT:_>'.join(a) for a in nfilts[:, <NUM_LIT:1>:<NUM_LIT:3>]])<EOL>fgrp = np.unique(fgnames)[<NUM_LIT:0>]<EOL>fig.set_size_inches(<NUM_LIT:10>, <NUM_LIT> * ngrps)<EOL>h = <NUM_LIT> / ngrps<EOL>y = nominal_values(Data.focus[analyte])<EOL>yh = y[~np.isnan(y)]<EOL>m, u = unitpicker(np.nanmax(y),<EOL>denominator=Data.internal_standard,<EOL>focus_stage=Data.focus_stage)<EOL>axs = tax, hax = (fig.add_axes([<NUM_LIT>, <NUM_LIT> - (i + <NUM_LIT:1>) * h, <NUM_LIT>, h * <NUM_LIT>]),<EOL>fig.add_axes([<NUM_LIT>, <NUM_LIT> - (i + <NUM_LIT:1>) * h, <NUM_LIT>, h * <NUM_LIT>]))<EOL>axes.append(axs)<EOL>fg = sets[i]<EOL>cs = cm(np.linspace(<NUM_LIT:0>, <NUM_LIT:1>, len(fg)))<EOL>fn = ['<STR_LIT:_>'.join(x) for x in nfilts[:, (<NUM_LIT:0>, <NUM_LIT:3>)]]<EOL>an = nfilts[:, <NUM_LIT:0>]<EOL>bins = np.linspace(np.nanmin(y), np.nanmax(y), len(yh) // nbin) * m<EOL>if '<STR_LIT>' in fgrp:<EOL><INDENT>core_ind = Data.filt.components[[f for f in fg<EOL>if '<STR_LIT>' in f][<NUM_LIT:0>]]<EOL>other = np.array([('<STR_LIT>' not in f) & ('<STR_LIT>' not in f)<EOL>for f in fg])<EOL>tfg = fg[other]<EOL>tfn = fn[other]<EOL>tcs = cm(np.linspace(<NUM_LIT:0>, <NUM_LIT:1>, len(tfg)))<EOL>hax.hist(m * yh, bins, alpha=<NUM_LIT>, orientation='<STR_LIT>',<EOL>color='<STR_LIT:k>', lw=<NUM_LIT:0>)<EOL>tax.scatter([], [], s=<NUM_LIT:20>, label='<STR_LIT>', color='<STR_LIT:w>', lw=<NUM_LIT:0.5>, edgecolor='<STR_LIT:k>')<EOL>tax.scatter([], [], s=<NUM_LIT>, label='<STR_LIT>', color='<STR_LIT:w>', lw=<NUM_LIT:0.5>, edgecolor='<STR_LIT:k>')<EOL>try:<EOL><INDENT>noise_ind = Data.filt.components[[f for f in fg<EOL>if '<STR_LIT>' in f][<NUM_LIT:0>]]<EOL>tax.scatter(Data.Time[noise_ind], m * y[noise_ind],<EOL>lw=<NUM_LIT:1>, color='<STR_LIT:k>', s=<NUM_LIT:10>, marker='<STR_LIT:x>',<EOL>label='<STR_LIT>', alpha=<NUM_LIT>)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT>for f, c, lab in zip(tfg, tcs, tfn):<EOL><INDENT>ind = Data.filt.components[f]<EOL>tax.scatter(Data.Time[~core_ind & ind],<EOL>m * y[~core_ind & ind], lw=<NUM_LIT>, color=c, s=<NUM_LIT:5>, edgecolor='<STR_LIT:k>')<EOL>tax.scatter(Data.Time[core_ind & ind],<EOL>m * y[core_ind & ind], lw=<NUM_LIT>, color=c, s=<NUM_LIT:15>, edgecolor='<STR_LIT:k>',<EOL>label=lab)<EOL>hax.hist(m * y[ind][~np.isnan(y[ind])], bins, color=c, lw=<NUM_LIT:0.1>,<EOL>orientation='<STR_LIT>', alpha=<NUM_LIT>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>tax.scatter(Data.Time, m * y, color='<STR_LIT:k>', alpha=<NUM_LIT>, lw=<NUM_LIT:0.1>,<EOL>s=<NUM_LIT:20>, label='<STR_LIT>')<EOL>hax.hist(m * yh, bins, alpha=<NUM_LIT>, orientation='<STR_LIT>',<EOL>color='<STR_LIT:k>', lw=<NUM_LIT:0>)<EOL>for f, c, lab in zip(fg, cs, fn):<EOL><INDENT>ind = Data.filt.components[f]<EOL>tax.scatter(Data.Time[ind], m * y[ind],<EOL>edgecolor=(<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>), color=c, s=<NUM_LIT:15>, label=lab)<EOL>hax.hist(m * y[ind][~np.isnan(y[ind])], bins, color=c, lw=<NUM_LIT:0.1>,<EOL>orientation='<STR_LIT>', alpha=<NUM_LIT>)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in fgrp and analyte in fgrp:<EOL><INDENT>tax.axhline(Data.filt.params[fg[<NUM_LIT:0>]]['<STR_LIT>'] * m,<EOL>ls='<STR_LIT>', zorder=-<NUM_LIT:2>, alpha=<NUM_LIT:0.5>, color='<STR_LIT:k>')<EOL>hax.axhline(Data.filt.params[fg[<NUM_LIT:0>]]['<STR_LIT>'] * m,<EOL>ls='<STR_LIT>', zorder=-<NUM_LIT:2>, alpha=<NUM_LIT:0.5>, color='<STR_LIT:k>')<EOL><DEDENT>for ax in axs:<EOL><INDENT>mn = np.nanmin(y) * m<EOL>mx = np.nanmax(y) * m<EOL>rn = mx - mn<EOL>ax.set_ylim(mn - <NUM_LIT> * rn, mx + <NUM_LIT> * rn)<EOL><DEDENT>hn, la = tax.get_legend_handles_labels()<EOL>hax.legend(hn, la, loc='<STR_LIT>', scatterpoints=<NUM_LIT:1>)<EOL>tax.text(<NUM_LIT>, <NUM_LIT>, Data.sample + '<STR_LIT>' + fgrp, size=<NUM_LIT:12>,<EOL>weight='<STR_LIT>', ha='<STR_LIT:left>', va='<STR_LIT>',<EOL>transform=tax.transAxes)<EOL>tax.set_ylabel(pretty_element(analyte) + '<STR_LIT>' + u + '<STR_LIT:)>')<EOL>tax.set_xticks(tax.get_xticks()[:-<NUM_LIT:1>])<EOL>hax.set_yticklabels([])<EOL>if i < ngrps - <NUM_LIT:1>:<EOL><INDENT>tax.set_xticklabels([])<EOL>hax.set_xticklabels([])<EOL><DEDENT>else:<EOL><INDENT>tax.set_xlabel('<STR_LIT>')<EOL>hax.set_xlabel('<STR_LIT:n>')<EOL><DEDENT><DEDENT><DEDENT>if isinstance(savedir, str):<EOL><INDENT>fig.savefig(savedir + '<STR_LIT:/>' + Data.sample + '<STR_LIT:_>' +<EOL>analyte + '<STR_LIT>')<EOL>plt.close(fig)<EOL><DEDENT><DEDENT>return fig, axes<EOL>

Visualise effect of data filters.

Parameters
----------
filt : str
    Exact or partial name of filter to plot. Supports
    partial matching. i.e. if 'cluster' is specified, all
    filters with 'cluster' in the name will be plotted.
    Defaults to all filters.
analyte : str
    Name of analyte to plot.
save : str
    file path to save the plot

Returns
-------
(fig, axes)


return pd.read_csv(srm_file).set_index('<STR_LIT>').dropna(how='<STR_LIT:all>')<EOL>

Reads SRM compositional data from file.

For file format information, see:
http://latools.readthedocs.io/en/latest/users/configuration/srm-file.html

Parameters
----------
file : str
    Path to SRM file.

Returns
-------
SRM compositions : pandas.DataFrame


srms = read_table(srm_file)<EOL>return np.asanyarray(srms.index.unique())<EOL>

Returns list of SRMS defined in the SRM database


if time_format is None:<EOL><INDENT>t = du.parser.parse(datetime)<EOL><DEDENT>else:<EOL><INDENT>t = dt.datetime.strftime(datetime, time_format)<EOL><DEDENT>return t<EOL>

Return a datetime oject from a string, with optional time format.

Parameters
----------
datetime : str
    Date-time as string in any sensible format.
time_format : datetime str (optional)
    String describing the datetime format. If missing uses
    dateutil.parser to guess time format.


n = <NUM_LIT:0><EOL>for di in d.values():<EOL><INDENT>n += len(di)<EOL><DEDENT>return n<EOL>

Returns the total number of data points in values of dict.

Paramters
---------
d : dict


tmax = <NUM_LIT:0><EOL>for di in d.values():<EOL><INDENT>if di.uTime.max() > tmax:<EOL><INDENT>tmax = di.uTime.max()<EOL><DEDENT><DEDENT>return tmax<EOL>


def unitpicker(a, llim=<NUM_LIT:0.1>, denominator=None, focus_stage=None):

if not isinstance(a, (int, float)):<EOL><INDENT>a = nominal_values(a)<EOL>a = np.percentile(a[~np.isnan(a)], <NUM_LIT>)<EOL><DEDENT>if denominator is not None:<EOL><INDENT>pd = pretty_element(denominator)<EOL><DEDENT>else:<EOL><INDENT>pd = '<STR_LIT>'<EOL><DEDENT>if focus_stage == '<STR_LIT>':<EOL><INDENT>udict = {<NUM_LIT:0>: '<STR_LIT>' + pd,<EOL><NUM_LIT:1>: '<STR_LIT>' + pd,<EOL><NUM_LIT:2>: '<STR_LIT>' + pd,<EOL><NUM_LIT:3>: '<STR_LIT>' + pd,<EOL><NUM_LIT:4>: '<STR_LIT>' + pd,<EOL><NUM_LIT:5>: '<STR_LIT>' + pd}<EOL><DEDENT>elif focus_stage == '<STR_LIT>':<EOL><INDENT>udict = {<NUM_LIT:0>: '<STR_LIT>' + pd,<EOL><NUM_LIT:1>: '<STR_LIT>' + pd,<EOL><NUM_LIT:2>: '<STR_LIT>' + pd,<EOL><NUM_LIT:3>: '<STR_LIT>' + pd,<EOL><NUM_LIT:4>: '<STR_LIT>' + pd,<EOL><NUM_LIT:5>: '<STR_LIT>' + pd}<EOL><DEDENT>elif focus_stage in ('<STR_LIT>', '<STR_LIT>', '<STR_LIT>'):<EOL><INDENT>udict = udict = {<NUM_LIT:0>: '<STR_LIT>',<EOL><NUM_LIT:1>: '<STR_LIT>',<EOL><NUM_LIT:2>: '<STR_LIT>',<EOL><NUM_LIT:3>: '<STR_LIT>',<EOL><NUM_LIT:4>: '<STR_LIT>',<EOL><NUM_LIT:5>: '<STR_LIT>'}<EOL><DEDENT>else:<EOL><INDENT>udict = {<NUM_LIT:0>: '<STR_LIT>', <NUM_LIT:1>: '<STR_LIT>', <NUM_LIT:2>: '<STR_LIT>', <NUM_LIT:3>: '<STR_LIT>', <NUM_LIT:4>: '<STR_LIT>', <NUM_LIT:5>: '<STR_LIT>'}<EOL><DEDENT>a = abs(a)<EOL>n = <NUM_LIT:0><EOL>if a < llim:<EOL><INDENT>while a < llim:<EOL><INDENT>a *= <NUM_LIT:1000><EOL>n += <NUM_LIT:1><EOL><DEDENT><DEDENT>return float(<NUM_LIT:1000>**n), udict[n]<EOL>

Determines the most appropriate plotting unit for data.

Parameters
----------
a : float or array-like
    number to optimise. If array like, the 25% quantile is optimised.
llim : float
    minimum allowable value in scaled data.

Returns
-------
(float, str)
    (multiplier, unit)


el = re.match('<STR_LIT>', s).groups()[<NUM_LIT:0>]<EOL>m = re.match('<STR_LIT>', s).groups()[<NUM_LIT:0>]<EOL>return '<STR_LIT>' + m + '<STR_LIT>' + el<EOL>

Returns formatted element name.

Parameters
----------
s : str
    of format [A-Z][a-z]?[0-9]+

Returns
-------
str
    LaTeX formatted string with superscript numbers.


el = re.match('<STR_LIT>', s).groups()[<NUM_LIT:0>]<EOL>m = re.match('<STR_LIT>', s).groups()[<NUM_LIT:0>]<EOL>return el + m<EOL>

Converts analytes in format '27Al' to 'Al27'.

Parameters
----------
s : str
    of format [A-z]{1,3}[0-9]{1,3}

Returns
-------
str
    Name in format [0-9]{1,3}[A-z]{1,3}


el = re.match('<STR_LIT>', s).groups()[<NUM_LIT:0>]<EOL>m = re.match('<STR_LIT>', s).groups()[<NUM_LIT:0>]<EOL>return m + el<EOL>

Converts analytes in format 'Al27' to '27Al'.

Parameters
----------
s : str
    of format [0-9]{1,3}[A-z]{1,3}

Returns
-------
str
    Name in format [A-z]{1,3}[0-9]{1,3}


def collate_data(in_dir, extension='<STR_LIT>', out_dir=None):

if out_dir is None:<EOL><INDENT>out_dir = '<STR_LIT>' + re.search('<STR_LIT>', extension).groups(<NUM_LIT:0>)[<NUM_LIT:0>]<EOL><DEDENT>if not os.path.isdir(out_dir):<EOL><INDENT>os.mkdir(out_dir)<EOL><DEDENT>for p, d, fs in os.walk(in_dir):<EOL><INDENT>for f in fs:<EOL><INDENT>if extension in f:<EOL><INDENT>shutil.copy(p + '<STR_LIT:/>' + f, out_dir + '<STR_LIT:/>' + f)<EOL><DEDENT><DEDENT><DEDENT>return<EOL>

Copy all csvs in nested directroy to single directory.

Function to copy all csvs from a directory, and place
them in a new directory.

Parameters
----------
in_dir : str
    Input directory containing csv files in subfolders
extension : str
    The extension that identifies your data files.
    Defaults to '.csv'.
out_dir : str
    Destination directory

Returns
-------
None


if any(a):<EOL><INDENT>lims = []<EOL>lims.append(np.where(a[:-<NUM_LIT:1>] != a[<NUM_LIT:1>:])[<NUM_LIT:0>])<EOL>if a[<NUM_LIT:0>]:<EOL><INDENT>lims.append([<NUM_LIT:0>])<EOL><DEDENT>if a[-<NUM_LIT:1>]:<EOL><INDENT>lims.append([len(a) - <NUM_LIT:1>])<EOL><DEDENT>lims = np.concatenate(lims)<EOL>lims.sort()<EOL>return np.reshape(lims, (lims.size // <NUM_LIT:2>, <NUM_LIT:2>))<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Convert boolean array into a 2D array of (start, stop) pairs.


ind = bool_2_indices(bool_array)<EOL>ns = np.full(bool_array.size, nstart, dtype=int)<EOL>for n, lims in enumerate(ind):<EOL><INDENT>ns[lims[<NUM_LIT:0>]:lims[-<NUM_LIT:1>] + <NUM_LIT:1>] = nstart + n + <NUM_LIT:1><EOL><DEDENT>return ns<EOL>

Consecutively numbers contiguous booleans in array.

i.e. a boolean sequence, and resulting numbering
T F T T T F T F F F T T F
0-1 1 1 - 2 ---3 3 -

where ' - '

Parameters
----------
bool_array : array_like
    Array of booleans.
nstart : int
    The number of the first boolean group.


if np.ndim(tuples) == <NUM_LIT:1>:<EOL><INDENT>tuples = [tuples]<EOL><DEDENT>out = np.zeros(x.size, dtype=bool)<EOL>for l, u in tuples:<EOL><INDENT>out[(x > l) & (x < u)] = True<EOL><DEDENT>return out<EOL>

Generate boolean array from list of limit tuples.

Parameters
----------
tuples : array_like
    [2, n] array of (start, end) values
x : array_like
    x scale the tuples are mapped to

Returns
-------
array_like
    boolean array, True where x is between each pair of tuples.


def rolling_window(a, window, pad=None):

shape = a.shape[:-<NUM_LIT:1>] + (a.shape[-<NUM_LIT:1>] - window + <NUM_LIT:1>, window)<EOL>strides = a.strides + (a.strides[-<NUM_LIT:1>], )<EOL>out = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)<EOL>if window % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>npre = window // <NUM_LIT:2> - <NUM_LIT:1><EOL>npost = window // <NUM_LIT:2><EOL><DEDENT>else:<EOL><INDENT>npre = npost = window // <NUM_LIT:2><EOL><DEDENT>if isinstance(pad, str):<EOL><INDENT>if pad == '<STR_LIT>':<EOL><INDENT>prepad = np.full((npre, window), a[<NUM_LIT:0>])<EOL>postpad = np.full((npost, window), a[-<NUM_LIT:1>])<EOL><DEDENT>elif pad == '<STR_LIT>':<EOL><INDENT>prepad = np.full((npre, window), np.mean(a[:(window // <NUM_LIT:2>)]))<EOL>postpad = np.full((npost, window), np.mean(a[-(window // <NUM_LIT:2>):]))<EOL><DEDENT>elif pad == '<STR_LIT>':<EOL><INDENT>prepad = np.full((npre, window), out[<NUM_LIT:0>])<EOL>postpad = np.full((npost, window), out[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return np.concatenate((prepad, out, postpad))<EOL><DEDENT>elif pad is not None:<EOL><INDENT>pre_blankpad = np.empty(((npre, window)))<EOL>pre_blankpad[:] = pad<EOL>post_blankpad = np.empty(((npost, window)))<EOL>post_blankpad[:] = pad<EOL>return np.concatenate([pre_blankpad, out, post_blankpad])<EOL><DEDENT>else:<EOL><INDENT>return out<EOL><DEDENT>

Returns (win, len(a)) rolling - window array of data.

Parameters
----------
a : array_like
    Array to calculate the rolling window of
window : int
    Description of `window`.
pad : same as dtype(a)
    Description of `pad`.

Returns
-------
array_like
    An array of shape (n, window), where n is either len(a) - window
    if pad is None, or len(a) if pad is not None.


<EOL>if win % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>win += <NUM_LIT:1>  <EOL><DEDENT>kernel = np.ones(win) / win<EOL>npad = int((win - <NUM_LIT:1>) / <NUM_LIT:2>)<EOL>spad = np.full(npad + <NUM_LIT:1>, np.mean(a[:(npad + <NUM_LIT:1>)]))<EOL>epad = np.full(npad - <NUM_LIT:1>, np.mean(a[-(npad - <NUM_LIT:1>):]))<EOL>return np.concatenate([spad, np.convolve(a, kernel, '<STR_LIT>'), epad])<EOL>

Returns rolling - window smooth of a.

Function to efficiently calculate the rolling mean of a numpy
array using 'stride_tricks' to split up a 1D array into an ndarray of
sub - sections of the original array, of dimensions [len(a) - win, win].

Parameters
----------
a : array_like
    The 1D array to calculate the rolling gradient of.
win : int
    The width of the rolling window.

Returns
-------
array_like
    Gradient of a, assuming as constant integer x - scale.


<EOL>if win % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>win += <NUM_LIT:1>  <EOL><DEDENT>wins = rolling_window(a, win, '<STR_LIT>')<EOL>a = map(lambda x: np.polyfit(np.arange(win), x, <NUM_LIT:1>)[<NUM_LIT:0>], wins)<EOL>return np.array(list(a))<EOL>

Returns rolling - window gradient of a.

Function to efficiently calculate the rolling gradient of a numpy
array using 'stride_tricks' to split up a 1D array into an ndarray of
sub - sections of the original array, of dimensions [len(a) - win, win].

Parameters
----------
a : array_like
    The 1D array to calculate the rolling gradient of.
win : int
    The width of the rolling window.

Returns
-------
array_like
    Gradient of a, assuming as constant integer x - scale.


def calc_grads(x, dat, keys=None, win=<NUM_LIT:5>):

if keys is None:<EOL><INDENT>keys = dat.keys()<EOL><DEDENT>def grad(xy):<EOL><INDENT>if (~np.isnan(xy)).all():<EOL><INDENT>try:<EOL><INDENT>return np.polyfit(xy[<NUM_LIT:0>], xy[<NUM_LIT:1>], <NUM_LIT:1>)[<NUM_LIT:0>]<EOL><DEDENT>except ValueError:<EOL><INDENT>return np.nan<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return np.nan<EOL><DEDENT><DEDENT>xs = rolling_window(x, win, pad='<STR_LIT>')<EOL>grads = Bunch()<EOL>for k in keys:<EOL><INDENT>d = nominal_values(rolling_window(dat[k], win, pad='<STR_LIT>'))<EOL>grads[k] = np.array(list(map(grad, zip(xs, d))))<EOL><DEDENT>return grads<EOL>

Calculate gradients of values in dat.

Parameters
----------
x : array like
    Independent variable for items in dat.
dat : dict
    {key: dependent_variable} pairs
keys : str or array-like
    Which keys in dict to calculate the gradient of.
win : int
    The side of the rolling window for gradient calculation

Returns
-------
dict of gradients


return x[np.r_[False, y[<NUM_LIT:1>:] < y[:-<NUM_LIT:1>]] & np.r_[y[:-<NUM_LIT:1>] < y[<NUM_LIT:1>:], False]]<EOL>

Function to find local minima.

    Parameters
    ----------
    x, y : array_like
        1D arrays of the independent (x) and dependent (y) variables.

    Returns
    -------
    array_like
        Array of points in x where y has a local minimum.


def stack_keys(ddict, keys, extra=None):

if isinstance(keys, str):<EOL><INDENT>d = [ddict[keys]]<EOL><DEDENT>else:<EOL><INDENT>d = [ddict[k] for k in keys]<EOL><DEDENT>if extra is not None:<EOL><INDENT>d = extra + d<EOL><DEDENT>return np.vstack(d).T<EOL>

Combine elements of ddict into an array of shape (len(ddict[key]), len(keys)).

Useful for preparing data for sklearn.

Parameters
----------
ddict : dict
    A dict containing arrays or lists to be stacked.
    Must be of equal length.
keys : list or str
    The keys of dict to stack. Must be present in ddict.
extra : list (optional)
    A list of additional arrays to stack. Elements of extra
    must be the same length as arrays in ddict.
    Extras are inserted as the first columns of output.


def zipdir(directory, name=None, delete=False):

if not os.path.isdir(directory) or not os.path.exists(directory):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if name is None:<EOL><INDENT>name = directory.split('<STR_LIT:/>')[-<NUM_LIT:1>]<EOL><DEDENT>savepath = os.path.join(directory, os.path.pardir)<EOL>with zipfile.ZipFile(os.path.join(savepath, name + '<STR_LIT>'), '<STR_LIT:w>', zipfile.ZIP_DEFLATED) as zipf:<EOL><INDENT>for root, dirs, files in os.walk(directory):<EOL><INDENT>for f in files:<EOL><INDENT>zipf.write(os.path.join(root, f), os.path.join(root.replace(directory, '<STR_LIT>'), f))<EOL><DEDENT><DEDENT><DEDENT>if delete:<EOL><INDENT>shutil.rmtree(directory)<EOL><DEDENT>return None<EOL>

Compresses the target directory, and saves it to ../name.zip

Parameters
----------
directory : str
    Path to the directory you want to compress.
    Compressed file will be saved at directory/../name.zip
name : str (default=None)
    The name of the resulting zip file. If not specified, the
    name of the directory to be compressed is used.
delete : bool
    If True, the uncompressed directory is deleted after the zip file
    has been created. Defaults to False.

Returns
-------
None


if not os.path.exists(zip_file):<EOL><INDENT>raise ValueError('<STR_LIT>'.format(zip_file))<EOL><DEDENT>directory = os.path.dirname(zip_file)<EOL>filename = os.path.basename(zip_file)<EOL>dirpath = os.path.join(directory, filename.replace('<STR_LIT>', '<STR_LIT>'))<EOL>with zipfile.ZipFile(zip_file, '<STR_LIT:r>', zipfile.ZIP_DEFLATED) as zipf:<EOL><INDENT>zipf.extractall(dirpath)<EOL><DEDENT>return dirpath<EOL>

Extract contents of zip file into subfolder in parent directory.

Parameters
----------
zip_file : str
    Path to zip file

Returns
-------
    str : folder where the zip was extracted


try:<EOL><INDENT>return un.nominal_values(uarray), un.std_devs(uarray)<EOL><DEDENT>except:<EOL><INDENT>return uarray, None<EOL><DEDENT>

Convenience function to unpack nominal values and uncertainties from an
``uncertainties.uarray``.

Returns:
    (nominal_values, std_devs)


def gauss_weighted_stats(x, yarray, x_new, fwhm):

sigma = fwhm / (<NUM_LIT:2> * np.sqrt(<NUM_LIT:2> * np.log(<NUM_LIT:2>)))<EOL>mask = np.zeros((x.size, yarray.shape[<NUM_LIT:1>], x_new.size))<EOL>for i, xni in enumerate(x_new):<EOL><INDENT>mask[:, :, i] = gauss(x[:, np.newaxis], <NUM_LIT:1>, xni, sigma)<EOL><DEDENT>nmask = mask / mask.sum(<NUM_LIT:0>)  <EOL>av = (nmask * yarray[:, :, np.newaxis]).sum(<NUM_LIT:0>)  <EOL>diff = np.power(av - yarray[:, :, np.newaxis], <NUM_LIT:2>)<EOL>std = np.sqrt((diff * nmask).sum(<NUM_LIT:0>))<EOL>se = std / np.sqrt(mask.sum(<NUM_LIT:0>))<EOL>return av, std, se<EOL>

Calculate gaussian weigted moving mean, SD and SE.

Parameters
----------
x : array-like
    The independent variable
yarray : (n,m) array
    Where n = x.size, and m is the number of
    dependent variables to smooth.
x_new : array-like
    The new x-scale to interpolate the data
fwhm : int
    FWHM of the gaussian kernel.

Returns
-------
(mean, std, se) : tuple


A, mu, sigma = p<EOL>return A * np.exp(-<NUM_LIT:0.5> * (-mu + x)**<NUM_LIT:2> / sigma**<NUM_LIT:2>)<EOL>

Gaussian function.

    Parameters
    ----------
    x : array_like
        Independent variable.
    *p : parameters unpacked to A, mu, sigma
        A = amplitude, mu = centre, sigma = width

    Return
    ------
    array_like
        gaussian descriped by *p.


return np.nanstd(a) / np.sqrt(sum(np.isfinite(a)))<EOL>


mu = np.nanmean(x)<EOL>sd = np.nanstd(x) * <NUM_LIT><EOL>sig = <NUM_LIT><EOL>hi = x > mu + sig * sd<EOL>lo = x < mu - sig * sd<EOL>if any(hi | lo):<EOL><INDENT>x[hi] = mu + sig * sd<EOL>x[lo] = mu - sig * sd<EOL>return H15_mean(x)<EOL><DEDENT>else:<EOL><INDENT>return mu<EOL><DEDENT>

Calculate the Huber (H15) Robust mean of x.

For details, see:
    http://www.cscjp.co.jp/fera/document/ANALYSTVol114Decpgs1693-97_1989.pdf
    http://www.rsc.org/images/robust-statistics-technical-brief-6_tcm18-214850.pdf


mu = np.nanmean(x)<EOL>sd = np.nanstd(x) * <NUM_LIT><EOL>sig = <NUM_LIT><EOL>hi = x > mu + sig * sd<EOL>lo = x < mu - sig * sd<EOL>if any(hi | lo):<EOL><INDENT>x[hi] = mu + sig * sd<EOL>x[lo] = mu - sig * sd<EOL>return H15_std(x)<EOL><DEDENT>else:<EOL><INDENT>return sd<EOL><DEDENT>

Calculate the Huber (H15) Robust standard deviation of x.

For details, see:
    http://www.cscjp.co.jp/fera/document/ANALYSTVol114Decpgs1693-97_1989.pdf
    http://www.rsc.org/images/robust-statistics-technical-brief-6_tcm18-214850.pdf


sd = H15_std(x)<EOL>return sd / np.sqrt(sum(np.isfinite(x)))<EOL>


max_points = np.sum(~np.isnan(s))<EOL>n_points = max_points - min_points<EOL>out = np.full((n_points, s.size), np.nan)<EOL>ind = ~np.isnan(s)<EOL>s = s[ind]<EOL>for i, w in enumerate(range(min_points, s.size)):<EOL><INDENT>r = rolling_window(s, w, pad=np.nan)<EOL>out[i, ind] = np.apply_along_axis(fn, <NUM_LIT:1>, r)<EOL><DEDENT>return out<EOL>

Apply fn to all contiguous regions in s that have at least min_points.


def calc_window_mean_std(s, min_points, ind=None):

max_points = np.sum(~np.isnan(s))<EOL>n_points = max_points - min_points<EOL>mean = np.full((n_points, s.size), np.nan)<EOL>std = np.full((n_points, s.size), np.nan)<EOL>if ind is None:<EOL><INDENT>ind = ~np.isnan(s)<EOL><DEDENT>else:<EOL><INDENT>ind = ind & ~np.isnan(s)<EOL><DEDENT>s = s[ind]<EOL>for i, w in enumerate(range(min_points, s.size)):<EOL><INDENT>r = rolling_window(s, w, pad=np.nan)<EOL>mean[i, ind] = r.sum(<NUM_LIT:1>) / w<EOL>std[i, ind] = (((r - mean[i, ind][:, np.newaxis])**<NUM_LIT:2>).sum(<NUM_LIT:1>) / (w - <NUM_LIT:1>))**<NUM_LIT:0.5><EOL><DEDENT>return mean, std<EOL>


return (s - np.nanmean(s)) / np.nanstd(s)<EOL>

Remove the mean, and divide by the standard deviation.


if sum(~np.isnan(s)) > <NUM_LIT:1>:<EOL><INDENT>bm, bv, bs = bayes_mvs(s[~np.isnan(s)])<EOL>return (s - bm.statistic) / bs.statistic<EOL><DEDENT>else:<EOL><INDENT>return np.full(s.shape, np.nan)<EOL><DEDENT>

Remove mean and divide by standard deviation, using bayes_kvm statistics.


if sum(~np.isnan(s)) > <NUM_LIT:2>:<EOL><INDENT>ss = s[~np.isnan(s)]<EOL>median = np.median(ss)<EOL>IQR = np.diff(np.percentile(ss, [<NUM_LIT>, <NUM_LIT>]))<EOL>return (s - median) / IQR<EOL><DEDENT>else:<EOL><INDENT>return np.full(s.shape, np.nan)<EOL><DEDENT>


def signal_optimiser(d, analytes, min_points=<NUM_LIT:5>,<EOL>threshold_mode='<STR_LIT>',<EOL>threshold_mult=<NUM_LIT:1.>, x_bias=<NUM_LIT:0>,<EOL>weights=None, ind=None, mode='<STR_LIT>'):

errmsg = '<STR_LIT>'<EOL>if isinstance(analytes, str):<EOL><INDENT>analytes = [analytes]<EOL><DEDENT>if ind is None:<EOL><INDENT>ind = np.full(len(d.Time), True)<EOL><DEDENT>if not any(ind) or (np.diff(bool_2_indices(ind)).max() < min_points):<EOL><INDENT>errmsg = '<STR_LIT>'.format(min_points)<EOL>return Bunch({'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': ind,<EOL>'<STR_LIT>': threshold_mode,<EOL>'<STR_LIT>': min_points,<EOL>'<STR_LIT>': analytes,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': weights,<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': errmsg}), errmsg<EOL><DEDENT>msmeans, msstds = calculate_optimisation_stats(d, analytes, min_points, weights, ind, x_bias)<EOL>if all(np.isnan(msmeans).flat) or all(np.isnan(msmeans).flat):<EOL><INDENT>errmsg = '<STR_LIT>'.format(min_points)<EOL>return Bunch({'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': ind,<EOL>'<STR_LIT>': threshold_mode,<EOL>'<STR_LIT>': min_points,<EOL>'<STR_LIT>': analytes,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': weights,<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': errmsg}), errmsg<EOL><DEDENT>valid = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>n_under = <NUM_LIT:0><EOL>i = np.argwhere(np.array(valid) == threshold_mode)[<NUM_LIT:0>, <NUM_LIT:0>]<EOL>o_threshold_mode = threshold_mode<EOL>while (n_under <= <NUM_LIT:0>) & (i < len(valid)):<EOL><INDENT>if threshold_mode == '<STR_LIT>':<EOL><INDENT>std_threshold = np.nanmedian(msstds)<EOL>mean_threshold = np.nanmedian(msmeans)<EOL><DEDENT>elif threshold_mode == '<STR_LIT>':<EOL><INDENT>std_threshold = np.nanmean(msstds)<EOL>mean_threshold = np.nanmean(msmeans)<EOL><DEDENT>elif threshold_mode == '<STR_LIT>':<EOL><INDENT>mkd = gaussian_kde(msmeans[~np.isnan(msmeans)].flat)<EOL>xm = np.linspace(*np.percentile(msmeans.flatten()[~np.isnan(msmeans.flatten())], (<NUM_LIT:1>, <NUM_LIT>)), <NUM_LIT:100>)<EOL>mdf = mkd.pdf(xm)<EOL>mean_threshold = xm[np.argmax(mdf)]<EOL>rkd = gaussian_kde(msstds[~np.isnan(msstds)])<EOL>xr = np.linspace(*np.percentile(msstds.flatten()[~np.isnan(msstds.flatten())], (<NUM_LIT:1>, <NUM_LIT>)), <NUM_LIT:100>)<EOL>rdf = rkd.pdf(xr)<EOL>std_threshold = xr[np.argmax(rdf)]<EOL><DEDENT>elif threshold_mode == '<STR_LIT>':<EOL><INDENT>mkd = gaussian_kde(msmeans[~np.isnan(msmeans)].flat)<EOL>xm = np.linspace(*np.percentile(msmeans.flatten()[~np.isnan(msmeans.flatten())], (<NUM_LIT:1>, <NUM_LIT>)), <NUM_LIT:100>)<EOL>mdf = mkd.pdf(xm)<EOL>inds = np.argwhere(np.r_[False, mdf[<NUM_LIT:1>:] > mdf[:-<NUM_LIT:1>]] & <EOL>np.r_[mdf[:-<NUM_LIT:1>] > mdf[<NUM_LIT:1>:], False] & <EOL>(mdf > <NUM_LIT> * mdf.max()))<EOL>mean_threshold = xm[np.min(inds)]<EOL>rkd = gaussian_kde(msstds[~np.isnan(msstds)])<EOL>xr = np.linspace(*np.percentile(msstds.flatten()[~np.isnan(msstds.flatten())], (<NUM_LIT:1>, <NUM_LIT>)), <NUM_LIT:100>)<EOL>rdf = rkd.pdf(xr)<EOL>inds = np.argwhere(np.r_[False, rdf[<NUM_LIT:1>:] > rdf[:-<NUM_LIT:1>]] & <EOL>np.r_[rdf[:-<NUM_LIT:1>] > rdf[<NUM_LIT:1>:], False] & <EOL>(rdf > <NUM_LIT> * rdf.max()))<EOL>std_threshold = xr[np.min(inds)]<EOL><DEDENT>elif threshold_mode == '<STR_LIT>':<EOL><INDENT>bm, _, bs = bayes_mvs(msstds[~np.isnan(msstds)])<EOL>std_threshold = bm.statistic<EOL>bm, _, bs = bayes_mvs(msmeans[~np.isnan(msmeans)])<EOL>mean_threshold = bm.statistic<EOL><DEDENT>elif callable(threshold_mode):<EOL><INDENT>std_threshold = threshold_mode(msstds[~np.isnan(msstds)].flatten())<EOL>mean_threshold = threshold_mode(msmeans[~np.isnan(msmeans)].flatten())<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>mean_threshold, std_threshold = threshold_mode<EOL><DEDENT>except:<EOL><INDENT>raise ValueError('<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(valid) + '<STR_LIT>')<EOL><DEDENT><DEDENT>if isinstance(threshold_mult, (int, float)):<EOL><INDENT>std_threshold *= threshold_mult<EOL>mean_threshold *= threshold_mult<EOL><DEDENT>elif len(threshold_mult) == <NUM_LIT:2>:<EOL><INDENT>mean_threshold *= threshold_mult[<NUM_LIT:0>]<EOL>std_threshold *= threshold_mult[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>rind = (msstds < std_threshold)<EOL>if mode == '<STR_LIT>':<EOL><INDENT>mind = (msmeans < mean_threshold)<EOL><DEDENT>else:<EOL><INDENT>mind = (msmeans > mean_threshold)<EOL><DEDENT>ind = rind & mind<EOL>n_under = ind.sum()<EOL>if n_under == <NUM_LIT:0>:<EOL><INDENT>i += <NUM_LIT:1><EOL>if i <= len(valid) - <NUM_LIT:1>:<EOL><INDENT>threshold_mode = valid[i]<EOL><DEDENT>else:<EOL><INDENT>errmsg = '<STR_LIT>'<EOL>return Bunch({'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': ind,<EOL>'<STR_LIT>': threshold_mode,<EOL>'<STR_LIT>': min_points,<EOL>'<STR_LIT>': analytes,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': np.nan,<EOL>'<STR_LIT>': weights,<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': errmsg}), errmsg<EOL><DEDENT><DEDENT><DEDENT>if i > <NUM_LIT:0>:<EOL><INDENT>errmsg = "<STR_LIT>".format(o_threshold_mode, threshold_mode)<EOL><DEDENT>passing = np.argwhere(ind)<EOL>opt_n_points = passing[:, <NUM_LIT:0>].max()<EOL>opt_centre = passing[passing[:, <NUM_LIT:0>] == opt_n_points, <NUM_LIT:1>].min()<EOL>opt_n_points += min_points<EOL>if opt_n_points % <NUM_LIT:2> == <NUM_LIT:0>:<EOL><INDENT>lims = (opt_centre - opt_n_points // <NUM_LIT:2>,<EOL>opt_centre + opt_n_points // <NUM_LIT:2>)<EOL><DEDENT>else:<EOL><INDENT>lims = (opt_centre - opt_n_points // <NUM_LIT:2>,<EOL>opt_centre + opt_n_points // <NUM_LIT:2> + <NUM_LIT:1>)<EOL><DEDENT>filt = np.zeros(d.Time.shape, dtype=bool)<EOL>filt[lims[<NUM_LIT:0>]:lims[<NUM_LIT:1>]] = True<EOL>return Bunch({'<STR_LIT>': msmeans,<EOL>'<STR_LIT>': msstds,<EOL>'<STR_LIT>': mean_threshold,<EOL>'<STR_LIT>': std_threshold,<EOL>'<STR_LIT>': lims,<EOL>'<STR_LIT>': filt,<EOL>'<STR_LIT>': threshold_mode,<EOL>'<STR_LIT>': min_points,<EOL>'<STR_LIT>': analytes,<EOL>'<STR_LIT>': opt_centre,<EOL>'<STR_LIT>': opt_n_points,<EOL>'<STR_LIT>': weights,<EOL>'<STR_LIT>': True,<EOL>'<STR_LIT>': errmsg}), errmsg<EOL>

Optimise data selection based on specified analytes.

Identifies the longest possible contiguous data region in
the signal where the relative standard deviation (std) and
concentration of all analytes is minimised.

Optimisation is performed via a grid search of all possible
contiguous data regions. For each region, the mean std and
mean scaled analyte concentration ('amplitude') are calculated.

The size and position of the optimal data region are identified
using threshold std and amplitude values. Thresholds are derived
from all calculated stds and amplitudes using the method specified
by `threshold_mode`. For example, using the 'kde_max' method, a
probability density function (PDF) is calculated for std and
amplitude values, and the threshold is set as the maximum of the
PDF. These thresholds are then used to identify the size and position
of the longest contiguous region where the std is below the threshold,
and the amplitude is either below the threshold.

All possible regions of the data that have at least
`min_points` are considered.

For a graphical demonstration of the action of signal_optimiser,
use `optimisation_plot`.

Parameters
----------
d : latools.D object
    An latools data object.
analytes : str or array-like
    Which analytes to consider.
min_points : int
    The minimum number of contiguous points to
    consider.
threshold_mode : str
    The method used to calculate the optimisation
    thresholds. Can be 'mean', 'median', 'kde_max'
    or 'bayes_mvs', or a custom function. If a
    function, must take a 1D array, and return a
    single, real number.
threshood_mult : float or tuple
    A multiplier applied to the calculated threshold
    before use. If a tuple, the first value is applied
    to the mean threshold, and the second is applied to
    the standard deviation threshold. Reduce this to make
    data selection more stringent.
x_bias : float
    If non-zero, a bias is applied to the calculated statistics
    to prefer the beginning (if > 0) or end (if < 0) of the
    signal. Should be between zero and 1.
weights : array-like of length len(analytes)
    An array of numbers specifying the importance of
    each analyte considered. Larger number makes the
    analyte have a greater effect on the optimisation.
    Default is None.
ind : boolean array
    A boolean array the same length as the data. Where
    false, data will not be included.
mode : str
    Whether to 'minimise' or 'maximise' the concentration
    of the elements.

Returns
-------
dict, str : optimisation result, error message


def optimisation_plot(d, overlay_alpha=<NUM_LIT:0.5>, **kwargs):

if not hasattr(d, '<STR_LIT>'):<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>out = []<EOL>for n, opt in d.opt.items():<EOL><INDENT>if not opt['<STR_LIT>']:<EOL><INDENT>out.append((None, None))<EOL><DEDENT>else:<EOL><INDENT>means = opt['<STR_LIT>']<EOL>stds = opt['<STR_LIT>']<EOL>min_points = opt['<STR_LIT>']<EOL>mean_threshold = opt['<STR_LIT>']<EOL>std_threshold = opt['<STR_LIT>']<EOL>opt_centre = opt['<STR_LIT>']<EOL>opt_n_points = opt['<STR_LIT>']<EOL>centres, npoints = np.meshgrid(np.arange(means.shape[<NUM_LIT:1>]), np.arange(min_points, min_points + means.shape[<NUM_LIT:0>]))<EOL>rind = (stds < std_threshold)<EOL>mind = (means < mean_threshold)<EOL>mlim = np.percentile(means.flatten()[~np.isnan(means.flatten())], (<NUM_LIT:0>, <NUM_LIT>))<EOL>rlim = np.percentile(stds.flatten()[~np.isnan(stds.flatten())], (<NUM_LIT:0>, <NUM_LIT>))<EOL>cmr = plt.cm.Blues<EOL>cmr.set_bad((<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT>))<EOL>cmm = plt.cm.Reds<EOL>cmm.set_bad((<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT>))<EOL>fig = plt.figure(figsize=[<NUM_LIT:7>,<NUM_LIT:7>])<EOL>ma = fig.add_subplot(<NUM_LIT:3>, <NUM_LIT:2>, <NUM_LIT:1>)<EOL>ra = fig.add_subplot(<NUM_LIT:3>, <NUM_LIT:2>, <NUM_LIT:2>)<EOL>nonan = np.argwhere(~np.isnan(means))<EOL>xdif = np.ptp(nonan[:, <NUM_LIT:1>])<EOL>ydif = np.ptp(nonan[:, <NUM_LIT:0>])<EOL>extent = (nonan[:, <NUM_LIT:1>].min() - np.ceil(<NUM_LIT:0.1> * xdif),  <EOL>nonan[:, <NUM_LIT:1>].max() + np.ceil(<NUM_LIT:0.1> * xdif),  <EOL>nonan[:, <NUM_LIT:0>].min() + min_points,  <EOL>nonan[:, <NUM_LIT:0>].max() + np.ceil(<NUM_LIT:0.1> * ydif) + min_points)  <EOL>mm = ma.imshow(means, origin='<STR_LIT>', cmap=cmm, vmin=mlim[<NUM_LIT:0>], vmax=mlim[<NUM_LIT:1>],<EOL>extent=(centres.min(), centres.max(), npoints.min(), npoints.max()))<EOL>ma.set_ylabel('<STR_LIT>')<EOL>ma.set_xlabel('<STR_LIT>')<EOL>fig.colorbar(mm, ax=ma, label='<STR_LIT>')<EOL>mr = ra.imshow(stds, origin='<STR_LIT>', cmap=cmr, vmin=rlim[<NUM_LIT:0>], vmax=rlim[<NUM_LIT:1>],<EOL>extent=(centres.min(), centres.max(), npoints.min(), npoints.max()))<EOL>ra.set_xlabel('<STR_LIT>')<EOL>fig.colorbar(mr, ax=ra, label='<STR_LIT>')<EOL>ra.imshow(~rind, origin='<STR_LIT>', cmap=plt.cm.Greys, alpha=overlay_alpha,<EOL>extent=(centres.min(), centres.max(), npoints.min(), npoints.max()))<EOL>ma.imshow(~mind, origin='<STR_LIT>', cmap=plt.cm.Greys, alpha=overlay_alpha,<EOL>extent=(centres.min(), centres.max(), npoints.min(), npoints.max()))<EOL>for ax in [ma, ra]:<EOL><INDENT>ax.scatter(opt_centre, opt_n_points, c=(<NUM_LIT:1>,<NUM_LIT:1>,<NUM_LIT:1>,<NUM_LIT>), edgecolor='<STR_LIT:k>',marker='<STR_LIT:o>')<EOL>ax.set_xlim(extent[:<NUM_LIT:2>])<EOL>ax.set_ylim(extent[-<NUM_LIT:2>:])<EOL><DEDENT>mah = fig.add_subplot(<NUM_LIT:3>, <NUM_LIT:2>, <NUM_LIT:3>)<EOL>rah = fig.add_subplot(<NUM_LIT:3>, <NUM_LIT:2>, <NUM_LIT:4>)<EOL>mah.set_xlim(mlim)<EOL>mbin = np.linspace(*mah.get_xlim(), <NUM_LIT:50>)<EOL>mah.hist(means.flatten()[~np.isnan(means.flatten())], mbin)<EOL>mah.axvspan(mean_threshold, mah.get_xlim()[<NUM_LIT:1>], color=(<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>,overlay_alpha))<EOL>mah.axvline(mean_threshold, c='<STR_LIT:r>')<EOL>mah.set_xlabel('<STR_LIT>')<EOL>mah.set_ylabel('<STR_LIT:N>')<EOL>rah.set_xlim(rlim)<EOL>rbin = np.linspace(*rah.get_xlim(), <NUM_LIT:50>)<EOL>rah.hist(stds.flatten()[~np.isnan(stds.flatten())], rbin)<EOL>rah.axvspan(std_threshold, rah.get_xlim()[<NUM_LIT:1>], color=(<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT:0>,<NUM_LIT>))<EOL>rah.axvline(std_threshold, c='<STR_LIT:r>')<EOL>rah.set_xlabel('<STR_LIT>')<EOL>tax = fig.add_subplot(<NUM_LIT:3>,<NUM_LIT:1>,<NUM_LIT:3>)<EOL>tplot(d, opt.analytes, ax=tax, **kwargs)<EOL>tax.axvspan(*d.Time[[opt.lims[<NUM_LIT:0>], opt.lims[<NUM_LIT:1>]]], alpha=<NUM_LIT>)<EOL>tax.set_xlim(d.Time[d.ns == n].min() - <NUM_LIT:3>, d.Time[d.ns == n].max() + <NUM_LIT:3>)<EOL>fig.tight_layout()<EOL>out.append((fig, (ma, ra, mah, rah, tax)))<EOL><DEDENT><DEDENT>return out<EOL>

Plot the result of signal_optimise.

`signal_optimiser` must be run first, and the output
stored in the `opt` attribute of the latools.D object.

Parameters
----------
d : latools.D object
    A latools data object.
overlay_alpha : float
    The opacity of the threshold overlays. Between 0 and 1.
**kwargs
    Passed to `tplot`


values = nominal_values(values)<EOL>return (values < threshold, values >= threshold)<EOL>

Return boolean arrays where a >= and < threshold.

Parameters
----------
values : array-like
    Array of real values.
threshold : float
    Threshold value

Returns
-------
(below, above) : tuple or boolean arrays


cfilt = filt.copy()<EOL>inds = bool_2_indices(~filt)<EOL>rem = (np.diff(inds) >= threshold)[:, <NUM_LIT:0>]<EOL>if any(rem):<EOL><INDENT>if inds[rem].shape[<NUM_LIT:0>] > <NUM_LIT:1>:<EOL><INDENT>limit = inds[rem][<NUM_LIT:1>, <NUM_LIT:0>]<EOL>cfilt[limit:] = False<EOL><DEDENT><DEDENT>return cfilt<EOL>

Exclude all data after the first excluded portion.

This makes sense for spot measurements where, because
of the signal mixing inherent in LA-ICPMS, once a
contaminant is ablated, it will always be present to
some degree in signals from further down the ablation
pit.

Parameters
----------
filt : boolean array
threshold : int

Returns
-------
filter : boolean array


def defrag(filt, threshold=<NUM_LIT:3>, mode='<STR_LIT>'):

if bool_2_indices(filt) is None:<EOL><INDENT>return filt<EOL><DEDENT>if mode == '<STR_LIT>':<EOL><INDENT>inds = bool_2_indices(~filt) + <NUM_LIT:1><EOL>rep = True<EOL><DEDENT>if mode == '<STR_LIT>':<EOL><INDENT>inds = bool_2_indices(filt) + <NUM_LIT:1><EOL>rep = False<EOL><DEDENT>rem = (np.diff(inds) <= threshold)[:, <NUM_LIT:0>]<EOL>cfilt = filt.copy()<EOL>if any(rem):<EOL><INDENT>for lo, hi in inds[rem]:<EOL><INDENT>cfilt[lo:hi] = rep<EOL><DEDENT><DEDENT>return cfilt<EOL>

'Defragment' a filter.

Parameters
----------
filt : boolean array
    A filter
threshold : int
    Consecutive values equal to or below this threshold
    length are considered fragments, and will be removed.
mode : str
    Wheter to change False fragments to True ('include')
    or True fragments to False ('exclude')

Returns
-------
defragmented filter : boolean array


def trim(ind, start=<NUM_LIT:1>, end=<NUM_LIT:0>):

return np.roll(ind, start) & np.roll(ind, -end)<EOL>

Remove points from the start and end of True regions.

Parameters
----------
start, end : int
    The number of points to remove from the start and end of
    the specified filter.
ind : boolean array
    Which filter to trim. If True, applies to currently active
    filters.


def add(self, name, filt, info='<STR_LIT>', params=(), setn=None):

iname = '<STR_LIT>'.format(self.n) + name<EOL>self.index[self.n] = iname<EOL>if setn is None:<EOL><INDENT>setn = self.maxset + <NUM_LIT:1><EOL><DEDENT>self.maxset = setn<EOL>if setn not in self.sets.keys():<EOL><INDENT>self.sets[setn] = [iname]<EOL><DEDENT>else:<EOL><INDENT>self.sets[setn].append(iname)<EOL><DEDENT>self.components[iname] = filt<EOL>self.info[iname] = info<EOL>self.params[iname] = params<EOL>for a in self.analytes:<EOL><INDENT>self.switches[a][iname] = False<EOL><DEDENT>self.n += <NUM_LIT:1><EOL>return<EOL>

Add filter.

Parameters
----------
name : str
    filter name
filt : array_like
    boolean filter array
info : str
    informative description of the filter
params : tuple
    parameters used to make the filter

Returns
-------
None


if isinstance(name, int):<EOL><INDENT>name = self.index[name]<EOL><DEDENT>if setn is not None:<EOL><INDENT>name = self.sets[setn]<EOL>del self.sets[setn]<EOL><DEDENT>elif isinstance(name, (int, str)):<EOL><INDENT>name = [name]<EOL><DEDENT>if setn is True:<EOL><INDENT>for n in name:<EOL><INDENT>for k, v in self.sets.items():<EOL><INDENT>if n in v:<EOL><INDENT>name.append([m for m in v if m != n])<EOL><DEDENT><DEDENT><DEDENT><DEDENT>for n in name:<EOL><INDENT>for k, v in self.sets.items():<EOL><INDENT>if n in v:<EOL><INDENT>self.sets[k] = [m for m in v if n != m]<EOL><DEDENT><DEDENT>del self.components[n]<EOL>del self.info[n]<EOL>del self.params[n]<EOL>del self.keys[n]<EOL>for a in self.analytes:<EOL><INDENT>del self.switches[a][n]<EOL><DEDENT>return<EOL><DEDENT>

Remove filter.

Parameters
----------
name : str
    name of the filter to remove
setn : int or True
    int: number of set to remove
    True: remove all filters in set that 'name' belongs to

Returns
-------
None


self.components = {}<EOL>self.info = {}<EOL>self.params = {}<EOL>self.switches = {}<EOL>self.keys = {}<EOL>self.index = {}<EOL>self.sets = {}<EOL>self.maxset = -<NUM_LIT:1><EOL>self.n = <NUM_LIT:0><EOL>for a in self.analytes:<EOL><INDENT>self.switches[a] = {}<EOL><DEDENT>return<EOL>


for f in sorted(self.components.keys()):<EOL><INDENT>unused = not any(self.switches[a][f] for a in self.analytes)<EOL>if unused:<EOL><INDENT>self.remove(f)<EOL><DEDENT><DEDENT>