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  }