static PyObject * __jump_to_frame(PyObject *self, PyObject *args) { PyObject* temp; dcdhandle *dcd; int frame; if (! self) { /* we were in fact called as a module function, try to retrieve a matching object from args */ if( !PyArg_ParseTuple(args, "Oi", &self, &frame) ) return NULL; } else { /* we were obviously called as an object method so args should only have the int value. */ if( !PyArg_ParseTuple(args, "i", &frame) ) return NULL; } if ( !PyObject_HasAttrString(self, "_dcd_C_ptr") ) { // Raise exception PyErr_SetString(PyExc_AttributeError, "_dcd_C_ptr is not an attribute"); return NULL; } if ((temp = PyObject_GetAttrString(self, "_dcd_C_ptr")) == NULL) { // This gives me a New Reference // Raise exception PyErr_SetString(PyExc_AttributeError, "_dcd_C_ptr is not an attribute"); return NULL; } dcd = (dcdhandle*)PyCObject_AsVoidPtr(temp); Py_DECREF(temp); /*if (frame > dcd->nsets) { PyErr_SetString(PyExc_IndexError, "Invalid frame"); return NULL; } // Calculate file offset { off_t extrablocksize, ndims, firstframesize, framesize; off_t pos; extrablocksize = dcd->charmm & DCD_HAS_EXTRA_BLOCK ? 48 + 8 : 0; ndims = dcd->charmm & DCD_HAS_4DIMS ? 4 : 3; firstframesize = (dcd->natoms+2) * ndims * sizeof(float) + extrablocksize; framesize = (dcd->natoms-dcd->nfixed+2) * ndims * sizeof(float) + extrablocksize; // Use zero indexing if (frame == 0) { pos = dcd->header_size; } else { pos = dcd->header_size + firstframesize + framesize * (frame-1); } rc = fio_fseek(dcd->fd, pos, FIO_SEEK_SET); } dcd->setsread = frame; dcd->first = 0;*/ jump_to_frame(dcd, frame); temp = Py_BuildValue("i", dcd->setsread); return temp; }
void Compartment_Report_Binary_File_Reader::reset() /* throw (IO_Error, Unsupported) */ { jump_to_frame(UNDEFINED_FRAME_NUMBER); }
static PyObject * __read_timeseries(PyObject *self, PyObject *args) { PyObject *temp = NULL; PyArrayObject *coord = NULL; PyListObject *atoms = NULL; int lowerb = 0, upperb = 0, range=0; float *tempX = NULL, *tempY = NULL, *tempZ = NULL; int rc; int i, j, index; int n_atoms = 0, n_frames = 0; /* Stop = -1 is incorrect and causes an error, look for a fix of this in line 469 */ int start = 0, stop = -1, step = 1, numskip = 0, remaining_frames=0; dcdhandle *dcd = NULL; int *atomlist = NULL; npy_intp dimensions[3]; float unitcell[6]; const char* format = "afc"; if (!self) { /* we were in fact called as a module function, try to retrieve a matching object from args */ if( !PyArg_ParseTuple(args, "OO!|iiis", &self, &PyList_Type, &atoms, &start, &stop, &step, &format) ) return NULL; } else { /* we were obviously called as an object method so args should only have the int value. */ if( !PyArg_ParseTuple(args, "O!|iiis", &PyList_Type, &atoms, &start, &stop, &step, &format) ) return NULL; } if ((temp = PyObject_GetAttrString(self, "_dcd_C_ptr")) == NULL) { // This gives me a New Reference // Raise exception PyErr_SetString(PyExc_AttributeError, "_dcd_C_ptr is not an attribute"); return NULL; } dcd = (dcdhandle*)PyCObject_AsVoidPtr(temp); Py_DECREF(temp); n_frames = ((stop-start) / step); if ((stop-start) % step > 0) { n_frames++; } //n_frames = dcd->nsets / skip; n_atoms = PyList_Size((PyObject*)atoms); if (n_atoms == 0) { PyErr_SetString(PyExc_Exception, "No atoms passed into _read_timeseries function"); return NULL; } atomlist = (int*)malloc(sizeof(int)*n_atoms); memset(atomlist, 0, sizeof(int)*n_atoms); // Get the atom indexes for (i=0;i<n_atoms;i++) { temp = PyList_GetItem((PyObject*)atoms, i); // Borrowed Reference if (temp==NULL) goto error; // Make sure temp is an integer /* TODO: this is not the proper check but [OB] cannot figure out how to check if this is a numpy.int64 or similar; PyInt_Check would fail on those (Issue 18) */ if (!PyArray_IsAnyScalar((PyObject*)temp)) { PyErr_SetString(PyExc_ValueError, "Atom number is not an integer"); goto error; } atomlist[i] = PyInt_AsLong(temp); } lowerb = atomlist[0]; upperb = atomlist[n_atoms-1]; range = upperb-lowerb+1; // Figure out the format string if (strncasecmp(format, "afc", 3) == 0) { dimensions[0] = n_atoms; dimensions[1] = n_frames; dimensions[2] = 3; } else if (strncasecmp(format, "acf", 3) == 0) { dimensions[0] = n_atoms; dimensions[1] = 3; dimensions[2] = n_frames; } else if (strncasecmp(format, "fac", 3) == 0) { dimensions[0] = n_frames; dimensions[1] = n_atoms; dimensions[2] = 3; } else if (strncasecmp(format, "fca", 3) == 0) { dimensions[0] = n_frames; dimensions[1] = 3; dimensions[2] = n_atoms; } else if (strncasecmp(format, "caf", 3) == 0) { dimensions[0] = 3; dimensions[1] = n_atoms; dimensions[2] = n_frames; } else if (strncasecmp(format, "cfa", 3) == 0) { dimensions[0] = 3; dimensions[1] = n_frames; dimensions[2] = n_atoms; } coord = (PyArrayObject*) PyArray_SimpleNew(3, dimensions, NPY_DOUBLE); if (coord == NULL) goto error; // Reset trajectory rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET); dcd->setsread = 0; dcd->first = 1; // Jump to starting frame jump_to_frame(dcd, start); // Now read through trajectory and get the atom pos tempX = (float*)malloc(sizeof(float)*range); tempY = (float*)malloc(sizeof(float)*range); tempZ = (float*)malloc(sizeof(float)*range); if ((tempX == NULL) | (tempY == NULL) || (tempZ == NULL)) { PyErr_SetString(PyExc_MemoryError, "Can't allocate temporary space for coordinate arrays"); goto error; } remaining_frames = stop-start; for (i=0;i<n_frames;i++) { if (step > 1 && i>0) { // Check if we have fixed atoms // XXX not done /* Figure out how many steps to step over, if step = n, np array slicing treats this as skip over n-1, read the nth. */ numskip = step -1; /* If the number to skip is greater than the number of frames left to be jumped over, just take one more step to reflect np slicing if there is a remainder, guaranteed to have at least one more frame. */ if(remaining_frames < numskip){ numskip = 1; } rc = skip_dcdstep(dcd->fd, dcd->natoms, dcd->nfixed, dcd->charmm, numskip); if (rc < 0) { // return an exception PyErr_SetString(PyExc_IOError, "Error skipping frame from DCD file"); goto error; } } // on first iteration, numskip == 0, first set is always read. dcd->setsread += numskip; //now read from subset rc = read_dcdsubset(dcd->fd, dcd->natoms, lowerb, upperb, tempX, tempY, tempZ, unitcell, dcd->nfixed, dcd->first, dcd->freeind, dcd->fixedcoords, dcd->reverse, dcd->charmm); dcd->first = 0; dcd->setsread++; remaining_frames = stop - dcd->setsread; if (rc < 0) { // return an exception PyErr_SetString(PyExc_IOError, "Error reading frame from DCD file"); goto error; } // Copy into Numeric array only those atoms we are interested in for (j=0;j<n_atoms;j++) { index = atomlist[j]-lowerb; /* * coord[a][b][c] = *(float*)(coord->data + a*coord->strides[0] + b*coord->strides[1] + c*coord->strides[2]) */ if (strncasecmp(format, "afc", 3) == 0) { *(double*)(coord->data + j*coord->strides[0] + i*coord->strides[1] + 0*coord->strides[2]) = tempX[index]; *(double*)(coord->data + j*coord->strides[0] + i*coord->strides[1] + 1*coord->strides[2]) = tempY[index]; *(double*)(coord->data + j*coord->strides[0] + i*coord->strides[1] + 2*coord->strides[2]) = tempZ[index]; } else if (strncasecmp(format, "acf", 3) == 0) { *(double*)(coord->data + j*coord->strides[0] + 0*coord->strides[1] + i*coord->strides[2]) = tempX[index]; *(double*)(coord->data + j*coord->strides[0] + 1*coord->strides[1] + i*coord->strides[2]) = tempY[index]; *(double*)(coord->data + j*coord->strides[0] + 2*coord->strides[1] + i*coord->strides[2]) = tempZ[index]; } else if (strncasecmp(format, "fac", 3) == 0) { *(double*)(coord->data + i*coord->strides[0] + j*coord->strides[1] + 0*coord->strides[2]) = tempX[index]; *(double*)(coord->data + i*coord->strides[0] + j*coord->strides[1] + 1*coord->strides[2]) = tempY[index]; *(double*)(coord->data + i*coord->strides[0] + j*coord->strides[1] + 2*coord->strides[2]) = tempZ[index]; } else if (strncasecmp(format, "fca", 3) == 0) { *(double*)(coord->data + i*coord->strides[0] + 0*coord->strides[1] + j*coord->strides[2]) = tempX[index]; *(double*)(coord->data + i*coord->strides[0] + 1*coord->strides[1] + j*coord->strides[2]) = tempY[index]; *(double*)(coord->data + i*coord->strides[0] + 2*coord->strides[1] + j*coord->strides[2]) = tempZ[index]; } else if (strncasecmp(format, "caf", 3) == 0) { *(double*)(coord->data + 0*coord->strides[0] + j*coord->strides[1] + i*coord->strides[2]) = tempX[index]; *(double*)(coord->data + 1*coord->strides[0] + j*coord->strides[1] + i*coord->strides[2]) = tempY[index]; *(double*)(coord->data + 2*coord->strides[0] + j*coord->strides[1] + i*coord->strides[2]) = tempZ[index]; } else if (strncasecmp(format, "cfa", 3) == 0) { *(double*)(coord->data + 0*coord->strides[0] + i*coord->strides[1] + j*coord->strides[2]) = tempX[index]; *(double*)(coord->data + 1*coord->strides[0] + i*coord->strides[1] + j*coord->strides[2]) = tempY[index]; *(double*)(coord->data + 2*coord->strides[0] + i*coord->strides[1] + j*coord->strides[2]) = tempZ[index]; } } // Check if we've been interupted by the user if (PyErr_CheckSignals() == 1) goto error; } // Reset trajectory rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET); dcd->setsread = 0; dcd->first = 1; free(atomlist); free(tempX); free(tempY); free(tempZ); return PyArray_Return(coord); error: // Reset trajectory rc = fio_fseek(dcd->fd, dcd->header_size, FIO_SEEK_SET); dcd->setsread = 0; dcd->first = 1; Py_XDECREF(coord); if (atomlist != NULL) free(atomlist); if (tempX != NULL) free(tempX); if (tempY != NULL) free(tempY); if (tempZ != NULL) free(tempZ); return NULL; }