From bfe247380da24c44f506beaecb46fb2bf28a6ea6 Mon Sep 17 00:00:00 2001 From: maximus-victor Date: Thu, 13 Jul 2023 19:24:36 +0200 Subject: [PATCH 01/14] classic missing ; --- src/util/Logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/Logger.cpp b/src/util/Logger.cpp index 1d96b5b4f..e9efb8e1b 100644 --- a/src/util/Logger.cpp +++ b/src/util/Logger.cpp @@ -143,7 +143,7 @@ void Logger::logResourceUsage() { logLine(" File system outputs: " + std::to_string(usage_info.ru_oublock)); #else - logLine("No resource usage information available. Only works under linux.") + logLine("No resource usage information available. Only works under linux."); #endif } From 9b2144a1cd9f646d2be15715b42a19c6c5ebebb2 Mon Sep 17 00:00:00 2001 From: Maximilian Harl Date: Sat, 5 Aug 2023 12:25:24 +0200 Subject: [PATCH 02/14] cov push w req errors --- data/COV_TEST/EpiGEN_RND_COV.csv | 1601 ++++++++++++++++++++++++++++++ src/model/bayesian_model.hpp | 2 + src/model/bayesian_model.ipp | 11 +- src/model/instance.hpp | 4 + src/model/instance.ipp | 9 + src/model/penetrance_model.hpp | 2 + src/model/penetrance_model.ipp | 17 +- src/model/regression_model.ipp | 10 +- src/model/variance_model.hpp | 1 + src/model/variance_model.ipp | 10 +- test/unit/src/bayesian_model.cpp | 17 +- 11 files changed, 1664 insertions(+), 20 deletions(-) create mode 100644 data/COV_TEST/EpiGEN_RND_COV.csv diff --git a/data/COV_TEST/EpiGEN_RND_COV.csv b/data/COV_TEST/EpiGEN_RND_COV.csv new file mode 100644 index 000000000..966d02681 --- /dev/null +++ b/data/COV_TEST/EpiGEN_RND_COV.csv @@ -0,0 +1,1601 @@ +ID,COV1,COV2,COV3 +1,1.4,0.3,1.1 +2,1.8,1.7,0.3 +3,1.4,0.1,1.9 +4,1.9,1.3,1.1 +5,0.2,0.0,0.3 +6,1.2,0.7,1.7 +7,1.0,0.3,0.6 +8,0.7,1.8,1.7 +9,0.3,1.3,2.0 +10,1.8,1.3,1.7 +11,0.0,0.7,0.5 +12,0.5,1.8,0.2 +13,1.9,1.1,1.0 +14,1.9,1.3,0.1 +15,0.2,1.5,1.4 +16,1.9,1.5,0.2 +17,0.3,1.6,0.2 +18,1.8,0.7,1.0 +19,0.6,2.0,1.8 +20,0.1,0.3,0.1 +21,0.5,1.3,0.2 +22,1.8,0.9,1.6 +23,1.2,1.9,0.3 +24,0.9,1.0,0.8 +25,0.4,0.1,0.6 +26,1.1,0.7,1.7 +27,0.6,1.1,1.4 +28,0.7,0.6,0.0 +29,2.0,1.2,1.2 +30,0.2,0.9,2.0 +31,1.3,0.6,1.4 +32,1.3,1.9,0.6 +33,1.8,1.4,1.1 +34,1.4,0.3,0.3 +35,1.3,0.0,1.2 +36,1.5,1.1,2.0 +37,1.6,1.0,1.0 +38,1.3,1.4,0.4 +39,0.2,0.8,0.7 +40,2.0,0.2,0.4 +41,1.2,0.2,1.7 +42,0.9,0.9,1.3 +43,0.6,1.6,1.5 +44,1.6,1.0,1.9 +45,0.0,1.3,1.3 +46,0.0,1.9,1.5 +47,1.4,0.6,0.6 +48,0.4,1.2,0.3 +49,1.4,1.4,1.2 +50,0.6,0.3,1.1 +51,0.0,1.1,1.3 +52,0.6,1.9,1.1 +53,1.0,1.7,1.4 +54,1.3,0.8,1.0 +55,1.2,0.1,1.1 +56,0.5,0.1,0.2 +57,1.4,0.5,0.4 +58,1.7,2.0,1.6 +59,0.3,1.1,0.5 +60,0.7,1.3,0.3 +61,0.4,1.5,0.3 +62,1.0,1.7,0.5 +63,0.8,1.3,1.1 +64,0.3,1.7,1.8 +65,0.8,1.6,1.1 +66,1.3,0.9,0.6 +67,1.2,0.3,0.3 +68,0.9,0.1,0.3 +69,1.2,0.3,0.3 +70,0.1,0.0,0.2 +71,0.6,0.5,0.6 +72,0.8,1.6,1.8 +73,0.7,1.1,0.2 +74,1.3,1.6,1.5 +75,0.5,1.5,1.2 +76,0.7,0.8,1.1 +77,1.8,0.9,1.9 +78,0.9,0.3,1.5 +79,1.4,0.7,1.6 +80,0.3,1.5,0.4 +81,0.7,1.9,1.8 +82,1.5,0.2,1.8 +83,0.0,1.0,1.0 +84,1.8,0.7,0.1 +85,1.1,1.7,0.5 +86,2.0,1.6,1.2 +87,1.6,0.1,0.7 +88,0.1,0.5,1.5 +89,0.2,0.4,2.0 +90,1.3,0.5,0.3 +91,0.4,0.0,1.2 +92,1.4,1.7,0.5 +93,0.2,0.6,0.8 +94,1.6,1.8,1.0 +95,1.5,1.6,0.3 +96,0.9,0.8,0.3 +97,0.6,0.9,1.6 +98,0.4,1.3,0.9 +99,0.4,1.9,0.1 +100,1.1,1.9,0.8 +101,1.9,0.8,1.9 +102,1.1,0.5,0.1 +103,1.8,1.8,0.9 +104,1.5,1.2,0.8 +105,1.5,0.7,0.9 +106,1.2,1.9,0.9 +107,2.0,1.0,2.0 +108,1.8,1.0,1.5 +109,1.6,0.1,0.1 +110,1.6,0.8,1.1 +111,1.1,1.6,1.9 +112,0.9,1.7,1.4 +113,1.9,0.1,0.6 +114,1.2,1.3,0.1 +115,0.1,0.4,1.8 +116,0.3,0.5,0.3 +117,1.4,1.3,0.1 +118,0.4,1.0,0.5 +119,1.2,0.0,1.7 +120,1.1,1.5,1.6 +121,0.0,1.1,1.4 +122,1.2,0.3,1.1 +123,2.0,0.3,0.2 +124,0.7,1.2,1.0 +125,2.0,1.4,0.1 +126,0.5,0.5,1.1 +127,0.7,0.6,1.0 +128,0.7,1.5,0.2 +129,1.0,0.2,1.4 +130,1.6,1.6,1.7 +131,0.8,0.2,0.8 +132,0.6,1.9,0.1 +133,0.9,1.0,0.7 +134,1.7,1.6,0.0 +135,1.8,0.1,1.4 +136,0.7,0.9,1.4 +137,1.9,0.2,0.5 +138,0.7,0.9,0.2 +139,1.1,1.6,1.5 +140,0.7,0.9,1.2 +141,1.8,0.5,1.7 +142,1.3,1.6,1.1 +143,0.8,1.5,1.5 +144,1.5,0.1,1.1 +145,0.9,1.7,1.5 +146,0.3,1.0,1.8 +147,0.1,0.6,1.5 +148,1.6,2.0,1.9 +149,1.9,0.2,0.2 +150,1.9,0.2,0.9 +151,0.2,1.7,1.2 +152,2.0,1.1,0.9 +153,1.4,0.2,0.8 +154,2.0,2.0,1.7 +155,1.4,2.0,1.5 +156,0.1,0.3,1.0 +157,1.3,0.1,1.4 +158,1.4,0.6,1.2 +159,1.1,0.6,1.6 +160,1.3,0.1,1.8 +161,0.3,0.1,1.1 +162,1.6,1.7,0.2 +163,1.5,1.6,1.2 +164,1.8,0.7,1.9 +165,1.6,1.8,1.1 +166,0.6,1.1,1.3 +167,1.9,0.4,1.2 +168,0.6,0.7,0.1 +169,1.2,1.1,0.3 +170,1.2,1.3,1.1 +171,1.2,1.4,0.8 +172,1.0,1.7,0.1 +173,1.2,0.4,0.9 +174,0.7,1.5,1.9 +175,1.4,0.3,0.0 +176,1.1,0.2,0.6 +177,1.4,1.8,0.3 +178,0.2,0.1,1.5 +179,0.4,1.7,0.1 +180,0.2,1.5,1.2 +181,0.5,1.2,1.6 +182,1.0,0.4,1.7 +183,1.7,0.5,1.9 +184,0.9,1.5,1.9 +185,0.9,0.0,1.2 +186,0.8,0.6,0.6 +187,0.6,0.3,0.6 +188,0.4,0.0,1.0 +189,0.5,1.4,0.7 +190,1.0,0.6,0.9 +191,0.9,1.1,1.3 +192,1.7,0.4,0.6 +193,0.3,1.1,0.8 +194,0.1,0.0,0.4 +195,1.6,0.7,1.6 +196,1.9,1.7,1.9 +197,1.7,0.8,1.9 +198,0.4,1.1,0.7 +199,1.7,0.3,0.6 +200,0.5,1.3,1.8 +201,1.2,0.9,1.4 +202,0.0,1.8,1.2 +203,0.8,1.5,1.2 +204,1.4,0.9,0.1 +205,0.3,1.1,0.8 +206,0.6,1.7,0.1 +207,2.0,0.0,2.0 +208,0.0,1.5,0.9 +209,1.2,1.3,1.7 +210,0.8,1.3,0.5 +211,1.1,1.4,0.9 +212,2.0,0.7,0.9 +213,0.3,0.3,0.7 +214,0.3,0.7,0.2 +215,2.0,1.8,0.4 +216,2.0,0.1,0.6 +217,1.8,1.5,0.9 +218,0.8,0.8,0.9 +219,1.1,1.7,0.9 +220,0.8,1.9,0.3 +221,0.2,0.7,0.1 +222,1.2,1.9,0.1 +223,1.3,1.9,0.9 +224,1.2,0.8,0.4 +225,0.8,1.9,1.6 +226,1.9,0.5,0.7 +227,1.0,1.0,1.9 +228,0.4,1.4,0.4 +229,0.3,0.7,1.2 +230,1.2,0.1,0.7 +231,1.1,1.9,0.7 +232,1.4,1.9,0.2 +233,1.4,1.7,0.6 +234,0.6,1.5,2.0 +235,0.8,0.6,1.1 +236,1.0,0.1,0.3 +237,0.6,0.5,1.6 +238,2.0,0.2,1.7 +239,1.1,1.1,0.3 +240,1.9,1.6,1.0 +241,0.8,0.8,0.9 +242,1.9,1.0,0.4 +243,1.8,1.3,0.7 +244,2.0,1.8,1.3 +245,1.7,1.5,0.7 +246,0.4,1.4,0.4 +247,0.5,1.0,1.2 +248,1.3,0.1,1.1 +249,0.7,1.8,0.5 +250,0.5,1.1,0.2 +251,1.1,1.7,0.3 +252,1.2,0.6,0.4 +253,1.9,0.9,1.4 +254,1.5,1.1,1.8 +255,0.7,0.1,0.8 +256,0.0,1.2,0.0 +257,1.2,1.8,0.1 +258,1.3,2.0,1.3 +259,0.9,1.3,1.5 +260,0.2,0.7,0.5 +261,0.1,1.5,0.1 +262,0.8,0.7,1.2 +263,0.9,0.3,1.1 +264,0.8,0.8,0.7 +265,0.1,1.0,1.2 +266,0.3,1.1,1.8 +267,0.2,0.8,0.1 +268,1.8,0.4,0.2 +269,0.5,2.0,1.4 +270,1.9,0.9,0.9 +271,0.7,1.0,0.3 +272,1.9,1.7,1.3 +273,1.2,1.5,1.3 +274,1.1,1.2,0.4 +275,1.8,0.6,0.8 +276,1.4,1.9,0.3 +277,1.5,1.1,0.1 +278,0.3,0.8,0.5 +279,0.5,1.8,1.8 +280,0.7,1.3,1.8 +281,1.8,1.8,1.6 +282,1.1,1.8,1.2 +283,0.9,0.4,1.3 +284,1.9,0.8,0.1 +285,0.2,0.2,0.9 +286,0.5,1.7,1.4 +287,1.2,1.4,0.5 +288,1.7,1.0,1.9 +289,1.6,1.8,1.4 +290,0.5,1.5,1.2 +291,1.1,1.3,0.3 +292,1.9,0.8,0.7 +293,1.5,1.0,1.6 +294,1.4,1.7,1.3 +295,1.0,0.5,1.1 +296,0.3,0.4,1.7 +297,0.7,0.5,1.6 +298,1.7,1.4,0.2 +299,0.2,1.3,0.6 +300,0.4,1.5,0.5 +301,0.8,0.7,1.3 +302,2.0,0.6,0.3 +303,1.7,1.5,0.6 +304,1.1,0.9,1.1 +305,0.7,1.2,1.4 +306,1.8,1.7,0.0 +307,0.4,1.8,0.6 +308,1.1,0.9,0.4 +309,2.0,2.0,2.0 +310,1.5,1.7,1.7 +311,1.6,0.3,1.1 +312,0.1,0.5,0.7 +313,0.5,0.1,0.7 +314,1.4,0.7,0.4 +315,1.0,1.2,0.3 +316,0.7,1.1,1.7 +317,1.2,0.9,1.3 +318,0.1,0.8,0.9 +319,0.2,1.6,0.3 +320,0.8,0.8,1.9 +321,1.4,0.4,1.7 +322,0.6,0.8,0.7 +323,0.8,0.3,0.7 +324,0.1,1.4,0.2 +325,0.5,1.4,1.0 +326,1.0,0.4,1.1 +327,1.9,1.0,2.0 +328,1.7,1.5,1.2 +329,1.7,2.0,0.8 +330,1.8,1.1,1.8 +331,0.1,0.3,0.2 +332,0.3,1.1,0.6 +333,0.1,1.7,0.9 +334,0.6,0.0,1.7 +335,0.7,1.5,2.0 +336,0.4,0.1,0.3 +337,1.4,0.1,1.9 +338,1.9,1.5,1.9 +339,0.6,0.3,1.2 +340,1.8,1.9,1.4 +341,1.7,1.4,1.5 +342,0.7,0.3,1.6 +343,1.8,0.2,0.4 +344,1.6,1.0,1.4 +345,1.1,2.0,0.7 +346,0.4,1.9,1.4 +347,0.5,1.4,1.9 +348,1.2,0.4,0.0 +349,1.3,0.6,1.3 +350,1.7,1.8,1.7 +351,1.7,0.1,0.5 +352,0.1,0.5,0.3 +353,0.2,1.5,0.8 +354,0.1,1.6,1.1 +355,0.9,0.7,1.8 +356,1.8,1.7,1.3 +357,1.4,0.1,1.3 +358,1.9,0.0,1.0 +359,1.9,0.3,1.0 +360,1.1,0.2,1.4 +361,1.4,1.9,2.0 +362,1.0,1.4,0.8 +363,1.8,0.5,1.5 +364,0.2,1.5,0.1 +365,1.5,0.4,0.2 +366,1.2,0.3,0.3 +367,0.9,1.9,2.0 +368,1.3,0.1,1.1 +369,0.1,1.0,1.1 +370,1.4,1.7,2.0 +371,1.0,1.5,0.9 +372,1.0,1.3,2.0 +373,0.8,1.1,2.0 +374,1.3,0.5,0.9 +375,1.9,1.1,1.7 +376,1.6,1.0,1.1 +377,1.5,1.9,1.2 +378,0.4,0.4,1.8 +379,1.8,0.7,1.3 +380,1.2,0.1,1.3 +381,0.4,1.9,0.3 +382,1.4,1.8,0.8 +383,0.2,1.6,1.3 +384,2.0,1.8,0.5 +385,0.4,0.0,0.5 +386,0.8,1.3,1.8 +387,1.4,1.9,1.1 +388,0.5,1.5,0.7 +389,1.2,1.5,1.4 +390,0.3,1.5,0.7 +391,0.6,1.5,1.9 +392,1.1,1.0,2.0 +393,0.7,0.1,0.6 +394,1.9,0.3,1.2 +395,1.7,1.7,1.8 +396,0.5,1.6,1.9 +397,0.4,1.5,0.6 +398,1.7,1.9,0.8 +399,0.6,0.8,2.0 +400,1.2,0.9,1.5 +401,1.8,1.8,1.7 +402,0.8,1.9,1.4 +403,0.4,0.0,0.6 +404,0.3,1.6,1.4 +405,1.2,1.1,0.1 +406,2.0,1.8,0.1 +407,0.7,1.0,2.0 +408,0.4,1.3,1.4 +409,0.7,1.4,0.9 +410,0.0,0.0,0.7 +411,1.9,2.0,0.8 +412,0.7,0.4,0.4 +413,1.2,0.9,2.0 +414,1.4,1.5,1.9 +415,0.2,0.3,1.2 +416,1.4,0.4,1.7 +417,1.1,0.3,0.2 +418,0.9,0.1,1.3 +419,1.6,0.4,1.6 +420,0.3,1.3,1.4 +421,2.0,0.6,0.1 +422,1.8,0.4,0.1 +423,0.3,1.4,0.8 +424,0.5,0.3,0.4 +425,0.9,1.0,0.8 +426,1.4,0.3,0.7 +427,0.2,1.0,1.1 +428,0.7,0.3,0.1 +429,1.0,0.2,1.6 +430,0.2,0.3,0.0 +431,0.2,1.6,0.7 +432,1.2,1.4,1.2 +433,1.7,1.7,0.7 +434,0.1,0.4,0.9 +435,0.6,1.4,0.1 +436,1.4,0.9,0.5 +437,0.5,0.0,0.5 +438,0.1,1.8,1.4 +439,0.4,0.7,0.4 +440,1.4,0.3,0.8 +441,1.9,1.3,0.5 +442,0.8,1.5,1.1 +443,0.8,0.8,1.6 +444,2.0,1.4,0.7 +445,0.9,1.2,0.7 +446,0.4,1.1,0.9 +447,1.7,0.1,0.1 +448,1.5,0.3,0.4 +449,1.0,1.8,1.2 +450,0.6,0.1,1.0 +451,0.0,1.8,1.1 +452,0.0,1.1,0.9 +453,1.9,1.7,0.7 +454,0.7,1.6,1.7 +455,1.4,0.6,0.2 +456,1.1,1.3,0.6 +457,1.3,0.8,0.1 +458,1.6,1.4,1.7 +459,1.0,1.0,1.8 +460,0.4,0.5,1.9 +461,1.3,0.2,1.5 +462,0.2,1.4,1.5 +463,0.2,1.9,0.7 +464,1.4,1.8,0.3 +465,1.7,1.4,0.6 +466,1.9,1.7,1.3 +467,0.6,1.7,1.9 +468,0.6,0.6,0.8 +469,0.3,1.3,0.3 +470,0.1,0.4,1.9 +471,0.6,0.7,1.1 +472,1.6,1.7,0.0 +473,0.5,1.7,0.9 +474,1.7,1.3,1.9 +475,0.9,1.4,1.4 +476,0.2,0.3,0.2 +477,1.5,1.4,1.7 +478,0.5,0.7,1.6 +479,0.6,1.9,1.5 +480,1.8,0.7,0.2 +481,1.7,0.7,0.1 +482,0.9,1.3,1.3 +483,0.7,1.3,1.0 +484,0.5,1.7,1.0 +485,0.5,0.2,1.7 +486,0.9,1.9,0.7 +487,1.9,1.8,0.7 +488,1.0,0.5,0.4 +489,1.1,1.6,0.8 +490,0.6,0.9,0.8 +491,0.5,0.0,0.4 +492,1.8,0.4,0.4 +493,0.2,0.9,1.1 +494,0.8,0.7,1.0 +495,0.4,1.3,1.7 +496,0.7,1.0,1.8 +497,1.6,1.9,0.4 +498,0.1,1.7,0.4 +499,0.7,1.5,0.6 +500,0.2,1.7,1.2 +501,1.6,1.0,0.9 +502,0.0,1.4,1.9 +503,0.9,0.8,0.9 +504,1.0,0.4,1.5 +505,0.4,0.3,0.9 +506,0.4,0.5,0.8 +507,0.5,1.8,0.2 +508,0.4,1.2,1.3 +509,1.2,0.4,0.9 +510,0.3,1.5,1.9 +511,1.9,1.2,0.2 +512,0.9,1.5,1.8 +513,0.8,0.6,0.1 +514,1.5,1.3,1.4 +515,0.6,0.4,1.5 +516,1.1,1.8,0.5 +517,1.3,1.2,0.1 +518,0.1,1.0,1.0 +519,1.1,0.0,0.8 +520,0.5,0.6,0.0 +521,0.4,1.8,1.4 +522,0.4,1.5,0.5 +523,1.1,1.6,0.1 +524,1.9,0.1,0.6 +525,1.4,0.6,1.8 +526,2.0,1.0,0.1 +527,0.3,1.3,0.5 +528,0.3,1.5,0.4 +529,0.8,1.7,0.9 +530,0.3,1.4,1.1 +531,1.6,1.0,0.7 +532,0.5,0.9,1.8 +533,1.5,1.0,0.7 +534,0.1,0.1,1.6 +535,1.5,0.9,0.9 +536,0.0,1.9,0.4 +537,1.4,2.0,1.6 +538,0.7,0.1,0.7 +539,0.2,0.3,1.2 +540,1.1,1.1,1.7 +541,0.1,1.5,1.2 +542,1.6,1.3,0.0 +543,0.1,0.3,1.2 +544,0.6,0.5,0.2 +545,1.3,0.4,1.9 +546,0.9,0.1,1.5 +547,0.8,1.7,1.2 +548,0.1,1.6,0.3 +549,1.5,1.4,0.7 +550,1.0,1.4,0.5 +551,1.5,0.9,1.5 +552,0.9,1.7,0.7 +553,0.8,1.8,0.6 +554,0.6,1.2,1.4 +555,1.8,1.8,0.3 +556,1.7,0.5,1.7 +557,1.4,2.0,1.4 +558,1.3,0.5,0.2 +559,1.5,0.0,0.1 +560,0.8,0.7,0.9 +561,1.6,0.2,0.8 +562,1.9,0.9,1.7 +563,1.8,0.1,2.0 +564,0.4,0.7,1.7 +565,0.6,0.8,0.9 +566,1.2,0.4,1.9 +567,0.2,1.8,0.9 +568,1.6,1.4,0.5 +569,0.9,2.0,1.3 +570,1.4,1.0,1.0 +571,0.9,1.3,1.7 +572,0.1,1.4,0.8 +573,1.5,1.0,1.4 +574,0.1,1.1,1.6 +575,1.6,0.1,1.0 +576,0.8,1.2,1.0 +577,1.8,1.3,1.8 +578,0.1,0.4,1.0 +579,0.3,1.5,1.7 +580,0.9,0.3,1.2 +581,1.5,1.9,1.7 +582,1.8,0.5,0.8 +583,0.5,1.2,1.8 +584,1.0,1.7,0.0 +585,1.0,0.5,0.3 +586,0.3,1.1,1.5 +587,1.7,1.5,1.3 +588,0.4,1.4,0.2 +589,1.2,1.5,0.2 +590,1.5,1.5,0.7 +591,1.1,1.2,1.1 +592,0.5,0.9,0.4 +593,0.2,0.5,1.3 +594,1.6,1.9,1.8 +595,1.5,1.3,0.4 +596,0.6,0.2,1.1 +597,0.4,1.8,0.0 +598,1.8,0.4,0.6 +599,0.4,0.1,1.9 +600,1.7,0.7,1.1 +601,1.0,0.2,0.1 +602,0.3,0.3,1.9 +603,1.5,1.6,0.8 +604,1.0,0.6,0.3 +605,1.5,1.7,0.3 +606,1.3,1.2,1.2 +607,1.1,1.3,1.1 +608,0.1,1.9,1.2 +609,0.6,1.1,0.8 +610,1.7,0.4,0.1 +611,2.0,2.0,1.7 +612,1.5,0.3,1.4 +613,0.5,1.5,0.4 +614,1.4,0.2,1.7 +615,0.4,0.8,1.7 +616,0.7,0.5,1.5 +617,1.4,1.6,0.2 +618,0.3,0.9,0.0 +619,1.4,0.5,0.1 +620,0.6,0.9,1.5 +621,0.8,1.1,2.0 +622,1.2,1.5,0.9 +623,0.2,1.8,1.0 +624,0.8,1.3,0.5 +625,0.2,0.2,1.6 +626,1.7,0.7,1.9 +627,0.6,0.3,0.5 +628,1.5,0.2,0.5 +629,0.1,0.1,2.0 +630,0.2,0.6,0.0 +631,0.9,1.5,0.8 +632,0.2,0.9,1.9 +633,1.0,0.5,1.7 +634,1.6,0.4,1.6 +635,1.2,2.0,1.9 +636,0.3,1.9,0.3 +637,0.1,0.7,1.5 +638,2.0,1.6,0.6 +639,0.4,1.4,0.3 +640,0.5,0.8,0.8 +641,0.7,0.7,0.3 +642,1.0,1.8,1.5 +643,1.4,1.0,0.5 +644,1.2,1.4,2.0 +645,0.6,0.1,1.1 +646,0.4,1.5,0.0 +647,0.2,1.4,0.2 +648,1.8,1.8,0.9 +649,1.5,0.9,0.5 +650,0.8,1.0,0.3 +651,0.4,1.4,1.0 +652,1.9,1.9,1.5 +653,0.9,0.9,0.6 +654,0.3,0.6,0.0 +655,1.2,0.9,1.9 +656,1.2,0.5,1.8 +657,0.7,0.3,1.0 +658,0.3,1.0,1.4 +659,1.6,1.4,1.4 +660,0.9,0.4,1.3 +661,1.4,0.2,1.1 +662,1.1,0.7,0.1 +663,0.8,0.3,1.4 +664,1.0,0.5,1.2 +665,1.9,0.3,1.0 +666,0.1,0.2,1.1 +667,0.6,1.2,1.7 +668,1.4,0.6,0.3 +669,0.1,1.9,1.1 +670,0.2,0.8,0.3 +671,1.2,1.3,1.2 +672,0.1,1.0,1.8 +673,0.7,1.5,1.1 +674,1.8,0.7,0.7 +675,1.8,0.9,0.4 +676,0.2,0.2,0.3 +677,1.8,1.9,1.9 +678,1.7,0.5,1.2 +679,1.5,1.2,0.6 +680,1.8,1.6,0.7 +681,0.2,0.2,0.2 +682,0.6,0.7,0.7 +683,1.7,0.4,0.8 +684,0.4,0.6,0.6 +685,1.1,1.6,0.4 +686,1.3,0.4,0.2 +687,1.1,0.5,1.0 +688,1.7,0.9,1.4 +689,1.6,0.2,0.3 +690,2.0,1.1,0.7 +691,1.6,0.6,0.4 +692,0.8,1.9,1.5 +693,0.2,1.2,1.4 +694,0.2,1.8,0.4 +695,0.1,1.9,1.0 +696,0.5,1.6,0.1 +697,1.9,1.8,2.0 +698,0.9,0.6,0.7 +699,0.6,0.6,1.2 +700,1.9,0.2,1.4 +701,0.0,0.6,1.6 +702,0.8,0.1,0.2 +703,0.2,1.6,0.6 +704,0.9,1.9,0.5 +705,1.4,1.4,0.0 +706,0.9,1.5,0.4 +707,1.7,0.4,1.7 +708,1.3,0.5,1.0 +709,1.1,1.6,0.1 +710,0.8,0.0,1.0 +711,0.5,0.4,0.4 +712,1.8,1.1,1.1 +713,1.1,0.1,0.9 +714,1.4,1.8,1.8 +715,0.8,0.9,0.9 +716,0.3,0.4,1.3 +717,0.1,0.2,1.2 +718,1.6,1.1,1.1 +719,1.9,0.5,0.2 +720,1.5,0.5,0.2 +721,0.9,0.8,0.8 +722,0.3,0.6,0.8 +723,0.0,1.7,1.2 +724,0.1,1.5,1.9 +725,1.4,1.3,0.0 +726,1.3,1.5,0.0 +727,1.0,0.1,0.3 +728,0.8,1.6,0.1 +729,1.3,0.6,1.9 +730,0.9,1.7,2.0 +731,0.2,0.9,1.4 +732,0.5,1.2,1.9 +733,0.1,1.1,1.4 +734,0.5,1.5,0.6 +735,0.8,0.2,1.9 +736,1.2,0.4,1.0 +737,0.1,1.2,0.3 +738,0.1,1.9,1.8 +739,0.9,1.6,1.6 +740,1.9,0.0,1.1 +741,0.4,1.3,1.6 +742,1.5,1.2,0.8 +743,0.3,0.8,0.4 +744,1.5,2.0,0.9 +745,0.5,1.2,0.2 +746,0.6,1.8,0.6 +747,0.8,0.3,0.7 +748,2.0,1.0,0.6 +749,0.3,1.2,0.9 +750,0.0,0.9,0.7 +751,0.9,1.2,0.2 +752,1.5,1.7,1.0 +753,0.6,1.5,0.7 +754,1.5,0.7,1.3 +755,1.4,0.6,0.9 +756,1.7,0.4,0.5 +757,1.0,0.8,1.4 +758,0.5,1.4,1.4 +759,1.9,1.3,0.3 +760,0.1,1.8,0.6 +761,0.9,1.0,0.6 +762,0.6,0.7,1.5 +763,0.0,1.8,1.1 +764,1.6,0.3,1.0 +765,1.7,0.2,1.7 +766,1.2,0.3,0.3 +767,0.1,1.5,0.0 +768,0.2,1.5,0.2 +769,0.6,0.5,0.9 +770,0.3,1.3,1.8 +771,0.1,1.4,0.9 +772,1.6,1.3,0.4 +773,1.5,1.5,1.4 +774,1.6,1.2,0.7 +775,0.7,0.6,0.2 +776,1.4,1.4,1.5 +777,0.9,1.1,1.0 +778,0.7,1.7,0.9 +779,1.1,0.9,0.2 +780,1.0,1.2,0.3 +781,1.6,0.4,1.9 +782,0.4,1.3,1.3 +783,0.4,2.0,1.9 +784,0.6,0.6,2.0 +785,0.3,0.5,1.1 +786,1.0,0.5,2.0 +787,0.5,0.3,0.8 +788,0.4,2.0,0.3 +789,0.6,0.7,1.5 +790,0.8,0.4,1.6 +791,0.7,0.3,1.8 +792,0.2,0.7,1.5 +793,1.2,1.7,0.3 +794,0.7,1.1,1.5 +795,0.2,1.5,0.9 +796,1.0,1.0,0.2 +797,0.6,0.3,0.1 +798,0.9,0.4,0.4 +799,0.8,0.9,0.9 +800,1.1,1.6,0.2 +801,1.3,1.0,1.1 +802,0.7,1.8,0.6 +803,1.7,2.0,1.7 +804,1.7,0.7,0.0 +805,0.2,1.1,1.4 +806,1.9,1.0,0.3 +807,1.1,1.2,0.6 +808,0.4,0.0,0.2 +809,0.2,0.1,0.3 +810,0.8,1.6,0.3 +811,0.5,0.9,0.8 +812,0.1,1.1,1.1 +813,0.7,0.7,0.0 +814,0.2,1.5,1.1 +815,1.0,0.2,0.5 +816,1.3,0.9,1.1 +817,1.8,1.6,1.6 +818,1.3,1.4,0.2 +819,1.3,1.2,0.6 +820,1.4,0.8,1.0 +821,0.0,0.7,1.9 +822,0.5,0.7,0.8 +823,1.9,1.7,0.4 +824,0.3,0.8,0.2 +825,1.8,1.2,1.9 +826,1.5,0.2,1.4 +827,0.5,1.0,0.6 +828,1.1,0.4,1.2 +829,0.3,0.1,1.8 +830,0.0,2.0,0.5 +831,1.8,1.4,2.0 +832,0.6,1.8,0.7 +833,0.1,1.5,1.4 +834,1.5,0.7,0.9 +835,1.9,1.2,0.4 +836,0.2,1.5,1.5 +837,0.7,1.6,1.1 +838,1.4,1.8,0.2 +839,1.7,1.5,1.2 +840,0.2,0.1,0.7 +841,0.1,1.3,0.1 +842,0.2,1.3,1.1 +843,0.6,0.1,1.1 +844,0.8,1.3,1.6 +845,1.6,1.4,1.1 +846,1.9,1.3,0.6 +847,1.4,1.5,0.2 +848,0.1,1.9,1.7 +849,1.3,0.2,0.1 +850,0.3,1.0,1.6 +851,0.1,0.9,0.7 +852,1.2,1.7,0.3 +853,1.9,1.1,1.3 +854,0.8,1.6,0.7 +855,0.1,1.2,0.4 +856,0.6,1.0,0.2 +857,1.0,0.9,1.9 +858,0.0,1.5,1.8 +859,1.9,1.0,1.6 +860,0.6,1.2,0.8 +861,1.9,0.7,2.0 +862,1.1,0.9,1.3 +863,1.1,0.7,0.8 +864,1.7,0.2,1.8 +865,0.6,1.7,0.1 +866,0.5,0.8,0.2 +867,1.7,0.4,0.4 +868,0.0,0.8,0.6 +869,1.0,1.7,1.3 +870,0.5,0.5,0.7 +871,0.4,1.9,0.3 +872,0.7,0.4,0.6 +873,1.1,1.6,1.2 +874,1.2,1.7,1.2 +875,1.8,0.8,1.5 +876,0.0,1.4,0.7 +877,0.1,1.7,1.6 +878,1.9,1.7,0.4 +879,1.9,0.5,0.5 +880,1.5,0.1,0.7 +881,1.1,1.8,1.5 +882,1.5,0.7,1.1 +883,0.5,0.1,1.7 +884,0.8,1.1,1.9 +885,0.2,1.7,0.3 +886,1.6,1.4,2.0 +887,1.8,0.1,1.6 +888,2.0,1.4,1.3 +889,0.8,1.5,1.2 +890,0.6,0.1,1.8 +891,1.1,0.3,0.7 +892,1.8,1.0,1.8 +893,0.9,0.6,0.3 +894,0.7,1.1,1.0 +895,1.6,0.9,1.6 +896,0.6,0.7,0.9 +897,1.7,1.9,0.6 +898,0.4,1.7,1.7 +899,1.0,1.8,1.0 +900,0.9,1.8,2.0 +901,0.4,1.6,1.6 +902,1.0,0.7,0.9 +903,0.5,1.3,1.8 +904,0.2,0.1,0.5 +905,1.0,0.4,1.6 +906,1.7,1.6,0.8 +907,0.7,1.7,1.7 +908,1.5,0.9,1.5 +909,1.5,1.8,0.3 +910,0.8,1.3,0.1 +911,1.0,1.7,1.8 +912,1.7,0.9,0.2 +913,0.8,0.1,1.6 +914,0.1,1.8,1.7 +915,1.2,1.9,1.9 +916,1.3,1.3,0.5 +917,0.2,1.9,0.4 +918,0.6,0.6,0.8 +919,0.4,1.6,0.3 +920,2.0,1.8,0.4 +921,0.7,0.5,0.0 +922,1.5,0.1,1.0 +923,2.0,0.7,0.9 +924,1.5,0.3,1.8 +925,1.5,1.2,1.3 +926,1.5,1.8,0.2 +927,0.2,1.9,0.8 +928,1.2,0.1,1.8 +929,0.1,1.2,0.6 +930,0.4,0.5,1.4 +931,0.6,1.6,1.0 +932,1.5,0.4,1.0 +933,0.2,1.4,0.4 +934,1.5,1.8,0.0 +935,1.0,1.7,0.7 +936,0.5,2.0,1.1 +937,0.7,1.4,0.4 +938,1.7,0.8,1.0 +939,0.1,1.7,0.8 +940,0.7,2.0,1.3 +941,1.0,1.8,0.0 +942,0.4,0.4,1.1 +943,1.2,1.0,1.6 +944,0.4,1.4,0.6 +945,0.2,1.8,1.6 +946,1.8,0.7,0.4 +947,1.8,0.0,1.4 +948,1.0,1.4,0.5 +949,0.8,1.9,1.1 +950,1.7,1.3,0.5 +951,0.4,1.8,0.6 +952,1.9,0.8,0.1 +953,1.4,1.7,1.6 +954,0.4,1.5,1.0 +955,0.9,0.5,0.2 +956,1.6,1.1,1.2 +957,0.5,0.1,1.3 +958,0.2,0.9,1.6 +959,1.9,1.3,1.7 +960,1.3,0.3,1.0 +961,1.3,1.6,1.2 +962,1.3,1.4,1.4 +963,0.2,1.1,1.1 +964,0.7,1.6,0.1 +965,1.4,1.7,1.4 +966,1.3,0.7,1.2 +967,1.5,0.6,1.6 +968,1.0,0.7,0.8 +969,1.4,1.9,1.3 +970,1.8,0.2,2.0 +971,0.9,1.7,0.6 +972,0.1,0.9,0.3 +973,2.0,1.0,1.7 +974,0.9,1.0,0.8 +975,1.4,1.4,0.7 +976,1.1,0.7,0.9 +977,1.5,0.5,0.5 +978,0.4,0.4,0.9 +979,0.3,0.2,0.2 +980,1.9,1.9,1.6 +981,1.7,1.2,1.7 +982,1.6,1.7,0.2 +983,0.7,1.3,1.0 +984,0.5,0.8,0.4 +985,0.8,1.2,0.9 +986,0.1,0.3,1.1 +987,0.3,1.7,1.2 +988,1.8,1.3,0.6 +989,0.8,0.1,1.6 +990,0.0,0.3,1.1 +991,0.7,1.4,0.6 +992,0.2,0.3,1.5 +993,1.3,1.5,1.2 +994,1.1,0.9,1.3 +995,1.4,1.3,0.7 +996,0.8,1.1,1.0 +997,1.4,1.2,0.6 +998,1.6,0.4,0.7 +999,1.4,1.3,0.4 +1000,0.4,0.7,1.0 +1001,0.5,1.4,0.3 +1002,1.2,0.0,0.6 +1003,1.8,0.5,0.4 +1004,0.2,0.5,1.2 +1005,1.9,0.7,1.0 +1006,1.9,0.1,1.0 +1007,0.7,2.0,1.7 +1008,0.4,1.4,1.7 +1009,1.4,1.4,1.3 +1010,0.7,1.8,0.6 +1011,0.9,1.2,1.3 +1012,2.0,1.0,0.6 +1013,0.8,1.1,0.8 +1014,0.4,1.8,0.9 +1015,1.9,1.9,1.0 +1016,1.4,0.8,1.7 +1017,1.6,1.1,0.9 +1018,0.6,1.1,2.0 +1019,1.3,0.7,1.5 +1020,0.3,0.5,0.6 +1021,0.6,0.9,1.8 +1022,0.4,0.5,0.1 +1023,1.3,0.6,0.5 +1024,0.5,0.9,0.0 +1025,1.6,1.1,1.5 +1026,0.4,1.5,1.8 +1027,1.2,1.8,1.3 +1028,0.7,0.4,0.4 +1029,0.2,1.8,1.4 +1030,0.9,0.9,1.4 +1031,1.9,1.1,0.2 +1032,0.6,1.0,1.4 +1033,0.9,1.5,1.0 +1034,1.9,0.2,0.5 +1035,1.0,0.0,0.4 +1036,1.7,1.1,0.8 +1037,0.9,0.9,0.7 +1038,1.6,1.2,0.0 +1039,0.3,1.2,0.5 +1040,1.4,1.8,1.8 +1041,0.5,0.3,0.4 +1042,0.7,1.0,0.5 +1043,1.4,1.6,0.4 +1044,0.9,0.7,1.5 +1045,1.6,0.6,0.8 +1046,0.8,0.9,1.4 +1047,1.3,1.8,0.3 +1048,1.5,0.9,0.5 +1049,1.3,0.8,0.1 +1050,1.6,1.7,1.6 +1051,0.6,1.2,0.1 +1052,1.0,0.5,1.7 +1053,0.6,0.6,1.3 +1054,1.2,1.6,0.9 +1055,0.4,0.5,1.3 +1056,1.3,0.3,0.8 +1057,0.1,1.9,1.4 +1058,0.6,1.8,0.2 +1059,0.2,1.4,0.4 +1060,0.0,1.5,1.6 +1061,1.3,1.5,1.9 +1062,0.6,0.2,1.6 +1063,0.3,0.4,0.0 +1064,0.8,1.2,0.7 +1065,0.0,1.3,1.7 +1066,1.2,0.4,0.5 +1067,0.0,1.9,2.0 +1068,1.7,1.7,0.4 +1069,1.8,0.3,0.6 +1070,1.0,1.6,1.2 +1071,0.9,1.7,0.9 +1072,1.1,0.5,0.1 +1073,1.6,2.0,0.6 +1074,0.6,0.2,1.4 +1075,0.2,0.0,0.4 +1076,0.7,1.7,1.8 +1077,0.2,0.6,1.9 +1078,1.4,1.9,0.1 +1079,1.6,0.8,0.2 +1080,0.1,0.5,1.0 +1081,1.7,0.4,1.8 +1082,1.1,0.7,0.6 +1083,0.9,1.5,0.6 +1084,1.4,1.7,1.5 +1085,1.2,0.8,0.6 +1086,0.1,1.2,0.3 +1087,0.5,0.7,1.7 +1088,0.9,1.0,1.4 +1089,0.2,0.4,1.8 +1090,1.3,1.6,1.3 +1091,0.5,1.0,0.1 +1092,1.9,0.2,0.3 +1093,1.3,0.2,1.1 +1094,0.9,1.7,0.1 +1095,1.2,1.5,0.2 +1096,1.8,0.4,0.4 +1097,0.3,1.1,1.5 +1098,1.3,0.9,0.8 +1099,1.9,1.2,0.0 +1100,1.9,0.2,0.2 +1101,1.5,1.6,1.0 +1102,0.3,0.5,0.3 +1103,1.0,1.6,0.4 +1104,1.4,0.4,0.8 +1105,1.0,0.2,1.7 +1106,0.5,1.6,0.0 +1107,0.4,1.7,0.2 +1108,1.7,1.7,1.6 +1109,1.1,0.9,0.9 +1110,1.1,0.8,0.9 +1111,1.7,1.6,1.5 +1112,1.1,0.2,1.6 +1113,1.8,1.6,0.2 +1114,0.3,0.1,0.4 +1115,0.8,0.1,1.8 +1116,1.6,1.5,0.8 +1117,1.2,1.7,1.6 +1118,0.1,0.5,1.3 +1119,1.4,0.7,0.9 +1120,1.6,0.4,0.9 +1121,0.9,1.4,0.5 +1122,1.6,1.4,0.8 +1123,0.3,1.4,1.2 +1124,0.4,1.1,1.8 +1125,0.7,0.5,1.2 +1126,1.2,1.0,0.5 +1127,1.4,0.3,1.7 +1128,0.7,0.0,1.1 +1129,0.9,1.1,1.6 +1130,0.2,1.7,1.2 +1131,0.7,0.3,1.4 +1132,0.0,2.0,0.2 +1133,0.4,1.6,1.7 +1134,1.2,2.0,1.3 +1135,1.7,1.0,0.5 +1136,1.7,1.2,0.4 +1137,1.5,1.8,0.8 +1138,0.5,1.3,0.2 +1139,1.1,0.8,0.2 +1140,0.0,0.1,0.1 +1141,1.5,1.8,0.5 +1142,0.4,0.4,0.4 +1143,1.4,0.6,2.0 +1144,0.7,1.7,0.3 +1145,0.7,1.3,0.4 +1146,0.8,0.0,1.3 +1147,0.5,1.6,0.1 +1148,1.7,0.7,1.0 +1149,1.0,1.6,0.6 +1150,0.8,0.9,0.0 +1151,1.2,0.7,0.7 +1152,1.7,0.9,0.4 +1153,0.4,0.4,1.7 +1154,1.3,1.9,1.9 +1155,0.5,0.6,1.1 +1156,1.6,0.8,1.3 +1157,1.4,2.0,1.7 +1158,0.6,0.7,0.8 +1159,0.1,1.7,1.1 +1160,1.9,0.7,2.0 +1161,1.5,0.3,0.3 +1162,0.7,1.9,0.5 +1163,0.9,0.8,1.6 +1164,1.8,1.0,0.8 +1165,0.7,1.8,1.8 +1166,1.9,0.5,0.8 +1167,1.6,0.8,0.1 +1168,1.3,0.8,1.2 +1169,1.8,2.0,1.5 +1170,0.4,0.4,0.8 +1171,0.2,1.2,1.0 +1172,0.7,0.1,1.8 +1173,1.5,1.8,1.5 +1174,0.8,1.5,1.8 +1175,1.2,0.1,0.2 +1176,0.0,0.9,0.9 +1177,0.9,1.6,1.3 +1178,1.3,0.3,0.8 +1179,0.1,0.1,1.0 +1180,1.1,0.1,0.7 +1181,0.1,1.2,1.4 +1182,0.2,2.0,1.3 +1183,0.2,0.1,0.5 +1184,1.1,0.8,0.7 +1185,1.7,1.6,0.4 +1186,1.6,0.2,0.0 +1187,1.1,0.4,0.5 +1188,1.1,0.2,0.4 +1189,1.5,1.3,0.8 +1190,1.4,1.7,0.4 +1191,0.5,0.7,0.3 +1192,1.0,0.4,1.5 +1193,1.1,0.7,0.4 +1194,0.1,0.7,1.5 +1195,1.4,0.3,0.2 +1196,1.5,1.1,1.7 +1197,0.1,1.7,1.2 +1198,1.1,0.8,0.2 +1199,0.1,1.0,0.7 +1200,1.1,1.5,0.7 +1201,0.1,1.9,0.5 +1202,0.4,2.0,1.7 +1203,1.4,1.0,0.9 +1204,0.5,0.2,1.1 +1205,0.9,1.9,1.4 +1206,1.2,0.0,1.3 +1207,1.6,1.9,0.7 +1208,0.0,1.2,0.0 +1209,1.8,1.6,0.1 +1210,1.3,0.6,0.3 +1211,1.7,0.9,1.4 +1212,0.9,1.7,1.1 +1213,2.0,0.6,1.4 +1214,1.3,0.9,1.6 +1215,0.4,0.9,0.9 +1216,0.5,0.4,1.1 +1217,0.4,0.9,0.7 +1218,0.2,1.9,0.6 +1219,1.8,1.0,0.5 +1220,0.4,1.7,1.2 +1221,1.4,0.5,1.1 +1222,0.6,1.3,0.8 +1223,0.4,1.6,0.4 +1224,1.4,0.1,0.2 +1225,1.9,1.3,0.7 +1226,1.2,0.2,1.7 +1227,1.9,0.0,1.8 +1228,0.0,2.0,1.8 +1229,0.6,0.2,0.4 +1230,1.6,0.3,1.7 +1231,1.9,0.5,0.8 +1232,0.3,1.9,0.8 +1233,1.0,0.3,0.4 +1234,0.2,1.4,0.7 +1235,0.3,1.0,1.9 +1236,0.9,0.1,1.0 +1237,0.0,1.3,1.6 +1238,0.8,0.6,0.5 +1239,1.1,1.3,1.9 +1240,1.7,1.1,1.4 +1241,1.4,0.0,1.2 +1242,1.8,0.1,0.7 +1243,1.1,0.6,1.0 +1244,0.6,0.9,1.6 +1245,1.7,0.1,1.8 +1246,0.9,0.4,0.8 +1247,1.9,0.0,1.8 +1248,1.1,0.8,1.7 +1249,1.6,1.3,0.7 +1250,1.5,0.1,1.3 +1251,1.1,0.1,1.1 +1252,0.4,1.4,0.3 +1253,0.9,1.3,0.3 +1254,0.0,0.0,0.9 +1255,1.9,0.9,0.3 +1256,0.8,1.8,0.4 +1257,1.1,1.2,1.1 +1258,0.1,1.2,0.0 +1259,1.2,0.0,1.7 +1260,1.7,0.3,1.1 +1261,0.5,0.1,1.4 +1262,1.5,1.0,0.2 +1263,1.8,0.9,0.3 +1264,1.3,1.2,0.7 +1265,1.9,0.2,0.4 +1266,0.5,1.8,1.8 +1267,0.4,1.1,0.3 +1268,0.0,1.0,0.2 +1269,0.5,0.0,1.3 +1270,1.9,1.5,0.5 +1271,0.8,1.6,1.4 +1272,1.9,1.5,1.1 +1273,1.5,0.4,0.6 +1274,1.7,0.6,0.4 +1275,0.4,0.4,1.6 +1276,0.5,0.4,0.3 +1277,1.6,0.9,0.5 +1278,0.9,1.6,1.6 +1279,1.8,0.6,0.8 +1280,1.8,0.6,1.0 +1281,1.6,0.2,1.3 +1282,1.1,1.9,0.5 +1283,0.8,0.4,1.2 +1284,0.0,1.1,1.0 +1285,1.1,0.6,0.8 +1286,1.7,1.4,0.5 +1287,0.5,0.2,0.9 +1288,0.5,1.1,0.0 +1289,1.6,1.5,1.8 +1290,1.8,1.2,0.6 +1291,0.8,0.3,0.1 +1292,1.6,0.7,1.0 +1293,0.6,0.4,0.9 +1294,0.2,1.3,0.3 +1295,0.4,1.8,0.9 +1296,1.8,1.8,1.0 +1297,1.0,1.4,0.8 +1298,1.1,1.6,0.0 +1299,1.5,0.2,1.4 +1300,0.0,1.0,0.3 +1301,1.2,1.9,1.1 +1302,1.0,1.6,1.2 +1303,1.3,0.6,0.1 +1304,0.4,0.8,1.8 +1305,1.5,0.8,1.8 +1306,0.5,1.1,0.2 +1307,0.6,0.8,1.5 +1308,0.6,1.8,1.6 +1309,0.4,1.8,0.6 +1310,1.6,1.5,1.6 +1311,0.9,0.9,1.2 +1312,1.6,0.4,1.9 +1313,0.2,0.1,1.5 +1314,1.5,0.8,1.8 +1315,0.3,1.2,1.2 +1316,0.1,0.1,2.0 +1317,0.8,1.5,0.1 +1318,0.1,0.9,1.4 +1319,1.7,1.5,0.7 +1320,1.4,1.3,1.6 +1321,0.0,1.3,1.1 +1322,1.1,0.4,1.8 +1323,0.7,1.2,1.9 +1324,2.0,1.7,1.0 +1325,0.4,1.4,1.1 +1326,0.5,1.3,0.9 +1327,1.8,1.1,1.2 +1328,0.0,2.0,1.4 +1329,0.8,0.7,1.9 +1330,1.5,1.8,0.2 +1331,0.4,0.2,1.0 +1332,2.0,1.7,1.0 +1333,1.8,1.5,0.6 +1334,1.5,0.1,1.7 +1335,1.8,1.9,0.0 +1336,1.4,1.9,0.6 +1337,0.1,0.8,0.5 +1338,1.7,1.1,0.3 +1339,1.8,0.5,1.0 +1340,1.8,0.4,1.1 +1341,0.7,0.7,1.2 +1342,1.5,0.3,1.3 +1343,1.4,1.1,1.5 +1344,0.0,0.2,0.7 +1345,0.5,0.8,0.3 +1346,1.3,1.6,1.3 +1347,1.6,1.3,0.7 +1348,1.0,2.0,0.0 +1349,1.4,0.3,0.4 +1350,0.8,2.0,0.1 +1351,1.0,1.8,0.5 +1352,0.1,1.0,0.6 +1353,1.0,0.9,1.7 +1354,0.2,1.5,1.2 +1355,1.7,0.9,0.3 +1356,0.3,1.3,1.4 +1357,1.0,1.0,0.5 +1358,0.0,1.3,0.3 +1359,0.1,0.3,1.7 +1360,0.7,1.8,1.5 +1361,0.7,0.4,0.4 +1362,1.7,0.2,0.5 +1363,0.6,0.7,0.6 +1364,1.1,0.8,0.5 +1365,0.3,0.0,1.5 +1366,0.5,0.3,1.5 +1367,1.9,1.4,1.5 +1368,1.4,1.4,1.4 +1369,1.5,0.4,0.7 +1370,0.7,1.9,0.9 +1371,0.4,1.8,0.8 +1372,1.4,0.4,0.3 +1373,0.5,0.7,0.8 +1374,1.1,0.1,0.8 +1375,0.8,1.3,1.0 +1376,0.0,0.5,0.2 +1377,0.0,0.5,0.9 +1378,0.2,1.1,0.6 +1379,0.9,0.9,1.3 +1380,1.9,0.8,0.8 +1381,1.1,1.3,1.4 +1382,0.2,0.2,1.8 +1383,1.4,0.9,1.0 +1384,1.3,0.9,0.2 +1385,1.5,0.2,1.8 +1386,1.1,0.1,0.9 +1387,1.8,0.8,1.6 +1388,2.0,1.0,1.0 +1389,1.1,1.7,0.2 +1390,0.0,1.5,1.2 +1391,1.1,1.0,0.6 +1392,0.9,1.1,0.7 +1393,1.9,1.3,0.9 +1394,1.1,1.0,1.1 +1395,1.8,0.7,2.0 +1396,0.2,1.9,0.1 +1397,1.5,0.0,1.1 +1398,0.6,1.5,0.6 +1399,1.4,0.8,0.5 +1400,0.1,0.3,0.8 +1401,1.6,1.8,0.5 +1402,1.9,1.0,1.5 +1403,1.1,0.4,1.1 +1404,0.4,0.9,1.8 +1405,1.3,0.2,1.7 +1406,0.3,0.3,0.9 +1407,0.7,1.9,1.1 +1408,0.1,1.7,1.7 +1409,1.8,0.2,0.5 +1410,0.4,1.7,1.4 +1411,1.4,1.4,0.4 +1412,1.2,1.5,1.3 +1413,0.5,1.4,1.7 +1414,0.8,1.7,1.5 +1415,1.3,0.4,0.3 +1416,1.4,0.0,2.0 +1417,1.6,0.8,1.8 +1418,1.4,0.2,1.5 +1419,0.6,1.8,1.5 +1420,0.4,1.2,1.7 +1421,0.0,0.9,0.6 +1422,0.3,1.1,1.1 +1423,0.0,2.0,0.2 +1424,0.4,1.0,0.6 +1425,0.6,1.7,1.4 +1426,1.4,0.6,0.4 +1427,1.1,1.7,1.7 +1428,0.5,1.5,0.8 +1429,1.8,1.4,1.2 +1430,2.0,1.0,1.8 +1431,1.3,1.9,1.6 +1432,1.1,1.8,1.9 +1433,0.7,0.0,1.5 +1434,0.8,0.5,1.1 +1435,1.6,0.7,1.3 +1436,1.2,1.6,0.4 +1437,1.3,0.5,0.0 +1438,1.4,0.8,1.5 +1439,0.0,1.2,0.7 +1440,0.8,0.4,0.9 +1441,0.8,0.5,0.6 +1442,0.6,1.6,0.7 +1443,0.7,1.8,0.6 +1444,1.9,1.0,1.0 +1445,1.4,0.4,1.3 +1446,0.3,0.8,0.8 +1447,1.2,0.2,0.3 +1448,0.6,1.3,1.9 +1449,1.9,1.1,0.2 +1450,0.5,1.1,0.4 +1451,0.7,0.1,0.8 +1452,0.6,1.4,1.1 +1453,1.8,0.6,1.2 +1454,1.9,0.5,0.0 +1455,1.3,0.5,1.8 +1456,1.4,0.8,0.8 +1457,1.5,2.0,1.6 +1458,0.7,0.0,0.3 +1459,0.5,0.3,0.4 +1460,0.3,1.5,0.6 +1461,1.2,0.6,1.6 +1462,1.6,0.4,1.7 +1463,0.3,1.0,1.1 +1464,1.2,2.0,0.1 +1465,0.1,0.2,1.1 +1466,0.4,0.0,0.8 +1467,1.7,0.7,0.2 +1468,1.8,1.2,0.2 +1469,0.2,0.5,0.5 +1470,0.5,1.7,0.1 +1471,1.9,1.0,0.2 +1472,1.0,0.9,1.8 +1473,1.1,0.3,1.9 +1474,0.6,0.7,0.6 +1475,1.5,1.1,1.3 +1476,1.8,1.9,0.6 +1477,1.1,1.0,0.3 +1478,0.4,2.0,1.6 +1479,0.3,1.9,0.7 +1480,0.7,0.1,0.6 +1481,1.6,1.6,0.2 +1482,1.7,0.7,1.2 +1483,0.8,1.3,1.9 +1484,0.2,1.0,1.5 +1485,0.2,1.4,0.4 +1486,0.3,1.2,1.4 +1487,0.2,1.3,0.0 +1488,0.9,0.3,0.9 +1489,1.5,1.5,1.3 +1490,1.9,0.4,0.7 +1491,1.1,1.9,1.1 +1492,0.9,1.2,1.7 +1493,0.5,0.0,1.7 +1494,0.6,1.2,1.3 +1495,1.4,0.1,0.6 +1496,0.8,0.1,1.2 +1497,1.3,1.9,0.1 +1498,1.0,1.2,0.9 +1499,0.1,0.4,1.4 +1500,1.2,0.7,0.6 +1501,1.7,1.9,1.8 +1502,0.0,1.9,1.7 +1503,1.1,0.3,1.3 +1504,1.9,1.4,1.4 +1505,0.1,0.1,1.1 +1506,1.0,1.9,1.7 +1507,0.4,1.8,0.4 +1508,1.7,0.6,1.6 +1509,1.2,0.3,1.9 +1510,1.2,1.3,0.3 +1511,1.5,0.5,1.9 +1512,1.3,1.3,1.3 +1513,0.9,0.8,0.3 +1514,0.3,0.3,0.2 +1515,0.7,1.9,1.1 +1516,0.9,1.8,1.7 +1517,1.3,1.2,0.1 +1518,1.9,0.9,1.6 +1519,0.6,0.3,1.3 +1520,0.8,0.7,1.2 +1521,1.6,1.2,0.0 +1522,2.0,1.4,1.7 +1523,2.0,1.4,1.7 +1524,0.7,0.3,0.1 +1525,1.6,0.9,1.0 +1526,2.0,1.1,0.1 +1527,0.7,1.2,0.5 +1528,1.7,1.6,0.8 +1529,0.2,0.6,1.4 +1530,0.4,0.5,0.2 +1531,1.6,0.2,1.4 +1532,1.0,0.5,1.6 +1533,1.6,0.7,0.8 +1534,1.3,0.9,0.8 +1535,0.3,0.3,1.2 +1536,1.4,1.3,0.8 +1537,1.2,1.3,1.1 +1538,0.9,1.0,0.4 +1539,1.9,1.1,0.3 +1540,1.1,1.3,1.6 +1541,1.6,1.6,0.3 +1542,0.1,1.6,0.6 +1543,0.2,1.5,1.6 +1544,1.2,0.7,0.5 +1545,0.6,1.8,0.5 +1546,1.6,0.5,0.2 +1547,1.7,1.7,0.7 +1548,0.9,1.4,2.0 +1549,1.5,0.4,1.6 +1550,1.6,1.5,1.2 +1551,1.9,1.1,1.1 +1552,1.4,0.4,0.3 +1553,1.6,0.0,1.2 +1554,1.9,0.9,0.3 +1555,1.1,1.8,0.2 +1556,1.7,0.8,0.3 +1557,0.1,0.2,0.0 +1558,0.0,0.5,0.1 +1559,1.7,0.6,0.4 +1560,0.2,1.2,0.9 +1561,0.6,2.0,1.2 +1562,1.4,1.8,1.4 +1563,0.8,1.8,1.2 +1564,0.7,0.2,1.3 +1565,1.2,1.9,1.7 +1566,1.4,0.2,1.5 +1567,1.1,0.1,0.2 +1568,1.8,0.5,0.9 +1569,1.8,1.2,0.3 +1570,0.1,1.8,1.6 +1571,0.9,0.6,0.7 +1572,1.1,1.2,0.0 +1573,1.5,0.9,0.0 +1574,1.2,1.6,0.8 +1575,1.7,0.8,1.8 +1576,0.0,0.2,0.9 +1577,0.1,1.7,1.2 +1578,0.6,0.5,1.5 +1579,0.0,1.2,0.8 +1580,0.5,1.9,0.9 +1581,1.6,0.9,0.3 +1582,1.4,1.9,1.6 +1583,1.3,1.3,1.6 +1584,0.6,1.3,1.2 +1585,0.5,2.0,0.0 +1586,0.1,1.2,0.5 +1587,1.5,1.7,0.7 +1588,1.0,1.3,0.5 +1589,1.8,0.7,2.0 +1590,0.5,1.9,2.0 +1591,0.3,0.4,1.2 +1592,1.2,1.7,1.5 +1593,1.7,0.4,2.0 +1594,1.2,1.9,1.1 +1595,1.3,1.0,0.2 +1596,1.6,0.1,0.5 +1597,1.0,1.9,0.6 +1598,1.9,0.1,1.3 +1599,0.2,0.4,1.7 +1600,1.2,1.2,0.2 diff --git a/src/model/bayesian_model.hpp b/src/model/bayesian_model.hpp index 9d335e4e8..3ffe9f4a9 100644 --- a/src/model/bayesian_model.hpp +++ b/src/model/bayesian_model.hpp @@ -92,6 +92,8 @@ namespace epi { double log_factorial_(std::size_t n); bool get_cov_status() const; + + bool cov_score_() const; }; } diff --git a/src/model/bayesian_model.ipp b/src/model/bayesian_model.ipp index dddc35c36..ba78ede86 100644 --- a/src/model/bayesian_model.ipp +++ b/src/model/bayesian_model.ipp @@ -72,6 +72,10 @@ namespace epi { BayesianModel:: evaluate_(const std::vector & snp_set, bool prepare_prediction) { + if (this->get_cov_status() and not this->instance_->has_cov()){ + throw epi::Error("No Covariates specified."); + } + Eigen::MatrixXd residuals; if (this->get_cov_status()){ // linear regression model for phenotypes with covariates as target @@ -139,7 +143,12 @@ namespace epi { void BayesianModel:: cov_activate() { - incl_cov_ = true; + if (this->instance_->has_cov() == false){ + incl_cov_ = false; + throw epi::Error("No covariates specified."); + } else { + incl_cov_ = true; + } } template diff --git a/src/model/instance.hpp b/src/model/instance.hpp index 192096c51..6bbcf2c41 100644 --- a/src/model/instance.hpp +++ b/src/model/instance.hpp @@ -306,6 +306,8 @@ namespace epi { Eigen::VectorXd get_covariates_at_ind(Ind ind) const; + bool has_cov(); + private: std::size_t num_categories_; @@ -337,6 +339,8 @@ namespace epi { std::size_t construct_folds_(std::size_t num_folds, std::size_t fold_id, options::DataPurpose cv_data, std::vector & skip); void load_csv_cov_(const std::string &filename); + + bool has_cov_; }; } diff --git a/src/model/instance.ipp b/src/model/instance.ipp index 8e71cf167..6b3391397 100644 --- a/src/model/instance.ipp +++ b/src/model/instance.ipp @@ -92,6 +92,7 @@ namespace epi { Instance(std::size_t num_categories): rs_ids_(), rs_ids_chromosomes_(), + has_cov_(false), num_categories_{num_categories}, num_snps_{undefined_uint()}, num_inds_{undefined_uint()}, @@ -148,6 +149,7 @@ namespace epi { default: throw Error("Unsupported input format."); } + has_cov_ = true; } template @@ -164,6 +166,13 @@ namespace epi { return num_inds_; } + template + bool + Instance:: + has_cov() { + return has_cov_; + } + template std::size_t Instance:: diff --git a/src/model/penetrance_model.hpp b/src/model/penetrance_model.hpp index a668b3ba4..2ffa1a761 100644 --- a/src/model/penetrance_model.hpp +++ b/src/model/penetrance_model.hpp @@ -110,6 +110,8 @@ namespace epi { void check_loaded_model_() const; bool get_cov_status() const; + + bool cov_score_() const; }; } diff --git a/src/model/penetrance_model.ipp b/src/model/penetrance_model.ipp index a97176f35..26e194b25 100644 --- a/src/model/penetrance_model.ipp +++ b/src/model/penetrance_model.ipp @@ -59,6 +59,9 @@ namespace epi { double PenetranceModel:: evaluate_(const std::vector & snp_set, bool prepare_prediction) { + if (cov_score_() and not this->instance_->has_cov()){ + throw epi::Error("No Covariates specified."); + } Eigen::MatrixXd beta; Eigen::MatrixXd residuals; @@ -258,7 +261,12 @@ namespace epi { void PenetranceModel:: cov_activate() { - incl_cov_ = true; + if (this->instance_->has_cov() == false){ + incl_cov_ = false; + throw epi::Error("No covariates specified."); + } else { + incl_cov_ = true; + } } template @@ -268,6 +276,13 @@ namespace epi { incl_cov_ = false; } + template + bool + PenetranceModel:: + cov_score_() const { + return score_ == "CLG-L-LC" or score_ == "CLG-Q-QC" or score_ == "CLG-Q-LC"; + } + template const std::string &PenetranceModel::get_score() { return score_; diff --git a/src/model/regression_model.ipp b/src/model/regression_model.ipp index bbf565588..96666057a 100644 --- a/src/model/regression_model.ipp +++ b/src/model/regression_model.ipp @@ -211,6 +211,9 @@ namespace epi { double RegressionModel:: evaluate_(const std::vector & snp_set, bool prepare_prediction) { + if (this->get_cov_status() and not this->instance_->has_cov()){ + throw epi::Error("No Covariates specified."); + } // Compute interaction model. // for CLG scores: here the second (bigger) model is created, e.g., CLG-L-LC here, LC (linear with covariates) Eigen::MatrixXd interaction_features; @@ -466,7 +469,12 @@ namespace epi { void RegressionModel:: cov_activate() { - incl_cov_ = true; + if (this->instance_->has_cov() == false){ + incl_cov_ = false; + throw epi::Error("No covariates specified."); + } else { + incl_cov_ = true; + } } template diff --git a/src/model/variance_model.hpp b/src/model/variance_model.hpp index 575916cb3..fe1cd5575 100644 --- a/src/model/variance_model.hpp +++ b/src/model/variance_model.hpp @@ -82,6 +82,7 @@ namespace epi { bool get_cov_status() const; + bool cov_score_() const; }; } diff --git a/src/model/variance_model.ipp b/src/model/variance_model.ipp index 99401c927..b9aba0d2a 100644 --- a/src/model/variance_model.ipp +++ b/src/model/variance_model.ipp @@ -65,6 +65,9 @@ namespace epi { double VarianceModel:: evaluate_(const std::vector &snp_set, bool prepare_prediction) { + if (this->get_cov_status() and not this->instance_->has_cov()){ + throw epi::Error("No Covariates specified."); + } Eigen::MatrixXd residuals; if (this->get_cov_status()) { @@ -137,7 +140,12 @@ namespace epi { void VarianceModel:: cov_activate() { - incl_cov_ = true; + if (this->instance_->has_cov() == false){ + incl_cov_ = false; + throw epi::Error("No covariates specified."); + } else { + incl_cov_ = true; + } } template diff --git a/test/unit/src/bayesian_model.cpp b/test/unit/src/bayesian_model.cpp index 9740e1116..bf4fc5675 100644 --- a/test/unit/src/bayesian_model.cpp +++ b/test/unit/src/bayesian_model.cpp @@ -92,7 +92,7 @@ TEST_CASE("Quantitative Instance - Cov") { CHECK_THAT(model.monte_carlo_p_value(disease_snp_set, 100, 0), Catch::WithinAbs(model.monte_carlo_p_value(disease_snp_set_shuffled, 100, 0), 0.0001)); } -TEST_CASE("Categorical Instance 1 - Cov") { +TEST_CASE("Categorical Instance - Cov") { epi::Instance instance(2); REQUIRE_NOTHROW(instance.load(epi::options::InputFormat::JSON_EPIGEN, "../../../data/EpiGEN/dichotomous/2_disease_snps/exponential/1_1_ASW.json")); REQUIRE_NOTHROW(instance.load_cov(epi::options::InputFormat::CSV_COV, "../../../data/COV_TEST/EpiGEN_RND_COV.csv")); @@ -107,19 +107,4 @@ TEST_CASE("Categorical Instance 1 - Cov") { CHECK_THAT(model.monte_carlo_p_value(disease_snp_set, 100, 0), Catch::WithinAbs(model.monte_carlo_p_value(disease_snp_set_shuffled, 100, 0), 0.0001)); } -TEST_CASE("Categorical Instance 2 - Cov") { - epi::Instance instance(2); - REQUIRE_NOTHROW(instance.load(epi::options::InputFormat::CSV_SNPS_AS_COLUMNS_FIRST, "../../../data/MACOED/NME/00.1600.0.antesnp100.csv")); - REQUIRE_NOTHROW(instance.load_cov(epi::options::InputFormat::CSV_COV, "../../../data/COV_TEST/EpiGEN_RND_COV.csv")); - epi::BayesianModel model(&instance); - REQUIRE_NOTHROW(model.initialize()); - REQUIRE_NOTHROW(model.cov_activate()); - CHECK(model.model_sense() == epi::options::ModelSense::MINIMIZE); - CHECK(not model.is_predictive()); - std::vector disease_snp_set{0, 1}; - std::vector disease_snp_set_shuffled{1, 0}; - CHECK_THAT(model.evaluate(disease_snp_set), Catch::WithinAbs(model.evaluate(disease_snp_set_shuffled), 0.0001)); - CHECK_THAT(model.monte_carlo_p_value(disease_snp_set, 100, 0), Catch::WithinAbs(model.monte_carlo_p_value(disease_snp_set_shuffled, 100, 0), 0.0001)); -} - From e0ba0bcb95b88e907ae6c24c6cd3380aba4b9d55 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Sun, 6 Aug 2023 14:54:32 +0200 Subject: [PATCH 03/14] integrated covariate calculation into NeEDL pipeline --- src/data_model/SNPStorage.ipp | 72 ++++++++++++++++++++++++++++++++- src/jobs/InstanceLoader.cpp | 15 ++++++- src/jobs/InstanceLoader.hpp | 3 +- src/pipelines/NeEDLPipeline.cpp | 7 ++-- src/pipelines/NeEDLPipeline.hpp | 1 + src/util/types.cpp | 31 +++++++++----- src/util/types.hpp | 2 +- test/model/src/NeEDL.cpp | 5 +++ 8 files changed, 120 insertions(+), 16 deletions(-) diff --git a/src/data_model/SNPStorage.ipp b/src/data_model/SNPStorage.ipp index 8450c6479..9ca9e6797 100644 --- a/src/data_model/SNPStorage.ipp +++ b/src/data_model/SNPStorage.ipp @@ -121,48 +121,56 @@ namespace epi { // set required options if necessary switch(score) { case options::EpistasisScore::PENETRANCE_NLL: + case options::EpistasisScore::PENETRANCE_COV_NLL: if (penetrance_model_scores[current_thread] != score) { penetrance_models[current_thread]->set_options("--score NLL"); penetrance_model_scores[current_thread] = score; } break; case options::EpistasisScore::PENETRANCE_LLH: + case options::EpistasisScore::PENETRANCE_COV_LLH: if (penetrance_model_scores[current_thread] != score) { penetrance_models[current_thread]->set_options("--score LLH"); penetrance_model_scores[current_thread] = score; } break; case options::EpistasisScore::PENETRANCE_AIC: + case options::EpistasisScore::PENETRANCE_COV_AIC: if (penetrance_model_scores[current_thread] != score) { penetrance_models[current_thread]->set_options("--score AIC"); penetrance_model_scores[current_thread] = score; } break; case options::EpistasisScore::PENETRANCE_BIC: + case options::EpistasisScore::PENETRANCE_COV_BIC: if (penetrance_model_scores[current_thread] != score) { penetrance_models[current_thread]->set_options("--score BIC"); penetrance_model_scores[current_thread] = score; } break; case options::EpistasisScore::REGRESSION_NLL: + case options::EpistasisScore::REGRESSION_COV_NLL: if (regression_model_scores[current_thread] != score) { regression_models[current_thread]->set_options("--score NLL"); regression_model_scores[current_thread] = score; } break; case options::EpistasisScore::REGRESSION_LLH: + case options::EpistasisScore::REGRESSION_COV_LLH: if (regression_model_scores[current_thread] != score) { regression_models[current_thread]->set_options("--score LLH"); regression_model_scores[current_thread] = score; } break; case options::EpistasisScore::REGRESSION_AIC: + case options::EpistasisScore::REGRESSION_COV_AIC: if (regression_model_scores[current_thread] != score) { regression_models[current_thread]->set_options("--score AIC"); regression_model_scores[current_thread] = score; } break; case options::EpistasisScore::REGRESSION_BIC: + case options::EpistasisScore::REGRESSION_COV_BIC: if (regression_model_scores[current_thread] != score) { regression_models[current_thread]->set_options("--score BIC"); regression_model_scores[current_thread] = score; @@ -192,7 +200,69 @@ namespace epi { regression_model_scores[current_thread] = score; } break; - default: + case options::EpistasisScore::REGRESSION_CLG_L_LC: + if (regression_model_scores[current_thread] != score) { + regression_models[current_thread]->set_options("--score CLG-L-LC"); + regression_model_scores[current_thread] = score; + } + break; + case options::EpistasisScore::REGRESSION_CLG_Q_LC: + if (regression_model_scores[current_thread] != score) { + regression_models[current_thread]->set_options("--score CLG-Q-LC"); + regression_model_scores[current_thread] = score; + } + break; + case options::EpistasisScore::REGRESSION_CLG_Q_QC: + if (regression_model_scores[current_thread] != score) { + regression_models[current_thread]->set_options("--score CLG-Q-QC"); + regression_model_scores[current_thread] = score; + } + break; + } + + switch(score) { + case options::EpistasisScore::BAYESIAN_COV: + bayesian_models[current_thread]->cov_activate(); + break; + case options::EpistasisScore::VARIANCE_COV: + variance_models[current_thread]->cov_activate(); + break; + case options::EpistasisScore::PENETRANCE_COV_NLL: + case options::EpistasisScore::PENETRANCE_COV_LLH: + case options::EpistasisScore::PENETRANCE_COV_AIC: + case options::EpistasisScore::PENETRANCE_COV_BIC: + penetrance_models[current_thread]->cov_activate(); + break; + case options::EpistasisScore::REGRESSION_COV_NLL: + case options::EpistasisScore::REGRESSION_COV_LLH: + case options::EpistasisScore::REGRESSION_COV_AIC: + case options::EpistasisScore::REGRESSION_COV_BIC: + case options::EpistasisScore::REGRESSION_CLG_L_LC: + case options::EpistasisScore::REGRESSION_CLG_Q_LC: + case options::EpistasisScore::REGRESSION_CLG_Q_QC: + regression_models[current_thread]->cov_activate(); + break; + case options::EpistasisScore::BAYESIAN: + bayesian_models[current_thread]->cov_deactivate(); + break; + case options::EpistasisScore::VARIANCE: + variance_models[current_thread]->cov_deactivate(); + break; + case options::EpistasisScore::PENETRANCE_NLL: + case options::EpistasisScore::PENETRANCE_LLH: + case options::EpistasisScore::PENETRANCE_AIC: + case options::EpistasisScore::PENETRANCE_BIC: + penetrance_models[current_thread]->cov_deactivate(); + break; + case options::EpistasisScore::REGRESSION_NLL: + case options::EpistasisScore::REGRESSION_LLH: + case options::EpistasisScore::REGRESSION_AIC: + case options::EpistasisScore::REGRESSION_BIC: + case options::EpistasisScore::REGRESSION_NLL_GAIN: + case options::EpistasisScore::REGRESSION_LLH_GAIN: + case options::EpistasisScore::REGRESSION_AIC_GAIN: + case options::EpistasisScore::REGRESSION_BIC_GAIN: + regression_models[current_thread]->cov_deactivate(); break; } } diff --git a/src/jobs/InstanceLoader.cpp b/src/jobs/InstanceLoader.cpp index e55e8d05b..e71d13686 100644 --- a/src/jobs/InstanceLoader.cpp +++ b/src/jobs/InstanceLoader.cpp @@ -8,7 +8,7 @@ #include "../util/TimeLogger.hpp" namespace epi { - InstanceLoader::InstanceLoader(std::string path_, std::string input_format_, std::string phenotype_, size_t num_categories_) { + InstanceLoader::InstanceLoader(std::string path_, std::string input_format_, std::string phenotype_, size_t num_categories_, std::string covariates_file_) { std::string ending = ".csv"; input_format_ = toUpperCase(input_format_); inputFormatStr = input_format_; @@ -47,6 +47,13 @@ namespace epi { throw epi::Error("At least 2 categories needed."); } num_categories = num_categories_; + + // check covariates file if provided + if (!covariates_file_.empty()) { + FileFinder cov_ff; + cov_ff.add_ends_with(".csv"); + this->covariates_file = find_file_by_ending(covariates_file_, cov_ff); + } } void InstanceLoader::run(std::shared_ptr data) { @@ -56,6 +63,9 @@ namespace epi { if (phenotype == options::PhenoType::QUANTITATIVE) { auto instance = std::make_shared>(); instance->load(inputFormat, path); + if (!covariates_file.empty()) { + instance->load_cov(options::InputFormat::CSV_COV, covariates_file); + } auto storage = std::make_shared>(instance); auto snpStorage = std::static_pointer_cast(storage); data->snpStorage = snpStorage; @@ -63,6 +73,9 @@ namespace epi { } else if (phenotype == options::PhenoType::CATEGORICAL) { auto instance = std::make_shared>(num_categories); instance->load(inputFormat, path); + if (!covariates_file.empty()) { + instance->load_cov(options::InputFormat::CSV_COV, covariates_file); + } auto storage = std::make_shared>(instance); auto snpStorage = std::static_pointer_cast(storage); data->snpStorage = snpStorage; diff --git a/src/jobs/InstanceLoader.hpp b/src/jobs/InstanceLoader.hpp index aa0ed0d64..589b3eb0c 100644 --- a/src/jobs/InstanceLoader.hpp +++ b/src/jobs/InstanceLoader.hpp @@ -11,7 +11,7 @@ namespace epi { class InstanceLoader : public Job { public: - InstanceLoader(std::string path, std::string input_format, std::string phenotype, size_t num_categories = 2); + InstanceLoader(std::string path, std::string input_format, std::string phenotype, size_t num_categories = 2, std::string covariates_file = ""); void run(std::shared_ptr data) override; rapidjson::Value getConfig(rapidjson::Document &doc) override; const std::string getInputFilePath() const; @@ -22,6 +22,7 @@ namespace epi { std::string phenotypeStr; epi::options::PhenoType phenotype; size_t num_categories; + std::string covariates_file; }; } // epi diff --git a/src/pipelines/NeEDLPipeline.cpp b/src/pipelines/NeEDLPipeline.cpp index c8062718d..d527d1d10 100644 --- a/src/pipelines/NeEDLPipeline.cpp +++ b/src/pipelines/NeEDLPipeline.cpp @@ -26,7 +26,7 @@ NeEDLPipeline::NeEDLPipeline(std::string input_path, std::string input_format, std::string input_phenotype, - size_t input_num_categories, bool disable_save_network, bool calculate_advanced_network_stats, bool joint_degree_analysis, + size_t input_num_categories, std::string covariates_file, bool disable_save_network, bool calculate_advanced_network_stats, bool joint_degree_analysis, bool no_additional_scores, std::string output_directory, int num_threads, std::string data_directory) { @@ -36,7 +36,7 @@ NeEDLPipeline::NeEDLPipeline(std::string input_path, std::string input_format, s this->disable_save_network = disable_save_network; if (!no_additional_scores) { - additional_scores = epi::options::get_all_epistasis_scores(); + additional_scores = epi::options::get_all_epistasis_scores(!covariates_file.empty()); } if (output_directory.empty()) { @@ -61,7 +61,8 @@ NeEDLPipeline::NeEDLPipeline(std::string input_path, std::string input_format, s input_path, input_format, input_phenotype, - input_num_categories + input_num_categories, + covariates_file ); preparationPipeline = { diff --git a/src/pipelines/NeEDLPipeline.hpp b/src/pipelines/NeEDLPipeline.hpp index aeec1a586..ce030fd89 100644 --- a/src/pipelines/NeEDLPipeline.hpp +++ b/src/pipelines/NeEDLPipeline.hpp @@ -31,6 +31,7 @@ class NeEDLPipeline { std::string input_format, std::string input_phenotype, size_t input_num_categories, + std::string covariates_file, // network stats bool disable_save_network, diff --git a/src/util/types.cpp b/src/util/types.cpp index aedd3766d..4d6a02730 100644 --- a/src/util/types.cpp +++ b/src/util/types.cpp @@ -235,16 +235,29 @@ namespace epi { } } - std::vector get_all_epistasis_scores() { + std::vector get_all_epistasis_scores(bool include_covariates) { // return { "PENETRANCE" }; - return std::vector{"BAYESIAN", "BAYESIAN_COV", - "PENETRANCE_NLL", "PENETRANCE_LLH", "PENETRANCE_AIC", "PENETRANCE_BIC", - "PENETRANCE_COV_NLL", "PENETRANCE_COV_LLH", "PENETRANCE_COV_AIC", "PENETRANCE_COV_BIC", - "REGRESSION_NLL", "REGRESSION_LLH", "REGRESSION_AIC", "REGRESSION_BIC", - "REGRESSION_COV_NLL", "REGRESSION_COV_LLH", "REGRESSION_COV_AIC", "REGRESSION_COV_BIC", - "REGRESSION_NLL-GAIN", "REGRESSION_LLH-GAIN", "REGRESSION_AIC-GAIN", "REGRESSION_BIC-GAIN", - "REGRESSION_CLG_Q_LC", "REGRESSION_CLG_Q_QC", "REGRESSION_CLG_L_LC", - "VARIANCE", "VARIANCE_COV"}; + auto without_cov = std::vector{ + "BAYESIAN", + "PENETRANCE_NLL", "PENETRANCE_LLH", "PENETRANCE_AIC", "PENETRANCE_BIC", + "REGRESSION_NLL", "REGRESSION_LLH", "REGRESSION_AIC", "REGRESSION_BIC", + "REGRESSION_NLL-GAIN", "REGRESSION_LLH-GAIN", "REGRESSION_AIC-GAIN", "REGRESSION_BIC-GAIN", + "VARIANCE" + }; + + if (include_covariates) { + auto with_cov = std::vector{ + "BAYESIAN_COV", + "PENETRANCE_COV_NLL", "PENETRANCE_COV_LLH", "PENETRANCE_COV_AIC", "PENETRANCE_COV_BIC", + "REGRESSION_COV_NLL", "REGRESSION_COV_LLH", "REGRESSION_COV_AIC", "REGRESSION_COV_BIC", + "REGRESSION_CLG_Q_LC", "REGRESSION_CLG_Q_QC","REGRESSION_CLG_L_LC", + "VARIANCE_COV" + }; + + without_cov.insert(without_cov.begin(), with_cov.begin(), with_cov.end()); + } + + return without_cov; } std::string epistasis_score_to_string(EpistasisScore model) { diff --git a/src/util/types.hpp b/src/util/types.hpp index d8f098db6..96959cb1b 100644 --- a/src/util/types.hpp +++ b/src/util/types.hpp @@ -244,7 +244,7 @@ namespace epi { EpistasisModel epistasis_model_from_string(const std::string & model_string); EpistasisModel epistasis_model_from_epistasis_score(EpistasisScore score); EpistasisScore epistasis_score_from_string(const std::string & score_string); - std::vector get_all_epistasis_scores(); + std::vector get_all_epistasis_scores(bool include_covariates = false); std::string epistasis_model_to_string(EpistasisModel model); std::string epistasis_score_to_string(EpistasisScore model); bool is_epistasis_model_string(const std::string & model_string); diff --git a/test/model/src/NeEDL.cpp b/test/model/src/NeEDL.cpp index 8bfac945f..43d1de7e0 100644 --- a/test/model/src/NeEDL.cpp +++ b/test/model/src/NeEDL.cpp @@ -74,6 +74,10 @@ int main(int argc, char** argv) { "The number of categories for categorical phenotypes. DEFAULT: 2.")->check( CLI::Validator(check_integer_greater_1, "GREATER1")); + std::string covariates_file; + app.add_option("--covariates-file", covariates_file, "CSV file containing covariate data."); + + /* app.add_option("--input-SNP-format", options.input_SNP_format, "The format of the SNPs, either rsIDs (RSID) or position based (POSITION_BASED)")->required(); @@ -556,6 +560,7 @@ int main(int argc, char** argv) { input_format, input_phenotype, input_num_categories, + covariates_file, disable_save_network, calculate_advanced_network_statistics, do_joint_degree_analysis, From ab09e02e3cd40e201983a3a38e402e13b46b1f0a Mon Sep 17 00:00:00 2001 From: maximus-victor Date: Mon, 7 Aug 2023 01:33:37 +0200 Subject: [PATCH 04/14] readme up --- README.md | 6 +++--- src/model/regression_model.ipp | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 934bf634d..a49b75774 100644 --- a/README.md +++ b/README.md @@ -356,9 +356,9 @@ NeEDL supports various statistical scores that can be used for `--ms-model`. Ple - `REGRESSION_COV_LLH`: likelihood of the quadratic-regression model, includes covariates - `REGRESSION_COV_AIC`: Akaike information criterion of the quadratic-regression model, includes covariates - `REGRESSION_COV_BIC`: Bayesian information criterion of the quadratic-regression model, includes covariates -- `REGRESSION_CLG_Q_LC`: **TODO** -- `REGRESSION_CLG_Q_QC`: **TODO** -- `REGRESSION_CLG_L_LC`: **TODO** +- `REGRESSION_CLG_Q_LC`: Confounder corrected likelihood gain (CLG) of linear regression model vs linear regression model with covariates. We define CLG as the LLH-Gain of a model with covariates over a model without covariates. The higher the CLG, the better is our linear model with covariates. +- `REGRESSION_CLG_Q_QC`: Confounder corrected likelihood gain (CLG) of quadratic regression model vs quadratic regression model with covariates. We define CLG as the LLH-Gain of a model with covariates over a model without covariates. The higher the CLG, the better is our quadratic model with covariates. +- `REGRESSION_CLG_L_LC`: Confounder corrected likelihood gain (CLG) of  quadratic regression model vs linear regression model with covariates. We define CLG as the LLH-Gain of a model with covariates over a model without covariates. The higher the CLG, the better is our linear model with covariates. **IMPORTANT: Please make sure you selected a score that has `COV` in its name if you want to use covariates. Specifying a covariate file is not enough.** diff --git a/src/model/regression_model.ipp b/src/model/regression_model.ipp index 96666057a..9d7012d1d 100644 --- a/src/model/regression_model.ipp +++ b/src/model/regression_model.ipp @@ -116,12 +116,10 @@ namespace epi { return true; } if (option == "cov") { - score_ = arg; - if (arg == "COV-ONLY") { + try { + score_ = arg; this->cov_activate(); - } else if (arg == "COV-MIXED"){ - - } else { + } catch (...) { throw Error(std::string("Invalid argument \"") + arg + "\" for option \"--" + option + "\". Usage: options = \"[--" + option + " COV-ONLY|COV-MIXED] [...]\""); } return true; From 736e4dbf90720b6c7cd09ef1a984262e85c9718b Mon Sep 17 00:00:00 2001 From: maximus-victor Date: Mon, 7 Aug 2023 02:09:42 +0200 Subject: [PATCH 05/14] readme up --- src/model/regression_model.ipp | 11 +---------- test/unit/src/regression_model.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/model/regression_model.ipp b/src/model/regression_model.ipp index 9d7012d1d..eff99aecf 100644 --- a/src/model/regression_model.ipp +++ b/src/model/regression_model.ipp @@ -115,15 +115,6 @@ namespace epi { } return true; } - if (option == "cov") { - try { - score_ = arg; - this->cov_activate(); - } catch (...) { - throw Error(std::string("Invalid argument \"") + arg + "\" for option \"--" + option + "\". Usage: options = \"[--" + option + " COV-ONLY|COV-MIXED] [...]\""); - } - return true; - } return false; } @@ -143,7 +134,7 @@ namespace epi { std::string RegressionModel:: valid_options_() const { - return "[--score LLH|LLH-GAIN|NLL|NLL-GAIN|AIC|AIC-GAIN|BIC|BIC-GAIN|CLG-L-LC|CLG-Q-QC|CLG-Q-LC] [--max-itrs ] [--learning-rate ] [--epsilon ] [--cov COV-ONLY|COV-MIXED]"; + return "[--score LLH|LLH-GAIN|NLL|NLL-GAIN|AIC|AIC-GAIN|BIC|BIC-GAIN|CLG-L-LC|CLG-Q-QC|CLG-Q-LC] [--max-itrs ] [--learning-rate ] [--epsilon ] [--cov]"; } template diff --git a/test/unit/src/regression_model.cpp b/test/unit/src/regression_model.cpp index 2d770aa98..007ccee38 100644 --- a/test/unit/src/regression_model.cpp +++ b/test/unit/src/regression_model.cpp @@ -152,7 +152,7 @@ TEST_CASE("Quantitative Instance - Cov Scores") { std::vector scores{"CLG-L-LC", "CLG-Q-QC", "CLG-Q-LC"}; for (const auto & score : scores) { - REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --cov COV-MIXED --score " + score))); + REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --score " + score))); CHECK_THAT(model.evaluate(disease_snp_set), Catch::WithinAbs(model.evaluate(disease_snp_set_shuffled), 0.0001)); @@ -197,7 +197,7 @@ TEST_CASE("Categorical Instance 1 - Cov Scores") { std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC"}; for (const auto & score : scores) { - REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --cov COV-MIXED --score " + score))); + REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --score " + score))); double check1 = model.evaluate(disease_snp_set); double check2 = model.evaluate(disease_snp_set_shuffled); CHECK_THAT(check1, Catch::WithinAbs(check2, 0.0001)); @@ -237,7 +237,7 @@ TEST_CASE("Categorical Instance 2 - Cov Scores") { std::vector disease_snp_set_shuffled{1, 0}; std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC"}; for (const auto & score : scores) { - REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --cov COV-MIXED --score " + score))); + REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --score " + score))); CHECK_THAT(model.evaluate(disease_snp_set), Catch::WithinAbs(model.evaluate(disease_snp_set_shuffled), 0.0001)); CHECK_NOTHROW(model.evaluate_track_time(disease_snp_set)); @@ -267,7 +267,7 @@ TEST_CASE("Quantitative Instance - Cov activate/deactivate") { std::vector disease_snp_set_shuffled{30, 4, 43}; std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC", "LLH", "NLL", "AIC", "BIC", "LLH-GAIN", "NLL-GAIN", "AIC-GAIN", "BIC-GAIN"}; for (const auto & score : scores) { - REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --cov COV-MIXED --score " + score))); + REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --score " + score))); CHECK_THAT(model.evaluate(disease_snp_set), Catch::WithinAbs(model.evaluate(disease_snp_set_shuffled), 0.0001)); @@ -311,7 +311,7 @@ TEST_CASE("Categorical Instance 1 - Cov activate/deactivate") { std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC", "LLH", "NLL", "AIC", "BIC", "LLH-GAIN", "NLL-GAIN", "AIC-GAIN", "BIC-GAIN"}; for (const auto & score : scores) { - REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --cov COV-MIXED --score " + score))); + REQUIRE_NOTHROW(model.set_options(std::string("--max-itrs 5 --score " + score))); double check1 = model.evaluate(disease_snp_set); double check2 = model.evaluate(disease_snp_set_shuffled); CHECK_THAT(check1, Catch::WithinAbs(check2, 0.0001)); From 81cab8fa8cb5fcefbd8b96acfa8a6f5b91fbee26 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Wed, 16 Aug 2023 10:27:47 +0200 Subject: [PATCH 06/14] removed -max-itrs flag, started implementing unit test for NaN --- src/data_model/SNPStorage.ipp | 2 +- test/unit/src/regression_model.cpp | 36 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/data_model/SNPStorage.ipp b/src/data_model/SNPStorage.ipp index 9ca9e6797..48e042398 100644 --- a/src/data_model/SNPStorage.ipp +++ b/src/data_model/SNPStorage.ipp @@ -178,7 +178,7 @@ namespace epi { break; case options::EpistasisScore::REGRESSION_NLL_GAIN: if (regression_model_scores[current_thread] != score) { - regression_models[current_thread]->set_options("--score NLL-GAIN --max-itrs 50000"); + regression_models[current_thread]->set_options("--score NLL-GAIN"); regression_model_scores[current_thread] = score; } break; diff --git a/test/unit/src/regression_model.cpp b/test/unit/src/regression_model.cpp index 2d770aa98..cc39a6d56 100644 --- a/test/unit/src/regression_model.cpp +++ b/test/unit/src/regression_model.cpp @@ -337,3 +337,39 @@ TEST_CASE("Categorical Instance 1 - Cov activate/deactivate") { } } } + +TEST_CASE("Categorical Instance 1 - No NaN values") { + epi::Instance instance(2); + REQUIRE_NOTHROW(instance.load(epi::options::InputFormat::JSON_EPIGEN, "../../../data/EpiGEN/dichotomous/2_disease_snps/exponential/1_1_ASW.json")); + REQUIRE_NOTHROW(instance.load_cov(epi::options::InputFormat::CSV_COV, "../../../data/COV_TEST/EpiGEN_RND_COV.csv")); + epi::RegressionModel model(&instance); + REQUIRE_NOTHROW(model.initialize()); + CHECK(model.is_predictive()); + CHECK(model.model_sense() == epi::options::ModelSense::MINIMIZE); + + std::vector problematic_rs_ids = { "rs11589207", "rs10927631" }; + std::vector problematic_snps(2); + // ugly way to find RS-IDs in dataset + for (size_t i = 0; i < problematic_rs_ids.size(); ++i) { + bool found = false; + for (size_t j = 0; j < instance.rs_ids_.size(); ++j) { + if (problematic_rs_ids[i] == instance.rs_ids_[j]) { + problematic_snps[i] = j; + found = true; + } + } + CHECK(found); + } + + std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC", "LLH", "NLL", "AIC", "BIC", "LLH-GAIN", "NLL-GAIN", "AIC-GAIN", "BIC-GAIN"}; + for(size_t i = 0; i < 3; ++i) { + for (const auto &score: scores) { + REQUIRE_NOTHROW(model.set_options(std::string("--score " + score))); + REQUIRE_NOTHROW(model.cov_activate()); + double value = model.evaluate(problematic_snps); + + CHECK(!std::isnan(value)); + std::cout << value << std::endl; + } + } +} From 1fc0e85e20742b34e6c53ee61f111e63bbd5e3d6 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 11:21:28 +0200 Subject: [PATCH 07/14] tried to get cov working in NeEDL workflow --- ext/uWebSockets | 1 + src/data_model/SNPStorage.ipp | 95 +++++++++++++++++++----------- src/jobs/WriteSets.cpp | 7 ++- src/util/types.cpp | 30 +++++----- src/util/types.hpp | 54 ++++++++--------- test/unit/CMakeLists.txt | 3 + test/unit/src/regression_model.cpp | 48 ++++++++++++++- 7 files changed, 158 insertions(+), 80 deletions(-) create mode 160000 ext/uWebSockets diff --git a/ext/uWebSockets b/ext/uWebSockets new file mode 160000 index 000000000..f1b10ed22 --- /dev/null +++ b/ext/uWebSockets @@ -0,0 +1 @@ +Subproject commit f1b10ed221b36c0d8848998e3e939823f66496eb diff --git a/src/data_model/SNPStorage.ipp b/src/data_model/SNPStorage.ipp index 48e042398..b47552134 100644 --- a/src/data_model/SNPStorage.ipp +++ b/src/data_model/SNPStorage.ipp @@ -101,20 +101,30 @@ namespace epi { void SNPStorage_PhenoType::request_score_method(options::EpistasisScore score, size_t current_thread) { switch (epistasis_model_from_epistasis_score(score)) { case options::EpistasisModel::BAYESIAN_MODEL: - if (bayesian_models[current_thread] == nullptr) + if (bayesian_models[current_thread] == nullptr) { bayesian_models[current_thread] = std::make_shared>(instance.get()); + bayesian_models[current_thread]->initialize(); + } break; case options::EpistasisModel::PENETRANCE_MODEL: - if (penetrance_models[current_thread] == nullptr) + if (penetrance_models[current_thread] == nullptr) { penetrance_models[current_thread] = std::make_shared>(instance.get()); + penetrance_models[current_thread]->set_options("--score NLL"); + penetrance_models[current_thread]->initialize(); + } break; case options::EpistasisModel::REGRESSION_MODEL: - if (regression_models[current_thread] == nullptr) + if (regression_models[current_thread] == nullptr) { regression_models[current_thread] = std::make_shared>(instance.get()); + regression_models[current_thread]->set_options("--score NLL"); + regression_models[current_thread]->initialize(); + } break; case options::EpistasisModel::VARIANCE_MODEL: - if (variance_models[current_thread] == nullptr) + if (variance_models[current_thread] == nullptr) { variance_models[current_thread] = std::make_shared>(instance.get()); + variance_models[current_thread]->initialize(); + } break; } @@ -122,102 +132,119 @@ namespace epi { switch(score) { case options::EpistasisScore::PENETRANCE_NLL: case options::EpistasisScore::PENETRANCE_COV_NLL: - if (penetrance_model_scores[current_thread] != score) { + if (penetrance_model_scores[current_thread] != options::EpistasisScore::PENETRANCE_NLL) { penetrance_models[current_thread]->set_options("--score NLL"); - penetrance_model_scores[current_thread] = score; + penetrance_models[current_thread]->initialize(); + penetrance_model_scores[current_thread] = options::EpistasisScore::PENETRANCE_NLL; } break; case options::EpistasisScore::PENETRANCE_LLH: case options::EpistasisScore::PENETRANCE_COV_LLH: - if (penetrance_model_scores[current_thread] != score) { + if (penetrance_model_scores[current_thread] != options::EpistasisScore::PENETRANCE_LLH) { penetrance_models[current_thread]->set_options("--score LLH"); - penetrance_model_scores[current_thread] = score; + penetrance_models[current_thread]->initialize(); + penetrance_model_scores[current_thread] = options::EpistasisScore::PENETRANCE_LLH; } break; case options::EpistasisScore::PENETRANCE_AIC: case options::EpistasisScore::PENETRANCE_COV_AIC: - if (penetrance_model_scores[current_thread] != score) { + if (penetrance_model_scores[current_thread] != options::EpistasisScore::PENETRANCE_AIC) { penetrance_models[current_thread]->set_options("--score AIC"); - penetrance_model_scores[current_thread] = score; + penetrance_models[current_thread]->initialize(); + penetrance_model_scores[current_thread] = options::EpistasisScore::PENETRANCE_AIC; } break; case options::EpistasisScore::PENETRANCE_BIC: case options::EpistasisScore::PENETRANCE_COV_BIC: - if (penetrance_model_scores[current_thread] != score) { + if (penetrance_model_scores[current_thread] != options::EpistasisScore::PENETRANCE_BIC) { penetrance_models[current_thread]->set_options("--score BIC"); - penetrance_model_scores[current_thread] = score; + penetrance_models[current_thread]->initialize(); + penetrance_model_scores[current_thread] = options::EpistasisScore::PENETRANCE_BIC; } break; case options::EpistasisScore::REGRESSION_NLL: case options::EpistasisScore::REGRESSION_COV_NLL: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_NLL) { regression_models[current_thread]->set_options("--score NLL"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_NLL; } break; case options::EpistasisScore::REGRESSION_LLH: case options::EpistasisScore::REGRESSION_COV_LLH: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_LLH) { regression_models[current_thread]->set_options("--score LLH"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_LLH; } break; case options::EpistasisScore::REGRESSION_AIC: case options::EpistasisScore::REGRESSION_COV_AIC: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_AIC) { regression_models[current_thread]->set_options("--score AIC"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_AIC; } break; case options::EpistasisScore::REGRESSION_BIC: case options::EpistasisScore::REGRESSION_COV_BIC: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_BIC) { regression_models[current_thread]->set_options("--score BIC"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_BIC; } break; case options::EpistasisScore::REGRESSION_NLL_GAIN: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_NLL_GAIN) { regression_models[current_thread]->set_options("--score NLL-GAIN"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_NLL_GAIN; } break; case options::EpistasisScore::REGRESSION_LLH_GAIN: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_LLH_GAIN) { regression_models[current_thread]->set_options("--score LLH-GAIN"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_LLH_GAIN; } break; case options::EpistasisScore::REGRESSION_AIC_GAIN: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_AIC_GAIN) { regression_models[current_thread]->set_options("--score AIC-GAIN"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_AIC_GAIN; } break; case options::EpistasisScore::REGRESSION_BIC_GAIN: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_BIC_GAIN) { regression_models[current_thread]->set_options("--score BIC-GAIN"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_BIC_GAIN; } break; case options::EpistasisScore::REGRESSION_CLG_L_LC: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_CLG_L_LC) { regression_models[current_thread]->set_options("--score CLG-L-LC"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_CLG_L_LC; } break; case options::EpistasisScore::REGRESSION_CLG_Q_LC: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_CLG_Q_LC) { regression_models[current_thread]->set_options("--score CLG-Q-LC"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_CLG_Q_LC; } break; case options::EpistasisScore::REGRESSION_CLG_Q_QC: - if (regression_model_scores[current_thread] != score) { + if (regression_model_scores[current_thread] != options::EpistasisScore::REGRESSION_CLG_Q_QC) { regression_models[current_thread]->set_options("--score CLG-Q-QC"); - regression_model_scores[current_thread] = score; + regression_models[current_thread]->initialize(); + regression_model_scores[current_thread] = options::EpistasisScore::REGRESSION_CLG_Q_QC; } break; + default: + break; } switch(score) { diff --git a/src/jobs/WriteSets.cpp b/src/jobs/WriteSets.cpp index a06d0774d..8ad04eea7 100644 --- a/src/jobs/WriteSets.cpp +++ b/src/jobs/WriteSets.cpp @@ -24,9 +24,14 @@ namespace epi { } std::set models; - std::transform(scores.begin(), scores.end(), std::inserter(models, models.begin()), [] (auto & model_str) -> auto { + std::transform(scores.begin(), scores.end(), std::inserter(models, models.end()), [] (auto & model_str) -> auto { return options::epistasis_score_from_string(model_str); }); + /* + if (has_rank_model) { + models.erase(this->rank_model); + } + */ epi_models = {models.begin(), models.end()}; } diff --git a/src/util/types.cpp b/src/util/types.cpp index 4d6a02730..5ee3ac9fb 100644 --- a/src/util/types.cpp +++ b/src/util/types.cpp @@ -27,7 +27,7 @@ std::ostream &operator<<(std::ostream &os, const epi::options::EpistasisScore &m os << "BAYESIAN"; break; case epi::options::EpistasisScore::BAYESIAN_COV: - os << "BAYESIAN"; + os << "BAYESIAN_COV"; break; case epi::options::EpistasisScore::PENETRANCE_NLL: os << "PENETRANCE_NLL"; @@ -66,16 +66,16 @@ std::ostream &operator<<(std::ostream &os, const epi::options::EpistasisScore &m os << "REGRESSION_BIC"; break; case epi::options::EpistasisScore::REGRESSION_NLL_GAIN: - os << "REGRESSION_NLL-GAIN"; + os << "REGRESSION_NLL_GAIN"; break; case epi::options::EpistasisScore::REGRESSION_LLH_GAIN: - os << "REGRESSION_LLH-GAIN"; + os << "REGRESSION_LLH_GAIN"; break; case epi::options::EpistasisScore::REGRESSION_AIC_GAIN: - os << "REGRESSION_AIC-GAIN"; + os << "REGRESSION_AIC_GAIN"; break; case epi::options::EpistasisScore::REGRESSION_BIC_GAIN: - os << "REGRESSION_BIC-GAIN"; + os << "REGRESSION_BIC_GAIN"; break; case epi::options::EpistasisScore::REGRESSION_COV_NLL: os << "REGRESSION_COV_NLL"; @@ -144,7 +144,7 @@ namespace epi { case EpistasisScore::VARIANCE_COV: return EpistasisModel::VARIANCE_MODEL; default: - return EpistasisModel::BAYESIAN_MODEL; + throw epi::Error("Unknown Epistasis Score."); } } @@ -162,8 +162,8 @@ namespace epi { } else if (model_string == "REGRESSION") { return EpistasisModel::REGRESSION_MODEL; } else if (model_string.substr(0, 11) == "REGRESSION_") { - std::vector scores = {"NLL", "LLH", "AIC", "BIC", "COV_NLL", "COV_LLH", "COV_AIC", "COV_BIC", "NLL-GAIN", "LLH-GAIN", "AIC-GAIN", - "BIC-GAIN", "CLG-L-LC", "CLG-Q-QC", "CLG-Q-LC"}; + std::vector scores = {"NLL", "LLH", "AIC", "BIC", "COV_NLL", "COV_LLH", "COV_AIC", "COV_BIC", "NLL_GAIN", "LLH_GAIN", "AIC_GAIN", + "BIC_GAIN", "CLG_L_LC", "CLG_Q_QC", "CLG_Q_LC"}; if (std::find(scores.begin(), scores.end(), model_string.substr(12)) == scores.end()) { throw epi::Error("Unknown REGRESSION score " + model_string); } @@ -204,13 +204,13 @@ namespace epi { return EpistasisScore::REGRESSION_AIC; } else if (model_string == "REGRESSION_BIC") { return EpistasisScore::REGRESSION_BIC; - } else if (model_string == "REGRESSION_NLL-GAIN") { + } else if (model_string == "REGRESSION_NLL_GAIN") { return EpistasisScore::REGRESSION_NLL_GAIN; - } else if (model_string == "REGRESSION_LLH-GAIN") { + } else if (model_string == "REGRESSION_LLH_GAIN") { return EpistasisScore::REGRESSION_LLH_GAIN; - } else if (model_string == "REGRESSION_AIC-GAIN") { + } else if (model_string == "REGRESSION_AIC_GAIN") { return EpistasisScore::REGRESSION_AIC_GAIN; - } else if (model_string == "REGRESSION_BIC-GAIN") { + } else if (model_string == "REGRESSION_BIC_GAIN") { return EpistasisScore::REGRESSION_BIC_GAIN; } else if (model_string == "REGRESSION_COV" || model_string == "REGRESSION_COV_NLL") { return EpistasisScore::REGRESSION_COV_NLL; @@ -241,7 +241,7 @@ namespace epi { "BAYESIAN", "PENETRANCE_NLL", "PENETRANCE_LLH", "PENETRANCE_AIC", "PENETRANCE_BIC", "REGRESSION_NLL", "REGRESSION_LLH", "REGRESSION_AIC", "REGRESSION_BIC", - "REGRESSION_NLL-GAIN", "REGRESSION_LLH-GAIN", "REGRESSION_AIC-GAIN", "REGRESSION_BIC-GAIN", + "REGRESSION_NLL_GAIN", "REGRESSION_LLH_GAIN", "REGRESSION_AIC_GAIN", "REGRESSION_BIC_GAIN", "VARIANCE" }; @@ -279,8 +279,8 @@ namespace epi { std::vector scores = {"NLL", "LLH", "AIC", "BIC", "COV_NLL", "COV_LLH", "COV_AIC", "COV_BIC"}; return std::find(scores.begin(), scores.end(), model_string.substr(12)) != scores.end(); } else if (model_string.substr(0, 11) == "REGRESSION_") { - std::vector scores = {"NLL", "LLH", "AIC", "BIC", "COV_NLL", "COV_LLH", "COV_AIC", "COV_BIC", "NLL-GAIN", "LLH-GAIN", "AIC-GAIN", - "BIC-GAIN", "CLG-L-LC", "CLG-Q-QC", "CLG-Q-LC"}; + std::vector scores = {"NLL", "LLH", "AIC", "BIC", "COV_NLL", "COV_LLH", "COV_AIC", "COV_BIC", "NLL_GAIN", "LLH_GAIN", "AIC_GAIN", + "BIC_GAIN", "CLG_L_LC", "CLG_Q_QC", "CLG_Q_LC"}; return std::find(scores.begin(), scores.end(), model_string.substr(12)) != scores.end(); } else { return false; diff --git a/src/util/types.hpp b/src/util/types.hpp index 96959cb1b..a35e398bc 100644 --- a/src/util/types.hpp +++ b/src/util/types.hpp @@ -211,33 +211,33 @@ namespace epi { }; enum class EpistasisScore { - BAYESIAN, - BAYESIAN_COV, - VARIANCE, - VARIANCE_COV, - PENETRANCE_NLL, - PENETRANCE_LLH, - PENETRANCE_AIC, - PENETRANCE_BIC, - PENETRANCE_COV_NLL, - PENETRANCE_COV_LLH, - PENETRANCE_COV_AIC, - PENETRANCE_COV_BIC, - REGRESSION_NLL, - REGRESSION_LLH, - REGRESSION_AIC, - REGRESSION_BIC, - REGRESSION_NLL_GAIN, - REGRESSION_LLH_GAIN, - REGRESSION_AIC_GAIN, - REGRESSION_BIC_GAIN, - REGRESSION_COV_NLL, - REGRESSION_COV_LLH, - REGRESSION_COV_AIC, - REGRESSION_COV_BIC, - REGRESSION_CLG_Q_LC, - REGRESSION_CLG_Q_QC, - REGRESSION_CLG_L_LC + BAYESIAN = 0, + BAYESIAN_COV = 1, + VARIANCE = 2, + VARIANCE_COV = 3, + PENETRANCE_NLL = 4, + PENETRANCE_LLH = 5, + PENETRANCE_AIC = 6, + PENETRANCE_BIC = 7, + PENETRANCE_COV_NLL = 8, + PENETRANCE_COV_LLH = 9, + PENETRANCE_COV_AIC = 10, + PENETRANCE_COV_BIC = 11, + REGRESSION_NLL = 12, + REGRESSION_LLH = 13, + REGRESSION_AIC = 14, + REGRESSION_BIC = 15, + REGRESSION_NLL_GAIN = 16, + REGRESSION_LLH_GAIN = 17, + REGRESSION_AIC_GAIN = 18, + REGRESSION_BIC_GAIN = 19, + REGRESSION_COV_NLL = 20, + REGRESSION_COV_LLH = 21, + REGRESSION_COV_AIC = 22, + REGRESSION_COV_BIC = 23, + REGRESSION_CLG_Q_LC = 24, + REGRESSION_CLG_Q_QC = 25, + REGRESSION_CLG_L_LC = 26 }; #define NUM_EPISTASIS_SCORES 27 diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index c58bb9ea5..79a349248 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -31,6 +31,9 @@ add_executable(variance_model src/variance_model.cpp src/catch_main.cpp) add_executable(penetrance_model src/penetrance_model.cpp src/catch_main.cpp) add_executable(regression_model src/regression_model.cpp src/catch_main.cpp) add_executable(bayesian_model src/bayesian_model.cpp src/catch_main.cpp) + +target_link_libraries(regression_model boost_filesystem igraph) + if(APPLE) target_link_libraries(regression_model omp) target_link_libraries(penetrance_model omp) diff --git a/test/unit/src/regression_model.cpp b/test/unit/src/regression_model.cpp index e5808ae29..d47276b19 100644 --- a/test/unit/src/regression_model.cpp +++ b/test/unit/src/regression_model.cpp @@ -37,6 +37,9 @@ #include // std::runtime_error #include // std::stringstream +#include "../../../src/jobs/InstanceLoader.hpp" +#include "../../../src/jobs/WriteSets.hpp" + TEST_CASE("Quantitative Instance") { epi::Instance instance; REQUIRE_NOTHROW(instance.load(epi::options::InputFormat::JSON_EPIGEN, "../../../data/EpiGEN/quantitative/2_disease_snps/exponential/0_1_ASW.json")); @@ -361,15 +364,54 @@ TEST_CASE("Categorical Instance 1 - No NaN values") { CHECK(found); } - std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC", "LLH", "NLL", "AIC", "BIC", "LLH-GAIN", "NLL-GAIN", "AIC-GAIN", "BIC-GAIN"}; - for(size_t i = 0; i < 3; ++i) { + std::vector scores{"CLG-Q-QC", "CLG-L-LC", "CLG-Q-LC", "LLH", "NLL", "AIC", "BIC" }; + for(size_t i = 0; i < 1; ++i) { for (const auto &score: scores) { REQUIRE_NOTHROW(model.set_options(std::string("--score " + score))); + REQUIRE_NOTHROW(model.initialize()); REQUIRE_NOTHROW(model.cov_activate()); - double value = model.evaluate(problematic_snps); + double value = model.evaluate(problematic_snps); CHECK(!std::isnan(value)); std::cout << value << std::endl; } } } + +TEST_CASE("Categorical Instance through NeEDL Pipelines - No NaN values") { + // load the instance via InstanceLoader Job + omp_set_num_threads(1); + epi::InstanceLoader loader( + "../../../data/EpiGEN/dichotomous/2_disease_snps/exponential/1_1_ASW.json", + "JSON_EPIGEN", + "DICHOTOMOUS", + 2, + "../../../data/COV_TEST/EpiGEN_RND_COV.csv" + ); + + auto data = std::make_shared(true); + loader.run(data); + + // construct SNP set + epi::SNPSet set {{data->snpStorage->by_name("rs11589207"),data->snpStorage->by_name("rs10927631")}}; + data->snpSetStorage.push_back(set); + + epi::WriteSets write_sets("PENETRANCE", epi::options::get_all_epistasis_scores(true)); + write_sets.outfile_path("regression_model.test.csv"); + write_sets.run(data); + + for (size_t i = 0; i < 20; ++i) { + double score_value = set.calculate_score(epi::options::EpistasisScore::PENETRANCE_NLL); + CHECK(!std::isnan(score_value)); + } + + // test scores + auto all_scores = epi::options::get_all_epistasis_scores(true); + for (const auto & score : all_scores) { + auto score_rep = epi::options::epistasis_score_from_string(score); + double score_value = set.calculate_score(score_rep); + + CHECK(!std::isnan(score_value)); + std::cout << score_value << std::endl; + } +} From ed2e9331e363b5e962bb0c3e0e0e87a43539d4d2 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 11:50:39 +0200 Subject: [PATCH 08/14] added nan e2e test --- test/e2e/test_container.sh | 82 ++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/test/e2e/test_container.sh b/test/e2e/test_container.sh index 41046bfeb..eed10f868 100755 --- a/test/e2e/test_container.sh +++ b/test/e2e/test_container.sh @@ -9,6 +9,17 @@ # abort on first error set -e +# die method to fail the test +warn () { + echo "$0:" "$@" >&2 +} +die () { + rc=$1 + shift + warn "$@" + exit $rc +} + # create temp output folder mkdir -p ./test_out out_dir=$(realpath ./test_out) @@ -40,16 +51,16 @@ dummy_dataset=$(realpath ./data/e2e_tests/dummy_dataset.json) python ./run/NeEDL.py \ --docker-image-name "$1" \ --docker-no-pulling \ - "--num-threads" "1" \ - "--output-directory" "$out_dir" \ - "--input-format" "JSON_EPIGEN" \ - "--input-path" "$dummy_dataset" \ - "--phenotype" "DICHOTOMOUS" \ - "--snp-annotate-dbSNP" \ - "--network-BIOGRID" \ - "--ms-seeding-routine" "RANDOM_CONNECTED" \ - "--ms-rc-start-seeds" "5" \ - "--ms-model" "PENETRANCE_NLL" + --num-threads 1 \ + --output-directory "$out_dir" \ + --input-format JSON_EPIGEN \ + --input-path "$dummy_dataset" \ + --phenotype DICHOTOMOUS \ + --snp-annotate-dbSNP \ + --network-BIOGRID \ + --ms-seeding-routine RANDOM_CONNECTED \ + --ms-rc-start-seeds 5 \ + --ms-model PENETRANCE_NLL # test that custom annotation files and custom networks work @@ -61,17 +72,48 @@ network_file=$(realpath ./data/e2e_tests/network.csv) python ./run/NeEDL.py \ --docker-image-name "$1" \ --docker-no-pulling \ - "--num-threads" "1" \ - "--output-directory" "$out_dir" \ - "--input-format" "JSON_EPIGEN" \ - "--input-path" "$dummy_dataset" \ - "--phenotype" "DICHOTOMOUS" \ - "--snp-annotate" "$annotation_file|yes|SNP|gene|\t|-1|-1" \ - "--network" "dummy_network|$network_file|yes|col1|col2|\t|-1|-1" \ - "--ms-seeding-routine" "RANDOM_CONNECTED" \ - "--ms-rc-start-seeds" "5" \ - "--ms-model" "PENETRANCE_NLL" + --num-threads 1 \ + --output-directory "$out_dir" \ + --input-format JSON_EPIGEN \ + --input-path "$dummy_dataset" \ + --phenotype DICHOTOMOUS \ + --snp-annotate "$annotation_file|yes|SNP|gene|\t|-1|-1" \ + --network "dummy_network|$network_file|yes|col1|col2|\t|-1|-1" \ + --ms-seeding-routine RANDOM_CONNECTED \ + --ms-rc-start-seeds 5 \ + --ms-model PENETRANCE_NLL +covariates_file=$(realpath ./data/COV_TEST/EpiGEN_RND_COV.csv) + +python ./run/NeEDL.py \ + --input-path "$dummy_dataset" \ + --input-format JSON_EPIGEN \ + --phenotype DICHOTOMOUS \ + --num-threads 1 \ + --output-directory "$out_dir" \ + --snp-annotate-dbSNP \ + --network-BIOGRID \ + --ms-model PENETRANCE \ + --ms-seeding-routine RANDOM_CONNECTED \ + --ms-rc-start-seeds 5 \ + --ms-search-time-limit 5s \ + --covariates-file "$covariates_file" + +# check that no NA values are present +for dir in "$out_dir"/* ; do + if [ -f "$dir/BIOGRID_seeds.csv" ]; then + if grep -Fxq "nan" "$dir/BIOGRID_seeds.csv"; then + die 1 "'nan' found in $dir/BIOGRID_seeds.csv" + fi + fi + + if [ -f "$dir/BIOGRID_results.csv" ]; then + if grep -Fxq "nan" "$dir/BIOGRID_results.csv"; then + die 1 "'nan' found in $dir/BIOGRID_results.csv" + fi + fi + +done # TODO: add more tests here From a42d1e954391773aa018bad62f0180f3528fca10 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:11:43 +0200 Subject: [PATCH 09/14] fixed docker container bug in e2e test --- test/e2e/test_container.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/e2e/test_container.sh b/test/e2e/test_container.sh index eed10f868..4dc27e1ed 100755 --- a/test/e2e/test_container.sh +++ b/test/e2e/test_container.sh @@ -86,6 +86,8 @@ python ./run/NeEDL.py \ covariates_file=$(realpath ./data/COV_TEST/EpiGEN_RND_COV.csv) python ./run/NeEDL.py \ + --docker-image-name "$1" \ + --docker-no-pulling \ --input-path "$dummy_dataset" \ --input-format JSON_EPIGEN \ --phenotype DICHOTOMOUS \ From e1924eefd3eb5f1883674585098c2982f84aa4fc Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:20:01 +0200 Subject: [PATCH 10/14] added --covariates-file to mount list --- run/NeEDL.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run/NeEDL.py b/run/NeEDL.py index 691ce12cd..b00b487cb 100644 --- a/run/NeEDL.py +++ b/run/NeEDL.py @@ -51,7 +51,7 @@ input_paths = [] # normal paths -normal_path_attribs = ['--input-path', '--ms-ld-matrix', '--fs-ld-matrix'] +normal_path_attribs = ['--input-path', '--ms-ld-matrix', '--fs-ld-matrix', '--covariates-file'] for i, arg in enumerate(arguments): if arg in normal_path_attribs: if len(arguments) > i + 1: From 3153e3496408a0d99e5f9548d7ae0c4dcbb7a5e8 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:29:54 +0200 Subject: [PATCH 11/14] e2e test more verbose --- test/e2e/test_container.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/e2e/test_container.sh b/test/e2e/test_container.sh index 4dc27e1ed..725e410d4 100755 --- a/test/e2e/test_container.sh +++ b/test/e2e/test_container.sh @@ -103,15 +103,21 @@ python ./run/NeEDL.py \ # check that no NA values are present for dir in "$out_dir"/* ; do + echo "NAN Check: entering directory '$dir'" + if [ -f "$dir/BIOGRID_seeds.csv" ]; then if grep -Fxq "nan" "$dir/BIOGRID_seeds.csv"; then die 1 "'nan' found in $dir/BIOGRID_seeds.csv" + elif + echo "NAN Check: $dir/BIOGRID_seeds.csv passed" fi fi if [ -f "$dir/BIOGRID_results.csv" ]; then if grep -Fxq "nan" "$dir/BIOGRID_results.csv"; then die 1 "'nan' found in $dir/BIOGRID_results.csv" + elif + echo "NAN Check: $dir/BIOGRID_results.csv passed" fi fi From de681ae7b964e6632f9867d563a06b8ce1229207 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:49:28 +0200 Subject: [PATCH 12/14] e2e bug fix --- test/e2e/test_container.sh | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/test/e2e/test_container.sh b/test/e2e/test_container.sh index 725e410d4..f6f1b1cdb 100755 --- a/test/e2e/test_container.sh +++ b/test/e2e/test_container.sh @@ -104,22 +104,30 @@ python ./run/NeEDL.py \ # check that no NA values are present for dir in "$out_dir"/* ; do echo "NAN Check: entering directory '$dir'" - - if [ -f "$dir/BIOGRID_seeds.csv" ]; then - if grep -Fxq "nan" "$dir/BIOGRID_seeds.csv"; then - die 1 "'nan' found in $dir/BIOGRID_seeds.csv" - elif - echo "NAN Check: $dir/BIOGRID_seeds.csv passed" - fi - fi - - if [ -f "$dir/BIOGRID_results.csv" ]; then - if grep -Fxq "nan" "$dir/BIOGRID_results.csv"; then - die 1 "'nan' found in $dir/BIOGRID_results.csv" - elif - echo "NAN Check: $dir/BIOGRID_results.csv passed" + filelist=("$dir/BIOGRID_seeds.csv" "$dir/BIOGRID_results.csv") + + for file in "${filelist[@]}"; do + if [ -f "$file" ]; then + + case `grep -Fx "nan" "$file" >/dev/null; echo $?` in + 0) + # code if found + echo "NAN Check: $file passed" + ;; + 1) + # code if not found + die 2 "NAN Check: 'nan' found in $file" + ;; + *) + # code if an error occurred + die 3 "NAN Check: An error occurred while checking $file" + ;; + esac + + else + echo "$file does not exist --> skip" fi - fi + done done From 2bb3093826bb12e0e78f5f5f8f4e57a016ab2083 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Mon, 2 Oct 2023 17:49:28 +0200 Subject: [PATCH 13/14] continue searching the error --- src/jobs/DummyErrorTask.cpp | 62 ++++++++++++++++++++++++++++ src/jobs/DummyErrorTask.hpp | 35 ++++++++++++++++ src/jobs/NetworkCsvConnector.cpp | 7 ---- test/unit/src/regression_model.cpp | 65 ++++++++++++++++++++++++------ 4 files changed, 150 insertions(+), 19 deletions(-) create mode 100644 src/jobs/DummyErrorTask.cpp create mode 100644 src/jobs/DummyErrorTask.hpp diff --git a/src/jobs/DummyErrorTask.cpp b/src/jobs/DummyErrorTask.cpp new file mode 100644 index 000000000..4ac790885 --- /dev/null +++ b/src/jobs/DummyErrorTask.cpp @@ -0,0 +1,62 @@ +// +// Created by juli on 02.10.23. +// + +#include "DummyErrorTask.hpp" + +#include "../util/FileFinder.hpp" +#include "../util/helper_functions.hpp" +#include "../util/TimeLogger.hpp" + +namespace epi { + void DummyErrorTask::run(std::shared_ptr data) { + TimeLogger logger("Run CSVParser to cause the error"); + + // extract mappings + std::vector> all_annotations; + CSVParser parser; + parser.parse(path, csv_separator); + + + logger.stop(); + } + + DummyErrorTask::DummyErrorTask(std::string name, std::string path, std::string column1, std::string column2, + char csv_separator, char col1_separator, char col2_separator) + : DummyErrorTask(name, true, csv_separator, col1_separator, col2_separator) { + + FileFinder ff; + // ff.add_ends_with(".csv"); + this->path = find_file_by_ending(std::move(path), ff); + + check_columns(column1, column2); + } + + DummyErrorTask::DummyErrorTask(std::string name, bool has_header, char csv_separator, char col1_separator, + char col2_separator) { + this->has_header = has_header; + this->csv_separator = csv_separator; + this->col1_separator = col1_separator; + this->col2_separator = col2_separator; + this->name = name; + } + + void DummyErrorTask::check_columns(const std::string &col1, const std::string &col2) { +// check if column indices are valid + std::ifstream file(this->path); + std::string first_line; + std::getline(file, first_line); + auto splits = string_split(first_line, csv_separator); + auto col1_pos = std::find(splits.begin(), splits.end(), col1); + if (col1_pos == splits.end()) { + throw epi::Error("Invalid column name " + col1 + "."); + } else this->column1 = col1_pos - splits.begin(); + + auto col2_pos = std::find(splits.begin(), splits.end(), col2); + if (col2_pos == splits.end()) { + throw epi::Error("Invalid column name " + col2 + "."); + } else this->column2 = col2_pos - splits.begin(); + + file.close(); + } +} // epi \ No newline at end of file diff --git a/src/jobs/DummyErrorTask.hpp b/src/jobs/DummyErrorTask.hpp new file mode 100644 index 000000000..c9820bdbb --- /dev/null +++ b/src/jobs/DummyErrorTask.hpp @@ -0,0 +1,35 @@ +// +// Created by juli on 02.10.23. +// + +#ifndef NEEDL_DUMMYERRORTASK_HPP +#define NEEDL_DUMMYERRORTASK_HPP + +#include "Job.hpp" + +namespace epi { + + class DummyErrorTask : public Job { + public: + DummyErrorTask(std::string name, std::string path, std::string column1, std::string column2, char csv_separator = ',', char col1_separator = -1, char col2_separator = -1); + void run(std::shared_ptr data) override; + + protected: + explicit DummyErrorTask(std::string name, bool has_header = false, char csv_separator = ',', char col1_separator = -1, char col2_separator = -1); + + void check_columns(const std::string& col1, const std::string& col2); + + std::string path; + std::string name; + bool has_header = true; + size_t column1, column2; + char csv_separator, col1_separator, col2_separator; + }; + +} // epi + +#ifdef HEADER_ONLY +#include "DummyErrorTask.cpp" +#endif + +#endif //NEEDL_DUMMYERRORTASK_HPP diff --git a/src/jobs/NetworkCsvConnector.cpp b/src/jobs/NetworkCsvConnector.cpp index bc4d57896..a8656622f 100644 --- a/src/jobs/NetworkCsvConnector.cpp +++ b/src/jobs/NetworkCsvConnector.cpp @@ -163,12 +163,6 @@ namespace epi { edges[thr].clear(); nodes[thr].clear(); } - - /* - if (i % 10000 == 0) { - Logger::logProgress("applied " + std::to_string(i) + " of " + std::to_string(parser.num_rows()) + " lines of CSV file."); - } - */ } // insert nodes and edges @@ -179,7 +173,6 @@ namespace epi { data->snpNetwork->add_edges(edges[i].begin(), edges[i].end(), name); } - // Logger::logLine("applied " + std::to_string(parser.num_rows()) + " of " + std::to_string(parser.num_rows()) + " lines of CSV file."); logger.stop(); } diff --git a/test/unit/src/regression_model.cpp b/test/unit/src/regression_model.cpp index d47276b19..eb174c387 100644 --- a/test/unit/src/regression_model.cpp +++ b/test/unit/src/regression_model.cpp @@ -38,7 +38,8 @@ #include // std::stringstream #include "../../../src/jobs/InstanceLoader.hpp" -#include "../../../src/jobs/WriteSets.hpp" +#include "../../../src/jobs/DummyErrorTask.hpp" + TEST_CASE("Quantitative Instance") { epi::Instance instance; @@ -378,35 +379,73 @@ TEST_CASE("Categorical Instance 1 - No NaN values") { } } -TEST_CASE("Categorical Instance through NeEDL Pipelines - No NaN values") { +TEST_CASE("Categorical Instance 1 - NeEDL with CSVParser") { // load the instance via InstanceLoader Job omp_set_num_threads(1); - epi::InstanceLoader loader( + auto data = std::make_shared(true); + + epi::InstanceLoader( "../../../data/EpiGEN/dichotomous/2_disease_snps/exponential/1_1_ASW.json", "JSON_EPIGEN", "DICHOTOMOUS", 2, "../../../data/COV_TEST/EpiGEN_RND_COV.csv" - ); + ).run(data); + + // this is the error-causing code (src/jobs/DummyErrorTask) + // in the DummyErrorTask class I reduced the problematic code essentially to a CSVParser call after which the scores are nan + epi::DummyErrorTask( + "BIOGRID", + "../../../data/BIOGRID/BIOGRID-ORGANISM-Homo_sapiens-3.5.182.tab2.txt", + "Official Symbol Interactor A", + "Official Symbol Interactor B", + '\t', + -1, + -1).run(data); + + + // the error does not occur when adding the CSVParser code directly to the test here - auto data = std::make_shared(true); - loader.run(data); // construct SNP set epi::SNPSet set {{data->snpStorage->by_name("rs11589207"),data->snpStorage->by_name("rs10927631")}}; data->snpSetStorage.push_back(set); - epi::WriteSets write_sets("PENETRANCE", epi::options::get_all_epistasis_scores(true)); - write_sets.outfile_path("regression_model.test.csv"); - write_sets.run(data); + // test scores + // auto all_scores = epi::options::get_all_epistasis_scores(true); + std::vector all_scores = { "REGRESSION_COV_NLL" }; + for (const auto & score : all_scores) { + auto score_rep = epi::options::epistasis_score_from_string(score); + double score_value = set.calculate_score(score_rep); - for (size_t i = 0; i < 20; ++i) { - double score_value = set.calculate_score(epi::options::EpistasisScore::PENETRANCE_NLL); CHECK(!std::isnan(score_value)); + std::cout << score_value << std::endl; } + data->snpStorage.reset(); +} + +// this test is just here to show that the above issue really comes from the call to epi::DummyErrorTask +TEST_CASE("Categorical Instance 1 - NeEDL without CSVParser") { + // load the instance via InstanceLoader Job + omp_set_num_threads(1); + auto data = std::make_shared(true); + + epi::InstanceLoader( + "../../../data/EpiGEN/dichotomous/2_disease_snps/exponential/1_1_ASW.json", + "JSON_EPIGEN", + "DICHOTOMOUS", + 2, + "../../../data/COV_TEST/EpiGEN_RND_COV.csv" + ).run(data); + + // construct SNP set + epi::SNPSet set {{data->snpStorage->by_name("rs11589207"),data->snpStorage->by_name("rs10927631")}}; + data->snpSetStorage.push_back(set); + // test scores - auto all_scores = epi::options::get_all_epistasis_scores(true); + // auto all_scores = epi::options::get_all_epistasis_scores(true); + std::vector all_scores = { "REGRESSION_COV_NLL" }; for (const auto & score : all_scores) { auto score_rep = epi::options::epistasis_score_from_string(score); double score_value = set.calculate_score(score_rep); @@ -414,4 +453,6 @@ TEST_CASE("Categorical Instance through NeEDL Pipelines - No NaN values") { CHECK(!std::isnan(score_value)); std::cout << score_value << std::endl; } + + data->snpStorage.reset(); } From 395823e70068d8bdefdbebcae1e81ce8ad763b95 Mon Sep 17 00:00:00 2001 From: juli-p <63345753+juli-p@users.noreply.github.com> Date: Wed, 8 Nov 2023 12:43:24 +0100 Subject: [PATCH 14/14] cleaning up --- src/data_model/SNPStorage.hpp | 1 + src/model/instance.hpp | 2 +- src/model/instance.ipp | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/data_model/SNPStorage.hpp b/src/data_model/SNPStorage.hpp index 5aac53007..285c7ede8 100644 --- a/src/data_model/SNPStorage.hpp +++ b/src/data_model/SNPStorage.hpp @@ -17,6 +17,7 @@ namespace epi { class SNPData { public: SNPData() = default; + virtual ~SNPData() {}; private: // attributes std::vector annotations {}; diff --git a/src/model/instance.hpp b/src/model/instance.hpp index 6bbcf2c41..f251a7e9f 100644 --- a/src/model/instance.hpp +++ b/src/model/instance.hpp @@ -52,7 +52,7 @@ namespace epi { * @brief Constructs and empty instance. * @param[in] num_categories The number of categories for categorical phenotypes. Has no effect if @p PhenoType is set to epi::QuantititativePhenoType. */ - Instance(std::size_t num_categories = 2); + explicit Instance(std::size_t num_categories = 2); /*! * @brief Constant iterator for iterating over the genotype of an individual at all SNPs. diff --git a/src/model/instance.ipp b/src/model/instance.ipp index 6b3391397..34156e653 100644 --- a/src/model/instance.ipp +++ b/src/model/instance.ipp @@ -92,7 +92,6 @@ namespace epi { Instance(std::size_t num_categories): rs_ids_(), rs_ids_chromosomes_(), - has_cov_(false), num_categories_{num_categories}, num_snps_{undefined_uint()}, num_inds_{undefined_uint()}, @@ -101,7 +100,8 @@ namespace epi { original_phenotypes_(), disease_snps_(), urng_(), - covariates_() {} + covariates_(), + has_cov_(false) {} template void