From 12069f2c0649c0d29ac224e56cc77541674b549b Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 10:52:18 -0400 Subject: [PATCH 1/7] Issue #114 - Add numeric ids to spectra Added spectrum ids internally. --- src/messaging/spectrum_messages.rs | 81 +++++++++++++++++------------- src/projections/mod.rs | 24 +++++++++ src/spectra/mod.rs | 64 ++++++++++++++--------- 3 files changed, 110 insertions(+), 59 deletions(-) diff --git a/src/messaging/spectrum_messages.rs b/src/messaging/spectrum_messages.rs index 220dae24..d2325e0b 100644 --- a/src/messaging/spectrum_messages.rs +++ b/src/messaging/spectrum_messages.rs @@ -47,6 +47,7 @@ pub type SpectrumContents = Vec; #[derive(Clone, Debug, PartialEq)] pub struct SpectrumProperties { + pub id: usize, pub name: String, pub type_name: String, pub xparams: Vec, @@ -483,11 +484,12 @@ impl SpectrumProcessor { } // List spectra and properties. - fn get_properties(spec: &spectra::SpectrumContainer) -> SpectrumProperties { - let s = spec.borrow(); + fn get_properties(spec: &(spectra::SpectrumContainer, usize)) -> SpectrumProperties { + let s = spec.0.borrow(); let x = s.get_xaxis(); let y = s.get_yaxis(); SpectrumProperties { + id: spec.1, name: s.get_name(), type_name: s.get_type(), xparams: s.get_xparams(), @@ -529,7 +531,7 @@ impl SpectrumProcessor { cdict: &conditions::ConditionDictionary, ) -> SpectrumReply { if let Some(spec) = self.dict.get(sname) { - if let Err(msg) = spec.borrow_mut().gate(gname, cdict) { + if let Err(msg) = spec.0.borrow_mut().gate(gname, cdict) { SpectrumReply::Error(msg) } else { SpectrumReply::Gated @@ -540,7 +542,7 @@ impl SpectrumProcessor { } fn ungate_spectrum(&self, spectrum: &str) -> SpectrumReply { if let Some(spec) = self.dict.get(spectrum) { - spec.borrow_mut().ungate(); + spec.0.borrow_mut().ungate(); SpectrumReply::Ungated } else { SpectrumReply::Error(format!("Spectrum {} does not exist", spectrum)) @@ -554,7 +556,7 @@ impl SpectrumProcessor { let pat = pat.unwrap(); for (name, s) in self.dict.iter() { if pat.matches(name) { - s.borrow_mut().clear(); + s.0.borrow_mut().clear(); } } SpectrumReply::Cleared @@ -571,7 +573,7 @@ impl SpectrumProcessor { let mut result = SpectrumContents::new(); if let Some(spec) = self.dict.get(name) { - if let Some(spectrum) = spec.borrow().get_histogram_1d() { + if let Some(spectrum) = spec.0.borrow().get_histogram_1d() { for c in spectrum.borrow().iter() { let v = c.value.get(); if v != 0.0 { @@ -609,7 +611,7 @@ impl SpectrumProcessor { } } } else { - let spectrum = spec.borrow().get_histogram_2d().unwrap(); + let spectrum = spec.0.borrow().get_histogram_2d().unwrap(); for c in spectrum.borrow().iter() { let v = c.value.get(); let xbin = c.bin.0; @@ -678,7 +680,7 @@ impl SpectrumProcessor { // Get spectrumstatistics: fn get_statistics(&self, name: &str) -> SpectrumReply { if let Some(spec) = self.dict.get(name) { - SpectrumReply::Statistics(spec.borrow().get_out_of_range()) + SpectrumReply::Statistics(spec.0.borrow().get_out_of_range()) } else { SpectrumReply::Error(format!("Spectrum {} does not exist", name)) } @@ -696,7 +698,7 @@ impl SpectrumProcessor { // Find the spectrum: if let Some(spec) = self.dict.get(name) { - let mut histogram = spec.borrow_mut(); + let mut histogram = spec.0.borrow_mut(); histogram.clear(); if histogram.is_1d() { let spec1d = histogram.get_histogram_1d().unwrap(); @@ -764,9 +766,10 @@ impl SpectrumProcessor { if let Some(spec) = self.dict.get(name) { // What we do next depends on the spectrum dimensionality: - if spec.borrow().is_1d() { + if spec.0.borrow().is_1d() { let xchan = (xchan + 1) as usize; if let Some(f) = spec + .0 .borrow() .get_histogram_1d() .unwrap() @@ -783,7 +786,7 @@ impl SpectrumProcessor { if let Some(ybin) = ychan { // Have o turn the x/y channel into an index: - let spec = spec.borrow().get_histogram_2d().unwrap(); + let spec = spec.0.borrow().get_histogram_2d().unwrap(); match Self::channels2d_to_index(&spec, xchan, ybin) { Ok(index) => { if let Some(f) = spec.borrow().value_at_index(index) { @@ -817,9 +820,10 @@ impl SpectrumProcessor { if let Some(spec) = self.dict.get(name) { // How we figure out the index etc. depends on the dimensionality: - if spec.borrow().is_1d() { + if spec.0.borrow().is_1d() { let xchan = (xchan + 1) as usize; // -1 is overflow so.. if let Some(c) = spec + .0 .borrow() .get_histogram_1d() .unwrap() @@ -835,7 +839,7 @@ impl SpectrumProcessor { // 2d spectrum: if let Some(ybin) = ychan { - let spec = spec.borrow().get_histogram_2d().unwrap(); + let spec = spec.0.borrow().get_histogram_2d().unwrap(); match Self::channels2d_to_index(&spec, xchan, ybin) { Ok(index) => { if let Some(c) = spec.borrow_mut().value_at_index_mut(index) { @@ -864,7 +868,7 @@ impl SpectrumProcessor { cdict: &conditions::ConditionDictionary, ) -> SpectrumReply { if let Some(s) = self.dict.get(spectrum) { - if let Err(s) = s.borrow_mut().fold(condition, cdict) { + if let Err(s) = s.0.borrow_mut().fold(condition, cdict) { SpectrumReply::Error(format!("Failed to fold {}: {}", spectrum, s)) } else { SpectrumReply::Folded @@ -877,7 +881,7 @@ impl SpectrumProcessor { fn unfold_spectrum(&mut self, spectrum: &str) -> SpectrumReply { if let Some(s) = self.dict.get(spectrum) { - if let Err(s) = s.borrow_mut().unfold() { + if let Err(s) = s.0.borrow_mut().unfold() { SpectrumReply::Error(format!("Failed to unfold spectrum {}: {}", spectrum, s)) } else { SpectrumReply::Unfolded @@ -890,7 +894,7 @@ impl SpectrumProcessor { fn is_1d(&mut self, spectrum: &str) -> SpectrumReply { if let Some(s) = self.dict.get(spectrum) { - SpectrumReply::Flag(s.borrow().is_1d()) + SpectrumReply::Flag(s.0.borrow().is_1d()) } else { SpectrumReply::Error(format!("no such spectrum {}", spectrum)) } @@ -1793,7 +1797,7 @@ mod spproc_tests { assert!(to.processor.dict.exists("test")); let spc = to.processor.dict.get("test"); assert!(spc.is_some()); - let spc = spc.unwrap().borrow(); + let spc = spc.unwrap().0.borrow(); assert_eq!(String::from("test"), spc.get_name()); assert_eq!(String::from("1D"), spc.get_type()); @@ -1915,7 +1919,7 @@ mod spproc_tests { assert!(to.processor.dict.exists("test")); let spc = to.processor.dict.get("test"); assert!(spc.is_some()); - let spc = spc.unwrap().borrow(); + let spc = spc.unwrap().0.borrow(); assert_eq!(String::from("test"), spc.get_name()); assert_eq!(String::from("Multi1d"), spc.get_type()); @@ -2048,7 +2052,7 @@ mod spproc_tests { assert!(to.processor.dict.exists("test")); let spc = to.processor.dict.get("test"); assert!(spc.is_some()); - let spc = spc.unwrap().borrow(); + let spc = spc.unwrap().0.borrow(); assert_eq!(String::from("test"), spc.get_name()); assert_eq!(String::from("Multi2d"), spc.get_type()); @@ -2213,7 +2217,7 @@ mod spproc_tests { assert!(to.processor.dict.exists("test")); let spc = to.processor.dict.get("test"); assert!(spc.is_some()); - let spc = spc.unwrap().borrow(); // Ref to spectrum (readonly) + let spc = spc.unwrap().0.borrow(); // Ref to spectrum (readonly) assert_eq!(String::from("test"), spc.get_name()); assert_eq!(String::from("PGamma"), spc.get_type()); assert_eq!(xparams, spc.get_xparams()); @@ -2419,7 +2423,7 @@ mod spproc_tests { .processor .dict .get("test") - .expect("Missing summary spectrum") + .expect("Missing summary spectrum").0 .borrow(); assert_eq!(String::from("test"), spec.get_name()); assert_eq!(String::from("Summary"), spec.get_type()); @@ -2554,7 +2558,7 @@ mod spproc_tests { .processor .dict .get("test") - .expect("Missing spectru") + .expect("Missing spectrum").0 .borrow(); assert_eq!(String::from("test"), spec.get_name()); @@ -2743,7 +2747,7 @@ mod spproc_tests { .processor .dict .get("test") - .expect("Could not find spectrum") + .expect("Could not find spectrum").0 .borrow(); assert_eq!(String::from("test"), spec.get_name()); assert_eq!(String::from("2DSum"), spec.get_type()); @@ -3058,7 +3062,7 @@ mod spproc_tests { assert_eq!(SpectrumReply::Created, reply); } let spec = to.processor.dict.get("test.1").expect("Missing spectrum"); - let h = spec + let h = spec.0 .borrow() .get_histogram_1d() .expect("Not 1d but should be"); @@ -3106,7 +3110,7 @@ mod spproc_tests { assert_eq!(SpectrumReply::Created, reply); } let spec = to.processor.dict.get("test.1").expect("Missing spectrum"); - let h = spec + let h = spec.0 .borrow() .get_histogram_1d() .expect("Not 1d but should be"); @@ -3513,7 +3517,7 @@ mod spproc_tests { // These should havve counts in the indicated channels: for (name, chan) in with_counts { - let spec = to.processor.dict.get(&name).unwrap().borrow(); + let spec = to.processor.dict.get(&name).unwrap().0.borrow(); for ch in spec.get_histogram_1d().unwrap().borrow().iter() { let d = ch.value.get(); if d != 0.0 { @@ -3528,7 +3532,7 @@ mod spproc_tests { } // these should have no counts. for name in no_counts { - let spec = to.processor.dict.get(&name).unwrap().borrow(); + let spec = to.processor.dict.get(&name).unwrap().0.borrow(); for ch in spec.get_histogram_1d().unwrap().borrow().iter() { assert_eq!(0.0, ch.value.get()); } @@ -4388,7 +4392,7 @@ mod spproc_tests { // Put a value in bin 512 (exclusive of 0 which is the underflow): // Block so that the borrow is given back: { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_1d() .unwrap() @@ -4502,7 +4506,7 @@ mod spproc_tests { // otherwise I don't think the processor can then borrow // the spectrum to give us the value. { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_1d() .unwrap() @@ -4549,7 +4553,7 @@ mod spproc_tests { // otherwise I don't think the processor can then borrow // the spectrum to give us the value. { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_1d() .unwrap() @@ -4601,7 +4605,7 @@ mod spproc_tests { // increment 512.0, 512.0 (bin 256, 256) // in a block so the borrow is released { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_2d() .unwrap() .borrow_mut() @@ -4809,7 +4813,7 @@ mod spproc_tests { // on the 256 line. { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_2d() .unwrap() .borrow_mut() @@ -4858,7 +4862,7 @@ mod spproc_tests { // Set increment x channel at coordinate 1025.0 and y 512.0 that should // be an overflow an the y bin 256 { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_2d() .unwrap() .borrow_mut() @@ -4907,7 +4911,7 @@ mod spproc_tests { // bin (256, -1) in our coords for underflow { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_2d() .unwrap() .borrow_mut() @@ -4957,7 +4961,7 @@ mod spproc_tests { // This will be 256, 512 in bin space. { - let spc = to.processor.dict.get("test").unwrap().borrow(); + let spc = to.processor.dict.get("test").unwrap().0.borrow(); spc.get_histogram_2d() .unwrap() .borrow_mut() @@ -6659,6 +6663,7 @@ mod spectrum_api_tests { assert_eq!(1, listing.len()); assert_eq!( SpectrumProperties { + id: 0, name: String::from("test"), type_name: String::from("1D"), xparams: vec![String::from("param.1")], @@ -6701,6 +6706,7 @@ mod spectrum_api_tests { assert_eq!(1, l.len()); assert_eq!( SpectrumProperties { + id: 0, name: String::from("test"), type_name: String::from("Multi1d"), xparams: params, @@ -6743,6 +6749,7 @@ mod spectrum_api_tests { assert_eq!(1, l.len()); assert_eq!( SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("Multi2d"), xparams: params, @@ -6796,6 +6803,7 @@ mod spectrum_api_tests { assert_eq!(1, l.len()); assert_eq!( SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("PGamma"), xparams, @@ -6842,6 +6850,7 @@ mod spectrum_api_tests { assert_eq!(1, l.len()); assert_eq!( SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("Summary"), xparams: params, @@ -6878,6 +6887,7 @@ mod spectrum_api_tests { assert_eq!(1, l.len()); assert_eq!( SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("2D"), xparams: vec![String::from("param.0")], @@ -6929,6 +6939,7 @@ mod spectrum_api_tests { assert_eq!(1, l.len()); assert_eq!( SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("2DSum"), xparams, diff --git a/src/projections/mod.rs b/src/projections/mod.rs index 642a1a90..180f92d6 100644 --- a/src/projections/mod.rs +++ b/src/projections/mod.rs @@ -432,6 +432,7 @@ mod make_sum_tests { fn invalid_1() { // Only x axus is insufficient to project in x let props = spectrum_messages::SpectrumProperties { + id: 0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -451,6 +452,7 @@ mod make_sum_tests { fn invalid_2() { // Only x axis insufficient to project in y. let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -471,6 +473,7 @@ mod make_sum_tests { // only y axis is insufficient to project in x or y: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -493,6 +496,7 @@ mod make_sum_tests { #[test] fn ok_1() { let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -518,6 +522,7 @@ mod make_sum_tests { // Ensure x projections get the size right: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -542,6 +547,7 @@ mod make_sum_tests { #[test] fn ok_3() { let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -575,6 +581,7 @@ mod project_spectrum_tests { // No y axis: // let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -597,6 +604,7 @@ mod project_spectrum_tests { // No X axis: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -619,6 +627,7 @@ mod project_spectrum_tests { // x/y axis allows projection - no contents so zeroes for sums: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -646,6 +655,7 @@ mod project_spectrum_tests { // Sizes should be correct: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -683,6 +693,7 @@ mod project_spectrum_tests { // in these cases the sums should be zero: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -722,6 +733,7 @@ mod project_spectrum_tests { // result in a non-zero projection: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -759,6 +771,7 @@ mod project_spectrum_tests { // Using a closure that always returns false gives zeros in the projection: let props = spectrum_messages::SpectrumProperties { + id:0, name: String::from("test"), type_name: String::from("1d"), xparams: vec![], // Parameters are ignored. @@ -822,6 +835,7 @@ mod make_spectrum_tests { let sapi = spectrum_messages::SpectrumMessageClient::new(&ch); let data = vec![]; let desc = spectrum_messages::SpectrumProperties { + id:0, name: String::from("dummy"), type_name: String::from("1D"), // not projectable. xparams: vec![], @@ -848,6 +862,7 @@ mod make_spectrum_tests { let (ch, jh) = setup(); let sapi = spectrum_messages::SpectrumMessageClient::new(&ch); let desc = spectrum_messages::SpectrumProperties { + id:0, name: String::from("dummy"), type_name: String::from("2D"), // valid. xparams: vec![], @@ -874,6 +889,7 @@ mod make_spectrum_tests { let (ch, jh) = setup(); let sapi = spectrum_messages::SpectrumMessageClient::new(&ch); let desc = spectrum_messages::SpectrumProperties { + id:0, name: String::from("dummy"), type_name: String::from("2D"), // valid. xparams: vec![], @@ -908,6 +924,7 @@ mod make_spectrum_tests { api.create_parameter(name).expect("making parameters"); } spectrum_messages::SpectrumProperties { + id:0, name: String::from("input"), type_name: String::from("Multi2D"), xparams: vec![String::from("p1"), String::from("p2"), String::from("p3")], @@ -1147,6 +1164,7 @@ mod make_spectrum_tests { } // THis must be as gotten back from list_spectra so bins inluce over/under. spectrum_messages::SpectrumProperties { + id: 0, name: String::from("input"), type_name: String::from("PGamma"), xparams: xparams.clone(), @@ -1348,6 +1366,7 @@ mod make_spectrum_tests { api.create_parameter("p2").expect("Making p2"); spectrum_messages::SpectrumProperties { + id:0, name: String::from("input"), type_name: String::from("2D"), xparams: vec![String::from("p1")], @@ -1402,6 +1421,7 @@ mod make_spectrum_tests { assert_eq!( spectrum_messages::SpectrumProperties { + id:0, name: String::from("test1"), type_name: String::from("1D"), xparams: vec![String::from("p1")], @@ -1440,6 +1460,7 @@ mod make_spectrum_tests { assert_eq!( spectrum_messages::SpectrumProperties { + id: 0, name: String::from("test1"), type_name: String::from("1D"), xparams: vec![String::from("p2")], @@ -1538,6 +1559,7 @@ mod make_spectrum_tests { } spectrum_messages::SpectrumProperties { + id:0, name: String::from("input"), type_name: String::from("2DSum"), xparams: vec![String::from("x1"), String::from("x2"), String::from("x3")], @@ -1591,6 +1613,7 @@ mod make_spectrum_tests { assert_eq!( spectrum_messages::SpectrumProperties { + id:0, name: String::from("test1"), type_name: String::from("Multi1d"), xparams: vec![String::from("x1"), String::from("x2"), String::from("x3"),], @@ -1628,6 +1651,7 @@ mod make_spectrum_tests { assert_eq!( spectrum_messages::SpectrumProperties { + id:0, name: String::from("test1"), type_name: String::from("Multi1d"), xparams: vec![String::from("y1"), String::from("y2"), String::from("y3"),], diff --git a/src/spectra/mod.rs b/src/spectra/mod.rs index f0458b66..9851112c 100644 --- a/src/spectra/mod.rs +++ b/src/spectra/mod.rs @@ -372,7 +372,7 @@ pub trait Spectrum { pub type SpectrumContainer = Rc>; pub type SpectrumContainerReference = Weak>; pub type SpectrumReferences = Vec; -pub type SpectrumDictionary = HashMap; +pub type SpectrumDictionary = HashMap; /// The SpectrumStorage type supports several things: /// - Spectrum storage by name through a contained SpectrumDictionary. @@ -391,6 +391,7 @@ pub struct SpectrumStorage { dict: SpectrumDictionary, spectra_by_parameter: Vec>, other_spectra: SpectrumReferences, + next_id: usize, } impl SpectrumStorage { @@ -434,11 +435,12 @@ impl SpectrumStorage { dict: SpectrumDictionary::new(), spectra_by_parameter: Vec::>::new(), other_spectra: SpectrumReferences::new(), + next_id: 0_usize, } } /// Iterate over the dict: /// - pub fn iter(&self) -> hash_map::Iter<'_, String, SpectrumContainer> { + pub fn iter(&self) -> hash_map::Iter<'_, String, (SpectrumContainer, usize)> { self.dict.iter() } @@ -462,9 +464,11 @@ impl SpectrumStorage { /// pub fn add(&mut self, spectrum: SpectrumContainer) -> Option { let inc_ref = Rc::clone(&spectrum); + let id = self.next_id; + self.next_id += 1; let result = self .dict - .insert(inc_ref.borrow().get_name(), Rc::clone(&spectrum)); + .insert(inc_ref.borrow().get_name(), (Rc::clone(&spectrum), id)); let param = inc_ref.borrow().required_parameter(); let inc_ref = Rc::downgrade(&inc_ref); @@ -486,7 +490,11 @@ impl SpectrumStorage { } else { self.other_spectra.push(inc_ref); } - result + if let Some(r) = result { + Some(r.0) + } else { + None + } } /// Does the specified spectrum exist? /// @@ -500,15 +508,19 @@ impl SpectrumStorage { /// If the caller is going to hold on to that reference for /// some time, they should clone the container. /// - pub fn get(&self, name: &str) -> Option<&SpectrumContainer> { - self.dict.get(name) + pub fn get(&self, name: &str) -> Option<(&SpectrumContainer, usize)> { + if let Some(entry) = self.dict.get(name) { + Some((&entry.0, entry.1)) + } else { + None + } } /// Clear all the spectra /// #[allow(dead_code)] pub fn clear_all(&self) { for (_, spec) in self.dict.iter() { - spec.borrow_mut().clear(); + spec.0.borrow_mut().clear(); } } /// Process an event @@ -550,7 +562,11 @@ impl SpectrumStorage { /// which the caller can do with as they please (including dropping). /// pub fn remove(&mut self, name: &str) -> Option { - self.dict.remove(name) + if let Some(entry) = self.dict.remove(name) { + Some(entry.0) + } else { + None + } } } @@ -839,7 +855,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // Figure out which element of spectra_by_parameter it should be in: @@ -879,7 +895,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // Figure out which element of spectra_by_parameter it should be in @@ -931,7 +947,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // The spectrum should be in other_spectra: @@ -970,7 +986,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // The spectrum should be in other_spectra: @@ -1021,7 +1037,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // The spectrum should be in other_spectra: @@ -1062,7 +1078,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // The spectrum should be in other_spectra: @@ -1100,7 +1116,7 @@ mod spec_storage_tests { let dict_spec = dict_spec.as_ref().unwrap(); assert_eq!( spec_container.borrow().get_name(), - dict_spec.borrow().get_name() + dict_spec.0.borrow().get_name() ); // The spectrum should be in other_spectra: @@ -1133,7 +1149,7 @@ mod spec_storage_tests { let result = store.get("spec1"); assert!(result.is_some()); let spec = result.unwrap(); - assert_eq!(String::from("spec1"), spec.borrow().get_name()); + assert_eq!(String::from("spec1"), spec.0.borrow().get_name()); } #[test] fn get_2() { @@ -1211,13 +1227,13 @@ mod spec_storage_tests { let c1 = store .get("spec1") .expect("spec1 should have been in the container"); - for c in c1.borrow().get_histogram_1d().unwrap().borrow().iter() { + for c in c1.0.borrow().get_histogram_1d().unwrap().borrow().iter() { assert_eq!(0.0, c.value.get()); } let c2 = store .get("spec2") .expect("spec2 should have been in the container"); - for c in c2.borrow().get_histogram_2d().unwrap().borrow().iter() { + for c in c2.0.borrow().get_histogram_2d().unwrap().borrow().iter() { assert_eq!(0.0, c.value.get()); } } @@ -1275,7 +1291,7 @@ mod spec_storage_tests { let s1 = store .get("spec1") .expect("Failed to fetch spec1 from store"); - let h1 = s1 + let h1 = s1.0 .borrow() .get_histogram_1d() .expect("Failed to get 1d histogram"); @@ -1289,7 +1305,7 @@ mod spec_storage_tests { let s2 = store .get("spec2") .expect("Failed to fetch spec2 from store"); - let h2 = s2 + let h2 = s2.0 .borrow() .get_histogram_2d() .expect("Failed to get 2d histogram"); @@ -1346,13 +1362,13 @@ mod spec_storage_tests { store .get("spec1") - .expect("spec1 was missing") + .expect("spec1 was missing").0 .borrow_mut() .gate("true", &cd) .expect("true gate not found when gating spec1."); store .get("spec2") - .expect("spec2 was missing") + .expect("spec2 was missing").0 .borrow_mut() .gate("false", &cd) .expect("false gate not found when gating spec2"); @@ -1383,7 +1399,7 @@ mod spec_storage_tests { let s1 = store .get("spec1") .expect("Failed to fetch spec1 from store"); - let h1 = s1 + let h1 = s1.0 .borrow() .get_histogram_1d() .expect("Failed to get 1d histogram"); @@ -1397,7 +1413,7 @@ mod spec_storage_tests { let s2 = store .get("spec2") .expect("Failed to fetch spec2 from store"); - let h2 = s2 + let h2 = s2.0 .borrow() .get_histogram_2d() .expect("Failed to get 2d histogram"); From ab1f43a4e805bef34ad09bb468820002e7900c08 Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 11:09:30 -0400 Subject: [PATCH 2/7] Issue #114 - Add numeric ids to spectra Modified the spectrum list thing to return the id in the JSON. Tested this in list_4. --- src/rest/spectrum.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/rest/spectrum.rs b/src/rest/spectrum.rs index ad4ab565..c08306b1 100644 --- a/src/rest/spectrum.rs +++ b/src/rest/spectrum.rs @@ -57,6 +57,7 @@ pub struct Axis { #[derive(Serialize, Deserialize, Clone)] #[serde(crate = "rocket::serde")] pub struct SpectrumDescription { + id: usize, name: String, #[serde(rename = "type")] spectrum_type: String, @@ -84,6 +85,7 @@ fn list_to_detail(l: Vec) -> Vec { let mut result = Vec::::new(); for mut d in l { let mut def = SpectrumDescription { + id: d.id, name: d.name, spectrum_type: rg_sptype_to_spectcl(&d.type_name), parameters: d.xparams.clone(), @@ -1484,6 +1486,26 @@ mod spectrum_tests { teardown(chan, &papi, &binder_api); } #[test] + fn list_4() { + // The id is now included and correct: + + let rocket = setup(); + let (chan, papi, binder_api) = getstate(&rocket); + + let client = Client::untracked(rocket).expect("making client"); + let req = client.get("/list?filter=pgamma"); + let reply = req + .dispatch() + .into_json::() + .expect("Parsing JSON"); + assert_eq!("OK", reply.status); + assert_eq!(1, reply.detail.len()); + let props = &reply.detail[0]; + assert_eq!(3, props.id); + + teardown(chan, &papi, &binder_api); + } + #[test] fn delete_1() { // delete an existing spectrum. From 49bb0359e8e0806cfc282e79fcd125a5e0e6d225 Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 11:18:37 -0400 Subject: [PATCH 3/7] Issue #114 - Add numeric ids to spectra * If provided include the correct Id in spectrum -list * Opportunisitc reformattting (I think) --- restclients/Tcl/SpecTclRestCommand.tcl | 11 ++++++++--- restclients/Tcl/restclient.tcl | 1 + src/rest/fold.rs | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/restclients/Tcl/SpecTclRestCommand.tcl b/restclients/Tcl/SpecTclRestCommand.tcl index 6d49b0a0..73f6cf03 100644 --- a/restclients/Tcl/SpecTclRestCommand.tcl +++ b/restclients/Tcl/SpecTclRestCommand.tcl @@ -1612,12 +1612,17 @@ namespace eval spectrum { set result [list] foreach s $raw { - set item [list \ - 0 [dict get $s name] [dict get $s type] \ + if {[dict exists $s id]} { + set item [dict get $s id] + } else { + set item 0 + } + lappend item \ \ + [dict get $s name] [dict get $s type] \ [dict get $s parameters] \ [::SpecTclRestCommand::_axesDictToAxesList [dict get $s axes]] \ [dict get $s chantype] \ - ] + carggo if {$showgates} { lappend item [dict get $s gate] } diff --git a/restclients/Tcl/restclient.tcl b/restclients/Tcl/restclient.tcl index dd5d6548..6d8f6f87 100644 --- a/restclients/Tcl/restclient.tcl +++ b/restclients/Tcl/restclient.tcl @@ -1303,6 +1303,7 @@ snit::type SpecTclRestClient { # @param pattern - The pattern (which can include Glob wildcard characters), # this defaults to "*" which matches all spectra. # @return List of dicts that contain: + # - id - id of the spectrum (only present if REST defines it). # - name - spectrum name. # - type - spectrum type. # - parameter - list of parameters needed by the spectrum. diff --git a/src/rest/fold.rs b/src/rest/fold.rs index 665543f2..7f515b94 100644 --- a/src/rest/fold.rs +++ b/src/rest/fold.rs @@ -412,8 +412,11 @@ mod fold_tests { params.push(name); param_ids.push(i); } - assert!(matches!(capi.create_multicut_condition("mcut", ¶m_ids, 100.0, 200.0), condition_messages::ConditionReply::Created )); - + assert!(matches!( + capi.create_multicut_condition("mcut", ¶m_ids, 100.0, 200.0), + condition_messages::ConditionReply::Created + )); + sapi.create_spectrum_multi1d("test", ¶ms, 0.0, 1024.0, 1024) .expect("Making spectrum"); From 157501303088fb711bfdb01f2588a7bc9e219fb2 Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 11:37:03 -0400 Subject: [PATCH 4/7] Issue #114 - Add numeric ids to spectra Fill in correct spectrum id in /sbind/list response. --- src/rest/sbind.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/rest/sbind.rs b/src/rest/sbind.rs index 184ed4bf..e549def7 100644 --- a/src/rest/sbind.rs +++ b/src/rest/sbind.rs @@ -224,6 +224,21 @@ pub struct BindingsResponse { status: String, detail: Vec, } +//Get the id of a spectrum or - if it cannot be gotten: + +fn get_spectrum_id(api: &spectrum_messages::SpectrumMessageClient, name: &str) -> usize { + let listing = api.list_spectra(name); + if let Ok(l) = listing { + if l.len() == 1 { + l[0].id + } else { + 0 + } + } else { + 0 + } +} + /// Handles the /spectcl/sbind/list REST request. /// /// ### Parameters @@ -244,8 +259,10 @@ pub struct BindingsResponse { pub fn sbind_bindings( pattern: OptionalString, state: &State, + spec_api: &State, ) -> Json { let api = binder::BindingApi::new(&state.inner().lock().unwrap()); + let sapi = spectrum_messages::SpectrumMessageClient::new(&spec_api.inner().lock().unwrap()); let p = if let Some(pat) = pattern { pat } else { @@ -259,8 +276,9 @@ pub fn sbind_bindings( Ok(l) => { response.status = String::from("OK"); for b in l { + let id = get_spectrum_id(&sapi, &b.1); response.detail.push(Binding { - spectrumid: 0, + spectrumid: id, name: b.1, binding: b.0, }); @@ -661,7 +679,9 @@ mod sbind_tests { bind_list.sort_by(|a, b| a.name.cmp(&b.name)); assert_eq!("oned", bind_list[0].name); + assert_eq!(0, bind_list[0].spectrumid); assert_eq!("twod", bind_list[1].name); + assert_eq!(1, bind_list[1].spectrumid); teardown(c, &papi, &bapi); } @@ -686,6 +706,7 @@ mod sbind_tests { assert_eq!("OK", reply.status); assert_eq!(1, reply.detail.len()); assert_eq!("twod", reply.detail[0].name); + assert_eq!(1, reply.detail[0].spectrumid); teardown(c, &papi, &bapi); } From 2619ccbc969c14975a5ebfb745cbf1f3728ff1cd Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 11:38:14 -0400 Subject: [PATCH 5/7] Issue #114 - Add numeric ids to spectra Clean up some code. --- src/rest/sbind.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rest/sbind.rs b/src/rest/sbind.rs index e549def7..c5e163ed 100644 --- a/src/rest/sbind.rs +++ b/src/rest/sbind.rs @@ -276,9 +276,8 @@ pub fn sbind_bindings( Ok(l) => { response.status = String::from("OK"); for b in l { - let id = get_spectrum_id(&sapi, &b.1); response.detail.push(Binding { - spectrumid: id, + spectrumid: get_spectrum_id(&sapi, &b.1), name: b.1, binding: b.0, }); From 19853918d1f99094c7cbc8f6d958861dcf0a4a64 Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 11:43:22 -0400 Subject: [PATCH 6/7] Set Cargo.toml version to 1.0.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index ccc8bbe0..c4111ee5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustogramer" -version = "0.4.1" +version = "1.0.0" edition = "2021" authors = ["Ron Fox fox@frib.msu.edu"] description="A generic histogramer intended for nuclear science data from the FRIB" From 32bbd0aa0eec42cd57c65459ef7a073ce285e6ff Mon Sep 17 00:00:00 2001 From: Ron Fox Date: Wed, 27 Sep 2023 11:51:55 -0400 Subject: [PATCH 7/7] Apply clippy recommendations --- src/spectra/mod.rs | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/spectra/mod.rs b/src/spectra/mod.rs index 9851112c..95110278 100644 --- a/src/spectra/mod.rs +++ b/src/spectra/mod.rs @@ -509,11 +509,7 @@ impl SpectrumStorage { /// some time, they should clone the container. /// pub fn get(&self, name: &str) -> Option<(&SpectrumContainer, usize)> { - if let Some(entry) = self.dict.get(name) { - Some((&entry.0, entry.1)) - } else { - None - } + self.dict.get(name).map(|entry| (&entry.0, entry.1)) } /// Clear all the spectra /// @@ -1291,10 +1287,10 @@ mod spec_storage_tests { let s1 = store .get("spec1") .expect("Failed to fetch spec1 from store"); - let h1 = s1.0 - .borrow() - .get_histogram_1d() - .expect("Failed to get 1d histogram"); + let h1 = + s1.0.borrow() + .get_histogram_1d() + .expect("Failed to get 1d histogram"); let mut sum1 = 0.0; for c in h1.borrow().iter() { @@ -1305,10 +1301,10 @@ mod spec_storage_tests { let s2 = store .get("spec2") .expect("Failed to fetch spec2 from store"); - let h2 = s2.0 - .borrow() - .get_histogram_2d() - .expect("Failed to get 2d histogram"); + let h2 = + s2.0.borrow() + .get_histogram_2d() + .expect("Failed to get 2d histogram"); let mut sum2 = 0.0; for c in h2.borrow().iter() { sum2 += c.value.get(); @@ -1362,13 +1358,15 @@ mod spec_storage_tests { store .get("spec1") - .expect("spec1 was missing").0 + .expect("spec1 was missing") + .0 .borrow_mut() .gate("true", &cd) .expect("true gate not found when gating spec1."); store .get("spec2") - .expect("spec2 was missing").0 + .expect("spec2 was missing") + .0 .borrow_mut() .gate("false", &cd) .expect("false gate not found when gating spec2"); @@ -1399,10 +1397,10 @@ mod spec_storage_tests { let s1 = store .get("spec1") .expect("Failed to fetch spec1 from store"); - let h1 = s1.0 - .borrow() - .get_histogram_1d() - .expect("Failed to get 1d histogram"); + let h1 = + s1.0.borrow() + .get_histogram_1d() + .expect("Failed to get 1d histogram"); let mut sum1 = 0.0; for c in h1.borrow().iter() { @@ -1413,10 +1411,10 @@ mod spec_storage_tests { let s2 = store .get("spec2") .expect("Failed to fetch spec2 from store"); - let h2 = s2.0 - .borrow() - .get_histogram_2d() - .expect("Failed to get 2d histogram"); + let h2 = + s2.0.borrow() + .get_histogram_2d() + .expect("Failed to get 2d histogram"); let mut sum2 = 0.0; for c in h2.borrow().iter() { sum2 += c.value.get();