Repository: pepkit/peppy (language: python)

Issue:
Env variables in config file are not expanding
Looking at [pep-pipelines](https://github.com/pepkit/pep-pipelines) for snakemake integration:

https://github.com/pepkit/pep-pipelines/blob/805cbc75ca2dfdf57bfee412987816e5f7c52d0a/pipelines/pep-snakemake/simple/examples/wc_config.yaml#L1-L11

```
name: snakemake-line-count

pep_version: 2.0.0
sample_table: wc_sample_table.csv
output_dir: $HOME/pep-snakemake/simple/examples

sample_modifiers:
  derive:
    attributes: [filename]
    sources:
      F: $CODE/pep-snakemake/simple/examples/{sample_name}.txt
```

The environment variables are not being expanded. I confirmed that, if I add the absolute path manually, the pipeline works fine.

Using `peppy v0.40.0a5`
Make a peppy.Project from a sample yaml file
              example: I would like to make a peppy.Project from a sample yaml file:

```
- sample_name: sample 1
  file: path/to/file.tsv
- sample_name: sample 2
  file: path/to/2.tsv
```


```
prj = peppy.Project(sample_yaml="path.yaml")
```

or `prj = peppy.Project(sample_yaml={ ... sample dict ... })

_Originally posted by @nsheff in https://github.com/pepkit/peppy/issues/457#issuecomment-1841195131_
            


Discussion / hints:

Fix patch:
diff --git a/docs/changelog.md b/docs/changelog.md
index 1351854c..fbe23a1e 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -2,6 +2,21 @@
 
 This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format.
 
+## [0.40.0] -- 2023-XX-XX
+
+**This version introduced backwards-incompatible changes.**
+
+### Changed
+- Replaced `attmap` with `MutableMapping` (which removes some attributes)
+- Replaced OrderedDict with dict
+- Deprecated support for Python versions <= 3.7
+
+_Due to the changes mentioned above, a few functionalities may be disabled. For example, the `name` and `description` project properties can no longer be accessed with `getitem`; use the `getattr` syntax instead_
+
+### Added
+- Constructor methods: `Project.from_dict`, `Project.from_pandas`, `Project.from_sample_yaml`, `Project.from_pep_config`
+
+
 ## [0.35.7] -- 2023-07-19
 ### Fixed 
 - incorrect setting of sample and subsample indexes using from_dict function (#452)
@@ -17,6 +32,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 ### Changed
 - Reduced the number of items returned in the to_dict(extended=True) method to 3, with the name and description now stored in the config key.
 
+
 ## [0.35.5] -- 2023-03-27
 ### Fixed
 - A [bug](https://github.com/pepkit/peppy/issues/435) with custom sample ids
@@ -33,8 +49,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 
 ## [0.35.2] -- 2022-09-13
 ### Fixed
-
 - Returning `NaN` value within `to_dict` method was fixed and method now returns `None` instead
+
 ## [0.35.1] -- 2022-09-07
 ### Changed
 - Organization of test files. Separated unittests from smoketests.
@@ -67,7 +83,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
 ### Changed 
 
 - Way of initialization project from dictionary. Now it's possible as follows: `Project().from_dict()`
-- 
+
 ### Fixed
 
 - Fix error that was raised when duplicated sample in `sample_table` had different read types (single-end mixed with paired-end).
diff --git a/docs/hello-world.md b/docs/hello-world.md
index d6cf503b..b8162e86 100644
--- a/docs/hello-world.md
+++ b/docs/hello-world.md
@@ -40,7 +40,7 @@ project = peppy.Project("example_basic/project_config.yaml") # instantiate in-me
 samples = project.samples # grab the list of Sample objects defined in this Project
 
 # Find the input file for the first sample in the project
-samples[0].file
+samples[0]["file"]
 ```
 
 That's it! You've got `peppy` running on an example project.
diff --git a/docs/img/format_convert.svg b/docs/img/format_convert.svg
new file mode 100644
index 00000000..bc08ce4e
--- /dev/null
+++ b/docs/img/format_convert.svg
@@ -0,0 +1,1275 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="62.425854mm"
+   height="43.717167mm"
+   viewBox="-3 -3 62.425854 43.717167"
+   version="1.1"
+   id="svg5"
+   inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
+   sodipodi:docname="format_conver.svg"
+   xml:space="preserve"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
+     id="namedview7"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0"
+     inkscape:pagecheckerboard="0"
+     inkscape:document-units="mm"
+     showgrid="false"
+     inkscape:zoom="1.6870196"
+     inkscape:cx="479.24754"
+     inkscape:cy="189.09087"
+     inkscape:window-width="2560"
+     inkscape:window-height="1370"
+     inkscape:window-x="3760"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1"
+     inkscape:snap-global="false"
+     inkscape:showpageshadow="2"
+     inkscape:deskcolor="#eeeeee"><inkscape:page
+       x="0"
+       y="0"
+       width="62.425854"
+       height="43.717167"
+       id="page106"
+       margin="2.0000002"
+       bleed="0" /></sodipodi:namedview><defs
+     id="defs2"><marker
+       inkscape:stockid="TriangleOutM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="TriangleOutM"
+       style="overflow:visible"><path
+         id="path4156"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
+         transform="scale(0.4)"
+         inkscape:connector-curvature="0" /></marker><linearGradient
+       id="linearGradient892-3-0"><stop
+         style="stop-color:#ffffff;stop-opacity:0.00000000;"
+         offset="0.00000000"
+         id="stop893-2-3" /><stop
+         style="stop-color:#fff;stop-opacity:1;"
+         offset="1"
+         id="stop894-2-1" /></linearGradient><linearGradient
+       x1="35"
+       x2="100"
+       y1="20"
+       gradientUnits="userSpaceOnUse"
+       y2="89"
+       id="linearGradient4492"><stop
+         offset="0"
+         stop-opacity=".75294"
+         stop-color="#00c0c0"
+         id="stop4488" /><stop
+         offset="1"
+         stop-opacity=".30196"
+         stop-color="#80f5f5"
+         id="stop4490" /></linearGradient><linearGradient
+       id="linearGradient3161"><stop
+         offset="0"
+         stop-color="#fff"
+         id="stop3163" /><stop
+         offset="1"
+         stop-opacity="0"
+         stop-color="#fff"
+         id="stop3165" /></linearGradient><linearGradient
+       gradientTransform="matrix(0.89839544,0,0,1.4262987,-2583.0381,2966.5502)"
+       id="linearGradient15378"
+       x1="285.47037"
+       x2="292.65842"
+       xlink:href="#linearGradient15251"
+       y1="108.87218"
+       y2="108.87218"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       id="linearGradient15251"><stop
+         id="stop15252"
+         offset="0"
+         stop-color="#11ffff" /><stop
+         id="stop15253"
+         offset="1"
+         stop-opacity="0"
+         stop-color="#e1ebff" /></linearGradient><linearGradient
+       gradientTransform="matrix(1.2750153,0,0,1.0049921,-2583.0381,2966.5502)"
+       id="linearGradient15379"
+       x1="239.22408"
+       x2="244.25108"
+       xlink:href="#linearGradient15251"
+       y1="186.81477"
+       y2="186.81477"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(1.148607,0,0,1.115595,-2583.0381,2966.5502)"
+       id="linearGradient15380"
+       x1="305.36746"
+       x2="311.97397"
+       xlink:href="#linearGradient15251"
+       y1="111.47942"
+       y2="111.47942"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(1.5031099,0,0,0.85248603,-2583.0381,2966.5502)"
+       id="linearGradient15383"
+       x1="266.74103"
+       x2="271.39532"
+       xlink:href="#linearGradient15251"
+       y1="270.58075"
+       y2="270.58075"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(1.149307,0,0,1.1149155,-2583.0381,2966.5502)"
+       id="linearGradient15384"
+       x1="169.62802"
+       x2="175.87711"
+       xlink:href="#linearGradient15251"
+       y1="212.56871"
+       y2="212.56871"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(0.9480899,0,0,1.3515387,-2583.0381,2966.5502)"
+       id="linearGradient15385"
+       x1="208.20387"
+       x2="215.18179"
+       xlink:href="#linearGradient15251"
+       y1="220.00958"
+       y2="220.00958"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(1.6080623,0,0,0.79684736,-2583.0381,2966.5502)"
+       id="linearGradient15386"
+       x1="216.48724"
+       x2="219.02859"
+       xlink:href="#linearGradient15251"
+       y1="264.51785"
+       y2="264.51785"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(1.847117,0,0,0.69371905,-2583.0381,2966.5502)"
+       id="linearGradient15387"
+       x1="184.40688"
+       x2="186.3316"
+       xlink:href="#linearGradient15251"
+       y1="529.10437"
+       y2="529.10437"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(0.92408916,0,0,1.3866413,-2583.0381,2966.5502)"
+       id="linearGradient15388"
+       x1="307.05576"
+       x2="315.26337"
+       xlink:href="#linearGradient15251"
+       y1="245.84831"
+       y2="245.84831"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(0.72507885,0,0,1.7672288,-2583.0381,2966.5502)"
+       id="linearGradient15389"
+       x1="622.69678"
+       x2="630.80371"
+       xlink:href="#linearGradient15251"
+       y1="168.36928"
+       y2="168.36928"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(0.93320216,0,0,1.3731004,-2583.0381,2966.5502)"
+       id="linearGradient15390"
+       x1="491.17938"
+       x2="495.96729"
+       xlink:href="#linearGradient15251"
+       y1="234.81921"
+       y2="234.81921"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(0.97200857,0,0,1.3182808,-2583.0381,2966.5502)"
+       id="linearGradient15391"
+       x1="527.91168"
+       x2="535.78436"
+       xlink:href="#linearGradient15251"
+       y1="225.18878"
+       y2="225.18878"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       gradientTransform="matrix(1.2300616,0,0,1.0417204,-2583.0381,2966.5502)"
+       id="linearGradient15392"
+       x1="204.62263"
+       x2="206.7001"
+       xlink:href="#linearGradient15251"
+       y1="238.44827"
+       y2="238.44827"
+       gradientUnits="userSpaceOnUse" /><linearGradient
+       id="E"><stop
+         stop-color="#2e3436"
+         id="R" /><stop
+         stop-opacity="0"
+         stop-color="#2e3436"
+         offset="1"
+         id="S" /></linearGradient><linearGradient
+       id="D"><stop
+         stop-color="#eeeeec"
+         id="P" /><stop
+         stop-color="#d3d7cf"
+         offset="1"
+         id="Q" /></linearGradient><filter
+       id="K"
+       height="1.302"
+       width="1.321"
+       y="-0.15099999"
+       x="-0.16"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         id="T"
+         stdDeviation="0.5327" /></filter><radialGradient
+       gradientTransform="matrix(2.6607075,0,0,0.21711748,-259.90161,564.66242)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#E"
+       id="F"
+       r="21.856001"
+       cy="48.735001"
+       cx="25.712" /><radialGradient
+       gradientTransform="matrix(1.5010936,6.2249964,-9.2108788,2.221111,-129.81603,374.91355)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="G"
+       r="16.219"
+       cy="12.06"
+       cx="13.559" /><linearGradient
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient892-3-0"
+       id="H"
+       y2="43.34"
+       x2="0"
+       y1="2.438"
+       gradientTransform="matrix(2.4311654,0,0,2.4311654,-249.83623,466.9785)" /><radialGradient
+       gradientTransform="matrix(4.8623306,5.0367582e-7,-5.2704226e-7,5.0879031,-332.79973,444.08618)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="I"
+       r="3.03"
+       cy="8.6090002"
+       cx="34.130001" /><linearGradient
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient892-3-0"
+       id="J"
+       y2="6.3629999"
+       x2="36.533001"
+       y1="8.75"
+       x1="34.130001"
+       gradientTransform="matrix(2.4311654,0,0,2.4311654,-249.83623,466.61717)" /><filter
+       id="K-0"
+       height="1.302"
+       width="1.321"
+       y="-0.15099999"
+       x="-0.16"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         id="T-0"
+         stdDeviation="0.5327" /></filter><radialGradient
+       gradientTransform="matrix(2.6607075,0,0,0.21711748,-281.84156,543.48915)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#E"
+       id="F-5"
+       r="21.856001"
+       cy="48.735001"
+       cx="25.712" /><radialGradient
+       gradientTransform="matrix(1.5010936,6.2249964,-9.2108788,2.221111,-151.75598,353.74028)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="G-3"
+       r="16.219"
+       cy="12.06"
+       cx="13.559" /><linearGradient
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient892-3-0"
+       id="H-7"
+       y2="43.34"
+       x2="0"
+       y1="2.438"
+       gradientTransform="matrix(2.4311654,0,0,2.4311654,-271.77618,445.80523)" /><radialGradient
+       gradientTransform="matrix(4.8623306,5.0367582e-7,-5.2704226e-7,5.0879031,-354.73969,422.91291)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="I-9"
+       r="3.03"
+       cy="8.6090002"
+       cx="34.130001" /><filter
+       id="K-0-3"
+       height="1.3019289"
+       width="1.3208734"
+       y="-0.15096442"
+       x="-0.1604367"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         id="T-0-5"
+         stdDeviation="0.5327" /></filter><radialGradient
+       gradientTransform="matrix(3.2895963,0,0,0.26843569,123.83968,345.41502)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#E"
+       id="F-5-6"
+       r="21.856001"
+       cy="48.735001"
+       cx="25.712" /><radialGradient
+       gradientTransform="matrix(1.8558945,7.6963458,-11.387976,2.746096,284.67246,110.81677)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="G-3-2"
+       r="16.219"
+       cy="12.06"
+       cx="13.559" /><linearGradient
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient892-3-0"
+       id="H-7-9"
+       y2="43.34"
+       x2="0"
+       y1="2.438"
+       gradientTransform="matrix(3.0057991,0,0,3.0057991,136.28408,224.64237)" /><filter
+       id="filter4619"
+       height="1.302"
+       width="1.321"
+       y="-0.15099999"
+       x="-0.16"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         id="feGaussianBlur4621"
+         stdDeviation="0.5327" /></filter><radialGradient
+       gradientTransform="matrix(6.0115982,6.2272537e-7,-6.5161475e-7,6.2904874,33.711276,196.33917)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="I-9-1"
+       r="3.03"
+       cy="8.6090002"
+       cx="34.130001" /><radialGradient
+       r="16.219"
+       cy="12.06"
+       cx="13.559"
+       gradientTransform="matrix(1.8558945,7.6963458,-11.387976,2.746096,848.22767,302.28895)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient5032"
+       xlink:href="#D"
+       inkscape:collect="always" /><linearGradient
+       y2="43.34"
+       x2="0"
+       y1="2.438"
+       gradientTransform="matrix(3.0057991,0,0,3.0057991,699.83932,416.11451)"
+       gradientUnits="userSpaceOnUse"
+       id="linearGradient5034"
+       xlink:href="#linearGradient892-3-0"
+       inkscape:collect="always" /><filter
+       id="K-2"
+       height="1.3019289"
+       width="1.3208734"
+       y="-0.15096442"
+       x="-0.1604367"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         id="T-7"
+         stdDeviation="0.5327" /></filter><radialGradient
+       r="3.03"
+       cy="8.6090002"
+       cx="34.130001"
+       gradientTransform="matrix(6.0115982,6.2272537e-7,-6.5161475e-7,6.2904874,597.26643,387.81133)"
+       gradientUnits="userSpaceOnUse"
+       id="radialGradient5036"
+       xlink:href="#D"
+       inkscape:collect="always" /><radialGradient
+       gradientTransform="matrix(1.8558945,7.6963458,-11.387976,2.746096,496.7991,197.14557)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="G-0"
+       r="16.219"
+       cy="12.06"
+       cx="13.559" /><linearGradient
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient892-3-0"
+       id="H-9"
+       y2="43.34"
+       x2="0"
+       y1="2.438"
+       gradientTransform="matrix(3.0057991,0,0,3.0057991,348.41075,310.9711)" /><filter
+       id="filter4688"
+       height="1.302"
+       width="1.321"
+       y="-0.15099999"
+       x="-0.16"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         id="feGaussianBlur4690"
+         stdDeviation="0.5327" /></filter><radialGradient
+       gradientTransform="matrix(6.0115982,6.2272537e-7,-6.5161475e-7,6.2904874,245.83788,282.66792)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#D"
+       id="I-3"
+       r="3.03"
+       cy="8.6090002"
+       cx="34.130001" /><linearGradient
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient892-3-0"
+       id="J-6"
+       y2="6.3629999"
+       x2="36.533001"
+       y1="8.75"
+       x1="34.130001"
+       gradientTransform="matrix(3.0057991,0,0,3.0057991,348.41075,310.52437)" /><linearGradient
+       gradientTransform="matrix(0.03158331,0,0,0.03188823,-57.888854,171.24765)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient4689"
+       id="linearGradient1478"
+       y2="114.39767"
+       x2="135.66525"
+       y1="20.603781"
+       x1="26.648937" /><linearGradient
+       id="linearGradient4689"><stop
+         id="stop4691"
+         offset="0"
+         style="stop-color:#5a9fd4;stop-opacity:1" /><stop
+         id="stop4693"
+         offset="1"
+         style="stop-color:#306998;stop-opacity:1" /></linearGradient><linearGradient
+       gradientTransform="matrix(0.03158331,0,0,0.03188823,-57.888854,171.24765)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient4671"
+       id="linearGradient1475"
+       y2="137.27299"
+       x2="112.03144"
+       y1="192.35176"
+       x1="150.96111" /><linearGradient
+       id="linearGradient4671"><stop
+         id="stop4673"
+         offset="0"
+         style="stop-color:#ffd43b;stop-opacity:1" /><stop
+         id="stop4675"
+         offset="1"
+         style="stop-color:#ffe873;stop-opacity:1" /></linearGradient><radialGradient
+       gradientTransform="matrix(0,-0.01347159,0.0592133,2.1287261e-8,-61.746494,179.90305)"
+       gradientUnits="userSpaceOnUse"
+       xlink:href="#linearGradient2795"
+       id="radialGradient1480"
+       fy="132.28575"
+       fx="61.518883"
+       r="29.036913"
+       cy="132.28575"
+       cx="61.518883" /><linearGradient
+       id="linearGradient2795"><stop
+         id="stop2797"
+         offset="0"
+         style="stop-color:#b8b8b8;stop-opacity:0.49803922" /><stop
+         id="stop2799"
+         offset="1"
+         style="stop-color:#7f7f7f;stop-opacity:0" /></linearGradient><linearGradient
+       gradientTransform="matrix(0.11494196,0,0,0.07697987,-1421.6662,392.76358)"
+       spreadMethod="pad"
+       gradientUnits="userSpaceOnUse"
+       y2="593.78699"
+       y1="3.6658268"
+       x2="590.86261"
+       x1="0.7414425"
+       id="gradientFill-1"><stop
+         id="stop7"
+         stop-opacity="1"
+         stop-color="rgb(203,206,208)"
+         offset="0" /><stop
+         id="stop9"
+         stop-opacity="1"
+         stop-color="rgb(132,131,139)"
+         offset="1" /></linearGradient><linearGradient
+       gradientTransform="matrix(0.09311939,0,0,0.09502015,-1421.6662,392.76358)"
+       spreadMethod="pad"
+       gradientUnits="userSpaceOnUse"
+       y2="553.44208"
+       y1="151.4006"
+       x2="703.0675"
+       x1="301.02603"
+       id="gradientFill-2"><stop
+         id="stop12"
+         stop-opacity="1"
+         stop-color="rgb(39,109,195)"
+         offset="0" /><stop
+         id="stop14"
+         stop-opacity="1"
+         stop-color="rgb(22,92,170)"
+         offset="1" /></linearGradient><radialGradient
+       inkscape:collect="always"
+       xlink:href="#D"
+       id="radialGradient6720"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.8558945,7.6963458,-11.387976,2.746096,848.22767,302.28895)"
+       cx="13.559"
+       cy="12.06"
+       r="16.219" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient892-3-0"
+       id="linearGradient6722"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(3.0057991,0,0,3.0057991,699.83932,416.11451)"
+       y1="2.438"
+       x2="0"
+       y2="43.34" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#D"
+       id="radialGradient6724"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(6.0115982,6.2272537e-7,-6.5161475e-7,6.2904874,597.26643,387.81133)"
+       cx="34.130001"
+       cy="8.6090002"
+       r="3.03" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#D"
+       id="radialGradient6730"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.8558945,7.6963458,-11.387976,2.746096,496.7991,197.14557)"
+       cx="13.559"
+       cy="12.06"
+       r="16.219" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient892-3-0"
+       id="linearGradient6732"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(3.0057991,0,0,3.0057991,348.41075,310.9711)"
+       y1="2.438"
+       x2="0"
+       y2="43.34" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#D"
+       id="radialGradient6734"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(6.0115982,6.2272537e-7,-6.5161475e-7,6.2904874,245.83788,282.66792)"
+       cx="34.130001"
+       cy="8.6090002"
+       r="3.03" /><style
+       id="style1">.cls-1{fill:#130754;}.cls-2{fill:#ffca00;}.cls-3{fill:#e70488;}</style><style
+       type="text/css"
+       id="style6">
+   
+    .fil1 {fill:none}
+    .fil0 {fill:black}
+   
+  </style></defs><g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-9.4672978,-6.5781827)"><g
+       id="g1768"
+       transform="matrix(1.7949691,0,0,1.7949691,-27.135218,-11.341666)" /><text
+       xml:space="preserve"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+       x="18.882563"
+       y="37.104298"
+       id="text5449"><tspan
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+         sodipodi:role="line"
+         x="18.882563"
+         y="37.104298"
+         id="tspan5451">PEP</tspan></text><text
+       xml:space="preserve"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:0%;font-family:Arial;-inkscape-font-specification:Arial;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:middle;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;marker:none;enable-background:accumulate"
+       x="36.528324"
+       y="31.389357"
+       id="text3805"><tspan
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:100%;font-family:mono;-inkscape-font-specification:mono;stroke-width:0.15072px"
+         id="tspan4559"
+         sodipodi:role="line"
+         x="36.528324"
+         y="31.389357">peppy.Project</tspan></text><g
+       inkscape:label="Layer 1"
+       id="layer1-6"
+       transform="matrix(0.14945875,0,0,0.14945875,-38.348967,-49.7154)"><g
+         id="g4180-7"
+         style="fill:#000000;fill-rule:evenodd;stroke:none"
+         transform="matrix(0.56420713,0,0,0.56420713,339.23445,559.72193)"><g
+           id="g4182-5"
+           transform="translate(-986,-742)"
+           style="fill:#000000"><g
+             style="fill:#000000"
+             id="g4184-3"
+             transform="translate(986,742)"><path
+               style="fill:#000000"
+               id="path4188-5"
+               d="M 30,50 C 18.972,50 10,41.028 10,30 c 0,-0.33 0.009,-0.664 0.025,-1 0.185,-0.001 0.359,-0.036 0.538,-0.057 0.151,-0.017 0.307,-0.018 0.454,-0.048 0.177,-0.037 0.34,-0.104 0.51,-0.159 0.142,-0.046 0.29,-0.076 0.425,-0.134 0.16,-0.068 0.304,-0.163 0.455,-0.247 0.131,-0.073 0.27,-0.132 0.393,-0.215 0.14,-0.095 0.26,-0.214 0.39,-0.322 0.116,-0.097 0.241,-0.182 0.348,-0.289 0.12,-0.121 0.218,-0.262 0.325,-0.394 0.094,-0.116 0.2,-0.222 0.284,-0.346 0.1,-0.147 0.172,-0.312 0.255,-0.469 0.068,-0.127 0.149,-0.246 0.205,-0.379 0.08,-0.188 0.128,-0.391 0.184,-0.59 0.033,-0.117 0.083,-0.226 0.107,-0.346 C 14.965,24.68 15,24.344 15,24 15,23.702 14.964,23.411 14.911,23.124 14.898,23.047 14.884,22.97 14.867,22.893 14.808,22.64 14.734,22.393 14.637,22.154 14.596,22.053 14.547,21.958 14.5,21.86 14.429,21.712 14.351,21.568 14.265,21.428 14.191,21.305 14.116,21.185 14.032,21.07 13.914,20.908 13.786,20.753 13.649,20.606 13.555,20.505 13.457,20.411 13.355,20.319 13.252,20.224 13.143,20.137 13.031,20.052 12.945,19.985 12.869,19.908 12.778,19.847 16.374,13.748 22.883,10 30,10 41.028,10 50,18.972 50,30 50,41.028 41.028,50 30,50 M 52,30 C 52,17.869 42.131,8 30,8 22.072,8 14.841,12.234 10.918,19.093 10.62,19.037 10.315,19 10,19 7.243,19 5,21.243 5,24 5,26.073 6.269,27.854 8.07,28.611 8.041,29.076 8,29.544 8,30 8,42.131 17.869,52 30,52 42.131,52 52,42.131 52,30"
+               inkscape:connector-curvature="0" /><path
+               style="fill:#000000"
+               id="path4190-6"
+               d="m 43.2881,54.6436 c -4.071,2.198 -8.646,3.356 -13.288,3.356 -15.44,0 -28,-12.56 -28,-28 0,-15.439 12.56,-28 28,-28 5.296,0 10.454,1.492 14.922,4.314 l 0.26,0.247 c -0.115,0.462 -0.182,0.943 -0.182,1.439 0,3.309 2.691,6 6,6 0.263,0 0.521,-0.022 0.775,-0.055 0.069,-0.009 0.136,-0.02 0.204,-0.032 0.219,-0.036 0.434,-0.083 0.645,-0.142 0.029,-0.008 0.06,-0.011 0.089,-0.02 l 0.255,0.244 c 3.292,4.714 5.032,10.247 5.032,16.005 0,7.001 -2.574,13.645 -7.269,18.811 -0.235,-0.154 -0.484,-0.28 -0.74,-0.392 -0.053,-0.022 -0.107,-0.039 -0.161,-0.06 -0.225,-0.089 -0.456,-0.161 -0.693,-0.216 -0.077,-0.018 -0.152,-0.036 -0.23,-0.051 -0.297,-0.054 -0.599,-0.092 -0.907,-0.092 -2.757,0 -5,2.244 -5,5 0,0.303 0.034,0.603 0.091,0.901 0.03,0.166 0.082,0.323 0.128,0.483 0.026,0.086 0.039,0.175 0.069,0.26 m 16.712,-24.644 c 0,-6.187 -1.877,-12.131 -5.424,-17.193 1.468,-1.095 2.424,-2.839 2.424,-4.807 0,-3.308 -2.691,-6 -6,-6 -2.068,0 -3.894,1.052 -4.974,2.648 -4.797,-3.04 -10.337,-4.648 -16.026,-4.648 -16.542,0 -30,13.458 -30,30 0,16.542 13.458,30 30,30 5.005,0 9.929,-1.27 14.311,-3.654 0.915,1.009 2.223,1.654 3.689,1.654 2.757,0 5,-2.243 5,-5 0,-1.031 -0.315,-1.991 -0.852,-2.788 5.066,-5.542 7.852,-12.682 7.852,-20.212"
+               inkscape:connector-curvature="0" /></g></g></g><path
+         inkscape:connector-curvature="0"
+         style="fill:#000000"
+         d="m 363.07286,583.10964 c 1.64873,-1.64873 1.64875,-4.31724 0,-5.96599 l -6.71633,-6.71632 c -0.99716,-0.99717 -2.36772,-1.38806 -3.66033,-1.17905 -0.0432,0.006 -0.0857,0.0112 -0.12771,0.0182 -0.0117,0.002 -0.0248,0.007 -0.0365,0.009 -0.65273,0.13194 -1.27922,0.41721 -1.82216,0.85976 -0.11095,0.0899 -0.21765,0.18574 -0.32156,0.28965 -1.64758,1.64758 -1.64875,4.32183 -2e-5,5.97056 l 6.71633,6.71633 c 1.64987,1.64761 4.3207,1.64528 5.96828,-0.002 z m -0.49943,-0.49943 c -1.36967,1.36967 -3.59744,1.36969 -4.96713,0 l -3.35932,-3.35932 4.96711,-4.96711 3.35932,3.35932 c 1.36969,1.36969 1.36967,3.59746 2e-5,4.96711 z m -10.48385,-6.65698 c -0.10043,0.13076 -0.30148,0.13602 -0.42876,0.0227 -0.0163,-0.014 -1.81286,-1.66965 -0.8963,-3.94311 0.014,-0.0397 0.0382,-0.0746 0.0662,-0.10262 0.0829,-0.0829 0.21392,-0.11514 0.32837,-0.0684 0.15764,0.0642 0.23183,0.24037 0.16876,0.39683 -0.76014,1.88344 0.72485,3.24948 0.74124,3.26354 0.12489,0.11322 0.13375,0.30605 0.0205,0.43104 z"
+         id="path4220-2" /><ellipse
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
+         id="path4248"
+         cx="344.8399"
+         cy="573.29431"
+         rx="2.3967094"
+         ry="2.3335748" /><circle
+         r="2.3335748"
+         cy="589.61456"
+         cx="366.30563"
+         id="circle4250"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate" /><circle
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
+         id="circle4252"
+         cx="367.95255"
+         cy="564.29224"
+         r="2.9017856" /></g><g
+       id="g5"
+       transform="translate(-84.088873,-96.148211)"><path
+         inkscape:connector-curvature="0"
+         d="m 119.9132,116.99157 c -0.25734,0.001 -0.5031,0.0231 -0.71934,0.0614 -0.63702,0.11254 -0.75268,0.34809 -0.75268,0.7825 v 0.57372 h 1.50536 v 0.19124 h -1.50536 -0.56495 c -0.4375,0 -0.82059,0.26297 -0.94041,0.76321 -0.13822,0.5734 -0.14435,0.93121 0,1.52993 0.107,0.44566 0.36255,0.7632 0.80005,0.76321 h 0.51758 v -0.68777 c 0,-0.49687 0.4299,-0.93515 0.94041,-0.93515 h 1.50361 c 0.41855,0 0.75268,-0.34462 0.75268,-0.76496 v -1.43343 c 0,-0.40796 -0.34417,-0.71442 -0.75268,-0.7825 -0.2586,-0.0431 -0.52692,-0.0626 -0.78427,-0.0614 z m -0.81408,0.46143 c 0.15549,0 0.28247,0.12906 0.28247,0.28774 0,0.15812 -0.12698,0.28598 -0.28247,0.28598 -0.15606,0 -0.28248,-0.12786 -0.28248,-0.28598 0,-0.15868 0.12642,-0.28774 0.28248,-0.28774 z"
+         style="fill:url(#linearGradient1478);fill-opacity:1;stroke-width:0.056144"
+         id="path1948" /><path
+         inkscape:connector-curvature="0"
+         d="m 121.63788,118.60044 v 0.66847 c 0,0.51825 -0.43938,0.95445 -0.94041,0.95445 h -1.50361 c -0.41187,0 -0.75268,0.3525 -0.75268,0.76496 v 1.43343 c 0,0.40796 0.35475,0.64792 0.75268,0.76496 0.47651,0.14011 0.93346,0.16544 1.50361,0 0.37898,-0.10973 0.75268,-0.33055 0.75268,-0.76496 v -0.57372 h -1.50361 v -0.19124 h 1.50361 0.75268 c 0.4375,0 0.60053,-0.30517 0.75268,-0.76321 0.15716,-0.47155 0.15048,-0.92502 0,-1.52993 -0.10812,-0.43553 -0.31463,-0.76321 -0.75268,-0.76321 z m -0.84567,3.63007 c 0.15605,0 0.28247,0.12786 0.28247,0.28598 0,0.15868 -0.12642,0.28774 -0.28247,0.28774 -0.1555,0 -0.28248,-0.12906 -0.28248,-0.28774 0,-0.15812 0.12698,-0.28598 0.28248,-0.28598 z"
+         style="fill:url(#linearGradient1475);fill-opacity:1;stroke-width:0.056144"
+         id="path1950" /><path
+         inkscape:connector-curvature="0"
+         d="m 121.98093,124.16115 a 2.01731,0.39117323 0 1 1 -4.03462,0 2.01731,0.39117323 0 1 1 4.03462,0 z"
+         style="opacity:0.44382;fill:url(#radialGradient1480);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0432797"
+         id="path1894" /></g><g
+       id="g84"
+       transform="translate(-6.9158927,-3.9270914)"><text
+         id="text4527"
+         y="20.763296"
+         x="19.629797"
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:0%;font-family:Arial;-inkscape-font-specification:Arial;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;marker:none;enable-background:accumulate"
+         xml:space="preserve"><tspan
+           style="font-size:2.11667px;line-height:1.25;stroke-width:0.15072px"
+           id="tspan4529"
+           y="20.763296"
+           x="19.629797"
+           sodipodi:role="line">DataFrame</tspan></text><g
+         id="g2"
+         transform="matrix(0.01902873,0,0,0.01902873,14.694541,14.244532)"><path
+           class="cls-1"
+           d="m 290.85,199.21 c -10.27,0 -20.73,-4.25 -27.28,-12.58 v 45 H 243 V 120.54 h 18.6 l 0.71,12.22 c 6.38,-9.39 17.71,-14.35 28.52,-14.35 20.73,0 36,17.37 36,40.4 0,23.03 -15.25,40.41 -35.98,40.4 z m -6.37,-65.55 c -12.05,0 -21.79,9.39 -21.79,25.16 0,15.77 9.74,25.18 21.79,25.18 12.05,0 21.79,-9.39 21.79,-25.16 0,-15.77 -9.74,-25.18 -21.79,-25.18 z"
+           id="path1" /><path
+           class="cls-1"
+           d="m 404.36,197.1 -0.71,-12.22 c -6.38,9.39 -17.72,14.35 -28.53,14.34 -20.73,0 -36,-17.36 -36,-40.39 0,-23.03 15.24,-40.4 36,-40.39 10.81,0 22.15,5 28.53,14.35 l 0.71,-12.22 H 423 v 76.53 z m -22.85,-63.43 c -12.05,0 -21.79,9.39 -21.8,25.16 -0.01,15.77 9.74,25.17 21.79,25.17 12.05,0 21.8,-9.39 21.8,-25.16 0,-15.77 -9.74,-25.17 -21.79,-25.17 z"
+           id="path2" /><path
+           class="cls-1"
+           d="m 494.87,197.11 v -42.34 c 0,-14.88 -5.13,-19.84 -14.52,-19.84 -9.75,0 -20.38,8.85 -20.38,19.48 v 42.7 h -20.56 v -76.54 h 18.79 l 0.89,14.18 c 5.14,-9.75 16.65,-16.3 28.35,-16.3 20.37,0 28,14.18 28,33.13 v 45.54 z"
+           id="path3" /><path
+           class="cls-1"
+           d="m 590.77,197.13 -0.71,-12.23 c -6.38,9.39 -17.72,14.35 -28.52,14.35 -20.73,0 -36,-17.37 -36,-40.4 0,-23.03 15.24,-40.39 36,-40.39 10.27,0 20.72,4.26 27.28,12.58 V 90.83 h 20.56 v 106.3 z M 567.92,133.7 c -12,0 -21.79,9.39 -21.79,25.15 0,15.76 9.74,25.15 21.79,25.15 12.05,0 21.79,-9.38 21.79,-25.15 0,-15.77 -9.71,-25.15 -21.79,-25.15 z"
+           id="path4-67" /><path
+           class="cls-1"
+           d="m 686.6,197.14 -0.71,-12.22 c -6.38,9.39 -17.72,14.34 -28.53,14.34 -20.73,0 -36,-17.36 -36,-40.4 0,-23.04 15.24,-40.39 36,-40.39 10.81,0 22.15,5 28.53,14.36 l 0.71,-12.23 h 18.6 v 76.53 z m -22.85,-63.43 c -12,0 -21.79,9.39 -21.8,25.16 -0.01,15.77 9.75,25.13 21.79,25.13 12.04,0 21.8,-9.39 21.8,-25.16 0,-15.77 -9.74,-25.13 -21.79,-25.13 z"
+           id="path5" /><path
+           class="cls-1"
+           d="m 750.73,199.63 a 60.16,60.16 0 0 1 -30.65,-8.69 l 3.37,-14.17 c 6.2,3.72 15.59,8.51 26.93,8.51 8.15,0 13.82,-2.48 13.82,-8.86 0,-5.49 -5.85,-7.44 -16.3,-9.92 -18.78,-4.08 -25.51,-14 -25.51,-24.81 0,-12.05 9.39,-23.38 30.12,-23.38 12.58,0 23.57,5.49 26,6.91 l -3.37,13.47 A 44.59,44.59 0 0 0 753,132.31 c -8.32,0 -12.4,2.83 -12.4,7.44 0,5.13 5.32,7.44 13.46,9.39 20.2,4.25 28.35,13.64 28.35,23.92 0.04,16.47 -12.01,26.57 -31.68,26.57 z"
+           id="path6-53" /><rect
+           class="cls-1"
+           x="74.879997"
+           y="68.419998"
+           width="24.09"
+           height="50.02"
+           id="rect6-5" /><rect
+           class="cls-1"
+           x="74.879997"
+           y="171.17"
+           width="24.09"
+           height="50.02"
+           id="rect7" /><rect
+           class="cls-2"
+           x="74.879997"
+           y="133.03999"
+           width="24.09"
+           height="23.6"
+           id="rect8-6" /><rect
+           class="cls-1"
+           x="36.189999"
+           y="109.55"
+           width="24.09"
+           height="166.27"
+           id="rect9" /><rect
+           class="cls-1"
+           x="112.78"
+           y="212.44"
+           width="24.09"
+           height="50.02"
+           id="rect10-2" /><rect
+           class="cls-1"
+           x="112.78"
+           y="109.61"
+           width="24.09"
+           height="50.02"
+           id="rect11" /><rect
+           class="cls-3"
+           x="112.78"
+           y="174.23"
+           width="24.09"
+           height="23.6"
+           id="rect12-9" /><rect
+           class="cls-1"
+           x="150.67"
+           y="55.389999"
+           width="24.09"
+           height="166.27"
+           id="rect13" /></g></g><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g3"
+       transform="matrix(0.12915609,0.0745683,-0.0745683,0.12915609,24.569288,16.119439)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path6051"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       id="g98"
+       transform="translate(-6.9158927,-3.9270914)"><g
+         id="g4"
+         transform="matrix(0.01238786,0,0,0.01238786,15.484692,23.793841)"><polygon
+           id="Y"
+           points="143.978,137.674 143.978,224.949 87.702,224.949 87.702,137.674 0,0 63.25,0 119.018,88.646 175.243,0 235.793,0 " /><path
+           id="A"
+           fill="#cb171e"
+           d="M 330.294,175.451 H 228.433 l -20.717,50.024 H 162.61 L 257.99,0.526 h 46.137 l 91.51,224.949 h -48.2 l -17.144,-50.024 z m -16.92,-44.911 -31.226,-82.55 -34.837,82.55 z" /><polygon
+           id="M"
+           points="135.004,318.569 184.509,420.789 221.743,420.789 272.939,314.976 272.939,470.602 318.318,470.602 318.318,250.177 256.358,250.177 201.381,349.883 149.021,250.177 87.701,250.177 87.701,470.647 135.004,470.647 " /><polygon
+           id="L"
+           points="512,422.737 512,422.735 395.638,422.735 395.638,250.125 347.442,250.125 347.442,469.647 512,469.647 " /></g><text
+         id="text4"
+         y="26.14957"
+         x="25.727568"
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+         xml:space="preserve"><tspan
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+           id="tspan4"
+           y="26.14957"
+           x="25.727568"
+           sodipodi:role="line">samples</tspan><tspan
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+           y="28.795408"
+           x="25.727568"
+           sodipodi:role="line"
+           id="tspan21">YAML</tspan></text></g><text
+       xml:space="preserve"
+       style="font-size:3.52778px;line-height:1.25;font-family:arial;-inkscape-font-specification:'arial, Normal';text-decoration:none;text-decoration-line:none;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#000000;stroke-width:0.264583"
+       x="8.7711296"
+       y="8.1482258"
+       id="text5"><tspan
+         sodipodi:role="line"
+         id="tspan5"
+         style="font-size:3.52778px;stroke-width:0.264583"
+         x="8.7711296"
+         y="8.1482258">Input formats</tspan></text><text
+       xml:space="preserve"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52778px;line-height:1.25;font-family:arial;-inkscape-font-specification:'arial, Normal';font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;white-space:normal;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1"
+       x="43.697308"
+       y="8.1482258"
+       id="text6"><tspan
+         sodipodi:role="line"
+         id="tspan6"
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.52778px;line-height:1.25;font-family:arial;-inkscape-font-specification:'arial, Normal';font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1"
+         x="43.697308"
+         y="8.1482258">Output formats</tspan></text><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g6"
+       transform="matrix(0.1440549,-0.03859939,-0.03859939,-0.1440549,24.089209,37.356232)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path6"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g7"
+       transform="matrix(0.1491366,0,0,-0.1491366,23.557434,31.04603)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path7"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       id="g1768-6"
+       transform="matrix(1.7949691,0,0,1.7949691,185.00225,8.44766)" /><g
+       id="g7834"
+       transform="matrix(0.16140361,0,0,0.16140361,10.277418,27.270242)"><g
+         id="g7799"
+         transform="translate(-115.83488,-67.066169)"><rect
+           style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;stroke:#000000;stroke-width:1.70391;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+           id="rect4316-4"
+           width="36.296738"
+           height="27.656088"
+           x="121.50172"
+           y="69.676781" /><g
+           id="g7714"
+           transform="translate(0.39446045,-0.57180636)"><path
+             inkscape:connector-curvature="0"
+             id="path4483-8"
+             d="m 125.2588,73.035809 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,73.035809 h 5.69105"
+             id="path4485-9"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,73.035809 h 4.12505"
+             id="path4487-2"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,85.183195 h 9.92365"
+             id="path4489-6"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path4491-6"
+             d="m 139.57663,85.183195 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4493-4"
+             d="m 149.1274,85.183195 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4495-9"
+             d="m 125.2588,82.753714 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,82.753714 h 5.69105"
+             id="path4497-5"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,82.753714 h 4.12505"
+             id="path4499-0"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,80.324233 h 9.92365"
+             id="path4501-4"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path4503-8"
+             d="m 139.57663,80.324233 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4505-7"
+             d="m 149.1274,80.324233 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4507-1"
+             d="m 125.2588,77.894761 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,77.894761 h 5.69105"
+             id="path4509-7"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,77.894761 h 4.12505"
+             id="path4511-2"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,75.46528 h 9.92365"
+             id="path4513-7"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path4515-2"
+             d="m 139.57663,75.46528 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4517-2"
+             d="m 149.1274,75.46528 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4519-6"
+             d="m 125.2588,87.612666 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,87.612666 h 5.69105"
+             id="path4521-1"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,87.612666 h 4.12505"
+             id="path4523-0"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,90.042147 h 9.92365"
+             id="path4525-6"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path4527-1"
+             d="m 139.57663,90.042147 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4529-5"
+             d="m 149.1274,90.042147 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path4531-9"
+             d="m 125.2588,92.471618 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,92.471618 h 5.69105"
+             id="path4533-4"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,92.471618 h 4.12505"
+             id="path4535-9"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path7678"
+             d="m 125.2588,95.117453 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,95.117453 h 5.69105"
+             id="path7680"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,95.117453 h 4.12505"
+             id="path7682"
+             inkscape:connector-curvature="0" /></g></g></g><text
+       id="text33"
+       y="30.685396"
+       x="20.249443"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+       xml:space="preserve"><tspan
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+         y="30.685396"
+         x="20.249443"
+         sodipodi:role="line"
+         id="tspan33">CSV</tspan></text><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g34"
+       transform="matrix(0.12915609,-0.0745683,-0.0745683,-0.12915609,24.569288,43.393317)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path34"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><path
+       d="m 18.035324,42.063685 c -0.03026,-0.04545 -0.06246,-0.0895 -0.09612,-0.132366 -0.380679,-0.485045 -0.971942,-0.796673 -1.637025,-0.796673 v 0 c -0.665789,0 -1.257533,0.312293 -1.638172,0.798115 -0.0336,0.0429 -0.06576,0.08699 -0.09601,0.132477 -0.21861,0.329305 -0.346171,0.724443 -0.346171,1.14976 v 0 c 0,0.425316 0.127561,0.820417 0.346171,1.149723 0.03021,0.04549 0.06243,0.08965 0.09601,0.132477 0.380678,0.485896 0.972383,0.798152 1.638172,0.798152 v -0.0068 0 0.0068 c 0.665083,0 1.256307,-0.311701 1.637025,-0.796599 0.03365,-0.0429 0.06587,-0.08699 0.09616,-0.132403 0.219277,-0.329602 0.347205,-0.725368 0.347205,-1.151313 v -3.7e-5 c -3.4e-5,-0.426019 -0.127962,-0.821712 -0.347245,-1.151313 z m -2.227803,-0.69016 c -0.189694,0.196497 -0.343693,0.502799 -0.439114,0.874414 -0.216099,-0.05444 -0.406676,-0.128741 -0.560121,-0.218242 0.25049,-0.315401 0.598882,-0.548918 0.999235,-0.656172 z m -1.095877,0.788907 c 0.171756,0.103481 0.382233,0.188767 0.619263,0.250382 -0.04434,0.221608 -0.06891,0.462115 -0.06891,0.71383 h -0.864572 c 0.01624,-0.355639 0.12959,-0.685611 0.314213,-0.964212 z m -0.31462,1.134116 h 0.864979 v 0 0 c 0,5.39e-4 0,10e-4 0,0.0015 v 0.0085 h 1.13e-4 c 4.91e-4,0.250567 0.0255,0.48989 0.07012,0.710352 -0.237584,0.06169 -0.448542,0.147086 -0.620592,0.250715 -0.185804,-0.280413 -0.299531,-0.612826 -0.31462,-0.971053 z m 0.411262,1.103751 c 0.153852,-0.08972 0.345022,-0.164172 0.561823,-0.218649 0.09712,0.374833 0.254006,0.682392 0.446953,0.877372 -0.404346,-0.10607 -0.756251,-0.340808 -1.008776,-0.658723 z m 1.405838,0.705582 c -0.295358,-0.06236 -0.546588,-0.435302 -0.678808,-0.96092 0.209664,-0.04038 0.438629,-0.06291 0.678808,-0.06306 z m 0,-1.197358 c -0.25253,2.23e-4 -0.493665,0.02515 -0.71564,0.07001 -0.04061,-0.210625 -0.06313,-0.440628 -0.06313,-0.68195 v 0 h 0.778775 z m 0,-0.781917 h -0.778776 c 0,-0.238806 0.02212,-0.466516 0.06187,-0.675329 0.222388,0.04504 0.463929,0.07005 0.716901,0.07024 z m 0,-0.77844 c -0.240807,-1.81e-4 -0.470326,-0.02278 -0.680436,-0.06343 0.131813,-0.529019 0.383857,-0.904851 0.680436,-0.967465 z m 1.992809,0.77844 h -0.864577 c 0,-0.251972 -0.02462,-0.492738 -0.06909,-0.714531 0.236882,-0.06187 0.447138,-0.147345 0.618595,-0.250974 0.185103,0.278822 0.298791,0.609312 0.315067,0.965505 z m -0.41189,-1.098166 c -0.153116,0.08965 -0.343399,0.164134 -0.559311,0.218796 -0.09542,-0.371282 -0.249347,-0.677288 -0.438928,-0.873711 0.399872,0.107069 0.747857,0.340143 0.998239,0.654915 z m -1.410978,-0.712166 c 0.299124,0.05873 0.553725,0.435562 0.686459,0.967947 -0.211807,0.04112 -0.443402,0.06398 -0.686459,0.06398 z m 0,1.205273 c 0.255227,0 0.49884,-0.02529 0.722964,-0.0709 0.03983,0.208959 0.06198,0.436892 0.06198,0.67592 h -0.784946 z m 0,0.775001 h 0.784946 v 0 c 0,0.241543 -0.02261,0.471768 -0.06324,0.682541 -0.223756,-0.04546 -0.466961,-0.07064 -0.721708,-0.07064 z m 0,1.810332 v -1.02505 c 0.242469,0 0.47347,0.02275 0.68487,0.06372 -0.133216,0.528946 -0.386962,0.902891 -0.68487,0.961326 z m 0.403164,-0.04789 c 0.192833,-0.194832 0.349609,-0.502095 0.4468,-0.876633 0.21658,0.0547 0.407491,0.12937 0.561014,0.219242 -0.252378,0.317249 -0.603949,0.551506 -1.007814,0.657391 z m 1.104599,-0.790016 c -0.171791,-0.103888 -0.382489,-0.189469 -0.619925,-0.251307 0.04474,-0.220684 0.06964,-0.460266 0.07026,-0.711166 h 1.42e-4 v -0.0085 c 0,-4.47e-4 0,-9.41e-4 0,-0.0014 v 0 0 h 0.864946 c -0.01506,0.358782 -0.129077,0.691712 -0.315435,0.972421 z"
+       id="path1-1"
+       style="stroke-width:0.036984" /><text
+       id="text34"
+       y="43.828514"
+       x="21.029636"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+       xml:space="preserve"><tspan
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+         y="43.828514"
+         x="21.029636"
+         sodipodi:role="line"
+         id="tspan34">URL</tspan></text><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g35"
+       transform="matrix(0.1440549,0.03859939,-0.03859939,0.1440549,24.089209,22.156524)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path35"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       id="g67"
+       transform="matrix(0.16140361,0,0,0.16140361,50.306004,31.358409)"><g
+         id="g66"
+         transform="translate(-115.83488,-67.066169)"><rect
+           style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;stroke:#000000;stroke-width:1.70391;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
+           id="rect35"
+           width="36.296738"
+           height="27.656088"
+           x="121.50172"
+           y="69.676781" /><g
+           id="g65"
+           transform="translate(0.39446045,-0.57180636)"><path
+             inkscape:connector-curvature="0"
+             id="path36"
+             d="m 125.2588,73.035809 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,73.035809 h 5.69105"
+             id="path37"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,73.035809 h 4.12505"
+             id="path38"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,85.183195 h 9.92365"
+             id="path39"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path40"
+             d="m 139.57663,85.183195 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path41"
+             d="m 149.1274,85.183195 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path42"
+             d="m 125.2588,82.753714 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,82.753714 h 5.69105"
+             id="path43"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,82.753714 h 4.12505"
+             id="path44"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,80.324233 h 9.92365"
+             id="path45"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path46"
+             d="m 139.57663,80.324233 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path47"
+             d="m 149.1274,80.324233 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path48"
+             d="m 125.2588,77.894761 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,77.894761 h 5.69105"
+             id="path49"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,77.894761 h 4.12505"
+             id="path50"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,75.46528 h 9.92365"
+             id="path51"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path52"
+             d="m 139.57663,75.46528 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path53"
+             d="m 149.1274,75.46528 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path54"
+             d="m 125.2588,87.612666 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,87.612666 h 5.69105"
+             id="path55"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,87.612666 h 4.12505"
+             id="path56"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 125.2588,90.042147 h 9.92365"
+             id="path57"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path58"
+             d="m 139.57663,90.042147 h 5.69105"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path59"
+             d="m 149.1274,90.042147 h 4.12505"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             inkscape:connector-curvature="0"
+             id="path60"
+             d="m 125.2588,92.471618 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,92.471618 h 5.69105"
+             id="path61"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,92.471618 h 4.12505"
+             id="path62"
+             inkscape:connector-curvature="0" /><path
+             inkscape:connector-curvature="0"
+             id="path63"
+             d="m 125.2588,95.117453 h 9.92365"
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 139.57663,95.117453 h 5.69105"
+             id="path64"
+             inkscape:connector-curvature="0" /><path
+             style="fill:#4d4d4d;stroke:#666666;stroke-width:1.21474px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+             d="m 149.1274,95.117453 h 4.12505"
+             id="path65"
+             inkscape:connector-curvature="0" /></g></g></g><text
+       id="text67"
+       y="34.773567"
+       x="60.27803"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+       xml:space="preserve"><tspan
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+         y="34.773567"
+         x="60.27803"
+         sodipodi:role="line"
+         id="tspan67">CSV</tspan></text><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g68"
+       transform="matrix(0.12915609,-0.0745683,-0.0745683,-0.12915609,45.735956,24.340199)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path67"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g69"
+       transform="matrix(0.1440549,0.03859939,-0.03859939,0.1440549,45.255877,31.708527)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path68"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g71"
+       transform="matrix(0.12915609,0.0745683,-0.0745683,0.12915609,45.735956,37.289225)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path70"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       style="clip-rule:evenodd;fill-rule:evenodd;image-rendering:optimizeQuality;shape-rendering:geometricPrecision;text-rendering:geometricPrecision"
+       id="g72"
+       transform="matrix(0.1440549,-0.03859939,-0.03859939,-0.1440549,45.255877,29.920897)"><path
+         style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 13.466794,0.999996 v 5.22559 H 0.999997 v 4.841788 h 12.466797 v 5.227543 L 20.08984,12.470699 26.71093,8.64648 20.08984,4.824214 Z"
+         id="path71"
+         inkscape:connector-curvature="0"
+         sodipodi:nodetypes="cccccccccc" /></g><g
+       id="g97"
+       transform="translate(35.428201,1.3410864)"><text
+         id="text84"
+         y="20.763296"
+         x="19.629797"
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:0%;font-family:Arial;-inkscape-font-specification:Arial;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;marker:none;enable-background:accumulate"
+         xml:space="preserve"><tspan
+           style="font-size:2.11667px;line-height:1.25;stroke-width:0.15072px"
+           id="tspan84"
+           y="20.763296"
+           x="19.629797"
+           sodipodi:role="line">DataFrame</tspan></text><g
+         id="g96"
+         transform="matrix(0.01902873,0,0,0.01902873,14.694541,14.244532)"><path
+           class="cls-1"
+           d="m 290.85,199.21 c -10.27,0 -20.73,-4.25 -27.28,-12.58 v 45 H 243 V 120.54 h 18.6 l 0.71,12.22 c 6.38,-9.39 17.71,-14.35 28.52,-14.35 20.73,0 36,17.37 36,40.4 0,23.03 -15.25,40.41 -35.98,40.4 z m -6.37,-65.55 c -12.05,0 -21.79,9.39 -21.79,25.16 0,15.77 9.74,25.18 21.79,25.18 12.05,0 21.79,-9.39 21.79,-25.16 0,-15.77 -9.74,-25.18 -21.79,-25.18 z"
+           id="path84" /><path
+           class="cls-1"
+           d="m 404.36,197.1 -0.71,-12.22 c -6.38,9.39 -17.72,14.35 -28.53,14.34 -20.73,0 -36,-17.36 -36,-40.39 0,-23.03 15.24,-40.4 36,-40.39 10.81,0 22.15,5 28.53,14.35 l 0.71,-12.22 H 423 v 76.53 z m -22.85,-63.43 c -12.05,0 -21.79,9.39 -21.8,25.16 -0.01,15.77 9.74,25.17 21.79,25.17 12.05,0 21.8,-9.39 21.8,-25.16 0,-15.77 -9.74,-25.17 -21.79,-25.17 z"
+           id="path85" /><path
+           class="cls-1"
+           d="m 494.87,197.11 v -42.34 c 0,-14.88 -5.13,-19.84 -14.52,-19.84 -9.75,0 -20.38,8.85 -20.38,19.48 v 42.7 h -20.56 v -76.54 h 18.79 l 0.89,14.18 c 5.14,-9.75 16.65,-16.3 28.35,-16.3 20.37,0 28,14.18 28,33.13 v 45.54 z"
+           id="path86" /><path
+           class="cls-1"
+           d="m 590.77,197.13 -0.71,-12.23 c -6.38,9.39 -17.72,14.35 -28.52,14.35 -20.73,0 -36,-17.37 -36,-40.4 0,-23.03 15.24,-40.39 36,-40.39 10.27,0 20.72,4.26 27.28,12.58 V 90.83 h 20.56 v 106.3 z M 567.92,133.7 c -12,0 -21.79,9.39 -21.79,25.15 0,15.76 9.74,25.15 21.79,25.15 12.05,0 21.79,-9.38 21.79,-25.15 0,-15.77 -9.71,-25.15 -21.79,-25.15 z"
+           id="path87" /><path
+           class="cls-1"
+           d="m 686.6,197.14 -0.71,-12.22 c -6.38,9.39 -17.72,14.34 -28.53,14.34 -20.73,0 -36,-17.36 -36,-40.4 0,-23.04 15.24,-40.39 36,-40.39 10.81,0 22.15,5 28.53,14.36 l 0.71,-12.23 h 18.6 v 76.53 z m -22.85,-63.43 c -12,0 -21.79,9.39 -21.8,25.16 -0.01,15.77 9.75,25.13 21.79,25.13 12.04,0 21.8,-9.39 21.8,-25.16 0,-15.77 -9.74,-25.13 -21.79,-25.13 z"
+           id="path88" /><path
+           class="cls-1"
+           d="m 750.73,199.63 a 60.16,60.16 0 0 1 -30.65,-8.69 l 3.37,-14.17 c 6.2,3.72 15.59,8.51 26.93,8.51 8.15,0 13.82,-2.48 13.82,-8.86 0,-5.49 -5.85,-7.44 -16.3,-9.92 -18.78,-4.08 -25.51,-14 -25.51,-24.81 0,-12.05 9.39,-23.38 30.12,-23.38 12.58,0 23.57,5.49 26,6.91 l -3.37,13.47 A 44.59,44.59 0 0 0 753,132.31 c -8.32,0 -12.4,2.83 -12.4,7.44 0,5.13 5.32,7.44 13.46,9.39 20.2,4.25 28.35,13.64 28.35,23.92 0.04,16.47 -12.01,26.57 -31.68,26.57 z"
+           id="path89" /><rect
+           class="cls-1"
+           x="74.879997"
+           y="68.419998"
+           width="24.09"
+           height="50.02"
+           id="rect89" /><rect
+           class="cls-1"
+           x="74.879997"
+           y="171.17"
+           width="24.09"
+           height="50.02"
+           id="rect90" /><rect
+           class="cls-2"
+           x="74.879997"
+           y="133.03999"
+           width="24.09"
+           height="23.6"
+           id="rect91" /><rect
+           class="cls-1"
+           x="36.189999"
+           y="109.55"
+           width="24.09"
+           height="166.27"
+           id="rect92" /><rect
+           class="cls-1"
+           x="112.78"
+           y="212.44"
+           width="24.09"
+           height="50.02"
+           id="rect93" /><rect
+           class="cls-1"
+           x="112.78"
+           y="109.61"
+           width="24.09"
+           height="50.02"
+           id="rect94" /><rect
+           class="cls-3"
+           x="112.78"
+           y="174.23"
+           width="24.09"
+           height="23.6"
+           id="rect95" /><rect
+           class="cls-1"
+           x="150.67"
+           y="55.389999"
+           width="24.09"
+           height="166.27"
+           id="rect96" /></g></g><g
+       id="g101"
+       transform="translate(34.566767,0.08292345)"><g
+         id="g100"
+         transform="matrix(0.01238786,0,0,0.01238786,15.484692,23.793841)"><polygon
+           id="polygon98"
+           points="87.702,224.949 87.702,137.674 0,0 63.25,0 119.018,88.646 175.243,0 235.793,0 143.978,137.674 143.978,224.949 " /><path
+           id="path98"
+           fill="#cb171e"
+           d="M 330.294,175.451 H 228.433 l -20.717,50.024 H 162.61 L 257.99,0.526 h 46.137 l 91.51,224.949 h -48.2 l -17.144,-50.024 z m -16.92,-44.911 -31.226,-82.55 -34.837,82.55 z" /><polygon
+           id="polygon99"
+           points="87.701,470.647 135.004,470.647 135.004,318.569 184.509,420.789 221.743,420.789 272.939,314.976 272.939,470.602 318.318,470.602 318.318,250.177 256.358,250.177 201.381,349.883 149.021,250.177 87.701,250.177 " /><polygon
+           id="polygon100"
+           points="347.442,250.125 347.442,469.647 512,469.647 512,422.737 512,422.735 395.638,422.735 395.638,250.125 " /></g><text
+         id="text101"
+         y="26.14957"
+         x="25.727568"
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+         xml:space="preserve"><tspan
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+           id="tspan100"
+           y="26.14957"
+           x="25.727568"
+           sodipodi:role="line">samples</tspan><tspan
+           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:center;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:middle;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+           y="28.795408"
+           x="25.727568"
+           sodipodi:role="line"
+           id="tspan101">YAML</tspan></text></g><text
+       xml:space="preserve"
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;display:inline;overflow:visible;visibility:visible;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+       x="56.855858"
+       y="41.524033"
+       id="text102"><tspan
+         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.11667px;line-height:1.25;font-family:Arial;-inkscape-font-specification:Arial;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:0px;word-spacing:0px;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;white-space:normal;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.15072px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;marker:none;stop-color:#000000;stop-opacity:1"
+         sodipodi:role="line"
+         x="56.855858"
+         y="41.524033"
+         id="tspan102">PEP</tspan></text><g
+       inkscape:label="Layer 1"
+       id="g106"
+       transform="matrix(0.14945875,0,0,0.14945875,-0.37567185,-45.295666)"><g
+         id="g105"
+         style="fill:#000000;fill-rule:evenodd;stroke:none"
+         transform="matrix(0.56420713,0,0,0.56420713,339.23445,559.72193)"><g
+           id="g104"
+           transform="translate(-986,-742)"
+           style="fill:#000000"><g
+             style="fill:#000000"
+             id="g103"
+             transform="translate(986,742)"><path
+               style="fill:#000000"
+               id="path102"
+               d="M 30,50 C 18.972,50 10,41.028 10,30 c 0,-0.33 0.009,-0.664 0.025,-1 0.185,-0.001 0.359,-0.036 0.538,-0.057 0.151,-0.017 0.307,-0.018 0.454,-0.048 0.177,-0.037 0.34,-0.104 0.51,-0.159 0.142,-0.046 0.29,-0.076 0.425,-0.134 0.16,-0.068 0.304,-0.163 0.455,-0.247 0.131,-0.073 0.27,-0.132 0.393,-0.215 0.14,-0.095 0.26,-0.214 0.39,-0.322 0.116,-0.097 0.241,-0.182 0.348,-0.289 0.12,-0.121 0.218,-0.262 0.325,-0.394 0.094,-0.116 0.2,-0.222 0.284,-0.346 0.1,-0.147 0.172,-0.312 0.255,-0.469 0.068,-0.127 0.149,-0.246 0.205,-0.379 0.08,-0.188 0.128,-0.391 0.184,-0.59 0.033,-0.117 0.083,-0.226 0.107,-0.346 C 14.965,24.68 15,24.344 15,24 15,23.702 14.964,23.411 14.911,23.124 14.898,23.047 14.884,22.97 14.867,22.893 14.808,22.64 14.734,22.393 14.637,22.154 14.596,22.053 14.547,21.958 14.5,21.86 14.429,21.712 14.351,21.568 14.265,21.428 14.191,21.305 14.116,21.185 14.032,21.07 13.914,20.908 13.786,20.753 13.649,20.606 13.555,20.505 13.457,20.411 13.355,20.319 13.252,20.224 13.143,20.137 13.031,20.052 12.945,19.985 12.869,19.908 12.778,19.847 16.374,13.748 22.883,10 30,10 41.028,10 50,18.972 50,30 50,41.028 41.028,50 30,50 M 52,30 C 52,17.869 42.131,8 30,8 22.072,8 14.841,12.234 10.918,19.093 10.62,19.037 10.315,19 10,19 7.243,19 5,21.243 5,24 5,26.073 6.269,27.854 8.07,28.611 8.041,29.076 8,29.544 8,30 8,42.131 17.869,52 30,52 42.131,52 52,42.131 52,30"
+               inkscape:connector-curvature="0" /><path
+               style="fill:#000000"
+               id="path103"
+               d="m 43.2881,54.6436 c -4.071,2.198 -8.646,3.356 -13.288,3.356 -15.44,0 -28,-12.56 -28,-28 0,-15.439 12.56,-28 28,-28 5.296,0 10.454,1.492 14.922,4.314 l 0.26,0.247 c -0.115,0.462 -0.182,0.943 -0.182,1.439 0,3.309 2.691,6 6,6 0.263,0 0.521,-0.022 0.775,-0.055 0.069,-0.009 0.136,-0.02 0.204,-0.032 0.219,-0.036 0.434,-0.083 0.645,-0.142 0.029,-0.008 0.06,-0.011 0.089,-0.02 l 0.255,0.244 c 3.292,4.714 5.032,10.247 5.032,16.005 0,7.001 -2.574,13.645 -7.269,18.811 -0.235,-0.154 -0.484,-0.28 -0.74,-0.392 -0.053,-0.022 -0.107,-0.039 -0.161,-0.06 -0.225,-0.089 -0.456,-0.161 -0.693,-0.216 -0.077,-0.018 -0.152,-0.036 -0.23,-0.051 -0.297,-0.054 -0.599,-0.092 -0.907,-0.092 -2.757,0 -5,2.244 -5,5 0,0.303 0.034,0.603 0.091,0.901 0.03,0.166 0.082,0.323 0.128,0.483 0.026,0.086 0.039,0.175 0.069,0.26 m 16.712,-24.644 c 0,-6.187 -1.877,-12.131 -5.424,-17.193 1.468,-1.095 2.424,-2.839 2.424,-4.807 0,-3.308 -2.691,-6 -6,-6 -2.068,0 -3.894,1.052 -4.974,2.648 -4.797,-3.04 -10.337,-4.648 -16.026,-4.648 -16.542,0 -30,13.458 -30,30 0,16.542 13.458,30 30,30 5.005,0 9.929,-1.27 14.311,-3.654 0.915,1.009 2.223,1.654 3.689,1.654 2.757,0 5,-2.243 5,-5 0,-1.031 -0.315,-1.991 -0.852,-2.788 5.066,-5.542 7.852,-12.682 7.852,-20.212"
+               inkscape:connector-curvature="0" /></g></g></g><path
+         inkscape:connector-curvature="0"
+         style="fill:#000000"
+         d="m 363.07286,583.10964 c 1.64873,-1.64873 1.64875,-4.31724 0,-5.96599 l -6.71633,-6.71632 c -0.99716,-0.99717 -2.36772,-1.38806 -3.66033,-1.17905 -0.0432,0.006 -0.0857,0.0112 -0.12771,0.0182 -0.0117,0.002 -0.0248,0.007 -0.0365,0.009 -0.65273,0.13194 -1.27922,0.41721 -1.82216,0.85976 -0.11095,0.0899 -0.21765,0.18574 -0.32156,0.28965 -1.64758,1.64758 -1.64875,4.32183 -2e-5,5.97056 l 6.71633,6.71633 c 1.64987,1.64761 4.3207,1.64528 5.96828,-0.002 z m -0.49943,-0.49943 c -1.36967,1.36967 -3.59744,1.36969 -4.96713,0 l -3.35932,-3.35932 4.96711,-4.96711 3.35932,3.35932 c 1.36969,1.36969 1.36967,3.59746 2e-5,4.96711 z m -10.48385,-6.65698 c -0.10043,0.13076 -0.30148,0.13602 -0.42876,0.0227 -0.0163,-0.014 -1.81286,-1.66965 -0.8963,-3.94311 0.014,-0.0397 0.0382,-0.0746 0.0662,-0.10262 0.0829,-0.0829 0.21392,-0.11514 0.32837,-0.0684 0.15764,0.0642 0.23183,0.24037 0.16876,0.39683 -0.76014,1.88344 0.72485,3.24948 0.74124,3.26354 0.12489,0.11322 0.13375,0.30605 0.0205,0.43104 z"
+         id="path105" /><ellipse
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
+         id="ellipse105"
+         cx="344.8399"
+         cy="573.29431"
+         rx="2.3967094"
+         ry="2.3335748" /><circle
+         r="2.3335748"
+         cy="589.61456"
+         cx="366.30563"
+         id="circle105"
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate" /><circle
+         style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ff0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;enable-background:accumulate"
+         id="circle106"
+         cx="367.95255"
+         cy="564.29224"
+         r="2.9017856" /></g></g></svg>
diff --git a/docs/initialize.md b/docs/initialize.md
new file mode 100644
index 00000000..f8d74632
--- /dev/null
+++ b/docs/initialize.md
@@ -0,0 +1,91 @@
+# How to initiate peppy using different methods
+
+The primary use case of `peppy` is to create a `peppy.Project` object, which will give you an API for interacting with your project and sample metadata. There are multiple ways to instantiate a `peppy.Project`. 
+The most common is to use a configuration file; however, you can also use a `CSV` file (sample sheet), or a sample `YAML` file (sample sheet), or use Python objects directly, such as a `pandas` DataFrame, or a Python `dict`.
+
+
+<figure>
+<img src="../img/format_convert.svg" width="475">
+<figcaption>peppy can read from and produce various metadata formats</figcaption>
+</figure>
+
+
+## 1. From PEP configuration file
+
+```python
+import peppy
+project = peppy.Project.from_pep_config("path/to/project/config.yaml")
+```
+
+## 2. FROM `CSV` file (sample sheet)
+
+```python
+import peppy
+project = peppy.Project.from_pep_config("path/to/project/sample_sheet.csv")
+```
+
+You can also instantiate directly from a URL to a CSV file:
+
+```python
+import peppy
+project = peppy.Project("https://raw.githubusercontent.com/pepkit/example_peps/master/example_basic/sample_table.csv")
+```
+
+
+## 3. From `YAML` sample sheet
+
+```python
+import peppy
+
+project = peppy.Project.from_sample_yaml("path/to/project/sample_sheet.yaml")
+```
+
+
+## 4. From a `pandas` DataFrame
+
+```python
+import pandas as pd
+import peppy
+df = pd.read_csv("path/to/project/sample_sheet.csv")
+project = peppy.Project.from_pandas(df)
+```
+
+## 5. From a `peppy`-generated `dict`
+
+Store a `peppy.Project` object as a dict using `prj.to_dict()`. Then, load it with `Project.from_dict()`:
+
+```python
+import peppy
+
+project = peppy.Project("https://raw.githubusercontent.com/pepkit/example_peps/master/example_basic/sample_table.csv")
+project_dict = project.to_dict(extended=True)
+project_copy = peppy.Project.from_dict(project_dict)
+
+# now you can check if this project is the same as the original project
+print(project_copy == project)
+```
+
+Or, you could generate an equivalent dictionary in some other way:
+
+
+```python
+import peppy
+project = peppy.Project.from_dict(
+    {'_config': {'description': None,
+                 'name': 'example_basic',
+                 'pep_version': '2.0.0',
+                 'sample_table': 'sample_table.csv',},
+    '_sample_dict': [{'organism': 'pig', 'sample_name': 'pig_0h', 'time': '0'},
+                     {'organism': 'pig', 'sample_name': 'pig_1h', 'time': '1'},
+                     {'organism': 'frog', 'sample_name': 'frog_0h', 'time': '0'},
+                     {'organism': 'frog', 'sample_name': 'frog_1h', 'time': '1'}],
+    '_subsample_list': [[{'read1': 'frog1a_data.txt',
+                       'read2': 'frog1a_data2.txt',
+                       'sample_name': 'frog_0h'},
+                      {'read1': 'frog1b_data.txt',
+                       'read2': 'frog1b_data2.txt',
+                       'sample_name': 'pig_0h'},
+                      {'read1': 'frog1c_data.txt',
+                       'read2': 'frog1b_data2.txt',
+                       'sample_name': 'pig_0h'}]]})
+```
diff --git a/mkdocs.yml b/mkdocs.yml
index 0eea2c95..c2989c63 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -8,6 +8,7 @@ nav:
     - Introduction: README.md
     - Installing and Hello World: hello-world.md
   - How-to Guides:
