Copy disabled (too large)
Download .txt
Showing preview only (10,351K chars total). Download the full file to get everything.
Repository: FreyrS/dMaSIF
Branch: master
Commit: 0dcc26c3c218
Files: 34
Total size: 9.9 MB
Directory structure:
gitextract_4r95syc5/
├── .gitignore
├── Arguments.py
├── LICENSE.md
├── README.md
├── benchmark_layers.py
├── benchmark_models.py
├── benchmark_scripts/
│ ├── DGCNN_site.sh
│ ├── Pointnet_site.sh
│ ├── dMaSIF_search.sh
│ └── dMaSIF_site.sh
├── data.py
├── data_analysis/
│ ├── analyse_atomnet.ipynb
│ ├── analyse_descriptors.py
│ ├── analyse_descriptors_para.py
│ ├── analyse_output.ipynb
│ ├── analyse_site_outputs.py
│ ├── analyse_site_outputs_graph.ipynb
│ ├── plot_search.ipynb
│ └── profiling_surface.ipynb
├── data_iteration.py
├── data_preprocessing/
│ ├── convert_pdb2npy.py
│ ├── convert_ply2npy.py
│ └── download_pdb.py
├── geometry_processing.py
├── helper.py
├── lists/
│ ├── testing.txt
│ ├── testing_ppi.txt
│ ├── training.txt
│ └── training_ppi.txt
├── main_inference.py
├── main_training.py
├── model.py
├── models/
│ └── dMaSIF_search_3layer_12A_16dim
└── requirements.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
01-benchmark_surfaces/
01-benchmark_surfaces_npy/
01-benchmark_pdbs_npy/
01-benchmark_pdbs/
01-benchmark_pdbs/
shape_index/
masif_preds/
runs/
venv/
preds/
*.log
NeurIPS_2020_benchmarks/
*.out
figures/
timings/
data_analysis/roc_curves
data_analysis/.ipynb_checkpoints/
.ipynb_checkpoints/
================================================
FILE: Arguments.py
================================================
import argparse
parser = argparse.ArgumentParser(description="Network parameters")
# Main parameters
parser.add_argument(
"--experiment_name", type=str, help="Name of experiment", required=True
)
parser.add_argument(
"--use_mesh", type=bool, default=False, help="Use precomputed surfaces"
)
parser.add_argument(
"--embedding_layer",
type=str,
default="dMaSIF",
choices=["dMaSIF", "DGCNN", "PointNet++"],
help="Which convolutional embedding layer to use",
)
parser.add_argument("--profile", type=bool, default=False, help="Profile code")
# Geometric parameters
parser.add_argument(
"--curvature_scales",
type=list,
default=[1.0, 2.0, 3.0, 5.0, 10.0],
help="Scales at which we compute the geometric features (mean and Gauss curvatures)",
)
parser.add_argument(
"--resolution",
type=float,
default=1.0,
help="Resolution of the generated point cloud",
)
parser.add_argument(
"--distance",
type=float,
default=1.05,
help="Distance parameter in surface generation",
)
parser.add_argument(
"--variance",
type=float,
default=0.1,
help="Variance parameter in surface generation",
)
parser.add_argument(
"--sup_sampling", type=int, default=20, help="Sup-sampling ratio around atoms"
)
# Hyper-parameters for the embedding
parser.add_argument(
"--atom_dims",
type=int,
default=6,
help="Number of atom types and dimension of resulting chemical features",
)
parser.add_argument(
"--emb_dims",
type=int,
default=8,
help="Number of input features (+ 3 xyz coordinates for DGCNNs)",
)
parser.add_argument(
"--in_channels",
type=int,
default=16,
help="Number of embedding dimensions",
)
parser.add_argument(
"--orientation_units",
type=int,
default=16,
help="Number of hidden units for the orientation score MLP",
)
parser.add_argument(
"--unet_hidden_channels",
type=int,
default=8,
help="Number of hidden units for TangentConv UNet",
)
parser.add_argument(
"--post_units",
type=int,
default=8,
help="Number of hidden units for the post-processing MLP",
)
parser.add_argument(
"--n_layers", type=int, default=1, help="Number of convolutional layers"
)
parser.add_argument(
"--radius", type=float, default=9.0, help="Radius to use for the convolution"
)
parser.add_argument(
"--k",
type=int,
default=40,
help="Number of nearset neighbours for DGCNN and PointNet++",
)
parser.add_argument(
"--dropout",
type=float,
default=0.0,
help="Amount of Dropout for the input features",
)
# Training
parser.add_argument(
"--n_epochs", type=int, default=50, help="Number of training epochs"
)
parser.add_argument(
"--batch_size", type=int, default=1, help="Number of proteins in a batch"
)
parser.add_argument(
"--device", type=str, default="cuda:0", help="Which gpu/cpu to train on"
)
parser.add_argument(
"--restart_training",
type=str,
default="",
help="Which model to restart the training from",
)
parser.add_argument(
"--n_rocauc_samples",
type=int,
default=100,
help="Number of samples for the Matching ROC-AUC",
)
parser.add_argument(
"--validation_fraction",
type=float,
default=0.1,
help="Fraction of training dataset to use for validation",
)
parser.add_argument("--seed", type=int, default=42, help="Random seed")
parser.add_argument(
"--random_rotation",
type=bool,
default=False,
help="Move proteins to center and add random rotation",
)
parser.add_argument(
"--single_protein",
type=bool,
default=False,
help="Use single protein in a pair or both",
)
parser.add_argument("--site", type=bool, default=False, help="Predict interaction site")
parser.add_argument(
"--search",
type=bool,
default=False,
help="Predict matching between two partners",
)
parser.add_argument(
"--no_chem", type=bool, default=False, help="Predict without chemical information"
)
parser.add_argument(
"--no_geom", type=bool, default=False, help="Predict without curvature information"
)
parser.add_argument(
"--single_pdb",
type=str,
default="",
help="Which structure to do inference on",
)
parser.add_argument(
"--pdb_list",
type=str,
default="",
help="Which structures to do inference on",
)
================================================
FILE: LICENSE.md
================================================
Attribution-NonCommercial-NoDerivatives 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-NonCommercial-NoDerivatives 4.0
International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International Public
License ("Public License"). To the extent this Public License may be
interpreted as a contract, You are granted the Licensed Rights in
consideration of Your acceptance of these terms and conditions, and the
Licensor grants You such rights in consideration of benefits the
Licensor receives from making the Licensed Material available under
these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
c. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
d. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
e. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
f. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
g. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
h. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of
this Public License, the exchange of the Licensed Material for
other material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is
no payment of monetary compensation in connection with the
exchange.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part, for NonCommercial purposes only; and
b. produce and reproduce, but not Share, Adapted Material
for NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties, including when
the Licensed Material is used other than for NonCommercial
purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material, You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
For the avoidance of doubt, You do not have permission under
this Public License to Share Adapted Material.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database for NonCommercial purposes
only and provided You do not Share Adapted Material;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.
================================================
FILE: README.md
================================================
## dMaSIF - Fast end-to-end learning on protein surfaces

