1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#[cfg(not(target_arch = "wasm32"))]
use std::{
fs::{DirBuilder, File},
io::Write,
path::PathBuf,
};
use failure::{format_err, Error};
use reqwest::{Client, Url};
#[cfg(test)]
mod tests;
fn root_url() -> Url {
if cfg!(target_arch = "wasm32") {
"http://127.0.0.1:3030/opendata/".parse().unwrap()
} else {
"http://opendata.web.cern.ch".parse().unwrap()
}
}
#[cfg(not(target_arch = "wasm32"))]
pub async fn download(base_dir: PathBuf, url: Url) -> Result<usize, Error> {
let mut dest = base_dir;
let mut sub_dir = url.path().to_owned();
sub_dir.remove(0);
dest.push(sub_dir);
if dest.exists() {
return Ok(0);
}
if let Some(dir) = dest.parent() {
DirBuilder::new().recursive(true).create(dir)?;
}
let mut n_retries = 3;
let bytes = loop {
let result = try_download(url.clone()).await;
if result.is_ok() || n_retries <= 0 {
break result;
} else {
n_retries -= 1;
}
}?;
let mut f = File::create(dest)?;
Ok(f.write(&bytes)?)
}
async fn try_download(url: Url) -> Result<Vec<u8>, Error> {
let resp = Client::new().get(url).send().await?;
Ok(resp
.error_for_status()?
.bytes()
.await?
.into_iter()
.collect())
}
#[cfg(not(target_arch = "wasm32"))]
pub fn data_dir() -> Result<PathBuf, Error> {
let mut dir = dirs::home_dir().ok_or_else(|| format_err!("No home directory"))?;
dir.push("lhc_open_data");
Ok(dir)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn test_file() -> Result<PathBuf, Error> {
let mut dir = data_dir()?;
dir.push("eos/opendata/alice/2010/LHC10h/000139038/ESD/0001/AliESDs.root");
Ok(dir)
}
#[cfg(not(target_arch = "wasm32"))]
pub fn all_files_10h() -> Result<Vec<PathBuf>, Error> {
let mut search_dir = data_dir()?;
search_dir.push("**/AliESDs.root");
let files: Vec<_> = glob::glob(search_dir.to_str().unwrap())
.expect("Can't resolve glob")
.map(|path| path.unwrap())
.collect();
Ok(files)
}
pub async fn get_file_list(run: u32) -> Result<Vec<Url>, Error> {
let uri = root_url().join(match run {
139_038 => "record/1102/files/ALICE_LHC10h_PbPb_ESD_139038_file_index.txt",
139_173 => "record/1103/files/ALICE_LHC10h_PbPb_ESD_139173_file_index.txt",
139_437 => "record/1104/files/ALICE_LHC10h_PbPb_ESD_139437_file_index.txt",
139_438 => "record/1105/files/ALICE_LHC10h_PbPb_ESD_139438_file_index.txt",
139_465 => "record/1106/files/ALICE_LHC10h_PbPb_ESD_139465_file_index.txt",
_ => return Err(format_err!("Invalid run number")),
})?;
let req = Client::new().get(uri);
let resp = req.send().await?;
if resp.status().is_success() {
let content = resp.text().await?;
content
.lines()
.map(|l| root_url().join(&l[26..]).map_err(Into::into))
.collect()
} else {
Err(format_err!("Could not download list of files"))
}
}