diff --git a/.gitignore b/.gitignore
index 91cf1fa13b2b487d6c5d5003ff16c0bc9419b22a..b85f6e7e04eb8af98f13ab427752988894ab3b80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,7 @@
 output_graphs/
+batteries_data_temp/
+results/
+current_results/
 
 
 # Byte-compiled / optimized / DLL files
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 62f89a7d23c6e050bf581bf203158de4eabbe79a..db4adff7a7b1c3dced4ed4ed6bf5739ac1ae72fb 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,8 +1,11 @@
-before_script:
-  - pipenv install
-
-lint:
-  tags:
-      - ubuntu-docker
-  script:
-    - pipenv run flake8
+# before_script:
+#   - pkill -f apt
+#   - apt install -y python-dev
+#   - apt install -y python3-dev
+#   - pipenv install
+# 
+# lint:
+#   tags:
+#     - ubuntu-docker
+#   script:
+#     - pipenv run flake8
diff --git a/Pipfile b/Pipfile
index f732758831d8a0877ca0b6b7fb2dd9146d0cfa93..bfde6313c1ea200fb8851a4e3aeb141489194f26 100644
--- a/Pipfile
+++ b/Pipfile
@@ -10,6 +10,12 @@ matplotlib = "*"
 pillow = "*"
 "flake8" = "*"
 pylint = "*"
+cython = "*"
+pandas = "*"
+pytest = "*"
+openpyxl = "*"
+"auto-sklearn2" = {ref = "8bdcba15caa28cb4336d9cb6ee4108078ab6d8a2", git = "git://github.com/automl/auto-sklearn.git"}
+auto-sklearn = "*"
 
 [dev-packages]
 