+    - How to initialize a Project: initialize.md
     - How to use peppy: tutorial.md
     - How to use subsample table: feature4_subsample_table.md
     - How to use amendments: feature5_amend.md
diff --git a/peppy/_version.py b/peppy/_version.py
index c83377ec..da7ed90a 100644
--- a/peppy/_version.py
+++ b/peppy/_version.py
@@ -1,1 +1,1 @@
-__version__ = "0.35.7"
+__version__ = "0.40.0"
diff --git a/peppy/parsers.py b/peppy/parsers.py
index 7276a6d0..961d6e17 100644
--- a/peppy/parsers.py
+++ b/peppy/parsers.py
@@ -1,7 +1,9 @@
+import os
 from typing import Any, Dict, List
-from .exceptions import InvalidSampleTableFileException
+
 import pandas as pd
-import os
+
+from .exceptions import InvalidSampleTableFileException
 
 
 class TableParser:
diff --git a/peppy/project.py b/peppy/project.py
index 665d4b25..66e35fa7 100644
--- a/peppy/project.py
+++ b/peppy/project.py
@@ -1,23 +1,21 @@
 """
 Build a Project object.
 """
-import math
-import os, sys
-from collections.abc import Mapping
+import os
+import sys
+from collections.abc import Mapping, MutableMapping
 from contextlib import suppress
 from logging import getLogger
