@sjcrh/proteinpaint-rust 2.195.0 → 2.196.0

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.
@@ -1,247 +0,0 @@
1
- // syntax:
2
- // echo '{"hdf5_file":"/path/to/my/local/file.h5"}' | ./target/release/validateHDF5
3
-
4
- use hdf5::types::{VarLenAscii, VarLenUnicode};
5
- use hdf5::{File, Result};
6
- use ndarray::Array1;
7
- use ndarray::Dim;
8
- use std::io;
9
-
10
- /// Detects the format of the HDF5 file
11
- pub fn detect_hdf5_format(hdf5_filename: &str) -> Result<&'static str> {
12
- let file = File::open(hdf5_filename)?;
13
-
14
- // Check for dense format (has counts, gene_names, and samples datasets)
15
- let has_counts = file.dataset("counts").is_ok();
16
- let has_gene_names = file.dataset("gene_names").is_ok();
17
- let has_samples = file.dataset("samples").is_ok();
18
-
19
- // Check for sparse matrix format (has data group and sample_names)
20
- let has_data_group = file.group("data").is_ok();
21
- let has_sample_names = file.dataset("sample_names").is_ok();
22
-
23
- // Check for promoter DNA methylation format (has meta/samples/names)
24
- let has_meta_sample_names = file.dataset("meta/samples/names").is_ok();
25
-
26
- if has_counts && has_gene_names && has_samples {
27
- // eprintln!("Dense format detected");
28
- Ok("dense")
29
- } else if has_data_group && has_sample_names {
30
- // eprintln!("Sparse format detected");
31
- Ok("sparse")
32
- } else if has_meta_sample_names {
33
- Ok("dna_meth_promoter")
34
- } else {
35
- // eprintln!("Unknown format detected");
36
- Ok("unknown")
37
- }
38
- }
39
-
40
- /// Validates and loads the HDF5 file
41
- pub fn validate_hdf5_file(hdf5_filename: String) -> Result<()> {
42
- // Open the HDF5 file
43
- let file = File::open(&hdf5_filename)?;
44
-
45
- // Detect file format
46
- let file_format = detect_hdf5_format(&hdf5_filename)?;
47
-
48
- // Get basic information about the file depending on format
49
- let output = match file_format {
50
- "dense" => {
51
- // For dense format, get dimensions from the counts dataset
52
- let ds_counts = file.dataset("counts")?;
53
- let data_shape = ds_counts.shape();
54
-
55
- // Read sample names using VarLenAscii
56
- let mut sample_names: Vec<String> = Vec::new();
57
- if let Ok(ds_samples) = file.dataset("samples") {
58
- if let Ok(samples) = ds_samples.read_1d::<VarLenAscii>() {
59
- for sample in samples.iter() {
60
- sample_names.push(sample.to_string());
61
- }
62
- } else {
63
- eprintln!("Error reading samples as VarLenAscii");
64
- }
65
- }
66
-
67
- // Read gene names using VarLenAscii
68
- let mut gene_names: Vec<String> = Vec::new();
69
- if let Ok(ds_genes) = file.dataset("gene_ids") {
70
- if let Ok(genes) = ds_genes.read_1d::<VarLenAscii>() {
71
- for gene in genes.iter() {
72
- gene_names.push(gene.to_string());
73
- }
74
- } else {
75
- eprintln!("Error reading gene_ids as VarLenAscii");
76
- }
77
- } else {
78
- eprintln!("Could not find 'gene_ids' dataset");
79
- }
80
-
81
- // Create JSON with both sample names and gene names
82
- serde_json::json!({
83
- "status": "success",
84
- "message": "HDF5 file loaded successfully",
85
- "file_path": hdf5_filename,
86
- "format": "dense",
87
- "sampleNames": sample_names,
88
- "matrix_dimensions": {
89
- "num_genes": data_shape[0],
90
- "num_samples": data_shape[1]
91
- }
92
- })
93
- }
94
- "sparse" => {
95
- // For sparse format, get dimensions from the data/dim dataset
96
- let ds_dim = file.dataset("data/dim")?;
97
- let data_dim: Array1<usize> = ds_dim.read::<usize, Dim<[usize; 1]>>()?;
98
- let num_samples = data_dim[0];
99
- let num_genes = data_dim[1];
100
-
101
- // Read sample names using VarLenAscii
102
- let mut sample_names: Vec<String> = Vec::new();
103
- if let Ok(ds_samples) = file.dataset("sample_names") {
104
- if let Ok(samples) = ds_samples.read_1d::<VarLenAscii>() {
105
- for sample in samples.iter() {
106
- sample_names.push(sample.to_string());
107
- }
108
- } else {
109
- eprintln!("Error reading sample_names as VarLenAscii");
110
- }
111
- }
112
-
113
- // Read gene names using VarLenAscii
114
- let mut gene_names: Vec<String> = Vec::new();
115
- if let Ok(ds_genes) = file.dataset("gene_names") {
116
- if let Ok(genes) = ds_genes.read_1d::<VarLenAscii>() {
117
- for gene in genes.iter() {
118
- gene_names.push(gene.to_string());
119
- }
120
- } else {
121
- eprintln!("Error reading gene_names as VarLenAscii");
122
- }
123
- } else {
124
- eprintln!("Could not find 'gene_names' dataset, trying alternatives");
125
- }
126
-
127
- // Create JSON with the same structure as dense format
128
- serde_json::json!({
129
- "status": "success",
130
- "message": "HDF5 file loaded successfully",
131
- "file_path": hdf5_filename,
132
- "format": "sparse",
133
- "sampleNames": sample_names,
134
- "matrix_dimensions": {
135
- "num_genes": num_genes,
136
- "num_samples": num_samples
137
- }
138
- })
139
- }
140
- "dna_meth_promoter" => {
141
- // For promoter DNA methylation format - only read sample names
142
- let mut sample_names: Vec<String> = Vec::new();
143
- if let Ok(ds_samples) = file.dataset("meta/samples/names") {
144
- if let Ok(samples) = ds_samples.read_1d::<VarLenUnicode>() {
145
- for sample in samples.iter() {
146
- sample_names.push(sample.to_string());
147
- }
148
- } else {
149
- eprintln!("Error reading meta/samples/names as VarLenUnicode");
150
- }
151
- }
152
-
153
- serde_json::json!({
154
- "status": "success",
155
- "message": "HDF5 promoter DNA methylation file loaded successfully",
156
- "file_path": hdf5_filename,
157
- "format": "dna_meth_promoter",
158
- "sampleNames": sample_names
159
- })
160
- }
161
- _ => {
162
- // For unknown format
163
- serde_json::json!({
164
- "status": "failure",
165
- "message": "Unknown file format cannot be loaded successfully",
166
- "file_path": hdf5_filename,
167
- "format": "unknown",
168
- "sampleNames": [],
169
- "geneNames": []
170
- })
171
- }
172
- };
173
-
174
- // Print the output
175
- println!("{}", output);
176
-
177
- Ok(())
178
- }
179
-
180
- /// Main function to handle the validation process
181
- fn main() -> Result<()> {
182
- let mut input = String::new();
183
- match io::stdin().read_line(&mut input) {
184
- Ok(_bytes_read) => {
185
- let input_json = json::parse(&input);
186
- match input_json {
187
- Ok(json_string) => {
188
- // Extract HDF5 filename
189
- let hdf5_filename = match json_string["hdf5_file"].as_str() {
190
- Some(x) => x.to_string(),
191
- None => {
192
- eprintln!("HDF5 filename not provided");
193
- println!(
194
- "{}",
195
- serde_json::json!({
196
- "status": "error",
197
- "message": "HDF5 filename not provided"
198
- })
199
- );
200
- return Ok(());
201
- }
202
- };
203
-
204
- // Log the start of validation
205
- // let start_time = Instant::now();
206
- // eprintln!("Starting validation of file: {}", hdf5_filename);
207
-
208
- // Run the validation
209
- if let Err(err) = validate_hdf5_file(hdf5_filename.clone()) {
210
- eprintln!("Error validating HDF5 file: {:?}", err);
211
- println!(
212
- "{}",
213
- serde_json::json!({
214
- "status": "error",
215
- "message": format!("Error validating HDF5 file: {}", err)
216
- })
217
- );
218
- }
219
-
220
- // Log completion time
221
- // eprintln!("Validation completed in: {:?}", start_time.elapsed());
222
- }
223
- Err(error) => {
224
- eprintln!("Incorrect JSON: {}", error);
225
- println!(
226
- "{}",
227
- serde_json::json!({
228
- "status": "error",
229
- "message": format!("Invalid JSON input: {}", error)
230
- })
231
- );
232
- }
233
- }
234
- }
235
- Err(error) => {
236
- eprintln!("Piping error: {}", error);
237
- println!(
238
- "{}",
239
- serde_json::json!({
240
- "status": "error",
241
- "message": format!("Error reading input: {}", error)
242
- })
243
- );
244
- }
245
- }
246
- Ok(())
247
- }