// structureToSequence uses structural fragments to categorize a segment // of alpha-carbon atoms, and adds the corresponding residues to a // corresponding sequence fragment. func structureToSequence( lib fragbag.StructureLibrary, chain *pdb.Chain, nullChan chan seq.Sequence, seqChans []chan seq.Sequence, ) { sequence := chain.AsSequence() fragSize := lib.FragmentSize() // If the chain is shorter than the fragment size, we can do nothing // with it. if sequence.Len() < fragSize { util.Verbosef("Sequence '%s' is too short (length: %d)", sequence.Name, sequence.Len()) return } // If we're accumulating a null model, add this sequence to it. if nullChan != nil { nullChan <- sequence } // This bit of trickery here is all about getting the call to // SequenceCaAtoms outside of the loop. In particular, it's a very // expensive call since it has to reconcile inconsistencies between // SEQRES and ATOM records in PDB files. limit := sequence.Len() - fragSize atoms := chain.SequenceCaAtoms() atomSlice := make([]structure.Coords, fragSize) noGaps := func(atoms []*structure.Coords) []structure.Coords { for i, atom := range atoms { if atom == nil { return nil } atomSlice[i] = *atom } return atomSlice } for start := 0; start <= limit; start++ { end := start + fragSize cas := noGaps(atoms[start:end]) if cas == nil { // Nothing contiguous was found (a "disordered" residue perhaps). // So skip this part of the chain. continue } bestFrag := lib.BestStructureFragment(atomSlice) sliced := sequence.Slice(start, end) seqChans[bestFrag] <- sliced } }
// StructureBow is a helper function to compute a bag-of-words given a // structure fragment library and a list of alpha-carbon atoms. // // If the lib given is a weighted library, then the Bow returned will also // be weighted. // // Note that this function should only be used when providing your own // implementation of the StructureBower interface. Otherwise, BOWs should // be computed using the StructureBow method of the interface. func StructureBow(lib fragbag.StructureLibrary, atoms []structure.Coords) Bow { var best, uplimit int b := NewBow(lib.Size()) libSize := lib.FragmentSize() uplimit = len(atoms) - libSize for i := 0; i <= uplimit; i++ { best = lib.BestStructureFragment(atoms[i : i+libSize]) if best > -1 { b.Freqs[best] += 1 } } if wlib, ok := lib.(fragbag.WeightedLibrary); ok { b = b.Weighted(wlib) } return b }