-from typing import Dict, Iterable, List, Tuple, Union, Literal, NoReturn
+from typing import Iterable, List, Tuple, Union, Literal, NoReturn
 
 import numpy as np
 import pandas as pd
-from attmap import PathExAttMap
+import yaml
 from pandas.core.common import flatten
-from rich.progress import track
 from rich.console import Console
+from rich.progress import track
 from ubiquerg import is_url
 
-from peppy.sample import Sample
-
 from .const import (
     ACTIVE_AMENDMENTS_KEY,
     AMENDMENTS_KEY,
@@ -61,13 +59,16 @@
     SUBSAMPLE_TABLE_INDEX_KEY,
     SUBSAMPLE_TABLES_FILE_KEY,
 )
-from .exceptions import *
+from .exceptions import (
+    InvalidSampleTableFileException,
+    MissingAmendmentError,
+    IllegalStateException,
+    InvalidConfigFileException,
+)
 from .parsers import select_parser
 from .sample import Sample
 from .utils import (
     copy,
-    extract_custom_index_for_sample_table,
-    extract_custom_index_for_subsample_table,
     is_cfg_or_anno,
     load_yaml,
     make_abs_via_cfg,
@@ -78,7 +79,7 @@
 
 
 @copy
-class Project(PathExAttMap):
+class Project(MutableMapping):
     """
     A class to model a Project (collection of samples and metadata).
 
@@ -114,6 +115,7 @@ def __init__(
                 self.__class__.__name__, " from file {}".format(cfg) if cfg else ""
             )
         )
+        self._project_data = {}
         super(Project, self).__init__()
         is_cfg = is_cfg_or_anno(cfg)
         if is_cfg is None:
@@ -156,9 +158,6 @@ def __init__(
             or [SAMPLE_NAME_ATTR, SUBSAMPLE_NAME_ATTR]
         )
 
-        self.name = self.infer_name()
-        self.description = self.get_description()
-
         if not defer_samples_creation:
             self.create_samples(modify=False if self[SAMPLE_TABLE_FILE_KEY] else True)
         self._sample_table = self._get_table_from_samples(
@@ -170,41 +169,60 @@ def __eq__(self, other):
             s.to_dict() for s in other.samples
         ]
 
+    @classmethod
     def from_pandas(
-        self,
+        cls,
         samples_df: pd.DataFrame,
         sub_samples_df: List[pd.DataFrame] = None,
         config: dict = None,
-    ) -> "Project":
+    ):
         """
         Init a peppy project instance from a pandas Dataframe
+
         :param samples_df: in-memory pandas DataFrame object of samples
         :param sub_samples_df: in-memory list of pandas DataFrame objects of sub-samples
         :param config: dict of yaml file
         """
+        tmp_obj = cls()
         if not config:
             config = {CONFIG_VERSION_KEY: PEP_LATEST_VERSION}
-        self[SAMPLE_DF_KEY] = samples_df.replace(np.nan, "")
-        self[SUBSAMPLE_DF_KEY] = sub_samples_df
+        tmp_obj[SAMPLE_DF_KEY] = samples_df.replace(np.nan, "")
+        tmp_obj[SUBSAMPLE_DF_KEY] = sub_samples_df
 
-        self[SAMPLE_DF_LARGE] = self[SAMPLE_DF_KEY].shape[0] > 1000
+        tmp_obj[SAMPLE_DF_LARGE] = tmp_obj[SAMPLE_DF_KEY].shape[0] > 1000
 
-        self[CONFIG_KEY] = config
+        tmp_obj[CONFIG_KEY] = config
 
-        self.create_samples(modify=False if self[SAMPLE_TABLE_FILE_KEY] else True)
-        self._sample_table = self._get_table_from_samples(
-            index=self.st_index, initial=True
+        tmp_obj.create_samples(modify=False if tmp_obj[SAMPLE_TABLE_FILE_KEY] else True)
+        tmp_obj._sample_table = tmp_obj._get_table_from_samples(
+            index=tmp_obj.st_index, initial=True
         )
-        return self
+        return tmp_obj
 
-    def from_dict(self, pep_dictionary: dict) -> "Project":
+    @classmethod
+    def from_dict(cls, pep_dictionary: dict):
         """
         Init a peppy project instance from a dictionary representation
         of an already processed PEP.
-        :param dict pep_dictionary: in-memory dict representation of pep.
+
+        :param Dict[Any] pep_dictionary: dict representation of the project {_config: dict,
+                                                                             _samples: list | dict,
+                                                                             _subsamples: list[list | dict]}
+        """
+        _LOGGER.info("Processing project from dictionary...")
+        temp_obj = cls()
+        return temp_obj._from_dict(pep_dictionary)
+
+    def _from_dict(self, pep_dictionary) -> "Project":
         """
-        _LOGGER.info(f"Processing project from dictionary...")
+        Initiate a peppy project instance from a dictionary representation of an already processed PEP.
 
+        # This function is needed in looper to reinit the project after it was created from a dictionary representation.
+
+        :param Dict[Any] pep_dictionary: dict representation of the project {_config: dict,
+                                                                             _samples: list | dict,
+                                                                             _subsamples: list[list | dict]}
+        """
         self[SAMPLE_DF_KEY] = pd.DataFrame(pep_dictionary[SAMPLE_RAW_DICT_KEY])
         self[CONFIG_KEY] = pep_dictionary[CONFIG_KEY]
 
@@ -215,10 +233,10 @@ def from_dict(self, pep_dictionary: dict) -> "Project":
                     for sub_a in pep_dictionary[SUBSAMPLE_RAW_LIST_KEY]
                 ]
         if NAME_KEY in self[CONFIG_KEY]:
-            self[NAME_KEY] = self[CONFIG_KEY][NAME_KEY]
+            self.name = self[CONFIG_KEY][NAME_KEY]
 
         if DESC_KEY in self[CONFIG_KEY]:
-            self[DESC_KEY] = self[CONFIG_KEY][DESC_KEY]
+            self.description = self[CONFIG_KEY][DESC_KEY]
 
         self._set_indexes(self[CONFIG_KEY])
 
@@ -229,9 +247,53 @@ def from_dict(self, pep_dictionary: dict) -> "Project":
 
         return self
 
+    @classmethod
+    def from_pep_config(
+        cls,
+        cfg: str = None,
+        amendments: Union[str, Iterable[str]] = None,
+        sample_table_index: Union[str, Iterable[str]] = None,
+        subsample_table_index: Union[str, Iterable[str]] = None,
+        defer_samples_creation: bool = False,
+    ):
+        """
+        Init a peppy project instance from a yaml file
+
+        :param str cfg: Project config file (YAML) or sample table (CSV/TSV)
+            with one row per sample to constitute project
+        :param str | Iterable[str] sample_table_index: name of the columns to set
+            the sample_table index to
+        :param str | Iterable[str] subsample_table_index: name of the columns to set
+            the subsample_table index to
+        :param str | Iterable[str] amendments: names of the amendments to activate
+        :param Iterable[str] amendments: amendments to use within configuration file
+        :param bool defer_samples_creation: whether the sample creation should be skipped
+        """
+        # TODO: this is just a copy of the __init__ method. It should be refactored
+        return cls(
+            cfg=cfg,
+            amendments=amendments,
+            sample_table_index=sample_table_index,
+            subsample_table_index=subsample_table_index,
+            defer_samples_creation=defer_samples_creation,
+        )
+
+    @classmethod
+    def from_sample_yaml(cls, yaml_file: str):
+        """
+        Init a peppy project instance from a yaml file
+
+        :param str yaml_file: path to yaml file
+        """
+        _LOGGER.info("Processing project from yaml...")
+        with open(yaml_file, "r") as f:
+            prj_dict = yaml.safe_load(f)
+        pd_df = pd.DataFrame.from_dict(prj_dict)
+        return cls.from_pandas(pd_df)
+
     def to_dict(
         self,
-        expand: bool = False,
+        # expand: bool = False, # expand was used to expand paths. This functionality was removed, because of attmapp
         extended: bool = False,
         orient: Literal[
             "dict", "list", "series", "split", "tight", "records", "index"
@@ -240,7 +302,6 @@ def to_dict(
         """
         Convert the Project object to a dictionary.
 
-        :param bool expand: whether to expand the paths
         :param bool extended: whether to produce complete project dict (used to reinit the project)
         :param Literal orient: orientation of the returned df
         :return dict: a dictionary representation of the Project object
@@ -252,15 +313,18 @@ def to_dict(
                 ]
             else:
                 sub_df = None
-            self[CONFIG_KEY][NAME_KEY] = self[NAME_KEY]
-            self[CONFIG_KEY][DESC_KEY] = self[DESC_KEY]
+            try:
+                self[CONFIG_KEY][NAME_KEY] = self.name
+            except NotImplementedError:
+                self[CONFIG_KEY][NAME_KEY] = "unnamed"
+            self[CONFIG_KEY][DESC_KEY] = self.description
             p_dict = {
                 SAMPLE_RAW_DICT_KEY: self[SAMPLE_DF_KEY].to_dict(orient=orient),
-                CONFIG_KEY: self[CONFIG_KEY].to_dict(expand=expand),
+                CONFIG_KEY: dict(self[CONFIG_KEY]),
                 SUBSAMPLE_RAW_LIST_KEY: sub_df,
             }
         else:
-            p_dict = self.config.to_dict(expand=expand)
+            p_dict = self.config.copy()
             p_dict["_samples"] = [s.to_dict() for s in self.samples]
 
         return p_dict
@@ -271,7 +335,7 @@ def create_samples(self, modify: bool = False):
         """
         self._samples: List[Sample] = self.load_samples()
         if self.samples is None:
-            _LOGGER.info("No samples found in the project.")
+            _LOGGER.debug("No samples found in the project.")
 
         if modify:
             self.modify_samples()
@@ -283,9 +347,13 @@ def _reinit(self):
         """
         Clear all object attributes and initialize again
         """
-        cfg_path = self[CONFIG_FILE_KEY] if CONFIG_FILE_KEY in self else None
-        for attr in self.keys():
-            del self[attr]
+        if hasattr(self, "config_file"):
+            cfg_path = getattr(self, "config_file")
+        else:
+            cfg_path = None
+        obj_attributes = self.__dict__.copy().keys()
+        for attr in obj_attributes:
+            delattr(self, attr)
         self.__init__(cfg=cfg_path)
 
     def _get_table_from_samples(self, index, initial=False):
@@ -301,7 +369,10 @@ def _get_table_from_samples(self, index, initial=False):
             # (there is no chance of manual sample edits)
             # and no sample_modifiers section is defined in the config,
             # then we can simply reuse the previously read anno sheet.
-            df = self[SAMPLE_DF_KEY] if hasattr(self, SAMPLE_DF_KEY) else pd.DataFrame()
+            if SAMPLE_DF_KEY in self:
+                df = self[SAMPLE_DF_KEY]
+            else:
+                df = pd.DataFrame()
         else:
             df = pd.DataFrame.from_dict([s.to_dict() for s in self.samples])
         index = [index] if isinstance(index, str) else index
@@ -328,7 +399,7 @@ def parse_config_file(
         :raises KeyError: if config file lacks required section(s)
         """
         if CONFIG_KEY not in self:
-            self[CONFIG_KEY] = PathExAttMap()
+            self[CONFIG_KEY] = {}
         if not os.path.exists(cfg_path) and not is_url(cfg_path):
             raise OSError(f"Project config file path does not exist: {cfg_path}")
         config = load_yaml(cfg_path)
@@ -339,7 +410,7 @@ def parse_config_file(
             config, type(config)
         )
 
-        _LOGGER.debug("Raw ({}) config data: {}".format(cfg_path, config))
+        _LOGGER.debug(f"Raw ({cfg_path}) config data: {config}")
 
         self._set_indexes(config)
         # recursively import configs
@@ -363,7 +434,7 @@ def parse_config_file(
                         "External Project configuration does not" " exist: {}".format(i)
                     )
 
-        self[CONFIG_KEY].add_entries(config)
+        self[CONFIG_KEY].update(**config)
         # Parse yaml into the project.config attributes
         _LOGGER.debug("Adding attributes: {}".format(", ".join(config)))
         # Overwrite any config entries with entries in the amendments
@@ -384,7 +455,7 @@ def parse_config_file(
                             amendment, c[PROJ_MODS_KEY][AMENDMENTS_KEY]
                         )
                     _LOGGER.debug("Updating with: {}".format(amends))
-                    self[CONFIG_KEY].add_entries(amends)
+                    self[CONFIG_KEY].update(**amends)
                     _LOGGER.info("Using amendments: {}".format(amendment))
                 else:
                     raise MissingAmendmentError(amendment)
@@ -448,13 +519,14 @@ def modify_samples(self):
         Perform any sample modifications defined in the config.
         """
         if self._modifier_exists():
+            # check for unrecognizable modification keys
             mod_diff = set(self[CONFIG_KEY][SAMPLE_MODS_KEY].keys()) - set(
                 SAMPLE_MODIFIERS
             )
             if len(mod_diff) > 0:
                 _LOGGER.warning(
-                    "Config '{}' section contains unrecognized "
-                    "subsections: {}".format(SAMPLE_MODS_KEY, mod_diff)
+                    f"Config '{SAMPLE_MODS_KEY}' section contains unrecognized "
+                    f"subsections: {mod_diff}"
                 )
         self.attr_remove()
         self.attr_constants()
@@ -496,7 +568,7 @@ def _del_if_in(obj, attr):
 
         if self._modifier_exists(REMOVE_KEY):
             to_remove = self[CONFIG_KEY][SAMPLE_MODS_KEY][REMOVE_KEY]
-            _LOGGER.debug("Removing attributes: {}".format(to_remove))
+            _LOGGER.debug(f"Removing attributes: {to_remove}")
             for s in track(
                 self.samples,
                 description="Removing sample attributes",
@@ -531,7 +603,7 @@ def attr_synonyms(self):
         """
         if self._modifier_exists(DUPLICATED_KEY):
             synonyms = self[CONFIG_KEY][SAMPLE_MODS_KEY][DUPLICATED_KEY]
-            _LOGGER.debug("Applying synonyms: {}".format(synonyms))
+            _LOGGER.debug(f"Applying synonyms: {synonyms}")
             for sample in track(
                 self.samples,
                 description="Applying synonymous sample attributes",
@@ -540,7 +612,7 @@ def attr_synonyms(self):
             ):
                 for attr, new in synonyms.items():
                     if attr in sample:
-                        setattr(sample, new, getattr(sample, attr))
+                        sample[new] = sample[attr]
                     else:
                         _LOGGER.warning(
                             f"The sample attribute to duplicate not found: {attr}"
@@ -571,12 +643,12 @@ def _assert_samples_have_names(self):
                 )
                 if self.st_index != SAMPLE_NAME_ATTR:
                     try:
-                        custom_sample_name = getattr(sample, self.st_index)
-                    except AttributeError:
+                        custom_sample_name = sample[self.st_index]
+                    except KeyError:
                         raise InvalidSampleTableFileException(
                             f"Specified {CFG_SAMPLE_TABLE_KEY} index ({self.st_index}) does not exist"
                         )
-                    setattr(sample, SAMPLE_NAME_ATTR, custom_sample_name)
+                    sample[SAMPLE_NAME_ATTR] = custom_sample_name
                     _LOGGER.warning(
                         message
                         + f"using specified {CFG_SAMPLE_TABLE_KEY} index ({self.st_index}) instead. "
@@ -592,14 +664,15 @@ def _auto_merge_duplicated_names(self):
         :raises IllegalStateException: if both duplicated samples are detected and subsample_table is
             specified in the config
         """
-        sample_names_list = [getattr(s, self.st_index) for s in self.samples]
+        sample_names_list = [s[self.st_index] for s in self.samples]
         duplicated_sample_ids = self._get_duplicated_sample_ids(sample_names_list)
 
         if not duplicated_sample_ids:
             return
 
         _LOGGER.info(
-            f"Found {len(duplicated_sample_ids)} samples with non-unique names: {duplicated_sample_ids}. Attempting to auto-merge."
+            f"Found {len(duplicated_sample_ids)} samples with non-unique names: {duplicated_sample_ids}. "
+            f"Attempting to auto-merge."
         )
         if SUBSAMPLE_DF_KEY in self and self[SUBSAMPLE_DF_KEY] is not None:
             raise IllegalStateException(
@@ -679,7 +752,7 @@ def _get_merged_attributes(
         for attr in sample_attributes:
             attribute_values = []
             for sample in duplicated_samples:
-                attribute_value_for_sample = getattr(sample, attr, "")
+                attribute_value_for_sample = sample.get(attr, "")
                 attribute_values.append(attribute_value_for_sample)
 
             merged_attributes[attr] = list(flatten(attribute_values))
@@ -750,12 +823,10 @@ def _select_new_attval(merged_attrs, attname, attval):
 
                     for attname, attval in rowdata.items():
                         if attname == sample_colname or not attval:
-                            _LOGGER.debug("Skipping KV: {}={}".format(attname, attval))
+                            _LOGGER.debug(f"Skipping KV: {attname}={attval}")
                             continue
                         _LOGGER.debug(
-                            "merge: sample '{}'; '{}'='{}'".format(
-                                sample[self.st_index], attname, attval
-                            )
+                            f"merge: sample '{sample[self.st_index]}'; '{attname}'='{attval}'"
                         )
                         merged_attrs[attname] = _select_new_attval(
                             merged_attrs, attname, attval
@@ -765,7 +836,7 @@ def _select_new_attval(merged_attrs, attname, attval):
                 merged_attrs.pop(sample_colname, None)
 
                 _LOGGER.debug(
-                    "Updating Sample {}: {}".format(sample[self.st_index], merged_attrs)
+                    f"Updating Sample {sample[self.st_index]}: {merged_attrs}"
                 )
                 sample.update(merged_attrs)
 
@@ -782,17 +853,13 @@ def attr_imply(self):
         implications = self[CONFIG_KEY][SAMPLE_MODS_KEY][IMPLIED_KEY]
         if not isinstance(implications, list):
             raise InvalidConfigFileException(
-                "{}.{} has to be a list of key-value pairs".format(
-                    SAMPLE_MODS_KEY, IMPLIED_KEY
-                )
+                f"{SAMPLE_MODS_KEY}.{IMPLIED_KEY} has to be a list of key-value pairs"
             )
-        _LOGGER.debug("Sample attribute implications: {}".format(implications))
+        _LOGGER.debug(f"Sample attribute implications: {implications}")
         for implication in implications:
             if not all([key in implication for key in IMPLIED_COND_KEYS]):
                 raise InvalidConfigFileException(
-                    "{}.{} section is invalid: {}".format(
-                        SAMPLE_MODS_KEY, IMPLIED_KEY, implication
-                    )
+                    f"{SAMPLE_MODS_KEY}.{IMPLIED_KEY} section is invalid: {implication}"
                 )
         for sample in track(
             self.samples,
@@ -803,24 +870,19 @@ def attr_imply(self):
             for implication in implications:
                 implier_attrs = list(implication[IMPLIED_IF_KEY].keys())
                 implied_attrs = list(implication[IMPLIED_THEN_KEY].keys())
-                _LOGGER.debug(
-                    "Setting Sample attributes implied by '{}'".format(implier_attrs)
-                )
+                _LOGGER.debug(f"Setting Sample attributes implied by '{implier_attrs}'")
                 for implier_attr in implier_attrs:
                     implier_val = implication[IMPLIED_IF_KEY][implier_attr]
                     if implier_attr not in sample:
                         _LOGGER.debug(
-                            "Sample lacks implier attr ({}), "
-                            "skipping:".format(implier_attr)
+                            f"Sample lacks implier attr ({implier_attr}), skipping:"
                         )
                         break
                     sample_val = sample[implier_attr]
                     if sample_val not in implier_val:
                         _LOGGER.debug(
                             "Sample attr value does not match any of implier "
-                            "requirements ({} not in {}), skipping".format(
-                                sample_val, implier_val
-                            )
+                            f"requirements ({sample_val} not in {implier_val}), skipping"
                         )
                         break
                 else:
@@ -828,9 +890,7 @@ def attr_imply(self):
                     for implied_attr in implied_attrs:
                         imp_val = implication[IMPLIED_THEN_KEY][implied_attr]
                         _LOGGER.debug(
-                            "Setting implied attr: '{}={}'".format(
-                                implied_attr, imp_val
-                            )
+                            f"Setting implied attr: '{implied_attr}={imp_val}'"
                         )
                         sample.__setitem__(implied_attr, imp_val)
 
@@ -851,29 +911,26 @@ def attr_derive(self, attrs=None):
             console=Console(file=sys.stderr),
         ):
             for attr in derivations:
-                if not hasattr(sample, attr):
-                    _LOGGER.debug("sample lacks '{}' attribute".format(attr))
+                if attr not in sample:
+                    _LOGGER.debug(f"sample lacks '{attr}' attribute")
                     continue
                 elif attr in sample._derived_cols_done:
-                    _LOGGER.debug("'{}' has been derived".format(attr))
+                    _LOGGER.debug(f"'{attr}' has been derived")
                     continue
                 _LOGGER.debug(
-                    "Deriving '{}' attribute for '{}'".format(
-                        attr, sample[self.st_index]
-                    )
+                    f"Deriving '{attr}' attribute for '{sample[self.st_index]}'"
                 )
 
                 # Set {atr}_key, so the original source can also be retrieved
-                setattr(sample, ATTR_KEY_PREFIX + attr, getattr(sample, attr))
+                sample[ATTR_KEY_PREFIX + attr] = sample[attr]
 
                 derived_attr = sample.derive_attribute(ds, attr)
                 if derived_attr:
                     _LOGGER.debug("Setting '{}' to '{}'".format(attr, derived_attr))
-                    setattr(sample, attr, derived_attr)
+                    sample[attr] = derived_attr
                 else:
                     _LOGGER.debug(
-                        "Not setting null/empty value for data source"
-                        " '{}': {}".format(attr, type(derived_attr))
+                        f"Not setting null/empty value for data source '{attr}': {type(derived_attr)}"
                     )
                 sample._derived_cols_done.append(attr)
 
@@ -977,14 +1034,14 @@ def infer_name(self):
         """
         if CONFIG_KEY not in self:
             return
-        if hasattr(self[CONFIG_KEY], "name"):
-            if " " in self[CONFIG_KEY].name:
+        if NAME_KEY in self[CONFIG_KEY]:
+            if " " in self[CONFIG_KEY][NAME_KEY]:
                 raise InvalidConfigFileException(
                     "Specified Project name ({}) contains whitespace".format(
-                        self[CONFIG_KEY].name
+                        self[CONFIG_KEY][NAME_KEY]
                     )
                 )
-            return self[CONFIG_KEY].name.replace(" ", "_")
+            return self[CONFIG_KEY][NAME_KEY].replace(" ", "_")
         if not self[CONFIG_FILE_KEY]:
             raise NotImplementedError(
                 "Project name inference isn't supported "
@@ -1008,7 +1065,7 @@ def get_description(self):
         """
         if CONFIG_KEY not in self:
             return
-        if hasattr(self[CONFIG_KEY], DESC_KEY):
+        if DESC_KEY in self[CONFIG_KEY]:
             desc_str = str(self[CONFIG_KEY][DESC_KEY])
             if not isinstance(desc_str, str):
                 try:
@@ -1040,7 +1097,7 @@ def __str__(self):
             num_samples = 0
         if num_samples > 0:
             msg = f"{msg}\n{num_samples} samples"
-            sample_names = [getattr(s, self.st_index) for s in self.samples]
+            sample_names = [s[self.st_index] for s in self.samples]
             repr_names = sample_names[:MAX_PROJECT_SAMPLES_REPR]
             context = (
                 f" (showing first {MAX_PROJECT_SAMPLES_REPR})"
@@ -1081,7 +1138,7 @@ def list_amendments(self):
         :return Iterable[str]: a list of available amendment names
         """
         try:
-            return self[CONFIG_KEY][PROJ_MODS_KEY][AMENDMENTS_KEY].keys()
+            return list(self[CONFIG_KEY][PROJ_MODS_KEY][AMENDMENTS_KEY].keys())
         except Exception as e:
             _LOGGER.debug(
                 "Could not retrieve available amendments: {}".format(
@@ -1098,7 +1155,7 @@ def config(self):
         :return Mapping: config. May be formatted to comply with the most
             recent version specifications
         """
-        return self[CONFIG_KEY] if CONFIG_KEY in self else PathExAttMap()
+        return self[CONFIG_KEY] if CONFIG_KEY in self else {}
 
     @property
     def config_file(self):
@@ -1117,7 +1174,7 @@ def samples(self):
         :return Iterable[Sample]: Sample instance for each
             of this Project's samples
         """
-        if self._samples:
+        if self._samples is not None:
             return self._samples
         if SAMPLE_DF_KEY not in self or self[SAMPLE_DF_KEY] is None:
             _LOGGER.debug("No samples are defined")
@@ -1366,6 +1423,55 @@ def get_samples(self, sample_names):
         """
         return [s for s in self.samples if s[self.st_index] in sample_names]
 
+    @property
+    def description(self):
+        return self.get_description()
+
+    @description.setter
+    def description(self, value):
+        self[CONFIG_KEY][DESC_KEY] = str(value)
+
+    @property
+    def name(self):
+        return self.infer_name()
+
+    @name.setter
+    def name(self, value):
+        self[CONFIG_KEY][NAME_KEY] = str(value)
+
+    def __setitem__(self, key, value):
+        self._project_data[key] = value
+
+    def __getitem__(self, item):
+        """
+        Fetch the value of given key.
+
+        :param hashable item: key for which to fetch value
+        :return object: value mapped to given key, if available
+        :raise KeyError: if the requested key is unmapped.
+        """
+        return self._project_data[item]
+
+    def __iter__(self):
+        return iter(self._project_data)
+
+    def __len__(self):
+        return len(self._project_data)
+
+    def __delitem__(self, key):
+        value = self[key]
+        del self._project_data[key]
+        self.pop(value, None)
+
+    def __repr__(self):
+        return str(self)
+
+    def __reduce__(self):
+        return (
+            self.__class__.from_dict,
+            (self.to_dict(extended=True, orient="records"),),
+        )
+
 
 def infer_delimiter(filepath):
     """
diff --git a/peppy/sample.py b/peppy/sample.py
index bd65dc1e..9f92a6ac 100644
--- a/peppy/sample.py
+++ b/peppy/sample.py
@@ -1,6 +1,5 @@
 import glob
 import os
-from collections import OrderedDict
 from collections.abc import Mapping
 from copy import copy as cp
 from logging import getLogger
@@ -8,7 +7,7 @@
 
 import pandas as pd
 import yaml
-from attmap import AttMap, PathExAttMap
+from pandas import Series, isnull
 
 from .const import (
     CONFIG_FILE_KEY,
@@ -21,6 +20,7 @@
 )
 from .exceptions import InvalidSampleTableFileException
 from .utils import copy, grab_project_data
+from .simple_attr_map import SimpleAttMap
 
 _LOGGER = getLogger(PKG_NAME)
 
@@ -31,7 +31,7 @@ def __missing__(self, key):
 
 
 @copy
-class Sample(PathExAttMap):
+class Sample(SimpleAttMap):
     """
     Class to model Samples based on a pandas Series.
 
@@ -41,8 +41,8 @@ class Sample(PathExAttMap):
     def __init__(self, series, prj=None):
         super(Sample, self).__init__()
 
-        data = OrderedDict(series)
-        _LOGGER.debug("Sample data: {}".format(data))
+        data = dict(series)
+        _LOGGER.debug("Sample data: {data}")
 
         # Attach Project reference
         try:
@@ -50,12 +50,11 @@ def __init__(self, series, prj=None):
         except (AttributeError, KeyError):
             data_proj = None
 
-        self.add_entries(data)
+        self.update(**data)
 
         if data_proj and PRJ_REF not in self:
             self[PRJ_REF] = data_proj
 
-        typefam = PathExAttMap
         if PRJ_REF in self and prj:
             _LOGGER.warning(
                 "Project data provided both in data and as separate"
@@ -68,13 +67,10 @@ def __init__(self, series, prj=None):
             self[PRJ_REF] = None
             _LOGGER.debug("No project reference for sample")
         else:
-            prefix = "Project reference on a sample must be an instance of {}".format(
-                typefam.__name__
-            )
+            prefix = "Project reference on a sample must be an instance of dict"
+
             if not isinstance(self[PRJ_REF], Mapping):
-                raise TypeError(
-                    prefix + "; got {}".format(type(self[PRJ_REF]).__name__)
-                )
+                raise TypeError(f"{prefix}; got {type(self[PRJ_REF]).__name__}")
         self._derived_cols_done = []
         self._attributes = list(series.keys())
 
@@ -88,7 +84,7 @@ def get_sheet_dict(self):
             originally provided via the sample sheet (i.e., the a map-like
             representation of the instance, excluding derived items)
         """
-        return OrderedDict([[k, getattr(self, k)] for k in self._attributes])
+        return dict([[k, self[k]] for k in self._attributes])
 
     def to_dict(self, add_prj_ref=False):
         """
@@ -108,18 +104,10 @@ def _obj2dict(obj, name=None):
             :param str name: name of the object to represent.
             :param Iterable[str] to_skip: names of attributes to ignore.
             """
-            from pandas import Series, isnull
-
             if name:
-                _LOGGER.log(5, "Converting to dict: {}".format(name))
+                _LOGGER.log(5, "Converting to dict: {name}")
             if isinstance(obj, list):
                 return [_obj2dict(i) for i in obj]
-            if isinstance(obj, AttMap):
-                return {
-                    k: _obj2dict(v, name=k)
-                    for k, v in obj.items()
-                    if not k.startswith("_")
-                }
             elif isinstance(obj, Mapping):
                 return {
                     k: _obj2dict(v, name=k)
@@ -269,7 +257,7 @@ def _glob_regex(patterns):
             return None
         sn = self[SAMPLE_NAME_ATTR] if SAMPLE_NAME_ATTR in self else "this sample"
         try:
-            source_key = getattr(self, attr_name)
+            source_key = self[attr_name]
         except AttributeError:
             reason = (
                 "'{attr}': to locate sample's derived attribute source, "
@@ -282,31 +270,25 @@ def _glob_regex(patterns):
 
         try:
             regex = data_sources[source_key]
-            _LOGGER.debug("Data sources: {}".format(data_sources))
+            _LOGGER.debug("Data sources: {data_sources}")
         except KeyError:
             _LOGGER.debug(
-                "{}: config lacks entry for {} key: "
-                "'{}' in column '{}'; known: {}".format(
-                    sn, DERIVED_SOURCES_KEY, source_key, attr_name, data_sources.keys()
-                )
+                f"{sn}: config lacks entry for {DERIVED_SOURCES_KEY} key: "
+                f"'{source_key}' in column '{attr_name}'; known: {data_sources.keys()}"
             )
             return ""
         deriv_exc_base = (
-            "In sample '{sn}' cannot correctly parse derived "
-            "attribute source: {r}.".format(sn=sn, r=regex)
+            f"In sample '{sn}' cannot correctly parse derived "
+            f"attribute source: {regex}."
         )
         try:
-            vals = _format_regex(regex, dict(self.items()))
+            expanded_regex = os.path.expandvars(regex)
+            vals = _format_regex(expanded_regex, dict(self.items()))
             _LOGGER.debug("Formatted regex: {}".format(vals))
         except KeyError as ke:
-            _LOGGER.warning(
-                deriv_exc_base + " Can't access {ke} attribute".format(ke=str(ke))
-            )
+            _LOGGER.warning(f"{deriv_exc_base} Can't access {str(ke)} attribute")
         except Exception as e:
-            _LOGGER.warning(
-                deriv_exc_base
-                + " Caught exception: {e}".format(e=getattr(e, "message", repr(e)))
-            )
+            _LOGGER.warning(f"{deriv_exc_base} Caught exception: {str(e)}")
         else:
             return _glob_regex(vals)
         return None
@@ -320,29 +302,20 @@ def project(self):
         """
         return self[PRJ_REF]
 
-    def __setattr__(self, key, value):
-        self._try_touch_samples()
-        super(Sample, self).__setattr__(key, value)
-
-    def __delattr__(self, item):
-        self._try_touch_samples()
-        super(Sample, self).__delattr__(item)
-
-    def __setitem__(self, key, value):
-        self._try_touch_samples()
-        super(Sample, self).__setitem__(key, value)
-
     # The __reduce__ function provides an interface for
     # correct object serialization with the pickle module.
     def __reduce__(self):
         return (
             self.__class__,
-            (self.as_series(),),
-            (None, {}),
-            iter([]),
-            iter({PRJ_REF: self[PRJ_REF]}.items()),
+            (pd.Series(self.to_dict()),),
+            # (None, {}),
+            # iter([]),
+            # iter({PRJ_REF: self[PRJ_REF]}.items()),
         )
 
+    def __len__(self):
+        return len(self.to_dict())
+
     def __str__(self, max_attr=10):
         """Representation in interpreter."""
         if len(self) == 0:
@@ -363,15 +336,24 @@ def __str__(self, max_attr=10):
         attrs = ""
         counter = 0
         for k, v in pub_attrs.items():
-            attrs += "\n{}{}".format(
-                (k + ":").ljust(maxlen), v if not isinstance(v, list) else ", ".join(v)
-            )
+            key_to_show = (k + ":").ljust(maxlen)
+            if not isinstance(v, list):
+                val_to_show = v
+            else:
+                try:
+                    val_to_show = ", ".join([i for i in v if v is not None])
+                except TypeError:
+                    val_to_show = "None"
+            attrs += f"\n{key_to_show}{val_to_show}"
             if counter == max_attr:
                 attrs += "\n\n...".ljust(maxlen) + f"(showing first {max_attr})"
                 break
             counter += 1
         return head + "\n" + attrs
 
+    def __repr__(self):
+        return str(self)
+
     def _excl_from_eq(self, k):
         """Exclude the Project reference from object comparison."""
         return k == PRJ_REF or super(Sample, self)._excl_from_eq(k)
diff --git a/peppy/simple_attr_map.py b/peppy/simple_attr_map.py
new file mode 100644
index 00000000..50b1a089
--- /dev/null
+++ b/peppy/simple_attr_map.py
@@ -0,0 +1,51 @@
+from collections.abc import MutableMapping
+
+
+class SimpleAttMap(MutableMapping):
+    """
+    Simplified the AttrMap class, which enables storing key-value pairs in
+    a dictionary-like structure.
+    It allows assigning and accessing the values both through attributes and items.
+    In most cases used as SuperClass.
+    """
+
+    def __init__(self):
+        super(SimpleAttMap, self).__init__()
+        super(SimpleAttMap, self).__setattr__("_mapped_attr", {})
+
+    def __delitem__(self, key):
+        value = self[key]
+        del self._mapped_attr[key]
+        self.pop(value, None)
+
+    def __setitem__(self, item, value):
+        self._try_touch_samples()
+        self._mapped_attr[item] = value
+
+    def __getitem__(self, item):
+        return self._mapped_attr[item]
+
+    def __iter__(self):
+        return iter(self._mapped_attr)
+
+    def __len__(self):
+        return len(self._mapped_attr)
+
+    def __contains__(self, key):
+        return key in list(self.keys())
+
+    def __delattr__(self, key):
+        del self[key]
+
+    def __setattr__(self, item, value):
+        self._mapped_attr[item] = value
+
+    def __getattr__(self, item):
+        try:
+            return self._mapped_attr[item]
+        except KeyError:
+            raise AttributeError(f"Attribute not found: {item}")
+
+    @property
+    def attributes(self):
+        return self._mapped_attr
diff --git a/peppy/utils.py b/peppy/utils.py
index bc2a1838..35e6017a 100644
--- a/peppy/utils.py
+++ b/peppy/utils.py
@@ -2,15 +2,14 @@
 
 import logging
 import os
-from typing import Dict
+from typing import Dict, Mapping
 from urllib.request import urlopen
 
 import yaml
 from ubiquerg import expandpath, is_url
 
-from .exceptions import *
-
 from .const import CONFIG_KEY, SAMPLE_TABLE_INDEX_KEY, SUBSAMPLE_TABLE_INDEX_KEY
+from .exceptions import RemoteYAMLError
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -72,10 +71,9 @@ def grab_project_data(prj):
         return {}
 
     try:
-        return prj[CONFIG_KEY].to_dict()
+        return dict(prj[CONFIG_KEY])
     except KeyError:
         raise KeyError("Project lacks section '{}'".format(CONFIG_KEY))
-    return data
 
 
 def make_list(arg, obj_class):
@@ -106,6 +104,30 @@ def _raise_faulty_arg():
         _raise_faulty_arg()
 
 
+def _expandpath(path: str):
+    """
+    Expand a filesystem path that may or may not contain user/env vars.
+
+    :param str path: path to expand
+    :return str: expanded version of input path
+    """
+    return os.path.expandvars(os.path.expanduser(path))
+
+
+def expand_paths(x: dict) -> dict:
+    """
+    Recursively expand paths in a dict.
+
+    :param dict x: dict to expand
+    :return dict: dict with expanded paths
+    """
+    if isinstance(x, str):
+        return expandpath(x)
+    elif isinstance(x, Mapping):
+        return {k: expand_paths(v) for k, v in x.items()}
+    return x
+
+
 def load_yaml(filepath):
     """
     Load a local or remote YAML file into a Python dict
@@ -125,11 +147,11 @@ def load_yaml(filepath):
             )
         else:
             data = response.read().decode("utf-8")
-            return yaml.safe_load(data)
+            return expand_paths(yaml.safe_load(data))
     else:
         with open(os.path.abspath(filepath), "r") as f:
             data = yaml.safe_load(f)
-        return data
+        return expand_paths(data)
 
 
 def is_cfg_or_anno(file_path, formats=None):
diff --git a/requirements/requirements-all.txt b/requirements/requirements-all.txt
index 9436a3fb..a0036b9c 100644
--- a/requirements/requirements-all.txt
+++ b/requirements/requirements-all.txt
@@ -1,5 +1,5 @@
-attmap>=0.13.2
 pandas>=0.24.2
 pyyaml
 rich>=10.3.0
 ubiquerg>=0.6.2
+numpy
diff --git a/setup.py b/setup.py
index 75528d67..d0d1551b 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,6 @@
-import sys
 import os
+import sys
+
 from setuptools import find_packages, setup
 
 PACKAGE_NAME = "peppy"
@@ -47,16 +48,16 @@ def get_static(name, condition=None):
     classifiers=[
         "Development Status :: 4 - Beta",
         "License :: OSI Approved :: BSD License",
-        "Programming Language :: Python :: 3.6",
-        "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
+        "Programming Language :: Python :: 3.12",
         "Topic :: Scientific/Engineering :: Bio-Informatics",
     ],
     keywords="project, metadata, bioinformatics, sequencing, ngs, workflow",
     url="https://github.com/pepkit/peppy/",
-    author="Michal Stolarczyk, Nathan Sheffield, Vince Reuter, Andre Rendeiro",
+    author="Michal Stolarczyk, Nathan Sheffield, Vince Reuter, Andre Rendeiro, Oleksandr Khoroshevskyi",
     license="BSD2",
     include_package_data=True,
     tests_require=(["pytest"]),


Test patch:
diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml
index 8918af5a..ee1d60cc 100644
--- a/.github/workflows/run-pytest.yml
+++ b/.github/workflows/run-pytest.yml
@@ -4,14 +4,14 @@ on:
   push:
     branches: [dev]
   pull_request:
-    branches: [master]
+    branches: [master, dev]
 
 jobs:
   pytest:
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        python-version: ["3.8", "3.9", "3.10"]
+        python-version: ["3.8", "3.12"]
         os: [ubuntu-20.04]
 
     steps:
@@ -22,10 +22,10 @@ jobs:
       with:
         python-version: ${{ matrix.python-version }}
 
-    - name: Install dev dependancies
+    - name: Install dev dependencies
       run: if [ -f requirements/requirements-dev.txt ]; then pip install -r requirements/requirements-dev.txt; fi
 
-    - name: Install test dependancies
+    - name: Install test dependencies
       run: if [ -f requirements/requirements-test.txt ]; then pip install -r requirements/requirements-test.txt; fi
 
     - name: Install package
diff --git a/tests/conftest.py b/tests/conftest.py
index de98c0e3..50c7ffd5 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -4,7 +4,6 @@
 
 import pandas as pd
 import pytest
-import json
 
 __author__ = "Michal Stolarczyk"
 __email__ = "michal.stolarczyk@nih.gov"
@@ -37,6 +36,11 @@ def example_pep_csv_path(request):
     return get_path_to_example_file(EPB, request.param, "sample_table.csv")
 
 
+@pytest.fixture
+def example_yaml_sample_file(request):
+    return get_path_to_example_file(EPB, request.param, "sample.yaml")
+
+
 @pytest.fixture
 def example_pep_nextflow_csv_path():
     return get_path_to_example_file(EPB, "nextflow_taxprofiler_pep", "samplesheet.csv")
diff --git a/tests/data/example_peps-master/example_basic_sample_yaml/sample.yaml b/tests/data/example_peps-master/example_basic_sample_yaml/sample.yaml
new file mode 100644
index 00000000..468a4eab
--- /dev/null
+++ b/tests/data/example_peps-master/example_basic_sample_yaml/sample.yaml
@@ -0,0 +1,6 @@
+- sample_name: sample1
+  file: path/to/file.tsv
+- sample_name: sample2
+  file: path/to/2.tsv
+- sample_name: sample3
+  file: path/to/3.tsv
\ No newline at end of file
diff --git a/tests/smoketests/test_Project.py b/tests/smoketests/test_Project.py
index eda46102..197ba9b0 100644
--- a/tests/smoketests/test_Project.py
+++ b/tests/smoketests/test_Project.py
@@ -44,7 +44,7 @@ def test_derive(self, example_pep_cfg_path):
         """
         p = Project(cfg=example_pep_cfg_path)
         assert all(["file_path" in s for s in p.samples])
-        assert all(["file_path" in s["_derived_cols_done"] for s in p.samples])
+        assert all(["file_path" in s._derived_cols_done for s in p.samples])
 
     @pytest.mark.parametrize("example_pep_cfg_path", ["remove"], indirect=True)
     def test_remove(self, example_pep_cfg_path):
diff --git a/tests/smoketests/test_Sample.py b/tests/smoketests/test_Sample.py
index 58de9a41..a9a933bd 100644
--- a/tests/smoketests/test_Sample.py
+++ b/tests/smoketests/test_Sample.py
@@ -27,7 +27,7 @@
 ]
 
 
-class SampleTests:
+class TestSample:
     @pytest.mark.parametrize("example_pep_cfg_path", ["basic"], indirect=True)
     def test_serialization(self, example_pep_cfg_path):
         """
@@ -37,9 +37,9 @@ def test_serialization(self, example_pep_cfg_path):
         fn = os.path.join(td, "serialized_sample.yaml")
         p = Project(cfg=example_pep_cfg_path)
         sample = p.samples[0]
-        sample.set = set(["set"])
-        sample.dict = dict({"dict": "dict"})
-        sample.list = list(["list"])
+        sample["set"] = set("set")
+        sample["dict"] = dict({"dict": "dict"})
+        sample["list"] = list(["list"])
         sample.to_yaml(fn)
         with open(fn, "r") as f:
             contents = f.read()
@@ -56,7 +56,7 @@ def test_str_repr_correctness(self, example_pep_cfg_path):
         for sample in p.samples:
             str_repr = sample.__str__(max_attr=100)
             assert example_pep_cfg_path in str_repr
-            assert "Sample '{}'".format(sample.sample_name) in str_repr
+            assert "Sample '{}'".format(sample["sample_name"]) in str_repr
 
     @pytest.mark.parametrize("example_pep_cfg_path", ["basic"], indirect=True)
     def test_sheet_dict_excludes_private_attrs(self, example_pep_cfg_path):
@@ -66,3 +66,14 @@ def test_sheet_dict_excludes_private_attrs(self, example_pep_cfg_path):
         p = Project(cfg=example_pep_cfg_path)
         for sample in p.samples:
             assert len(sample.get_sheet_dict()) == len(p.sample_table.columns)
+
+    @pytest.mark.parametrize("example_pep_cfg_path", ["basic"], indirect=True)
+    def test_pickle_in_samples(self, example_pep_cfg_path):
+        import pickle
+
+        p = Project(cfg=example_pep_cfg_path)
+        for sample in p.samples:
+            pickled_data = pickle.dumps(sample)
+            unpickled_sample = pickle.loads(pickled_data)
+
+            assert sample.to_dict() == unpickled_sample.to_dict()
diff --git a/tests/test_Project.py b/tests/test_Project.py
index 751c4ef9..b2241f2f 100644
--- a/tests/test_Project.py
+++ b/tests/test_Project.py
@@ -8,7 +8,9 @@
 import pytest
 from pandas import DataFrame
 from yaml import dump, safe_load
+import pickle
 
+import peppy
 from peppy import Project
 from peppy.const import SAMPLE_NAME_ATTR, SAMPLE_TABLE_FILE_KEY
 from peppy.exceptions import (
@@ -65,9 +67,8 @@ def _cmp_all_samples_attr(p1, p2, attr):
     :param attr: attribute name to compare
     :type attr: str
     """
-
-    assert [getattr(s, attr, None) for s in p1.samples] == [
-        getattr(s, attr, None) for s in p2.samples
+    assert [s1.get(attr, "") for s1 in p1.samples] == [
+        s2.get(attr, "") for s2 in p2.samples
     ]
 
 
@@ -92,6 +93,19 @@ def test_instantiaion(self, example_pep_cfg_path, defer):
         p = Project(cfg=example_pep_cfg_path, defer_samples_creation=defer)
         assert isinstance(p, Project)
 
+    @pytest.mark.parametrize("defer", [False, True])
+    @pytest.mark.parametrize("example_pep_cfg_path", ["amendments1"], indirect=True)
+    def test_expand_path(self, example_pep_cfg_path, defer):
+        """
+        Verify output_path is expanded
+        """
+        p = Project(
+            cfg=example_pep_cfg_path,
+            amendments="newLib",
+            defer_samples_creation=defer,
+        )
+        assert not p.config["output_dir"].startswith("$")
+
     @pytest.mark.parametrize(
         "config_path",
         [
@@ -245,7 +259,7 @@ def test_no_description(self, example_pep_cfg_path, defer):
         """
         p = Project(cfg=example_pep_cfg_path, defer_samples_creation=defer)
         assert isinstance(p, Project)
-        assert "description" in p and p.description is None
+        assert p.description is None
 
     @pytest.mark.parametrize("defer", [False, True])
     @pytest.mark.parametrize("desc", ["desc1", "desc 2 <test> 123$!@#;11", 11, None])
@@ -264,7 +278,7 @@ def test_description(self, example_pep_cfg_path, desc, defer):
             dump(data, f)
         p = Project(cfg=temp_path_cfg, defer_samples_creation=defer)
         assert isinstance(p, Project)
-        assert "description" in p and p.description == str(desc)
+        assert p.description == str(desc)
 
     @pytest.mark.parametrize(
         "example_pep_cfg_noname_path", ["project_config.yaml"], indirect=True
@@ -336,7 +350,11 @@ def test_from_dict_instatiation(self, example_pep_cfg_path):
         representation.
         """
         p1 = Project(cfg=example_pep_cfg_path)
-        p2 = Project().from_dict(p1.to_dict(extended=True))
+        ff = p1.to_dict(extended=True)
+        import pprint
+
+        pprint.pprint(ff)
+        p2 = Project.from_dict(p1.to_dict(extended=True))
         assert p1 == p2
 
     def test_to_dict_does_not_create_nans(self, example_pep_nextflow_csv_path):
@@ -390,7 +408,18 @@ def test_peppy_initializes_samples_with_correct_attributes(
         self, example_pep_cfg_path, expected_attribute
     ):
         p = Project(example_pep_cfg_path, sample_table_index="sample")
-        assert all([hasattr(sample, expected_attribute) for sample in p.samples])
+        assert all([expected_attribute in sample for sample in p.samples])
+
+    # @pytest.mark.skip(
+    #     "skipping this test, because this functionality is unavailable now"
+    # )
+    @pytest.mark.parametrize("example_pep_cfg_path", ["basic", "imply"], indirect=True)
+    def test_correct_pickle(self, example_pep_cfg_path):
+        proj = Project(example_pep_cfg_path)
+        pickled_data = pickle.dumps(proj)
+        unpickled_project = pickle.loads(pickled_data)
+
+        assert proj == unpickled_project
 
 
 class TestProjectManipulationTests:
@@ -543,8 +572,11 @@ def test_equality(self, example_pep_cfg_path):
         p2 = Project(cfg=example_pep_cfg_path)
         assert p1 == p2
 
-    @pytest.mark.parametrize("example_pep_cfg_path", ["append"], indirect=True)
-    @pytest.mark.parametrize("example_pep_csv_path", ["derive"], indirect=True)
+    @pytest.mark.parametrize(
+        "example_pep_cfg_path, example_pep_csv_path",
+        [["append", "derive"]],
+        indirect=True,
+    )
     def test_unequality(self, example_pep_cfg_path, example_pep_csv_path):
         """
         Test equality function of two projects
@@ -566,16 +598,117 @@ def test_from_dict(self, example_pep_cfg_path, orient):
         p1 = Project(cfg=example_pep_cfg_path)
         p1_dict = p1.to_dict(extended=True, orient=orient)
         del p1_dict["_config"]["sample_table"]
-        p2 = Project().from_dict(p1_dict)
+        p2 = Project.from_dict(p1_dict)
         assert p1 == p2
 
-    @pytest.mark.parametrize("config_with_pandas_obj", ["append"], indirect=True)
-    @pytest.mark.parametrize("example_pep_csv_path", ["append"], indirect=True)
+    @pytest.mark.parametrize(
+        "config_with_pandas_obj, example_pep_csv_path",
+        [
+            ["append", "append"],
+            ["derive", "derive"],
+            ["subtable1", "subtable1"],
+        ],
+        indirect=True,
+    )
     def test_from_pandas(self, config_with_pandas_obj, example_pep_csv_path):
         """
         Test initializing project from dict
         """
+        p1 = Project.from_pandas(config_with_pandas_obj)
+        p2 = Project(example_pep_csv_path)
+        assert p1 == p2
+
+    @pytest.mark.parametrize(
+        "example_yaml_sample_file",
+        [
+            "basic_sample_yaml",
+        ],
+        indirect=True,
+    )
+    def test_from_yaml(self, example_yaml_sample_file):
+        """
+        Test initializing project from dict
+        """
+        p1 = Project.from_sample_yaml(example_yaml_sample_file)
+        assert p1.samples[0].sample_name == "sample1"
+        assert len(p1.samples) == 3
+
+    @pytest.mark.parametrize(
+        "config_with_pandas_obj, example_pep_csv_path",
+        [
+            ["append", "append"],
+            ["derive", "derive"],
+            ["subtable1", "subtable1"],
+        ],
+        indirect=True,
+    )
+    def test_from_pandas_unequal(self, config_with_pandas_obj, example_pep_csv_path):
+        """
+        Test initializing project from pandas changing one of the samples
+        and checking inequality
+        """
         p1 = Project().from_pandas(config_with_pandas_obj)
+
+        del p1.samples[0].sample_name
         p2 = Project(example_pep_csv_path)
+        assert p1 != p2
 
-        assert p1 == p2
+    @pytest.mark.parametrize(
+        "example_pep_cfg_path",
+        ["append"],
+        indirect=True,
+    )
+    def test_description_setter(self, example_pep_cfg_path):
+        new_description = "new_description1"
+        p = Project(cfg=example_pep_cfg_path)
+        p.description = new_description
+
+        assert p.description == new_description
+        assert p.to_dict(extended=True)["_config"]["description"] == new_description
+
+    @pytest.mark.parametrize(
+        "example_pep_cfg_path",
+        ["append"],
+        indirect=True,
+    )
+    def test_name_setter(self, example_pep_cfg_path):
+        new_name = "new_name1"
+        p = Project(cfg=example_pep_cfg_path)
+        p.name = new_name
+
+        assert p.name == new_name
+        assert p.to_dict(extended=True)["_config"]["name"] == new_name
+
+
+class TestSampleAttrMap:
+    @pytest.mark.parametrize("example_pep_cfg_path", ["append"], indirect=True)
+    def test_sample_getattr(self, example_pep_cfg_path):
+        """
+        Verify that the getattr works
+        """
+        p = Project(cfg=example_pep_cfg_path)
+        p1 = Project(cfg=example_pep_cfg_path)
+
+        for s1, s2 in zip(p.samples, p1.samples):
+            assert s1.sample_name == s1["sample_name"]
+            assert s2.organism == s2["organism"]
+
+    @pytest.mark.parametrize("example_pep_cfg_path", ["append"], indirect=True)
+    def test_sample_getattr(self, example_pep_cfg_path):
+        """
+        Verify that the setattr works
+        """
+        p = Project(cfg=example_pep_cfg_path)
+        new_name = "bingo"
+        p.samples[0].sample_name = new_name
+
+        df = p.samples[0].to_dict()
+        assert df["sample_name"] == new_name
+
+    @pytest.mark.parametrize("example_pep_cfg_path", ["append"], indirect=True)
+    def test_sample_len(self, example_pep_cfg_path):
+        """
+        Verify that the len works
+        """
+        p = Project(cfg=example_pep_cfg_path)
+        assert len(p.samples[0]) == 4