Skip to main content

bbsg_a02/
p03.rs

1use crate::p02::DayLoadProf;
2use crate::p02::DrawLoadProf;
3use crate::p02::FeederLoadProf;
4use crate::p02::LoadProf;
5use crate::p02::SubLoadProf;
6use crate::p02::DAY_VAL_PNTS;
7use bincode::{Decode, Encode};
8use std::collections::HashMap;
9use std::error::Error;
10pub const LOAD_PROF_MIN_DAYS: usize = 5;
11pub const LOAD_PROF_MAX_DAYS: usize = 30;
12pub const LOAD_PROF_MIN_HOUR: usize = 18;
13
14impl DayLoadProf {
15    fn is_valid(&self) -> bool {
16        let mut hrls = vec![];
17        for (vi, v) in self.val.iter().enumerate() {
18            if v.is_some() {
19                let hr = vi / 4;
20                if !hrls.contains(&hr) {
21                    hrls.push(vi);
22                }
23            }
24        }
25        hrls.len() > LOAD_PROF_MIN_HOUR
26    }
27}
28
29pub fn p03_calc_lp_1(lp: &FeederLoadProf) -> Result<(Vec<usize>, Vec<usize>), Box<dyn Error>> {
30    let mut po_lst = Vec::<(f32, usize)>::new();
31    let mut ne_lst = Vec::<(f32, usize)>::new();
32    for (di, dlp) in lp.days.iter().enumerate() {
33        if let Some(dlp) = dlp {
34            let mut po_pw = 0.0;
35            let mut ne_pw = 0.0;
36            for v in dlp.val.into_iter().flatten() {
37                if v > 0.0 {
38                    po_pw += v;
39                }
40                if v < 0.0 {
41                    ne_pw += -v;
42                }
43            }
44            if po_pw > 0.0 {
45                po_lst.push((po_pw, di));
46            }
47            if ne_pw > 0.0 {
48                ne_lst.push((ne_pw, di));
49            }
50        }
51    }
52    po_lst.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap());
53    let mut po_lst2 = Vec::<usize>::new();
54    for (_v, i) in po_lst {
55        if let Some(dlp) = &lp.days[i] {
56            if !dlp.is_valid() {
57                break;
58            }
59        }
60        po_lst2.push(i);
61    }
62    ne_lst.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap());
63    let mut ne_lst2 = Vec::<usize>::new();
64    for (_v, i) in ne_lst {
65        if let Some(dlp) = &lp.days[i] {
66            if !dlp.is_valid() {
67                break;
68            }
69        }
70        ne_lst2.push(i);
71    }
72    Ok((po_lst2, ne_lst2))
73}
74
75#[derive(Encode, Decode, PartialEq, Debug, Clone, Default)]
76pub struct LoadProfRepr {
77    pub val: Option<[Option<f32>; DAY_VAL_PNTS]>,
78    pub rep: Option<Vec<usize>>,
79}
80
81#[derive(Encode, Decode, PartialEq, Debug, Clone, Default)]
82pub struct SubLoadProfRepr {
83    pub sub: String,
84    pub year: String,
85    pub pos_rep: LoadProfRepr,
86    pub neg_rep: LoadProfRepr,
87}
88
89pub fn p03_draw_sub_av(
90    ldpf: &FeederLoadProf,
91    po: &[usize],
92    pn: &str,
93) -> Result<LoadProfRepr, Box<dyn Error>> {
94    let mut lpre = LoadProfRepr::default();
95    let s = ldpf.sub.to_string();
96    let f = ldpf.feed.to_string();
97    let yr = ldpf.year.to_string();
98    if po.len() >= LOAD_PROF_MIN_DAYS {
99        let mut avls = Vec::<usize>::new();
100        for ii in po.iter().take(LOAD_PROF_MAX_DAYS) {
101            avls.push(*ii);
102        }
103        let mut avdlp = ldpf.days[avls[0]].clone();
104        for ii in &avls[1..] {
105            let fdlp = &ldpf.days[*ii];
106            if let (Some(slp), Some(flp)) = (&mut avdlp, fdlp) {
107                for (sva, fva) in slp.val.iter_mut().zip(flp.val.iter()) {
108                    if let (None, Some(fva)) = (&sva, &fva) {
109                        *sva = Some(*fva);
110                    } else if let (Some(sv), Some(fv)) = (&sva, &fva) {
111                        *sva = Some(*sv + *fv);
112                    }
113                }
114            }
115        }
116        let ln = avls.len() as f32;
117        if let Some(slp) = &mut avdlp {
118            for sva in slp.val.iter_mut() {
119                if let Some(sv) = &sva {
120                    *sva = Some(*sv / ln);
121                }
122            }
123            let val = slp.val;
124            lpre.val = Some(slp.val);
125            lpre.rep = Some(avls.clone());
126            let dnm = format!("/mnt/e/CHMBACK/pea-data/sbdrlp/{yr}/{s}");
127            std::fs::create_dir_all(&dnm)?;
128            let fnm = format!("{dnm}/{s}-{f}-{pn}.jpg");
129            //println!(" -> {fnm}");
130            let sz = (400, 300);
131            let rf = Vec::<(String, f32)>::new();
132
133            let drlp = LoadProf {
134                lb1: s.to_string(),
135                lb2: yr.to_string(),
136                fnm,
137                val,
138                sz,
139                rf,
140            };
141            drlp.draw_prof()?;
142        }
143    }
144    Ok(lpre)
145}
146//use crate::p03::SubLoadProfRepr;
147
148pub fn p03_load_lp(yr: &str) -> HashMap<String, SubLoadProfRepr> {
149    //let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p02_sub_lp_{yr}.bin");
150    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p03_lp_repr_{yr}.bin");
151    let bytes = std::fs::read(fnm).unwrap();
152    let (subh, _): (HashMap<String, SubLoadProfRepr>, usize) =
153        bincode::decode_from_slice(&bytes[..], bincode::config::standard()).unwrap();
154    subh
155}
156
157pub fn p03_calc_lp2(yr: &str, s: &str) -> Result<(), Box<dyn Error>> {
158    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p02_sub_lp_{yr}.bin");
159    let bytes = std::fs::read(fnm).unwrap();
160    let (subh, _): (HashMap<String, SubLoadProf>, usize) =
161        bincode::decode_from_slice(&bytes[..], bincode::config::standard()).unwrap();
162
163    let mut p03_lp_repr = HashMap::<String, SubLoadProfRepr>::new();
164    //for (s, sub) in subh {
165    {
166        let sub = subh.get(s).unwrap();
167        if let Some(ldpf) = &sub.ldpf {
168            print!("{s} ");
169            let (po, ne) = p03_calc_lp_1(ldpf)?;
170            let sbre = SubLoadProfRepr {
171                sub: s.to_string(),
172                year: yr.to_string(),
173                pos_rep: p03_draw_sub_av(ldpf, &po, "PO")?,
174                neg_rep: p03_draw_sub_av(ldpf, &ne, "NE")?,
175            };
176            p03_lp_repr.insert(s.to_string(), sbre);
177
178            print!("  p:{} [", po.len());
179            for (pi, ii) in po.iter().enumerate() {
180                if pi >= LOAD_PROF_MIN_DAYS {
181                    break;
182                }
183                if pi > 0 {
184                    print!(",");
185                }
186                print!("{ii}");
187            }
188            print!("] n:{} [", ne.len());
189            for (ni, ii) in ne.iter().enumerate() {
190                if ni >= LOAD_PROF_MIN_DAYS {
191                    break;
192                }
193                if ni > 0 {
194                    print!(",");
195                }
196                print!("{ii}");
197            }
198            print!("]");
199            println!();
200        }
201        for ldpf in sub.fdldp.values() {
202            let f = &ldpf.feed;
203            //p03_calc_lp_1(ldpf)?;
204            let (po, ne) = p03_calc_lp_1(ldpf)?;
205            let sbre = SubLoadProfRepr {
206                sub: s.to_string(),
207                year: yr.to_string(),
208                pos_rep: p03_draw_sub_av(ldpf, &po, "PO")?,
209                neg_rep: p03_draw_sub_av(ldpf, &ne, "NE")?,
210            };
211            p03_lp_repr.insert(format!("{s}-{f}"), sbre);
212        }
213    }
214    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p03_lp_repr_{yr}.bin");
215    println!("write pre {} to {fnm}", p03_lp_repr.len());
216    let bin: Vec<u8> = bincode::encode_to_vec(&p03_lp_repr, bincode::config::standard()).unwrap();
217    std::fs::write(fnm, bin).unwrap();
218    Ok(())
219}
220
221pub fn p03_calc_lp_3(lp: &FeederLoadProf) -> Result<(Vec<usize>, Vec<usize>), Box<dyn Error>> {
222    let mut po_lst = Vec::<(f32, usize)>::new();
223    let mut ne_lst = Vec::<(f32, usize)>::new();
224    for (di, dlp) in lp.days.iter().enumerate() {
225        if let Some(dlp) = dlp {
226            let mut po_pw = 0.0;
227            let mut ne_pw = 0.0;
228            for v in dlp.val.into_iter().flatten() {
229                if v > 0.0 {
230                    po_pw += v;
231                }
232                if v < 0.0 {
233                    ne_pw += -v;
234                }
235            }
236            if po_pw > 0.0 {
237                po_lst.push((po_pw, di));
238            }
239            if ne_pw > 0.0 {
240                ne_lst.push((ne_pw, di));
241            }
242        }
243    }
244    po_lst.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap());
245    let mut po_lst2 = Vec::<usize>::new();
246    for (_v, i) in po_lst {
247        if let Some(dlp) = &lp.days[i] {
248            if !dlp.is_valid() {
249                break;
250            }
251        }
252        po_lst2.push(i);
253    }
254    ne_lst.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap());
255    let mut ne_lst2 = Vec::<usize>::new();
256    for (_v, i) in ne_lst {
257        if let Some(dlp) = &lp.days[i] {
258            if !dlp.is_valid() {
259                break;
260            }
261        }
262        ne_lst2.push(i);
263    }
264    Ok((po_lst2, ne_lst2))
265}
266
267pub fn p03_calc_lp3(yr: &str) -> Result<(), Box<dyn Error>> {
268    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p02_sub_lp_{yr}.bin");
269    let bytes = std::fs::read(fnm).unwrap();
270    let (subh, _): (HashMap<String, SubLoadProf>, usize) =
271        bincode::decode_from_slice(&bytes[..], bincode::config::standard()).unwrap();
272    let mut p03_lp_repr = HashMap::<String, SubLoadProfRepr>::new();
273    let mut dy_cn = HashMap::<usize, usize>::new();
274    for (s, sub) in subh {
275        if let Some(ldpf) = &sub.ldpf {
276            print!("{s} ");
277            let (po, ne) = p03_calc_lp_3(ldpf)?;
278            let sbre = SubLoadProfRepr {
279                sub: s.to_string(),
280                year: yr.to_string(),
281                pos_rep: p03_draw_sub_av(ldpf, &po, "PO")?,
282                neg_rep: p03_draw_sub_av(ldpf, &ne, "NE")?,
283            };
284            p03_lp_repr.insert(s.to_string(), sbre);
285
286            print!("  p:{} [", po.len());
287            for (pi, ii) in po.iter().enumerate() {
288                if pi >= LOAD_PROF_MIN_DAYS {
289                    break;
290                }
291                if let Some(cn) = dy_cn.get_mut(ii) {
292                    *cn += 1;
293                } else {
294                    dy_cn.insert(*ii, 1);
295                }
296                if pi > 0 {
297                    print!(",");
298                }
299                print!("{ii}");
300            }
301            print!("] n:{} [", ne.len());
302            for (ni, ii) in ne.iter().enumerate() {
303                if ni >= LOAD_PROF_MIN_DAYS {
304                    break;
305                }
306                if let Some(cn) = dy_cn.get_mut(ii) {
307                    *cn += 1;
308                } else {
309                    dy_cn.insert(*ii, 1);
310                }
311                if ni > 0 {
312                    print!(",");
313                }
314                print!("{ii}");
315            }
316            print!("]");
317            println!();
318        }
319        for ldpf in sub.fdldp.values() {
320            let f = &ldpf.feed;
321            //p03_calc_lp_1(ldpf)?;
322            let (po, ne) = p03_calc_lp_3(ldpf)?;
323            let sbre = SubLoadProfRepr {
324                sub: s.to_string(),
325                year: yr.to_string(),
326                pos_rep: p03_draw_sub_av(ldpf, &po, "PO")?,
327                neg_rep: p03_draw_sub_av(ldpf, &ne, "NE")?,
328            };
329            p03_lp_repr.insert(format!("{s}-{f}"), sbre);
330        }
331    }
332    //println!("{dy_cn:?}");
333    let mut dycn = dy_cn.iter().map(|(a, b)| (*a, *b)).collect::<Vec<_>>();
334    dycn.sort_by(|a, b| b.1.cmp(&a.1));
335    for (d, c) in dycn {
336        println!("{d} - {c}");
337    }
338    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p03_lp_repr_{yr}.bin");
339    println!("write pre {} to {fnm}", p03_lp_repr.len());
340    let bin: Vec<u8> = bincode::encode_to_vec(&p03_lp_repr, bincode::config::standard()).unwrap();
341    std::fs::write(fnm, bin).unwrap();
342    Ok(())
343}
344
345pub fn p03_calc_lp(yr: &str) -> Result<(), Box<dyn Error>> {
346    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p02_sub_lp_{yr}.bin");
347    let bytes = std::fs::read(fnm).unwrap();
348    let (subh, _): (HashMap<String, SubLoadProf>, usize) =
349        bincode::decode_from_slice(&bytes[..], bincode::config::standard()).unwrap();
350    let mut p03_lp_repr = HashMap::<String, SubLoadProfRepr>::new();
351    for (s, sub) in subh {
352        if let Some(ldpf) = &sub.ldpf {
353            print!("{s} ");
354            let (po, ne) = p03_calc_lp_1(ldpf)?;
355            let sbre = SubLoadProfRepr {
356                sub: s.to_string(),
357                year: yr.to_string(),
358                pos_rep: p03_draw_sub_av(ldpf, &po, "PO")?,
359                neg_rep: p03_draw_sub_av(ldpf, &ne, "NE")?,
360            };
361            p03_lp_repr.insert(s.to_string(), sbre);
362
363            print!("  p:{} [", po.len());
364            for (pi, ii) in po.iter().enumerate() {
365                if pi >= LOAD_PROF_MIN_DAYS {
366                    break;
367                }
368                if pi > 0 {
369                    print!(",");
370                }
371                print!("{ii}");
372            }
373            print!("] n:{} [", ne.len());
374            for (ni, ii) in ne.iter().enumerate() {
375                if ni >= LOAD_PROF_MIN_DAYS {
376                    break;
377                }
378                if ni > 0 {
379                    print!(",");
380                }
381                print!("{ii}");
382            }
383            print!("]");
384            println!();
385        }
386        for ldpf in sub.fdldp.values() {
387            let f = &ldpf.feed;
388            //p03_calc_lp_1(ldpf)?;
389            let (po, ne) = p03_calc_lp_1(ldpf)?;
390            let sbre = SubLoadProfRepr {
391                sub: s.to_string(),
392                year: yr.to_string(),
393                pos_rep: p03_draw_sub_av(ldpf, &po, "PO")?,
394                neg_rep: p03_draw_sub_av(ldpf, &ne, "NE")?,
395            };
396            p03_lp_repr.insert(format!("{s}-{f}"), sbre);
397        }
398    }
399    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p03_lp_repr_{yr}.bin");
400    println!("write pre {} to {fnm}", p03_lp_repr.len());
401    let bin: Vec<u8> = bincode::encode_to_vec(&p03_lp_repr, bincode::config::standard()).unwrap();
402    std::fs::write(fnm, bin).unwrap();
403    Ok(())
404}
405
406use std::path::Path;
407
408pub fn p03_draw_all() -> Result<(), Box<dyn Error>> {
409    for yr in ["2023", "2024"] {
410        println!("{yr}");
411        let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p02_sub_lp_{yr}.bin");
412        let bytes = std::fs::read(fnm).unwrap();
413        let (subh, _): (HashMap<String, SubLoadProf>, usize) =
414            bincode::decode_from_slice(&bytes[..], bincode::config::standard()).unwrap();
415        println!("sub {}", subh.len());
416        //println!("subh: {}", subh.len());
417        let mut keys: Vec<_> = subh.keys().collect();
418        keys.sort();
419        for sb in &keys {
420            //let ddr = format!("/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/000_01-01");
421            let ddr = format!("/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/364_12-31");
422            if Path::new(&ddr).exists() {
423                println!("{yr}-{sb} {ddr} exists");
424                continue;
425            }
426            let sb = sb.to_string();
427            let sub = subh.get(&sb).unwrap();
428            //println!("s: {}", sub.sub);
429            /*
430            let mut fc = 0;
431            for f in &sub.feeds {
432                let f = f.to_string();
433                let flp = sub.fdldp.get(&f).unwrap();
434                println!("  f:{f} - {}", flp.days.len());
435                for (di, dlp) in flp.days.iter().enumerate() {
436                    if let Some(dlp) = dlp {
437                        let lb1 = format!("{sb}-{f}");
438                        let mon = dlp.mon;
439                        let mdt = dlp.mdt;
440                        let dnm = format!(
441                            "/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/{di:03}_{mon:02}-{mdt:02}/{lb1}.jpg"
442                        );
443                        if !Path::new(&dnm).exists() {
444                            fc += 1;
445                        }
446                    }
447                }
448            }
449            if fc == 0 {
450                println!("{yr}-{sb} exists");
451                continue;
452            }
453            */
454            println!(">>> {yr}-{sb} NEW");
455            for f in &sub.feeds {
456                let f = f.to_string();
457                let flp = sub.fdldp.get(&f).unwrap();
458                println!("  f:{f} - {}", flp.days.len());
459                for (di, dlp) in flp.days.iter().enumerate() {
460                    if let Some(dlp) = dlp {
461                        let lb1 = format!("{sb}-{f}");
462                        let mon = dlp.mon;
463                        let mdt = dlp.mdt;
464                        let lb2 = format!("{yr}-{mon:02}-{mdt:02}");
465                        let val = dlp.val;
466                        let dnm = format!(
467                            "/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/{di:03}_{mon:02}-{mdt:02}"
468                        );
469                        std::fs::create_dir_all(&dnm)?;
470                        let fnm = format!("{dnm}/{lb1}.jpg");
471                        //println!("{lb1} {lb2} -> {fnm}");
472                        let sz = (400, 300);
473                        let rf = Vec::<(String, f32)>::new();
474
475                        let drlp = LoadProf {
476                            lb1,
477                            lb2,
478                            fnm,
479                            val,
480                            sz,
481                            rf,
482                        };
483                        drlp.draw_prof()?;
484                    }
485                }
486            }
487            if let Some(ldpf) = &sub.ldpf {
488                for (di, dlp) in ldpf.days.iter().enumerate() {
489                    if let Some(dlp) = dlp {
490                        //let lb1 = format!("{sb}");
491                        let lb1 = sb.to_string();
492                        let mon = dlp.mon;
493                        let mdt = dlp.mdt;
494                        let lb2 = format!("{yr}-{mon:02}-{mdt:02}");
495                        let val = dlp.val;
496                        let dnm = format!(
497                            "/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/{di:03}_{mon:02}-{mdt:02}"
498                        );
499                        std::fs::create_dir_all(&dnm)?;
500                        let fnm = format!("{dnm}/{lb1}.jpg");
501                        //println!("{lb1} {lb2} -> {fnm}");
502                        let sz = (400, 300);
503                        let rf = Vec::<(String, f32)>::new();
504
505                        let drlp = LoadProf {
506                            lb1,
507                            lb2,
508                            fnm,
509                            val,
510                            sz,
511                            rf,
512                        };
513                        drlp.draw_prof()?;
514                    }
515                }
516            }
517        }
518    }
519    Ok(())
520}
521
522pub fn p03_draw_slp(yr: &str, sb: &str) -> Result<(), Box<dyn Error>> {
523    let fnm = format!("/mnt/e/CHMBACK/pea-data/data2/p02_sub_lp_{yr}.bin");
524    let bytes = std::fs::read(fnm).unwrap();
525    let (subh, _): (HashMap<String, SubLoadProf>, usize) =
526        bincode::decode_from_slice(&bytes[..], bincode::config::standard()).unwrap();
527    println!("sub {}", subh.len());
528    //println!("subh: {}", subh.len());
529    let mut keys: Vec<_> = subh.keys().collect();
530    keys.sort();
531    //for sb in &keys {
532    {
533        let sb = sb.to_string();
534        let sub = subh.get(&sb).unwrap();
535        println!("s: {}", sub.sub);
536        if let Some(ldpf) = &sub.ldpf {
537            for (di, dlp) in ldpf.days.iter().enumerate() {
538                if let Some(dlp) = dlp {
539                    let lb1 = format!("{sb}");
540                    let mon = dlp.mon;
541                    let mdt = dlp.mdt;
542                    let lb2 = format!("{yr}-{mon:02}-{mdt:02}");
543                    let val = dlp.val;
544                    let dnm = format!(
545                        "/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/{di:03}_{mon:02}-{mdt:02}"
546                    );
547                    std::fs::create_dir_all(&dnm)?;
548                    let fnm = format!("{dnm}/{lb1}.jpg");
549                    //println!("{lb1} {lb2} -> {fnm}");
550                    let sz = (400, 300);
551                    let rf = Vec::<(String, f32)>::new();
552
553                    let drlp = LoadProf {
554                        lb1,
555                        lb2,
556                        fnm,
557                        val,
558                        sz,
559                        rf,
560                    };
561                    drlp.draw_prof()?;
562                }
563            }
564        } else {
565            println!("  NO SUB SUM");
566        }
567        for f in &sub.feeds {
568            let f = f.to_string();
569            let flp = sub.fdldp.get(&f).unwrap();
570            println!("  f:{f} - {}", flp.days.len());
571            for (di, dlp) in flp.days.iter().enumerate() {
572                if let Some(dlp) = dlp {
573                    let lb1 = format!("{sb}-{f}");
574                    let mon = dlp.mon;
575                    let mdt = dlp.mdt;
576                    let lb2 = format!("{yr}-{mon:02}-{mdt:02}");
577                    let val = dlp.val;
578                    let dnm = format!(
579                        "/mnt/e/CHMBACK/pea-data/lpdrw/{yr}/{sb}/{di:03}_{mon:02}-{mdt:02}"
580                    );
581                    std::fs::create_dir_all(&dnm)?;
582                    let fnm = format!("{dnm}/{lb1}.jpg");
583                    //println!("{lb1} {lb2} -> {fnm}");
584                    let sz = (400, 300);
585                    let rf = Vec::<(String, f32)>::new();
586
587                    let drlp = LoadProf {
588                        lb1,
589                        lb2,
590                        fnm,
591                        val,
592                        sz,
593                        rf,
594                    };
595                    drlp.draw_prof()?;
596                }
597            }
598        }
599    }
600
601    Ok(())
602}