From 94ef77280ac227ce3c00f8e582d6649d1d832209 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Thu, 31 Oct 2024 15:05:19 +1300 Subject: [PATCH 1/5] Use per-build metadata files The previous implementation generated a metadata file for each subtype (i.e. before filtering) and then used that for all downstream rules. It's more common to (also) generate a post-subsampling metadata file and use this instead. This is both smaller and useful for debugging (as all the data in the TSV file are used in the build). It's also going to make generating colours for specific builds much easier, which I'll do in subsequent commits. --- Snakefile | 14 ++++++++------ rules/cattle-flu.smk | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Snakefile b/Snakefile index b3bf558..9b076d3 100755 --- a/Snakefile +++ b/Snakefile @@ -1,8 +1,8 @@ # constrain the wildcards to not include `_` which we use to separate "parts" of filenames (where a part may be a wildcard itself) wildcard_constraints: - subtype = "[^_]+", - segment = "[^_]+", - time = "[^_]+", + subtype = "[^_/]+", + segment = "[^_/]+", + time = "[^_/]+", # defined before extra rules `include`d as they reference this constant SEGMENTS = ["pb2", "pb1", "pa", "ha","np", "na", "mp", "ns"] @@ -281,6 +281,7 @@ rule filter: output: sequences = "results/{subtype}/{segment}/{time}/filtered.fasta", strains = "results/{subtype}/{segment}/{time}/filtered.txt", + metadata = "results/{subtype}/{segment}/{time}/metadata.tsv", params: args = _filter_params, shell: @@ -291,6 +292,7 @@ rule filter: --exclude {input.exclude} \ --output-sequences {output.sequences} \ --output-strains {output.strains} \ + --output-metadata {output.metadata} \ {params.args} """ @@ -359,7 +361,7 @@ rule refine: input: tree = rules.tree.output.tree, alignment = rules.align.output, - metadata = metadata_by_wildcards, + metadata = rules.filter.output.metadata, output: tree = "results/{subtype}/{segment}/{time}/tree.nwk", node_data = "results/{subtype}/{segment}/{time}/branch-lengths.json" @@ -463,7 +465,7 @@ def traits_params(wildcards): rule traits: input: tree = refined_tree, - metadata = metadata_by_wildcards, + metadata = "results/{subtype}/{segment}/{time}/metadata.tsv", output: node_data = "results/{subtype}/{segment}/{time}/traits.json", params: @@ -561,7 +563,7 @@ rule export: """ input: tree = refined_tree, - metadata = metadata_by_wildcards, + metadata = rules.filter.output.metadata, node_data = export_node_data_files, colors = files.colors, lat_longs = files.lat_longs, diff --git a/rules/cattle-flu.smk b/rules/cattle-flu.smk index 810f28a..a9ada15 100644 --- a/rules/cattle-flu.smk +++ b/rules/cattle-flu.smk @@ -9,7 +9,7 @@ rule filter_segments_for_genome: # distinguish it when reading the code. input: sequences = "results/{subtype}/{genome_seg}/sequences.fasta", - metadata = "results/{subtype}/metadata-with-clade.tsv", + metadata = "results/{subtype}/metadata-with-clade.tsv", # TODO: use a function here instead of hardcoding include = config['include_strains'], exclude = config['dropped_strains'], output: @@ -78,6 +78,26 @@ rule join_segments: --output {output.alignment} """ +rule genome_metadata: + input: + sequences = "results/{subtype}/{segment}/{time}/aligned.fasta", + metadata = "results/{subtype}/{segment}/{time}/metadata-with-clade-and-non-inferred-values.tsv", + output: + metadata = "results/{subtype}/{segment}/{time}/metadata.tsv" + wildcard_constraints: + subtype = 'h5n1-cattle-outbreak', + segment = 'genome', + time = 'default', + shell: + """ + augur filter --metadata {input.metadata} --sequences {input.sequences} --output-metadata {output.metadata} + """ + +ruleorder: genome_metadata > filter +# Note: I tried to avoid the above ruleorder and instead add a wildcard constraint on the `filter` rule (as it can also produce +# rules.genome_metadata.output.metadata) telling it to use any segment that's _not_ "genome" however I couldn't get this +# working. I thought `segment = "^(?!genome)[^_/]+"` should work but it doesn't. + rule prune_tree: input: tree = "results/{subtype}/{segment}/{time}/tree.nwk", From a84e1cd4907dc8726ab732c3441920fc906bcdd1 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Thu, 31 Oct 2024 15:26:22 +1300 Subject: [PATCH 2/5] Simplify metadata modifications This shifts the modification of metadata which is specific to the h5n1-cattle-outbreak/genome/default build to be downstream of the subsetted-metadata file, which is much simpler to reason with. We could consider doing something similar for the `add_h5_clade` rule, however this wouldn't allow us to use that data as a filtering criteria, and it seems plausible we'd want to do that one day. --- Snakefile | 8 +------ rules/cattle-flu.smk | 50 +++++++++++++++++++++----------------------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/Snakefile b/Snakefile index 9b076d3..c1b0924 100755 --- a/Snakefile +++ b/Snakefile @@ -161,14 +161,8 @@ def metadata_by_wildcards(wildcards): # H5 builds have extra clade-level metadata added to the metadata TSV. # We may move this to a node-data JSON which would simplify the snakemake logic # a bit -- see - if wildcards.subtype in ("h5n1", "h5nx"): + if wildcards.subtype in ("h5n1", "h5nx", "h5n1-cattle-outbreak"): return "results/{subtype}/metadata-with-clade.tsv" - # cattle-flu.smk will make its own modifications as needed - elif wildcards.subtype=="h5n1-cattle-outbreak": - if wildcards.segment=="genome": - return "results/{subtype}/{segment}/default/metadata-with-clade-and-non-inferred-values.tsv" - else: - return "results/{subtype}/metadata-with-clade.tsv" else: return "results/{subtype}/metadata.tsv", diff --git a/rules/cattle-flu.smk b/rules/cattle-flu.smk index a9ada15..8f20a90 100644 --- a/rules/cattle-flu.smk +++ b/rules/cattle-flu.smk @@ -83,7 +83,7 @@ rule genome_metadata: sequences = "results/{subtype}/{segment}/{time}/aligned.fasta", metadata = "results/{subtype}/{segment}/{time}/metadata-with-clade-and-non-inferred-values.tsv", output: - metadata = "results/{subtype}/{segment}/{time}/metadata.tsv" + metadata = temp("results/{subtype}/{segment}/{time}/metadata_intermediate.tsv") wildcard_constraints: subtype = 'h5n1-cattle-outbreak', segment = 'genome', @@ -93,29 +93,6 @@ rule genome_metadata: augur filter --metadata {input.metadata} --sequences {input.sequences} --output-metadata {output.metadata} """ -ruleorder: genome_metadata > filter -# Note: I tried to avoid the above ruleorder and instead add a wildcard constraint on the `filter` rule (as it can also produce -# rules.genome_metadata.output.metadata) telling it to use any segment that's _not_ "genome" however I couldn't get this -# working. I thought `segment = "^(?!genome)[^_/]+"` should work but it doesn't. - -rule prune_tree: - input: - tree = "results/{subtype}/{segment}/{time}/tree.nwk", - strains = "auspice/avian-flu_h5n1-cattle-outbreak_genome.json", - output: - tree = "results/{subtype}/{segment}/{time}/tree_outbreak-clade.nwk", - node_data = "results/{subtype}/{segment}/{time}/outbreak-clade-strains-in-genome-tree.json", - wildcard_constraints: - subtype="h5n1-cattle-outbreak", - time="default", - shell: - """ - python3 scripts/restrict-via-common-ancestor.py \ - --tree {input.tree} \ - --strains {input.strains} \ - --output-tree {output.tree} \ - --output-metadata {output.node_data} - """ def assert_expected_config(w): try: @@ -135,9 +112,9 @@ rule add_metadata_columns_to_show_non_inferred_values: that function's not visible to this .smk file so would require deeper refactoring. """ input: - metadata = "results/{subtype}/metadata-with-clade.tsv", + metadata = "results/{subtype}/{segment}/{time}/metadata_intermediate.tsv" output: - metadata = "results/{subtype}/{segment}/{time}/metadata-with-clade-and-non-inferred-values.tsv", + metadata = "results/{subtype}/{segment}/{time}/metadata.tsv" wildcard_constraints: subtype="h5n1-cattle-outbreak", segment="genome", @@ -150,3 +127,24 @@ rule add_metadata_columns_to_show_non_inferred_values: """ cat {input.metadata} | csvtk mutate -t -f {params.old_column} -n {params.new_column} > {output.metadata} """ + +ruleorder: add_metadata_columns_to_show_non_inferred_values > filter + +rule prune_tree: + input: + tree = "results/{subtype}/{segment}/{time}/tree.nwk", + strains = "auspice/avian-flu_h5n1-cattle-outbreak_genome.json", + output: + tree = "results/{subtype}/{segment}/{time}/tree_outbreak-clade.nwk", + node_data = "results/{subtype}/{segment}/{time}/outbreak-clade-strains-in-genome-tree.json", + wildcard_constraints: + subtype="h5n1-cattle-outbreak", + time="default", + shell: + """ + python3 scripts/restrict-via-common-ancestor.py \ + --tree {input.tree} \ + --strains {input.strains} \ + --output-tree {output.tree} \ + --output-metadata {output.node_data} + """ From 6675e5640af8eed1426c721f39593a7ae157744b Mon Sep 17 00:00:00 2001 From: james hadfield Date: Thu, 31 Oct 2024 16:41:32 +1300 Subject: [PATCH 3/5] rearrange snakefiles Make variables and functions defined in the snakefile available to custom rule files such as cattle-flu.smk. See for more context. --- Snakefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Snakefile b/Snakefile index c1b0924..52570f2 100755 --- a/Snakefile +++ b/Snakefile @@ -7,10 +7,6 @@ wildcard_constraints: # defined before extra rules `include`d as they reference this constant SEGMENTS = ["pb2", "pb1", "pa", "ha","np", "na", "mp", "ns"] - -for rule_file in config.get('custom_rules', []): - include: rule_file - # The config option `same_strains_per_segment=True'` (e.g. supplied to snakemake via --config command line argument) # will change the behaviour of the workflow to use the same strains for each segment. This is achieved via these steps: # (1) Filter the HA segment as normal plus filter to those strains with 8 segments @@ -629,3 +625,7 @@ rule clean: "auspice" shell: "rm -rfv {params}" + + +for rule_file in config.get('custom_rules', []): + include: rule_file From 85397ff9c495edc247098059c3998a49ada30d2c Mon Sep 17 00:00:00 2001 From: james hadfield Date: Thu, 31 Oct 2024 17:03:10 +1300 Subject: [PATCH 4/5] Consistent coloring for genome builds Uses our well-established pattern of a color-ordering file and a set of hexes to produce a well-ordered color pallet. Here we restrict the values within the generating script to better maximise the final color range (rather than setting colors for all divisions then having augur export subset them). This approach also ensures colors are consistent across "division" and "division_metadata" which aids interpretation of the data. Closes #101 --- Snakefile | 14 +++- .../h5n1-cattle-outbreak/color_ordering.tsv | 64 +++++++++++++++ config/h5n1-cattle-outbreak/color_schemes.tsv | 77 ++++++++++++++++++ rules/cattle-flu.smk | 32 +++++++- scripts/assign-colors.py | 79 +++++++++++++++++++ 5 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 config/h5n1-cattle-outbreak/color_ordering.tsv create mode 100644 config/h5n1-cattle-outbreak/color_schemes.tsv create mode 100644 scripts/assign-colors.py diff --git a/Snakefile b/Snakefile index 52570f2..fa83424 100755 --- a/Snakefile +++ b/Snakefile @@ -274,6 +274,9 @@ rule filter: metadata = "results/{subtype}/{segment}/{time}/metadata.tsv", params: args = _filter_params, + wildcard_constraints: + # The genome build has a different approach to filtering (see cattle-flu.smk) + segment="(?!genome)[^_/]+" shell: """ augur filter \ @@ -545,6 +548,15 @@ rule auspice_config: with open(output.auspice_config, 'w') as fh: json.dump(auspice_config, fh, indent=2) +rule colors: + input: + colors = files.colors, + output: + colors = "results/{subtype}/{segment}/{time}/colors.tsv", + shell: + """ + cp {input.colors} {output.colors} + """ rule export: """ @@ -555,7 +567,7 @@ rule export: tree = refined_tree, metadata = rules.filter.output.metadata, node_data = export_node_data_files, - colors = files.colors, + colors = "results/{subtype}/{segment}/{time}/colors.tsv", lat_longs = files.lat_longs, auspice_config = rules.auspice_config.output.auspice_config, description = files.description diff --git a/config/h5n1-cattle-outbreak/color_ordering.tsv b/config/h5n1-cattle-outbreak/color_ordering.tsv new file mode 100644 index 0000000..8ac348a --- /dev/null +++ b/config/h5n1-cattle-outbreak/color_ordering.tsv @@ -0,0 +1,64 @@ +# Ordering taken from +division American Samoa +division Hawaii +division Alaska +division Oregon +division Washington +division California +division Nevada +division Idaho +division Utah +division Arizona +division Montana +division Wyoming +division New Mexico +division Colorado +division North Dakota +division South Dakota +division Nebraska +division Texas +division USA +division Kansas +division North America +division Oklahoma +division Minnesota +division Iowa +division Louisiana +division Arkansas +division Missouri +division Mississippi +division Wisconsin +division Illinois +division Alabama +division Tennessee +division Indiana +division Kentucky +division Michigan +division Georgia +division Ohio +division Florida +division South Carolina +division West Virginia +division North Carolina +division Virginia +division Pennsylvania +division Washington DC +division Maryland +division Delaware +division New Jersey +division New York +division Connecticut +division Vermont +division Massachusetts +division New Hampshire +division Rhode Island +division Maine +division Puerto Rico +division Virgin Islands +division Guam +division Northern Mariana Islands +# +# +# +data_source genbank +data_source sra-via-andersen-lab diff --git a/config/h5n1-cattle-outbreak/color_schemes.tsv b/config/h5n1-cattle-outbreak/color_schemes.tsv new file mode 100644 index 0000000..f1c2952 --- /dev/null +++ b/config/h5n1-cattle-outbreak/color_schemes.tsv @@ -0,0 +1,77 @@ +#4C90C0 +#529AB6 #AABD52 +#4E94BD #81BA72 #C8B944 +#4A8CC2 #71B486 #ABBD52 #DEA73C +#4784C8 #67AE95 #98BD5E #CDB642 #E68634 +#447CCD #5EA9A1 #8ABB6A #BEBB48 #E29E39 #E2562B +#4272CE #58A2AC #7DB877 #AEBD50 #D8AE3E #E67A32 #DB2823 +#4068CF #5098B9 #6CB28C #94BD62 #BFBB47 #DFA53B #E67131 #DB2823 +#3E5DD0 #4A8CC2 #60AA9E #80B974 #A6BE55 #CBB742 #E29D39 #E56A2F #DB2823 +#3F52CD #4681CA #57A1AD #70B487 #90BC65 #B4BD4C #D3B240 #E59638 #E4642E #DB2823 +#3F47C9 #4274CE #4F97BB #64AC99 #7EB976 #9EBE5A #BEBB48 #D9AE3E #E69036 #E35F2D #DB2823 +#403CC5 #4067CF #4A8BC3 #5AA4A9 #6FB488 #8BBB69 #A9BD53 #C7B944 #DDA93C #E68A35 #E35C2C #DB2823 +#4433BE #3E5ACF #457FCB #529AB6 #64AD98 #7BB77A #96BD60 #B3BD4D #CDB642 #DFA43B #E68434 #E2582C #DB2823 +#492AB5 #3F4CCB #4271CE #4C8FC0 #5AA5A8 #6DB38A #85BA6F #A0BE59 #BBBC49 #D2B340 #E19F3A #E68033 #E2562B #DB2823 +#4D21AD #403FC6 #3F63CF #4783C8 #539BB5 #63AC9B #77B67F #8EBC66 #A8BD53 #C1BA47 #D6B03F #E39C39 #E67C33 #E1532B #DB2823 +#571EA2 #4334BF #3F55CE #4376CD #4C91C0 #59A4A9 #6AB18F #7FB975 #97BD5F #AFBD4F #C7B944 #D9AD3D #E49838 #E67932 #E1512A #DB2823 +#5E1D9D #462EB9 #3F4CCB #416CCE #4887C6 #539CB3 #62AB9C #74B582 #89BB6B #A0BE59 #B7BD4B #CCB742 #DDAA3C #E69537 #E67631 #E14F2A #DB2823 +#5E1D9D #472DB8 #3F48C9 #4066CF #4682C9 #5097BA #5CA7A5 #6CB28D #7FB976 #93BD62 #A9BD53 #BFBB48 #D1B340 #DFA53B #E68F36 #E67231 #E04D29 #DB2823 +#5E1D9D #482BB6 #3F45C8 #3F62D0 #447DCC #4D92BF #58A2AC #66AE96 #76B680 #89BB6B #9DBE5A #B2BD4D #C5B945 #D5B03F #E1A13A #E68B35 #E56E30 #E04B29 #DB2823 +#5E1D9D #492AB5 #4042C7 #3E5DD0 #4377CD #4A8CC2 #549DB2 #60AA9E #6EB389 #80B974 #92BC63 #A6BE55 #B9BC4A #CBB742 #D9AD3D #E29D39 #E68634 #E56A2F #E04929 #DB2823 +#5E1D9D #4929B4 #403FC6 #3E59CF #4272CE #4887C6 #5199B8 #5BA7A6 #69B091 #78B67E #89BB6B #9BBE5B #AEBD50 #C0BB47 #D0B441 #DDAA3C #E49938 #E68234 #E4672E #DF4728 #DB2823 +#5E1D9D #4A28B3 #403DC5 #3F56CE #416DCE #4683C8 #4E95BD #58A2AC #64AC99 #71B486 #80B973 #91BC64 #A3BE57 #B5BD4C #C5B945 #D3B23F #DEA63B #E59638 #E67F33 #E4642E #DF4628 #DB2823 +#5E1D9D #4A27B2 #403AC4 #3F52CD #4169CF #457ECB #4C90C0 #559EB1 #5FA9A0 #6BB18E #79B77C #89BB6B #99BD5D #AABD52 #BBBC49 #CBB842 #D7AF3E #E0A23A #E69237 #E67B32 #E3612D #DF4528 #DB2823 +#5E1D9D #4B26B1 #4138C3 #3F4FCC #4065CF #447ACD #4A8BC3 #529AB6 #5BA6A6 #66AE95 #73B583 #81B973 #91BC64 #A1BE58 #B1BD4E #C0BA47 #CEB541 #DAAD3D #E19F3A #E68E36 #E67832 #E35F2D #DF4328 #DB2823 +#5E1D9D #4B25B1 #4137C2 #3F4CCB #3F62D0 #4376CD #4887C6 #4F97BB #58A2AC #62AB9C #6DB38A #7BB77A #89BB6B #98BD5E #A8BE54 #B7BD4B #C5B945 #D2B340 #DDAA3C #E39C39 #E68B35 #E67631 #E35C2C #DF4227 #DB2823 +#5E1D9D #4C25B0 #4236C0 #3F4ACA #3F5ED0 #4272CE #4783C8 #4D93BE #559EB1 #5EA9A2 #69B091 #75B581 #82BA72 #90BC65 #9FBE59 #AEBD50 #BCBB49 #CAB843 #D5B03F #DEA73B #E49938 #E68735 #E67331 #E25A2C #DF4127 #DB2823 +#5E1D9D #4C24AF #4334BF #3F47C9 #3E5BD0 #416ECE #4580CA #4B8FC1 #529BB5 #5BA5A7 #65AD98 #6FB388 #7CB879 #89BB6B #97BD5F #A5BE55 #B4BD4C #C1BA47 #CDB642 #D8AE3E #DFA43B #E59638 #E68434 #E67030 #E2582C #DF4027 #DB2823 +#5E1D9D #4C24AF #4433BE #3F45C8 #3E58CF #416BCF #447DCC #4A8BC3 #5098B9 #58A2AC #61AA9D #6BB18E #76B680 #82BA71 #8FBC65 #9DBE5A #ABBD52 #B9BC4A #C5B945 #D1B440 #DAAC3D #E1A13A #E69437 #E68134 #E56E30 #E2562B #DE3F27 #DB2823 +#5E1D9D #4D23AE #4432BD #3F43C7 #3F56CE #4067CF #4379CD #4887C6 #4E95BD #559FB0 #5DA8A3 #67AE94 #71B486 #7CB878 #89BB6B #96BD60 #A3BE57 #B1BD4E #BDBB48 #CAB843 #D3B23F #DDAA3C #E29E39 #E69036 #E67F33 #E56B2F #E1552B #DE3E27 #DB2823 +#5E1D9D #4D22AE #4531BC #4041C7 #3F53CD #4064CF #4375CD #4784C8 #4C91BF #539CB4 #5AA5A7 #63AC9A #6CB28C #77B67E #82BA71 #8FBC66 #9CBE5B #A9BD53 #B5BD4C #C1BA46 #CDB642 #D6B03F #DEA73B #E39B39 #E68D36 #E67C33 #E5692F #E1532B #DE3E27 #DB2823 +#5E1D9D #4D22AD #4530BB #403FC6 #3F51CC #3F62D0 #4272CE #4681CA #4B8EC2 #5199B8 #58A2AC #60AA9F #69B091 #72B584 #7DB877 #89BB6B #95BD61 #A1BE58 #AEBD50 #BABC4A #C5B945 #D0B441 #D8AE3E #DFA43B #E49938 #E68B35 #E67A32 #E4672E #E1522A #DE3D27 #DB2823 +#5E1D9D #4D22AD #462FBA #403DC5 #3F4ECB #3F5FD0 #426FCE #457ECB #4A8AC4 #4F96BB #569FB0 #5DA8A4 #65AD97 #6EB389 #78B77D #83BA71 #8FBC66 #9ABE5C #A7BE54 #B3BD4D #BEBB48 #C9B843 #D2B240 #DBAC3D #E0A23A #E59738 #E68835 #E67832 #E4652E #E1512A #DE3C26 #DB2823 +#5E1D9D #4E21AD #462EB9 #403CC5 #3F4CCB #3E5DD0 #416CCE #447BCD #4887C6 #4D93BE #539CB3 #5AA5A8 #62AB9C #6AB18F #74B582 #7EB876 #89BB6B #94BD61 #A0BE59 #ABBD51 #B7BD4B #C2BA46 #CCB742 #D5B13F #DDAA3C #E19F3A #E69537 #E68534 #E67631 #E4632E #E14F2A #DE3C26 #DB2823 +#5E1D9D #4E21AC #472DB8 #403AC4 #3F4ACA #3E5ACF #4169CF #4378CD #4784C7 #4C90C0 #519AB7 #58A2AC #5FA9A0 #67AF94 #6FB488 #79B77C #83BA70 #8EBC67 #99BD5D #A5BE56 #B0BD4F #BBBC49 #C5B945 #CFB541 #D7AF3E #DEA83C #E29D39 #E69237 #E68334 #E67431 #E3612D #E04E2A #DE3B26 #DB2823 +#5E1D9D #4E20AC #472DB8 #4039C4 #3F48C9 #3E58CF #4066CF #4375CD #4682C9 #4B8DC2 #5097BA #569FAF #5CA7A5 #64AD99 #6CB28D #75B581 #7FB976 #89BB6B #93BD62 #9EBE59 #A9BD53 #B4BD4C #BFBB48 #C9B843 #D1B340 #D9AD3D #DFA53B #E39B39 #E68F36 #E68133 #E67231 #E35F2D #E04D29 #DE3B26 #DB2823 +#5E1D9D #4E20AB #472CB7 #4138C3 #3F47C9 #3F56CE #4064CF #4272CE #457FCB #498AC4 #4E95BD #549DB3 #5AA5A8 #61AB9D #69B091 #71B486 #7AB77B #83BA70 #8EBC67 #98BD5E #A3BE57 #AEBD50 #B8BC4A #C2BA46 #CCB742 #D3B23F #DBAC3D #E0A33A #E49938 #E68D36 #E67F33 #E67030 #E35E2D #E04C29 #DE3A26 #DB2823 +#5E1D9D #4E20AB #482BB6 #4137C2 #3F45C8 #3F53CD #3F62D0 #426FCE #447DCC #4887C6 #4D92BF #529AB6 #58A2AC #5EA9A1 #66AE96 #6DB38A #76B680 #7FB975 #89BB6B #93BC63 #9DBE5A #A8BE54 #B2BD4D #BCBB49 #C5B945 #CEB541 #D5B03F #DDAA3C #E1A13A #E59738 #E68B35 #E67D33 #E56E30 #E35C2C #E04B29 #DE3926 #DB2823 +#5E1D9D #4F1FAB #482BB6 #4236C1 #3F43C8 #3F52CC #3F5FD0 #416DCE #437ACD #4785C7 #4B8FC1 #5098B9 #56A0AF #5CA7A5 #63AC9A #6AB18F #72B484 #7BB77A #84BA70 #8EBC67 #97BD5E #A2BE57 #ACBD51 #B6BD4B #BFBB47 #C9B843 #D0B441 #D7AE3E #DEA83C #E19F39 #E59537 #E68835 #E67B32 #E56C2F #E25B2C #E04A29 #DE3926 #DB2823 +#5E1D9D #4F1FAB #492AB5 #4235C0 #4042C7 #3F50CC #3E5DD0 #416ACF #4377CD #4682C9 #4A8CC2 #4F96BC #549DB2 #5AA4A8 #60AA9E #67AF93 #6EB389 #77B67F #80B974 #89BB6B #92BC63 #9CBE5B #A6BE55 #B0BD4F #B9BC4A #C2BA46 #CBB742 #D2B240 #D9AD3D #DEA63B #E29D39 #E69337 #E68634 #E67932 #E56A2F #E25A2C #E04929 #DE3926 #DB2823 +#5E1D9D #4F1FAA #492AB5 #4334BF #4040C7 #3F4ECB #3E5BD0 #4068CF #4374CD #4580CA #498AC4 #4D93BE #529BB5 #58A2AC #5EA8A2 #65AD98 #6BB28D #73B583 #7CB879 #84BA6F #8DBC67 #97BD5F #A0BE58 #AABD52 #B4BD4C #BDBB49 #C5B945 #CDB642 #D4B13F #DBAC3D #DFA43B #E39B39 #E69137 #E68434 #E67732 #E4682F #E2582C #E04828 #DE3826 #DB2823 +#5E1D9D #4F1FAA #4929B4 #4333BE #403FC6 #3F4CCB #3E59CF #4066CF #4272CE #447ECC #4887C6 #4C91C0 #5199B8 #56A0AF #5BA7A6 #62AB9C #69B091 #70B487 #78B67E #80B974 #89BB6B #92BC63 #9BBE5B #A4BE56 #AEBD50 #B7BD4B #C0BB47 #C8B843 #D0B441 #D6AF3E #DDAA3C #E0A23A #E49938 #E68F36 #E68234 #E67631 #E4672E #E2572B #DF4728 #DD3826 #DB2823 +#5E1D9D #4F1EAA #4928B4 #4433BE #403EC6 #3F4BCA #3E57CE #4064CF #426FCE #447BCD #4785C7 #4B8EC1 #4F97BA #549EB2 #5AA4A9 #5FAA9F #66AE95 #6DB28B #74B582 #7CB878 #84BA6F #8DBC67 #96BD60 #9FBE59 #A8BD53 #B2BD4E #BABC4A #C3BA46 #CBB842 #D1B340 #D8AE3E #DDA83C #E1A03A #E59738 #E68D36 #E68033 #E67431 #E4652E #E2562B #DF4728 #DD3726 #DB2823 +#5E1D9D #4F1EA9 #4A28B3 #4432BD #403DC5 #3F49CA #3F56CE #3F62D0 #416DCE #4379CD #4683C8 #4A8CC3 #4E95BD #539BB4 #58A2AC #5DA8A3 #64AC99 #6AB18F #71B486 #79B77D #80B973 #89BB6B #91BC64 #9ABE5C #A3BE57 #ACBD51 #B5BD4C #BDBB48 #C5B945 #CDB642 #D3B23F #DAAD3D #DEA63B #E29E39 #E59638 #E68B35 #E67F33 #E67331 #E4642E #E1552B #DF4628 #DD3725 #DB2823 +#5E1D9D #501EA9 #4A28B3 #4531BC #403BC5 #3F48C9 #3F54CD #3F60D0 #416BCE #4376CD #4681CA #4989C4 #4D92BF #519AB7 #56A0AF #5BA6A6 #61AB9D #67AF93 #6EB38A #75B681 #7DB878 #84BA6F #8DBC68 #95BD60 #9EBE5A #A7BE54 #B0BD4F #B8BC4A #C0BA47 #C8B844 #CFB541 #D5B03F #DBAC3D #DFA43B #E29C39 #E69437 #E68935 #E67D33 #E67130 #E4622E #E1542B #DF4528 #DD3725 #DB2823 +#5E1D9D #501EA9 #4A27B2 #4531BB #403AC4 #3F46C9 #3F52CD #3F5ED0 #4169CF #4274CE #457ECB #4887C6 #4C90C0 #5098B9 #559EB1 #59A4A9 #5FA9A0 #65AD97 #6BB18E #72B485 #79B77C #81B973 #89BB6B #91BC64 #99BD5D #A2BE57 #AABD52 #B3BD4D #BBBC49 #C3BA46 #CBB842 #D1B340 #D7AF3E #DDAA3C #E0A23A #E39B39 #E69237 #E68735 #E67B32 #E66F30 #E3612D #E1532B #DF4528 #DD3625 #DB2823 +#5E1D9D #501EA9 #4A27B2 #4530BB #4039C4 #3F45C8 #3F51CC #3E5CD0 #4067CF #4272CE #447DCC #4785C7 #4B8EC2 #4E96BC #539CB4 #58A2AC #5DA8A3 #63AC9A #69B091 #6FB388 #76B680 #7DB877 #85BA6F #8DBC68 #95BD61 #9DBE5A #A5BE55 #AEBD50 #B6BD4B #BEBB48 #C5B945 #CDB642 #D3B240 #D8AE3E #DDA83C #E1A13A #E49938 #E69036 #E68534 #E67A32 #E56E30 #E3602D #E1522A #DF4428 #DD3625 #DB2823 +#5E1D9D #511EA8 #4B26B1 #462FBA #4138C3 #3F44C8 #3F4FCC #3E5AD0 #4065CF #4270CE #447ACD #4783C8 #4A8BC3 #4D94BE #529AB6 #56A0AE #5BA6A6 #60AA9E #66AE95 #6CB28C #73B583 #7AB77B #81B973 #89BB6B #91BC64 #99BD5E #A1BE58 #A9BD53 #B1BD4E #B9BC4A #C0BA47 #C8B944 #CEB541 #D4B13F #DAAD3D #DEA63B #E19F3A #E49838 #E68E36 #E68334 #E67832 #E56C2F #E35F2D #E1512A #DF4328 #DD3625 #DB2823 +#5E1D9D #511EA8 #4B26B1 #462FBA #4138C2 #3F42C7 #3F4ECB #3E59CF #4063CF #416ECE #4378CD #4681C9 #4989C4 #4C91BF #5098B9 #559EB1 #59A4A9 #5EA9A1 #64AD98 #6AB090 #70B487 #77B67F #7EB877 #85BA6F #8DBC68 #94BD61 #9CBE5B #A4BE56 #ACBD51 #B4BD4C #BCBB49 #C3BA46 #CAB843 #D0B441 #D6B03F #DBAC3D #DFA53B #E29D39 #E59638 #E68C36 #E68234 #E67732 #E56B2F #E35D2D #E1502A #DF4328 #DD3525 #DB2823 +#5E1D9D #511EA8 #4B25B1 #462EB9 #4137C2 #4041C7 #3F4CCB #3E57CE #3F62D0 #416CCE #4376CD #457FCB #4887C6 #4C8FC1 #4F97BB #539CB3 #58A2AC #5CA7A4 #62AB9C #68AF93 #6DB38A #74B582 #7BB77A #81BA72 #89BB6B #90BC65 #98BD5E #A0BE59 #A8BE54 #AFBD4F #B7BD4B #BEBB48 #C5B945 #CCB742 #D2B340 #D7AF3E #DDAA3C #E0A33B #E39C39 #E69537 #E68B35 #E68033 #E67631 #E5692F #E35C2C #E14F2A #DF4227 #DD3525 #DB2823 +#5E1D9D #511EA8 #4B25B0 #472EB9 #4236C1 #4040C6 #3F4BCA #3F56CE #3F60D0 #416ACF #4274CE #447DCC #4885C7 #4B8DC2 #4E95BD #529BB6 #56A0AE #5BA6A7 #60AA9F #65AD96 #6BB18E #71B486 #78B67E #7EB976 #85BA6F #8CBC68 #94BD62 #9BBE5B #A3BE57 #ABBD52 #B2BD4D #BABC4A #C1BA47 #C8B944 #CEB541 #D3B23F #D9AE3E #DDA83C #E0A13A #E39A39 #E69337 #E68935 #E67F33 #E67431 #E4682F #E25B2C #E04E2A #DF4227 #DD3525 #DB2823 +#5E1D9D #521EA7 #4C25B0 #472DB8 #4236C0 #403FC6 #3F4ACA #3F54CD #3F5ED0 #4068CF #4272CE #447CCD #4783C8 #4A8BC3 #4D93BE #5199B8 #559EB1 #59A4A9 #5EA9A2 #63AC99 #69B091 #6EB389 #75B581 #7BB77A #82BA72 #89BB6B #90BC65 #97BD5F #9FBE59 #A6BE55 #AEBD50 #B5BD4C #BCBB49 #C3BA46 #CAB843 #D0B441 #D5B03F #DAAC3D #DEA73B #E1A03A #E49938 #E69137 #E68735 #E67D33 #E67331 #E4672E #E25A2C #E04E2A #DF4127 #DD3525 #DB2823 +#5E1D9D #521EA7 #4C24B0 #472DB8 #4335C0 #403EC6 #3F48C9 #3F53CD #3E5DD0 #4066CF #4270CE #4379CD #4682C9 #4989C4 #4C91C0 #5097BA #549DB3 #58A2AC #5CA7A5 #61AB9D #67AE95 #6CB28D #72B485 #78B77D #7FB976 #85BA6E #8CBB68 #93BD62 #9BBE5C #A2BE57 #A9BD53 #B1BD4E #B8BC4B #BFBB48 #C5B945 #CCB742 #D1B340 #D6AF3E #DCAB3D #DFA53B #E29E39 #E49838 #E68F36 #E68634 #E67C33 #E67231 #E4652E #E2592C #E04D29 #DF4127 #DD3425 #DB2823 +#5E1D9D #521EA7 #4C24AF #472CB7 #4334BF #403DC5 #3F47C9 #3F51CC #3E5BD0 #4065CF #416ECE #4377CD #4580CA #4887C6 #4B8FC1 #4E96BC #529BB5 #56A0AE #5BA5A7 #5FA99F #65AD98 #6AB090 #6FB388 #75B681 #7CB879 #82BA72 #89BB6B #90BC65 #97BD5F #9EBE5A #A5BE55 #ACBD51 #B4BD4C #BABC49 #C1BA47 #C8B944 #CDB642 #D3B240 #D8AE3E #DDAA3C #DFA43B #E29D39 #E59638 #E68E36 #E68434 #E67B32 #E67030 #E4642E #E2582C #E04C29 #DF4027 #DD3425 #DB2823 +#5E1D9D #521EA7 #4C24AF #482CB7 #4334BE #403CC5 #3F46C8 #3F50CC #3E5ACF #3F63CF #416CCE #4376CD #457ECB #4885C7 #4B8DC2 #4D94BE #5199B7 #559FB0 #59A4A9 #5DA8A2 #63AC9B #68AF93 #6DB28B #73B584 #79B77C #7FB975 #85BA6E #8CBB68 #93BC62 #9ABD5C #A1BE58 #A8BD53 #AFBD4F #B6BD4B #BDBB48 #C3BA46 #CAB843 #CFB541 #D4B13F #D9AD3D #DDA93C #E0A23A #E39C39 #E59537 #E68C36 #E68334 #E67932 #E56F30 #E4632E #E2572B #E04C29 #DF4027 #DD3425 #DB2823 +#5E1D9D #531EA7 #4C24AF #482BB6 #4433BE #403BC5 #3F45C8 #3F4FCB #3E58CF #3F62D0 #416BCF #4274CE #447DCC #4784C8 #4A8BC3 #4D92BF #5098B9 #549DB2 #58A2AC #5CA7A5 #61AA9D #66AE96 #6BB18E #70B487 #76B680 #7CB879 #82BA71 #89BB6B #8FBC65 #96BD60 #9DBE5A #A4BE56 #ABBD52 #B2BD4D #B9BC4A #BFBB47 #C5B945 #CCB742 #D1B440 #D5B03F #DAAC3D #DEA73B #E1A13A #E39A39 #E69437 #E68B35 #E68134 #E67832 #E56E30 #E3622D #E2562B #E04B29 #DE3F27 #DD3425 #DB2823 +#5E1D9D #531EA7 #4C23AF #482BB6 #4432BD #403AC4 #3F44C8 #3F4DCB #3E57CE #3F60D0 #4169CF #4272CE #447BCD #4682C9 #4989C4 #4C90C0 #4F96BB #539BB5 #57A0AE #5AA5A7 #5FA9A0 #64AC99 #69B091 #6EB38A #73B583 #79B77C #7FB975 #85BA6E #8CBB68 #93BC63 #99BD5D #A0BE58 #A7BE54 #AEBD50 #B5BD4C #BBBC49 #C1BA47 #C8B944 #CDB642 #D2B340 #D7AF3E #DCAB3D #DFA63B #E19F3A #E49938 #E69237 #E68935 #E68033 #E67732 #E56C30 #E3612D #E2562B #E04A29 #DE3F27 #DD3325 #DB2823 +#5E1D9D #531EA6 #4D23AE #482AB6 #4432BD #4039C4 #3F43C7 #3F4CCB #3F56CE #3F5FD0 #4067CF #4270CE #4379CD #4680CA #4887C6 #4B8EC1 #4E95BD #529AB7 #559FB0 #59A4AA #5DA8A3 #62AB9C #67AE94 #6CB28D #71B486 #77B67F #7CB878 #82BA71 #89BB6B #8FBC66 #96BD60 #9CBE5B #A3BE57 #AABD52 #B1BD4E #B7BD4B #BDBB48 #C3BA46 #CAB843 #CFB541 #D3B23F #D8AE3E #DDAA3C #DFA43B #E29E39 #E49838 #E69036 #E68835 #E67F33 #E67631 #E56B2F #E3602D #E1552B #E04A29 #DE3E27 #DD3325 #DB2823 +#5E1D9D #531EA6 #4D23AE #492AB5 #4431BC #4039C3 #4042C7 #3F4BCA #3F54CD #3E5DD0 #4066CF #416ECE #4377CD #457FCB #4886C7 #4A8CC2 #4D93BE #5098B8 #549DB2 #58A2AC #5CA7A5 #60AA9E #65AD97 #6AB090 #6EB389 #74B582 #7AB77B #80B974 #85BB6E #8CBB69 #92BC63 #99BD5D #9FBE59 #A6BE55 #ADBD51 #B3BD4D #B9BC4A #BFBB47 #C5B945 #CBB742 #D0B441 #D5B13F #D9AD3D #DDA93C #E0A33A #E29D39 #E59738 #E68F36 #E68634 #E67D33 #E67531 #E56A2F #E35F2D #E1542B #E04929 #DE3E27 #DD3325 #DB2823 +#5E1D9D #531EA6 #4D22AE #492AB5 #4531BC #4138C3 #4041C7 #3F4ACA #3F53CD #3E5CD0 #4064CF #416DCE #4375CD #447DCC #4784C8 #4A8BC3 #4C91BF #4F97BA #539CB4 #57A0AE #5AA5A7 #5EA9A1 #63AC9A #68AF93 #6CB28C #72B485 #77B67E #7DB878 #82BA71 #89BB6B #8FBC66 #95BD60 #9CBE5B #A2BE57 #A9BD53 #AFBD4F #B5BD4C #BBBC49 #C1BA46 #C7B944 #CDB642 #D1B340 #D6B03F #DBAC3D #DEA73B #E0A13A #E39B39 #E59637 #E68D36 #E68534 #E67C33 #E67431 #E5692F #E35E2D #E1532B #E04929 #DE3E27 #DD3325 #DB2823 +#5E1D9D #541EA6 #4D22AE #4929B4 #4530BB #4137C2 #4040C6 #3F49C9 #3F52CD #3E5BD0 #3F63CF #416BCE #4274CE #447CCD #4682C9 #4989C5 #4C8FC0 #4E96BC #529AB6 #559FB0 #59A4AA #5DA8A3 #61AB9C #66AE95 #6AB18F #6FB488 #75B581 #7AB77B #80B974 #86BB6E #8CBB69 #92BC63 #98BD5E #9EBE59 #A5BE55 #ABBD51 #B2BD4E #B8BC4B #BEBB48 #C3BA46 #C9B843 #CEB541 #D3B240 #D7AF3E #DCAB3C #DEA63B #E1A03A #E39A39 #E69437 #E68C36 #E68334 #E67B32 #E67231 #E4682F #E35D2D #E1532A #E04828 #DE3D27 #DD3325 #DB2823 +#5E1D9D #541EA6 #4D22AD #4929B4 #4530BB #4137C2 #403FC6 #3F48C9 #3F51CC #3E59CF #3F62D0 #416ACF #4272CE #437ACD #4681CA #4887C6 #4B8EC2 #4D94BD #5199B8 #549DB2 #58A2AC #5BA7A6 #60AA9F #64AD98 #69B091 #6DB38A #72B584 #78B67E #7DB877 #83BA71 #89BB6B #8FBC66 #95BD61 #9BBE5B #A1BE58 #A8BE54 #AEBD50 #B4BD4C #BABC4A #C0BB47 #C5B945 #CBB842 #D0B441 #D4B13F #D8AE3E #DDAA3C #DFA43B #E19F3A #E49938 #E69337 #E68B35 #E68234 #E67A32 #E67130 #E4672E #E35C2C #E1522A #DF4728 #DE3D27 #DD3325 #DB2823 +#5E1D9D #541EA6 #4D22AD #4929B4 #462FBA #4236C1 #403EC6 #3F47C9 #3F4FCC #3E58CF #3F60D0 #4068CF #4270CE #4378CD #457FCB #4886C7 #4A8CC3 #4D92BF #5098BA #539CB4 #57A0AE #5AA5A8 #5EA9A1 #62AC9B #67AF94 #6BB18D #70B487 #75B680 #7BB77A #80B974 #86BB6E #8CBB69 #92BC64 #98BD5E #9EBE5A #A4BE56 #AABD52 #B0BD4E #B6BD4B #BCBB49 #C2BA46 #C7B944 #CCB742 #D1B340 #D5B03F #DAAD3D #DDA93C #E0A33B #E29E39 #E49838 #E69137 #E68935 #E68133 #E67932 #E67030 #E4662E #E25B2C #E1512A #DF4728 #DE3D26 #DD3225 #DB2823 +#5E1D9D #541EA5 #4D22AD #4A28B3 #462FBA #4236C1 #403DC5 #3F46C8 #3F4ECB #3F57CE #3F5FD0 #4067CF #426FCE #4377CD #457ECB #4784C8 #4A8AC4 #4C90C0 #4F96BB #529BB5 #569FB0 #59A3AA #5DA8A4 #61AA9D #65AD97 #6AB090 #6EB389 #73B583 #78B77D #7EB877 #83BA71 #89BB6B #8FBC66 #94BD61 #9ABE5C #A0BE58 #A7BE54 #ADBD51 #B3BD4D #B8BC4A #BEBB48 #C4BA46 #C9B843 #CEB641 #D2B240 #D6AF3E #DBAC3D #DEA73B #E0A23A #E29C39 #E59738 #E69036 #E68835 #E68033 #E67832 #E56F30 #E4652E #E25B2C #E1512A #DF4628 #DE3C26 #DD3225 #DB2823 +#5E1D9D #541EA5 #4D21AD #4A28B3 #462FBA #4235C0 #403DC5 #3F45C8 #3F4DCB #3F56CE #3F5ED0 #4066CF #416DCE #4375CD #447DCC #4683C8 #4989C5 #4B8FC1 #4E95BD #5199B7 #549EB1 #58A2AC #5BA6A6 #5FA9A0 #64AC99 #68AF93 #6CB28C #71B486 #76B680 #7BB87A #80B973 #86BB6E #8CBB69 #91BC64 #97BD5F #9DBE5A #A3BE57 #A9BD53 #AFBD4F #B5BD4C #BABC49 #C0BA47 #C5B945 #CBB842 #CFB541 #D3B23F #D8AE3E #DCAB3C #DEA63B #E1A13A #E39B39 #E59638 #E68F36 #E68735 #E67F33 #E67732 #E56E30 #E4642E #E25A2C #E1502A #DF4628 #DE3C26 #DD3225 #DB2823 +#5E1D9D #541EA5 #4E21AD #4A28B3 #462EB9 #4335C0 #403CC5 #3F44C8 #3F4CCB #3F54CD #3E5DD0 #4064CF #416CCE #4273CE #447BCD #4681C9 #4887C6 #4B8DC2 #4D93BE #5098B9 #539CB3 #57A1AE #5AA5A8 #5EA8A2 #62AB9C #66AE95 #6AB18F #6FB388 #74B582 #79B77C #7EB876 #83BA70 #89BB6B #8EBC66 #94BD61 #9ABD5C #A0BE59 #A6BE55 #ABBD51 #B1BD4E #B7BD4B #BCBB49 #C2BA46 #C7B944 #CCB742 #D0B440 #D5B13F #D9AE3E #DDAA3C #DFA53B #E19F3A #E39A38 #E69537 #E68D36 #E68534 #E67E33 #E67631 #E56C30 #E4632E #E2592C #E14F2A #DF4528 #DE3C26 #DD3225 #DB2823 +#5E1D9D #541EA5 #4E21AC #4A27B3 #462EB9 #4334BF #403BC5 #3F43C7 #3F4BCA #3F53CD #3E5BD0 #3F63CF #416ACF #4272CE #4379CD #4580CA #4886C7 #4A8CC3 #4C92BF #4F97BB #529BB5 #569FAF #59A3AA #5CA7A4 #60AA9E #65AD98 #69B091 #6DB28B #72B485 #77B67F #7CB879 #81B973 #86BB6E #8BBB69 #91BC64 #97BD5F #9CBE5B #A2BE57 #A8BD53 #AEBD50 #B4BD4C #B9BC4A #BEBB48 #C4BA45 #C9B843 #CDB642 #D2B340 #D6B03F #DAAD3D #DDA93C #DFA43B #E29E39 #E49938 #E69437 #E68C36 #E68434 #E67C33 #E67531 #E56B2F #E3622D #E2582C #E14F2A #DF4528 #DE3B26 #DD3225 #DB2823 +#5E1D9D #551EA5 #4E21AC #4A27B2 #472DB8 #4334BF #403AC4 #4042C7 #3F4ACA #3F52CD #3E5ACF #3F62D0 #4169CF #4270CE #4378CD #457ECB #4784C7 #498AC4 #4C90C0 #4E96BC #519AB7 #559EB1 #58A2AC #5BA6A6 #5FA9A0 #63AC9A #67AF94 #6BB18E #6FB488 #74B582 #79B77C #7EB976 #83BA70 #89BB6B #8EBC67 #94BD62 #99BD5D #9FBE59 #A5BE56 #AABD52 #B0BD4F #B6BD4B #BBBC49 #C0BA47 #C5B945 #CBB842 #CFB541 #D3B240 #D7AF3E #DBAC3D #DEA83C #E0A23A #E29D39 #E49838 #E69237 #E68B35 #E68334 #E67B32 #E67431 #E56A2F #E3612D #E2582B #E04E2A #DF4528 #DE3B26 #DD3225 #DB2823 +#5E1D9D #551EA5 #4E21AC #4A27B2 #472DB8 #4333BE #403AC4 #4041C7 #3F49CA #3F51CC #3E59CF #3F60D0 #4068CF #426FCE #4376CD #447DCC #4783C8 #4989C5 #4B8EC1 #4E94BD #5098B8 #549DB3 #57A1AD #5AA5A8 #5DA8A2 #61AB9C #65AE96 #69B090 #6DB38A #72B584 #77B67E #7CB879 #81B973 #86BB6E #8BBB69 #91BC64 #96BD5F #9CBE5B #A1BE57 #A7BE54 #ADBD51 #B2BD4D #B8BC4B #BDBB48 #C2BA46 #C7B944 #CCB742 #D0B441 #D4B13F #D8AE3E #DCAB3C #DEA63B #E0A13A #E39C39 #E59738 #E69136 #E68935 #E68234 #E67A32 #E67331 #E5692F #E3602D #E2572B #E04E29 #DF4428 #DE3B26 #DD3124 #DB2823 +#5E1D9D #551EA5 #4E20AC #4B27B2 #472DB8 #4433BE #4039C4 #4041C7 #3F48C9 #3F50CC #3E58CF #3F5FD0 #4066CF #416ECE #4375CD #447CCD #4682C9 #4887C6 #4B8DC2 #4D92BE #5097BA #539BB5 #569FAF #59A3AA #5CA7A5 #60AA9F #64AD99 #68AF93 #6CB28D #70B487 #75B581 #7AB77B #7FB976 #83BA70 #89BB6B #8EBC67 #93BD62 #99BD5D #9EBE59 #A4BE56 #A9BD53 #AFBD4F #B4BD4C #BABC4A #BFBB48 #C4BA45 #C9B843 #CDB642 #D1B340 #D5B03F #D9AD3D #DDAA3C #DFA53B #E1A03A #E39B39 #E59638 #E68F36 #E68835 #E68133 #E67932 #E67231 #E4682F #E35F2D #E2562B #E04D29 #DF4428 #DE3B26 #DD3124 #DB2823 +#5E1D9D #551EA5 #4E20AC #4B26B1 #472CB7 #4432BD #4138C3 #4040C6 #3F47C9 #3F4FCC #3F57CE #3F5ED0 #4065CF #416CCE #4273CE #447ACD #4680CA #4886C6 #4A8BC3 #4C91BF #4F96BC #529AB6 #559EB1 #58A2AC #5BA6A6 #5FA9A1 #62AC9B #66AE95 #6AB18F #6EB389 #73B583 #78B67E #7CB878 #81B973 #86BB6E #8BBB69 #91BC64 #96BD60 #9BBE5B #A1BE58 #A6BE55 #ACBD51 #B1BD4E #B6BD4B #BBBC49 #C0BA47 #C5B945 #CAB843 #CEB541 #D2B240 #D6AF3E #DAAD3D #DDA93C #DFA43B #E19F3A #E39A38 #E69537 #E68E36 #E68735 #E68033 #E67832 #E67130 #E4682F #E35F2D #E2552B #E04C29 #DF4328 #DE3A26 #DD3124 #DB2823 +#5E1D9D #551EA4 #4E20AB #4B26B1 #472CB7 #4432BD #4138C3 #403FC6 #3F47C9 #3F4ECB #3F56CE #3E5DD0 #4064CF #416BCF #4272CE #4379CD #457FCB #4784C7 #498AC4 #4C8FC0 #4E95BD #5199B8 #549DB3 #57A1AD #5AA5A8 #5DA8A3 #61AB9D #65AD97 #69B091 #6CB28B #71B486 #76B680 #7AB77B #7FB975 #83BA70 #89BB6B #8EBC67 #93BD62 #98BD5E #9EBE5A #A3BE57 #A8BD53 #AEBD50 #B3BD4D #B8BC4A #BDBB48 #C2BA46 #C7B944 #CCB742 #D0B441 #D3B23F #D7AF3E #DBAC3D #DEA83C #E0A33A #E29E39 #E49938 #E69437 #E68D36 #E68634 #E67F33 #E67832 #E67030 #E4672E #E35E2D #E1552B #E04C29 #DF4328 #DE3A26 #DD3124 #DB2823 +#5E1D9D #551EA4 #4E20AB #4B26B1 #482CB7 #4432BC #4137C2 #403EC6 #3F46C8 #3F4DCB #3F55CD #3E5CD0 #3F63CF #416ACF #4270CE #4377CD #457ECC #4783C8 #4989C5 #4B8EC1 #4D93BE #5098B9 #539CB4 #569FAF #59A3AA #5CA7A5 #60AA9F #63AC99 #67AF94 #6BB18E #6FB388 #74B583 #78B67D #7DB878 #81BA72 #86BB6E #8BBB69 #90BC65 #96BD60 #9BBE5C #A0BE58 #A5BE55 #ABBD52 #B0BD4F #B5BD4C #BABC4A #BFBB48 #C4BA45 #C9B843 #CDB642 #D1B340 #D4B13F #D8AE3E #DCAB3C #DEA73B #E0A23A #E29D39 #E49838 #E69337 #E68C36 #E68534 #E67E33 #E67732 #E56F30 #E4662E #E35D2C #E1542B #E04B29 #DF4327 #DE3A26 #DD3124 #DB2823 +#5E1D9D #551EA4 #4E20AB #4B25B1 #482BB6 #4531BC #4137C2 #403EC6 #3F45C8 #3F4CCB #3F53CD #3E5BD0 #3F62D0 #4068CF #426FCE #4376CD #447DCC #4682C9 #4887C6 #4A8DC2 #4D92BF #4F97BB #529AB6 #559EB1 #58A2AC #5BA6A7 #5EA9A1 #62AB9C #66AE96 #69B090 #6DB38A #72B485 #76B680 #7BB77A #7FB975 #84BA70 #89BB6B #8EBC67 #93BC63 #98BD5E #9DBE5A #A2BE57 #A8BE54 #ADBD51 #B2BD4D #B7BD4B #BCBB49 #C1BA47 #C5B945 #CAB843 #CEB541 #D2B340 #D5B03F #D9AD3D #DDAA3C #DFA53B #E1A13A #E39C39 #E59738 #E69137 #E68B35 #E68434 #E67D33 #E67631 #E56E30 #E4652E #E35C2C #E1542B #E04B29 #DF4227 #DE3926 #DD3124 #DB2823 +#5E1D9D #561EA4 #4E20AB #4B25B1 #482BB6 #4531BC #4236C1 #403DC5 #3F44C8 #3F4BCA #3F52CD #3E5ACF #3F61D0 #4067CF #416ECE #4375CD #447BCD #4681CA #4886C6 #4A8BC3 #4C90C0 #4E96BC #5199B7 #549DB2 #57A1AD #5AA4A8 #5DA8A3 #61AA9E #64AD98 #68AF92 #6CB28D #70B487 #74B582 #79B77D #7DB878 #81BA72 #86BB6E #8BBB69 #90BC65 #95BD60 #9ABE5C #9FBE59 #A5BE56 #AABD52 #AFBD4F #B4BD4C #B9BC4A #BEBB48 #C2BA46 #C7B944 #CCB742 #CFB541 #D3B240 #D6AF3E #DAAD3D #DDA93C #DFA43B #E1A03A #E39B39 #E59638 #E69036 #E68935 #E68334 #E67C32 #E67531 #E56D30 #E4642E #E35C2C #E1532B #E04A29 #DF4227 #DE3926 #DD3124 #DB2823 +#5E1D9D #561EA4 #4F1FAB #4B25B0 #482BB6 #4530BB #4236C1 #403CC5 #3F43C8 #3F4ACA #3F52CC #3E59CF #3F5FD0 #4066CF #416DCE #4273CE #437ACD #457FCB #4785C7 #498AC4 #4B8FC1 #4E94BD #5098B9 #539CB4 #56A0AF #59A3AA #5CA7A5 #5FA9A0 #63AC9A #66AE95 #6AB18F #6EB38A #72B484 #77B67F #7BB77A #7FB975 #84BA70 #89BB6B #8EBC67 #93BC63 #97BD5E #9CBE5B #A2BE57 #A7BE54 #ACBD51 #B1BD4E #B6BD4B #BABC49 #BFBB47 #C4BA45 #C9B843 #CDB642 #D0B441 #D4B13F #D7AE3E #DBAC3D #DEA83C #E0A33B #E19F39 #E39A38 #E59537 #E68F36 #E68835 #E68234 #E67B32 #E67431 #E56C2F #E4632E #E25B2C #E1522A #E04A29 #DF4227 #DE3926 #DD3124 #DB2823 +#5E1D9D #561EA4 #4F1FAB #4C25B0 #482AB5 #4530BB #4236C0 #403CC5 #3F43C7 #3F4ACA #3F51CC #3E58CF #3F5ED0 #4065CF #416BCE #4272CE #4378CD #457ECB #4783C8 #4988C5 #4B8EC2 #4D93BE #4F97BA #529BB5 #559EB1 #58A2AC #5BA6A7 #5EA9A2 #61AB9C #65AD97 #69B091 #6CB28C #70B487 #75B581 #79B77C #7DB877 #82BA72 #86BB6D #8BBB69 #90BC65 #95BD61 #9ABD5D #9FBE59 #A4BE56 #A9BD53 #AEBD50 #B3BD4D #B8BC4B #BCBB49 #C1BA47 #C5B945 #CAB843 #CEB641 #D1B340 #D5B03F #D8AE3E #DCAB3C #DEA73B #E0A23A #E29E39 #E49938 #E69537 #E68E36 #E68735 #E68133 #E67A32 #E67331 #E56B2F #E4622E #E25A2C #E1522A #E04A29 #DF4127 #DE3926 #DD3024 #DB2823 +#5E1D9D #561EA4 #4F1FAB #4C25B0 #492AB5 #4530BB #4235C0 #403BC5 #4042C7 #3F49C9 #3F50CC #3F57CE #3E5DD0 #4064CF #416ACF #4271CE #4377CD #447DCC #4682C9 #4887C6 #4A8CC2 #4C91BF #4F96BC #519AB7 #549DB2 #57A1AD #5AA4A8 #5DA8A4 #60AA9E #64AC99 #67AF93 #6BB18E #6EB389 #73B584 #77B67F #7BB87A #80B974 #84BA70 #89BB6B #8DBC67 #92BC63 #97BD5F #9CBE5B #A1BE58 #A6BE55 #ABBD52 \ No newline at end of file diff --git a/rules/cattle-flu.smk b/rules/cattle-flu.smk index 8f20a90..ab01727 100644 --- a/rules/cattle-flu.smk +++ b/rules/cattle-flu.smk @@ -81,7 +81,7 @@ rule join_segments: rule genome_metadata: input: sequences = "results/{subtype}/{segment}/{time}/aligned.fasta", - metadata = "results/{subtype}/{segment}/{time}/metadata-with-clade-and-non-inferred-values.tsv", + metadata = metadata_by_wildcards, output: metadata = temp("results/{subtype}/{segment}/{time}/metadata_intermediate.tsv") wildcard_constraints: @@ -148,3 +148,33 @@ rule prune_tree: --output-tree {output.tree} \ --output-metadata {output.node_data} """ + +rule colors_genome: + # TODO: add these input files / params to the config YAML. The config YAML must also + # define the concept of whether this rule should run so this isn't trivial and is + # thus left as a to-do + input: + metadata = "results/{subtype}/{segment}/{time}/metadata.tsv", + ordering = "config/h5n1-cattle-outbreak/color_ordering.tsv", + schemes = "config/h5n1-cattle-outbreak/color_schemes.tsv", + colors = files.colors, + output: + colors = "results/{subtype}/{segment}/{time}/colors.tsv", + params: + duplications = "division=division_metadata", + wildcard_constraints: + subtype="h5n1-cattle-outbreak", + segment="genome", + time="default", + shell: + """ + cp {input.colors} {output.colors} && \ + python3 scripts/assign-colors.py \ + --metadata {input.metadata} \ + --ordering {input.ordering} \ + --color-schemes {input.schemes} \ + --duplications {params.duplications} \ + >> {output.colors} + """ + +ruleorder: colors_genome > colors diff --git a/scripts/assign-colors.py b/scripts/assign-colors.py new file mode 100644 index 0000000..a9018f0 --- /dev/null +++ b/scripts/assign-colors.py @@ -0,0 +1,79 @@ + +import argparse +from sys import stderr, stdout +from augur.io import read_metadata +import csv + +def parse_args(): + parser = argparse.ArgumentParser( + description="Assign colours based on ordering and metadata TSVs. Outputs a TSV on STDOUT.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter + ) + parser.add_argument('--ordering', type=str, required=True, metavar="TSV", + help="input ordering file. First column: category name, second column: value") + parser.add_argument('--color-schemes', type=str, required=True, metavar="TSV", + help="input color schemes file. Each line is a list of colour hexes, in order. Each line should have a different number of entries.") + parser.add_argument('--metadata', type=str, required=True, metavar="TSV", + help="restrict colors to only those found in metadata") + parser.add_argument('--duplications', type=str, required=False, nargs="+", metavar="categoryX=categoryY", + help="Duplicate the colours generated for categoryX under the name categoryY") + return parser.parse_args() + +def read_ordering(fname): + # copied from + assignment = {} + with open(fname) as f: + for line in f.readlines(): + array = line.lstrip().rstrip().split("\t") + if len(array) == 2: + name = array[0] + trait = array[1] + if name not in assignment: + assignment[name] = [trait] + else: + assignment[name].append(trait) + return assignment + +def read_schemes(fname): + # copied from + schemes = {} + counter = 0 + with open(args.color_schemes) as f: + for line in f.readlines(): + counter += 1 + array = line.lstrip().rstrip().split("\t") + schemes[counter] = array + return schemes + +def index_of(search_list, search_value, not_found_value): + try: + return search_list.index(search_value) + except ValueError: + return not_found_value + +if __name__ == '__main__': + args = parse_args() + metadata = read_metadata(args.metadata) + ordering = read_ordering(args.ordering) + schemes = read_schemes(args.color_schemes) + tsv_writer = csv.writer(stdout, delimiter='\t', lineterminator='\n') + duplications = {x.split('=')[0]: x.split('=')[1] for x in args.duplications} + + for category in ordering: + try: + observations = list(metadata[category].unique()) + except KeyError: + raise Exception(f"Ordering specified for '{category}' but this wasn't found in the metadata") + observations.sort(key=lambda x: index_of(ordering[category], x, len(ordering[category]))) + if (missing:=set(observations) - set(ordering[category])): + print(f"WARNING: For trait {category} we encountered {len(missing)} value(s) not present in the ordering TSV: {missing}", file=stderr) + try: + hexes = schemes[len(observations)] + except IndexError: + raise Exception(f"Ordering '{category}' had {len(observations)} values but the color-schemes don't go this high!") + for pair in zip(observations, hexes): + tsv_writer.writerow([category, *pair]) + + if category in duplications: + for pair in zip(observations, hexes): + tsv_writer.writerow([duplications[category], *pair]) From 4823e7aa120bd26393a48a44af93932c0985d1d7 Mon Sep 17 00:00:00 2001 From: james hadfield Date: Thu, 31 Oct 2024 17:06:25 +1300 Subject: [PATCH 5/5] [cattle-flu] consistent colours across segments It's possible segment-level builds will include a division not found in the genome build, but in this case Auspice will use a grey colour swatch which I think is acceptable. --- rules/cattle-flu.smk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rules/cattle-flu.smk b/rules/cattle-flu.smk index ab01727..2c0c762 100644 --- a/rules/cattle-flu.smk +++ b/rules/cattle-flu.smk @@ -154,7 +154,7 @@ rule colors_genome: # define the concept of whether this rule should run so this isn't trivial and is # thus left as a to-do input: - metadata = "results/{subtype}/{segment}/{time}/metadata.tsv", + metadata = "results/{subtype}/genome/{time}/metadata.tsv", # Always use the genome metadata, even for segment builds ordering = "config/h5n1-cattle-outbreak/color_ordering.tsv", schemes = "config/h5n1-cattle-outbreak/color_schemes.tsv", colors = files.colors, @@ -164,7 +164,6 @@ rule colors_genome: duplications = "division=division_metadata", wildcard_constraints: subtype="h5n1-cattle-outbreak", - segment="genome", time="default", shell: """