eva-sub-cli 0.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eva_sub_cli/__init__.py +27 -0
- eva_sub_cli/_version.py +21 -0
- eva_sub_cli/auth.py +106 -0
- eva_sub_cli/date_utils.py +32 -0
- eva_sub_cli/etc/EVA_Submission_template.xlsx +0 -0
- eva_sub_cli/etc/eva-biosamples.json +174 -0
- eva_sub_cli/etc/eva_logo.png +0 -0
- eva_sub_cli/etc/eva_schema.json +369 -0
- eva_sub_cli/etc/spreadsheet2json_conf.yaml +135 -0
- eva_sub_cli/exceptions/__init__.py +0 -0
- eva_sub_cli/exceptions/invalid_file_type_exception.py +4 -0
- eva_sub_cli/exceptions/submission_not_found_exception.py +4 -0
- eva_sub_cli/exceptions/submission_status_exception.py +5 -0
- eva_sub_cli/executables/__init__.py +0 -0
- eva_sub_cli/executables/check_fasta_insdc.py +159 -0
- eva_sub_cli/executables/check_metadata_semantics.py +18 -0
- eva_sub_cli/executables/cli.py +115 -0
- eva_sub_cli/executables/samples_checker.py +144 -0
- eva_sub_cli/executables/trim_down.py +78 -0
- eva_sub_cli/executables/xlsx2json.py +335 -0
- eva_sub_cli/file_utils.py +117 -0
- eva_sub_cli/jinja_templates/fasta_check.html +86 -0
- eva_sub_cli/jinja_templates/file_validation.html +93 -0
- eva_sub_cli/jinja_templates/html_report.html +142 -0
- eva_sub_cli/jinja_templates/metadata_validation.html +52 -0
- eva_sub_cli/jinja_templates/project_details.html +37 -0
- eva_sub_cli/jinja_templates/sample_name_check.html +60 -0
- eva_sub_cli/jinja_templates/shallow_validation.html +29 -0
- eva_sub_cli/metadata_utils.py +46 -0
- eva_sub_cli/nextflow/validation.nf +303 -0
- eva_sub_cli/orchestrator.py +233 -0
- eva_sub_cli/report.py +40 -0
- eva_sub_cli/semantic_metadata.py +243 -0
- eva_sub_cli/submission_ws.py +61 -0
- eva_sub_cli/submit.py +111 -0
- eva_sub_cli/validators/__init__.py +0 -0
- eva_sub_cli/validators/docker_validator.py +205 -0
- eva_sub_cli/validators/native_validator.py +68 -0
- eva_sub_cli/validators/validation_results_parsers.py +210 -0
- eva_sub_cli/validators/validator.py +510 -0
- eva_sub_cli-0.4.4.dist-info/METADATA +164 -0
- eva_sub_cli-0.4.4.dist-info/RECORD +46 -0
- eva_sub_cli-0.4.4.dist-info/WHEEL +5 -0
- eva_sub_cli-0.4.4.dist-info/entry_points.txt +7 -0
- eva_sub_cli-0.4.4.dist-info/licenses/LICENSE +201 -0
- eva_sub_cli-0.4.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
from eva_sub_cli.semantic_metadata import SemanticMetadataChecker
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
arg_parser = argparse.ArgumentParser(description='Perform semantic checks on the metadata')
|
|
9
|
+
arg_parser.add_argument('--metadata_json', required=True, dest='metadata_json', help='EVA metadata json file')
|
|
10
|
+
arg_parser.add_argument('--output_yaml', required=True, dest='output_yaml',
|
|
11
|
+
help='Path to the location of the results')
|
|
12
|
+
args = arg_parser.parse_args()
|
|
13
|
+
|
|
14
|
+
with open(args.metadata_json) as open_json:
|
|
15
|
+
metadata = json.load(open_json)
|
|
16
|
+
checker = SemanticMetadataChecker(metadata)
|
|
17
|
+
checker.check_all()
|
|
18
|
+
checker.write_result_yaml(args.output_yaml)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import eva_sub_cli
|
|
4
|
+
from eva_sub_cli.exceptions.submission_not_found_exception import SubmissionNotFoundException
|
|
5
|
+
from eva_sub_cli.exceptions.submission_status_exception import SubmissionStatusException
|
|
6
|
+
|
|
7
|
+
if not sys.warnoptions:
|
|
8
|
+
import warnings
|
|
9
|
+
warnings.simplefilter("ignore")
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
from argparse import ArgumentParser
|
|
14
|
+
from ebi_eva_common_pyutils.logger import logging_config
|
|
15
|
+
|
|
16
|
+
from eva_sub_cli import orchestrator
|
|
17
|
+
from eva_sub_cli.orchestrator import VALIDATE, SUBMIT, DOCKER, NATIVE
|
|
18
|
+
from eva_sub_cli.file_utils import is_submission_dir_writable, DirLockError, DirLock
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def validate_command_line_arguments(args, argparser):
|
|
22
|
+
if (args.vcf_files and not args.reference_fasta) or (not args.vcf_files and args.reference_fasta):
|
|
23
|
+
print("When using --vcf_files and --reference_fasta, both need to be specified")
|
|
24
|
+
argparser.print_usage()
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
|
|
27
|
+
if SUBMIT in args.tasks and (
|
|
28
|
+
not (args.username or os.environ.get('ENAWEBINACCOUNT')) or
|
|
29
|
+
not (args.password or os.environ.get('ENAWEBINPASSWORD'))):
|
|
30
|
+
print("To submit your data, you need to provide a Webin username and password")
|
|
31
|
+
argparser.print_usage()
|
|
32
|
+
sys.exit(1)
|
|
33
|
+
|
|
34
|
+
if not is_submission_dir_writable(args.submission_dir):
|
|
35
|
+
print(f"'{args.submission_dir}' does not have write permissions or is not a directory.")
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def parse_args(cmd_line_args):
|
|
40
|
+
argparser = ArgumentParser(prog='eva-sub-cli',
|
|
41
|
+
description='EVA Submission CLI - validate and submit data to EVA. '
|
|
42
|
+
'For full details, please see https://github.com/EBIvariation/eva-sub-cli')
|
|
43
|
+
argparser.add_argument('--version', action='version', version=f'%(prog)s {eva_sub_cli.__version__}')
|
|
44
|
+
argparser.add_argument('--submission_dir', required=True, type=str,
|
|
45
|
+
help='Path to the directory where all processing is done and submission info is stored')
|
|
46
|
+
vcf_group = argparser.add_argument_group(
|
|
47
|
+
'Input VCF and assembly',
|
|
48
|
+
"Specify the VCF files and associated assembly with the following options. If you used different assemblies "
|
|
49
|
+
"for different VCF files, then you must include these in the metadata file rather than specifying them here."
|
|
50
|
+
)
|
|
51
|
+
vcf_group.add_argument('--vcf_files', nargs='+', help="One or more VCF files to validate")
|
|
52
|
+
vcf_group.add_argument('--reference_fasta',
|
|
53
|
+
help="The FASTA file containing the reference genome from which the variants were derived")
|
|
54
|
+
|
|
55
|
+
metadata_group = argparser.add_argument_group('Metadata', 'Specify the metadata in a spreadsheet or in a JSON file')
|
|
56
|
+
metadata_group = metadata_group.add_mutually_exclusive_group(required=True)
|
|
57
|
+
metadata_group.add_argument("--metadata_json",
|
|
58
|
+
help="JSON file that describes the project, analysis, samples and files")
|
|
59
|
+
metadata_group.add_argument("--metadata_xlsx",
|
|
60
|
+
help="Excel spreadsheet that describes the project, analysis, samples and files")
|
|
61
|
+
argparser.add_argument('--tasks', nargs='+', choices=[VALIDATE, SUBMIT], default=[SUBMIT], type=str.lower,
|
|
62
|
+
help='Select a task to perform (default SUBMIT). VALIDATE will run the validation'
|
|
63
|
+
' regardless of the outcome of previous runs. SUBMIT will run validate only if'
|
|
64
|
+
' the validation was not performed successfully before and then run the submission.')
|
|
65
|
+
argparser.add_argument('--executor', choices=[DOCKER, NATIVE], default=NATIVE, type=str.lower,
|
|
66
|
+
help='Select the execution type for running validation (default native)')
|
|
67
|
+
credential_group = argparser.add_argument_group('Credentials', 'Specify the ENA Webin credentials you want to use '
|
|
68
|
+
'to submit to the EVA')
|
|
69
|
+
credential_group.add_argument("--username", help="Username for your ENA Webin account")
|
|
70
|
+
credential_group.add_argument("--password", help="Password for your ENA Webin account")
|
|
71
|
+
argparser.add_argument('--shallow', action='store_true', default=False, dest='shallow_validation',
|
|
72
|
+
help='Set the validation to be performed on the first 10000 records of the VCF. '
|
|
73
|
+
'Only applies if the number of records exceed 10000')
|
|
74
|
+
argparser.add_argument('--debug', action='store_true', default=False,
|
|
75
|
+
help='Set the script to output debug messages')
|
|
76
|
+
args = argparser.parse_args(cmd_line_args)
|
|
77
|
+
validate_command_line_arguments(args, argparser)
|
|
78
|
+
return args
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def main():
|
|
82
|
+
exit_status = 0
|
|
83
|
+
args = parse_args(sys.argv[1:])
|
|
84
|
+
|
|
85
|
+
args.submission_dir = os.path.abspath(args.submission_dir)
|
|
86
|
+
|
|
87
|
+
if args.debug:
|
|
88
|
+
logging_config.add_stdout_handler(logging.DEBUG)
|
|
89
|
+
else:
|
|
90
|
+
logging_config.add_stdout_handler(logging.INFO)
|
|
91
|
+
|
|
92
|
+
try:
|
|
93
|
+
# lock the submission directory
|
|
94
|
+
|
|
95
|
+
with DirLock(os.path.join(args.submission_dir)) as lock:
|
|
96
|
+
# Create the log file
|
|
97
|
+
logging_config.add_file_handler(os.path.join(args.submission_dir, 'eva_submission.log'), logging.DEBUG)
|
|
98
|
+
# Pass on all the arguments to the orchestrator
|
|
99
|
+
orchestrator.orchestrate_process(**args.__dict__)
|
|
100
|
+
except DirLockError:
|
|
101
|
+
print(f'Could not acquire the lock file for {args.submission_dir} because another process is using this '
|
|
102
|
+
f'directory or a previous process did not terminate correctly. '
|
|
103
|
+
f'If the problem persists, remove the lock file manually.')
|
|
104
|
+
exit_status = 65
|
|
105
|
+
except FileNotFoundError as fne:
|
|
106
|
+
print(fne)
|
|
107
|
+
exit_status = 66
|
|
108
|
+
except SubmissionNotFoundException as snfe:
|
|
109
|
+
print(f'{snfe}. Please contact EVA Helpdesk')
|
|
110
|
+
exit_status = 67
|
|
111
|
+
except SubmissionStatusException as sse:
|
|
112
|
+
print(f'{sse}. Please try again later. If the problem persists, please contact EVA Helpdesk')
|
|
113
|
+
exit_status = 68
|
|
114
|
+
return exit_status
|
|
115
|
+
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import gzip
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
from ebi_eva_common_pyutils.logger import logging_config
|
|
7
|
+
|
|
8
|
+
import yaml
|
|
9
|
+
|
|
10
|
+
from eva_sub_cli.file_utils import open_gzip_if_required
|
|
11
|
+
from eva_sub_cli.metadata_utils import get_samples_per_analysis, get_files_per_analysis, get_analysis_for_vcf_file
|
|
12
|
+
|
|
13
|
+
logger = logging_config.get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_samples_from_vcf(vcf_file):
|
|
17
|
+
"""
|
|
18
|
+
Get the list of samples present in a single VCF file
|
|
19
|
+
"""
|
|
20
|
+
with open_gzip_if_required(vcf_file) as vcf_in:
|
|
21
|
+
for line in vcf_in:
|
|
22
|
+
if line.startswith('#CHROM'):
|
|
23
|
+
sp_line = line.strip().split('\t')
|
|
24
|
+
if len(sp_line) > 9:
|
|
25
|
+
return sp_line[9:]
|
|
26
|
+
else:
|
|
27
|
+
logger.warning(f"No Sample names found in file {vcf_file}")
|
|
28
|
+
return []
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def compare_names_in_files_and_samples(sample_name_in_analysis, sample_name_per_file):
|
|
32
|
+
"""
|
|
33
|
+
Compare the sample names provided in vcf files and the one provided in a set of sample rows.
|
|
34
|
+
This is meant to compare the samples and files provided for a single analysis.
|
|
35
|
+
"""
|
|
36
|
+
has_difference = False
|
|
37
|
+
sample_names_in_vcf = set(
|
|
38
|
+
sample_name
|
|
39
|
+
for sample_name_list in sample_name_per_file.values()
|
|
40
|
+
for sample_name in sample_name_list
|
|
41
|
+
)
|
|
42
|
+
more_metadata_submitted_files = list(set(sample_name_in_analysis) - sample_names_in_vcf)
|
|
43
|
+
more_submitted_files_metadata = list(sample_names_in_vcf - set(sample_name_in_analysis))
|
|
44
|
+
more_per_submitted_files_metadata = {}
|
|
45
|
+
if more_submitted_files_metadata:
|
|
46
|
+
for file_name in sample_name_per_file:
|
|
47
|
+
more_per_submitted_files_metadata[os.path.basename(file_name)] = list(set(sample_name_per_file[file_name]) - set(sample_name_in_analysis))
|
|
48
|
+
has_difference = True
|
|
49
|
+
|
|
50
|
+
if more_metadata_submitted_files:
|
|
51
|
+
has_difference = True
|
|
52
|
+
|
|
53
|
+
return (has_difference, more_per_submitted_files_metadata, more_submitted_files_metadata,
|
|
54
|
+
more_metadata_submitted_files)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def compare_all_analysis(samples_per_analysis, files_per_analysis):
|
|
58
|
+
overall_differences = False
|
|
59
|
+
results_per_analysis_alias = {}
|
|
60
|
+
all_analysis_alias = set(samples_per_analysis) | set(files_per_analysis)
|
|
61
|
+
for analysis_alias in all_analysis_alias:
|
|
62
|
+
sample_name_in_analysis = samples_per_analysis.get(analysis_alias, [])
|
|
63
|
+
sample_name_per_file = {
|
|
64
|
+
file_path: get_samples_from_vcf(file_path)
|
|
65
|
+
for file_path in files_per_analysis.get(analysis_alias, [])
|
|
66
|
+
}
|
|
67
|
+
(
|
|
68
|
+
has_difference, more_per_submitted_files_metadata,
|
|
69
|
+
more_submitted_files_metadata, more_metadata_submitted_files
|
|
70
|
+
) = compare_names_in_files_and_samples(sample_name_in_analysis, sample_name_per_file)
|
|
71
|
+
overall_differences = overall_differences or has_difference
|
|
72
|
+
results_per_analysis_alias[analysis_alias] = {
|
|
73
|
+
'difference': has_difference,
|
|
74
|
+
'more_per_submitted_files_metadata': more_per_submitted_files_metadata,
|
|
75
|
+
'more_submitted_files_metadata': more_submitted_files_metadata,
|
|
76
|
+
'more_metadata_submitted_files': more_metadata_submitted_files
|
|
77
|
+
}
|
|
78
|
+
return overall_differences, results_per_analysis_alias
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def read_metadata_json(json_file):
|
|
82
|
+
with open(json_file) as open_json:
|
|
83
|
+
metadata = json.load(open_json)
|
|
84
|
+
return get_samples_per_analysis(metadata), get_files_per_analysis(metadata)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def associate_vcf_path_with_analysis(vcf_files, files_per_analysis):
|
|
88
|
+
"""
|
|
89
|
+
Match the files names associated with analysis provided in the metadata with the file path given on the command
|
|
90
|
+
line.
|
|
91
|
+
:param vcf_files the list of full path to the vcf files
|
|
92
|
+
:param files_per_analysis: dictionary of the analysis and their associated VCF file names
|
|
93
|
+
:returns dictionary of analysis and their associated vcf file path
|
|
94
|
+
"""
|
|
95
|
+
result_files_per_analysis = dict()
|
|
96
|
+
for analysis in files_per_analysis:
|
|
97
|
+
result_files_per_analysis[analysis] = []
|
|
98
|
+
for vcf_file in vcf_files:
|
|
99
|
+
analysis_aliases = get_analysis_for_vcf_file(vcf_file, files_per_analysis)
|
|
100
|
+
if len(analysis_aliases) == 1:
|
|
101
|
+
result_files_per_analysis[analysis_aliases[0]].append(vcf_file)
|
|
102
|
+
elif len(analysis_aliases) == 0:
|
|
103
|
+
logger.error(f'No analysis found for vcf {vcf_file}')
|
|
104
|
+
if 'No analysis' not in result_files_per_analysis:
|
|
105
|
+
result_files_per_analysis['No analysis'] = []
|
|
106
|
+
result_files_per_analysis['No analysis'].append(vcf_file)
|
|
107
|
+
else:
|
|
108
|
+
logger.error(f'More than one analysis were match to vcf {vcf_file}')
|
|
109
|
+
|
|
110
|
+
return result_files_per_analysis
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def write_result_yaml(output_yaml, overall_differences, results_per_analysis_alias):
|
|
114
|
+
with open(output_yaml, 'w') as open_yaml:
|
|
115
|
+
yaml.safe_dump(data={
|
|
116
|
+
'overall_differences': overall_differences,
|
|
117
|
+
'results_per_analysis': results_per_analysis_alias
|
|
118
|
+
}, stream=open_yaml)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def check_sample_name_concordance(metadata_json, vcf_files, output_yaml):
|
|
122
|
+
"""
|
|
123
|
+
Take the metadata following EVA standard and formatted in JSON then compare the sample names in it to the ones
|
|
124
|
+
found in the VCF files
|
|
125
|
+
"""
|
|
126
|
+
samples_per_analysis, files_per_analysis = read_metadata_json(metadata_json)
|
|
127
|
+
file_path_per_analysis = associate_vcf_path_with_analysis(vcf_files, files_per_analysis)
|
|
128
|
+
overall_differences, results_per_analysis_alias = compare_all_analysis(samples_per_analysis, file_path_per_analysis)
|
|
129
|
+
write_result_yaml(output_yaml, overall_differences, results_per_analysis_alias)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def main():
|
|
133
|
+
arg_parser = argparse.ArgumentParser(
|
|
134
|
+
description='Compare the sample name in the VCF file and the one specified in the metadata.')
|
|
135
|
+
arg_parser.add_argument('--metadata_json', required=True, dest='metadata_json',
|
|
136
|
+
help='EVA metadata json file')
|
|
137
|
+
arg_parser.add_argument('--vcf_files', dest='vcf_files', nargs='+',
|
|
138
|
+
help='Path to the vcf files to compare to the metadata')
|
|
139
|
+
arg_parser.add_argument('--output_yaml', required=True, dest='output_yaml',
|
|
140
|
+
help='Path to the location of the results')
|
|
141
|
+
|
|
142
|
+
args = arg_parser.parse_args()
|
|
143
|
+
logging_config.add_stdout_handler()
|
|
144
|
+
check_sample_name_concordance(args.metadata_json, args.vcf_files, args.output_yaml)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
from ebi_eva_common_pyutils.logger import logging_config
|
|
6
|
+
from eva_sub_cli.file_utils import open_gzip_if_required, fasta_iter
|
|
7
|
+
|
|
8
|
+
logger = logging_config.get_logger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
max_nb_lines = 10000
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def trim_down_vcf(vcf_file, output_vcf):
|
|
15
|
+
"""
|
|
16
|
+
Produce a smaller vcf files containing a maximum of 10000 records
|
|
17
|
+
"""
|
|
18
|
+
with open_gzip_if_required(vcf_file) as vcf_in, open(output_vcf, 'w') as vcf_out:
|
|
19
|
+
line_count = 0
|
|
20
|
+
ref_seq_names = set()
|
|
21
|
+
for line in vcf_in:
|
|
22
|
+
if line.startswith('#') or line_count < max_nb_lines:
|
|
23
|
+
vcf_out.write(line)
|
|
24
|
+
if not line.startswith('#'):
|
|
25
|
+
line_count += 1
|
|
26
|
+
ref_seq_names.add(line.split('\t')[0])
|
|
27
|
+
else:
|
|
28
|
+
break
|
|
29
|
+
if line_count != max_nb_lines:
|
|
30
|
+
logger.warning(f'Only {line_count} found in the source VCF {vcf_file} ')
|
|
31
|
+
return line_count, ref_seq_names
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def trim_down_fasta(fasta_file, output_fasta, ref_seq_names):
|
|
35
|
+
"""
|
|
36
|
+
Produce a smaller fasta files containing only the reference sequences found in the VCF file
|
|
37
|
+
"""
|
|
38
|
+
found_sequences = set()
|
|
39
|
+
with open(output_fasta, 'w') as fasta_out:
|
|
40
|
+
for header, sequence in fasta_iter(fasta_file):
|
|
41
|
+
name = header.split()[0]
|
|
42
|
+
if name in ref_seq_names:
|
|
43
|
+
found_sequences.add(name)
|
|
44
|
+
print(f'>{header}', file=fasta_out)
|
|
45
|
+
for i in range(0, len(sequence), 80):
|
|
46
|
+
print(sequence[i:i+80], file=fasta_out)
|
|
47
|
+
return found_sequences
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main():
|
|
51
|
+
arg_parser = argparse.ArgumentParser(
|
|
52
|
+
description=f'Take a VCF file and only keep {max_nb_lines} lines and remove unused fasta sequence from the '
|
|
53
|
+
f'associated reference genome')
|
|
54
|
+
arg_parser.add_argument('--vcf_file', dest='vcf_file', required=True,
|
|
55
|
+
help='Path to the vcf file to be trimmed down')
|
|
56
|
+
arg_parser.add_argument('--output_vcf_file', dest='output_vcf_file', required=True,
|
|
57
|
+
help='Path to the output vcf file')
|
|
58
|
+
arg_parser.add_argument('--fasta_file', dest='fasta_file', required=True,
|
|
59
|
+
help='Path to the fasta file to be trimmed down')
|
|
60
|
+
arg_parser.add_argument('--output_fasta_file', dest='output_fasta_file', required=True,
|
|
61
|
+
help='Path to the output fasta file')
|
|
62
|
+
arg_parser.add_argument('--output_yaml_file', dest='output_yaml_file', required=True,
|
|
63
|
+
help='Path to the yaml file containing the trim down metrics')
|
|
64
|
+
|
|
65
|
+
args = arg_parser.parse_args()
|
|
66
|
+
logging_config.add_stdout_handler()
|
|
67
|
+
|
|
68
|
+
line_count, ref_sequence = trim_down_vcf(args.vcf_file, args.output_vcf_file)
|
|
69
|
+
sequence_found = trim_down_fasta(args.fasta_file, args.output_fasta_file, ref_sequence)
|
|
70
|
+
trim_down_metrics = {'trim_down_vcf_record': line_count, 'number_sequence_found': sequence_found,
|
|
71
|
+
'trim_down_required': line_count == max_nb_lines}
|
|
72
|
+
if len(sequence_found) != len(ref_sequence):
|
|
73
|
+
logger.warning(f'Not all sequences were found in the fasta file. Cancelling trimming down of fasta file')
|
|
74
|
+
os.link(args.fasta_file, args.output_fasta_file)
|
|
75
|
+
trim_down_metrics.pop('number_sequence_found')
|
|
76
|
+
with open(args.output_yaml_file) as open_file:
|
|
77
|
+
yaml.safe_dump(trim_down_metrics, open_file)
|
|
78
|
+
|