## Abstract
Proteins’ biological functions are defined by the geometric
and chemical structure of their 3D molecular surfaces.
Recent works have shown that geometric deep learning can
be used on mesh-based representations of proteins to identify
potential functional sites, such as binding targets for
potential drugs. Unfortunately though, the use of meshes as
the underlying representation for protein structure has multiple
drawbacks including the need to pre-compute the input
features and mesh connectivities. This becomes a bottleneck
for many important tasks in protein science.
In this paper, we present a new framework for deep
learning on protein structures that addresses these limitations.
Among the key advantages of our method are the computation
and sampling of the molecular surface on-the-fly
from the underlying atomic point cloud and a novel efficient
geometric convolutional layer. As a result, we are able to
process large collections of proteins in an end-to-end fashion,
taking as the sole input the raw 3D coordinates and
chemical types of their atoms, eliminating the need for any
hand-crafted pre-computed features.
To showcase the performance of our approach, we test it
on two tasks in the field of protein structural bioinformatics:
the identification of interaction sites and the prediction
of protein-protein interactions. On both tasks, we achieve
state-of-the-art performance with much faster run times and
fewer parameters than previous models. These results will
considerably ease the deployment of deep learning methods
in protein science and open the door for end-to-end differentiable
approaches in protein modeling tasks such as function
prediction and design.
## Hardware requirements
Models have been trained on either a single NVIDIA RTX 2080 Ti or a single Tesla V100 GPU. Time and memory benchmarks were performed on a single Tesla V100.
## Software prerequisites
Scripts have been tested using the following two sets of core dependencies:
| Dependency | First Option | Second Option |
| ------------- | ------------- | ------------- |
| GCC | 7.5.0 | 8.4.0 |
| CMAKE | 3.10.2 | 3.16.5 |
| CUDA | 10.0.130 | 10.2.89 |
| cuDNN | 7.6.4.38 | 7.6.5.32 |
| Python | 3.6.9 | 3.7.7 |
| PyTorch | 1.4.0 | 1.6.0 |
| PyKeops | 1.4 | 1.4.1 |
| PyTorch Geometric | 1.5.0 | 1.6.1 |
## Code overview
Usage:
- In order to **train models**, run `main_training.py` with the appropriate flags.
Available flags and their descriptions can be found in `Arguments.py`.
- The command line options needed to reproduce the **benchmarks** can be found in `benchmark_scripts/`.
- To make **inference** on the testing set using pretrained models, use `main_inference.py` with the flags that were used for training the models.
Note that the `--experiment_name flag` should be modified to specify the training epoch to use.
Implementation:
- Our **surface generation** algorithm, **curvature** estimation method and **quasi-geodesic convolutions** are implemented in `geometry_processing.py`.
- The **definition of the neural network** along with surface and input features can be found in `model.py`. The convolutional layers are implemented in `benchmark_models.py`.
- The scripts used to **generate the figures** of the paper can be found in `data_analysis/`.
## License
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>.
## Reference
Sverrisson, F., Feydy, J., Correia, B. E., & Bronstein, M. M. (2020). Fast end-to-end learning on protein surfaces. [bioRxiv](https://www.biorxiv.org/content/10.1101/2020.12.28.424589v1).
================================================
FILE: benchmark_layers.py
================================================
import torch
from typing import Optional
from pykeops.torch import LazyTensor
from torch_geometric.nn import EdgeConv, Reshape
from torch_cluster import knn
from math import ceil
from torch_geometric.nn.inits import reset
from torch.nn import ELU, Conv1d
from torch.nn import Sequential as S, Linear as L, BatchNorm1d as BN
def ranges_slices(batch):
"""Helper function for the diagonal ranges function."""
Ns = batch.bincount()
indices = Ns.cumsum(0)
ranges = torch.cat((0 * indices[:1], indices))
ranges = (
torch.stack((ranges[:-1], ranges[1:])).t().int().contiguous().to(batch.device)
)
slices = (1 + torch.arange(len(Ns))).int().to(batch.device)
return ranges, slices
def diagonal_ranges(batch_x=None, batch_y=None):
"""Encodes the block-diagonal structure associated to a batch vector."""
if batch_x is None and batch_y is None:
return None
ranges_x, slices_x = ranges_slices(batch_x)
ranges_y, slices_y = ranges_slices(batch_y)
return ranges_x, slices_x, ranges_y, ranges_y, slices_y, ranges_x
@torch.jit.ignore
def keops_knn(
x: torch.Tensor,
y: torch.Tensor,
k: int,
batch_x: Optional[torch.Tensor] = None,
batch_y: Optional[torch.Tensor] = None,
cosine: bool = False,
) -> torch.Tensor:
r"""Straightforward modification of PyTorch_geometric's knn method."""
x = x.view(-1, 1) if x.dim() == 1 else x
y = y.view(-1, 1) if y.dim() == 1 else y
y_i = LazyTensor(y[:, None, :])
x_j = LazyTensor(x[None, :, :])
if cosine:
D_ij = -(y_i | x_j)
else:
D_ij = ((y_i - x_j) ** 2).sum(-1)
D_ij.ranges = diagonal_ranges(batch_y, batch_x)
idy = D_ij.argKmin(k, dim=1) # (N, K)
rows = torch.arange(k * len(y), device=idy.device) // k
return torch.stack([rows, idy.view(-1)], dim=0)
knns = {"torch": knn, "keops": keops_knn}
@torch.jit.ignore
def knn_graph(
x: torch.Tensor,
k: int,
batch: Optional[torch.Tensor] = None,
loop: bool = False,
flow: str = "source_to_target",
cosine: bool = False,
target: Optional[torch.Tensor] = None,
batch_target: Optional[torch.Tensor] = None,
backend: str = "torch",
) -> torch.Tensor:
r"""Straightforward modification of PyTorch_geometric's knn_graph method to allow for source/targets."""
assert flow in ["source_to_target", "target_to_source"]
if target is None:
target = x
if batch_target is None:
batch_target = batch
row, col = knns[backend](
x, target, k if loop else k + 1, batch, batch_target, cosine=cosine
)
row, col = (col, row) if flow == "source_to_target" else (row, col)
if not loop:
mask = row != col
row, col = row[mask], col[mask]
return torch.stack([row, col], dim=0)
class MyDynamicEdgeConv(EdgeConv):
r"""Straightforward modification of PyTorch_geometric's DynamicEdgeConv layer."""
def __init__(self, nn, k, aggr="max", **kwargs):
super(MyDynamicEdgeConv, self).__init__(nn=nn, aggr=aggr, **kwargs)
self.k = k
def forward(self, x, batch=None):
""""""
edge_index = knn_graph(
x, self.k, batch, loop=False, flow=self.flow, backend="keops"
)
return super(MyDynamicEdgeConv, self).forward(x, edge_index)
def __repr__(self):
return "{}(nn={}, k={})".format(self.__class__.__name__, self.nn, self.k)
class MyXConv(torch.nn.Module):
def __init__(
self,
in_channels=None,
out_channels=None,
dim=None,
kernel_size=None,
hidden_channels=None,
dilation=1,
bias=True,
backend="torch",
):
super(MyXConv, self).__init__()
self.in_channels = in_channels
if hidden_channels is None:
hidden_channels = in_channels // 4
if hidden_channels == 0:
hidden_channels = 1
self.hidden_channels = hidden_channels
self.out_channels = out_channels
self.dim = dim
self.kernel_size = kernel_size
self.dilation = dilation
self.backend = backend
C_in, C_delta, C_out = in_channels, hidden_channels, out_channels
D, K = dim, kernel_size
self.mlp1 = S(
L(dim, C_delta),
ELU(),
BN(C_delta),
L(C_delta, C_delta),
ELU(),
BN(C_delta),
Reshape(-1, K, C_delta),
)
self.mlp2 = S(
L(D * K, K ** 2),
ELU(),
BN(K ** 2),
Reshape(-1, K, K),
Conv1d(K, K ** 2, K, groups=K),
ELU(),
BN(K ** 2),
Reshape(-1, K, K),
Conv1d(K, K ** 2, K, groups=K),
BN(K ** 2),
Reshape(-1, K, K),
)
C_in = C_in + C_delta
depth_multiplier = int(ceil(C_out / C_in))
self.conv = S(
Conv1d(C_in, C_in * depth_multiplier, K, groups=C_in),
Reshape(-1, C_in * depth_multiplier),
L(C_in * depth_multiplier, C_out, bias=bias),
)
self.reset_parameters()
def reset_parameters(self):
reset(self.mlp1)
reset(self.mlp2)
reset(self.conv)
def forward(self, x, source, batch_source, target, batch_target):
""""""
# Load data shapes:
# pos = pos.unsqueeze(-1) if pos.dim() == 1 else pos
(Nin, _), (N, D), K = source.size(), target.size(), self.kernel_size
# Compute K-nn:
row, col = knn_graph(
source,
K * self.dilation,
batch_source,
loop=True,
flow="target_to_source",
target=target,
batch_target=batch_target,
backend=self.backend,
)
# row is a vector of size N*K*dilation that indexes "target"
# col is a vector of size N*K*dilation that indexes "source"
# If needed, sup-sample the K-NN graph:
if self.dilation > 1:
dil = self.dilation
index = torch.randint(
K * dil,
(N, K),
dtype=torch.long,
layout=torch.strided,
device=row.device,
)
arange = torch.arange(N, dtype=torch.long, device=row.device)
arange = arange * (K * dil)
index = (index + arange.view(-1, 1)).view(-1) # (N*K,)
row, col = row[index], col[index]
# assert row.max() < N
# assert col.max() < Nin
# Line 1: local difference vector:
pos = source[col] - target[row] # (N * K, D)
# Line 2: compute F_delta
x_star = self.mlp1(pos.view(N * K, D))
# Line 3: concatenate the features and reshape:
if x is not None:
x = x.unsqueeze(-1) if x.dim() == 1 else x
x = x[col].view(N, K, self.in_channels)
x_star = torch.cat([x_star, x], dim=-1)
x_star = x_star.transpose(1, 2).contiguous()
x_star = x_star.view(N, self.in_channels + self.hidden_channels, K, 1)
# Line 4: Compute the transformation matrix:
transform_matrix = self.mlp2(pos.view(N, K * D))
transform_matrix = transform_matrix.view(N, 1, K, K)
# Line 5: Apply it to the neighborhood:
x_transformed = torch.matmul(transform_matrix, x_star)
x_transformed = x_transformed.view(N, -1, K) # (N, I+H, K)
# Line 6: Apply the convolution filter:
out = self.conv(x_transformed) # (N, Cout)
return out
def __repr__(self):
return "{}({}, {})".format(
self.__class__.__name__, self.in_channels, self.out_channels
)
================================================
FILE: benchmark_models.py
================================================
import torch
import torch.nn.functional as F
import torch.nn as nn
from torch.nn import (
Sequential as Seq,
Dropout,
Linear as Lin,
LeakyReLU,
ReLU,
BatchNorm1d as BN,
)
import torch_geometric.transforms as T
from torch_geometric.data import DataLoader
from torch_geometric.nn import (
DynamicEdgeConv,
PointConv,
XConv,
fps,
radius,
global_max_pool,
knn_interpolate,
)
from pykeops.torch import LazyTensor
from benchmark_layers import MyDynamicEdgeConv, MyXConv
from geometry_processing import dMaSIFConv, mesh_normals_areas, tangent_vectors
from helper import diagonal_ranges
DEConv = {"torch": DynamicEdgeConv, "keops": MyDynamicEdgeConv}
# Dynamic Graph CNNs ===========================================================
# Adapted from the PyTorch_geometric gallery to get a close fit to
# the original paper.
def MLP(channels, batch_norm=True):
"""Multi-layer perceptron, with ReLU non-linearities and batch normalization."""
return Seq(
*[
Seq(
Lin(channels[i - 1], channels[i]),
BN(channels[i]) if batch_norm else nn.Identity(),
LeakyReLU(negative_slope=0.2),
)
for i in range(1, len(channels))
]
)
class DGCNN_seg(torch.nn.Module):
def __init__(
self, in_channels, out_channels, n_layers, k=40, aggr="max", backend="keops"
):
super(DGCNN_seg, self).__init__()
self.name = "DGCNN_seg_" + backend
self.I, self.O = (
in_channels + 3,
out_channels,
) # Add coordinates to input channels
self.n_layers = n_layers
self.transform_1 = DEConv[backend](MLP([2 * 3, 64, 128]), k, aggr)
self.transform_2 = MLP([128, 1024])
self.transform_3 = MLP([1024, 512, 256], batch_norm=False)
self.transform_4 = Lin(256, 3 * 3)
self.conv_layers = nn.ModuleList(
[DEConv[backend](MLP([2 * self.I, self.O, self.O]), k, aggr)]
+ [
DEConv[backend](MLP([2 * self.O, self.O, self.O]), k, aggr)
for i in range(n_layers - 1)
]
)
self.linear_layers = nn.ModuleList(
[
nn.Sequential(
nn.Linear(self.O, self.O), nn.ReLU(), nn.Linear(self.O, self.O)
)
for i in range(n_layers)
]
)
self.linear_transform = nn.ModuleList(
[nn.Linear(self.I, self.O)]
+ [nn.Linear(self.O, self.O) for i in range(n_layers - 1)]
)
def forward(self, positions, features, batch_indices):
# Lab: (B,), Pos: (N, 3), Batch: (N,)
pos, feat, batch = positions, features, batch_indices
# TransformNet:
x = pos # Don't use the normals!
x = self.transform_1(x, batch) # (N, 3) -> (N, 128)
x = self.transform_2(x) # (N, 128) -> (N, 1024)
x = global_max_pool(x, batch) # (B, 1024)
x = self.transform_3(x) # (B, 256)
x = self.transform_4(x) # (B, 3*3)
x = x[batch] # (N, 3*3)
x = x.view(-1, 3, 3) # (N, 3, 3)
# Apply the transform:
x0 = torch.einsum("ni,nij->nj", pos, x) # (N, 3)
# Add features to coordinates
x = torch.cat([x0, feat], dim=-1).contiguous()
for i in range(self.n_layers):
x_i = self.conv_layers[i](x, batch)
x_i = self.linear_layers[i](x_i)
x = self.linear_transform[i](x)
x = x + x_i
return x
# Reference PointNet models, from the PyTorch_geometric gallery =========================
class SAModule(torch.nn.Module):
"""Set abstraction module."""
def __init__(self, ratio, r, nn, max_num_neighbors=64):
super(SAModule, self).__init__()
self.ratio = ratio
self.r = r
self.conv = PointConv(nn)
self.max_num_neighbors = max_num_neighbors
def forward(self, x, pos, batch):
# Subsample with Farthest Point Sampling:
# idx = fps(pos, batch, ratio=self.ratio) # Extract self.ratio indices TURN OFF FOR NOW
idx = torch.arange(0, len(pos), device=pos.device)
# For each "cluster", get the list of (up to 64) neighbors in a ball of radius r:
row, col = radius(
pos,
pos[idx],
self.r,
batch,
batch[idx],
max_num_neighbors=self.max_num_neighbors,
)
# Applies the PointNet++ Conv:
edge_index = torch.stack([col, row], dim=0)
x = self.conv(x, (pos, pos[idx]), edge_index)
# Return the features and sub-sampled point clouds:
pos, batch = pos[idx], batch[idx]
return x, pos, batch
class GlobalSAModule(torch.nn.Module):
def __init__(self, nn):
super(GlobalSAModule, self).__init__()
self.nn = nn
def forward(self, x, pos, batch):
x = self.nn(torch.cat([x, pos], dim=1))
x = global_max_pool(x, batch)
pos = pos.new_zeros((x.size(0), 3))
batch = torch.arange(x.size(0), device=batch.device)
return x, pos, batch
class FPModule(torch.nn.Module):
def __init__(self, k, nn):
super(FPModule, self).__init__()
self.k = k
self.nn = nn
def forward(self, x, pos, batch, x_skip, pos_skip, batch_skip):
x = knn_interpolate(x, pos, pos_skip, batch, batch_skip, k=self.k)
if x_skip is not None:
x = torch.cat([x, x_skip], dim=1)
x = self.nn(x)
return x, pos_skip, batch_skip
class PointNet2_seg(torch.nn.Module):
def __init__(self, args, in_channels, out_channels):
super(PointNet2_seg, self).__init__()
self.name = "PointNet2"
self.I, self.O = in_channels, out_channels
self.radius = args.radius
self.k = 10000 # We don't restrict the number of points in a patch
self.n_layers = args.n_layers
# self.sa1_module = SAModule(1.0, self.radius, MLP([self.I+3, self.O, self.O]),self.k)
self.layers = nn.ModuleList(
[SAModule(1.0, self.radius, MLP([self.I + 3, self.O, self.O]), self.k)]
+ [
SAModule(1.0, self.radius, MLP([self.O + 3, self.O, self.O]), self.k)
for i in range(self.n_layers - 1)
]
)
self.linear_layers = nn.ModuleList(
[
nn.Sequential(
nn.Linear(self.O, self.O), nn.ReLU(), nn.Linear(self.O, self.O)
)
for i in range(self.n_layers)
]
)
self.linear_transform = nn.ModuleList(
[nn.Linear(self.I, self.O)]
+ [nn.Linear(self.O, self.O) for i in range(self.n_layers - 1)]
)
def forward(self, positions, features, batch_indices):
x = (features, positions, batch_indices)
for i, layer in enumerate(self.layers):
x_i, pos, b_ind = layer(*x)
x_i = self.linear_layers[i](x_i)
x = self.linear_transform[i](x[0])
x = x + x_i
x = (x, pos, b_ind)
return x[0]
## TangentConv benchmark segmentation
class dMaSIFConv_seg(torch.nn.Module):
def __init__(self, args, in_channels, out_channels, n_layers, radius=9.0):
super(dMaSIFConv_seg, self).__init__()
self.name = "dMaSIFConv_seg_keops"
self.radius = radius
self.I, self.O = in_channels, out_channels
self.layers = nn.ModuleList(
[dMaSIFConv(self.I, self.O, radius, self.O)]
+ [dMaSIFConv(self.O, self.O, radius, self.O) for i in range(n_layers - 1)]
)
self.linear_layers = nn.ModuleList(
[
nn.Sequential(
nn.Linear(self.O, self.O), nn.ReLU(), nn.Linear(self.O, self.O)
)
for i in range(n_layers)
]
)
self.linear_transform = nn.ModuleList(
[nn.Linear(self.I, self.O)]
+ [nn.Linear(self.O, self.O) for i in range(n_layers - 1)]
)
def forward(self, features):
# Lab: (B,), Pos: (N, 3), Batch: (N,)
points, nuv, ranges = self.points, self.nuv, self.ranges
x = features
for i, layer in enumerate(self.layers):
x_i = layer(points, nuv, x, ranges)
x_i = self.linear_layers[i](x_i)
x = self.linear_transform[i](x)
x = x + x_i
return x
def load_mesh(self, xyz, triangles=None, normals=None, weights=None, batch=None):
"""Loads the geometry of a triangle mesh.
Input arguments:
- xyz, a point cloud encoded as an (N, 3) Tensor.
- triangles, a connectivity matrix encoded as an (N, 3) integer tensor.
- weights, importance weights for the orientation estimation, encoded as an (N, 1) Tensor.
- radius, the scale used to estimate the local normals.
- a batch vector, following PyTorch_Geometric's conventions.
The routine updates the model attributes:
- points, i.e. the point cloud itself,
- nuv, a local oriented basis in R^3 for every point,
- ranges, custom KeOps syntax to implement batch processing.
"""
# 1. Save the vertices for later use in the convolutions ---------------
self.points = xyz
self.batch = batch
self.ranges = diagonal_ranges(
batch
) # KeOps support for heterogeneous batch processing
self.triangles = triangles
self.normals = normals
self.weights = weights
# 2. Estimate the normals and tangent frame ----------------------------
# Normalize the scale:
points = xyz / self.radius
# Normals and local areas:
if normals is None:
normals, areas = mesh_normals_areas(points, triangles, 0.5, batch)
tangent_bases = tangent_vectors(normals) # Tangent basis (N, 2, 3)
# 3. Steer the tangent bases according to the gradient of "weights" ----
# 3.a) Encoding as KeOps LazyTensors:
# Orientation scores:
weights_j = LazyTensor(weights.view(1, -1, 1)) # (1, N, 1)
# Vertices:
x_i = LazyTensor(points[:, None, :]) # (N, 1, 3)
x_j = LazyTensor(points[None, :, :]) # (1, N, 3)
# Normals:
n_i = LazyTensor(normals[:, None, :]) # (N, 1, 3)
n_j = LazyTensor(normals[None, :, :]) # (1, N, 3)
# Tangent basis:
uv_i = LazyTensor(tangent_bases.view(-1, 1, 6)) # (N, 1, 6)
# 3.b) Pseudo-geodesic window:
# Pseudo-geodesic squared distance:
rho2_ij = ((x_j - x_i) ** 2).sum(-1) * ((2 - (n_i | n_j)) ** 2) # (N, N, 1)
# Gaussian window:
window_ij = (-rho2_ij).exp() # (N, N, 1)
# 3.c) Coordinates in the (u, v) basis - not oriented yet:
X_ij = uv_i.matvecmult(x_j - x_i) # (N, N, 2)
# 3.d) Local average in the tangent plane:
orientation_weight_ij = window_ij * weights_j # (N, N, 1)
orientation_vector_ij = orientation_weight_ij * X_ij # (N, N, 2)
# Support for heterogeneous batch processing:
orientation_vector_ij.ranges = self.ranges # Block-diagonal sparsity mask
orientation_vector_i = orientation_vector_ij.sum(dim=1) # (N, 2)
orientation_vector_i = (
orientation_vector_i + 1e-5
) # Just in case someone's alone...
# 3.e) Normalize stuff:
orientation_vector_i = F.normalize(orientation_vector_i, p=2, dim=-1) # (N, 2)
ex_i, ey_i = (
orientation_vector_i[:, 0][:, None],
orientation_vector_i[:, 1][:, None],
) # (N,1)
# 3.f) Re-orient the (u,v) basis:
uv_i = tangent_bases # (N, 2, 3)
u_i, v_i = uv_i[:, 0, :], uv_i[:, 1, :] # (N, 3)
tangent_bases = torch.cat(
(ex_i * u_i + ey_i * v_i, -ey_i * u_i + ex_i * v_i), dim=1
).contiguous() # (N, 6)
# 4. Store the local 3D frame as an attribute --------------------------
self.nuv = torch.cat(
(normals.view(-1, 1, 3), tangent_bases.view(-1, 2, 3)), dim=1
)
================================================
FILE: benchmark_scripts/DGCNN_site.sh
================================================
# Load environment
python -W ignore -u main_training.py --experiment_name DGCNN_site_1layer_k200 --batch_size 64 --embedding_layer DGCNN --site True --single_protein True --device cuda:0 --n_layers 1 --random_rotation True --k 200
python -W ignore -u main_training.py --experiment_name DGCNN_site_1layer_k100 --batch_size 64 --embedding_layer DGCNN --site True --single_protein True --device cuda:0 --n_layers 1 --random_rotation True --k 100
python -W ignore -u main_training.py --experiment_name DGCNN_site_3layer_k200 --batch_size 64 --embedding_layer DGCNN --site True --single_protein True --device cuda:0 --n_layers 3 --random_rotation True --k 200
python -W ignore -u main_training.py --experiment_name DGCNN_site_3layer_k100 --batch_size 64 --embedding_layer DGCNN --site True --single_protein True --device cuda:0 --n_layers 3 --random_rotation True --k 100
================================================
FILE: benchmark_scripts/Pointnet_site.sh
================================================
# Load environment
python -W ignore -u main_training.py --experiment_name PointNet_site_3layer_15A --batch_size 64 --embedding_layer PointNet++ --site True --single_protein True --device cuda:0 --random_rotation True --radius 15.0 --n_layers 3
python -W ignore -u main_training.py --experiment_name PointNet_site_3layer_5A --batch_size 64 --embedding_layer PointNet++ --site True --single_protein True --device cuda:0 --random_rotation True --radius 5.0 --n_layers 3
python -W ignore -u main_training.py --experiment_name PointNet_site_3layer_9A --batch_size 64 --embedding_layer PointNet++ --site True --single_protein True --device cuda:0 --random_rotation True --radius 9.0 --n_layers 3
python -W ignore -u main_training.py --experiment_name PointNet_site_1layer_15A --batch_size 64 --embedding_layer PointNet++ --site True --single_protein True --device cuda:0 --random_rotation True --radius 15.0 --n_layers 1
python -W ignore -u main_training.py --experiment_name PointNet_site_1layer_5A --batch_size 64 --embedding_layer PointNet++ --site True --single_protein True --device cuda:0 --random_rotation True --radius 5.0 --n_layers 1
python -W ignore -u main_training.py --experiment_name PointNet_site_1layer_9A --batch_size 64 --embedding_layer PointNet++ --site True --single_protein True --device cuda:0 --random_rotation True --radius 9.0 --n_layers 1
================================================
FILE: benchmark_scripts/dMaSIF_search.sh
================================================
# Load environment
python -W ignore -u main_training.py --experiment_name dMaSIF_search_1layer_12A --batch_size 64 --embedding_layer dMaSIF --search True --device cuda:0 --random_rotation True --radius 12.0 --n_layers 1
python -W ignore -u main_training.py --experiment_name dMaSIF_search_3layer_12A --batch_size 64 --embedding_layer dMaSIF --search True --device cuda:0 --random_rotation True --radius 12.0 --n_layers 3
================================================
FILE: benchmark_scripts/dMaSIF_site.sh
================================================
# Load environment
python -W ignore -u main_training.py --experiment_name dMaSIF_site_1layer_15A --batch_size 64 --embedding_layer dMaSIF --site True --single_protein True --random_rotation True --radius 15.0 --n_layers 1
python -W ignore -u main_training.py --experiment_name dMaSIF_site_1layer_5A --batch_size 64 --embedding_layer dMaSIF --site True --single_protein True --random_rotation True --radius 5.0 --n_layers 1
python -W ignore -u main_training.py --experiment_name dMaSIF_site_1layer_9A --batch_size 64 --embedding_layer dMaSIF --site True --single_protein True --random_rotation True --radius 9.0 --n_layers 1
python -W ignore -u main_training.py --experiment_name dMaSIF_site_3layer_15A --batch_size 64 --embedding_layer dMaSIF --site True --single_protein True --random_rotation True --radius 15.0 --n_layers 3
python -W ignore -u main_training.py --experiment_name dMaSIF_site_3layer_5A --batch_size 64 --embedding_layer dMaSIF --site True --single_protein True --random_rotation True --radius 5.0 --n_layers 3
python -W ignore -u main_training.py --experiment_name dMaSIF_site_3layer_9A --batch_size 64 --embedding_layer dMaSIF --site True --single_protein True --random_rotation True --radius 9.0 --n_layers 3
================================================
FILE: data.py
================================================
import torch
from torch_geometric.data import InMemoryDataset, Data, DataLoader
from torch_geometric.transforms import Compose
import numpy as np
from scipy.spatial.transform import Rotation
import math
import urllib.request
import tarfile
from pathlib import Path
import requests
from data_preprocessing.convert_pdb2npy import convert_pdbs
from data_preprocessing.convert_ply2npy import convert_plys
tensor = torch.FloatTensor
inttensor = torch.LongTensor
def numpy(x):
return x.detach().cpu().numpy()
def iface_valid_filter(protein_pair):
labels1 = protein_pair.y_p1.reshape(-1)
labels2 = protein_pair.y_p2.reshape(-1)
valid1 = (
(torch.sum(labels1) < 0.75 * len(labels1))
and (torch.sum(labels1) > 30)
and (torch.sum(labels1) > 0.01 * labels2.shape[0])
)
valid2 = (
(torch.sum(labels2) < 0.75 * len(labels2))
and (torch.sum(labels2) > 30)
and (torch.sum(labels2) > 0.01 * labels1.shape[0])
)
return valid1 and valid2
class RandomRotationPairAtoms(object):
r"""Randomly rotate a protein"""
def __call__(self, data):
R1 = tensor(Rotation.random().as_matrix())
R2 = tensor(Rotation.random().as_matrix())
data.atom_coords_p1 = torch.matmul(R1, data.atom_coords_p1.T).T
data.xyz_p1 = torch.matmul(R1, data.xyz_p1.T).T
data.normals_p1 = torch.matmul(R1, data.normals_p1.T).T
data.atom_coords_p2 = torch.matmul(R2, data.atom_coords_p2.T).T
data.xyz_p2 = torch.matmul(R2, data.xyz_p2.T).T
data.normals_p2 = torch.matmul(R2, data.normals_p2.T).T
data.rand_rot1 = R1
data.rand_rot2 = R2
return data
def __repr__(self):
return "{}()".format(self.__class__.__name__)
class CenterPairAtoms(object):
r"""Centers a protein"""
def __call__(self, data):
atom_center1 = data.atom_coords_p1.mean(dim=-2, keepdim=True)
atom_center2 = data.atom_coords_p2.mean(dim=-2, keepdim=True)
data.atom_coords_p1 = data.atom_coords_p1 - atom_center1
data.atom_coords_p2 = data.atom_coords_p2 - atom_center2
data.xyz_p1 = data.xyz_p1 - atom_center1
data.xyz_p2 = data.xyz_p2 - atom_center2
data.atom_center1 = atom_center1
data.atom_center2 = atom_center2
return data
def __repr__(self):
return "{}()".format(self.__class__.__name__)
class NormalizeChemFeatures(object):
r"""Centers a protein"""
def __call__(self, data):
pb_upper = 3.0
pb_lower = -3.0
chem_p1 = data.chemical_features_p1
chem_p2 = data.chemical_features_p2
pb_p1 = chem_p1[:, 0]
pb_p2 = chem_p2[:, 0]
hb_p1 = chem_p1[:, 1]
hb_p2 = chem_p2[:, 1]
hp_p1 = chem_p1[:, 2]
hp_p2 = chem_p2[:, 2]
# Normalize PB
pb_p1 = torch.clamp(pb_p1, pb_lower, pb_upper)
pb_p1 = (pb_p1 - pb_lower) / (pb_upper - pb_lower)
pb_p1 = 2 * pb_p1 - 1
pb_p2 = torch.clamp(pb_p2, pb_lower, pb_upper)
pb_p2 = (pb_p2 - pb_lower) / (pb_upper - pb_lower)
pb_p2 = 2 * pb_p2 - 1
# Normalize HP
hp_p1 = hp_p1 / 4.5
hp_p2 = hp_p2 / 4.5
data.chemical_features_p1 = torch.stack([pb_p1, hb_p1, hp_p1]).T
data.chemical_features_p2 = torch.stack([pb_p2, hb_p2, hp_p2]).T
return data
def __repr__(self):
return "{}()".format(self.__class__.__name__)
def load_protein_npy(pdb_id, data_dir, center=False, single_pdb=False):
"""Loads a protein surface mesh and its features"""
# Load the data, and read the connectivity information:
triangles = (
None
if single_pdb
else inttensor(np.load(data_dir / (pdb_id + "_triangles.npy"))).T
)
# Normalize the point cloud, as specified by the user:
points = None if single_pdb else tensor(np.load(data_dir / (pdb_id + "_xyz.npy")))
center_location = None if single_pdb else torch.mean(points, axis=0, keepdims=True)
atom_coords = tensor(np.load(data_dir / (pdb_id + "_atomxyz.npy")))
atom_types = tensor(np.load(data_dir / (pdb_id + "_atomtypes.npy")))
if center:
points = points - center_location
atom_coords = atom_coords - center_location
# Interface labels
iface_labels = (
None
if single_pdb
else tensor(np.load(data_dir / (pdb_id + "_iface_labels.npy")).reshape((-1, 1)))
)
# Features
chemical_features = (
None if single_pdb else tensor(np.load(data_dir / (pdb_id + "_features.npy")))
)
# Normals
normals = (
None if single_pdb else tensor(np.load(data_dir / (pdb_id + "_normals.npy")))
)
protein_data = Data(
xyz=points,
face=triangles,
chemical_features=chemical_features,
y=iface_labels,
normals=normals,
center_location=center_location,
num_nodes=None if single_pdb else points.shape[0],
atom_coords=atom_coords,
atom_types=atom_types,
)
return protein_data
class PairData(Data):
def __init__(
self,
xyz_p1=None,
xyz_p2=None,
face_p1=None,
face_p2=None,
chemical_features_p1=None,
chemical_features_p2=None,
y_p1=None,
y_p2=None,
normals_p1=None,
normals_p2=None,
center_location_p1=None,
center_location_p2=None,
atom_coords_p1=None,
atom_coords_p2=None,
atom_types_p1=None,
atom_types_p2=None,
atom_center1=None,
atom_center2=None,
rand_rot1=None,
rand_rot2=None,
):
super().__init__()
self.xyz_p1 = xyz_p1
self.xyz_p2 = xyz_p2
self.face_p1 = face_p1
self.face_p2 = face_p2
self.chemical_features_p1 = chemical_features_p1
self.chemical_features_p2 = chemical_features_p2
self.y_p1 = y_p1
self.y_p2 = y_p2
self.normals_p1 = normals_p1
self.normals_p2 = normals_p2
self.center_location_p1 = center_location_p1
self.center_location_p2 = center_location_p2
self.atom_coords_p1 = atom_coords_p1
self.atom_coords_p2 = atom_coords_p2
self.atom_types_p1 = atom_types_p1
self.atom_types_p2 = atom_types_p2
self.atom_center1 = atom_center1
self.atom_center2 = atom_center2
self.rand_rot1 = rand_rot1
self.rand_rot2 = rand_rot2
def __inc__(self, key, value):
if key == "face_p1":
return self.xyz_p1.size(0)
if key == "face_p2":
return self.xyz_p2.size(0)
else:
return super(PairData, self).__inc__(key, value)
def __cat_dim__(self, key, value):
if ("index" in key) or ("face" in key):
return 1
else:
return 0
def load_protein_pair(pdb_id, data_dir,single_pdb=False):
"""Loads a protein surface mesh and its features"""
pspl = pdb_id.split("_")
p1_id = pspl[0] + "_" + pspl[1]
p2_id = pspl[0] + "_" + pspl[2]
p1 = load_protein_npy(p1_id, data_dir, center=False,single_pdb=single_pdb)
p2 = load_protein_npy(p2_id, data_dir, center=False,single_pdb=single_pdb)
# pdist = ((p1['xyz'][:,None,:]-p2['xyz'][None,:,:])**2).sum(-1).sqrt()
# pdist = pdist<2.0
# y_p1 = (pdist.sum(1)>0).to(torch.float).reshape(-1,1)
# y_p2 = (pdist.sum(0)>0).to(torch.float).reshape(-1,1)
y_p1 = p1["y"]
y_p2 = p2["y"]
protein_pair_data = PairData(
xyz_p1=p1["xyz"],
xyz_p2=p2["xyz"],
face_p1=p1["face"],
face_p2=p2["face"],
chemical_features_p1=p1["chemical_features"],
chemical_features_p2=p2["chemical_features"],
y_p1=y_p1,
y_p2=y_p2,
normals_p1=p1["normals"],
normals_p2=p2["normals"],
center_location_p1=p1["center_location"],
center_location_p2=p2["center_location"],
atom_coords_p1=p1["atom_coords"],
atom_coords_p2=p2["atom_coords"],
atom_types_p1=p1["atom_types"],
atom_types_p2=p2["atom_types"],
)
return protein_pair_data
class ProteinPairsSurfaces(InMemoryDataset):
url = ""
def __init__(self, root, ppi=False, train=True, transform=None, pre_transform=None):
self.ppi = ppi
super(ProteinPairsSurfaces, self).__init__(root, transform, pre_transform)
path = self.processed_paths[0] if train else self.processed_paths[1]
self.data, self.slices = torch.load(path)
@property
def raw_file_names(self):
return "masif_site_masif_search_pdbs_and_ply_files.tar.gz"
@property
def processed_file_names(self):
if not self.ppi:
file_names = [
"training_pairs_data.pt",
"testing_pairs_data.pt",
"training_pairs_data_ids.npy",
"testing_pairs_data_ids.npy",
]
else:
file_names = [
"training_pairs_data_ppi.pt",
"testing_pairs_data_ppi.pt",
"training_pairs_data_ids_ppi.npy",
"testing_pairs_data_ids_ppi.npy",
]
return file_names
def download(self):
url = 'https://zenodo.org/record/2625420/files/masif_site_masif_search_pdbs_and_ply_files.tar.gz'
target_path = self.raw_paths[0]
response = requests.get(url, stream=True)
if response.status_code == 200:
with open(target_path, 'wb') as f:
f.write(response.raw.read())
#raise RuntimeError(
# "Dataset not found. Please download {} from {} and move it to {}".format(
# self.raw_file_names, self.url, self.raw_dir
# )
#)
def process(self):
pdb_dir = Path(self.root) / "raw" / "01-benchmark_pdbs"
surf_dir = Path(self.root) / "raw" / "01-benchmark_surfaces"
protein_dir = Path(self.root) / "raw" / "01-benchmark_surfaces_npy"
lists_dir = Path('./lists')
# Untar surface files
if not (pdb_dir.exists() and surf_dir.exists()):
tar = tarfile.open(self.raw_paths[0])
tar.extractall(self.raw_dir)
tar.close()
if not protein_dir.exists():
protein_dir.mkdir(parents=False, exist_ok=False)
convert_plys(surf_dir,protein_dir)
convert_pdbs(pdb_dir,protein_dir)
with open(lists_dir / "training.txt") as f_tr, open(
lists_dir / "testing.txt"
) as f_ts:
training_list = sorted(f_tr.read().splitlines())
testing_list = sorted(f_ts.read().splitlines())
with open(lists_dir / "training_ppi.txt") as f_tr, open(
lists_dir / "testing_ppi.txt"
) as f_ts:
training_pairs_list = sorted(f_tr.read().splitlines())
testing_pairs_list = sorted(f_ts.read().splitlines())
pairs_list = sorted(training_pairs_list + testing_pairs_list)
if not self.ppi:
training_pairs_list = []
for p in pairs_list:
pspl = p.split("_")
p1 = pspl[0] + "_" + pspl[1]
p2 = pspl[0] + "_" + pspl[2]
if p1 in training_list:
training_pairs_list.append(p)
if p2 in training_list:
training_pairs_list.append(pspl[0] + "_" + pspl[2] + "_" + pspl[1])
testing_pairs_list = []
for p in pairs_list:
pspl = p.split("_")
p1 = pspl[0] + "_" + pspl[1]
p2 = pspl[0] + "_" + pspl[2]
if p1 in testing_list:
testing_pairs_list.append(p)
if p2 in testing_list:
testing_pairs_list.append(pspl[0] + "_" + pspl[2] + "_" + pspl[1])
# # Read data into huge `Data` list.
training_pairs_data = []
training_pairs_data_ids = []
for p in training_pairs_list:
try:
protein_pair = load_protein_pair(p, protein_dir)
except FileNotFoundError:
continue
training_pairs_data.append(protein_pair)
training_pairs_data_ids.append(p)
testing_pairs_data = []
testing_pairs_data_ids = []
for p in testing_pairs_list:
try:
protein_pair = load_protein_pair(p, protein_dir)
except FileNotFoundError:
continue
testing_pairs_data.append(protein_pair)
testing_pairs_data_ids.append(p)
if self.pre_filter is not None:
training_pairs_data = [
data for data in training_pairs_data if self.pre_filter(data)
]
testing_pairs_data = [
data for data in testing_pairs_data if self.pre_filter(data)
]
if self.pre_transform is not None:
training_pairs_data = [
self.pre_transform(data) for data in training_pairs_data
]
testing_pairs_data = [
self.pre_transform(data) for data in testing_pairs_data
]
training_pairs_data, training_pairs_slices = self.collate(training_pairs_data)
torch.save(
(training_pairs_data, training_pairs_slices), self.processed_paths[0]
)
np.save(self.processed_paths[2], training_pairs_data_ids)
testing_pairs_data, testing_pairs_slices = self.collate(testing_pairs_data)
torch.save((testing_pairs_data, testing_pairs_slices), self.processed_paths[1])
np.save(self.processed_paths[3], testing_pairs_data_ids)
================================================
FILE: data_analysis/analyse_atomnet.ipynb
================================================
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.7-final"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python37764bitvenvvenv0f8ab664edda4e43b2faa48ba983dc72",
"display_name": "Python 3.7.7 64-bit ('venv': venv)"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns\n",
"from sklearn.metrics import mean_squared_error"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"0.8289113443652403\n0.16479157\n"
]
},
{
"output_type": "display_data",
"data": {
"text/plain": "<Figure size 432x288 with 1 Axes>",
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<!-- Created with matplotlib (https://matplotlib.org/) -->\n<svg height=\"265.995469pt\" version=\"1.1\" viewBox=\"0 0 291.115 265.995469\" width=\"291.115pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n <metadata>\n <rdf:RDF xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2020-11-14T13:07:27.340743</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.3.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linecap:butt;stroke-linejoin:round;}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 265.995469 \nL 291.115 265.995469 \nL 291.115 0 \nL 0 0 \nz\n\" style=\"fill:none;\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 58.523438 228.439219 \nL 275.963437 228.439219 \nL 275.963437 10.999219 \nL 58.523438 10.999219 \nz\n\" style=\"fill:#ffffff;\"/>\n </g>\n <g id=\"PathCollection_1\">\n <defs>\n <path d=\"M 0 0.5 \nC 0.132602 0.5 0.25979 0.447317 0.353553 0.353553 \nC 0.447317 0.25979 0.5 0.132602 0.5 0 \nC 0.5 -0.132602 0.447317 -0.25979 0.353553 -0.353553 \nC 0.25979 -0.447317 0.132602 -0.5 0 -0.5 \nC -0.132602 -0.5 -0.25979 -0.447317 -0.353553 -0.353553 \nC -0.447317 -0.25979 -0.5 -0.132602 -0.5 0 \nC -0.5 0.132602 -0.447317 0.25979 -0.353553 0.353553 \nC -0.25979 0.447317 -0.132602 0.5 0 0.5 \nz\n\" id=\"md91571ca24\" style=\"stroke:#1f77b4;\"/>\n </defs>\n <g clip-path=\"url(#pd4d130ab8b)\">\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.44337\" xlink:href=\"#md91571ca24\" y=\"141.958379\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.303932\" xlink:href=\"#md91571ca24\" y=\"178.342521\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.657162\" xlink:href=\"#md91571ca24\" y=\"130.957431\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.423558\" xlink:href=\"#md91571ca24\" y=\"114.606713\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.494109\" xlink:href=\"#md91571ca24\" y=\"119.909365\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.367901\" xlink:href=\"#md91571ca24\" y=\"110.805951\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.129329\" xlink:href=\"#md91571ca24\" y=\"131.612228\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.38702\" xlink:href=\"#md91571ca24\" y=\"123.178228\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.902128\" xlink:href=\"#md91571ca24\" y=\"110.54833\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.655569\" xlink:href=\"#md91571ca24\" y=\"136.423971\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.597653\" xlink:href=\"#md91571ca24\" y=\"123.584656\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.395447\" xlink:href=\"#md91571ca24\" y=\"118.201671\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"188.009746\" xlink:href=\"#md91571ca24\" y=\"117.390967\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.078004\" xlink:href=\"#md91571ca24\" y=\"107.804066\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.298591\" xlink:href=\"#md91571ca24\" y=\"106.29894\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.562025\" xlink:href=\"#md91571ca24\" y=\"117.380821\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.7346\" xlink:href=\"#md91571ca24\" y=\"106.306597\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.26989\" xlink:href=\"#md91571ca24\" y=\"120.364077\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.104558\" xlink:href=\"#md91571ca24\" y=\"132.155897\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.009398\" xlink:href=\"#md91571ca24\" y=\"161.289315\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"205.666523\" xlink:href=\"#md91571ca24\" y=\"104.64813\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"188.232277\" xlink:href=\"#md91571ca24\" y=\"109.426978\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.021212\" xlink:href=\"#md91571ca24\" y=\"160.22085\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"83.895062\" xlink:href=\"#md91571ca24\" y=\"178.447397\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"93.953104\" xlink:href=\"#md91571ca24\" y=\"191.884114\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.698916\" xlink:href=\"#md91571ca24\" y=\"110.457895\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"214.519977\" xlink:href=\"#md91571ca24\" y=\"91.059322\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.9402\" xlink:href=\"#md91571ca24\" y=\"113.47294\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.089478\" xlink:href=\"#md91571ca24\" y=\"121.283049\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.151733\" xlink:href=\"#md91571ca24\" y=\"190.888331\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.4432\" xlink:href=\"#md91571ca24\" y=\"117.596665\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.969784\" xlink:href=\"#md91571ca24\" y=\"139.014562\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.590742\" xlink:href=\"#md91571ca24\" y=\"120.358431\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.904334\" xlink:href=\"#md91571ca24\" y=\"134.695783\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"88.249657\" xlink:href=\"#md91571ca24\" y=\"196.827172\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.799182\" xlink:href=\"#md91571ca24\" y=\"151.183951\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.250104\" xlink:href=\"#md91571ca24\" y=\"124.908076\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"258.943692\" xlink:href=\"#md91571ca24\" y=\"104.225806\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.796806\" xlink:href=\"#md91571ca24\" y=\"141.838171\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.424203\" xlink:href=\"#md91571ca24\" y=\"128.209055\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.791142\" xlink:href=\"#md91571ca24\" y=\"148.285447\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.941048\" xlink:href=\"#md91571ca24\" y=\"122.689174\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.576434\" xlink:href=\"#md91571ca24\" y=\"122.534155\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.288821\" xlink:href=\"#md91571ca24\" y=\"142.938811\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.90113\" xlink:href=\"#md91571ca24\" y=\"116.019838\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.41737\" xlink:href=\"#md91571ca24\" y=\"185.061515\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.799828\" xlink:href=\"#md91571ca24\" y=\"119.393388\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.016256\" xlink:href=\"#md91571ca24\" y=\"134.781357\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.667894\" xlink:href=\"#md91571ca24\" y=\"158.196375\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.492755\" xlink:href=\"#md91571ca24\" y=\"137.519772\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.873518\" xlink:href=\"#md91571ca24\" y=\"110.311423\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"251.427509\" xlink:href=\"#md91571ca24\" y=\"44.70772\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.543828\" xlink:href=\"#md91571ca24\" y=\"119.508292\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.186138\" xlink:href=\"#md91571ca24\" y=\"133.410112\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.333793\" xlink:href=\"#md91571ca24\" y=\"124.233556\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"200.58707\" xlink:href=\"#md91571ca24\" y=\"81.228635\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.013598\" xlink:href=\"#md91571ca24\" y=\"132.311667\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"242.765066\" xlink:href=\"#md91571ca24\" y=\"35.582064\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.403852\" xlink:href=\"#md91571ca24\" y=\"106.425392\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"202.831843\" xlink:href=\"#md91571ca24\" y=\"94.013752\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"134.782806\" xlink:href=\"#md91571ca24\" y=\"107.677892\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.60811\" xlink:href=\"#md91571ca24\" y=\"148.529272\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.128702\" xlink:href=\"#md91571ca24\" y=\"118.747259\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.352709\" xlink:href=\"#md91571ca24\" y=\"132.523015\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"130.240589\" xlink:href=\"#md91571ca24\" y=\"134.890589\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.334061\" xlink:href=\"#md91571ca24\" y=\"143.803468\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.060889\" xlink:href=\"#md91571ca24\" y=\"123.620693\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.375657\" xlink:href=\"#md91571ca24\" y=\"124.603939\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"196.312382\" xlink:href=\"#md91571ca24\" y=\"107.636504\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"58.523438\" xlink:href=\"#md91571ca24\" y=\"141.355289\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.409606\" xlink:href=\"#md91571ca24\" y=\"130.036401\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.50022\" xlink:href=\"#md91571ca24\" y=\"158.236287\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.398005\" xlink:href=\"#md91571ca24\" y=\"121.790344\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.798784\" xlink:href=\"#md91571ca24\" y=\"129.497451\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.934461\" xlink:href=\"#md91571ca24\" y=\"118.560854\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.243738\" xlink:href=\"#md91571ca24\" y=\"123.888507\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.195222\" xlink:href=\"#md91571ca24\" y=\"155.435835\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.027224\" xlink:href=\"#md91571ca24\" y=\"140.30153\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"83.525774\" xlink:href=\"#md91571ca24\" y=\"180.856515\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.57594\" xlink:href=\"#md91571ca24\" y=\"142.643155\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.987824\" xlink:href=\"#md91571ca24\" y=\"118.87857\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"125.78089\" xlink:href=\"#md91571ca24\" y=\"152.482418\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"89.49741\" xlink:href=\"#md91571ca24\" y=\"198.763908\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.143691\" xlink:href=\"#md91571ca24\" y=\"140.928758\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.425616\" xlink:href=\"#md91571ca24\" y=\"109.018072\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.986515\" xlink:href=\"#md91571ca24\" y=\"114.844115\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"194.192949\" xlink:href=\"#md91571ca24\" y=\"117.314784\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.409169\" xlink:href=\"#md91571ca24\" y=\"149.074673\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.703328\" xlink:href=\"#md91571ca24\" y=\"131.329195\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.410883\" xlink:href=\"#md91571ca24\" y=\"110.999936\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.08034\" xlink:href=\"#md91571ca24\" y=\"124.416759\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.633142\" xlink:href=\"#md91571ca24\" y=\"127.936912\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.528724\" xlink:href=\"#md91571ca24\" y=\"111.654101\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"203.518591\" xlink:href=\"#md91571ca24\" y=\"74.731576\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"112.481897\" xlink:href=\"#md91571ca24\" y=\"140.66266\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.966493\" xlink:href=\"#md91571ca24\" y=\"172.311733\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.522181\" xlink:href=\"#md91571ca24\" y=\"137.297587\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.754956\" xlink:href=\"#md91571ca24\" y=\"140.791731\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.068155\" xlink:href=\"#md91571ca24\" y=\"121.453552\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.706089\" xlink:href=\"#md91571ca24\" y=\"131.47516\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.662928\" xlink:href=\"#md91571ca24\" y=\"104.247749\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.206212\" xlink:href=\"#md91571ca24\" y=\"116.6499\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.158433\" xlink:href=\"#md91571ca24\" y=\"108.139366\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.093599\" xlink:href=\"#md91571ca24\" y=\"119.917509\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.699989\" xlink:href=\"#md91571ca24\" y=\"153.641933\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.573539\" xlink:href=\"#md91571ca24\" y=\"129.158621\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.420359\" xlink:href=\"#md91571ca24\" y=\"113.103246\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.589407\" xlink:href=\"#md91571ca24\" y=\"123.331529\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"91.556201\" xlink:href=\"#md91571ca24\" y=\"170.662528\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"232.283004\" xlink:href=\"#md91571ca24\" y=\"96.357205\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.342496\" xlink:href=\"#md91571ca24\" y=\"121.24441\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"231.957204\" xlink:href=\"#md91571ca24\" y=\"35.667675\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.919886\" xlink:href=\"#md91571ca24\" y=\"109.114987\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.874553\" xlink:href=\"#md91571ca24\" y=\"116.524784\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.145522\" xlink:href=\"#md91571ca24\" y=\"131.526574\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.561457\" xlink:href=\"#md91571ca24\" y=\"108.175219\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.352455\" xlink:href=\"#md91571ca24\" y=\"120.66145\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.510148\" xlink:href=\"#md91571ca24\" y=\"151.318885\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.203979\" xlink:href=\"#md91571ca24\" y=\"132.74544\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"133.717309\" xlink:href=\"#md91571ca24\" y=\"158.713672\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"101.801968\" xlink:href=\"#md91571ca24\" y=\"148.002758\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.022046\" xlink:href=\"#md91571ca24\" y=\"116.70029\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"189.986472\" xlink:href=\"#md91571ca24\" y=\"108.850181\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.873313\" xlink:href=\"#md91571ca24\" y=\"161.566561\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.023201\" xlink:href=\"#md91571ca24\" y=\"130.83218\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.458131\" xlink:href=\"#md91571ca24\" y=\"119.98918\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.767932\" xlink:href=\"#md91571ca24\" y=\"122.735227\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.252315\" xlink:href=\"#md91571ca24\" y=\"121.485627\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.621446\" xlink:href=\"#md91571ca24\" y=\"110.360005\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"202.405548\" xlink:href=\"#md91571ca24\" y=\"105.642878\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.322837\" xlink:href=\"#md91571ca24\" y=\"103.539709\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.02043\" xlink:href=\"#md91571ca24\" y=\"124.847774\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.238986\" xlink:href=\"#md91571ca24\" y=\"119.059676\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.235073\" xlink:href=\"#md91571ca24\" y=\"148.707708\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.776605\" xlink:href=\"#md91571ca24\" y=\"117.781957\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.682407\" xlink:href=\"#md91571ca24\" y=\"143.860585\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.975505\" xlink:href=\"#md91571ca24\" y=\"124.475104\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.915711\" xlink:href=\"#md91571ca24\" y=\"122.448405\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.374417\" xlink:href=\"#md91571ca24\" y=\"131.431687\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.463973\" xlink:href=\"#md91571ca24\" y=\"105.763628\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.814017\" xlink:href=\"#md91571ca24\" y=\"102.762333\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.986827\" xlink:href=\"#md91571ca24\" y=\"100.85861\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"126.176631\" xlink:href=\"#md91571ca24\" y=\"133.825805\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.319265\" xlink:href=\"#md91571ca24\" y=\"120.316072\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"130.791433\" xlink:href=\"#md91571ca24\" y=\"131.636488\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"105.915934\" xlink:href=\"#md91571ca24\" y=\"174.659827\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.947909\" xlink:href=\"#md91571ca24\" y=\"122.675579\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.952256\" xlink:href=\"#md91571ca24\" y=\"111.605909\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.849856\" xlink:href=\"#md91571ca24\" y=\"121.489075\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"85.88754\" xlink:href=\"#md91571ca24\" y=\"195.230504\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"104.670735\" xlink:href=\"#md91571ca24\" y=\"147.71593\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.275422\" xlink:href=\"#md91571ca24\" y=\"113.039288\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"125.392764\" xlink:href=\"#md91571ca24\" y=\"186.933967\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.550022\" xlink:href=\"#md91571ca24\" y=\"123.163544\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.647036\" xlink:href=\"#md91571ca24\" y=\"100.594188\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.996937\" xlink:href=\"#md91571ca24\" y=\"107.704582\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.840555\" xlink:href=\"#md91571ca24\" y=\"122.441493\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.611669\" xlink:href=\"#md91571ca24\" y=\"123.864427\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.625542\" xlink:href=\"#md91571ca24\" y=\"120.557091\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.41283\" xlink:href=\"#md91571ca24\" y=\"117.014701\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.521646\" xlink:href=\"#md91571ca24\" y=\"123.529214\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.750485\" xlink:href=\"#md91571ca24\" y=\"136.972006\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.988602\" xlink:href=\"#md91571ca24\" y=\"128.943388\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.404316\" xlink:href=\"#md91571ca24\" y=\"118.642072\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"130.799041\" xlink:href=\"#md91571ca24\" y=\"169.898374\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.493733\" xlink:href=\"#md91571ca24\" y=\"143.715556\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.403062\" xlink:href=\"#md91571ca24\" y=\"123.545172\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.993126\" xlink:href=\"#md91571ca24\" y=\"140.794934\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"213.897371\" xlink:href=\"#md91571ca24\" y=\"123.77323\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"226.595499\" xlink:href=\"#md91571ca24\" y=\"71.685819\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.077831\" xlink:href=\"#md91571ca24\" y=\"123.182096\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.764285\" xlink:href=\"#md91571ca24\" y=\"144.445047\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.600408\" xlink:href=\"#md91571ca24\" y=\"125.253597\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.205347\" xlink:href=\"#md91571ca24\" y=\"146.437625\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.134293\" xlink:href=\"#md91571ca24\" y=\"108.855427\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.404113\" xlink:href=\"#md91571ca24\" y=\"119.178317\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.241521\" xlink:href=\"#md91571ca24\" y=\"125.258523\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.866999\" xlink:href=\"#md91571ca24\" y=\"142.572874\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.990507\" xlink:href=\"#md91571ca24\" y=\"119.822893\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.620665\" xlink:href=\"#md91571ca24\" y=\"118.304075\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.063549\" xlink:href=\"#md91571ca24\" y=\"150.210182\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"106.368577\" xlink:href=\"#md91571ca24\" y=\"182.768425\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.983817\" xlink:href=\"#md91571ca24\" y=\"134.2012\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.441067\" xlink:href=\"#md91571ca24\" y=\"71.375916\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"118.24515\" xlink:href=\"#md91571ca24\" y=\"162.695817\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.694425\" xlink:href=\"#md91571ca24\" y=\"125.557725\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.437509\" xlink:href=\"#md91571ca24\" y=\"131.794233\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.500149\" xlink:href=\"#md91571ca24\" y=\"131.155063\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.334204\" xlink:href=\"#md91571ca24\" y=\"89.678255\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.407971\" xlink:href=\"#md91571ca24\" y=\"117.675961\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"194.0153\" xlink:href=\"#md91571ca24\" y=\"109.773613\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.37422\" xlink:href=\"#md91571ca24\" y=\"130.453044\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.983403\" xlink:href=\"#md91571ca24\" y=\"125.618334\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.888367\" xlink:href=\"#md91571ca24\" y=\"113.248582\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.165362\" xlink:href=\"#md91571ca24\" y=\"133.74124\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"251.695323\" xlink:href=\"#md91571ca24\" y=\"42.11621\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"135.661329\" xlink:href=\"#md91571ca24\" y=\"131.336399\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.810821\" xlink:href=\"#md91571ca24\" y=\"116.864002\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"197.258273\" xlink:href=\"#md91571ca24\" y=\"109.840147\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"221.990112\" xlink:href=\"#md91571ca24\" y=\"110.286186\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"271.512449\" xlink:href=\"#md91571ca24\" y=\"37.670308\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.383523\" xlink:href=\"#md91571ca24\" y=\"120.596766\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.837494\" xlink:href=\"#md91571ca24\" y=\"131.672453\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.245165\" xlink:href=\"#md91571ca24\" y=\"116.230969\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.418142\" xlink:href=\"#md91571ca24\" y=\"117.949575\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.981667\" xlink:href=\"#md91571ca24\" y=\"114.146466\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"117.76678\" xlink:href=\"#md91571ca24\" y=\"163.087799\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.229217\" xlink:href=\"#md91571ca24\" y=\"127.160026\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"116.3237\" xlink:href=\"#md91571ca24\" y=\"123.318523\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"93.659213\" xlink:href=\"#md91571ca24\" y=\"197.498146\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.598269\" xlink:href=\"#md91571ca24\" y=\"116.743393\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"264.183997\" xlink:href=\"#md91571ca24\" y=\"44.784958\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.469034\" xlink:href=\"#md91571ca24\" y=\"142.644167\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.163168\" xlink:href=\"#md91571ca24\" y=\"131.224925\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.926886\" xlink:href=\"#md91571ca24\" y=\"101.547671\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.697051\" xlink:href=\"#md91571ca24\" y=\"131.443765\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.770544\" xlink:href=\"#md91571ca24\" y=\"159.0022\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.477785\" xlink:href=\"#md91571ca24\" y=\"128.438103\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.428274\" xlink:href=\"#md91571ca24\" y=\"117.659549\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.612875\" xlink:href=\"#md91571ca24\" y=\"121.554336\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.963881\" xlink:href=\"#md91571ca24\" y=\"153.864363\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"189.869659\" xlink:href=\"#md91571ca24\" y=\"105.171752\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.550765\" xlink:href=\"#md91571ca24\" y=\"121.892798\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.599405\" xlink:href=\"#md91571ca24\" y=\"112.561638\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.776763\" xlink:href=\"#md91571ca24\" y=\"155.453695\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.756726\" xlink:href=\"#md91571ca24\" y=\"153.328287\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"109.408019\" xlink:href=\"#md91571ca24\" y=\"200.381208\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"128.647479\" xlink:href=\"#md91571ca24\" y=\"155.158184\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.483278\" xlink:href=\"#md91571ca24\" y=\"117.480683\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.127992\" xlink:href=\"#md91571ca24\" y=\"118.270865\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.963069\" xlink:href=\"#md91571ca24\" y=\"121.128892\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"127.244266\" xlink:href=\"#md91571ca24\" y=\"153.404054\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.774159\" xlink:href=\"#md91571ca24\" y=\"110.568728\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.724087\" xlink:href=\"#md91571ca24\" y=\"111.586232\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.052285\" xlink:href=\"#md91571ca24\" y=\"113.83051\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.808888\" xlink:href=\"#md91571ca24\" y=\"121.075606\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"194.145112\" xlink:href=\"#md91571ca24\" y=\"99.517832\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.446408\" xlink:href=\"#md91571ca24\" y=\"111.929345\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"199.045711\" xlink:href=\"#md91571ca24\" y=\"114.949366\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.418891\" xlink:href=\"#md91571ca24\" y=\"88.064156\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.054717\" xlink:href=\"#md91571ca24\" y=\"144.340768\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.982341\" xlink:href=\"#md91571ca24\" y=\"113.455548\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.586369\" xlink:href=\"#md91571ca24\" y=\"146.89088\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.713357\" xlink:href=\"#md91571ca24\" y=\"105.191687\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.548737\" xlink:href=\"#md91571ca24\" y=\"112.675056\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.162075\" xlink:href=\"#md91571ca24\" y=\"130.322441\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.109625\" xlink:href=\"#md91571ca24\" y=\"107.212973\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"219.274292\" xlink:href=\"#md91571ca24\" y=\"66.136952\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.297047\" xlink:href=\"#md91571ca24\" y=\"117.749462\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.626727\" xlink:href=\"#md91571ca24\" y=\"110.939887\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.590528\" xlink:href=\"#md91571ca24\" y=\"128.426829\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.902195\" xlink:href=\"#md91571ca24\" y=\"128.1055\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.628343\" xlink:href=\"#md91571ca24\" y=\"133.012773\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.941785\" xlink:href=\"#md91571ca24\" y=\"126.160492\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"92.813\" xlink:href=\"#md91571ca24\" y=\"185.166993\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"205.08307\" xlink:href=\"#md91571ca24\" y=\"81.368831\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.923959\" xlink:href=\"#md91571ca24\" y=\"164.806968\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"227.183306\" xlink:href=\"#md91571ca24\" y=\"43.518846\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.266419\" xlink:href=\"#md91571ca24\" y=\"129.252178\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.913306\" xlink:href=\"#md91571ca24\" y=\"115.353266\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"205.731766\" xlink:href=\"#md91571ca24\" y=\"116.166346\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.560666\" xlink:href=\"#md91571ca24\" y=\"129.525401\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.367098\" xlink:href=\"#md91571ca24\" y=\"113.512445\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"74.705859\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.273125\" xlink:href=\"#md91571ca24\" y=\"117.394235\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.500229\" xlink:href=\"#md91571ca24\" y=\"126.574292\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.555326\" xlink:href=\"#md91571ca24\" y=\"108.661252\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"200.711412\" xlink:href=\"#md91571ca24\" y=\"110.942513\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.327361\" xlink:href=\"#md91571ca24\" y=\"128.238485\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"90.119641\" xlink:href=\"#md91571ca24\" y=\"181.757213\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.719225\" xlink:href=\"#md91571ca24\" y=\"115.295146\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.912044\" xlink:href=\"#md91571ca24\" y=\"134.253793\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.1866\" xlink:href=\"#md91571ca24\" y=\"127.75802\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"86.547823\" xlink:href=\"#md91571ca24\" y=\"181.92391\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"108.982567\" xlink:href=\"#md91571ca24\" y=\"179.205731\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.527185\" xlink:href=\"#md91571ca24\" y=\"109.451718\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.679282\" xlink:href=\"#md91571ca24\" y=\"120.2754\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.511863\" xlink:href=\"#md91571ca24\" y=\"123.903457\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"135.823069\" xlink:href=\"#md91571ca24\" y=\"149.848673\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.771773\" xlink:href=\"#md91571ca24\" y=\"123.769322\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.70654\" xlink:href=\"#md91571ca24\" y=\"92.435746\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.807538\" xlink:href=\"#md91571ca24\" y=\"118.407271\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.930872\" xlink:href=\"#md91571ca24\" y=\"124.576262\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"130.064093\" xlink:href=\"#md91571ca24\" y=\"174.950776\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.35618\" xlink:href=\"#md91571ca24\" y=\"141.779672\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.098111\" xlink:href=\"#md91571ca24\" y=\"120.434555\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.099499\" xlink:href=\"#md91571ca24\" y=\"107.863702\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.26629\" xlink:href=\"#md91571ca24\" y=\"104.766834\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.591672\" xlink:href=\"#md91571ca24\" y=\"119.417008\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.567754\" xlink:href=\"#md91571ca24\" y=\"124.506965\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"91.464869\" xlink:href=\"#md91571ca24\" y=\"191.333678\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"111.129424\" xlink:href=\"#md91571ca24\" y=\"173.306719\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"90.889024\" xlink:href=\"#md91571ca24\" y=\"195.293434\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.881937\" xlink:href=\"#md91571ca24\" y=\"129.529989\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.039685\" xlink:href=\"#md91571ca24\" y=\"119.470834\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.642824\" xlink:href=\"#md91571ca24\" y=\"156.508671\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.223559\" xlink:href=\"#md91571ca24\" y=\"112.654729\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.284457\" xlink:href=\"#md91571ca24\" y=\"168.744111\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.470723\" xlink:href=\"#md91571ca24\" y=\"103.066636\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"105.269053\" xlink:href=\"#md91571ca24\" y=\"167.869259\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"247.208797\" xlink:href=\"#md91571ca24\" y=\"63.632351\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.464369\" xlink:href=\"#md91571ca24\" y=\"110.760512\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.544577\" xlink:href=\"#md91571ca24\" y=\"125.142254\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.62495\" xlink:href=\"#md91571ca24\" y=\"98.513255\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.334905\" xlink:href=\"#md91571ca24\" y=\"128.790176\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.500363\" xlink:href=\"#md91571ca24\" y=\"132.725758\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.8295\" xlink:href=\"#md91571ca24\" y=\"147.180655\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"208.668302\" xlink:href=\"#md91571ca24\" y=\"91.8313\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.942897\" xlink:href=\"#md91571ca24\" y=\"118.816246\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.693675\" xlink:href=\"#md91571ca24\" y=\"118.51564\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.998659\" xlink:href=\"#md91571ca24\" y=\"106.040513\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"207.16252\" xlink:href=\"#md91571ca24\" y=\"98.861931\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.595922\" xlink:href=\"#md91571ca24\" y=\"128.728425\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.660949\" xlink:href=\"#md91571ca24\" y=\"107.837153\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.750925\" xlink:href=\"#md91571ca24\" y=\"149.14346\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.193066\" xlink:href=\"#md91571ca24\" y=\"119.825942\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"216.46425\" xlink:href=\"#md91571ca24\" y=\"99.240557\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"41.066894\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.52893\" xlink:href=\"#md91571ca24\" y=\"156.090613\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"127.419666\" xlink:href=\"#md91571ca24\" y=\"172.972932\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"128.139391\" xlink:href=\"#md91571ca24\" y=\"145.734298\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.303202\" xlink:href=\"#md91571ca24\" y=\"119.162385\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.657983\" xlink:href=\"#md91571ca24\" y=\"131.919134\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.838567\" xlink:href=\"#md91571ca24\" y=\"122.740426\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.985306\" xlink:href=\"#md91571ca24\" y=\"170.943973\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.991507\" xlink:href=\"#md91571ca24\" y=\"109.644816\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"124.89881\" xlink:href=\"#md91571ca24\" y=\"165.129193\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"262.072276\" xlink:href=\"#md91571ca24\" y=\"38.192775\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.802269\" xlink:href=\"#md91571ca24\" y=\"117.168134\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"58.523438\" xlink:href=\"#md91571ca24\" y=\"159.569264\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"243.129643\" xlink:href=\"#md91571ca24\" y=\"39.317359\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.88125\" xlink:href=\"#md91571ca24\" y=\"93.511619\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"135.228988\" xlink:href=\"#md91571ca24\" y=\"133.940936\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.145806\" xlink:href=\"#md91571ca24\" y=\"122.209195\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.835704\" xlink:href=\"#md91571ca24\" y=\"154.170356\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"205.739024\" xlink:href=\"#md91571ca24\" y=\"89.942353\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.483766\" xlink:href=\"#md91571ca24\" y=\"118.752818\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.91415\" xlink:href=\"#md91571ca24\" y=\"112.278822\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.841797\" xlink:href=\"#md91571ca24\" y=\"112.45525\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.814397\" xlink:href=\"#md91571ca24\" y=\"121.735111\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"119.727\" xlink:href=\"#md91571ca24\" y=\"146.311353\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.732616\" xlink:href=\"#md91571ca24\" y=\"122.661256\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.277663\" xlink:href=\"#md91571ca24\" y=\"105.637919\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.141616\" xlink:href=\"#md91571ca24\" y=\"114.468331\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"207.965963\" xlink:href=\"#md91571ca24\" y=\"91.589776\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.766504\" xlink:href=\"#md91571ca24\" y=\"138.58211\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.462753\" xlink:href=\"#md91571ca24\" y=\"123.155062\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.271847\" xlink:href=\"#md91571ca24\" y=\"111.557936\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.625177\" xlink:href=\"#md91571ca24\" y=\"103.154305\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"38.951887\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.035266\" xlink:href=\"#md91571ca24\" y=\"119.747009\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.109593\" xlink:href=\"#md91571ca24\" y=\"161.763479\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.734449\" xlink:href=\"#md91571ca24\" y=\"105.233706\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.654865\" xlink:href=\"#md91571ca24\" y=\"134.50821\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"214.951223\" xlink:href=\"#md91571ca24\" y=\"79.010998\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.802187\" xlink:href=\"#md91571ca24\" y=\"102.823548\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.956107\" xlink:href=\"#md91571ca24\" y=\"144.643562\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.447759\" xlink:href=\"#md91571ca24\" y=\"142.060506\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.871528\" xlink:href=\"#md91571ca24\" y=\"122.043741\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"116.973848\" xlink:href=\"#md91571ca24\" y=\"150.341847\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.288726\" xlink:href=\"#md91571ca24\" y=\"108.679443\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.579691\" xlink:href=\"#md91571ca24\" y=\"119.412278\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.422425\" xlink:href=\"#md91571ca24\" y=\"116.839451\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"36.098732\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"114.726606\" xlink:href=\"#md91571ca24\" y=\"151.485741\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.566334\" xlink:href=\"#md91571ca24\" y=\"127.591478\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"95.146138\" xlink:href=\"#md91571ca24\" y=\"183.798689\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.190861\" xlink:href=\"#md91571ca24\" y=\"99.848614\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.404167\" xlink:href=\"#md91571ca24\" y=\"142.19282\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.543077\" xlink:href=\"#md91571ca24\" y=\"124.377851\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.366162\" xlink:href=\"#md91571ca24\" y=\"134.746993\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.658006\" xlink:href=\"#md91571ca24\" y=\"149.81219\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.976649\" xlink:href=\"#md91571ca24\" y=\"124.777589\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.943846\" xlink:href=\"#md91571ca24\" y=\"122.623063\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"37.982739\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.915553\" xlink:href=\"#md91571ca24\" y=\"118.184214\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"121.739769\" xlink:href=\"#md91571ca24\" y=\"178.671949\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.505618\" xlink:href=\"#md91571ca24\" y=\"123.691563\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"227.403284\" xlink:href=\"#md91571ca24\" y=\"100.016417\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.200966\" xlink:href=\"#md91571ca24\" y=\"128.21838\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.805991\" xlink:href=\"#md91571ca24\" y=\"119.572464\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.576245\" xlink:href=\"#md91571ca24\" y=\"158.291019\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"265.932204\" xlink:href=\"#md91571ca24\" y=\"38.148029\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.356055\" xlink:href=\"#md91571ca24\" y=\"120.951723\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.966628\" xlink:href=\"#md91571ca24\" y=\"151.362611\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"105.592312\" xlink:href=\"#md91571ca24\" y=\"181.235607\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.403062\" xlink:href=\"#md91571ca24\" y=\"148.85096\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"135.69373\" xlink:href=\"#md91571ca24\" y=\"144.143711\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.257341\" xlink:href=\"#md91571ca24\" y=\"93.608472\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.057549\" xlink:href=\"#md91571ca24\" y=\"117.217342\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.965695\" xlink:href=\"#md91571ca24\" y=\"108.989355\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.996996\" xlink:href=\"#md91571ca24\" y=\"124.377666\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.484714\" xlink:href=\"#md91571ca24\" y=\"117.108729\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.212796\" xlink:href=\"#md91571ca24\" y=\"128.722209\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.932331\" xlink:href=\"#md91571ca24\" y=\"180.836154\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"102.007819\" xlink:href=\"#md91571ca24\" y=\"176.991201\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.55718\" xlink:href=\"#md91571ca24\" y=\"117.48239\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"215.813739\" xlink:href=\"#md91571ca24\" y=\"67.283464\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.557591\" xlink:href=\"#md91571ca24\" y=\"100.064526\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"115.077406\" xlink:href=\"#md91571ca24\" y=\"176.477968\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.420535\" xlink:href=\"#md91571ca24\" y=\"142.582429\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"114.546851\" xlink:href=\"#md91571ca24\" y=\"161.131113\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.798031\" xlink:href=\"#md91571ca24\" y=\"118.551719\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.317876\" xlink:href=\"#md91571ca24\" y=\"99.259387\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"110.158195\" xlink:href=\"#md91571ca24\" y=\"165.614714\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.557179\" xlink:href=\"#md91571ca24\" y=\"130.305924\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.762905\" xlink:href=\"#md91571ca24\" y=\"97.600979\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.699279\" xlink:href=\"#md91571ca24\" y=\"105.129051\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.965581\" xlink:href=\"#md91571ca24\" y=\"110.831643\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.33125\" xlink:href=\"#md91571ca24\" y=\"128.401635\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.770297\" xlink:href=\"#md91571ca24\" y=\"121.998367\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.282556\" xlink:href=\"#md91571ca24\" y=\"177.281275\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.112164\" xlink:href=\"#md91571ca24\" y=\"104.613446\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.594948\" xlink:href=\"#md91571ca24\" y=\"128.733261\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.854043\" xlink:href=\"#md91571ca24\" y=\"129.766649\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.21286\" xlink:href=\"#md91571ca24\" y=\"136.364897\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.562562\" xlink:href=\"#md91571ca24\" y=\"146.789491\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"73.721769\" xlink:href=\"#md91571ca24\" y=\"203.123201\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.504332\" xlink:href=\"#md91571ca24\" y=\"132.397556\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.569835\" xlink:href=\"#md91571ca24\" y=\"110.27647\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"128.788813\" xlink:href=\"#md91571ca24\" y=\"169.961916\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.619914\" xlink:href=\"#md91571ca24\" y=\"119.50922\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.892873\" xlink:href=\"#md91571ca24\" y=\"149.22284\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.109665\" xlink:href=\"#md91571ca24\" y=\"122.654576\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.534808\" xlink:href=\"#md91571ca24\" y=\"120.979179\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.460701\" xlink:href=\"#md91571ca24\" y=\"121.945535\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.447373\" xlink:href=\"#md91571ca24\" y=\"100.833947\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"188.84585\" xlink:href=\"#md91571ca24\" y=\"116.256612\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"196.915807\" xlink:href=\"#md91571ca24\" y=\"102.881882\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"124.645854\" xlink:href=\"#md91571ca24\" y=\"162.705359\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.226051\" xlink:href=\"#md91571ca24\" y=\"127.687854\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"112.852268\" xlink:href=\"#md91571ca24\" y=\"175.446856\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.837514\" xlink:href=\"#md91571ca24\" y=\"127.730686\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.450293\" xlink:href=\"#md91571ca24\" y=\"169.647233\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.970305\" xlink:href=\"#md91571ca24\" y=\"124.345504\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.711919\" xlink:href=\"#md91571ca24\" y=\"129.556673\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"225.973242\" xlink:href=\"#md91571ca24\" y=\"93.039302\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.572465\" xlink:href=\"#md91571ca24\" y=\"114.526847\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.15709\" xlink:href=\"#md91571ca24\" y=\"119.613605\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.506123\" xlink:href=\"#md91571ca24\" y=\"113.826239\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"203.379318\" xlink:href=\"#md91571ca24\" y=\"101.564468\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.654486\" xlink:href=\"#md91571ca24\" y=\"97.010875\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.651434\" xlink:href=\"#md91571ca24\" y=\"115.656128\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.258265\" xlink:href=\"#md91571ca24\" y=\"145.815955\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.261114\" xlink:href=\"#md91571ca24\" y=\"119.304689\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.7935\" xlink:href=\"#md91571ca24\" y=\"131.365889\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.511084\" xlink:href=\"#md91571ca24\" y=\"110.807075\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"227.04704\" xlink:href=\"#md91571ca24\" y=\"99.812217\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.441984\" xlink:href=\"#md91571ca24\" y=\"114.674693\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.402778\" xlink:href=\"#md91571ca24\" y=\"133.278381\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.803511\" xlink:href=\"#md91571ca24\" y=\"135.680351\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.686215\" xlink:href=\"#md91571ca24\" y=\"125.278846\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.225139\" xlink:href=\"#md91571ca24\" y=\"125.797565\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.787159\" xlink:href=\"#md91571ca24\" y=\"118.836572\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.657013\" xlink:href=\"#md91571ca24\" y=\"119.099957\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"191.44872\" xlink:href=\"#md91571ca24\" y=\"100.385138\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"209.122384\" xlink:href=\"#md91571ca24\" y=\"93.452257\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.352937\" xlink:href=\"#md91571ca24\" y=\"109.200803\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.118463\" xlink:href=\"#md91571ca24\" y=\"121.157298\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.656224\" xlink:href=\"#md91571ca24\" y=\"119.680098\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.318019\" xlink:href=\"#md91571ca24\" y=\"154.000487\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.514197\" xlink:href=\"#md91571ca24\" y=\"112.369666\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"106.507371\" xlink:href=\"#md91571ca24\" y=\"192.798272\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.237817\" xlink:href=\"#md91571ca24\" y=\"113.712604\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.847727\" xlink:href=\"#md91571ca24\" y=\"127.379405\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"127.517148\" xlink:href=\"#md91571ca24\" y=\"159.485984\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"99.330401\" xlink:href=\"#md91571ca24\" y=\"182.449456\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"126.054867\" xlink:href=\"#md91571ca24\" y=\"114.234759\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.093171\" xlink:href=\"#md91571ca24\" y=\"114.769267\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.868497\" xlink:href=\"#md91571ca24\" y=\"126.665438\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.662006\" xlink:href=\"#md91571ca24\" y=\"132.069568\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.473089\" xlink:href=\"#md91571ca24\" y=\"134.303955\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.083292\" xlink:href=\"#md91571ca24\" y=\"105.620308\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.843603\" xlink:href=\"#md91571ca24\" y=\"122.756011\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.943576\" xlink:href=\"#md91571ca24\" y=\"108.29494\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.883682\" xlink:href=\"#md91571ca24\" y=\"124.934456\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.936372\" xlink:href=\"#md91571ca24\" y=\"103.569463\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.095269\" xlink:href=\"#md91571ca24\" y=\"118.088665\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.2446\" xlink:href=\"#md91571ca24\" y=\"108.426835\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.589576\" xlink:href=\"#md91571ca24\" y=\"111.576975\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.161368\" xlink:href=\"#md91571ca24\" y=\"135.617632\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.182422\" xlink:href=\"#md91571ca24\" y=\"103.966843\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.825842\" xlink:href=\"#md91571ca24\" y=\"128.274694\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.210137\" xlink:href=\"#md91571ca24\" y=\"109.826068\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.444887\" xlink:href=\"#md91571ca24\" y=\"118.578564\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.337572\" xlink:href=\"#md91571ca24\" y=\"90.699777\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.759086\" xlink:href=\"#md91571ca24\" y=\"97.716172\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.209403\" xlink:href=\"#md91571ca24\" y=\"110.809821\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.934548\" xlink:href=\"#md91571ca24\" y=\"119.085286\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.337724\" xlink:href=\"#md91571ca24\" y=\"118.504631\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.343642\" xlink:href=\"#md91571ca24\" y=\"113.270586\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"116.812082\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.917891\" xlink:href=\"#md91571ca24\" y=\"113.251351\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.431803\" xlink:href=\"#md91571ca24\" y=\"128.822493\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"104.331158\" xlink:href=\"#md91571ca24\" y=\"186.361012\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.732625\" xlink:href=\"#md91571ca24\" y=\"117.879492\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.233256\" xlink:href=\"#md91571ca24\" y=\"98.761269\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.205811\" xlink:href=\"#md91571ca24\" y=\"105.220073\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.899211\" xlink:href=\"#md91571ca24\" y=\"98.868636\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.883396\" xlink:href=\"#md91571ca24\" y=\"98.434222\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.193312\" xlink:href=\"#md91571ca24\" y=\"106.297793\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.940904\" xlink:href=\"#md91571ca24\" y=\"106.187559\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.985645\" xlink:href=\"#md91571ca24\" y=\"124.835518\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"184.082683\" xlink:href=\"#md91571ca24\" y=\"111.759999\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.377953\" xlink:href=\"#md91571ca24\" y=\"192.881303\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.096943\" xlink:href=\"#md91571ca24\" y=\"129.06155\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.601474\" xlink:href=\"#md91571ca24\" y=\"122.119809\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.844478\" xlink:href=\"#md91571ca24\" y=\"122.965965\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.08594\" xlink:href=\"#md91571ca24\" y=\"109.256947\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.842923\" xlink:href=\"#md91571ca24\" y=\"120.515292\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.116721\" xlink:href=\"#md91571ca24\" y=\"112.060082\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.579765\" xlink:href=\"#md91571ca24\" y=\"124.824543\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"234.639314\" xlink:href=\"#md91571ca24\" y=\"119.837513\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.323213\" xlink:href=\"#md91571ca24\" y=\"118.65618\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"108.068597\" xlink:href=\"#md91571ca24\" y=\"181.49595\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.865019\" xlink:href=\"#md91571ca24\" y=\"186.104305\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.555529\" xlink:href=\"#md91571ca24\" y=\"135.381996\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.519246\" xlink:href=\"#md91571ca24\" y=\"160.415749\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.165392\" xlink:href=\"#md91571ca24\" y=\"121.223959\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.687711\" xlink:href=\"#md91571ca24\" y=\"103.07279\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.455379\" xlink:href=\"#md91571ca24\" y=\"106.72948\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.726898\" xlink:href=\"#md91571ca24\" y=\"133.79499\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.317663\" xlink:href=\"#md91571ca24\" y=\"118.669127\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"210.248348\" xlink:href=\"#md91571ca24\" y=\"108.041602\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.681801\" xlink:href=\"#md91571ca24\" y=\"119.770948\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"103.282011\" xlink:href=\"#md91571ca24\" y=\"193.473335\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.304776\" xlink:href=\"#md91571ca24\" y=\"105.519774\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.598617\" xlink:href=\"#md91571ca24\" y=\"117.107928\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.580507\" xlink:href=\"#md91571ca24\" y=\"124.086664\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"256.942147\" xlink:href=\"#md91571ca24\" y=\"31.796762\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"118.413661\" xlink:href=\"#md91571ca24\" y=\"100.389597\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.370076\" xlink:href=\"#md91571ca24\" y=\"119.292281\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.803282\" xlink:href=\"#md91571ca24\" y=\"111.720173\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.95857\" xlink:href=\"#md91571ca24\" y=\"136.647431\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.234875\" xlink:href=\"#md91571ca24\" y=\"140.484577\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.175578\" xlink:href=\"#md91571ca24\" y=\"118.155006\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.295259\" xlink:href=\"#md91571ca24\" y=\"106.449993\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.255732\" xlink:href=\"#md91571ca24\" y=\"117.778161\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.316322\" xlink:href=\"#md91571ca24\" y=\"115.34127\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"90.401958\" xlink:href=\"#md91571ca24\" y=\"190.332789\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.315818\" xlink:href=\"#md91571ca24\" y=\"157.33472\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.244953\" xlink:href=\"#md91571ca24\" y=\"166.484058\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"202.966735\" xlink:href=\"#md91571ca24\" y=\"113.969625\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.4949\" xlink:href=\"#md91571ca24\" y=\"116.45705\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.161954\" xlink:href=\"#md91571ca24\" y=\"127.914367\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.749703\" xlink:href=\"#md91571ca24\" y=\"122.030733\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.619922\" xlink:href=\"#md91571ca24\" y=\"94.86105\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"195.536544\" xlink:href=\"#md91571ca24\" y=\"118.100127\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.419493\" xlink:href=\"#md91571ca24\" y=\"140.680861\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.120727\" xlink:href=\"#md91571ca24\" y=\"129.565111\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.830803\" xlink:href=\"#md91571ca24\" y=\"143.318567\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"188.214586\" xlink:href=\"#md91571ca24\" y=\"106.722238\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.319921\" xlink:href=\"#md91571ca24\" y=\"113.0884\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.28341\" xlink:href=\"#md91571ca24\" y=\"118.977118\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.754501\" xlink:href=\"#md91571ca24\" y=\"129.583279\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.315186\" xlink:href=\"#md91571ca24\" y=\"113.367321\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"95.657116\" xlink:href=\"#md91571ca24\" y=\"195.449419\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"95.247605\" xlink:href=\"#md91571ca24\" y=\"174.714792\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.18812\" xlink:href=\"#md91571ca24\" y=\"143.189923\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"119.285237\" xlink:href=\"#md91571ca24\" y=\"179.212976\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.084777\" xlink:href=\"#md91571ca24\" y=\"115.590751\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.453983\" xlink:href=\"#md91571ca24\" y=\"124.472516\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.075644\" xlink:href=\"#md91571ca24\" y=\"144.546195\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.088375\" xlink:href=\"#md91571ca24\" y=\"123.834092\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.939229\" xlink:href=\"#md91571ca24\" y=\"152.074395\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.775808\" xlink:href=\"#md91571ca24\" y=\"105.593963\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"30.297564\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.189855\" xlink:href=\"#md91571ca24\" y=\"96.305558\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.918886\" xlink:href=\"#md91571ca24\" y=\"144.049459\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"104.272447\" xlink:href=\"#md91571ca24\" y=\"170.706392\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.95164\" xlink:href=\"#md91571ca24\" y=\"112.460859\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.958966\" xlink:href=\"#md91571ca24\" y=\"174.971895\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"23.790726\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.932331\" xlink:href=\"#md91571ca24\" y=\"182.263668\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.846575\" xlink:href=\"#md91571ca24\" y=\"106.895791\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.31502\" xlink:href=\"#md91571ca24\" y=\"122.67509\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"184.861696\" xlink:href=\"#md91571ca24\" y=\"115.35837\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"104.311951\" xlink:href=\"#md91571ca24\" y=\"199.65322\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.769581\" xlink:href=\"#md91571ca24\" y=\"141.025947\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.928378\" xlink:href=\"#md91571ca24\" y=\"127.868723\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.062908\" xlink:href=\"#md91571ca24\" y=\"121.903181\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.199001\" xlink:href=\"#md91571ca24\" y=\"105.465335\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.037727\" xlink:href=\"#md91571ca24\" y=\"124.755124\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.277015\" xlink:href=\"#md91571ca24\" y=\"116.991946\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"228.949658\" xlink:href=\"#md91571ca24\" y=\"108.937654\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.151457\" xlink:href=\"#md91571ca24\" y=\"145.533392\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"222.692464\" xlink:href=\"#md91571ca24\" y=\"86.028917\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"109.060122\" xlink:href=\"#md91571ca24\" y=\"193.47896\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.731607\" xlink:href=\"#md91571ca24\" y=\"124.378582\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.222202\" xlink:href=\"#md91571ca24\" y=\"139.069908\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.433941\" xlink:href=\"#md91571ca24\" y=\"119.704484\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.940595\" xlink:href=\"#md91571ca24\" y=\"118.798962\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"206.278256\" xlink:href=\"#md91571ca24\" y=\"84.494872\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.433579\" xlink:href=\"#md91571ca24\" y=\"144.215288\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.752183\" xlink:href=\"#md91571ca24\" y=\"141.180079\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.515371\" xlink:href=\"#md91571ca24\" y=\"97.882762\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.366145\" xlink:href=\"#md91571ca24\" y=\"125.56943\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.872618\" xlink:href=\"#md91571ca24\" y=\"115.302387\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.220015\" xlink:href=\"#md91571ca24\" y=\"127.382177\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.102396\" xlink:href=\"#md91571ca24\" y=\"118.959642\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.405548\" xlink:href=\"#md91571ca24\" y=\"107.605419\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"209.595686\" xlink:href=\"#md91571ca24\" y=\"100.285691\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"140.953923\" xlink:href=\"#md91571ca24\" y=\"133.526509\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.116687\" xlink:href=\"#md91571ca24\" y=\"111.009809\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.690306\" xlink:href=\"#md91571ca24\" y=\"118.981022\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"119.906023\" xlink:href=\"#md91571ca24\" y=\"164.830511\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.561657\" xlink:href=\"#md91571ca24\" y=\"123.445707\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.968199\" xlink:href=\"#md91571ca24\" y=\"115.527647\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.634765\" xlink:href=\"#md91571ca24\" y=\"124.128825\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"135.659223\" xlink:href=\"#md91571ca24\" y=\"164.390358\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.2316\" xlink:href=\"#md91571ca24\" y=\"101.544284\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.123842\" xlink:href=\"#md91571ca24\" y=\"148.791533\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"188.096555\" xlink:href=\"#md91571ca24\" y=\"93.722382\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.676702\" xlink:href=\"#md91571ca24\" y=\"119.072549\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.951317\" xlink:href=\"#md91571ca24\" y=\"116.593741\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.261682\" xlink:href=\"#md91571ca24\" y=\"117.700874\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.809655\" xlink:href=\"#md91571ca24\" y=\"125.712468\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.940641\" xlink:href=\"#md91571ca24\" y=\"164.370017\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"128.048428\" xlink:href=\"#md91571ca24\" y=\"143.608871\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.951634\" xlink:href=\"#md91571ca24\" y=\"139.300283\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.705055\" xlink:href=\"#md91571ca24\" y=\"148.672077\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.797795\" xlink:href=\"#md91571ca24\" y=\"106.174276\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.559522\" xlink:href=\"#md91571ca24\" y=\"161.76426\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.652688\" xlink:href=\"#md91571ca24\" y=\"143.425704\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"114.526555\" xlink:href=\"#md91571ca24\" y=\"191.722452\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"205.269701\" xlink:href=\"#md91571ca24\" y=\"112.76156\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.350934\" xlink:href=\"#md91571ca24\" y=\"150.305532\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.6697\" xlink:href=\"#md91571ca24\" y=\"117.667792\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.788503\" xlink:href=\"#md91571ca24\" y=\"119.429088\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.499044\" xlink:href=\"#md91571ca24\" y=\"116.367325\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.906779\" xlink:href=\"#md91571ca24\" y=\"125.533395\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.313238\" xlink:href=\"#md91571ca24\" y=\"115.891026\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.130025\" xlink:href=\"#md91571ca24\" y=\"157.975591\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.267002\" xlink:href=\"#md91571ca24\" y=\"131.310862\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.815849\" xlink:href=\"#md91571ca24\" y=\"146.929498\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.539409\" xlink:href=\"#md91571ca24\" y=\"128.473755\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.314538\" xlink:href=\"#md91571ca24\" y=\"127.875579\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.455683\" xlink:href=\"#md91571ca24\" y=\"139.998952\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"98.365691\" xlink:href=\"#md91571ca24\" y=\"196.250575\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.196903\" xlink:href=\"#md91571ca24\" y=\"152.081925\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.817206\" xlink:href=\"#md91571ca24\" y=\"133.101178\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.489243\" xlink:href=\"#md91571ca24\" y=\"124.243834\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.949175\" xlink:href=\"#md91571ca24\" y=\"134.44719\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"190.597038\" xlink:href=\"#md91571ca24\" y=\"107.451175\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.074005\" xlink:href=\"#md91571ca24\" y=\"130.85239\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.320976\" xlink:href=\"#md91571ca24\" y=\"113.6\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.029282\" xlink:href=\"#md91571ca24\" y=\"135.269781\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"117.340233\" xlink:href=\"#md91571ca24\" y=\"182.41478\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.545438\" xlink:href=\"#md91571ca24\" y=\"129.078708\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.181214\" xlink:href=\"#md91571ca24\" y=\"113.66887\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.257532\" xlink:href=\"#md91571ca24\" y=\"123.64138\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"117.281885\" xlink:href=\"#md91571ca24\" y=\"164.144116\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.182223\" xlink:href=\"#md91571ca24\" y=\"100.747306\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.198931\" xlink:href=\"#md91571ca24\" y=\"139.550406\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.649008\" xlink:href=\"#md91571ca24\" y=\"122.680781\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.048759\" xlink:href=\"#md91571ca24\" y=\"147.666188\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.893671\" xlink:href=\"#md91571ca24\" y=\"125.073286\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"109.089115\" xlink:href=\"#md91571ca24\" y=\"171.390139\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.941698\" xlink:href=\"#md91571ca24\" y=\"127.886227\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.729486\" xlink:href=\"#md91571ca24\" y=\"127.104408\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.237866\" xlink:href=\"#md91571ca24\" y=\"98.091347\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.227197\" xlink:href=\"#md91571ca24\" y=\"114.418999\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.866984\" xlink:href=\"#md91571ca24\" y=\"133.146674\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.250415\" xlink:href=\"#md91571ca24\" y=\"109.33348\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.108411\" xlink:href=\"#md91571ca24\" y=\"129.021248\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"48.312405\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.422135\" xlink:href=\"#md91571ca24\" y=\"142.240236\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"116.459604\" xlink:href=\"#md91571ca24\" y=\"164.715043\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.468008\" xlink:href=\"#md91571ca24\" y=\"133.511957\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.32512\" xlink:href=\"#md91571ca24\" y=\"118.122\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.460685\" xlink:href=\"#md91571ca24\" y=\"115.510363\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.877518\" xlink:href=\"#md91571ca24\" y=\"143.71055\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"119.422579\" xlink:href=\"#md91571ca24\" y=\"143.883092\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.825805\" xlink:href=\"#md91571ca24\" y=\"121.579383\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.301542\" xlink:href=\"#md91571ca24\" y=\"133.172575\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.843579\" xlink:href=\"#md91571ca24\" y=\"111.702089\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.84997\" xlink:href=\"#md91571ca24\" y=\"103.824423\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.88716\" xlink:href=\"#md91571ca24\" y=\"96.61356\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"134.679045\" xlink:href=\"#md91571ca24\" y=\"142.610083\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.2044\" xlink:href=\"#md91571ca24\" y=\"140.333962\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"124.435299\" xlink:href=\"#md91571ca24\" y=\"103.276425\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.081263\" xlink:href=\"#md91571ca24\" y=\"102.000864\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"177.387699\" xlink:href=\"#md91571ca24\" y=\"53.970581\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"106.213467\" xlink:href=\"#md91571ca24\" y=\"185.785115\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.071762\" xlink:href=\"#md91571ca24\" y=\"123.669099\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.369515\" xlink:href=\"#md91571ca24\" y=\"118.943205\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.676625\" xlink:href=\"#md91571ca24\" y=\"132.473595\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"201.804832\" xlink:href=\"#md91571ca24\" y=\"115.649704\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.254132\" xlink:href=\"#md91571ca24\" y=\"121.255723\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"109.349309\" xlink:href=\"#md91571ca24\" y=\"151.032965\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.684545\" xlink:href=\"#md91571ca24\" y=\"182.360515\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.279328\" xlink:href=\"#md91571ca24\" y=\"111.229525\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"121.870598\" xlink:href=\"#md91571ca24\" y=\"147.358796\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"124.621573\" xlink:href=\"#md91571ca24\" y=\"167.872075\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.678309\" xlink:href=\"#md91571ca24\" y=\"118.813671\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.771681\" xlink:href=\"#md91571ca24\" y=\"105.191776\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.071581\" xlink:href=\"#md91571ca24\" y=\"126.604887\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.54307\" xlink:href=\"#md91571ca24\" y=\"168.902721\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.460803\" xlink:href=\"#md91571ca24\" y=\"129.94599\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"128.234702\" xlink:href=\"#md91571ca24\" y=\"163.264595\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.599917\" xlink:href=\"#md91571ca24\" y=\"115.678651\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.935607\" xlink:href=\"#md91571ca24\" y=\"123.056538\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.662212\" xlink:href=\"#md91571ca24\" y=\"121.453424\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.966043\" xlink:href=\"#md91571ca24\" y=\"111.984665\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.892332\" xlink:href=\"#md91571ca24\" y=\"139.722664\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.460447\" xlink:href=\"#md91571ca24\" y=\"106.076917\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.907553\" xlink:href=\"#md91571ca24\" y=\"178.571655\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.313887\" xlink:href=\"#md91571ca24\" y=\"120.944821\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.012327\" xlink:href=\"#md91571ca24\" y=\"130.153411\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.474708\" xlink:href=\"#md91571ca24\" y=\"102.194878\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"125.202505\" xlink:href=\"#md91571ca24\" y=\"163.641514\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.266518\" xlink:href=\"#md91571ca24\" y=\"121.526995\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.494595\" xlink:href=\"#md91571ca24\" y=\"129.899549\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.935451\" xlink:href=\"#md91571ca24\" y=\"124.090352\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.297682\" xlink:href=\"#md91571ca24\" y=\"122.008435\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.130561\" xlink:href=\"#md91571ca24\" y=\"109.050658\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"119.759615\" xlink:href=\"#md91571ca24\" y=\"161.689348\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.29672\" xlink:href=\"#md91571ca24\" y=\"123.046381\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.881345\" xlink:href=\"#md91571ca24\" y=\"177.85944\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.488288\" xlink:href=\"#md91571ca24\" y=\"156.494567\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.242067\" xlink:href=\"#md91571ca24\" y=\"117.331328\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.743399\" xlink:href=\"#md91571ca24\" y=\"155.314798\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"121.76151\" xlink:href=\"#md91571ca24\" y=\"187.726426\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.164351\" xlink:href=\"#md91571ca24\" y=\"135.463225\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.780496\" xlink:href=\"#md91571ca24\" y=\"119.651473\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.426586\" xlink:href=\"#md91571ca24\" y=\"125.287233\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.699158\" xlink:href=\"#md91571ca24\" y=\"116.562194\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"123.152767\" xlink:href=\"#md91571ca24\" y=\"145.110622\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"191.632058\" xlink:href=\"#md91571ca24\" y=\"100.477336\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.263078\" xlink:href=\"#md91571ca24\" y=\"123.488673\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.738624\" xlink:href=\"#md91571ca24\" y=\"127.797432\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.502131\" xlink:href=\"#md91571ca24\" y=\"116.309445\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.127379\" xlink:href=\"#md91571ca24\" y=\"134.809219\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.348723\" xlink:href=\"#md91571ca24\" y=\"121.773026\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.051528\" xlink:href=\"#md91571ca24\" y=\"138.248633\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.374205\" xlink:href=\"#md91571ca24\" y=\"115.464633\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"124.948455\" xlink:href=\"#md91571ca24\" y=\"148.512184\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.035163\" xlink:href=\"#md91571ca24\" y=\"111.958073\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"237.878464\" xlink:href=\"#md91571ca24\" y=\"56.278769\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.693951\" xlink:href=\"#md91571ca24\" y=\"106.937135\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.862648\" xlink:href=\"#md91571ca24\" y=\"160.911648\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.082471\" xlink:href=\"#md91571ca24\" y=\"120.489826\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.935489\" xlink:href=\"#md91571ca24\" y=\"130.832054\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.612435\" xlink:href=\"#md91571ca24\" y=\"124.326091\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.21049\" xlink:href=\"#md91571ca24\" y=\"103.986904\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"266.858124\" xlink:href=\"#md91571ca24\" y=\"76.49343\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.777892\" xlink:href=\"#md91571ca24\" y=\"120.603194\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.243534\" xlink:href=\"#md91571ca24\" y=\"130.735076\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.201803\" xlink:href=\"#md91571ca24\" y=\"113.000066\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.685066\" xlink:href=\"#md91571ca24\" y=\"119.640827\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.115907\" xlink:href=\"#md91571ca24\" y=\"127.74136\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.26738\" xlink:href=\"#md91571ca24\" y=\"117.866952\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.420668\" xlink:href=\"#md91571ca24\" y=\"126.974823\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.635675\" xlink:href=\"#md91571ca24\" y=\"102.778427\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.257949\" xlink:href=\"#md91571ca24\" y=\"165.545327\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.173033\" xlink:href=\"#md91571ca24\" y=\"132.734378\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"134.299071\" xlink:href=\"#md91571ca24\" y=\"120.096816\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.157241\" xlink:href=\"#md91571ca24\" y=\"117.37069\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"207.633282\" xlink:href=\"#md91571ca24\" y=\"101.825055\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.304746\" xlink:href=\"#md91571ca24\" y=\"149.495638\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.153367\" xlink:href=\"#md91571ca24\" y=\"103.478224\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.848406\" xlink:href=\"#md91571ca24\" y=\"121.270912\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"191.133172\" xlink:href=\"#md91571ca24\" y=\"123.963667\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.830975\" xlink:href=\"#md91571ca24\" y=\"92.627659\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.72606\" xlink:href=\"#md91571ca24\" y=\"95.514729\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.255368\" xlink:href=\"#md91571ca24\" y=\"151.438177\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"121.983302\" xlink:href=\"#md91571ca24\" y=\"166.740124\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"130.752655\" xlink:href=\"#md91571ca24\" y=\"135.204864\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.088659\" xlink:href=\"#md91571ca24\" y=\"196.267073\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"132.408247\" xlink:href=\"#md91571ca24\" y=\"144.387514\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"94.650375\" xlink:href=\"#md91571ca24\" y=\"142.670691\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.292428\" xlink:href=\"#md91571ca24\" y=\"112.311391\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.123159\" xlink:href=\"#md91571ca24\" y=\"150.773734\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.46938\" xlink:href=\"#md91571ca24\" y=\"129.669195\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.822415\" xlink:href=\"#md91571ca24\" y=\"141.195422\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.316985\" xlink:href=\"#md91571ca24\" y=\"169.019222\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"140.588957\" xlink:href=\"#md91571ca24\" y=\"132.866853\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"184.237275\" xlink:href=\"#md91571ca24\" y=\"86.122612\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.870455\" xlink:href=\"#md91571ca24\" y=\"134.613947\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.031312\" xlink:href=\"#md91571ca24\" y=\"123.428259\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.889363\" xlink:href=\"#md91571ca24\" y=\"144.828423\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"200.412778\" xlink:href=\"#md91571ca24\" y=\"109.538194\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.842846\" xlink:href=\"#md91571ca24\" y=\"108.879778\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.41512\" xlink:href=\"#md91571ca24\" y=\"110.504543\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"208.704903\" xlink:href=\"#md91571ca24\" y=\"122.619645\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.99966\" xlink:href=\"#md91571ca24\" y=\"105.63024\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.545603\" xlink:href=\"#md91571ca24\" y=\"136.101421\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.451627\" xlink:href=\"#md91571ca24\" y=\"106.416986\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.15668\" xlink:href=\"#md91571ca24\" y=\"157.312451\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"207.083876\" xlink:href=\"#md91571ca24\" y=\"89.454626\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.285151\" xlink:href=\"#md91571ca24\" y=\"121.279669\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.266243\" xlink:href=\"#md91571ca24\" y=\"112.301797\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"91.094498\" xlink:href=\"#md91571ca24\" y=\"201.936505\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.319249\" xlink:href=\"#md91571ca24\" y=\"175.459868\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.608567\" xlink:href=\"#md91571ca24\" y=\"88.588117\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.875002\" xlink:href=\"#md91571ca24\" y=\"138.38456\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.347958\" xlink:href=\"#md91571ca24\" y=\"138.841025\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.522371\" xlink:href=\"#md91571ca24\" y=\"134.643554\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.25473\" xlink:href=\"#md91571ca24\" y=\"112.968903\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.766328\" xlink:href=\"#md91571ca24\" y=\"127.315312\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.243643\" xlink:href=\"#md91571ca24\" y=\"126.767556\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.052555\" xlink:href=\"#md91571ca24\" y=\"164.399842\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.125637\" xlink:href=\"#md91571ca24\" y=\"133.767487\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.271294\" xlink:href=\"#md91571ca24\" y=\"119.988157\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.69003\" xlink:href=\"#md91571ca24\" y=\"142.534469\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.636952\" xlink:href=\"#md91571ca24\" y=\"89.362101\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.201282\" xlink:href=\"#md91571ca24\" y=\"124.812033\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.451168\" xlink:href=\"#md91571ca24\" y=\"126.38138\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.135059\" xlink:href=\"#md91571ca24\" y=\"112.807329\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"80.913235\" xlink:href=\"#md91571ca24\" y=\"199.469649\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.811657\" xlink:href=\"#md91571ca24\" y=\"115.983496\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.494364\" xlink:href=\"#md91571ca24\" y=\"121.188744\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.204476\" xlink:href=\"#md91571ca24\" y=\"113.199696\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.854824\" xlink:href=\"#md91571ca24\" y=\"123.906271\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"238.590212\" xlink:href=\"#md91571ca24\" y=\"105.021137\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.36794\" xlink:href=\"#md91571ca24\" y=\"110.140369\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.50557\" xlink:href=\"#md91571ca24\" y=\"112.030769\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.009226\" xlink:href=\"#md91571ca24\" y=\"149.061223\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.516103\" xlink:href=\"#md91571ca24\" y=\"110.650205\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"135.087979\" xlink:href=\"#md91571ca24\" y=\"156.373912\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.987603\" xlink:href=\"#md91571ca24\" y=\"112.587356\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.31663\" xlink:href=\"#md91571ca24\" y=\"141.248384\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.089304\" xlink:href=\"#md91571ca24\" y=\"131.869723\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.167815\" xlink:href=\"#md91571ca24\" y=\"143.807574\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.01302\" xlink:href=\"#md91571ca24\" y=\"115.435999\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.776035\" xlink:href=\"#md91571ca24\" y=\"117.935565\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"183.128367\" xlink:href=\"#md91571ca24\" y=\"103.074556\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.515261\" xlink:href=\"#md91571ca24\" y=\"148.716155\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.808944\" xlink:href=\"#md91571ca24\" y=\"140.200742\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.007198\" xlink:href=\"#md91571ca24\" y=\"126.097517\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"126.739437\" xlink:href=\"#md91571ca24\" y=\"119.198876\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.131334\" xlink:href=\"#md91571ca24\" y=\"152.554647\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"200.066086\" xlink:href=\"#md91571ca24\" y=\"100.102855\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"202.907662\" xlink:href=\"#md91571ca24\" y=\"104.462071\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"133.261549\" xlink:href=\"#md91571ca24\" y=\"135.860252\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.441509\" xlink:href=\"#md91571ca24\" y=\"124.696326\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.248954\" xlink:href=\"#md91571ca24\" y=\"93.794166\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.203191\" xlink:href=\"#md91571ca24\" y=\"128.916333\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.54123\" xlink:href=\"#md91571ca24\" y=\"110.392884\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.01667\" xlink:href=\"#md91571ca24\" y=\"113.581774\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.028992\" xlink:href=\"#md91571ca24\" y=\"124.154692\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.256199\" xlink:href=\"#md91571ca24\" y=\"139.909014\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.120048\" xlink:href=\"#md91571ca24\" y=\"118.726554\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.994301\" xlink:href=\"#md91571ca24\" y=\"106.009281\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.280732\" xlink:href=\"#md91571ca24\" y=\"118.208857\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.104993\" xlink:href=\"#md91571ca24\" y=\"125.763544\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.057732\" xlink:href=\"#md91571ca24\" y=\"134.739874\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.484413\" xlink:href=\"#md91571ca24\" y=\"104.149177\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.480135\" xlink:href=\"#md91571ca24\" y=\"126.056286\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"132.930611\" xlink:href=\"#md91571ca24\" y=\"165.520019\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.621666\" xlink:href=\"#md91571ca24\" y=\"119.888041\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.885592\" xlink:href=\"#md91571ca24\" y=\"121.67892\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.133243\" xlink:href=\"#md91571ca24\" y=\"154.037074\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"230.87725\" xlink:href=\"#md91571ca24\" y=\"101.020015\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.926293\" xlink:href=\"#md91571ca24\" y=\"131.628887\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"118.498098\" xlink:href=\"#md91571ca24\" y=\"160.136637\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.879587\" xlink:href=\"#md91571ca24\" y=\"121.306689\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.606035\" xlink:href=\"#md91571ca24\" y=\"111.950903\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.438796\" xlink:href=\"#md91571ca24\" y=\"142.108061\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.079716\" xlink:href=\"#md91571ca24\" y=\"144.987918\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.860481\" xlink:href=\"#md91571ca24\" y=\"141.493022\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.141067\" xlink:href=\"#md91571ca24\" y=\"116.403091\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.805984\" xlink:href=\"#md91571ca24\" y=\"137.04231\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.475292\" xlink:href=\"#md91571ca24\" y=\"127.624317\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.595973\" xlink:href=\"#md91571ca24\" y=\"103.828768\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"108.217539\" xlink:href=\"#md91571ca24\" y=\"201.975762\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.872664\" xlink:href=\"#md91571ca24\" y=\"124.637422\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"108.265739\" xlink:href=\"#md91571ca24\" y=\"180.141352\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.267143\" xlink:href=\"#md91571ca24\" y=\"104.096488\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.300919\" xlink:href=\"#md91571ca24\" y=\"133.817352\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.647511\" xlink:href=\"#md91571ca24\" y=\"122.642771\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.094607\" xlink:href=\"#md91571ca24\" y=\"116.27015\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.335452\" xlink:href=\"#md91571ca24\" y=\"177.950293\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.965886\" xlink:href=\"#md91571ca24\" y=\"156.730839\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"85.288853\" xlink:href=\"#md91571ca24\" y=\"201.040058\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.949526\" xlink:href=\"#md91571ca24\" y=\"122.115075\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.627831\" xlink:href=\"#md91571ca24\" y=\"116.553275\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"133.276596\" xlink:href=\"#md91571ca24\" y=\"156.209729\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.443056\" xlink:href=\"#md91571ca24\" y=\"138.4469\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.847028\" xlink:href=\"#md91571ca24\" y=\"118.219875\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"132.757712\" xlink:href=\"#md91571ca24\" y=\"163.490499\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"128.75982\" xlink:href=\"#md91571ca24\" y=\"171.388578\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.320577\" xlink:href=\"#md91571ca24\" y=\"116.128605\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.111613\" xlink:href=\"#md91571ca24\" y=\"134.517031\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.014243\" xlink:href=\"#md91571ca24\" y=\"148.281054\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.176101\" xlink:href=\"#md91571ca24\" y=\"164.059206\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.66634\" xlink:href=\"#md91571ca24\" y=\"131.57376\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.370051\" xlink:href=\"#md91571ca24\" y=\"122.224673\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.4103\" xlink:href=\"#md91571ca24\" y=\"125.826682\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.570642\" xlink:href=\"#md91571ca24\" y=\"133.235388\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.083082\" xlink:href=\"#md91571ca24\" y=\"118.965722\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.394965\" xlink:href=\"#md91571ca24\" y=\"142.667566\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.063405\" xlink:href=\"#md91571ca24\" y=\"124.71728\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"142.519355\" xlink:href=\"#md91571ca24\" y=\"126.598465\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.835472\" xlink:href=\"#md91571ca24\" y=\"115.172717\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.982337\" xlink:href=\"#md91571ca24\" y=\"116.750558\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.491478\" xlink:href=\"#md91571ca24\" y=\"100.087795\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.035723\" xlink:href=\"#md91571ca24\" y=\"143.883962\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.130982\" xlink:href=\"#md91571ca24\" y=\"121.225988\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.380186\" xlink:href=\"#md91571ca24\" y=\"126.757192\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.907555\" xlink:href=\"#md91571ca24\" y=\"123.050188\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"197.927265\" xlink:href=\"#md91571ca24\" y=\"94.045809\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.574667\" xlink:href=\"#md91571ca24\" y=\"107.36036\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"200.313488\" xlink:href=\"#md91571ca24\" y=\"106.073212\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.967054\" xlink:href=\"#md91571ca24\" y=\"140.375725\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"117.266663\" xlink:href=\"#md91571ca24\" y=\"157.705898\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.801643\" xlink:href=\"#md91571ca24\" y=\"135.764139\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.492631\" xlink:href=\"#md91571ca24\" y=\"131.269993\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.122573\" xlink:href=\"#md91571ca24\" y=\"124.932195\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.540038\" xlink:href=\"#md91571ca24\" y=\"113.852009\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"202.93484\" xlink:href=\"#md91571ca24\" y=\"93.606467\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.012989\" xlink:href=\"#md91571ca24\" y=\"132.288568\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.020067\" xlink:href=\"#md91571ca24\" y=\"128.532342\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.351478\" xlink:href=\"#md91571ca24\" y=\"110.129718\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.917566\" xlink:href=\"#md91571ca24\" y=\"118.66789\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"122.274309\" xlink:href=\"#md91571ca24\" y=\"125.937234\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.844809\" xlink:href=\"#md91571ca24\" y=\"121.889119\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"104.844676\" xlink:href=\"#md91571ca24\" y=\"190.751242\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.292205\" xlink:href=\"#md91571ca24\" y=\"86.560943\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.18621\" xlink:href=\"#md91571ca24\" y=\"134.515014\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.229345\" xlink:href=\"#md91571ca24\" y=\"117.170921\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"204.179236\" xlink:href=\"#md91571ca24\" y=\"114.114539\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.553281\" xlink:href=\"#md91571ca24\" y=\"122.270716\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.578637\" xlink:href=\"#md91571ca24\" y=\"156.38661\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.843128\" xlink:href=\"#md91571ca24\" y=\"123.665119\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.432616\" xlink:href=\"#md91571ca24\" y=\"108.570603\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.786587\" xlink:href=\"#md91571ca24\" y=\"156.631118\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.091694\" xlink:href=\"#md91571ca24\" y=\"119.485969\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"207.086779\" xlink:href=\"#md91571ca24\" y=\"109.435182\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.668549\" xlink:href=\"#md91571ca24\" y=\"151.586156\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"189.543031\" xlink:href=\"#md91571ca24\" y=\"97.595526\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.088294\" xlink:href=\"#md91571ca24\" y=\"133.478205\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.875033\" xlink:href=\"#md91571ca24\" y=\"119.291902\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"193.01447\" xlink:href=\"#md91571ca24\" y=\"95.58629\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.175423\" xlink:href=\"#md91571ca24\" y=\"149.49462\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"202.394817\" xlink:href=\"#md91571ca24\" y=\"108.986188\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"116.741182\" xlink:href=\"#md91571ca24\" y=\"187.57672\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.129923\" xlink:href=\"#md91571ca24\" y=\"101.178258\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.32085\" xlink:href=\"#md91571ca24\" y=\"119.862409\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"89.361507\" xlink:href=\"#md91571ca24\" y=\"171.748913\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"219.234426\" xlink:href=\"#md91571ca24\" y=\"36.807098\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.785854\" xlink:href=\"#md91571ca24\" y=\"118.323067\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.56355\" xlink:href=\"#md91571ca24\" y=\"113.651838\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.232658\" xlink:href=\"#md91571ca24\" y=\"116.671694\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.763247\" xlink:href=\"#md91571ca24\" y=\"119.338679\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.760509\" xlink:href=\"#md91571ca24\" y=\"126.399144\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.137442\" xlink:href=\"#md91571ca24\" y=\"155.501156\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.285089\" xlink:href=\"#md91571ca24\" y=\"111.784237\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.255922\" xlink:href=\"#md91571ca24\" y=\"128.761939\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.84263\" xlink:href=\"#md91571ca24\" y=\"122.585248\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.409937\" xlink:href=\"#md91571ca24\" y=\"111.940446\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"151.228469\" xlink:href=\"#md91571ca24\" y=\"129.185913\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"184.240865\" xlink:href=\"#md91571ca24\" y=\"102.835302\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.679431\" xlink:href=\"#md91571ca24\" y=\"155.056892\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.459855\" xlink:href=\"#md91571ca24\" y=\"124.200618\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.695537\" xlink:href=\"#md91571ca24\" y=\"116.326045\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.478715\" xlink:href=\"#md91571ca24\" y=\"129.985771\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.354887\" xlink:href=\"#md91571ca24\" y=\"122.295469\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"194.543283\" xlink:href=\"#md91571ca24\" y=\"100.606794\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"146.537641\" xlink:href=\"#md91571ca24\" y=\"153.607799\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"247.143217\" xlink:href=\"#md91571ca24\" y=\"40.619215\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"93.032252\" xlink:href=\"#md91571ca24\" y=\"200.285015\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.682611\" xlink:href=\"#md91571ca24\" y=\"113.960805\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"249.011749\" xlink:href=\"#md91571ca24\" y=\"108.290251\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"125.266646\" xlink:href=\"#md91571ca24\" y=\"150.997992\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.085699\" xlink:href=\"#md91571ca24\" y=\"122.912265\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.970378\" xlink:href=\"#md91571ca24\" y=\"110.875524\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.083547\" xlink:href=\"#md91571ca24\" y=\"130.403065\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.051498\" xlink:href=\"#md91571ca24\" y=\"149.314451\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"97.083528\" xlink:href=\"#md91571ca24\" y=\"184.834305\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.137812\" xlink:href=\"#md91571ca24\" y=\"130.466213\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.951681\" xlink:href=\"#md91571ca24\" y=\"103.34274\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"112.441668\" xlink:href=\"#md91571ca24\" y=\"170.468396\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.454214\" xlink:href=\"#md91571ca24\" y=\"116.019668\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"107.741709\" xlink:href=\"#md91571ca24\" y=\"190.865067\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.681579\" xlink:href=\"#md91571ca24\" y=\"148.923363\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.077379\" xlink:href=\"#md91571ca24\" y=\"116.063635\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"191.795282\" xlink:href=\"#md91571ca24\" y=\"106.45361\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"214.120964\" xlink:href=\"#md91571ca24\" y=\"80.470093\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"153.073199\" xlink:href=\"#md91571ca24\" y=\"128.085714\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.410356\" xlink:href=\"#md91571ca24\" y=\"122.526144\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"134.118124\" xlink:href=\"#md91571ca24\" y=\"146.451826\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.634444\" xlink:href=\"#md91571ca24\" y=\"113.841737\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.673607\" xlink:href=\"#md91571ca24\" y=\"130.375545\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"164.455175\" xlink:href=\"#md91571ca24\" y=\"122.310722\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.37376\" xlink:href=\"#md91571ca24\" y=\"114.880524\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.289673\" xlink:href=\"#md91571ca24\" y=\"110.229169\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.437638\" xlink:href=\"#md91571ca24\" y=\"117.748157\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"148.367032\" xlink:href=\"#md91571ca24\" y=\"123.80924\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.189477\" xlink:href=\"#md91571ca24\" y=\"144.077689\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.459374\" xlink:href=\"#md91571ca24\" y=\"86.525869\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"185.600881\" xlink:href=\"#md91571ca24\" y=\"109.670549\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.390477\" xlink:href=\"#md91571ca24\" y=\"108.09236\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"199.106185\" xlink:href=\"#md91571ca24\" y=\"99.621106\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"132.569948\" xlink:href=\"#md91571ca24\" y=\"141.178091\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.978922\" xlink:href=\"#md91571ca24\" y=\"168.113311\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.242922\" xlink:href=\"#md91571ca24\" y=\"109.434283\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.518968\" xlink:href=\"#md91571ca24\" y=\"109.465345\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"200.070428\" xlink:href=\"#md91571ca24\" y=\"83.698058\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"184.238908\" xlink:href=\"#md91571ca24\" y=\"101.69773\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.255228\" xlink:href=\"#md91571ca24\" y=\"140.000323\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.64348\" xlink:href=\"#md91571ca24\" y=\"123.547826\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.755519\" xlink:href=\"#md91571ca24\" y=\"120.383155\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.402549\" xlink:href=\"#md91571ca24\" y=\"108.85288\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.807944\" xlink:href=\"#md91571ca24\" y=\"122.42786\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.736288\" xlink:href=\"#md91571ca24\" y=\"124.896868\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.429182\" xlink:href=\"#md91571ca24\" y=\"119.233914\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"243.935976\" xlink:href=\"#md91571ca24\" y=\"45.365028\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"134.045279\" xlink:href=\"#md91571ca24\" y=\"136.65802\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"141.62911\" xlink:href=\"#md91571ca24\" y=\"136.821781\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.165907\" xlink:href=\"#md91571ca24\" y=\"109.370985\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"186.927771\" xlink:href=\"#md91571ca24\" y=\"118.788736\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"120.241607\" xlink:href=\"#md91571ca24\" y=\"170.831263\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.60901\" xlink:href=\"#md91571ca24\" y=\"118.949881\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"121.981487\" xlink:href=\"#md91571ca24\" y=\"164.960883\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"166.67995\" xlink:href=\"#md91571ca24\" y=\"112.793997\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.478757\" xlink:href=\"#md91571ca24\" y=\"143.564909\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.216324\" xlink:href=\"#md91571ca24\" y=\"115.266818\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"126.818081\" xlink:href=\"#md91571ca24\" y=\"170.339097\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"77.786446\" xlink:href=\"#md91571ca24\" y=\"190.129258\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.744243\" xlink:href=\"#md91571ca24\" y=\"112.626381\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.975551\" xlink:href=\"#md91571ca24\" y=\"109.156444\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.200099\" xlink:href=\"#md91571ca24\" y=\"128.200436\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"211.833862\" xlink:href=\"#md91571ca24\" y=\"73.795732\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.214373\" xlink:href=\"#md91571ca24\" y=\"121.014199\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.944019\" xlink:href=\"#md91571ca24\" y=\"133.84534\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.804329\" xlink:href=\"#md91571ca24\" y=\"120.858932\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.025638\" xlink:href=\"#md91571ca24\" y=\"115.490646\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"126.306371\" xlink:href=\"#md91571ca24\" y=\"121.51953\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.58779\" xlink:href=\"#md91571ca24\" y=\"122.381657\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"139.257499\" xlink:href=\"#md91571ca24\" y=\"117.726256\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.448405\" xlink:href=\"#md91571ca24\" y=\"121.645442\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.434107\" xlink:href=\"#md91571ca24\" y=\"122.299466\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.333303\" xlink:href=\"#md91571ca24\" y=\"107.525049\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"223.741235\" xlink:href=\"#md91571ca24\" y=\"106.49522\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"140.658321\" xlink:href=\"#md91571ca24\" y=\"156.654259\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"132.770212\" xlink:href=\"#md91571ca24\" y=\"139.264613\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"192.536243\" xlink:href=\"#md91571ca24\" y=\"95.855938\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.210956\" xlink:href=\"#md91571ca24\" y=\"111.78176\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.569\" xlink:href=\"#md91571ca24\" y=\"98.35011\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"191.156047\" xlink:href=\"#md91571ca24\" y=\"95.996358\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.382979\" xlink:href=\"#md91571ca24\" y=\"112.269354\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.47478\" xlink:href=\"#md91571ca24\" y=\"127.006353\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.324378\" xlink:href=\"#md91571ca24\" y=\"99.014532\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.687899\" xlink:href=\"#md91571ca24\" y=\"148.133062\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"218.420834\" xlink:href=\"#md91571ca24\" y=\"114.008647\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"101.276125\" xlink:href=\"#md91571ca24\" y=\"189.48747\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"168.210428\" xlink:href=\"#md91571ca24\" y=\"102.230814\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.958042\" xlink:href=\"#md91571ca24\" y=\"119.114154\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.731671\" xlink:href=\"#md91571ca24\" y=\"126.356841\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"215.195488\" xlink:href=\"#md91571ca24\" y=\"77.469192\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.29886\" xlink:href=\"#md91571ca24\" y=\"117.377107\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.929025\" xlink:href=\"#md91571ca24\" y=\"119.126449\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.656262\" xlink:href=\"#md91571ca24\" y=\"134.805467\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.935875\" xlink:href=\"#md91571ca24\" y=\"113.76779\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.657335\" xlink:href=\"#md91571ca24\" y=\"112.1933\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.617122\" xlink:href=\"#md91571ca24\" y=\"122.276291\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"127.243903\" xlink:href=\"#md91571ca24\" y=\"168.56388\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"136.53888\" xlink:href=\"#md91571ca24\" y=\"147.599652\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"73.384007\" xlink:href=\"#md91571ca24\" y=\"187.089855\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"198.764988\" xlink:href=\"#md91571ca24\" y=\"111.866166\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.839734\" xlink:href=\"#md91571ca24\" y=\"119.488907\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.322373\" xlink:href=\"#md91571ca24\" y=\"121.5659\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.372926\" xlink:href=\"#md91571ca24\" y=\"114.429804\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.563355\" xlink:href=\"#md91571ca24\" y=\"119.897952\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"114.325791\" xlink:href=\"#md91571ca24\" y=\"185.306622\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"173.325484\" xlink:href=\"#md91571ca24\" y=\"131.887183\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"181.321229\" xlink:href=\"#md91571ca24\" y=\"107.019197\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"189.759068\" xlink:href=\"#md91571ca24\" y=\"108.446829\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"182.533522\" xlink:href=\"#md91571ca24\" y=\"104.824195\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"189.401619\" xlink:href=\"#md91571ca24\" y=\"93.863164\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"137.047545\" xlink:href=\"#md91571ca24\" y=\"138.643716\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.598853\" xlink:href=\"#md91571ca24\" y=\"142.406697\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"154.729652\" xlink:href=\"#md91571ca24\" y=\"113.609176\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"150.246295\" xlink:href=\"#md91571ca24\" y=\"128.56412\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"197.472237\" xlink:href=\"#md91571ca24\" y=\"108.096036\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"201.30303\" xlink:href=\"#md91571ca24\" y=\"114.873479\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"87.847028\" xlink:href=\"#md91571ca24\" y=\"198.81411\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"180.698584\" xlink:href=\"#md91571ca24\" y=\"125.0968\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.053763\" xlink:href=\"#md91571ca24\" y=\"142.187659\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.633567\" xlink:href=\"#md91571ca24\" y=\"145.273546\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"129.174768\" xlink:href=\"#md91571ca24\" y=\"145.905742\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.940428\" xlink:href=\"#md91571ca24\" y=\"120.123645\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"85.87992\" xlink:href=\"#md91571ca24\" y=\"163.575668\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"187.698566\" xlink:href=\"#md91571ca24\" y=\"107.3528\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"248.006447\" xlink:href=\"#md91571ca24\" y=\"68.566178\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"169.844985\" xlink:href=\"#md91571ca24\" y=\"119.270323\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.690385\" xlink:href=\"#md91571ca24\" y=\"129.91456\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.336144\" xlink:href=\"#md91571ca24\" y=\"102.997218\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.009707\" xlink:href=\"#md91571ca24\" y=\"125.57131\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.035501\" xlink:href=\"#md91571ca24\" y=\"118.31449\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"189.326682\" xlink:href=\"#md91571ca24\" y=\"104.975014\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"131.97822\" xlink:href=\"#md91571ca24\" y=\"135.400851\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"152.208978\" xlink:href=\"#md91571ca24\" y=\"130.761556\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"144.037081\" xlink:href=\"#md91571ca24\" y=\"133.298304\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"191.566569\" xlink:href=\"#md91571ca24\" y=\"107.202377\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.206806\" xlink:href=\"#md91571ca24\" y=\"119.760595\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.336871\" xlink:href=\"#md91571ca24\" y=\"124.912833\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"110.88661\" xlink:href=\"#md91571ca24\" y=\"167.741842\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"109.44716\" xlink:href=\"#md91571ca24\" y=\"181.920748\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"147.197794\" xlink:href=\"#md91571ca24\" y=\"143.085109\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"161.937935\" xlink:href=\"#md91571ca24\" y=\"115.499841\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"170.941477\" xlink:href=\"#md91571ca24\" y=\"118.987681\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"176.46362\" xlink:href=\"#md91571ca24\" y=\"119.010264\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.0214\" xlink:href=\"#md91571ca24\" y=\"119.952803\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.277489\" xlink:href=\"#md91571ca24\" y=\"114.460773\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.900079\" xlink:href=\"#md91571ca24\" y=\"129.7627\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"133.991422\" xlink:href=\"#md91571ca24\" y=\"141.950361\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"172.486853\" xlink:href=\"#md91571ca24\" y=\"120.022597\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"158.007891\" xlink:href=\"#md91571ca24\" y=\"121.822319\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"157.024738\" xlink:href=\"#md91571ca24\" y=\"124.437891\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"149.239911\" xlink:href=\"#md91571ca24\" y=\"130.680412\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"179.642374\" xlink:href=\"#md91571ca24\" y=\"113.388783\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.123861\" xlink:href=\"#md91571ca24\" y=\"112.673391\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"103.072182\" xlink:href=\"#md91571ca24\" y=\"166.940051\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"167.361261\" xlink:href=\"#md91571ca24\" y=\"117.365572\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.142683\" xlink:href=\"#md91571ca24\" y=\"105.901444\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.490679\" xlink:href=\"#md91571ca24\" y=\"98.923277\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"225.028116\" xlink:href=\"#md91571ca24\" y=\"97.355914\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"138.415492\" xlink:href=\"#md91571ca24\" y=\"142.056089\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.417488\" xlink:href=\"#md91571ca24\" y=\"118.566788\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"155.979285\" xlink:href=\"#md91571ca24\" y=\"119.968953\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"162.330455\" xlink:href=\"#md91571ca24\" y=\"121.532894\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"165.326609\" xlink:href=\"#md91571ca24\" y=\"123.488734\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.083315\" xlink:href=\"#md91571ca24\" y=\"141.838919\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"174.800887\" xlink:href=\"#md91571ca24\" y=\"130.056284\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"199.809936\" xlink:href=\"#md91571ca24\" y=\"82.787351\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"160.289413\" xlink:href=\"#md91571ca24\" y=\"115.509716\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"159.993883\" xlink:href=\"#md91571ca24\" y=\"125.764295\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"196.307198\" xlink:href=\"#md91571ca24\" y=\"96.843604\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"114.366014\" xlink:href=\"#md91571ca24\" y=\"153.542339\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.986316\" xlink:href=\"#md91571ca24\" y=\"100.570547\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"163.638648\" xlink:href=\"#md91571ca24\" y=\"124.459025\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"145.471567\" xlink:href=\"#md91571ca24\" y=\"145.686725\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"171.750856\" xlink:href=\"#md91571ca24\" y=\"110.22612\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"102.930848\" xlink:href=\"#md91571ca24\" y=\"197.608977\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"103.906432\" xlink:href=\"#md91571ca24\" y=\"167.625943\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"156.478961\" xlink:href=\"#md91571ca24\" y=\"125.642675\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.087624\" xlink:href=\"#md91571ca24\" y=\"128.567053\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"143.856931\" xlink:href=\"#md91571ca24\" y=\"131.346582\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"275.963437\" xlink:href=\"#md91571ca24\" y=\"91.444525\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"178.214043\" xlink:href=\"#md91571ca24\" y=\"103.797094\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"258.254404\" xlink:href=\"#md91571ca24\" y=\"44.64354\"/>\n <use style=\"fill:#1f77b4;stroke:#1f77b4;\" x=\"175.919113\" xlink:href=\"#md91571ca24\" y=\"111.984809\"/>\n <use style=\"fill:#1f77b4;stro
gitextract_4r95syc5/ ├── .gitignore ├── Arguments.py ├── LICENSE.md ├── README.md ├── benchmark_layers.py ├── benchmark_models.py ├── benchmark_scripts/ │ ├── DGCNN_site.sh │ ├── Pointnet_site.sh │ ├── dMaSIF_search.sh │ └── dMaSIF_site.sh ├── data.py ├── data_analysis/ │ ├── analyse_atomnet.ipynb │ ├── analyse_descriptors.py │ ├── analyse_descriptors_para.py │ ├── analyse_output.ipynb │ ├── analyse_site_outputs.py │ ├── analyse_site_outputs_graph.ipynb │ ├── plot_search.ipynb │ └── profiling_surface.ipynb ├── data_iteration.py ├── data_preprocessing/ │ ├── convert_pdb2npy.py │ ├── convert_ply2npy.py │ └── download_pdb.py ├── geometry_processing.py ├── helper.py ├── lists/ │ ├── testing.txt │ ├── testing_ppi.txt │ ├── training.txt │ └── training_ppi.txt ├── main_inference.py ├── main_training.py ├── model.py ├── models/ │ └── dMaSIF_search_3layer_12A_16dim └── requirements.txt
SYMBOL INDEX (118 symbols across 11 files)
FILE: benchmark_layers.py
function ranges_slices (line 15) | def ranges_slices(batch):
function diagonal_ranges (line 28) | def diagonal_ranges(batch_x=None, batch_y=None):
function keops_knn (line 41) | def keops_knn(
function knn_graph (line 74) | def knn_graph(
class MyDynamicEdgeConv (line 103) | class MyDynamicEdgeConv(EdgeConv):
method __init__ (line 106) | def __init__(self, nn, k, aggr="max", **kwargs):
method forward (line 110) | def forward(self, x, batch=None):
method __repr__ (line 117) | def __repr__(self):
class MyXConv (line 121) | class MyXConv(torch.nn.Module):
method __init__ (line 122) | def __init__(
method reset_parameters (line 185) | def reset_parameters(self):
method forward (line 190) | def forward(self, x, source, batch_source, target, batch_target):
method __repr__ (line 255) | def __repr__(self):
FILE: benchmark_models.py
function MLP (line 36) | def MLP(channels, batch_norm=True):
class DGCNN_seg (line 50) | class DGCNN_seg(torch.nn.Module):
method __init__ (line 51) | def __init__(
method forward (line 90) | def forward(self, positions, features, batch_indices):
class SAModule (line 124) | class SAModule(torch.nn.Module):
method __init__ (line 127) | def __init__(self, ratio, r, nn, max_num_neighbors=64):
method forward (line 134) | def forward(self, x, pos, batch):
class GlobalSAModule (line 158) | class GlobalSAModule(torch.nn.Module):
method __init__ (line 159) | def __init__(self, nn):
method forward (line 163) | def forward(self, x, pos, batch):
class FPModule (line 171) | class FPModule(torch.nn.Module):
method __init__ (line 172) | def __init__(self, k, nn):
method forward (line 177) | def forward(self, x, pos, batch, x_skip, pos_skip, batch_skip):
class PointNet2_seg (line 185) | class PointNet2_seg(torch.nn.Module):
method __init__ (line 186) | def __init__(self, args, in_channels, out_channels):
method forward (line 218) | def forward(self, positions, features, batch_indices):
class dMaSIFConv_seg (line 233) | class dMaSIFConv_seg(torch.nn.Module):
method __init__ (line 234) | def __init__(self, args, in_channels, out_channels, n_layers, radius=9...
method forward (line 260) | def forward(self, features):
method load_mesh (line 272) | def load_mesh(self, xyz, triangles=None, normals=None, weights=None, b...
FILE: data.py
function numpy (line 18) | def numpy(x):
function iface_valid_filter (line 22) | def iface_valid_filter(protein_pair):
class RandomRotationPairAtoms (line 39) | class RandomRotationPairAtoms(object):
method __call__ (line 42) | def __call__(self, data):
method __repr__ (line 58) | def __repr__(self):
class CenterPairAtoms (line 62) | class CenterPairAtoms(object):
method __call__ (line 65) | def __call__(self, data):
method __repr__ (line 79) | def __repr__(self):
class NormalizeChemFeatures (line 83) | class NormalizeChemFeatures(object):
method __call__ (line 86) | def __call__(self, data):
method __repr__ (line 118) | def __repr__(self):
function load_protein_npy (line 122) | def load_protein_npy(pdb_id, data_dir, center=False, single_pdb=False):
class PairData (line 173) | class PairData(Data):
method __init__ (line 174) | def __init__(
method __inc__ (line 220) | def __inc__(self, key, value):
method __cat_dim__ (line 228) | def __cat_dim__(self, key, value):
function load_protein_pair (line 235) | def load_protein_pair(pdb_id, data_dir,single_pdb=False):
class ProteinPairsSurfaces (line 271) | class ProteinPairsSurfaces(InMemoryDataset):
method __init__ (line 274) | def __init__(self, root, ppi=False, train=True, transform=None, pre_tr...
method raw_file_names (line 281) | def raw_file_names(self):
method processed_file_names (line 285) | def processed_file_names(self):
method download (line 302) | def download(self):
method process (line 316) | def process(self):
FILE: data_analysis/analyse_descriptors_para.py
function analyse_pdb (line 29) | def analyse_pdb(pdb_id,D):
FILE: data_iteration.py
function process_single (line 16) | def process_single(protein_pair, chain_idx=1):
function save_protein_batch_single (line 76) | def save_protein_batch_single(protein_pair_id, P, save_path, pdb_idx):
function project_iface_labels (line 101) | def project_iface_labels(P, threshold=2.0):
function process (line 123) | def process(args, protein_pair, net):
function generate_matchinglabels (line 140) | def generate_matchinglabels(args, P1, P2):
function compute_loss (line 157) | def compute_loss(args, P1, P2, n_points_sample=16):
function extract_single (line 218) | def extract_single(P_batch, number):
function iterate (line 244) | def iterate(
function iterate_surface_precompute (line 423) | def iterate_surface_precompute(dataset, net, args):
FILE: data_preprocessing/convert_pdb2npy.py
function load_structure_np (line 9) | def load_structure_np(fname, center):
function convert_pdbs (line 34) | def convert_pdbs(pdb_dir, npy_dir):
FILE: data_preprocessing/convert_ply2npy.py
function load_surface_np (line 7) | def load_surface_np(fname, center):
function convert_plys (line 42) | def convert_plys(ply_dir, npy_dir):
FILE: data_preprocessing/download_pdb.py
class NotDisordered (line 28) | class NotDisordered(Select):
method accept_atom (line 29) | def accept_atom(self, atom):
function find_modified_amino_acids (line 33) | def find_modified_amino_acids(path):
function extractPDB (line 48) | def extractPDB(
function protonate (line 86) | def protonate(in_pdb_file, out_pdb_file):
function get_single (line 108) | def get_single(pdb_id: str,chains: list):
FILE: geometry_processing.py
function save_vtk (line 21) | def save_vtk(
function subsample (line 87) | def subsample(x, batch=None, scale=1.0):
function soft_distances (line 136) | def soft_distances(x, y, batch_x, batch_y, smoothness=0.01, atomtypes=No...
function atoms_to_points_normals (line 201) | def atoms_to_points_normals(
function mesh_normals_areas (line 328) | def mesh_normals_areas(vertices, triangles=None, scale=[1.0], batch=None...
function tangent_vectors (line 418) | def tangent_vectors(normals):
function curvatures (line 444) | def curvatures(
class ContiguousBackward (line 557) | class ContiguousBackward(torch.autograd.Function):
method forward (line 563) | def forward(ctx, input):
method backward (line 567) | def backward(ctx, grad_output):
class dMaSIFConv (line 570) | class dMaSIFConv(nn.Module):
method __init__ (line 571) | def __init__(
method forward (line 700) | def forward(self, points, nuv, features, ranges=None):
FILE: helper.py
function ranges_slices (line 15) | def ranges_slices(batch):
function diagonal_ranges (line 28) | def diagonal_ranges(batch_x=None, batch_y=None):
function soft_dimension (line 42) | def soft_dimension(features):
FILE: model.py
function knn_atoms (line 19) | def knn_atoms(x, y, x_batch, y_batch, k):
function get_atom_features (line 37) | def get_atom_features(x, y, x_batch, y_batch, y_atomtype, k=16):
class Atom_embedding (line 53) | class Atom_embedding(nn.Module):
method __init__ (line 54) | def __init__(self, args):
method forward (line 65) | def forward(self, x, y, y_atomtypes, x_batch, y_batch):
class AtomNet (line 84) | class AtomNet(nn.Module):
method __init__ (line 85) | def __init__(self, args):
method forward (line 99) | def forward(self, xyz, atom_xyz, atomtypes, batch, atom_batch):
class Atom_embedding_MP (line 104) | class Atom_embedding_MP(nn.Module):
method __init__ (line 105) | def __init__(self, args):
method forward (line 125) | def forward(self, x, y, y_atomtypes, x_batch, y_batch):
class Atom_Atom_embedding_MP (line 145) | class Atom_Atom_embedding_MP(nn.Module):
method __init__ (line 146) | def __init__(self, args):
method forward (line 168) | def forward(self, x, y, y_atomtypes, x_batch, y_batch):
class AtomNet_MP (line 191) | class AtomNet_MP(nn.Module):
method __init__ (line 192) | def __init__(self, args):
method forward (line 205) | def forward(self, xyz, atom_xyz, atomtypes, batch, atom_batch):
function combine_pair (line 215) | def combine_pair(P1, P2):
function split_pair (line 235) | def split_pair(P1P2):
function project_iface_labels (line 270) | def project_iface_labels(P, threshold=2.0):
class dMaSIF (line 289) | class dMaSIF(nn.Module):
method __init__ (line 290) | def __init__(self, args):
method features (line 358) | def features(self, P, i=1):
method embed (line 394) | def embed(self, P):
method preprocess_surface (line 446) | def preprocess_surface(self, P):
method forward (line 458) | def forward(self, P1, P2=None):
Copy disabled (too large)
Download .json
Condensed preview — 34 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (11,386K chars).
[
{
"path": ".gitignore",
"chars": 289,
"preview": "01-benchmark_surfaces/\n01-benchmark_surfaces_npy/\n01-benchmark_pdbs_npy/\n01-benchmark_pdbs/\n01-benchmark_pdbs/\nshape_ind"
},
{
"path": "Arguments.py",
"chars": 4337,
"preview": "import argparse\n\nparser = argparse.ArgumentParser(description=\"Network parameters\")\n\n# Main parameters\nparser.add_argume"
},
{
"path": "LICENSE.md",
"chars": 19123,
"preview": "Attribution-NonCommercial-NoDerivatives 4.0 International\n\n============================================================="
},
{
"path": "README.md",
"chars": 4014,
"preview": "## dMaSIF - Fast end-to-end learning on protein surfaces\n\n\n## Abstract\n\nProteins’ biolog"
},
{
"path": "benchmark_layers.py",
"chars": 7716,
"preview": "import torch\nfrom typing import Optional\nfrom pykeops.torch import LazyTensor\nfrom torch_geometric.nn import EdgeConv, R"
},
{
"path": "benchmark_models.py",
"chars": 12233,
"preview": "import torch\nimport torch.nn.functional as F\nimport torch.nn as nn\nfrom torch.nn import (\n Sequential as Seq,\n Dro"
},
{
"path": "benchmark_scripts/DGCNN_site.sh",
"chars": 867,
"preview": "# Load environment\npython -W ignore -u main_training.py --experiment_name DGCNN_site_1layer_k200 --batch_size 64 --embed"
},
{
"path": "benchmark_scripts/Pointnet_site.sh",
"chars": 1361,
"preview": "# Load environment\npython -W ignore -u main_training.py --experiment_name PointNet_site_3layer_15A --batch_size 64 --emb"
},
{
"path": "benchmark_scripts/dMaSIF_search.sh",
"chars": 421,
"preview": "# Load environment\npython -W ignore -u main_training.py --experiment_name dMaSIF_search_1layer_12A --batch_size 64 --emb"
},
{
"path": "benchmark_scripts/dMaSIF_site.sh",
"chars": 1230,
"preview": "# Load environment\npython -W ignore -u main_training.py --experiment_name dMaSIF_site_1layer_15A --batch_size 64 --embed"
},
{
"path": "data.py",
"chars": 13710,
"preview": "import torch\nfrom torch_geometric.data import InMemoryDataset, Data, DataLoader\nfrom torch_geometric.transforms import C"
},
{
"path": "data_analysis/analyse_atomnet.ipynb",
"chars": 3639398,
"preview": "{\n \"metadata\": {\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_ext"
},
{
"path": "data_analysis/analyse_descriptors.py",
"chars": 2820,
"preview": "import numpy as np\nfrom pathlib import Path\nfrom sklearn.metrics import roc_auc_score, roc_curve\nfrom scipy.spatial.dist"
},
{
"path": "data_analysis/analyse_descriptors_para.py",
"chars": 3303,
"preview": "import numpy as np\nfrom pathlib import Path\nfrom sklearn.metrics import roc_auc_score, roc_curve\nfrom scipy.spatial.dist"
},
{
"path": "data_analysis/analyse_output.ipynb",
"chars": 5880572,
"preview": "{\n \"metadata\": {\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_ext"
},
{
"path": "data_analysis/analyse_site_outputs.py",
"chars": 3631,
"preview": "import numpy as np\nimport pandas as pd\nfrom pathlib import Path\nfrom tqdm import tqdm\nfrom scipy.spatial.distance import"
},
{
"path": "data_analysis/analyse_site_outputs_graph.ipynb",
"chars": 85500,
"preview": "{\n \"cells\": [\n {\n \"cell_type\": \"code\",\n \"execution_count\": 1,\n \"metadata\": {},\n \"outputs\": [],\n \"source\": [\n "
},
{
"path": "data_analysis/plot_search.ipynb",
"chars": 163055,
"preview": "{\n \"metadata\": {\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_ext"
},
{
"path": "data_analysis/profiling_surface.ipynb",
"chars": 336892,
"preview": "{\n \"metadata\": {\n \"language_info\": {\n \"codemirror_mode\": {\n \"name\": \"ipython\",\n \"version\": 3\n },\n \"file_ext"
},
{
"path": "data_iteration.py",
"chars": 16950,
"preview": "import torch\nimport numpy as np\nfrom helper import *\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch."
},
{
"path": "data_preprocessing/convert_pdb2npy.py",
"chars": 1180,
"preview": "import numpy as np\nfrom pathlib import Path\nfrom tqdm import tqdm\nfrom Bio.PDB import *\n\nele2num = {\"C\": 0, \"H\": 1, \"O\":"
},
{
"path": "data_preprocessing/convert_ply2npy.py",
"chars": 1691,
"preview": "import numpy as np\nfrom pathlib import Path\nfrom tqdm import tqdm\nfrom plyfile import PlyData, PlyElement\n\n\ndef load_sur"
},
{
"path": "data_preprocessing/download_pdb.py",
"chars": 5075,
"preview": "import Bio\nfrom Bio.PDB import * \nfrom Bio.SeqUtils import IUPACData\nimport sys\nimport importlib\nimport os\nimport numpy "
},
{
"path": "geometry_processing.py",
"chars": 33557,
"preview": "import numpy as np\nfrom math import pi\nimport torch\nfrom pykeops.torch import LazyTensor\nfrom plyfile import PlyData, Pl"
},
{
"path": "helper.py",
"chars": 2131,
"preview": "import colorsys\n\nimport numpy as np\nimport torch\nfrom pykeops.torch import LazyTensor\nfrom plyfile import PlyData, PlyEl"
},
{
"path": "lists/testing.txt",
"chars": 2519,
"preview": "1A99_D\n1AUI_A\n1BO6_A\n1BOU_B\n1BPL_B\n1C7N_D\n1CS0_B\n1DM5_F\n1DOS_B\n1EFV_A\n1EHI_A\n1EV7_A\n1EWY_A\n1EZ1_B\n1F06_A\n1F6M_A\n1FFV_C\n1"
},
{
"path": "lists/testing_ppi.txt",
"chars": 8647,
"preview": "1A2K_C_AB\n1A2W_A_B\n1A79_C_B\n1A99_C_D\n1ACB_E_I\n1AGQ_C_D\n1AHS_C_B\n1AK4_A_D\n1AN1_E_I\n1ARZ_A_C\n1ATN_A_D\n1AVX_A_B\n1AY7_A_B\n1B"
},
{
"path": "lists/training.txt",
"chars": 21055,
"preview": "1A0G_B\n1A0H_D\n1A22_A\n1A2K_AB\n1A6J_B\n1A79_C\n1AA7_A\n1ACB_I\n1AIH_D\n1ARZ_C\n1AVA_C\n1AVO_K\n1AVO_L\n1AY7_A\n1AZS_AB\n1B0N_A\n1B27_A"
},
{
"path": "lists/training_ppi.txt",
"chars": 45070,
"preview": "1A0G_A_B\n1A0H_E_D\n1A14_HL_N\n1A1U_A_C\n1A22_A_B\n1A2A_C_D\n1A2X_A_B\n1A2Y_BA_C\n1A3R_H_P\n1A6D_A_B\n1A6J_A_B\n1A73_A_B\n1AA7_A_B\n1"
},
{
"path": "main_inference.py",
"chars": 2922,
"preview": "# Standard imports:\nimport numpy as np\nimport torch\nfrom torch.utils.tensorboard import SummaryWriter\nfrom torch.utils.d"
},
{
"path": "main_training.py",
"chars": 5366,
"preview": "# Standard imports:\nimport numpy as np\nimport torch\nfrom torch.utils.tensorboard import SummaryWriter\nfrom torch.utils.d"
},
{
"path": "model.py",
"chars": 16540,
"preview": "import math\nimport time\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.autograd.profile"
},
{
"path": "requirements.txt",
"chars": 2181,
"preview": "absl-py==0.11.0\nappdirs==1.4.4\nargon2-cffi==20.1.0\nase==3.20.1\nasync-generator==1.10\nattrs==20.3.0\nbackcall==0.2.0\nbiopy"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the FreyrS/dMaSIF GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 34 files (9.9 MB), approximately 2.6M tokens, and a symbol index with 118 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.