diff --git a/Pipfile.lock b/Pipfile.lock
index 4952fe2717ecd07da9d9b535e5a42b7caeedca63..27239833e53d160769daa4fd2869b46f0e985173 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "7e723a07b772661cda7518947388851ea0228514db02d079d9bd21697cf83cba"
+            "sha256": "83d6c1f4f2838b93de5827e2906aa9a8d88c90874eed7b2e7104ba6d4c5722b9"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -16,6 +16,13 @@
         ]
     },
     "default": {
+        "alabaster": {
+            "hashes": [
+                "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
+                "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
+            ],
+            "version": "==0.7.12"
+        },
         "astroid": {
             "hashes": [
                 "sha256:292fa429e69d60e4161e7612cb7cc8fa3609e2e309f80c224d93a76d5e7b58be",
@@ -23,6 +30,58 @@
             ],
             "version": "==2.0.4"
         },
+        "atomicwrites": {
+            "hashes": [
+                "sha256:0312ad34fcad8fac3704d441f7b317e50af620823353ec657a53e981f92920c0",
+                "sha256:ec9ae8adaae229e4f8446952d204a3e4b5fdd2d099f9be3aaf556120135fb3ee"
+            ],
+            "version": "==1.2.1"
+        },
+        "attrs": {
+            "hashes": [
+                "sha256:10cbf6e27dbce8c30807caf056c8eb50917e0eaafe86347671b57254006c3e69",
+                "sha256:ca4be454458f9dec299268d472aaa5a11f67a4ff70093396e1ceae9c76cf4bbb"
+            ],
+            "version": "==18.2.0"
+        },
+        "auto-sklearn": {
+            "hashes": [
+                "sha256:9b67e58a8f81571ebf060975c5c636f57a106ffcf0d644a4d03167bcc3f9ade5"
+            ],
+            "index": "pypi",
+            "version": "==0.4.1"
+        },
+        "auto-sklearn2": {
+            "git": "git://github.com/automl/auto-sklearn.git",
+            "ref": "8bdcba15caa28cb4336d9cb6ee4108078ab6d8a2"
+        },
+        "babel": {
+            "hashes": [
+                "sha256:6778d85147d5d85345c14a26aada5e478ab04e39b078b0745ee6870c2b5cf669",
+                "sha256:8cba50f48c529ca3fa18cf81fa9403be176d374ac4d60738b839122dfaaa3d23"
+            ],
+            "version": "==2.6.0"
+        },
+        "certifi": {
+            "hashes": [
+                "sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c",
+                "sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a"
+            ],
+            "version": "==2018.10.15"
+        },
+        "chardet": {
+            "hashes": [
+                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
+                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
+            ],
+            "version": "==3.0.4"
+        },
+        "configspace": {
+            "hashes": [
+                "sha256:cbc449544d75b3e0fa8bf10f3281e4cba0fd59646e3caa6094cec7805eeb7bc0"
+            ],
+            "version": "==0.4.7"
+        },
         "cycler": {
             "hashes": [
                 "sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d",
@@ -30,13 +89,75 @@
             ],
             "version": "==0.10.0"
         },
+        "cython": {
+            "hashes": [
+                "sha256:019008a69e6b7c102f2ed3d733a288d1784363802b437dd2b91e6256b12746da",
+                "sha256:1441fe19c56c90b8c2159d7b861c31a134d543ef7886fd82a5d267f9f11f35ac",
+                "sha256:1d1a5e9d6ed415e75a676b72200ad67082242ec4d2d76eb7446da255ae72d3f7",
+                "sha256:339f5b985de3662b1d6c69991ab46fdbdc736feb4ac903ef6b8c00e14d87f4d8",
+                "sha256:35bdf3f48535891fee2eaade70e91d5b2cc1ee9fc2a551847c7ec18bce55a92c",
+                "sha256:3d0afba0aec878639608f013045697fb0969ff60b3aea2daec771ea8d01ad112",
+                "sha256:42c53786806e24569571a7a24ebe78ec6b364fe53e79a3f27eddd573cacd398f",
+                "sha256:48b919da89614d201e72fbd8247b5ae8881e296cf968feb5595a015a14c67f1f",
+                "sha256:49906e008eeb91912654a36c200566392bd448b87a529086694053a280f8af2d",
+                "sha256:49fc01a7c9c4e3c1784e9a15d162c2cac3990fcc28728227a6f8f0837aabda7c",
+                "sha256:501b671b639b9ca17ad303f8807deb1d0ff754d1dab106f2607d14b53cb0ff0b",
+                "sha256:5574574142364804423ab4428bd331a05c65f7ecfd31ac97c936f0c720fe6a53",
+                "sha256:6092239a772b3c6604be9e94b9ab4f0dacb7452e8ad299fd97eae0611355b679",
+                "sha256:71ff5c7632501c4f60edb8a24fd0a772e04c5bdca2856d978d04271b63666ef7",
+                "sha256:7dcf2ad14e25b05eda8bdd104f8c03a642a384aeefd25a5b51deac0826e646fa",
+                "sha256:8ca3a99f5a7443a6a8f83a5d8fcc11854b44e6907e92ba8640d8a8f7b9085e21",
+                "sha256:927da3b5710fb705aab173ad630b45a4a04c78e63dcd89411a065b2fe60e4770",
+                "sha256:94916d1ede67682638d3cc0feb10648ff14dc51fb7a7f147f4fedce78eaaea97",
+                "sha256:a3e5e5ca325527d312cdb12a4dab8b0459c458cad1c738c6f019d0d8d147081c",
+                "sha256:a7716a98f0b9b8f61ddb2bae7997daf546ac8fc594be6ba397f4bde7d76bfc62",
+                "sha256:acf10d1054de92af8d5bfc6620bb79b85f04c98214b4da7db77525bfa9fc2a89",
+                "sha256:de46ffb67e723975f5acab101c5235747af1e84fbbc89bf3533e2ea93fb26947",
+                "sha256:df428969154a9a4cd9748c7e6efd18432111fbea3d700f7376046c38c5e27081",
+                "sha256:f5ebf24b599caf466f9da8c4115398d663b2567b89e92f58a835e9da4f74669f",
+                "sha256:f79e45d5c122c4fb1fd54029bf1d475cecc05f4ed5b68136b0d6ec268bae68b6",
+                "sha256:f7a43097d143bd7846ffba6d2d8cd1cc97f233318dbd0f50a235ea01297a096b",
+                "sha256:fceb8271bc2fd3477094ca157c824e8ea840a7b393e89e766eea9a3b9ce7e0c6",
+                "sha256:ff919ceb40259f5332db43803aa6c22ff487e86036ce3921ae04b9185efc99a4"
+            ],
+            "index": "pypi",
+            "version": "==0.29"
+        },
+        "docutils": {
+            "hashes": [
+                "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
+                "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
+                "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
+            ],
+            "version": "==0.14"
+        },
+        "et-xmlfile": {
+            "hashes": [
+                "sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b"
+            ],
+            "version": "==1.0.1"
+        },
         "flake8": {
             "hashes": [
-                "sha256:7253265f7abd8b313e3892944044a365e3f4ac3fcdcfb4298f55ee9ddf188ba0",
-                "sha256:c7841163e2b576d435799169b78703ad6ac1bbb0f199994fc05f700b2a90ea37"
+                "sha256:6a35f5b8761f45c5513e3405f110a86bea57982c3b75b766ce7b65217abe1670",
+                "sha256:c01f8a3963b3571a8e6bd7a4063359aff90749e160778e03817cd9b71c9e07d2"
             ],
             "index": "pypi",
-            "version": "==3.5.0"
+            "version": "==3.6.0"
+        },
+        "idna": {
+            "hashes": [
+                "sha256:156a6814fb5ac1fc6850fb002e0852d56c0c8d2531923a51032d1b70760e186e",
+                "sha256:684a38a6f903c1d71d6d5fac066b58d7768af4de2b832e426ec79c30daa94a16"
+            ],
+            "version": "==2.7"
+        },
+        "imagesize": {
+            "hashes": [
+                "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8",
+                "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5"
+            ],
+            "version": "==1.1.0"
         },
         "isort": {
             "hashes": [
@@ -44,9 +165,29 @@
                 "sha256:b9c40e9750f3d77e6e4d441d8b0266cf555e7cdabdcff33c4fd06366ca761ef8",
                 "sha256:ec9ef8f4a9bc6f71eec99e1806bfa2de401650d996c59330782b89a5555c1497"
             ],
-            "markers": "python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.2.*' and python_version != '3.3.*' and python_version != '3.0.*'",
             "version": "==4.3.4"
         },
+        "jdcal": {
+            "hashes": [
+                "sha256:948fb8d079e63b4be7a69dd5f0cd618a0a57e80753de8248fd786a8a20658a07",
+                "sha256:ea0a5067c5f0f50ad4c7bdc80abad3d976604f6fb026b0b3a17a9d84bb9046c9"
+            ],
+            "version": "==1.4"
+        },
+        "jinja2": {
+            "hashes": [
+                "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
+                "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
+            ],
+            "version": "==2.10"
+        },
+        "joblib": {
+            "hashes": [
+                "sha256:651fdd4888cdefa39f65c942e33ba1a610d395acd9c1d787adbda1a6beb22218",
+                "sha256:9002b53b88ae0adb3872164e0846a489b7e112c50087c5e3e1bcee35f18424c4"
+            ],
+            "version": "==0.13.0"
+        },
         "kiwisolver": {
             "hashes": [
                 "sha256:0ee4ed8b3ae8f5f712b0aa9ebd2858b5b232f1b9a96b0943dceb34df2a223bc3",
@@ -114,24 +255,70 @@
             ],
             "version": "==1.3.1"
         },
+        "liac-arff": {
+            "hashes": [
+                "sha256:fa7aa8e9710d5906e5bab523e332aa1e40c6d2f6e453647c0e000c9b271497f4"
+            ],
+            "version": "==2.3.1"
+        },
+        "lockfile": {
+            "hashes": [
+                "sha256:6aed02de03cba24efabcd600b30540140634fc06cfa603822d508d5361e9f799",
+                "sha256:6c3cb24f344923d30b2785d5ad75182c8ea7ac1b6171b08657258ec7429d50fa"
+            ],
+            "version": "==0.12.2"
+        },
+        "markupsafe": {
+            "hashes": [
+                "sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
+                "sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
+                "sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
+                "sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
+                "sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
+                "sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
+                "sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
+                "sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
+                "sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
+                "sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
+                "sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
+                "sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
+                "sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
+                "sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
+                "sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
+                "sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
+                "sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
+                "sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
+                "sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
+                "sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
+                "sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
+                "sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
+                "sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
+                "sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
+                "sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
+                "sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
+                "sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
+                "sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
+            ],
+            "version": "==1.1.0"
+        },
         "matplotlib": {
             "hashes": [
-                "sha256:0f738b57051e8a0f8bc8282031d0a82e9dedbd10a94fd54d4c3830d708607a8b",
-                "sha256:0f87d188528ff3c86286603bc13170a5932e631c0c69d9995aae86448a7d9692",
-                "sha256:290864f3c69d1e71d6648c9c75093db28486f1bf058b0ab2fda9d2d6814ddf19",
-                "sha256:70aba3a1c7dbef5a997db8afe06e256c6b67e1dc15bb16d8b55d140ea5375a8d",
-                "sha256:7318d11a4784c3e37f5de0c9141d18eac08565d303da7d3d557662369f2f866b",
-                "sha256:77c6edc4e25b36430df8a445195030abc8d5766d068b9aeed1a58a684cc0eb3b",
-                "sha256:91669d38938ae7b66db084e444ee5dceed09b59a6622fda10dfb021d5ce6d0dc",
-                "sha256:a547edc4d0ce68f3eb397ed8701314f254a0de593045ee0eecad4f1efc664951",
-                "sha256:b4e2333c98a7c2c1ff6eb930cd2b57d4b818de5437c5048802096b32f66e65f9",
-                "sha256:c99b3908e76de5d1582e6941dc34de086eb38d18539520f4ae4ffa29b8f2644f",
-                "sha256:e3acc990b3672132a670b23cc055b967d0aa04183dbc5be82a38a0426ee6d1a6",
-                "sha256:eaa8f8248c20eacfade26faf749e248adc1bec1edc2d08b05916297cc76a72bd",
-                "sha256:ede6d9676c43844e4994b041ffca08dd157ce171190a8ccb40fed9b377db5653"
+                "sha256:16aa61846efddf91df623bbb4598e63be1068a6b6a2e6361cc802b41c7a286eb",
+                "sha256:1975b71a33ac986bb39b6d5cfbc15c7b1f218f1134efb4eb3881839d6ae69984",
+                "sha256:2b222744bd54781e6cc0b717fa35a54e5f176ba2ced337f27c5b435b334ef854",
+                "sha256:317643c0e88fad55414347216362b2e229c130edd5655fea5f8159a803098468",
+                "sha256:4269ce3d1b897d46fc3cc2273a0cc2a730345bb47e4456af662e6fca85c89dd7",
+                "sha256:65214fd668975077cdf8d408ccf2b2d6bdf73b4e6895a79f8e99ce4f0b43fcdb",
+                "sha256:74bc213ab8a92d86a0b304d9359d1e1d14168d4c6121b83862c9d8a88b89a738",
+                "sha256:88949be0db54755995dfb0210d0099a8712a3c696c860441971354c3debfc4af",
+                "sha256:8e1223d868be89423ec95ada5f37aa408ee64fe76ccb8e4d5f533699ba4c0e4a",
+                "sha256:9fa00f2d7a552a95fa6016e498fdeb6d74df537853dda79a9055c53dfc8b6e1a",
+                "sha256:c27fd46cab905097ba4bc28d5ba5289930f313fb1970c9d41092c9975b80e9b4",
+                "sha256:c94b792af431f6adb6859eb218137acd9a35f4f7442cea57e4a59c54751c36af",
+                "sha256:f4c12a01eb2dc16693887a874ba948b18c92f425c4d329639ece6d3bb8e631bb"
             ],
             "index": "pypi",
-            "version": "==3.0.0"
+            "version": "==3.0.2"
         },
         "mccabe": {
             "hashes": [
@@ -140,89 +327,180 @@
             ],
             "version": "==0.6.1"
         },
+        "more-itertools": {
+            "hashes": [
+                "sha256:c187a73da93e7a8acc0001572aebc7e3c69daf7bf6881a2cea10650bd4420092",
+                "sha256:c476b5d3a34e12d40130bc2f935028b5f636df8f372dc2c1c01dc19681b2039e",
+                "sha256:fcbfeaea0be121980e15bc97b3817b5202ca73d0eae185b4550cbfce2a3ebb3d"
+            ],
+            "version": "==4.3.0"
+        },
+        "nose": {
+            "hashes": [
+                "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac",
+                "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a",
+                "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"
+            ],
+            "version": "==1.3.7"
+        },
         "numpy": {
             "hashes": [
-                "sha256:1b1cf8f7300cf7b11ddb4250b3898c711a6187df05341b5b7153db23ffe5d498",
-                "sha256:27a0d018f608a3fe34ac5e2b876f4c23c47e38295c47dd0775cc294cd2614bc1",
-                "sha256:3fde172e28c899580d32dc21cb6d4a1225d62362f61050b654545c662eac215a",
-                "sha256:497d7c86df4f85eb03b7f58a7dd0f8b948b1f582e77629341f624ba301b4d204",
-                "sha256:4e28e66cf80c09a628ae680efeb0aa9a066eb4bb7db2a5669024c5b034891576",
-                "sha256:58be95faf0ca2d886b5b337e7cba2923e3ad1224b806a91223ea39f1e0c77d03",
-                "sha256:5b4dfb6551eaeaf532054e2c6ef4b19c449c2e3a709ebdde6392acb1372ecabc",
-                "sha256:63f833a7c622e9082df3cbaf03b4fd92d7e0c11e2f9d87cb57dbf0e84441964b",
-                "sha256:71bf3b7ca15b1967bba3a1ef6a8e87286382a8b5e46ac76b42a02fe787c5237d",
-                "sha256:733dc5d47e71236263837825b69c975bc08728ae638452b34aeb1d6fa347b780",
-                "sha256:82f00a1e2695a0e5b89879aa25ea614530b8ebdca6d49d4834843d498e8a5e92",
-                "sha256:866bf72b9c3bfabe4476d866c70ee1714ad3e2f7b7048bb934892335e7b6b1f7",
-                "sha256:8aeac8b08f4b8c52129518efcd93706bb6d506ccd17830b67d18d0227cf32d9e",
-                "sha256:8d2cfb0aef7ec8759736cce26946efa084cdf49797712333539ef7d135e0295e",
-                "sha256:981224224bbf44d95278eb37996162e8beb6f144d2719b144e86dfe2fce6c510",
-                "sha256:981daff58fa3985a26daa4faa2b726c4e7a1d45178100125c0e1fdaf2ac64978",
-                "sha256:9ad36dbfdbb0cba90a08e7343fadf86f43cf6d87450e8d2b5d71d7c7202907e4",
-                "sha256:a251570bb3cb04f1627f23c234ad09af0e54fc8194e026cf46178f2e5748d647",
-                "sha256:b5ff7dae352fd9e1edddad1348698e9fea14064460a7e39121ef9526745802e6",
-                "sha256:c898f9cca806102fcacb6309899743aa39efb2ad2a302f4c319f54db9f05cd84",
-                "sha256:cf4b970042ce148ad8dce4369c02a4078b382dadf20067ce2629c239d76460d1",
-                "sha256:d1569013e8cc8f37e9769d19effdd85e404c976cd0ca28a94e3ddc026c216ae8",
-                "sha256:dca261e85fe0d34b2c242ecb31c9ab693509af2cf955d9caf01ee3ef3669abd0",
-                "sha256:ec8bf53ef7c92c99340972519adbe122e82c81d5b87cbd955c74ba8a8cd2a4ad",
-                "sha256:f2e55726a9ee2e8129d6ce6abb466304868051bcc7a09d652b3b07cd86e801a2",
-                "sha256:f4dee74f2626c783a3804df9191e9008946a104d5a284e52427a53ff576423cb",
-                "sha256:f592fd7fe1f20b5041928cce1330937eca62f9058cb41e69c2c2d83cffc0d1e3",
-                "sha256:ffab5b80bba8c86251291b8ce2e6c99a61446459d4c6637f5d5cc8c9ce37c972"
+                "sha256:0df89ca13c25eaa1621a3f09af4c8ba20da849692dcae184cb55e80952c453fb",
+                "sha256:154c35f195fd3e1fad2569930ca51907057ae35e03938f89a8aedae91dd1b7c7",
+                "sha256:18e84323cdb8de3325e741a7a8dd4a82db74fde363dce32b625324c7b32aa6d7",
+                "sha256:1e8956c37fc138d65ded2d96ab3949bd49038cc6e8a4494b1515b0ba88c91565",
+                "sha256:23557bdbca3ccbde3abaa12a6e82299bc92d2b9139011f8c16ca1bb8c75d1e95",
+                "sha256:24fd645a5e5d224aa6e39d93e4a722fafa9160154f296fd5ef9580191c755053",
+                "sha256:36e36b6868e4440760d4b9b44587ea1dc1f06532858d10abba98e851e154ca70",
+                "sha256:3d734559db35aa3697dadcea492a423118c5c55d176da2f3be9c98d4803fc2a7",
+                "sha256:416a2070acf3a2b5d586f9a6507bb97e33574df5bd7508ea970bbf4fc563fa52",
+                "sha256:4a22dc3f5221a644dfe4a63bf990052cc674ef12a157b1056969079985c92816",
+                "sha256:4d8d3e5aa6087490912c14a3c10fbdd380b40b421c13920ff468163bc50e016f",
+                "sha256:4f41fd159fba1245e1958a99d349df49c616b133636e0cf668f169bce2aeac2d",
+                "sha256:561ef098c50f91fbac2cc9305b68c915e9eb915a74d9038ecf8af274d748f76f",
+                "sha256:56994e14b386b5c0a9b875a76d22d707b315fa037affc7819cda08b6d0489756",
+                "sha256:73a1f2a529604c50c262179fcca59c87a05ff4614fe8a15c186934d84d09d9a5",
+                "sha256:7da99445fd890206bfcc7419f79871ba8e73d9d9e6b82fe09980bc5bb4efc35f",
+                "sha256:99d59e0bcadac4aa3280616591fb7bcd560e2218f5e31d5223a2e12a1425d495",
+                "sha256:a4cc09489843c70b22e8373ca3dfa52b3fab778b57cf81462f1203b0852e95e3",
+                "sha256:a61dc29cfca9831a03442a21d4b5fd77e3067beca4b5f81f1a89a04a71cf93fa",
+                "sha256:b1853df739b32fa913cc59ad9137caa9cc3d97ff871e2bbd89c2a2a1d4a69451",
+                "sha256:b1f44c335532c0581b77491b7715a871d0dd72e97487ac0f57337ccf3ab3469b",
+                "sha256:b261e0cb0d6faa8fd6863af26d30351fd2ffdb15b82e51e81e96b9e9e2e7ba16",
+                "sha256:c857ae5dba375ea26a6228f98c195fec0898a0fd91bcf0e8a0cae6d9faf3eca7",
+                "sha256:cf5bb4a7d53a71bb6a0144d31df784a973b36d8687d615ef6a7e9b1809917a9b",
+                "sha256:db9814ff0457b46f2e1d494c1efa4111ca089e08c8b983635ebffb9c1573361f",
+                "sha256:df04f4bad8a359daa2ff74f8108ea051670cafbca533bb2636c58b16e962989e",
+                "sha256:ecf81720934a0e18526177e645cbd6a8a21bb0ddc887ff9738de07a1df5c6b61",
+                "sha256:edfa6fba9157e0e3be0f40168eb142511012683ac3dc82420bee4a3f3981b30e"
             ],
             "index": "pypi",
-            "version": "==1.15.2"
+            "version": "==1.15.4"
+        },
+        "openpyxl": {
+            "hashes": [
+                "sha256:41eb21a5620343d715b38081536c4ed3c37249afb72e569fd2af93852ed4ddde"
+            ],
+            "index": "pypi",
+            "version": "==2.5.10"
+        },
+        "packaging": {
+            "hashes": [
+                "sha256:0886227f54515e592aaa2e5a553332c73962917f2831f1b0f9b9f4380a4b9807",
+                "sha256:f95a1e147590f204328170981833854229bb2912ac3d5f89e2a8ccd2834800c9"
+            ],
+            "version": "==18.0"
+        },
+        "pandas": {
+            "hashes": [
+                "sha256:11975fad9edbdb55f1a560d96f91830e83e29bed6ad5ebf506abda09818eaf60",
+                "sha256:12e13d127ca1b585dd6f6840d3fe3fa6e46c36a6afe2dbc5cb0b57032c902e31",
+                "sha256:1c87fcb201e1e06f66e23a61a5fea9eeebfe7204a66d99df24600e3f05168051",
+                "sha256:242e9900de758e137304ad4b5663c2eff0d798c2c3b891250bd0bd97144579da",
+                "sha256:26c903d0ae1542890cb9abadb4adcb18f356b14c2df46e4ff657ae640e3ac9e7",
+                "sha256:2e1e88f9d3e5f107b65b59cd29f141995597b035d17cc5537e58142038942e1a",
+                "sha256:31b7a48b344c14691a8e92765d4023f88902ba3e96e2e4d0364d3453cdfd50db",
+                "sha256:4fd07a932b4352f8a8973761ab4e84f965bf81cc750fb38e04f01088ab901cb8",
+                "sha256:5b24ca47acf69222e82530e89111dd9d14f9b970ab2cd3a1c2c78f0c4fbba4f4",
+                "sha256:647b3b916cc8f6aeba240c8171be3ab799c3c1b2ea179a3be0bd2712c4237553",
+                "sha256:66b060946046ca27c0e03e9bec9bba3e0b918bafff84c425ca2cc2e157ce121e",
+                "sha256:6efa9fa6e1434141df8872d0fa4226fc301b17aacf37429193f9d70b426ea28f",
+                "sha256:be4715c9d8367e51dbe6bc6d05e205b1ae234f0dc5465931014aa1c4af44c1ba",
+                "sha256:bea90da782d8e945fccfc958585210d23de374fa9294a9481ed2abcef637ebfc",
+                "sha256:d318d77ab96f66a59e792a481e2701fba879e1a453aefeebdb17444fe204d1ed",
+                "sha256:d785fc08d6f4207437e900ffead930a61e634c5e4f980ba6d3dc03c9581748c7",
+                "sha256:de9559287c4fe8da56e8c3878d2374abc19d1ba2b807bfa7553e912a8e5ba87c",
+                "sha256:f4f98b190bb918ac0bc0e3dd2ab74ff3573da9f43106f6dba6385406912ec00f",
+                "sha256:f71f1a7e2d03758f6e957896ed696254e2bc83110ddbc6942018f1a232dd9dad",
+                "sha256:fb944c8f0b0ab5c1f7846c686bc4cdf8cde7224655c12edcd59d5212cd57bec0"
+            ],
+            "index": "pypi",
+            "version": "==0.23.4"
         },
         "pillow": {
             "hashes": [
-                "sha256:00def5b638994f888d1058e4d17c86dec8e1113c3741a0a8a659039aec59a83a",
-                "sha256:026449b64e559226cdb8e6d8c931b5965d8fc90ec18ebbb0baa04c5b36503c72",
-                "sha256:03dbb224ee196ef30ed2156d41b579143e1efeb422974719a5392fc035e4f574",
-                "sha256:03eb0e04f929c102ae24bc436bf1c0c60a4e63b07ebd388e84d8b219df3e6acd",
-                "sha256:1be66b9a89e367e7d20d6cae419794997921fe105090fafd86ef39e20a3baab2",
-                "sha256:1e977a3ed998a599bda5021fb2c2889060617627d3ae228297a529a082a3cd5c",
-                "sha256:22cf3406d135cfcc13ec6228ade774c8461e125c940e80455f500638429be273",
-                "sha256:24adccf1e834f82718c7fc8e3ec1093738da95144b8b1e44c99d5fc7d3e9c554",
-                "sha256:2a3e362c97a5e6a259ee9cd66553292a1f8928a5bdfa3622fdb1501570834612",
-                "sha256:3832e26ecbc9d8a500821e3a1d3765bda99d04ae29ffbb2efba49f5f788dc934",
-                "sha256:4fd1f0c2dc02aaec729d91c92cd85a2df0289d88e9f68d1e8faba750bb9c4786",
-                "sha256:4fda62030f2c515b6e2e673c57caa55cb04026a81968f3128aae10fc28e5cc27",
-                "sha256:5044d75a68b49ce36a813c82d8201384207112d5d81643937fc758c05302f05b",
-                "sha256:522184556921512ec484cb93bd84e0bab915d0ac5a372d49571c241a7f73db62",
-                "sha256:5914cff11f3e920626da48e564be6818831713a3087586302444b9c70e8552d9",
-                "sha256:6661a7908d68c4a133e03dac8178287aa20a99f841ea90beeb98a233ae3fd710",
-                "sha256:79258a8df3e309a54c7ef2ef4a59bb8e28f7e4a8992a3ad17c24b1889ced44f3",
-                "sha256:7d74c20b8f1c3e99d3f781d3b8ff5abfefdd7363d61e23bdeba9992ff32cc4b4",
-                "sha256:81918afeafc16ba5d9d0d4e9445905f21aac969a4ebb6f2bff4b9886da100f4b",
-                "sha256:8194d913ca1f459377c8a4ed8f9b7ad750068b8e0e3f3f9c6963fcc87a84515f",
-                "sha256:84d5d31200b11b3c76fab853b89ac898bf2d05c8b3da07c1fcc23feb06359d6e",
-                "sha256:989981db57abffb52026b114c9a1f114c7142860a6d30a352d28f8cbf186500b",
-                "sha256:a3d7511d3fad1618a82299aab71a5fceee5c015653a77ffea75ced9ef917e71a",
-                "sha256:b3ef168d4d6fd4fa6685aef7c91400f59f7ab1c0da734541f7031699741fb23f",
-                "sha256:c1c5792b6e74bbf2af0f8e892272c2a6c48efa895903211f11b8342e03129fea",
-                "sha256:c5dcb5a56aebb8a8f2585042b2f5c496d7624f0bcfe248f0cc33ceb2fd8d39e7",
-                "sha256:e2bed4a04e2ca1050bb5f00865cf2f83c0b92fd62454d9244f690fcd842e27a4",
-                "sha256:e87a527c06319428007e8c30511e1f0ce035cb7f14bb4793b003ed532c3b9333",
-                "sha256:f63e420180cbe22ff6e32558b612e75f50616fc111c5e095a4631946c782e109",
-                "sha256:f8b3d413c5a8f84b12cd4c5df1d8e211777c9852c6be3ee9c094b626644d3eab"
+                "sha256:00203f406818c3f45d47bb8fe7e67d3feddb8dcbbd45a289a1de7dd789226360",
+                "sha256:0616f800f348664e694dddb0b0c88d26761dd5e9f34e1ed7b7a7d2da14b40cb7",
+                "sha256:1f7908aab90c92ad85af9d2fec5fc79456a89b3adcc26314d2cde0e238bd789e",
+                "sha256:2ea3517cd5779843de8a759c2349a3cd8d3893e03ab47053b66d5ec6f8bc4f93",
+                "sha256:48a9f0538c91fc136b3a576bee0e7cd174773dc9920b310c21dcb5519722e82c",
+                "sha256:5280ebc42641a1283b7b1f2c20e5b936692198b9dd9995527c18b794850be1a8",
+                "sha256:5e34e4b5764af65551647f5cc67cf5198c1d05621781d5173b342e5e55bf023b",
+                "sha256:63b120421ab85cad909792583f83b6ca3584610c2fe70751e23f606a3c2e87f0",
+                "sha256:696b5e0109fe368d0057f484e2e91717b49a03f1e310f857f133a4acec9f91dd",
+                "sha256:870ed021a42b1b02b5fe4a739ea735f671a84128c0a666c705db2cb9abd528eb",
+                "sha256:916da1c19e4012d06a372127d7140dae894806fad67ef44330e5600d77833581",
+                "sha256:9303a289fa0811e1c6abd9ddebfc770556d7c3311cb2b32eff72164ddc49bc64",
+                "sha256:9577888ecc0ad7d06c3746afaba339c94d62b59da16f7a5d1cff9e491f23dace",
+                "sha256:987e1c94a33c93d9b209315bfda9faa54b8edfce6438a1e93ae866ba20de5956",
+                "sha256:99a3bbdbb844f4fb5d6dd59fac836a40749781c1fa63c563bc216c27aef63f60",
+                "sha256:99db8dc3097ceafbcff9cb2bff384b974795edeb11d167d391a02c7bfeeb6e16",
+                "sha256:a5a96cf49eb580756a44ecf12949e52f211e20bffbf5a95760ac14b1e499cd37",
+                "sha256:aa6ca3eb56704cdc0d876fc6047ffd5ee960caad52452fbee0f99908a141a0ae",
+                "sha256:aade5e66795c94e4a2b2624affeea8979648d1b0ae3fcee17e74e2c647fc4a8a",
+                "sha256:b78905860336c1d292409e3df6ad39cc1f1c7f0964e66844bbc2ebfca434d073",
+                "sha256:b92f521cdc4e4a3041cc343625b699f20b0b5f976793fb45681aac1efda565f8",
+                "sha256:bfde84bbd6ae5f782206d454b67b7ee8f7f818c29b99fd02bf022fd33bab14cb",
+                "sha256:c2b62d3df80e694c0e4a0ed47754c9480521e25642251b3ab1dff050a4e60409",
+                "sha256:c5e2be6c263b64f6f7656e23e18a4a9980cffc671442795682e8c4e4f815dd9f",
+                "sha256:c99aa3c63104e0818ec566f8ff3942fb7c7a8f35f9912cb63fd8e12318b214b2",
+                "sha256:dae06620d3978da346375ebf88b9e2dd7d151335ba668c995aea9ed07af7add4",
+                "sha256:db5499d0710823fa4fb88206050d46544e8f0e0136a9a5f5570b026584c8fd74",
+                "sha256:f36baafd82119c4a114b9518202f2a983819101dcc14b26e43fc12cbefdce00e",
+                "sha256:f52b79c8796d81391ab295b04e520bda6feed54d54931708872e8f9ae9db0ea1",
+                "sha256:ff8cff01582fa1a7e533cb97f628531c4014af4b5f38e33cdcfe5eec29b6d888"
             ],
             "index": "pypi",
-            "version": "==5.2.0"
+            "version": "==5.3.0"
+        },
+        "pluggy": {
+            "hashes": [
+                "sha256:447ba94990e8014ee25ec853339faf7b0fc8050cdc3289d4d71f7f410fb90095",
+                "sha256:bde19360a8ec4dfd8a20dcb811780a30998101f078fc7ded6162f0076f50508f"
+            ],
+            "version": "==0.8.0"
+        },
+        "psutil": {
+            "hashes": [
+                "sha256:1c19957883e0b93d081d41687089ad630e370e26dc49fd9df6951d6c891c4736",
+                "sha256:1c71b9716790e202a00ab0931a6d1e25db1aa1198bcacaea2f5329f75d257fff",
+                "sha256:3b7a4daf4223dae171a67a89314ac5ca0738e94064a78d99cfd751c55d05f315",
+                "sha256:3e19be3441134445347af3767fa7770137d472a484070840eee6653b94ac5576",
+                "sha256:6e265c8f3da00b015d24b842bfeb111f856b13d24f2c57036582568dc650d6c3",
+                "sha256:809c9cef0402e3e48b5a1dddc390a8a6ff58b15362ea5714494073fa46c3d293",
+                "sha256:b4d1b735bf5b120813f4c89db8ac22d89162c558cbd7fdd298866125fe906219",
+                "sha256:bbffac64cfd01c6bcf90eb1bedc6c80501c4dae8aef4ad6d6dd49f8f05f6fc5a",
+                "sha256:bfcea4f189177b2d2ce4a34b03c4ac32c5b4c22e21f5b093d9d315e6e253cd81"
+            ],
+            "version": "==5.4.8"
+        },
+        "py": {
+            "hashes": [
+                "sha256:bf92637198836372b520efcba9e020c330123be8ce527e535d185ed4b6f45694",
+                "sha256:e76826342cefe3c3d5f7e8ee4316b80d1dd8a300781612ddbc765c17ba25a6c6"
+            ],
+            "version": "==1.7.0"
         },
         "pycodestyle": {
             "hashes": [
-                "sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766",
-                "sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9"
+                "sha256:cbc619d09254895b0d12c2c691e237b2e91e9b2ecf5e84c26b35400f93dcfb83",
+                "sha256:cbfca99bd594a10f674d0cd97a3d802a1fdef635d4361e1a2658de47ed261e3a"
             ],
-            "version": "==2.3.1"
+            "version": "==2.4.0"
         },
         "pyflakes": {
             "hashes": [
-                "sha256:08bd6a50edf8cffa9fa09a463063c425ecaaf10d1eb0335a7e8b1401aef89e6f",
-                "sha256:8d616a382f243dbf19b54743f280b80198be0bca3a5396f1d2e1fca6223e8805"
+                "sha256:9a7662ec724d0120012f6e29d6248ae3727d821bba522a0e6b356eff19126a49",
+                "sha256:f661252913bc1dbe7fcfcbf0af0db3f42ab65aabd1a6ca68fe5d466bace94dae"
+            ],
+            "version": "==2.0.0"
+        },
+        "pygments": {
+            "hashes": [
+                "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
+                "sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
             ],
-            "version": "==1.6.0"
+            "version": "==2.2.0"
         },
         "pylint": {
             "hashes": [
@@ -232,20 +510,102 @@
             "index": "pypi",
             "version": "==2.1.1"
         },
+        "pynisher": {
+            "hashes": [
+                "sha256:b4cfd460143c6651db61ef494515a9c2fc83820fdc290b7da19b6486ff1f0a6b"
+            ],
+            "version": "==0.4.2"
+        },
         "pyparsing": {
             "hashes": [
-                "sha256:905d8090c335314568b5faee0025b1829f27bb974604a5762a6cdef3a7dfc3b7",
-                "sha256:f493ee323be1e94929416b3585eefcc04943115cecbaaa35a8c86d1a2368af19"
+                "sha256:40856e74d4987de5d01761a22d1621ae1c7f8774585acae358aa5c5936c6c90b",
+                "sha256:f353aab21fd474459d97b709e527b5571314ee5f067441dc9f88e33eecd96592"
             ],
-            "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.2.*' and python_version != '3.1.*'",
-            "version": "==2.2.1"
+            "version": "==2.3.0"
+        },
+        "pyrfr": {
+            "hashes": [
+                "sha256:d0ee214c8d938c135ef951e99989b18e0b8b86885c6ae8d9869eb16a79242be4"
+            ],
+            "version": "==0.7.4"
+        },
+        "pytest": {
+            "hashes": [
+                "sha256:3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec",
+                "sha256:e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"
+            ],
+            "index": "pypi",
+            "version": "==3.10.1"
         },
         "python-dateutil": {
             "hashes": [
-                "sha256:1adb80e7a782c12e52ef9a8182bebeb73f1d7e24e374397af06fb4956c8dc5c0",
-                "sha256:e27001de32f627c22380a688bcc43ce83504a7bc5da472209b4c70f02829f0b8"
+                "sha256:063df5763652e21de43de7d9e00ccf239f953a832941e37be541614732cdfc93",
+                "sha256:88f9287c0174266bb0d8cedd395cfba9c58e87e5ad86b2ce58859bc11be3cf02"
+            ],
+            "version": "==2.7.5"
+        },
+        "pytz": {
+            "hashes": [
+                "sha256:31cb35c89bd7d333cd32c5f278fca91b523b0834369e757f4c5641ea252236ca",
+                "sha256:8e0f8568c118d3077b46be7d654cc8167fa916092e28320cde048e54bfc9f1e6"
+            ],
+            "version": "==2018.7"
+        },
+        "pyyaml": {
+            "hashes": [
+                "sha256:3d7da3009c0f3e783b2c873687652d83b1bbfd5c88e9813fb7e5b03c0dd3108b",
+                "sha256:3ef3092145e9b70e3ddd2c7ad59bdd0252a94dfe3949721633e41344de00a6bf",
+                "sha256:40c71b8e076d0550b2e6380bada1f1cd1017b882f7e16f09a65be98e017f211a",
+                "sha256:558dd60b890ba8fd982e05941927a3911dc409a63dcb8b634feaa0cda69330d3",
+                "sha256:a7c28b45d9f99102fa092bb213aa12e0aaf9a6a1f5e395d36166639c1f96c3a1",
+                "sha256:aa7dd4a6a427aed7df6fb7f08a580d68d9b118d90310374716ae90b710280af1",
+                "sha256:bc558586e6045763782014934bfaf39d48b8ae85a2713117d16c39864085c613",
+                "sha256:d46d7982b62e0729ad0175a9bc7e10a566fc07b224d2c79fafb5e032727eaa04",
+                "sha256:d5eef459e30b09f5a098b9cea68bebfeb268697f78d647bd255a085371ac7f3f",
+                "sha256:e01d3203230e1786cd91ccfdc8f8454c8069c91bee3962ad93b87a4b2860f537",
+                "sha256:e170a9e6fcfd19021dd29845af83bb79236068bf5fd4df3327c1be18182b2531"
+            ],
+            "version": "==3.13"
+        },
+        "requests": {
+            "hashes": [
+                "sha256:65b3a120e4329e33c9889db89c80976c5272f56ea92d3e74da8a463992e3ff54",
+                "sha256:ea881206e59f41dbd0bd445437d792e43906703fff75ca8ff43ccdb11f33f263"
+            ],
+            "version": "==2.20.1"
+        },
+        "scikit-learn": {
+            "hashes": [
+                "sha256:0a718b5ffbd5053fb3f9e1a2e20b7c4f256dd8035e246b907d3117d20bac0260",
+                "sha256:1725540b754a9967778e9385e1ee2c8db50d5ab70ed835c9f5e36002ffabc169",
+                "sha256:3e3ce307d7c5c5811658ba8686b24b571a8244eaafe707665ad601f400d5ce98",
+                "sha256:42ad71502237c9fe300ecf157f5a394df717789a2dde541dd7034b539c70bdcc",
+                "sha256:42cba716db197e0d1670e2fc13c4cc4a86d5c5358120ccfee6ec427b154e74ff",
+                "sha256:47b4090b7686642e41176becb7c42ef3cc665d7ee0db5e7ea5d307ec9779327e",
+                "sha256:51d99a08c8bf689cf60c9d8dca6e3d3e5f6d762def85ad735dcea11fb528a89b",
+                "sha256:5f7577fbb2399a4712e96cf0e786638168940a876c33735a1b5d5a86ba4b1370",
+                "sha256:66bfc2b6b15db1725d03ea657ec9184ff09dcbf1ecd834ef85f2edc2c9cbba97",
+                "sha256:69a34d389d9ca4687ad00af4e11d53686771f484c37366f68617ef656bab16ab",
+                "sha256:75297f3dd6685f01555f1bb75846995d45650af417280b69c81bf11b6987aed5",
+                "sha256:9ebb38ab1d0ee143982aed561811903ac6c1abb512ae2b9019b3b65bde63ffb9",
+                "sha256:a402c1484fe65df42d5dbc22a58e0695fe3afe2b0b229aee2a09c6d60ba8e5c2",
+                "sha256:aad6b9aac1617bd7efa0450643888bbd3410679a94bc8680d9863825686ef369",
+                "sha256:ad4db28d3dc16c01df75ed6efb72524537de3839a5d179fcf94094359fc72ec5",
+                "sha256:b276739a5f863ccacb61999a3067d0895ee291c95502929b2ae56ea1f882e888",
+                "sha256:b3dc88c4d2bcb26ffc5afe16d053ae28317d7d1de083651defcd5453a04f1563",
+                "sha256:b3e4681253e95da5aa5c231889a32b084fd997962bf8beda6f796bf422f734b2",
+                "sha256:c3d852d49d6c1710089d4513702099fa6f8e1aebfedf222319d80c47b0a195f8",
+                "sha256:c6612e7e43988b8b5e1957150449493a55f9c059de641083df7a964f86f2d1e7",
+                "sha256:c69e5c6051366a6ac9600d730276db939b1a205e42504ec0b8371f154b0058db",
+                "sha256:ce121baa8e85ec27c3065281657dcd78adaab7dcb046c7fe96ad4e5a9dcb6610",
+                "sha256:ed2a9a9bea6ec443b7effe5695c9c168b7bf9a67df6d880729760feda871b6a3",
+                "sha256:efd842d70b87e3ef3429c3149840b9189d4441ca951ab0cec62c94a964e219d9",
+                "sha256:f1428af5c381f6eef30ffbc7e047b7c713d4efa5d7bf5e57b62b3fc8d387044b",
+                "sha256:f6c7bf8cd4de1640b760b47f4d28deb26dbbf9acbe0194cdff54a898e190d872",
+                "sha256:f8329ac2160ad8bbbac6a507374685ceca3f24ca427fa9ee61a501280e1972d9",
+                "sha256:fefba2a43b92f8393366093b60efbe984a72a2b41cce16b4002005e4104ef938"
             ],
-            "version": "==2.7.3"
+            "version": "==0.19.2"
         },
         "scipy": {
             "hashes": [
@@ -288,6 +648,40 @@
             ],
             "version": "==1.11.0"
         },
+        "smac": {
+            "hashes": [
+                "sha256:dd4520a1ec4292302fa8115f7d9d9045eb2e12b3a3d7b215cfc1f8073891e6ee"
+            ],
+            "version": "==0.8.0"
+        },
+        "snowballstemmer": {
+            "hashes": [
+                "sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128",
+                "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89"
+            ],
+            "version": "==1.2.1"
+        },
+        "sphinx": {
+            "hashes": [
+                "sha256:120732cbddb1b2364471c3d9f8bfd4b0c5b550862f99a65736c77f970b142aea",
+                "sha256:b348790776490894e0424101af9c8413f2a86831524bd55c5f379d3e3e12ca64"
+            ],
+            "version": "==1.8.2"
+        },
+        "sphinx-rtd-theme": {
+            "hashes": [
+                "sha256:02f02a676d6baabb758a20c7a479d58648e0f64f13e07d1b388e9bb2afe86a09",
+                "sha256:d0f6bc70f98961145c5b0e26a992829363a197321ba571b31b24ea91879e0c96"
+            ],
+            "version": "==0.4.2"
+        },
+        "sphinxcontrib-websupport": {
+            "hashes": [
+                "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd",
+                "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9"
+            ],
+            "version": "==1.1.0"
+        },
         "typed-ast": {
             "hashes": [
                 "sha256:0948004fa228ae071054f5208840a1e88747a357ec1101c17217bfe99b299d58",
@@ -317,11 +711,32 @@
             "markers": "python_version < '3.7' and implementation_name == 'cpython'",
             "version": "==1.1.0"
         },
+        "typing": {
+            "hashes": [
+                "sha256:4027c5f6127a6267a435201981ba156de91ad0d1d98e9ddc2aa173453453492d",
+                "sha256:57dcf675a99b74d64dacf6fba08fb17cf7e3d5fdff53d4a30ea2a5e7e52543d4",
+                "sha256:a4c8473ce11a65999c8f59cb093e70686b6c84c98df58c1dae9b3b196089858a"
+            ],
+            "version": "==3.6.6"
+        },
+        "urllib3": {
+            "hashes": [
+                "sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
+                "sha256:de9529817c93f27c8ccbfead6985011db27bd0ddfcdb2d86f3f663385c6a9c22"
+            ],
+            "version": "==1.24.1"
+        },
         "wrapt": {
             "hashes": [
                 "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6"
             ],
             "version": "==1.10.11"
+        },
+        "xgboost": {
+            "hashes": [
+                "sha256:4224193159763ab50352b3c53087510a9ebef4c9dcbafb5c5f8c7e2a1d6d7b70"
+            ],
+            "version": "==0.7.post3"
         }
     },
     "develop": {}
diff --git a/explore_auto_scikit.py b/explore_auto_scikit.py
new file mode 100644
index 0000000000000000000000000000000000000000..3878d0cca9da8c15e7e9ad7a9c12dc6e3eb9e05b
--- /dev/null
+++ b/explore_auto_scikit.py
@@ -0,0 +1,421 @@
+import shutil
+import glob
+import pickle
+import os
+import traceback
+import time
+import autosklearn.classification
+import sys
+from extraction.retrieve_battery_data import extract_charge_discharge_impedance
+from functools import reduce
+import itertools
+import numpy as np
+import sklearn.model_selection
+import sklearn.datasets
+import sklearn.metrics
+import multiprocessing
+from concurrent.futures import ThreadPoolExecutor
+from autosklearn.constants import *
+from autosklearn.classification import AutoSklearnClassifier
+from autosklearn.metrics import accuracy
+from sklearn.metrics import precision_recall_fscore_support
+from sklearn.metrics import f1_score
+from sklearn.externals import joblib
+from sklearn.metrics import confusion_matrix
+import pandas as pd
+# import concurrent.futures
+# np.set_printoptions(threshold=np.nan)
+
+SEPARATOR = "-----------------------------------"
+RESULTS_FOLDER = "current_results"
+MODEL_FILE_SEP = "___"
+
+def chunk_it(seq, num):
+    avg = len(seq) / float(num)
+    last = 0
+    out = []
+
+    while last <= num:
+        res = [last] * (len(seq[int(last*avg):int((last + 1) * avg)]))
+        out += res
+        last += 1
+
+    return out
+
+# DISCRETISATION_TYPES = ["mean", "median", "standard-deviation"]
+DISCRETISATION_TYPES = [
+    "mean", "gradiant_mean",
+    "median", "gradiant_median",
+    "standard-deviation", "gradiant_std",
+]
+
+BATTERY_BASE = "./data/BatteryAgingARC_25-44/"
+TEST_BATTERIES = [BATTERY_BASE + "B0025.mat"]
+ALL_BATTERIES = [
+    # BATTERY_BASE + "B0025.mat",
+    BATTERY_BASE + "B0026.mat",
+    BATTERY_BASE + "B0027.mat",
+    BATTERY_BASE + "B0028.mat",
+    # BATTERY_BASE + "B0033.mat",
+    # BATTERY_BASE + "B0034.mat",
+]
+
+charges_params = [
+    "voltage_measured",
+    "current_measured",
+    "temperature_measured",
+    "current_charge",
+    "voltage_charge",
+]
+discharges_params = charges_params + ["capacity"] # capacity not same length
+impedance_params = [
+    # "re", # float_
+    # "rct", # float_
+    "sense_current", # Complexes
+    "battery_current", # Complexes
+    "current_ratio", # Complexes
+    "battery_impedance", # Complexes but multiple array of 1 complexe
+    # "rectified_impedance", # Complexes but multiple array of 1 complexe # not same length
+]
+
+
+def discretize(array, discretisation):
+    # array split should copy when split > lenght instead of empty arrays
+    splitted = np.array_split(array, discretisation["split"])
+
+    out = []
+    if "mean" in discretisation["types"]:
+        out.append([np.mean(split) for split in splitted])
+    if "median" in discretisation["types"]:
+        out.append([np.median(split) for split in splitted])
+    if "standard deviation" in discretisation["types"]:
+        out.append([np.std(split) for split in splitted])
+
+    splitted_gradient = np.array_split(np.gradient(array), discretisation["split"])
+    if "gradiant_mean" in discretisation["types"]:
+        out.append([np.mean(split) for split in splitted_gradient])
+    if "gradiant_median" in discretisation["types"]:
+        out.append([np.median(split) for split in splitted_gradient])
+    if "gradiant_std" in discretisation["types"]:
+        out.append([np.std(split) for split in splitted_gradient])
+
+    return out
+    # out = np.array(out)
+
+    # return out.T
+
+
+def append_params(result_cycles, cycles, used_parameters, discretisation):
+    """One line contain 1 moment of every feature"""
+    total_cycles_length = 0
+    for cycle in cycles:
+        # # Raw
+        # cycle_length = len(cycle[used_parameters[0]])
+        # total_cycles_length += cycle_length
+        # for i in range(cycle_length):
+        #     time_slice = []
+        #     for param in used_parameters:
+        #         time_slice.append(np.nan_to_num(cycle[param][i]))
+        #     result_cycles.append(time_slice)
+
+        # Discretisation
+        cycle_length = len(cycle[used_parameters[0]])
+        if cycle_length < discretisation["split"]:
+            raise "Discretisation split is too big in comparison with cycle length"
+
+        discretized = []
+        for param in used_parameters:
+            np.nan_to_num(cycle[param], copy=False)
+            mean_median_std = discretize(cycle[param], discretisation)
+            discretized += mean_median_std
+
+        transposed_discretized = np.array(discretized).T
+        for time_slice in transposed_discretized:
+            result_cycles.append(time_slice)
+
+        total_cycles_length += len(transposed_discretized)
+        # CycleWay
+        # reduce all features together but before, each feature length N should be reduced to a fixed length
+        # result_cycles.append(np.nan_to_num(np.array(
+        #     reduce((lambda acc, param: acc + cycle[param].tolist()), used_parameters, [])
+        # )))
+    return total_cycles_length
+
+
+def combinations(array):
+    return list(itertools.chain(*[itertools.combinations(array,i+1) for i,_ in enumerate(array)]))
+
+
+def get_charges(filepath):
+    charge_cycles, discharge_cycles, impedance_cycles = extract_charge_discharge_impedance(filepath)
+    return charge_cycles
+
+
+def get_discharges(filepath):
+    charge_cycles, discharge_cycles, impedance_cycles = extract_charge_discharge_impedance(filepath)
+    return discharge_cycles
+
+
+def get_impedance(filepath):
+    charge_cycles, discharge_cycles, impedance_cycles = extract_charge_discharge_impedance(filepath)
+    return impedance_cycles
+
+
+def load_batteries(extract_function, params, all_batteries=ALL_BATTERIES, class_count=-3, discretisation=None):
+    all_batteries_number = [bat.split(os.sep)[-1].split(".")[0] for bat in all_batteries]
+    # cycles_filename = "data__" + "-".join(params) + "__" + "-".join(all_batteries_number) + "__" + str(class_count) + ".p"
+    cycles_filename = "__".join([
+        "batteries_data_temp/data",
+        "-".join(params),
+        "-".join(all_batteries_number),
+        str(class_count),
+        "-".join(discretisation["types"]),
+        str(discretisation["split"]),
+    ]) + ".p"
+    X_cycles = []
+    y_cycles = []
+
+    if os.path.exists(cycles_filename):
+        loaded = pickle.load( open(cycles_filename, "rb") )
+        return loaded["x"], loaded["y"]
+    else:
+        for filepath in all_batteries:
+            cycles = extract_function(filepath)
+            # charge_cycles, discharge_cycles, impedance_cycles = extract_charge_discharge_impedance(filepath)
+
+            total_cycles_length = append_params(X_cycles, cycles, params, discretisation)
+
+            # add labels
+            y_cycles += chunk_it([-1]*total_cycles_length, class_count) # cycle way
+
+        # X_cycles = np.zeros([len(X_cycles),len(max(X_cycles,key = lambda x: len(x)))]) # padding #CycleWay
+        X_cycles = np.array(X_cycles)
+        y_cycles = np.array(y_cycles)
+        pickle.dump( {"x": X_cycles, "y": y_cycles} , open( cycles_filename, "wb" ) )
+        return X_cycles, y_cycles
+
+
+def save_dataframe(cv_results, model_file_name):
+    df = pd.DataFrame(cv_results)
+
+    writer = pd.ExcelWriter(model_file_name + ".xlsx")
+    df.to_excel(writer, "automl_dataframe")
+    writer.save()
+
+
+def auto_ML(options):
+    title, params, extract_function, class_count, discretisation, folds = options
+    print("--------------------------------------------------------------------------------")
+    print(title)
+    print(params)
+    print("--------------------------------------------------------------------------------")
+
+    X_cycles, y_cycles = load_batteries(extract_function, params, ALL_BATTERIES, class_count, discretisation)
+    # y_cycles = chunk_it(X_cycles, class_count) can be removed
+    # y_cycles = np.array(y_cycles) can be removed
+
+
+    print(X_cycles.shape)
+    print(y_cycles.shape)
+    # before split and are OK
+    #  40'000 inputs and 6 classes CV !not certain!
+    # 930'000 inputs and 6 classes holdout !not certain!
+    #  25'860 inputs and 3 classes CV
+    MAX_SIZE = 258600000
+
+    X_train, X_test, y_train, y_test = \
+        sklearn.model_selection.train_test_split(X_cycles, y_cycles, random_state=1)
+
+    X_train = X_train[:MAX_SIZE]
+    y_train = y_train[:MAX_SIZE]
+
+    # 0.3 is quite good
+    # k = 0.3
+    k = 0.5
+    automl = autosklearn.classification.AutoSklearnClassifier(
+        # time_left_for_this_task=69,
+        # per_run_time_limit=35,
+        time_left_for_this_task=int(3600*k),
+        per_run_time_limit=int(360*k),
+        ensemble_size=int(50),
+        ensemble_nbest=int(200),
+        # ml_memory_limit=1024,
+        # shared_mode=True,
+        # ensemble_size=50,
+        # ensemble_nbest=200,
+        # tmp_folder=tmp_folder,
+        # TODO Use CV instead of HOLDOUT
+        # resampling_strategy='holdout',
+        resampling_strategy='cv',
+        resampling_strategy_arguments={'folds': folds},
+        # output_folder=output_folder,
+        # initial_configurations_via_metalearning=0,
+        # seed=SEED,
+        # time_left_for_this_task=3600*18,
+        # per_run_time_limit=360*18,
+        ml_memory_limit=28024,
+        # delete_tmp_folder_after_terminate=False,
+        # delete_output_folder_after_terminate=False,
+    )
+
+    automl.fit(X_train.copy(), y_train.copy())
+    if automl.resampling_strategy == "cv":
+        automl.refit(X_train.copy(), y_train.copy())
+    y_pred = automl.predict(X_test, n_jobs=-1)
+
+    model_file_name = os.path.join(RESULTS_FOLDER, MODEL_FILE_SEP.join([
+        title,
+        "-".join(params),
+        str(class_count),
+        "-".join(discretisation["types"]),
+        str(discretisation["split"]),
+        "folds" + str(folds),
+    ]) + ".joblib")
+    print(model_file_name)
+    save_dataframe(automl.cv_results_, model_file_name[:-7])
+
+    joblib.dump(automl, model_file_name)
+
+    test_battery_result = test_model_with_test_battery(model_file_name)
+
+    results = [
+        title,
+        "Params: " + str(params),
+        "Discretisation: " + str(discretisation),
+        "Class count: " + str(class_count),
+        "Folds: " + str(folds),
+        "Accuracy score: " + str(sklearn.metrics.accuracy_score(y_test, y_pred)),
+        "F1 score: " + str(precision_recall_fscore_support(y_test, y_pred, average="weighted")),
+        str(confusion_matrix(y_test, y_pred)),
+    ] + test_battery_result + [
+        str(automl.sprint_statistics()),
+        str(automl.show_models()),
+        # str(automl.cv_results_),
+    ]
+    print(results)
+    return results
+
+
+def get_options(min_length=0):
+    class_count = 3
+    # 10, 50, 100, 200
+    charge_options = []
+    discharge_options = []
+    impedance_options = []
+    # charge_options = [("charge", param, get_charges, class_count) for param in combinations(charges_params) if len(param) >= min_length]
+    # charge_options = [("charge", charges_params, get_charges, class_count, {"types": discre_type, "split":100}) for discre_type in combinations(DISCRETISATION_TYPES)]
+    # discharge_options = [("discharge", charges_params, get_discharges, class_count, {"types": discre_type, "split":100}) for discre_type in combinations(DISCRETISATION_TYPES)]
+    # discharge_options = [("discharge", param, get_discharges, class_count) for param in combinations(charges_params) if len(param) >= min_length]
+    # impedance_options = [("impedance", param, get_impedance, class_count) for param in combinations(impedance_params) if len(param) >= min_length]
+    # charge_options = [("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":split}) for split in range(1,11)]
+    charge_options = [
+        # ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":10}, 10),
+        ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":6}, 5),
+        ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":6}, 10),
+        ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":6}, 15),
+        ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":6}, 20),
+        # ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":50}, 10),
+        # ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":100}, 10),
+        # # ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":1}, 10),
+        # ("charge", charges_params, get_charges, class_count, {"types": DISCRETISATION_TYPES, "split":200}, 10),
+    ]
+    # discharge_options = [("discharge", charges_params, get_discharges, class_count, {"types": DISCRETISATION_TYPES, "split":100})]
+    # impedance_options = [("impedance", impedance_params, get_impedance, class_count, {"types": DISCRETISATION_TYPES, "split":20})]
+    all_options = discharge_options + impedance_options + charge_options
+
+    return all_options
+
+def writeln(file, text):
+    file.write(text + "\n")
+
+
+def init_folder():
+    if os.path.exists(RESULTS_FOLDER):
+        shutil.rmtree(RESULTS_FOLDER)
+    if not os.path.exists(RESULTS_FOLDER):
+        os.makedirs(RESULTS_FOLDER)
+    results_file = os.path.join(RESULTS_FOLDER, "result.txt")
+    failed_file = os.path.join(RESULTS_FOLDER, "failed.txt")
+    open(results_file, 'w').close()
+    open(failed_file, 'w').close()
+    return results_file, failed_file
+
+
+def execute_auto_ML():
+    start_time = time.time()
+    print(start_time)
+    all_options = get_options(min_length=0)
+
+    results_file, failed_file = init_folder()
+
+    # results = list(map(auto_ML, all_options))
+    for option in all_options:
+        try:
+            result = auto_ML(option)
+            with open(results_file, 'a') as the_file:
+                writeln(the_file, SEPARATOR)
+                for line in result:
+                    writeln(the_file, str(line))
+                writeln(the_file, SEPARATOR)
+        except:
+            with open(failed_file, 'a') as the_file:
+                writeln(the_file, SEPARATOR)
+                writeln(the_file, str(option))
+                writeln(the_file, str(traceback.format_exc()))
+                writeln(the_file, SEPARATOR)
+
+
+    seconds = time.time() - start_time
+    print("execution time", int(seconds / 60 / 60), "h", int(seconds / 60) % 60, "m", int(seconds) % 60, "s")
+
+
+def test_model_with_test_battery(model_filepath):
+    batteries = TEST_BATTERIES
+    clean_model_filepath = model_filepath.split(os.sep)[-1].split(".")[0].split(MODEL_FILE_SEP)
+
+    params = clean_model_filepath[1].split("-")
+    class_count = int(clean_model_filepath[2])
+    discretisation = {
+        "types": clean_model_filepath[3].split("-"),
+        "split": int(clean_model_filepath[4]),
+    }
+
+    if clean_model_filepath[0] == "charge":
+        extract_function = get_charges
+    if clean_model_filepath[0] == "discharge":
+        extract_function = get_discharges
+    if clean_model_filepath[0] == "impedance":
+        extract_function = get_impedance
+
+    X_cycles, y_true = load_batteries(extract_function, params, batteries, class_count, discretisation)
+
+    try:
+        loaded_automl = joblib.load(model_filepath)
+    except:
+        print("Error in model loading-> " + model_filepath)
+
+    print(loaded_automl)
+    y_pred = loaded_automl.predict(X_cycles, n_jobs=-1)
+
+    result = [
+        "Batteries: " + str(batteries),
+        "Accuracy score for battery: " + str(sklearn.metrics.accuracy_score(y_true, y_pred)),
+        str(precision_recall_fscore_support(y_true, y_pred, average="weighted")),
+        str(confusion_matrix(y_true, y_pred)),
+    ]
+    return result
+
+
+def test_models_with_test_battery(folder_to_test=RESULTS_FOLDER):
+    # get all model inside the folder
+    for model_filepath in glob.glob(folder_to_test+os.sep+"*.joblib"):
+        results = test_model_with_test_battery(model_filepath)
+        for result in results:
+            print(result)
+
+
+if __name__ == "__main__":
+    # print(test_model_with_test_battery("results/004_fixed_labels_1h_charge/charge___voltage_measured-current_measured-temperature_measured-current_charge-voltage_charge___3.joblib"))
+    execute_auto_ML()
+    # print(discretize(np.array([1,2,3,4,5,6,7,8,9,10,11,12]), {"types": ["mean", "median", "standard deviation"], "split": 4}))
+    # test_models_with_test_battery("results/004_fixed_labels_1h_charge/")