Skip to content

Commit

Permalink
more anyhow
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Patro committed May 7, 2022
1 parent a0ef51d commit c3b7752
Showing 1 changed file with 47 additions and 33 deletions.
80 changes: 47 additions & 33 deletions src/collate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ pub fn collate(
version_str: &str,
//expected_ori: Strand,
log: &slog::Logger,
) -> anyhow::Result<()> { //}, Box<dyn std::error::Error>> {
) -> anyhow::Result<()> {
//}, Box<dyn std::error::Error>> {
let parent = std::path::Path::new(&input_dir);

// open the metadata file and read the json
let gpl_path = parent.join("generate_permit_list.json");
let meta_data_file =
File::open(&gpl_path).with_context( ||
format!("Could not open the file {:?}.", gpl_path)[..])?;
let meta_data_file = File::open(&gpl_path)
.with_context(|| format!("Could not open the file {:?}.", gpl_path.display()))?;
let mdata: serde_json::Value = serde_json::from_reader(meta_data_file)?;

let calling_version = InternalVersionInfo::from_str(version_str)?;
Expand All @@ -60,11 +60,11 @@ pub fn collate(
vd = InternalVersionInfo::from_str(s)?;
}
None => {
return Err("The version_str field must be a string".into());
return Err(anyhow!("The version_str field must be a string"));
}
},
None => {
return Err("The generate_permit_list.json file does not contain a version_str field. Please re-run the generate-permit-list step with a newer version of alevin-fry".into());
return Err(anyhow!("The generate_permit_list.json file does not contain a version_str field. Please re-run the generate-permit-list step with a newer version of alevin-fry"));
}
};

