From 784e3ce9b39f80aea767db22f92246a6a477d630 Mon Sep 17 00:00:00 2001 From: Damien Philippon <61393694+DAM-Philippon@users.noreply.github.com> Date: Thu, 28 May 2020 17:09:02 +0700 Subject: [PATCH 01/14] Bug fix when Individuals get infected in Hospital and Outside When Individuals agents are infected in a Hospital or Outside of the city, the map of the cumulative number of infections per building type would cause a problem once being saved since those two types of buildings did not exist --- COMOKIT/Model/Entities/Building.gaml | 4 +++- COMOKIT/Model/Entities/Hospital.gaml | 1 + COMOKIT/Model/Entities/Individual.gaml | 5 +---- COMOKIT/Model/Global.gaml | 3 +++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/COMOKIT/Model/Entities/Building.gaml b/COMOKIT/Model/Entities/Building.gaml index 8fef5fc..eb9fba8 100644 --- a/COMOKIT/Model/Entities/Building.gaml +++ b/COMOKIT/Model/Entities/Building.gaml @@ -67,4 +67,6 @@ species Building { } -species outside parent: Building ; \ No newline at end of file +species outside parent: Building{ + string type <- "Outside"; +} \ No newline at end of file diff --git a/COMOKIT/Model/Entities/Hospital.gaml b/COMOKIT/Model/Entities/Hospital.gaml index ac91db7..77b4c2e 100644 --- a/COMOKIT/Model/Entities/Hospital.gaml +++ b/COMOKIT/Model/Entities/Hospital.gaml @@ -27,6 +27,7 @@ global{ //Action to create a hospital TO CHANGE WHEN DATA ARE AVAILABLE (which building to chose, what capacity) action create_hospital{ create Hospital number:number_hospital{ + type <- "Hospital"; capacity_hospitalisation <- capacity_hospitalisation_per_hospital; capacity_ICU <- capacity_ICU_per_hospital; } diff --git a/COMOKIT/Model/Entities/Individual.gaml b/COMOKIT/Model/Entities/Individual.gaml index ae50265..ff76519 100644 --- a/COMOKIT/Model/Entities/Individual.gaml +++ b/COMOKIT/Model/Entities/Individual.gaml @@ -154,15 +154,12 @@ species Individual parent: BiologicalEntity schedules: shuffle(Individual where { //Add the new case to the total number of infected (not mandatorily known) total_number_of_infected <- total_number_of_infected +1; + //Add the infection to the infections having been caused in the building if(building_infections.keys contains(current_place.type)) { building_infections[current_place.type] <- building_infections[current_place.type] +1; } - else - { - add 1 to: building_infections at: current_place.type; - } //Add the infection to the infections of the same age if(total_incidence_age.keys contains(self.age)) { diff --git a/COMOKIT/Model/Global.gaml b/COMOKIT/Model/Global.gaml index 92e5e6e..123d316 100644 --- a/COMOKIT/Model/Global.gaml +++ b/COMOKIT/Model/Global.gaml @@ -50,6 +50,9 @@ global { { add 0 at: aBuilding_Type to: building_infections; } + //THIS SHOULD BE REMOVED ONCE WE FINALLY HAVE HOSPITAL IN SHAPEFILE + add 0 at: "Hospital" to: building_infections; + add 0 at: "Outside" to: building_infections; do console_output("building and boundary : done"); create outside; the_outside <- first(outside); From 90f8606def96b5b0eced81ffd5285db0cfa55572 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Sun, 31 May 2020 14:24:02 +0200 Subject: [PATCH 02/14] add file-based-SP parameter file, like for activities and epidemiological model, with the ability to add explicit ID for individual to make it possible to extend them in one way or another. Although this is necessary for COMOKIT Camps, it could benefit for any other application of COMOKIT outside the team. This commit might not be warning free, because warning is good --- COMOKIT/Model/Entities/Individual.gaml | 2 + COMOKIT/Model/Parameters.gaml | 21 ++++--- COMOKIT/Model/Synthetic Population.gaml | 54 +++++++++++++++++- .../Synthetic Entity Parameters.csv | Bin 0 -> 168 bytes 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 COMOKIT/Parameters/Synthetic Entity Parameters.csv diff --git a/COMOKIT/Model/Entities/Individual.gaml b/COMOKIT/Model/Entities/Individual.gaml index ff76519..13c6c95 100644 --- a/COMOKIT/Model/Entities/Individual.gaml +++ b/COMOKIT/Model/Entities/Individual.gaml @@ -44,6 +44,8 @@ species Individual parent: BiologicalEntity schedules: shuffle(Individual where int sex; //0 M 1 F //employement status of the individual bool is_unemployed; + //COMOKIT identifier + string individual_id; //Bool to consider only once the death bool is_counted_dead <- false; diff --git a/COMOKIT/Model/Parameters.gaml b/COMOKIT/Model/Parameters.gaml index 29f5c6f..693c22b 100644 --- a/COMOKIT/Model/Parameters.gaml +++ b/COMOKIT/Model/Parameters.gaml @@ -105,16 +105,19 @@ global { // ------ From file string var_mapper_parameters <- experiment.project_path+"Parameters/Synthetic Entity Parameters.csv"; //File for the parameters file csv_mappers <- file_exists(var_mapper_parameters)?csv_file(var_mapper_parameters):nil; - // **s + list sp_var_names <- ["age","sex","is_unemployed","household_id","individual_id"]; + // ** string separator <- ";"; - bool header <- true; // If there is a header or not (must be true for now) - string age_var <- "AGE"; // The variable name for "age" Individual attribute | WARNING : IPUMS name - map age_map; // The mapping of value for gama to translate, if nill then direct cast to int (Default behavior in Synthetic Population.gaml) - string gender_var <- "SEX"; // The variable name for "sex" Individual attribute | WARNING : IPUMS name - map gender_map <- ["1"::0,"2"::1,"male"::0,"female"::1]; // The mapping of value for gama to translate, if nill then cast to int - string unemployed_var <- "EMPSTAT"; // The variable that represent employment status | WARNING : IPUMS name - map unemployed_map <- ["1"::false,"2"::true,"3"::true]; // 1 = employed, 2 = unemployed, 3 = inactive | WARNING : IPUMS name - string householdID <- "parentId"; // The variable for household identification + bool header <- true; // If there is a header or not + string age_var; // The variable name for "age" Individual attribute + map> age_map; // The mapping of value for gama to translate, if nill then direct cast to int + string gender_var; // The variable name for "sex" Individual attribute + map gender_map; // The mapping of value for gama to translate sex into 0=male 1=female, if nill then cast to int + string unemployed_var; // The variable that represent employment status + map unemployed_map; // false = employed, true = unemployed + string householdID; // The variable for household identification + string individualID <- nil; // The variable for individual identification + // ** int number_of_individual <- -1; // Control the number of Individual agent in the simulation from the file: if <0 or more than record in the file, takes the exact number of individual in the file // ------ From default Gaml generator diff --git a/COMOKIT/Model/Synthetic Population.gaml b/COMOKIT/Model/Synthetic Population.gaml index 1268723..66c2ded 100644 --- a/COMOKIT/Model/Synthetic Population.gaml +++ b/COMOKIT/Model/Synthetic Population.gaml @@ -46,15 +46,19 @@ global { map> households <- []; + if not(csv_mappers=nil) { do read_mapping(); } + create Individual from:csv_population number: (number_of_individual <= 0 ? length(csv_population) : number_of_individual) with:[ age::convert_age(get(age_var)), sex::convert_gender(get(gender_var)), is_unemployed::convert_unemployed(get(unemployed_var)), - household_id::convert_hhid(get(householdID)) + household_id::convert_hhid(get(householdID)), + individual_id::get(individualID) ]{ if households contains_key household_id { households[household_id] <+ self; } else { households[household_id] <- [self]; } + if individual_id=nil or empty(individual_id) {individual_id <- name;} } list hh_empty <- Individual where (each.household_id = nil); @@ -152,10 +156,58 @@ global { _get_employment_status(rnd(1)) : unemployed_map[input]; } + // Convert household ID from file to string string convert_hhid(string input){ return not(input=nil) and input contains "\"" ? input replace("\"","") : input; } + /* + * Read the synthetic entity variable mapping from parameter file + */ + action read_mapping { + csv_parameters <- csv_file(var_mapper_parameters,",",true); + matrix data <- matrix(csv_parameters); + list data_rows <- rows_list(data); + //Loading the different rows number for the parameters in the file + loop row over:data_rows{ + string var <- first(row); + switch var { + match "age" { age_var <- row[1]; age_map <- map>(read_var_map(row)); } + match "sex" { gender_var <- row[1]; gender_map <- map(read_var_map(row)); } + match "is_unemployed" { unemployed_var <- row[1]; unemployed_map <- map(read_var_map(row)); } + match "household_id" { householdID <- row[1]; } + match "individual_id" { individualID <- row[1]; } + default {error "Failed to map variable "+var+" from Synthetic Entity Parameters.csv + \n Should be in "+sample(sp_var_names);} + } + } + } + + /* + * Transpose value and map pairs into a map to convert from file to COMOKIT variable convention + */ + map read_var_map(list var_row) { + int idx <- 2; + switch first(var_row) { + match "age" { + map> res <- []; + loop while:idx < length(var_row) { res[string(var_row[idx])] <- list(var_row[idx+1]); idx <- idx+2; } + return res; + } + match "sex" { + map res <- []; + loop while:idx < length(var_row) { res[string(var_row[idx])] <- int(var_row[idx+1]); idx <- idx+2; } + return res; + } + match "is_unemployed" { + map res <- []; + loop while:idx < length(var_row) { res[string(var_row[idx])] <- bool(var_row[idx+1]); idx <- idx+2; } + return res; + } + default {error "unknown variable "+first(var_row)+" to map synthetic entity attribute with";} + } + } + // ------------------------------------------- // // SYNTHETIC POPULATION FROM COMOKIT ALGORITHM // // ------------------------------------------- // diff --git a/COMOKIT/Parameters/Synthetic Entity Parameters.csv b/COMOKIT/Parameters/Synthetic Entity Parameters.csv new file mode 100644 index 0000000000000000000000000000000000000000..517149c2171226340cca7e5b3bf2b7700b8a0f8b GIT binary patch literal 168 zcmZQ5ODxg>;`qG8+*B~5EHMX6=Oz{q;&UaYr|LMmyXt@eS8-~EPOxi)j-if$juDX5 z;mRzIFU?EMEy&5QOij^o^$iFPaSQ>De;*p TIt7VEsd*)yE+CT`fF=O|0P{Cb literal 0 HcmV?d00001 From 098a148ff07a489e3bae92ee1060b444ad15fcf7 Mon Sep 17 00:00:00 2001 From: RoiArthurB Date: Wed, 3 Jun 2020 11:43:18 +0700 Subject: [PATCH 03/14] [SENSI] Fill headless parameters Based on Damien's exploration parameters --- .../Sensitivity Analysis/Sensitivity Analysis.gaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml b/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml index 8ee1445..ae6e623 100644 --- a/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml +++ b/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml @@ -49,4 +49,11 @@ experiment Sensitivity parent: "Abstract Batch" } } -experiment SensitivityHeadless parent: "Abstract Headless" {} +experiment SensitivityHeadless parent: "Abstract Headless" { + parameter "Allow Transmission Building" var: allow_transmission_building init: true; + + parameter "Basic Viral Release" var: basic_viral_release init: 0.01 min: 0.01 max: 0.1 step: 0.01; // if: [allow_transmission_building,true] + parameter "Basic Viral Decrease" var: basic_viral_decrease init: 0.02 min: 0.02 max: 0.2 step: 0.02; // if: [allow_transmission_building,true] + + parameter "Init All Ages Successful Contact Rate Human" var: init_all_ages_successful_contact_rate_human init: 0.01529959 among: [0.01529959, 0.02236774, 0.02993250, 0.03034067, 0.03319786, 0.034014, 0.03673534, 0.04043608, 0.04854507, 0.07120533]; +} From c6b051d8972c3b31f89ec81795f917a3c032e8bb Mon Sep 17 00:00:00 2001 From: Damien Philippon <61393694+DAM-Philippon@users.noreply.github.com> Date: Wed, 3 Jun 2020 11:50:54 +0700 Subject: [PATCH 04/14] Update to get default values contained in the SA step for the environmental contamination --- .../Parameters/Epidemiological Parameters.csv | Bin 3065 -> 3061 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/COMOKIT/Parameters/Epidemiological Parameters.csv b/COMOKIT/Parameters/Epidemiological Parameters.csv index 7c52d3a30d804e907e0b81f67e88547f6161f567..961713596f602be92bdf439dc40c5ee014945f75 100644 GIT binary patch literal 3061 zcmbW3*>2k~5Jlhn75;!i;HK@d3xWnH+5l;v1zKhtqFM}+N}Ip$jO5r7Njri8ukg&7 z;hn3IHxJUtRyk!hA2*-&3SPe|Cv^iKPCr$2@r`XhYuK(TG>GeJnr;A zwS#wO24wk>+d(%w-R&<0KMr-RtbH1qs_r`{YgZZR)TsiQl^_Y>f>6PxI+s%8CB5W3 zsMMQE+Sm5r`c^t!19e$Vq*I{>(;s@{@ZeYDSuw?bmR8r*i#D>UjB1p$sLYa0j_i5t zPSxfZ4DoNmk_3kVxi=lrXrfvHuk zw152Gr*4h{UI{!>@4I@~LSazvpp5Q!RjB#*e&6+`m1shmq&b#MvJ?&-W=BSFIsFkT z!W47|et#M9IEEi@wRloy@LeQ1)|$=vxwi-HWTWlaIran3^GFB_y%FZHWfCJtgIp~% zy6#+w6&xzR*IkP3oRc^SM;f*V0?(5KUvnlDE0#$)3D2bK0YD4E0`L?Q zs7lKVk)D)18=GG?J28Fzauy0WMFyg=<2srRb&B+rV#Ot#H1t4& zScaz^5jpyQsYoo(Q-RA<|J8!!6}8@iBYcTBabjBPbuy(=%a`t z-nlcav4)4Z%^M!%CUba zj>g$MbH!_6gxY-Ed^!mD{3;BW75uo~V)5b%Z$4~(DcYAxG_9lM%05CX3!`A_WO z+o;ZBxskh0R(shTZUw(|Whu0N?J8Ebjp3zXiW_ldKr;#yAwp41@xXH{HB9LwKLJy# z7}sz0$+R^$vINv68%+kHXVsosWo+Yj<8eO3f96`2>?{?pm=cxX+A6ceM#PWZi&Blj zaPuN86dsdoDrLuavXbVFS;g6@)zZkbOJL^*qkzhn;f**zt6n&YiYepL>tDeYOpeuD z|8eUd;71Yf1dgcNrtEe=3<{ovlI@=Px_@sEO{;2djTlEsW+|gIfiC>)z!+|)zW^gl zLN?&}a}RGv@#Dfpq9TQB8iB^WVwe7ptv*S^E2;a+Z9VXwjRj9bxt)WTNf?bLnVHHb z>YX<+;e2$<-K4~pGbIt^kJM)Zf#*q-tm&zDAwFjU1&!&T%eHwH zB`mK_uiIWY%G2Hvu)0$~wHxd{LTo)h-(WZ@Xp!c2R{%&sS77vGbubdz?{$En*$M~} zC}V;kWCa9uAxMNWoECP0*)mo@BtArp3Y6ND0}y0QCusnK#PA#)F^Uy+WC4trB(dFN zP)8nwc<0Hq#u^U9W8QE;9x{i6@sK+ljEC&uU_9mz2jnq>I3Oz=^0U#xFw-*s(d*hP pj_`0wGV9K7%YPphV*BN{wH~~$e_pJglgP%u82%QDuq&jG_zxMYR^k8v From 913a7dafca634dd487b6dfaa38eee224ca1926e0 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Wed, 3 Jun 2020 11:08:52 +0200 Subject: [PATCH 05/14] clean up pop file reading and move population records file to case study folder --- .../Case Studies Comparison.template | 6 ++ .../templates/Policy Comparison.template | 5 ++ .../Possible visualisations.template | 6 ++ .../templates/Simple Policy.template | 6 +- .../Datasets/Ben Tre/Population Records.csv | Bin 0 -> 168 bytes .../Datasets/Vinh Phuc/Population Records.csv | Bin 0 -> 168 bytes COMOKIT/Model/Constants.gaml | 6 ++ COMOKIT/Model/Parameters.gaml | 20 ++++-- COMOKIT/Model/Synthetic Population.gaml | 63 +++++++++++------- 9 files changed, 81 insertions(+), 31 deletions(-) create mode 100644 COMOKIT/Datasets/Ben Tre/Population Records.csv create mode 100644 COMOKIT/Datasets/Vinh Phuc/Population Records.csv diff --git a/COMOKIT Template Project/templates/Case Studies Comparison.template b/COMOKIT Template Project/templates/Case Studies Comparison.template index 4f401de..47b9989 100644 --- a/COMOKIT Template Project/templates/Case Studies Comparison.template +++ b/COMOKIT Template Project/templates/Case Studies Comparison.template @@ -12,6 +12,12 @@ model $TITLE$ import "All COMOKIT.gaml" global { + + // Parameter file folder + // by default parameter files are placed in Parameters/ folder of COMOKIT + // if you decide to redefine the path to that folder identify the place COMOKIT can find your parameter files + string parameter_folder_path <- "../../COMOKIT/Parameters/"; + string POLICY_NAME <- "your_policy"; // Not mandatory but will be used in GUI } diff --git a/COMOKIT Template Project/templates/Policy Comparison.template b/COMOKIT Template Project/templates/Policy Comparison.template index c87598c..bab5752 100644 --- a/COMOKIT Template Project/templates/Policy Comparison.template +++ b/COMOKIT Template Project/templates/Policy Comparison.template @@ -13,6 +13,11 @@ import "All COMOKIT.gaml" global { + // Parameter file folder + // by default parameter files are placed in Parameters/ folder of COMOKIT + // if you decide to redefine the path to that folder identify the place COMOKIT can find your parameter files + string parameter_folder_path <- "../../COMOKIT/Parameters/"; + string dataset_path <- "../Datasets/Case Study/"; // Relative path to the folder containing the boundary.shp, buildings.shp, satellite.png, etc. datafiles. string POLICY_NAME <- "your_policy"; // Not mandatory but will be used in GUI diff --git a/COMOKIT Template Project/templates/Possible visualisations.template b/COMOKIT Template Project/templates/Possible visualisations.template index f2d2e8e..2973594 100644 --- a/COMOKIT Template Project/templates/Possible visualisations.template +++ b/COMOKIT Template Project/templates/Possible visualisations.template @@ -12,6 +12,12 @@ model $TITLE$ import "All COMOKIT.gaml" global { + + // Parameter file folder + // by default parameter files are placed in Parameters/ folder of COMOKIT + // if you decide to redefine the path to that folder identify the place COMOKIT can find your parameter files + string parameter_folder_path <- "../../COMOKIT/Parameters/"; + string dataset_path <- "../Datasets/Case Study/"; // Relative path to the folder containing the boundary.shp, buildings.shp, satellite.png, etc. datafiles. action define_policy{ diff --git a/COMOKIT Template Project/templates/Simple Policy.template b/COMOKIT Template Project/templates/Simple Policy.template index 5c7aa66..f9603ce 100644 --- a/COMOKIT Template Project/templates/Simple Policy.template +++ b/COMOKIT Template Project/templates/Simple Policy.template @@ -13,9 +13,13 @@ import "All COMOKIT.gaml" global { + // Parameter file folder + // by default parameter files are placed in Parameters/ folder of COMOKIT + // if you decide to redefine the path to that folder identify the place COMOKIT can find your parameter files + string parameter_folder_path <- "../../COMOKIT/Parameters/"; + string dataset_path <- "../Datasets/Case Study/"; // Relative path to the folder containing the boundary.shp, buildings.shp, satellite.png, etc. datafiles. - action define_policy{ // *************************************************************************** // SEE Model/Entities/Authority.gaml for built-in functions to create policies diff --git a/COMOKIT/Datasets/Ben Tre/Population Records.csv b/COMOKIT/Datasets/Ben Tre/Population Records.csv new file mode 100644 index 0000000000000000000000000000000000000000..517149c2171226340cca7e5b3bf2b7700b8a0f8b GIT binary patch literal 168 zcmZQ5ODxg>;`qG8+*B~5EHMX6=Oz{q;&UaYr|LMmyXt@eS8-~EPOxi)j-if$juDX5 z;mRzIFU?EMEy&5QOij^o^$iFPaSQ>De;*p TIt7VEsd*)yE+CT`fF=O|0P{Cb literal 0 HcmV?d00001 diff --git a/COMOKIT/Datasets/Vinh Phuc/Population Records.csv b/COMOKIT/Datasets/Vinh Phuc/Population Records.csv new file mode 100644 index 0000000000000000000000000000000000000000..517149c2171226340cca7e5b3bf2b7700b8a0f8b GIT binary patch literal 168 zcmZQ5ODxg>;`qG8+*B~5EHMX6=Oz{q;&UaYr|LMmyXt@eS8-~EPOxi)j-if$juDX5 z;mRzIFU?EMEy&5QOij^o^$iFPaSQ>De;*p TIt7VEsd*)yE+CT`fF=O|0P{Cb literal 0 HcmV?d00001 diff --git a/COMOKIT/Model/Constants.gaml b/COMOKIT/Model/Constants.gaml index 531f23e..20a8ba5 100644 --- a/COMOKIT/Model/Constants.gaml +++ b/COMOKIT/Model/Constants.gaml @@ -53,6 +53,12 @@ global { string gravity <- "gravity"; string closest <- "closest"; + //List of demogrphic attributes + string AGE <- "age"; + string SEX <- "sex"; + string EMP <- "is_unemployed"; + string HID <- "household_id"; + string IID <- "individual_id"; //number of the column for the epidemiological parameters CSV file int epidemiological_csv_column_name <- 0; //Name of the parameter diff --git a/COMOKIT/Model/Parameters.gaml b/COMOKIT/Model/Parameters.gaml index 693c22b..eef75cb 100644 --- a/COMOKIT/Model/Parameters.gaml +++ b/COMOKIT/Model/Parameters.gaml @@ -17,6 +17,8 @@ import "Constants.gaml" global { + // Parameter folder path + string parameter_folder_path <- experiment.project_path+"Parameters"; // The case study name and dataset path variable to be used in models string case_study_folder_name; // The case study folder string datasets_folder_path; // The path from root project to the data set folder (can contains several case studies) @@ -32,7 +34,8 @@ global { file shp_buildings <- file_exists(dataset_path+"buildings.shp") ? shape_file(dataset_path+"buildings.shp"):nil; //Population data - csv_file csv_population <- file_exists(dataset_path+"population.csv") ? csv_file(dataset_path+"population.csv",separator,header):nil; + csv_file csv_population <- file_exists(dataset_path+"population.csv") ? csv_file(dataset_path+"population.csv",separator,qualifier,header):nil; + csv_file csv_population_attribute_mappers <- file_exists(dataset_path+"Population Records.csv")?csv_file(dataset_path+"Population Records.csv",",",true):nil; csv_file csv_parameter_population <- file_exists(dataset_path+"Population parameter.csv") ? csv_file(dataset_path+"Population parameter.csv",",",true):nil; csv_file csv_parameter_agenda <- file_exists(dataset_path+"Agenda parameter.csv") ? csv_file(dataset_path+"Agenda parameter.csv",",",true):nil; csv_file csv_activity_weights <- file_exists(dataset_path+"Activity weights.csv") ? csv_file(dataset_path+"Activity weights.csv",",",string, false):nil; @@ -50,7 +53,8 @@ global { float nb_step_for_one_day <- #day/step; //Used to define the different period used in the model bool load_epidemiological_parameter_from_file <- true; //Allowing parameters being loaded from a csv file - string epidemiological_parameters <- experiment.project_path+"Parameters/Epidemiological Parameters.csv"; //File for the parameters + string epidemiological_parameters <- (last(parameter_folder_path)="/"?parameter_folder_path:parameter_folder_path+"/") + +"Epidemiological Parameters.csv"; //File for the parameters file csv_parameters <- file_exists(epidemiological_parameters)?csv_file(epidemiological_parameters):nil; bool allow_transmission_human <- true; //Allowing human to human transmission @@ -103,12 +107,13 @@ global { //Synthetic population parameters // ------ From file - string var_mapper_parameters <- experiment.project_path+"Parameters/Synthetic Entity Parameters.csv"; //File for the parameters - file csv_mappers <- file_exists(var_mapper_parameters)?csv_file(var_mapper_parameters):nil; - list sp_var_names <- ["age","sex","is_unemployed","household_id","individual_id"]; + string OTHER <- "OTHER" const:true; + string EMPTY <- "EMPTY" const:true; // ** - string separator <- ";"; + string separator <- ";"; // File separator for synthetic population micro-data + string qualifier <- "\""; // The default text qualifier bool header <- true; // If there is a header or not + string age_var; // The variable name for "age" Individual attribute map> age_map; // The mapping of value for gama to translate, if nill then direct cast to int string gender_var; // The variable name for "sex" Individual attribute @@ -152,7 +157,8 @@ global { //Acvitity parameters - string building_type_per_activity_parameters <- experiment.project_path+"Parameters/Building type per activity type.csv"; //File for the parameters + string building_type_per_activity_parameters <- (last(parameter_folder_path)="/"?parameter_folder_path:parameter_folder_path+"/") + +"/Building type per activity type.csv"; //File for the parameters string choice_of_target_mode <- gravity among: ["random", "gravity","closest"]; // model used for the choice of building for an activity int nb_candidates <- 4; // number of building considered for the choice of building for a particular activity diff --git a/COMOKIT/Model/Synthetic Population.gaml b/COMOKIT/Model/Synthetic Population.gaml index 66c2ded..103fd4b 100644 --- a/COMOKIT/Model/Synthetic Population.gaml +++ b/COMOKIT/Model/Synthetic Population.gaml @@ -46,9 +46,11 @@ global { map> households <- []; - if not(csv_mappers=nil) { do read_mapping(); } + if not(csv_population_attribute_mappers=nil) { do read_mapping(); } - create Individual from:csv_population number: (number_of_individual <= 0 ? length(csv_population) : number_of_individual) + create Individual from:csv_population number: (number_of_individual <= 0 ? length(csv_population) : + (number_of_individual < length(csv_population) ? number_of_individual : length(csv_population)) + ) with:[ age::convert_age(get(age_var)), sex::convert_gender(get(gender_var)), @@ -133,27 +135,43 @@ global { // Convert SP encoded age into gama model specification (float) float convert_age(string input){ - if (input=nil) {return _get_age();} - input <- input contains "\"" ? input replace("\"","") : input; - return age_map=nil or empty(age_map) or not(age_map contains_key input) ? - int(input) : rnd(first(age_map[input]),last(age_map[input])); + if not(input=nil) { + input <- input contains qualifier ? input replace(qualifier,"") : input; + if not(age_map=nil) { + if age_map contains input { return rnd(first(age_map[input]),last(age_map[input])); } + } else { + if int(input) is int { return int(input); } + } + } + return _get_age(); } // Convert SP encoded gender into gama model specification (0=men, 1=women) int convert_gender(string input){ - if (input=nil) {return _get_sex();} - input <- input contains "\"" ? input replace("\"","") : input; - return gender_map=nil or empty(gender_map) or not(gender_map contains_key input) ? - _get_sex() : gender_map[input]; + if not(input=nil) { + input <- input contains qualifier ? input replace(qualifier,"") : input; + if not(gender_map=nil) { + if (gender_map contains EMPTY and empty(input)) { return gender_map[EMPTY]; } + else if (gender_map contains input) { return gender_map[input]; } + else if (gender_map contains OTHER) { return gender_map[OTHER]; } + } else { + if int(input) = 0 or int(input) = 1 {return int(input);} + } + } + return _get_sex(); } // Convert SP encoded employment status into gama model specification (true=unemployed,false=employed) bool convert_unemployed(string input){ - // because we don't know yet the sex then do unifrom - if (input=nil) {return _get_employment_status(rnd(1));} - input <- input contains "\"" ? input replace("\"","") : input; - return unemployed_map=nil or empty(unemployed_map) or not(unemployed_map contains_key input) ? - _get_employment_status(rnd(1)) : unemployed_map[input]; + if not(input=nil) { + input <- input contains qualifier ? input replace(qualifier,"") : input; + if not(unemployed_map=nil) { + if(unemployed_map contains EMPTY and empty(input)) { return unemployed_map[EMPTY]; } + else if(unemployed_map contains input) { return unemployed_map[input]; } + else if(unemployed_map contains OTHER) { return unemployed_map[OTHER]; } + } + } + return _get_employment_status(rnd(1)); // because we don't know yet the sex then do unifrom } // Convert household ID from file to string @@ -165,20 +183,19 @@ global { * Read the synthetic entity variable mapping from parameter file */ action read_mapping { - csv_parameters <- csv_file(var_mapper_parameters,",",true); - matrix data <- matrix(csv_parameters); + matrix data <- matrix(csv_population_attribute_mappers); list data_rows <- rows_list(data); //Loading the different rows number for the parameters in the file loop row over:data_rows{ string var <- first(row); switch var { - match "age" { age_var <- row[1]; age_map <- map>(read_var_map(row)); } - match "sex" { gender_var <- row[1]; gender_map <- map(read_var_map(row)); } - match "is_unemployed" { unemployed_var <- row[1]; unemployed_map <- map(read_var_map(row)); } - match "household_id" { householdID <- row[1]; } - match "individual_id" { individualID <- row[1]; } + match AGE { age_var <- row[1]; age_map <- map>(read_var_map(row)); } + match SEX { gender_var <- row[1]; gender_map <- map(read_var_map(row)); } + match EMP { unemployed_var <- row[1]; unemployed_map <- map(read_var_map(row)); } + match HID { householdID <- row[1]; } + match IID { individualID <- row[1]; } default {error "Failed to map variable "+var+" from Synthetic Entity Parameters.csv - \n Should be in "+sample(sp_var_names);} + \n Should be in "+[AGE,SEX,EMP,HID,IID];} } } } From 513906a77bc5a3859ccafbb79292945ac5a2c1d4 Mon Sep 17 00:00:00 2001 From: RoiArthurB Date: Wed, 3 Jun 2020 16:33:10 +0700 Subject: [PATCH 06/14] [SENSI] Split Headless experiment follow Damien's exploration plan --- ...on With and Without Environmental Transmission.gaml | 9 ++++++++- .../Sensitivity Analysis/Sensitivity Analysis.gaml | 10 ++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml b/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml index 4aa5cf8..fe0d5f0 100644 --- a/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml +++ b/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml @@ -20,7 +20,7 @@ model CoVid19 import "../../Model/Global.gaml" -import "../Abstract Experiment.gaml" +import "../Abstract Batch Experiment.gaml" experiment "Comparison" parent: "Abstract Experiment" autorun: true { @@ -84,3 +84,10 @@ experiment "Comparison" parent: "Abstract Experiment" autorun: true { display "Main" parent: default_display {} } } + +experiment HeadlessComparison parent: "Abstract Headless" { + parameter "Allow Transmission Building" var: allow_transmission_building init: true; + + parameter "Basic Viral Release" var: basic_viral_release init: 0.01 min: 0.01 max: 0.1 step: 0.01; // if: [allow_transmission_building,true] + parameter "Basic Viral Decrease" var: basic_viral_decrease init: 0.02 min: 0.02 max: 0.2 step: 0.02; // if: [allow_transmission_building,true] +} diff --git a/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml b/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml index ae6e623..8fa6ce1 100644 --- a/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml +++ b/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml @@ -49,11 +49,9 @@ experiment Sensitivity parent: "Abstract Batch" } } -experiment SensitivityHeadless parent: "Abstract Headless" { - parameter "Allow Transmission Building" var: allow_transmission_building init: true; - - parameter "Basic Viral Release" var: basic_viral_release init: 0.01 min: 0.01 max: 0.1 step: 0.01; // if: [allow_transmission_building,true] - parameter "Basic Viral Decrease" var: basic_viral_decrease init: 0.02 min: 0.02 max: 0.2 step: 0.02; // if: [allow_transmission_building,true] - +experiment SensitivityHeadless parent: "Abstract Headless" {} + + +experiment ContactRateHumanHeadless parent: "Abstract Headless" { parameter "Init All Ages Successful Contact Rate Human" var: init_all_ages_successful_contact_rate_human init: 0.01529959 among: [0.01529959, 0.02236774, 0.02993250, 0.03034067, 0.03319786, 0.034014, 0.03673534, 0.04043608, 0.04854507, 0.07120533]; } From 5e7eb9a58d981a21ab178561712aaec2884c8206 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Wed, 3 Jun 2020 12:04:44 +0200 Subject: [PATCH 07/14] fix #37 by adding a 's' to a variable --- COMOKIT/Model/Parameters.gaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/COMOKIT/Model/Parameters.gaml b/COMOKIT/Model/Parameters.gaml index eef75cb..cd7065f 100644 --- a/COMOKIT/Model/Parameters.gaml +++ b/COMOKIT/Model/Parameters.gaml @@ -18,7 +18,7 @@ import "Constants.gaml" global { // Parameter folder path - string parameter_folder_path <- experiment.project_path+"Parameters"; + string parameters_folder_path <- experiment.project_path+"Parameters"; // The case study name and dataset path variable to be used in models string case_study_folder_name; // The case study folder string datasets_folder_path; // The path from root project to the data set folder (can contains several case studies) @@ -53,7 +53,7 @@ global { float nb_step_for_one_day <- #day/step; //Used to define the different period used in the model bool load_epidemiological_parameter_from_file <- true; //Allowing parameters being loaded from a csv file - string epidemiological_parameters <- (last(parameter_folder_path)="/"?parameter_folder_path:parameter_folder_path+"/") + string epidemiological_parameters <- (last(parameters_folder_path)="/"?parameters_folder_path:parameters_folder_path+"/") +"Epidemiological Parameters.csv"; //File for the parameters file csv_parameters <- file_exists(epidemiological_parameters)?csv_file(epidemiological_parameters):nil; @@ -157,7 +157,7 @@ global { //Acvitity parameters - string building_type_per_activity_parameters <- (last(parameter_folder_path)="/"?parameter_folder_path:parameter_folder_path+"/") + string building_type_per_activity_parameters <- (last(parameters_folder_path)="/"?parameters_folder_path:parameters_folder_path+"/") +"/Building type per activity type.csv"; //File for the parameters string choice_of_target_mode <- gravity among: ["random", "gravity","closest"]; // model used for the choice of building for an activity From 3f7d4569d0376240d3eb8df8eb1d168621f31e57 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Wed, 3 Jun 2020 12:11:29 +0200 Subject: [PATCH 08/14] add virtual displays for demographics, example in No Containment.gaml (for a surprising result) --- COMOKIT/Experiments/Abstract Experiment.gaml | 30 ++++++++++++++++++ .../Experiments/Baseline/No containment.gaml | 5 +++ COMOKIT/Model/Synthetic Population.gaml | 11 ++++--- .../Synthetic Entity Parameters.csv | Bin 168 -> 0 bytes 4 files changed, 42 insertions(+), 4 deletions(-) delete mode 100644 COMOKIT/Parameters/Synthetic Entity Parameters.csv diff --git a/COMOKIT/Experiments/Abstract Experiment.gaml b/COMOKIT/Experiments/Abstract Experiment.gaml index 6ca29cf..f79cf0a 100644 --- a/COMOKIT/Experiments/Abstract Experiment.gaml +++ b/COMOKIT/Experiments/Abstract Experiment.gaml @@ -158,6 +158,36 @@ experiment "Abstract Experiment" virtual: true { } } + + // DEMOGRAPHICS + + display "demographics_age" virtual: true { + chart "Ages" type: histogram { + loop i from: 0 to: max_age { data ""+i value: Individual count(each.age = i); } + } + } + + display "demographics_sex" virtual: true { + chart "sex" type: pie { + data "Male" value: Individual count (each.sex=0); + data "Female" value: Individual count (each.sex=1); + } + } + + display "demographics_employed" virtual: true { + chart "unemployed" type: pie { + data "Employed" value: Individual count not(each.is_unemployed); + data "Unemployed" value: Individual count each.is_unemployed; + } + } + + display "demographics_household_size" virtual: true { + chart "Household size" type:histogram { + loop i from: 0 to:max(Individual collect (length(each.relatives))) { + data string(i) value: Individual count (length(each.relatives)=i); + } + } + } } diff --git a/COMOKIT/Experiments/Baseline/No containment.gaml b/COMOKIT/Experiments/Baseline/No containment.gaml index 6b2c73a..919686e 100644 --- a/COMOKIT/Experiments/Baseline/No containment.gaml +++ b/COMOKIT/Experiments/Baseline/No containment.gaml @@ -31,5 +31,10 @@ experiment "No Containment" parent: "Abstract Experiment" autorun: true { display "Main" parent: default_display {} display "Plot" parent: states_evolution_chart {} + + display "Population age" parent: demographics_age { } + display "Population gender" parent: demographics_sex { } + display "Population employment status" parent: demographics_employed { } + display "Household size" parent: demographics_household_size { } } } \ No newline at end of file diff --git a/COMOKIT/Model/Synthetic Population.gaml b/COMOKIT/Model/Synthetic Population.gaml index 103fd4b..685f438 100644 --- a/COMOKIT/Model/Synthetic Population.gaml +++ b/COMOKIT/Model/Synthetic Population.gaml @@ -136,8 +136,8 @@ global { // Convert SP encoded age into gama model specification (float) float convert_age(string input){ if not(input=nil) { - input <- input contains qualifier ? input replace(qualifier,"") : input; - if not(age_map=nil) { + input <- input contains qualifier ? input replace(qualifier,"") : input; + if not(age_map=nil) and not(empty(age_map)) { if age_map contains input { return rnd(first(age_map[input]),last(age_map[input])); } } else { if int(input) is int { return int(input); } @@ -150,7 +150,7 @@ global { int convert_gender(string input){ if not(input=nil) { input <- input contains qualifier ? input replace(qualifier,"") : input; - if not(gender_map=nil) { + if not(gender_map=nil) and not(empty(age_map)) { if (gender_map contains EMPTY and empty(input)) { return gender_map[EMPTY]; } else if (gender_map contains input) { return gender_map[input]; } else if (gender_map contains OTHER) { return gender_map[OTHER]; } @@ -165,7 +165,7 @@ global { bool convert_unemployed(string input){ if not(input=nil) { input <- input contains qualifier ? input replace(qualifier,"") : input; - if not(unemployed_map=nil) { + if not(unemployed_map=nil) and not(empty(age_map)) { if(unemployed_map contains EMPTY and empty(input)) { return unemployed_map[EMPTY]; } else if(unemployed_map contains input) { return unemployed_map[input]; } else if(unemployed_map contains OTHER) { return unemployed_map[OTHER]; } @@ -209,16 +209,19 @@ global { match "age" { map> res <- []; loop while:idx < length(var_row) { res[string(var_row[idx])] <- list(var_row[idx+1]); idx <- idx+2; } + if length(res)=1 and res contains_key "" {return nil;} return res; } match "sex" { map res <- []; loop while:idx < length(var_row) { res[string(var_row[idx])] <- int(var_row[idx+1]); idx <- idx+2; } + if length(res)=1 and res contains_key "" {return nil;} return res; } match "is_unemployed" { map res <- []; loop while:idx < length(var_row) { res[string(var_row[idx])] <- bool(var_row[idx+1]); idx <- idx+2; } + if length(res)=1 and res contains_key "" {return nil;} return res; } default {error "unknown variable "+first(var_row)+" to map synthetic entity attribute with";} diff --git a/COMOKIT/Parameters/Synthetic Entity Parameters.csv b/COMOKIT/Parameters/Synthetic Entity Parameters.csv deleted file mode 100644 index 517149c2171226340cca7e5b3bf2b7700b8a0f8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 168 zcmZQ5ODxg>;`qG8+*B~5EHMX6=Oz{q;&UaYr|LMmyXt@eS8-~EPOxi)j-if$juDX5 z;mRzIFU?EMEy&5QOij^o^$iFPaSQ>De;*p TIt7VEsd*)yE+CT`fF=O|0P{Cb From 2c03014f15e53293a62395e7e23374f800cac7a1 Mon Sep 17 00:00:00 2001 From: Damien Philippon <61393694+DAM-Philippon@users.noreply.github.com> Date: Wed, 3 Jun 2020 17:14:53 +0700 Subject: [PATCH 09/14] Adding forced parameters for the EDF sensitivity analysis experiments --- ... With and Without Environmental Transmission.gaml | 5 +++++ .../Sensitivity Analysis/Sensitivity Analysis.gaml | 1 + COMOKIT/Model/Global.gaml | 12 ++++++++++++ 3 files changed, 18 insertions(+) diff --git a/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml b/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml index fe0d5f0..67795a9 100644 --- a/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml +++ b/COMOKIT/Experiments/Sensitivity Analysis/Comparison With and Without Environmental Transmission.gaml @@ -22,6 +22,11 @@ model CoVid19 import "../../Model/Global.gaml" import "../Abstract Batch Experiment.gaml" +global{ + + list force_parameters <- list(epidemiological_transmission_building,epidemiological_basic_viral_decrease,epidemiological_basic_viral_release); +} + experiment "Comparison" parent: "Abstract Experiment" autorun: true { action _init_ { diff --git a/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml b/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml index 8fa6ce1..caa21da 100644 --- a/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml +++ b/COMOKIT/Experiments/Sensitivity Analysis/Sensitivity Analysis.gaml @@ -23,6 +23,7 @@ import "../Abstract Batch Experiment.gaml" global { int cycle_limit <- 5000 const:true; + list force_parameters <- list(epidemiological_successful_contact_rate_human); } experiment Sensitivity parent: "Abstract Batch" diff --git a/COMOKIT/Model/Global.gaml b/COMOKIT/Model/Global.gaml index 123d316..a740367 100644 --- a/COMOKIT/Model/Global.gaml +++ b/COMOKIT/Model/Global.gaml @@ -252,6 +252,18 @@ global { list list_value; switch aParameter { + match epidemiological_transmission_human{ + allow_transmission_human <- allow_transmission_human; + } + match epidemiological_transmission_building{ + allow_transmission_building <- allow_transmission_building; + } + match epidemiological_basic_viral_decrease{ + basic_viral_decrease <- basic_viral_decrease; + } + match epidemiological_successful_contact_rate_building{ + successful_contact_rate_building <- successful_contact_rate_building; + } match epidemiological_successful_contact_rate_human{ list_value <- list(epidemiological_fixed,init_all_ages_successful_contact_rate_human); } From 63a5c6b2639c40ba36e7e3d49f92e7a0ac24aff4 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Fri, 5 Jun 2020 09:53:58 +0200 Subject: [PATCH 10/14] fix path to building to activity parameter file --- COMOKIT/Model/Parameters.gaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COMOKIT/Model/Parameters.gaml b/COMOKIT/Model/Parameters.gaml index cd7065f..464a71c 100644 --- a/COMOKIT/Model/Parameters.gaml +++ b/COMOKIT/Model/Parameters.gaml @@ -158,7 +158,7 @@ global { //Acvitity parameters string building_type_per_activity_parameters <- (last(parameters_folder_path)="/"?parameters_folder_path:parameters_folder_path+"/") - +"/Building type per activity type.csv"; //File for the parameters + +"Building type per activity type.csv"; //File for the parameters string choice_of_target_mode <- gravity among: ["random", "gravity","closest"]; // model used for the choice of building for an activity int nb_candidates <- 4; // number of building considered for the choice of building for a particular activity From a63c3a20ef01f24cda17537487b586b55483f9fc Mon Sep 17 00:00:00 2001 From: Kevin Chapuis Date: Fri, 5 Jun 2020 14:26:19 +0200 Subject: [PATCH 11/14] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 1fa4d71eb352c8b83cd9e7bb2c32b8f4a0e51043 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Fri, 5 Jun 2020 14:37:01 +0200 Subject: [PATCH 12/14] add before_init and after_init actions (to be overleaded) to add new process to COMOKIT init from another project --- COMOKIT/Experiments/Abstract Experiment.gaml | 2 ++ COMOKIT/Model/Global.gaml | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/COMOKIT/Experiments/Abstract Experiment.gaml b/COMOKIT/Experiments/Abstract Experiment.gaml index f79cf0a..dafc9ae 100644 --- a/COMOKIT/Experiments/Abstract Experiment.gaml +++ b/COMOKIT/Experiments/Abstract Experiment.gaml @@ -30,9 +30,11 @@ global { * Gloabl three steps initialization of a any simulation */ init { + do before_init; do init_epidemiological_parameters; do global_init; do create_authority; + do after_init; } } diff --git a/COMOKIT/Model/Global.gaml b/COMOKIT/Model/Global.gaml index a740367..57557b2 100644 --- a/COMOKIT/Model/Global.gaml +++ b/COMOKIT/Model/Global.gaml @@ -336,6 +336,23 @@ global { } } + // ------------- // + // EMPTY METHODS // + + /* + * Add actions to be triggered before COMOKIT initializes + */ + action before_init {} + + /* + * Add actions after COMOKIT have been initialized but before starting simulation + */ + action after_init {} + + // ----- // + // DEBUG // + // ----- // + // Global debug mode to print in console all messages called from #console_output() bool DEBUG <- false; // the available level of debug among debug, error and warning (default = debug) From 3df18f503f6f7d41fe4621de30010ba5e90be290 Mon Sep 17 00:00:00 2001 From: chapuisk Date: Fri, 5 Jun 2020 16:42:12 +0200 Subject: [PATCH 13/14] bug fix on SP file reading and demographic attribute mapping to Individual --- .../Datasets/Ben Tre/Population Records.csv | Bin 168 -> 246 bytes .../Datasets/Vinh Phuc/Population Records.csv | Bin 168 -> 246 bytes COMOKIT/Model/Synthetic Population.gaml | 22 ++++++++---------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/COMOKIT/Datasets/Ben Tre/Population Records.csv b/COMOKIT/Datasets/Ben Tre/Population Records.csv index 517149c2171226340cca7e5b3bf2b7700b8a0f8b..396258d1c3677766e01bc2a3f1a29fa6206c28f7 100644 GIT binary patch literal 246 zcma)!y$ZuH41_i7SvvIR2{M?{p-@PMY(@~Z3HT2?4(;1lqMkApbf=F)C)g;%0mN+} z&kZ+njXb5lGX#3+hwf^`_k&RQEn#m)@ssE%IyaUD2urawuum?2c#_E6AN|k`?dD0Y f=zs03xhh^nzZhYTweTF>WEbrw${g04;(qW8&+s>I literal 168 zcmZQ5ODxg>;`qG8+*B~5EHMX6=Oz{q;&UaYr|LMmyXt@eS8-~EPOxi)j-if$juDX5 z;mRzIFU?EMEy&5QOij^o^$iFPaSQ>De;*p TIt7VEsd*)yE+CT`fF=O|0P{Cb diff --git a/COMOKIT/Datasets/Vinh Phuc/Population Records.csv b/COMOKIT/Datasets/Vinh Phuc/Population Records.csv index 517149c2171226340cca7e5b3bf2b7700b8a0f8b..396258d1c3677766e01bc2a3f1a29fa6206c28f7 100644 GIT binary patch literal 246 zcma)!y$ZuH41_i7SvvIR2{M?{p-@PMY(@~Z3HT2?4(;1lqMkApbf=F)C)g;%0mN+} z&kZ+njXb5lGX#3+hwf^`_k&RQEn#m)@ssE%IyaUD2urawuum?2c#_E6AN|k`?dD0Y f=zs03xhh^nzZhYTweTF>WEbrw${g04;(qW8&+s>I literal 168 zcmZQ5ODxg>;`qG8+*B~5EHMX6=Oz{q;&UaYr|LMmyXt@eS8-~EPOxi)j-if$juDX5 z;mRzIFU?EMEy&5QOij^o^$iFPaSQ>De;*p TIt7VEsd*)yE+CT`fF=O|0P{Cb diff --git a/COMOKIT/Model/Synthetic Population.gaml b/COMOKIT/Model/Synthetic Population.gaml index 685f438..467e127 100644 --- a/COMOKIT/Model/Synthetic Population.gaml +++ b/COMOKIT/Model/Synthetic Population.gaml @@ -138,7 +138,7 @@ global { if not(input=nil) { input <- input contains qualifier ? input replace(qualifier,"") : input; if not(age_map=nil) and not(empty(age_map)) { - if age_map contains input { return rnd(first(age_map[input]),last(age_map[input])); } + if age_map contains_key input { return rnd(first(age_map[input]),last(age_map[input])); } } else { if int(input) is int { return int(input); } } @@ -150,13 +150,11 @@ global { int convert_gender(string input){ if not(input=nil) { input <- input contains qualifier ? input replace(qualifier,"") : input; - if not(gender_map=nil) and not(empty(age_map)) { - if (gender_map contains EMPTY and empty(input)) { return gender_map[EMPTY]; } - else if (gender_map contains input) { return gender_map[input]; } - else if (gender_map contains OTHER) { return gender_map[OTHER]; } - } else { - if int(input) = 0 or int(input) = 1 {return int(input);} - } + if not(gender_map=nil) and not(empty(gender_map)) { + if (gender_map contains_key EMPTY and empty(input)) { return gender_map[EMPTY]; } + else if (gender_map contains_key input) { return gender_map[input]; } + else if (gender_map contains_key OTHER) { return gender_map[OTHER]; } + } else if int(input) = 0 or int(input) = 1 {return int(input);} } return _get_sex(); } @@ -165,10 +163,10 @@ global { bool convert_unemployed(string input){ if not(input=nil) { input <- input contains qualifier ? input replace(qualifier,"") : input; - if not(unemployed_map=nil) and not(empty(age_map)) { - if(unemployed_map contains EMPTY and empty(input)) { return unemployed_map[EMPTY]; } - else if(unemployed_map contains input) { return unemployed_map[input]; } - else if(unemployed_map contains OTHER) { return unemployed_map[OTHER]; } + if not(unemployed_map=nil) and not(empty(unemployed_map)) { + if(unemployed_map contains_key EMPTY and empty(input)) { return unemployed_map[EMPTY]; } + else if(unemployed_map contains_key input) { return unemployed_map[input]; } + else if(unemployed_map contains_key OTHER) { return unemployed_map[OTHER]; } } } return _get_employment_status(rnd(1)); // because we don't know yet the sex then do unifrom From f512b2b100ddd8b8528d8b600b6a06f683792534 Mon Sep 17 00:00:00 2001 From: Damien Philippon <61393694+DAM-Philippon@users.noreply.github.com> Date: Mon, 8 Jun 2020 01:28:34 +0700 Subject: [PATCH 14/14] Adding different viral factor to the individuals, hospital data and possibility of not having all parameters in CSV epi Individuals have now the possibility to have a viral factor, which will determine their beta and viral release (i.e. allowing superspreaders, for instance). The enhancement is set to false by default. Also changed the order of creation of the matrix of parameters to allow epidemiological CSV file not having all the parameters. In addition, I've added the data for the hospitalisation and ICU capacity, according to Vinh Phuc (hence why it should be added as a parameter LATER) --- COMOKIT/Model/Constants.gaml | 2 + COMOKIT/Model/Entities/Biological Entity.gaml | 3 + COMOKIT/Model/Entities/Hospital.gaml | 8 +-- COMOKIT/Model/Entities/Individual.gaml | 3 +- COMOKIT/Model/Functions.gaml | 15 +++++ COMOKIT/Model/Global.gaml | 63 ++++++++++--------- COMOKIT/Model/Parameters.gaml | 9 +++ 7 files changed, 68 insertions(+), 35 deletions(-) diff --git a/COMOKIT/Model/Constants.gaml b/COMOKIT/Model/Constants.gaml index 20a8ba5..bb3557f 100644 --- a/COMOKIT/Model/Constants.gaml +++ b/COMOKIT/Model/Constants.gaml @@ -97,5 +97,7 @@ global { string epidemiological_proportion_death_symptomatic <- "Proportion_death_symptomatic"; string epidemiological_infectious_period_symptomatic <- "Infectious_period_symptomatic"; string epidemiological_infectious_period_asymptomatic <- "Infectious_period_asymptomatic"; + string epidemiological_allow_viral_individual_factor <- "Allow_viral_individual_factor"; + string epidemiological_viral_individual_factor <- "Viral_individual_factor"; } \ No newline at end of file diff --git a/COMOKIT/Model/Entities/Biological Entity.gaml b/COMOKIT/Model/Entities/Biological Entity.gaml index e326ae7..f89c244 100644 --- a/COMOKIT/Model/Entities/Biological Entity.gaml +++ b/COMOKIT/Model/Entities/Biological Entity.gaml @@ -57,6 +57,8 @@ species BiologicalEntity control:fsm{ int last_test <- 0; //Age of the entity int age; + //Factor for the beta and the basic viral release + float viral_factor; //Factor of the contact rate for asymptomatic and presymptomatic individuals (might be age-dependent, hence its presence here) float factor_contact_rate_asymptomatic; //Basic viral release of the agent (might be age-dependent, hence its presence here) @@ -75,6 +77,7 @@ species BiologicalEntity control:fsm{ factor_contact_rate_asymptomatic <- world.get_factor_contact_rate_asymptomatic(age); basic_viral_release <- world.get_basic_viral_release(age); contact_rate <- world.get_contact_rate_human(age); + viral_factor <- world.get_viral_factor(age); } //Action to call when performing a test on a individual diff --git a/COMOKIT/Model/Entities/Hospital.gaml b/COMOKIT/Model/Entities/Hospital.gaml index 77b4c2e..7f5604e 100644 --- a/COMOKIT/Model/Entities/Hospital.gaml +++ b/COMOKIT/Model/Entities/Hospital.gaml @@ -19,17 +19,13 @@ import "Building.gaml" global{ //Number of hospital in the city int number_hospital <- 1; - //Capacity of hospitalisation per hospital (this should be initialised by data, but we don't have any :)) - int capacity_hospitalisation_per_hospital <- 10000; - //Capacity of ICU per hospital (this should be initialised by data, but we don't have any :)) - int capacity_ICU_per_hospital <- 1000; //Action to create a hospital TO CHANGE WHEN DATA ARE AVAILABLE (which building to chose, what capacity) action create_hospital{ create Hospital number:number_hospital{ type <- "Hospital"; - capacity_hospitalisation <- capacity_hospitalisation_per_hospital; - capacity_ICU <- capacity_ICU_per_hospital; + capacity_hospitalisation <- hospitalisation_capacity; + capacity_ICU <- ICU_capacity; } } } diff --git a/COMOKIT/Model/Entities/Individual.gaml b/COMOKIT/Model/Entities/Individual.gaml index 13c6c95..f35c028 100644 --- a/COMOKIT/Model/Entities/Individual.gaml +++ b/COMOKIT/Model/Entities/Individual.gaml @@ -149,6 +149,7 @@ species Individual parent: BiologicalEntity schedules: shuffle(Individual where basic_viral_release <- world.get_basic_viral_release(age); contact_rate <- world.get_contact_rate_human(age); proba_wearing_mask <- world.get_proba_wearing_mask(age); + viral_factor <- world.get_viral_factor(age); } //Action to call to define a new case, obtaining different time to key events @@ -259,7 +260,7 @@ species Individual parent: BiologicalEntity schedules: shuffle(Individual where reflex infect_others when: not is_outside and is_infectious { //Computation of the reduction of the transmission when being asymptomatic/presymptomatic and/or wearing mask - float reduction_factor <- 1.0; + float reduction_factor <- viral_factor; if(is_asymptomatic) { reduction_factor <- reduction_factor * factor_contact_rate_asymptomatic; diff --git a/COMOKIT/Model/Functions.gaml b/COMOKIT/Model/Functions.gaml index b6b6862..dfb3090 100644 --- a/COMOKIT/Model/Functions.gaml +++ b/COMOKIT/Model/Functions.gaml @@ -86,6 +86,21 @@ global } } + + //Basic viral release in the environment of an infectious individual of a given age MUST BE A DISTRIBUTION + float get_viral_factor(int age) + { + if(allow_viral_individual_factor=false) + { + //No difference between individuals + return 1.0; + } + else + { + return get_rnd_from_distribution(map_epidemiological_parameters[age][epidemiological_viral_individual_factor][0],float(map_epidemiological_parameters[age][epidemiological_viral_individual_factor][1]),float(map_epidemiological_parameters[age][epidemiological_viral_individual_factor][2])); + } + } + //Time between exposure and symptom onset of an individual of a given age float get_incubation_period_symptomatic(int age) { diff --git a/COMOKIT/Model/Global.gaml b/COMOKIT/Model/Global.gaml index 57557b2..90c1538 100644 --- a/COMOKIT/Model/Global.gaml +++ b/COMOKIT/Model/Global.gaml @@ -130,6 +130,34 @@ global { //Action used to initialise epidemiological parameters according to the file and parameters forced by the user action init_epidemiological_parameters { + + //In the case no file was provided, then we simply create the matrix from the default parameters, that are not age dependent + loop aYear from:0 to: max_age + { + map> tmp_map; + add list(epidemiological_fixed,string(init_all_ages_successful_contact_rate_human)) to: tmp_map at: epidemiological_successful_contact_rate_human; + add list(epidemiological_fixed,string(init_all_ages_factor_contact_rate_asymptomatic)) to: tmp_map at: epidemiological_factor_asymptomatic; + add list(epidemiological_fixed,string(init_all_ages_proportion_asymptomatic)) to: tmp_map at: epidemiological_proportion_asymptomatic; + add list(epidemiological_fixed,string(init_all_ages_proportion_dead_symptomatic)) to: tmp_map at: epidemiological_proportion_death_symptomatic; + add list(epidemiological_fixed,string(basic_viral_release)) to: tmp_map at: epidemiological_basic_viral_release; + add list(epidemiological_fixed,string(init_all_ages_probability_true_positive)) to: tmp_map at: epidemiological_probability_true_positive; + add list(epidemiological_fixed,string(init_all_ages_probability_true_negative)) to: tmp_map at: epidemiological_probability_true_negative; + add list(epidemiological_fixed,string(init_all_ages_proportion_wearing_mask)) to: tmp_map at: epidemiological_proportion_wearing_mask; + add list(epidemiological_fixed,string(init_all_ages_factor_contact_rate_wearing_mask)) to: tmp_map at: epidemiological_factor_wearing_mask; + add list(init_all_ages_distribution_type_incubation_period_symptomatic,string(init_all_ages_parameter_1_incubation_period_symptomatic),string(init_all_ages_parameter_2_incubation_period_symptomatic)) to: tmp_map at: epidemiological_incubation_period_symptomatic; + add list(init_all_ages_distribution_type_incubation_period_asymptomatic,string(init_all_ages_parameter_1_incubation_period_asymptomatic),string(init_all_ages_parameter_2_incubation_period_asymptomatic)) to: tmp_map at: epidemiological_incubation_period_asymptomatic; + add list(init_all_ages_distribution_type_serial_interval,string(init_all_ages_parameter_1_serial_interval),string(init_all_ages_parameter_2_serial_interval)) to: tmp_map at: epidemiological_serial_interval; + add list(epidemiological_fixed,string(init_all_ages_proportion_hospitalisation)) to: tmp_map at: epidemiological_proportion_hospitalisation; + add list(epidemiological_fixed,string(init_all_ages_proportion_icu)) to: tmp_map at: epidemiological_proportion_icu; + add list(init_all_ages_distribution_type_infectious_period_symptomatic,string(init_all_ages_parameter_1_infectious_period_symptomatic),string(init_all_ages_parameter_2_infectious_period_symptomatic)) to: tmp_map at: epidemiological_infectious_period_symptomatic; + add list(init_all_ages_distribution_type_infectious_period_asymptomatic,string(init_all_ages_parameter_1_infectious_period_asymptomatic),string(init_all_ages_parameter_2_infectious_period_asymptomatic)) to: tmp_map at: epidemiological_infectious_period_asymptomatic; + add list(init_all_ages_distribution_type_onset_to_hospitalisation,string(init_all_ages_parameter_1_onset_to_hospitalisation),string(init_all_ages_parameter_2_onset_to_hospitalisation)) to: tmp_map at: epidemiological_onset_to_hospitalisation; + add list(init_all_ages_distribution_type_hospitalisation_to_ICU,string(init_all_ages_parameter_1_hospitalisation_to_ICU),string(init_all_ages_parameter_2_hospitalisation_to_ICU)) to: tmp_map at: epidemiological_hospitalisation_to_ICU; + add list(init_all_ages_distribution_type_stay_ICU,string(init_all_ages_parameter_1_stay_ICU),string(init_all_ages_parameter_2_stay_ICU)) to: tmp_map at: epidemiological_stay_ICU; + add list(init_all_ages_distribution_viral_individual_factor,string(init_all_ages_parameter_1_viral_individual_factor),string(init_all_ages_parameter_2_viral_individual_factor)) to: tmp_map at: epidemiological_viral_individual_factor; + add tmp_map to: map_epidemiological_parameters at: aYear; + } + //If there are any file given as an epidemiological parameters, then we get the parameters value from it if(load_epidemiological_parameter_from_file and file_exists(epidemiological_parameters)) { @@ -159,6 +187,10 @@ global { allow_transmission_human <- bool(data[epidemiological_csv_column_parameter_one,first(map_parameters[aKey])])!=nil? bool(data[epidemiological_csv_column_parameter_one,first(map_parameters[aKey])]):allow_transmission_human; } + match epidemiological_allow_viral_individual_factor{ + allow_viral_individual_factor <- bool(data[epidemiological_csv_column_parameter_one,first(map_parameters[aKey])])!=nil? + bool(data[epidemiological_csv_column_parameter_one,first(map_parameters[aKey])]):allow_viral_individual_factor; + } match epidemiological_transmission_building{ allow_transmission_building <- bool(data[epidemiological_csv_column_parameter_one,first(map_parameters[aKey])])!=nil? bool(data[epidemiological_csv_column_parameter_one,first(map_parameters[aKey])]):allow_transmission_building; @@ -215,34 +247,6 @@ global { } } } - //In the case no file was provided, then we simply create the matrix from the default parameters, that are not age dependent - else - { - loop aYear from:0 to: max_age - { - map> tmp_map; - add list(epidemiological_fixed,string(init_all_ages_successful_contact_rate_human)) to: tmp_map at: epidemiological_successful_contact_rate_human; - add list(epidemiological_fixed,string(init_all_ages_factor_contact_rate_asymptomatic)) to: tmp_map at: epidemiological_factor_asymptomatic; - add list(epidemiological_fixed,string(init_all_ages_proportion_asymptomatic)) to: tmp_map at: epidemiological_proportion_asymptomatic; - add list(epidemiological_fixed,string(init_all_ages_proportion_dead_symptomatic)) to: tmp_map at: epidemiological_proportion_death_symptomatic; - add list(epidemiological_fixed,string(basic_viral_release)) to: tmp_map at: epidemiological_basic_viral_release; - add list(epidemiological_fixed,string(init_all_ages_probability_true_positive)) to: tmp_map at: epidemiological_probability_true_positive; - add list(epidemiological_fixed,string(init_all_ages_probability_true_negative)) to: tmp_map at: epidemiological_probability_true_negative; - add list(epidemiological_fixed,string(init_all_ages_proportion_wearing_mask)) to: tmp_map at: epidemiological_proportion_wearing_mask; - add list(epidemiological_fixed,string(init_all_ages_factor_contact_rate_wearing_mask)) to: tmp_map at: epidemiological_factor_wearing_mask; - add list(init_all_ages_distribution_type_incubation_period_symptomatic,string(init_all_ages_parameter_1_incubation_period_symptomatic),string(init_all_ages_parameter_2_incubation_period_symptomatic)) to: tmp_map at: epidemiological_incubation_period_symptomatic; - add list(init_all_ages_distribution_type_incubation_period_asymptomatic,string(init_all_ages_parameter_1_incubation_period_asymptomatic),string(init_all_ages_parameter_2_incubation_period_asymptomatic)) to: tmp_map at: epidemiological_incubation_period_asymptomatic; - add list(init_all_ages_distribution_type_serial_interval,string(init_all_ages_parameter_1_serial_interval),string(init_all_ages_parameter_2_serial_interval)) to: tmp_map at: epidemiological_serial_interval; - add list(epidemiological_fixed,string(init_all_ages_proportion_hospitalisation)) to: tmp_map at: epidemiological_proportion_hospitalisation; - add list(epidemiological_fixed,string(init_all_ages_proportion_icu)) to: tmp_map at: epidemiological_proportion_icu; - add list(init_all_ages_distribution_type_infectious_period_symptomatic,string(init_all_ages_parameter_1_infectious_period_symptomatic),string(init_all_ages_parameter_2_infectious_period_symptomatic)) to: tmp_map at: epidemiological_infectious_period_symptomatic; - add list(init_all_ages_distribution_type_infectious_period_asymptomatic,string(init_all_ages_parameter_1_infectious_period_asymptomatic),string(init_all_ages_parameter_2_infectious_period_asymptomatic)) to: tmp_map at: epidemiological_infectious_period_asymptomatic; - add list(init_all_ages_distribution_type_onset_to_hospitalisation,string(init_all_ages_parameter_1_onset_to_hospitalisation),string(init_all_ages_parameter_2_onset_to_hospitalisation)) to: tmp_map at: epidemiological_onset_to_hospitalisation; - add list(init_all_ages_distribution_type_hospitalisation_to_ICU,string(init_all_ages_parameter_1_hospitalisation_to_ICU),string(init_all_ages_parameter_2_hospitalisation_to_ICU)) to: tmp_map at: epidemiological_hospitalisation_to_ICU; - add list(init_all_ages_distribution_type_stay_ICU,string(init_all_ages_parameter_1_stay_ICU),string(init_all_ages_parameter_2_stay_ICU)) to: tmp_map at: epidemiological_stay_ICU; - add tmp_map to: map_epidemiological_parameters at: aYear; - } - } //In the case the user wanted to load parameters from the file, but change the value of some of them for an experiment, // the force_parameters list should contain the key for the parameter, so that the value given will replace the one already @@ -255,6 +259,9 @@ global { match epidemiological_transmission_human{ allow_transmission_human <- allow_transmission_human; } + match epidemiological_allow_viral_individual_factor{ + allow_viral_individual_factor <- allow_viral_individual_factor; + } match epidemiological_transmission_building{ allow_transmission_building <- allow_transmission_building; } diff --git a/COMOKIT/Model/Parameters.gaml b/COMOKIT/Model/Parameters.gaml index 464a71c..dba3289 100644 --- a/COMOKIT/Model/Parameters.gaml +++ b/COMOKIT/Model/Parameters.gaml @@ -57,9 +57,13 @@ global { +"Epidemiological Parameters.csv"; //File for the parameters file csv_parameters <- file_exists(epidemiological_parameters)?csv_file(epidemiological_parameters):nil; + //Dynamics bool allow_transmission_human <- true; //Allowing human to human transmission bool allow_transmission_building <- true; //Allowing environment contamination and infection + bool allow_viral_individual_factor <- false; //Allowing individual effects on the beta and viral release + + //Environmental contamination float successful_contact_rate_building <- 2.5 * 1/(14.69973*nb_step_for_one_day);//Contact rate for environment to human transmission derivated from the R0 and the mean infectious period float reduction_coeff_all_buildings_inhabitants <- 0.01; //reduction of the contact rate for individuals belonging to different households leaving in the same building float reduction_coeff_all_buildings_individuals <- 0.05; //reduction of the contact rate for individuals belonging to different households leaving in the same building @@ -102,6 +106,11 @@ global { string init_all_ages_distribution_type_stay_ICU <- "Lognormal";//Type of distribution of the time to stay in ICU float init_all_ages_parameter_1_stay_ICU <- 3.034953;//First parameter of the time to stay in ICU float init_all_ages_parameter_2_stay_ICU <- 0.34;//Second parameter of the time to stay in ICU + string init_all_ages_distribution_viral_individual_factor <- "Lognormal"; //Type of distribution of the individual factor for beta and viral release + float init_all_ages_parameter_1_viral_individual_factor <- -0.125; //First parameter of distribution of the individual factor for beta and viral release + float init_all_ages_parameter_2_viral_individual_factor <- 0.5; //Second parameter of distribution of the individual factor for beta and viral release + int ICU_capacity<-17; //Capacity of ICU for one hospital (from file) + int hospitalisation_capacity <- 200; //Capacity of hospitalisation admission for one hospital (assumed) list force_parameters; //Synthetic population parameters