//Next Reads the next frame in a XTCObj that has been initialized for read //With initread. If keep is true, returns a pointer to matrix.DenseMatrix //With the coordinates read, otherwiser, it discards the coordinates and //returns nil. func (X *XTCObj) Next(output *v3.Matrix) error { if !X.Readable() { return Error{TrajUnIni, X.filename, []string{"Next"}, true} } cnatoms := C.int(X.natoms) worked := C.get_coords(X.fp, &X.cCoords[0], cnatoms) if worked == 11 { X.readable = false return newlastFrameError(X.filename, "Next") //This is not really an error and should be catched in the calling function } if worked != 0 { X.readable = false return Error{ReadError, X.filename, []string{"Next"}, true} } if output != nil { //col the frame r, c := output.Dims() if r < (X.natoms) { panic("Buffer v3.Matrix too small to hold trajectory frame") } for j := 0; j < r; j++ { for k := 0; k < c; k++ { l := k + (3 * j) output.Set(j, k, (10 * float64(X.cCoords[l]))) //nm to Angstroms } } return nil } return nil //Just drop the frame }
/*NextConc takes a slice of bools and reads as many frames as elements the list has form the trajectory. The frames are discarted if the corresponding elemetn of the slice * is false. The function returns a slice of channels through each of each of which * a *matrix.DenseMatrix will be transmited*/ func (X *XTCObj) NextConc(frames []*v3.Matrix) ([]chan *v3.Matrix, error) { if X.buffSize < len(frames) { X.setConcBuffer(len(frames)) } if X.natoms == 0 { return nil, Error{TrajUnIni, X.filename, []string{"NextConc"}, true} } framechans := make([]chan *v3.Matrix, len(frames)) //the slice of chans that will be returned cnatoms := C.int(X.natoms) used := false for key, val := range frames { //cCoords:=X.concBuffer[key] worked := C.get_coords(X.fp, &X.concBuffer[key][0], cnatoms) //Error handling if worked == 11 { if used == false { X.readable = false return nil, newlastFrameError(X.filename, "NextConc") //This is not really an error and } else { //should be catched in the calling function X.readable = false return framechans, newlastFrameError(X.filename, "NextConc") //same } } if worked != 0 { X.readable = false return nil, Error{ReadError, X.filename, []string{"NextConc"}, true} } if val == nil { framechans[key] = nil //ignored frame continue } used = true framechans[key] = make(chan *v3.Matrix) //Now the parallel part go func(natoms int, cCoords []C.float, goCoords *v3.Matrix, pipe chan *v3.Matrix) { r, c := goCoords.Dims() for j := 0; j < r; j++ { for k := 0; k < c; k++ { l := k + (3 * j) goCoords.Set(j, k, (10 * float64(cCoords[l]))) //nm to Angstroms } } pipe <- goCoords }(X.natoms, X.concBuffer[key], val, framechans[key]) } return framechans, nil }