func viewLib(c *command) { c.assertNArg(1) lib := util.Library(c.flags.Arg(0)) fmt.Printf("Name: %s\n", lib.Name()) fmt.Printf("Tag: %s\n", strings.Join(libraryTag(lib), "/")) fmt.Printf("Size: %d\n", lib.Size()) fmt.Printf("Fragment Size: %d\n", lib.FragmentSize()) fmt.Printf("IsStructure: %v\n", fragbag.IsStructure(lib)) fmt.Printf("IsSequence: %v\n", fragbag.IsSequence(lib)) }
// ProcessBowers is a convenient wrapper around BowerOpen that processes each // bower value in parallel and sends the resulting BOW value on the channel // returned. The number of goroutines spawned is equivalent to N. // // It is appropriate for fpaths to be the arguments given to be command line // arguments. Each directory is recursively expanded to its files, and special // syntax is parsed as well. // // If `hideProgress` is true, then a progress bar will not be emitted to // stderr. // // If `models` is true, then every model in a PDB bower file will have its // BOW computed. Otherwise, the first model from each chain will be used. func ProcessBowers( fpaths []string, lib fragbag.Library, models bool, n int, hideProgress bool, ) <-chan bow.Bowed { if n <= 0 { n = 1 } results := make(chan bow.Bowed, n*2) fpaths = AllFilesFromArgs(fpaths) go func() { var progress *Progress totalJobs := 0 if !hideProgress { totalJobs = numJobs(fpaths) progress = NewProgress(totalJobs) } // We use two levels of concurrency here. The first is at the level // of translating files into bowers. The second is at the level of // computing BOWs from bowers. // The first level is necessary because there can a large number of // bower files given, where each file only produces a few BOWs. // The second level is necessary because there is a lot of variation // between the number of bowers that a single file can produce. For // example, while most PDB files only produce a few, some FASTA files // can produce millions. files := make(chan string, n*2) bs := make(chan interface{}, n*2) // channel of bowers wgBowers := new(sync.WaitGroup) wgFiles := new(sync.WaitGroup) // goroutines for computing BOWs from bowers for i := 0; i < n; i++ { wgBowers.Add(1) go func() { defer wgBowers.Done() for b := range bs { var bw bow.Bowed if fragbag.IsStructure(lib) { lib := lib.(fragbag.StructureLibrary) bw = b.(bow.StructureBower).StructureBow(lib) } else if fragbag.IsSequence(lib) { lib := lib.(fragbag.SequenceLibrary) bw = b.(bow.SequenceBower).SequenceBow(lib) } else { Fatalf("Unknown fragment library %T", lib) } results <- bw } }() } // goroutines for translating files into bowers for i := 0; i < n; i++ { wgFiles.Add(1) go func() { defer wgFiles.Done() for fpath := range files { var err error for b := range BowerOpen(fpath, lib, models) { if b.Err != nil { err = b.Err } else { bs <- b.Bower } if IsFasta(fpath) { // each sequence counts progress.JobDone(err) } } if IsPDB(fpath) { // PDB file only counts as one job progress.JobDone(err) } } }() } for _, fpath := range fpaths { files <- fpath } close(files) wgFiles.Wait() close(bs) wgBowers.Wait() progress.Close() close(results) }() return results }