github.com/andrewrech/ih-abstract@v0.0.0-20210322142951-2fec1c8d0f38/ih-abstract.go (about) 1 package main 2 3 import ( 4 "log" 5 "os" 6 "strings" 7 ) 8 9 // ih-abstract streams input raw pathology results to the immune.health.report R package for report generation and quality assurance. The input is .csv data or direct streaming from a Microsoft SQL driver-compatible database. The output is filtered .csv files for incremental new report generation and quality assurance. 10 // Optionally, Immune Health filtering can be turned off to use ih-abstract as a general method to retrieve arbitrary or incremental pathology results. 11 func main() { 12 usage() 13 14 log.Println("ih-abstract starting") 15 16 f := flagParse() 17 18 if *f.example { 19 printConf() 20 os.Exit(0) 21 } 22 23 mainInner(f, os.Stdin) 24 } 25 26 // mainInner facilitates testing by allowing parameters to be passed to the main program code path. 27 func mainInner(f flags, in *os.File) { 28 // parallel process completion signals 29 parallelProcesses := 9 30 doneSignals := make([]chan struct{}, parallelProcesses) 31 32 // result communication channels 33 allResults := make(map[string](chan []string)) // unfiltered 34 filteredResults := make(map[string](chan []string)) // from filtering 35 msiResults := make(map[string](chan []string)) // msi strings 36 pdl1Results := make(map[string](chan []string)) // pdl1 strings 37 var buf int64 = 2e7 38 diffResults := make(chan []string, buf) // results to diff 39 40 // read raw input data 41 r := read(f, in) 42 doneSignals[0] = r.done 43 44 // if no filter 45 // write all results and diff results 46 diffResults = make(chan []string, buf) 47 if *f.noFilter { 48 doneSignals[1] = make(chan struct{}) 49 allResults["results"] = make(chan []string, buf) 50 allResults["results"], diffResults, doneSignals[1] = splitCh(r.out) 51 } 52 53 // if immune health filter 54 // write filtered results, diff results, immune health results 55 if !*f.noFilter { 56 filteredResults, doneSignals[2] = filterResults(r.out, r.header) 57 // exclude intermediate channels 58 // containing 'diff' in channel name 59 // these are sent to DiffUnq below, not written out 60 for i, c := range filteredResults { 61 if strings.Contains(i, "diff") { 62 continue 63 } 64 allResults[i] = c 65 } 66 67 diffResults = filteredResults["diff"] 68 69 // determine unique strings 70 pdl1Results, doneSignals[3] = DiffUnq(filteredResults["pdl1-to-diff"], "pdl1") 71 msiResults, doneSignals[4] = DiffUnq(filteredResults["msi-to-diff"], "msi") 72 73 // write unique strings 74 doneSignals[5] = Write([]string{"unique-result"}, pdl1Results) 75 doneSignals[6] = Write([]string{"unique-result"}, msiResults) 76 } 77 78 // diff 79 if *f.old != "" { 80 allResults["results-increment"], doneSignals[7] = Diff(f.old, diffResults, r.header) 81 } 82 83 doneSignals[8] = Write(r.header, allResults) 84 85 // wait for all parallel processes to finish 86 for _, signal := range doneSignals { 87 if signal != nil { 88 <-signal 89 } 90 } 91 }