func main() { db := util.OpenBowDB(util.Arg(0)) out := util.CreateFile(util.Arg(1)) printf := func(format string, v ...interface{}) { fmt.Fprintf(out, format, v...) } // Set our search options. bowOpts := bowdb.SearchDefault bowOpts.Limit = -1 printf("QueryID\tResultID\tCosine\tEuclid\n") entries, err := db.ReadAll() util.Assert(err, "Could not read BOW database entries") for _, entry := range entries { results := db.Search(bowOpts, entry) for _, result := range results { printf("%s\t%s\t%0.4f\t%0.4f\n", entry.Id, result.Bowed.Id, result.Cosine, result.Euclid) } printf("\n") } util.Assert(out.Close()) util.Assert(db.Close()) }
func main() { fasInp := util.Arg(0) fmapOut := util.Arg(1) fmap := util.GetFmap(fasInp) util.FmapWrite(util.CreateFile(fmapOut), fmap) }
func main() { in, out := util.Arg(0), util.Arg(1) r, w := ioFromFile(in, flagInFmt).r, ioFromFile(out, flagOutFmt).w inf := util.OpenFile(in) defer inf.Close() msa, err := r(inf) util.Assert(err, "Error parsing '%s'", in) outf := util.CreateFile(out) defer outf.Close() util.Assert(w(outf, msa), "Error writing '%s'", out) }
func main() { flag.BoolVar(&flagAllFragments, "all-fragments", flagAllFragments, "When set, all fragments will be shown, even if the best fragment\n"+ "of each residue set is the same.") util.FlagParse( "fraglib align.{fasta,ali,a2m,a3m} out-csv", "Writes a CSV file to out-csv containing the best matching fragment\n"+ "for each pairwise contiguous set of residues between the\n"+ "first two proteins in the alignment.") util.AssertNArg(3) flib := util.SequenceLibrary(util.Arg(0)) aligned := util.MSA(util.Arg(1)) outcsv := util.CreateFile(util.Arg(2)) csvWriter := csv.NewWriter(outcsv) csvWriter.Comma = '\t' defer csvWriter.Flush() pf := func(record ...string) { util.Assert(csvWriter.Write(record), "Problem writing to '%s'", outcsv) } pf("start1", "end1", "start2", "end2", "frag1", "frag2", "rat1", "rat2") iter := newContiguous( flib.FragmentSize(), aligned.GetFasta(0), aligned.GetFasta(1)) for iter.next() { best1 := flib.BestSequenceFragment(iter.res1) best2 := flib.BestSequenceFragment(iter.res2) if !flagAllFragments && best1 == best2 { continue } if best1 == -1 || best2 == -1 { continue } p1 := flib.AlignmentProb(best1, iter.res1) p2 := flib.AlignmentProb(best2, iter.res2) if p1.Distance(p2) > 0.14 { continue } pf( fmt.Sprintf("%d", iter.s1()), fmt.Sprintf("%d", iter.e1()), fmt.Sprintf("%d", iter.s2()), fmt.Sprintf("%d", iter.e2()), fmt.Sprintf("%d", best1), fmt.Sprintf("%d", best2), fmt.Sprintf("%f", p1), fmt.Sprintf("%f", p2), ) } }
func main() { inFasta := util.Arg(0) outHHM := util.Arg(1) hhblits := hhsuite.HHBlitsDefault hhmake := hhsuite.HHMakePseudo hhblits.Verbose = !flagQuiet hhmake.Verbose = !flagQuiet HHM, err := hhsuite.BuildHHM( hhblits, hhmake, util.FlagSeqDB, inFasta) util.Assert(err, "Error building HHM") util.Assert(hmm.WriteHHM(util.CreateFile(outHHM), HHM), "Error writing HHM '%s'", outHHM) }
func main() { flag.BoolVar(&flagAllFragments, "all-fragments", flagAllFragments, "When set, all fragments will be shown, even if the best fragment\n"+ "of each ATOM set is the same.") util.FlagParse( "fraglib align.{fasta,ali,a2m,a3m} pdb-file out-csv", "Writes a CSV file to out-csv containing the best matching fragment\n"+ "for each pairwise contiguous set of alpha-carbon atoms of the\n"+ "first two proteins in the alignment and PDB file.") util.AssertNArg(4) flib := util.StructureLibrary(util.Arg(0)) aligned := util.MSA(util.Arg(1)) pentry := util.PDBRead(util.Arg(2)) outcsv := util.CreateFile(util.Arg(3)) csvWriter := csv.NewWriter(outcsv) csvWriter.Comma = '\t' defer csvWriter.Flush() pf := func(record ...string) { util.Assert(csvWriter.Write(record), "Problem writing to '%s'", outcsv) } pf("start1", "end1", "start2", "end2", "frag1", "frag2", "frag_rmsd") iter := newContiguous( flib.FragmentSize(), aligned.GetFasta(0), aligned.GetFasta(1), pentry.Chains[0], pentry.Chains[1]) for iter.next() { best1 := flib.BestStructureFragment(iter.atoms1) best2 := flib.BestStructureFragment(iter.atoms2) if !flagAllFragments && best1 == best2 { continue } bestRmsd := structure.RMSD(flib.Atoms(best1), flib.Atoms(best2)) pf( fmt.Sprintf("%d", iter.s1()), fmt.Sprintf("%d", iter.e1()), fmt.Sprintf("%d", iter.s2()), fmt.Sprintf("%d", iter.e2()), fmt.Sprintf("%d", best1), fmt.Sprintf("%d", best2), fmt.Sprintf("%f", bestRmsd), ) } }
func main() { dbPath := util.Arg(0) fragLibDir := util.Arg(1) pdbFiles := flag.Args()[2:] util.Assert(createBowDb(dbPath, fragLibDir, pdbFiles)) db := util.OpenBowDB(dbPath) _, err := db.ReadAll() util.Assert(err, "Could not read BOW database entries") bowOpts := bowdb.SearchDefault bowOpts.Limit = 200 mattOpts := matt.DefaultConfig mattOpts.Verbose = false chains := createChains(pdbFiles) mattArgs := createMattArgs(chains) tabw := tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0) header := []byte( "BOW entry\t" + "BOW chain\t" + "BOW dist\t" + "Matt entry\t" + "Matt chain\t" + "Matt dist\n") for i, chain := range chains { marg := mattArgs[i] bowOrdered := getBowOrdering(db, bowOpts, bow.BowerFromChain(chain)) mattOrdered := getMattOrdering(mattOpts, marg, mattArgs) fmt.Printf("Ordering for %s (chain %c)\n", chain.Entry.IdCode, chain.Ident) compared := comparison([2]ordering{bowOrdered, mattOrdered}) tabw.Write(header) tabw.Write([]byte(compared.String())) tabw.Flush() fmt.Println("\n") } util.Assert(db.Close()) }
func main() { fmap := util.FmapRead(util.Arg(0)) fmt.Printf("%s\n\n", fmap.Name) for _, frags := range fmap.Segments { fmt.Printf("\nSEGMENT: %d %d (%d)\n", frags.Start, frags.End, len(frags.Frags)) frags.Write(os.Stdout) } }
func main() { var f io.Reader var err error f = util.OpenFile(flag.Arg(0)) if strings.HasSuffix(flag.Arg(0), ".gz") { f, err = gzip.NewReader(f) util.Assert(err) } cifEntry, err := pdbx.Read(f) util.Assert(err, "Could not read PDBx/mmCIF file") fasEntries := make([]seq.Sequence, 0, 5) for _, ent := range cifEntry.Entities { for _, chain := range ent.Chains { if !isChainUsable(chain) || len(ent.Seq) == 0 { continue } fasEntry := seq.Sequence{ Name: chainHeader(chain), Residues: ent.Seq, } fasEntries = append(fasEntries, fasEntry) } } if len(fasEntries) == 0 { util.Fatalf("Could not find any chains with amino acids.") } var fasOut io.Writer if flag.NArg() == 1 { fasOut = os.Stdout } else { if len(flagSplit) > 0 { util.Fatalf("The '--split' option is incompatible with a single " + "output file.") } fasOut = util.CreateFile(util.Arg(1)) } if len(flagSplit) == 0 { util.Assert(fasta.NewWriter(fasOut).WriteAll(fasEntries), "Could not write FASTA file '%s'", fasOut) } else { for _, entry := range fasEntries { fp := path.Join(flagSplit, fmt.Sprintf("%s.fasta", entry.Name)) out := util.CreateFile(fp) w := fasta.NewWriter(out) util.Assert(w.Write(entry), "Could not write to '%s'", fp) util.Assert(w.Flush(), "Could not write to '%s'", fp) } } }
func main() { libPath := util.Arg(0) chain := util.Arg(1) pdbEntryPath := util.Arg(2) bowOut := util.Arg(3) lib := util.StructureLibrary(libPath) entry := util.PDBRead(pdbEntryPath) thechain := entry.Chain(chain[0]) if thechain == nil || !thechain.IsProtein() { util.Fatalf("Could not find chain with identifier '%c'.", chain[0]) } bow := bow.BowerFromChain(thechain).StructureBow(lib) if bowOut == "--" { fmt.Println(bow) } else { util.BowWrite(util.CreateFile(bowOut), bow) } }
func main() { if len(util.FlagCpuProf) > 0 { f := util.CreateFile(util.FlagCpuProf) pprof.StartCPUProfile(f) defer f.Close() defer pprof.StopCPUProfile() } if len(flagGobIt) > 0 { astralDir := util.Arg(0) dists := readAlignmentDists(astralDir) enc := gob.NewEncoder(util.CreateFile(flagGobIt)) util.Assert(enc.Encode(dists), "Could not GOB encode distances") return } var dists *intern.Table if util.IsDir(util.Arg(0)) { dists = readAlignmentDists(util.Arg(0)) } else { dec := gob.NewDecoder(util.OpenFile(util.Arg(0))) util.Assert(dec.Decode(&dists), "Could not GOB decode distances") } treeFile := util.Arg(1) outPath := util.Arg(2) treeReader := newick.NewReader(util.OpenFile(treeFile)) tree, err := treeReader.ReadTree() util.Assert(err, "Could not read newick tree") csvw := csv.NewWriter(util.CreateFile(outPath)) clusters := treeClusters(flagThreshold, dists, tree) util.Assert(csvw.WriteAll(clusters)) }
func main() { saveto := util.CreateFile(util.Arg(0)) defer saveto.Close() w := func(format string, v ...interface{}) { _, err := fmt.Fprintf(saveto, format, v...) util.Assert(err) } var fmats []*bufio.Reader for _, fmat := range util.Args()[1:] { fmats = append(fmats, bufio.NewReader(util.OpenFile(fmat))) } LOOP: for { var columns int scores := make([][]float64, len(fmats)) // matrix -> fields -> sas score for i, fmat := range fmats { line, err := fmat.ReadBytes('\n') if len(line) == 0 && err == io.EOF { break LOOP } else if err != io.EOF { util.Assert(err) } fields := bytes.Fields(line) columns = len(fields) scores[i] = make([]float64, columns) for j, sas := range fields { scores[i][j], err = strconv.ParseFloat(string(sas), 64) util.Assert(err) } } before := "" for j := 0; j < columns; j++ { best := scores[0][j] for i := 1; i < len(scores); i++ { if scores[i][j] < best { best = scores[i][j] } } if best == 0 { w("%s0", before) } else { w("%s%f", before, best) } before = " " } w("\n") } }
func main() { pdbf1, chain1, s1, e1 := util.Arg(0), util.Arg(1), util.Arg(2), util.Arg(3) pdbf2, chain2, s2, e2 := util.Arg(4), util.Arg(5), util.Arg(6), util.Arg(7) entry1 := util.PDBRead(pdbf1) entry2 := util.PDBRead(pdbf2) s1n, e1n := util.ParseInt(s1), util.ParseInt(e1) s2n, e2n := util.ParseInt(s2), util.ParseInt(e2) r, err := pdb.RMSD( entry1, chain1[0], s1n, e1n, entry2, chain2[0], s2n, e2n) util.Assert(err) fmt.Println(r) }
func main() { rfasta := util.OpenFasta(util.Arg(0)) dir := util.Arg(1) util.Assert(os.MkdirAll(dir, 0777)) fr := fasta.NewReader(rfasta) for { s, err := fr.Read() if err != nil { if err == io.EOF { break } util.Assert(err) } s.Name = strings.Fields(s.Name)[0] fw := util.CreateFile(path.Join(dir, s.Name+".fasta")) w := fasta.NewWriter(fw) util.Assert(w.Write(s)) util.Assert(w.Flush()) util.Assert(fw.Close()) } }
func main() { lib = util.StructureLibrary(util.Arg(0)) pdbEntry := util.PDBRead(util.Arg(1)) if util.NArg() == 2 { for _, chain := range pdbEntry.Chains { atoms := chain.CaAtoms() bestFragsForRegion(chain, atoms, 0, len(atoms)) } } else { chainId := util.Arg(2) chain := pdbEntry.Chain(chainId[0]) if chain == nil || !chain.IsProtein() { util.Fatalf("Could not find protein chain with id '%c'.", chainId) } atoms := chain.CaAtoms() if util.NArg() == 3 { bestFragsForRegion(chain, atoms, 0, len(atoms)) } else { if util.NArg() != 5 { log.Println("Both a start and end must be provided.") util.Usage() } s, e := util.Arg(3), util.Arg(4) sn, en := util.ParseInt(s)-1, util.ParseInt(e) if en-sn < lib.FragmentSize() { util.Fatalf("The range [%s, %s] specifies %d alpha-carbon "+ "atoms while at least %d alpha-carbon atoms are required "+ "for the given fragment library.", s, e, en-sn, lib.FragmentSize()) } bestFragsForRegion(chain, atoms, sn, en) } } }
func main() { a3mPath := util.Arg(0) fa3m := util.OpenFile(a3mPath) freader := fasta.NewReader(fa3m) freader.TrustSequences = true seqs, err := freader.ReadAll() util.Assert(err, "Could not read fasta format '%s'", a3mPath) util.Assert(fa3m.Close()) w := util.CreateFile(a3mPath) fwriter := fasta.NewWriter(w) fwriter.Columns = 0 for _, seq := range seqs { if len(seq.Residues) > 0 { util.Assert(fwriter.Write(seq)) } } util.Assert(fwriter.Flush()) util.Assert(w.Close()) }
func main() { libFile := util.Arg(0) brkFile := util.Arg(1) lib := util.StructureLibrary(libFile) stderrf("Loading PDB files into memory...\n") entries := make([]*pdb.Entry, util.NArg()-2) for i, pdbfile := range flag.Args()[2:] { entries[i] = util.PDBRead(pdbfile) } stderrf("Comparing the results of old fragbag and new fragbag on " + "each PDB file...\n") for _, entry := range entries { stderrf("Testing %s...\n", entry.Path) fmt.Printf("Testing %s\n", entry.Path) // Try to run old fragbag first. The output is an old-style BOW. oldBowStr, err := runOldFragbag(brkFile, entry.Path, lib.Size(), lib.FragmentSize()) if err != nil { fmt.Println(err) fmt.Printf("The output was:\n%s\n", oldBowStr) divider() continue } oldBow, err := bow.NewOldStyleBow(lib.Size(), oldBowStr) if err != nil { fmt.Printf("Could not parse the following as an old style "+ "BOW:\n%s\n", oldBowStr) fmt.Printf("%s\n", err) divider() continue } // Now use package fragbag to compute a BOW. var newBow bow.Bow if flagOldStyle { newBow = oldStyle{entry}.StructureBow(lib) } else { newBow = newStyle{entry}.StructureBow(lib) } // Create a diff and check if they are the same. If so, we passed. // Otherwise, print an error report. diff := bow.NewBowDiff(oldBow, newBow) if diff.IsSame() { fmt.Println("PASSED.") divider() continue } // Ruh roh... fmt.Println("FAILED.") fmt.Printf("\nOld BOW:\n%s\n\nNew BOW:\n%s\n", oldBow, newBow) fmt.Printf("\nDiff:\n%s\n", diff) divider() } stderrf("Done!\n") }
func main() { if len(util.FlagCpuProf) > 0 { f := util.CreateFile(util.FlagCpuProf) pprof.StartCPUProfile(f) defer f.Close() defer pprof.StopCPUProfile() } // Read all CATH domains, the best-of-all matrix, and the matrix for // each aligner. domains := readDomains(util.Arg(0)) boa := readMatrix(domains, util.Arg(1)) aligners := make([]aligner, 0) flibs := make([]flib, 0) for i := 2; i < util.NArg(); i += 2 { fpath := util.Arg(i) if path.Ext(fpath) == ".bowdb" { db := util.OpenBowDB(fpath) records, err := db.ReadAll() util.Assert(err) bowed := make([]bow.Bowed, domains.in.Len()) for _, b := range records { if !domains.in.Exists(b.Id) { util.Fatalf("Found ID in bowdb that isn't in the list "+ "of CATH domains provided: %s", b.Id) } bowed[domains.in.Atom(b.Id)] = b } flibs = append(flibs, flib{db, bowed, util.Arg(i + 1)}) } else { aligners = append(aligners, aligner{ readMatrix(domains, fpath), util.Arg(i + 1), }) } } // Now remove CATH domains that don't have a corresponding structure file. // We don't do this initially since the matrix files are indexed with // respect to all CATH domains (includings ones without structure). // This is an artifact of the fact that the matrices were generated with // a very old version of CATH. domains.removeOldDomains() if a := matrixAuc(domains, boa, boa, flagThreshold); a != 1.0 { util.Fatalf("Something is wrong. The AUC of the best-of-all matrix "+ "with respect to itself is %f, but it should be 1.0.", a) } if len(aligners) > 0 { fmt.Println("Computing AUC for aligners...") writeAuc := func(aligner aligner) struct{} { w := util.CreateFile(aligner.outpath) a := matrixAuc(domains, boa, aligner.matrix, flagThreshold) fmt.Fprintf(w, "%f\n", a) return struct{}{} } fun.ParMap(writeAuc, aligners) } if len(flibs) > 0 { fmt.Println("Computing AUC for bowdbs...") writeAuc := func(flib flib) struct{} { w := util.CreateFile(flib.outpath) a := flibAuc(domains, boa, flib, flagThreshold) fmt.Fprintf(w, "%f\n", a) return struct{}{} } fun.ParMap(writeAuc, flibs) } }
func main() { pdbEntry := util.PDBRead(flag.Arg(0)) fasEntries := make([]seq.Sequence, 0, 5) if !flagSeparateChains { var fasEntry seq.Sequence if len(pdbEntry.Chains) == 1 { fasEntry.Name = chainHeader(pdbEntry.OneChain()) } else { fasEntry.Name = fmt.Sprintf("%s", strings.ToLower(pdbEntry.IdCode)) } seq := make([]seq.Residue, 0, 100) for _, chain := range pdbEntry.Chains { if isChainUsable(chain) { seq = append(seq, chain.Sequence...) } } fasEntry.Residues = seq if len(fasEntry.Residues) == 0 { util.Fatalf("Could not find any amino acids.") } fasEntries = append(fasEntries, fasEntry) } else { for _, chain := range pdbEntry.Chains { if !isChainUsable(chain) { continue } fasEntry := seq.Sequence{ Name: chainHeader(chain), Residues: chain.Sequence, } fasEntries = append(fasEntries, fasEntry) } } if len(fasEntries) == 0 { util.Fatalf("Could not find any chains with amino acids.") } var fasOut io.Writer if flag.NArg() == 1 { fasOut = os.Stdout } else { if len(flagSplit) > 0 { util.Fatalf("The '--split' option is incompatible with a single " + "output file.") } fasOut = util.CreateFile(util.Arg(1)) } if len(flagSplit) == 0 { util.Assert(fasta.NewWriter(fasOut).WriteAll(fasEntries), "Could not write FASTA file '%s'", fasOut) } else { for _, entry := range fasEntries { fp := path.Join(flagSplit, fmt.Sprintf("%s.fasta", entry.Name)) out := util.CreateFile(fp) w := fasta.NewWriter(out) util.Assert(w.Write(entry), "Could not write to '%s'", fp) util.Assert(w.Flush(), "Could not write to '%s'", fp) } } }
func main() { rfasta := util.OpenFasta(util.Arg(0)) count, err := fasta.QuickSequenceCount(rfasta) util.Assert(err) fmt.Println(count) }
func main() { if len(util.FlagCpuProf) > 0 { f := util.CreateFile(util.FlagCpuProf) pprof.StartCPUProfile(f) defer f.Close() defer pprof.StopCPUProfile() } vectors := readVectors(util.Arg(1)) groups := readCathGroups(util.Args()[2:]) out := util.CreateFile(util.Arg(0)) defer out.Close() pf := func(format string, v ...interface{}) { // fmt.Printf(format, v...) fmt.Fprintf(out, format, v...) } type labeledPval struct { Name1, Name2 string Pval float32 } b := stdb(vectors, groups) pairs := combinations(len(groups)) dopairs, pvals := make(chan pair), make(chan labeledPval) wg := new(sync.WaitGroup) for i := 0; i < util.FlagCpu; i++ { wg.Add(1) go func() { for p := range dopairs { g1, g2 := groups[p.i], groups[p.j] b1, b2 := b[p.i], b[p.j] bm1, bm2 := bmean(b1, b2) bw := delta(bm1, bm2) randws := make([]float32, 1000) for i := range randws { randws[i] = delta(shuffle_mean_rows(b1, b2)) } bigger := 0 for _, rw := range randws { if rw >= bw { bigger++ } } pval := float32(bigger) / float32(len(randws)) pvals <- labeledPval{g1.Name, g2.Name, pval} } wg.Done() }() } done := make(chan struct{}) go func() { sig, cutoff := 0, 0.05/float32(len(pairs)) for pval := range pvals { if pval.Pval < cutoff { sig++ } pf("%s\t%s\t%f\n", pval.Name1, pval.Name2, pval.Pval) } pf("significant\t%d/%d\t(cutoff: %f)\n", sig, len(pairs), cutoff) done <- struct{}{} }() for _, p := range pairs { dopairs <- p } close(dopairs) wg.Wait() close(pvals) <-done }
func main() { lib := util.StructureLibrary(util.Arg(0)) fmap := util.FmapRead(util.Arg(1)) util.BowWrite(util.CreateFile(util.Arg(2)), fmap.StructureBow(lib)) }
func main() { fmapPath := util.Arg(0) fmap := util.FmapRead(fmapPath) qchain := getPdbChain(fmapPath) stats := newSequenceStats(qchain.Sequence) total, trueps := 0, 0 qcorrupt, tcorrupt := 0, 0 for _, frags := range fmap.Segments { for _, frag := range frags.Frags { hit := frag.Hit if frag.IsCorrupt() { tcorrupt += 1 stats.incTCorrupt(hit) continue } qatoms := qchain.SequenceCaAtomSlice(hit.QueryStart-1, hit.QueryEnd) if qatoms == nil { qcorrupt += 1 stats.incQCorrupt(hit) continue } if len(qatoms) != len(frag.CaAtoms) { util.Fatalf("Uncomparable lengths. Query is (%d, %d) while "+ "template is (%d, %d). Length of query CaAtoms: %d, "+ "length of template CaAtoms: %d", hit.QueryStart, hit.QueryEnd, hit.TemplateStart, hit.TemplateEnd, len(qatoms), len(frag.CaAtoms)) } if structure.RMSD(qatoms, frag.CaAtoms) <= flagRmsd { trueps += 1 stats.incTruePs(hit) } total += 1 stats.incTotal(hit) } } coveredResidues := 0 for _, resStats := range stats { if resStats.trueps >= 1 { coveredResidues += 1 } } coverage := float64(coveredResidues) / float64(len(qchain.Sequence)) fmt.Printf("RMSDThreshold: %f\n", flagRmsd) fmt.Printf("TotalFragments: %d\n", total) fmt.Printf("TruePositives: %d\n", trueps) fmt.Printf("Precision: %f\n", float64(trueps)/float64(total)) fmt.Printf("CorruptQuery: %d\n", qcorrupt) fmt.Printf("CorruptTemplate: %d\n", tcorrupt) fmt.Printf("TotalResidues: %d\n", len(qchain.Sequence)) fmt.Printf("CoveredResidues: %d\n", coveredResidues) fmt.Printf("Coverage: %f\n", coverage) }
func main() { b1 := util.BowRead(util.Arg(0)) b2 := util.BowRead(util.Arg(1)) fmt.Printf("%0.4f\n", math.Abs(b1.Bow.Cosine(b2.Bow))) }
func main() { outDir := util.Arg(0) fasInps := util.Args()[1:] util.Assert(os.MkdirAll(outDir, 0777)) fastaChan := make(chan string) wg := new(sync.WaitGroup) for i := 0; i < max(1, runtime.GOMAXPROCS(0)); i++ { go func() { wg.Add(1) for fasta := range fastaChan { util.Verbosef("Computing map for '%s'...", fasta) fmap := util.GetFmap(fasta) outF := path.Join(outDir, fmt.Sprintf("%s.fmap", fmap.Name)) util.FmapWrite(util.CreateFile(outF), fmap) } wg.Done() }() } for _, fasta := range fasInps { fastaChan <- fasta } close(fastaChan) wg.Wait() }