Expand All @@ -88,8 +88,11 @@ pub fn collate(

// read header
let mut rdr = BufReader::new(&freq_file);
rdr.read_exact(&mut rbuf).context("couldn't read freq file header")?;
let freq_file_version = rbuf.pread::<u64>(0).context("couldn't read freq file version")?;
rdr.read_exact(&mut rbuf)
.context("couldn't read freq file header")?;
let freq_file_version = rbuf
.pread::<u64>(0)
.context("couldn't read freq file version")?;
// make sure versions match
if freq_file_version > afconst::PERMIT_FILE_VER {
crit!(log,
Expand All @@ -100,12 +103,15 @@ pub fn collate(
}

// read the barcode length
rdr.read_exact(&mut rbuf).context("couldn't read freq file buffer")?;
let _bc_len = rbuf.pread::<u64>(0).context("couldn't read freq file barcode length")?;
rdr.read_exact(&mut rbuf)
.context("couldn't read freq file buffer")?;
let _bc_len = rbuf
.pread::<u64>(0)
.context("couldn't read freq file barcode length")?;

// read the barcode -> frequency hashmap
let freq_hm: HashMap<u64, u64> = bincode::deserialize_from(rdr).context(
"couldn't deserialize barcode to frequency map.")?;
let freq_hm: HashMap<u64, u64> =
bincode::deserialize_from(rdr).context("couldn't deserialize barcode to frequency map.")?;
let total_to_collate = freq_hm.values().sum();
let mut tsv_map = Vec::from_iter(freq_hm.into_iter());

Expand Down Expand Up @@ -251,7 +257,8 @@ pub fn collate_with_temp(
cmdline: &str,
version: &str,
log: &slog::Logger,
) -> anyhow::Result<()> { //Box<dyn std::error::Error>> {
) -> anyhow::Result<()> {
//Box<dyn std::error::Error>> {
// the number of corrected cells we'll write
let expected_output_chunks = tsv_map.len() as u64;
// the parent input directory
Expand All @@ -265,11 +272,13 @@ pub fn collate_with_temp(

// open the metadata file and read the json
let meta_data_file = File::open(parent.join("generate_permit_list.json"))
.expect("could not open the generate_permit_list.json file.");
.context("could not open the generate_permit_list.json file.")?;
let mdata: serde_json::Value = serde_json::from_reader(&meta_data_file)?;

// velo_mode
let velo_mode = mdata["velo_mode"].as_bool().unwrap();
let velo_mode = mdata["velo_mode"]
.as_bool()
.context("couldn't read velo_mode from meta data")?;
let expected_ori: Strand = match get_orientation(&mdata) {
Ok(o) => o,
Err(e) => {
Expand All @@ -279,7 +288,7 @@ pub fn collate_with_temp(
&meta_data_file,
e
);
return Err(e.into());
return Err(anyhow!(e));
}
};

Expand Down Expand Up @@ -312,32 +321,35 @@ pub fn collate_with_temp(
});

let cm_path = parent.join("collate.json");
let mut cm_file = std::fs::File::create(&cm_path).expect("could not create metadata file.");
let mut cm_file =
std::fs::File::create(&cm_path).context("could not create metadata file.")?;

let cm_info_string =
serde_json::to_string_pretty(&collate_meta).expect("could not format json.");
serde_json::to_string_pretty(&collate_meta).context("could not format json.")?;
cm_file
.write_all(cm_info_string.as_bytes())
.expect("cannot write to collate.json file");
.context("cannot write to collate.json file")?;
}

let oname = parent.join(cfname);
if oname.exists() {
std::fs::remove_file(oname)?;
std::fs::remove_file(&oname)
.with_context(|| format!("could not remove {}", oname.display()))?;
}

let ofile = File::create(parent.join(cfname)).unwrap();
let ofile = File::create(parent.join(cfname))
.with_context(|| format!("couldn't create directory {}", cfname))?;
let owriter = Arc::new(Mutex::new(BufWriter::with_capacity(1048576, ofile)));

let i_dir = std::path::Path::new(&rad_dir);

if !i_dir.exists() {
crit!(log, "the input RAD path {} does not exist", rad_dir);
return Err("invalid input".into());
return Err(anyhow!("invalid input"));
}

let input_rad_path = i_dir.join("map.rad");
let i_file = File::open(&input_rad_path).unwrap();
let i_file = File::open(&input_rad_path).context("couldn't open input RAD file")?;
let mut br = BufReader::new(i_file);

let hdr = rad_types::RadHeader::from_bytes(&mut br);
Expand Down Expand Up @@ -385,16 +397,16 @@ pub fn collate_with_temp(

// This temporary file pointer and buffer will be dropped
// at the end of this block (scope).
let mut rfile = File::open(&input_rad_path).unwrap();
let mut rfile = File::open(&input_rad_path).context("Couldn't open input RAD file")?;
let mut hdr_buf = Cursor::new(vec![0u8; pos as usize]);

rfile
.read_exact(hdr_buf.get_mut())
.expect("couldn't read input file header");
.context("couldn't read input file header")?;
hdr_buf.set_position(take_pos);
hdr_buf
.write_all(&expected_output_chunks.to_le_bytes())
.expect("couldn't write num_chunks");
.context("couldn't write num_chunks")?;
hdr_buf.set_position(0);

// compress the header buffer to a compressed buffer
Expand All @@ -403,21 +415,22 @@ pub fn collate_with_temp(
snap::write::FrameEncoder::new(Cursor::new(Vec::<u8>::with_capacity(pos as usize)));
compressed_buf
.write_all(hdr_buf.get_ref())
.expect("could not compress the output header.");
.context("could not compress the output header.")?;
hdr_buf = compressed_buf
.into_inner()
.expect("couldn't unwrap the FrameEncoder.");
.context("couldn't unwrap the FrameEncoder.")?;
hdr_buf.set_position(0);
}

if let Ok(mut oput) = owriter.lock() {
oput.write_all(hdr_buf.get_ref())
.expect("could not write the output header.");
.context("could not write the output header.")?;
}
}

// get the correction map
let cmfile = std::fs::File::open(parent.join("permit_map.bin")).unwrap();
let cmfile = std::fs::File::open(parent.join("permit_map.bin"))
.context("couldn't open output permit_map.bin file")?;
let correct_map: Arc<HashMap<u64, u64>> = Arc::new(bincode::deserialize_from(&cmfile).unwrap());

// NOTE: the assumption of where the unmapped file will be
Expand Down Expand Up @@ -644,7 +657,7 @@ pub fn collate_with_temp(
.lock()
.unwrap()
.flush()
.expect("could not flush temporary output file!");
.context("could not flush temporary output file!")?;
// a sanity check that we have the correct number of records
// and the expected number of bytes in each file
let expected = temp_bucket.1;
Expand Down Expand Up @@ -687,9 +700,10 @@ pub fn collate_with_temp(
// the number of chunks remaining to be processed
let buckets_remaining = buckets_to_process.clone();
// and knowledge of the UMI and BC types
let bc_type = rad_types::decode_int_type_tag(cc.bc_type).expect("unknown barcode type id.");
let bc_type =
rad_types::decode_int_type_tag(cc.bc_type).context("unknown barcode type id.")?;
let umi_type =
rad_types::decode_int_type_tag(cc.umi_type).expect("unknown barcode type id.");
rad_types::decode_int_type_tag(cc.umi_type).context("unknown barcode type id.")?;
// have access to the input directory
let input_dir = input_dir.clone();
// the output file
Expand Down

0 comments on commit c3b7752

Please sign in to comment.