bool CCP4File::read(RegularData3D& density_map) { // first read the header if (!readHeader()) { Log.error() << "CCP4File::read(): readHeader() failed. Aborting read." << std::endl; return false; } // then try to read symmetry records if present if (!readSymmetryRecords()) { Log.error() << "CCP4File::read(): readSymmteryRecords() failed. Aborting read." << std::endl; return false; } if (int(getSize()) > int(4*(extent_.x*extent_.y*extent_.z))) { Log.info() << "CCP4File::read(): Warning: datablock bigger than expected. But continuing anyway." << std::endl; } Size global_index = 0; RegularData3D::IndexType size_crs; size_crs.x = (Size) extent_[(Position) col_axis_]; size_crs.y = (Size) extent_[(Position) row_axis_]; size_crs.z = (Size) extent_[(Position) sec_axis_]; RegularData3D::IndexType size; size.x = (Size) extent_.x; size.y = (Size) extent_.y; size.z = (Size) extent_.z; density_map = RegularData3D(origin_, xaxis_, yaxis_, zaxis_, size); density_map.setDimension(Vector3(xaxis_.x, yaxis_.y, zaxis_.z)); char* rowblock = new char[4*int(size_crs.x)]; Size crs[3]; for(crs[2]=0; crs[2] < size_crs.z; crs[2]++) { for(crs[1]=0; crs[1] < size_crs.y; crs[1]++) { std::fstream::read(rowblock, 4*(int(size_crs.x))); for(crs[0]=0; crs[0] < size_crs.x; crs[0]++) { global_index = (Size)(crs[col_axis_]+ crs[row_axis_]*size.x + crs[sec_axis_]*size.x*size.y); density_map[global_index] = readBinValueasFloat_(rowblock,crs[0]); } } } delete [] rowblock; return true; }
bool DSN6File::read(RegularData3D& density_map) throw() { // first read the header if (!readHeader()) { Log.error() << "DSN6File::read(): readHeader() failed. Aborting read." << std::endl; return false; } // and then the individual bricks. each brick contains 8^3 grid points, stored as bytes // which are converted to floats using the formula // density = (byte_value - plus) / prod float factor = 1./prod_; // how many bricks do we have? Size number_of_bricks_x = (Size) ceil(extent_.x / 8.0); Size number_of_bricks_y = (Size) ceil(extent_.y / 8.0); Size number_of_bricks_z = (Size) ceil(extent_.z / 8.0); Size global_index = 0; Size brick_index = 0; char brick[512]; unsigned char* brick_pointer; RegularData3D::IndexType size; size.x = (Size) extent_.x; size.y = (Size) extent_.y; size.z = (Size) extent_.z; density_map = RegularData3D(origin_, xaxis_, yaxis_, zaxis_, size); // NOTE: this currently only works for orthogonal maps!!! // TODO: implement a simple volumetric data type. all we need to do currently // is to set a matrix converting between the given coordinate system of // the volumetric data set and 3D space density_map.setDimension(Vector3(xaxis_.x, yaxis_.y, zaxis_.z)); Size brick_x, brick_y, brick_z; // the ordering in both the individual bricks and the whole filw // is (fastest to slowest) x - y - z for (brick_z = 0; brick_z < number_of_bricks_z; brick_z++) { for (brick_y = 0; brick_y < number_of_bricks_y; brick_y++) { for (brick_x = 0; brick_x < number_of_bricks_x; brick_x++) { brick_index = 0; // read the next brick std::fstream::read(brick, 512); brick_pointer = (unsigned char*)brick; if (gcount() != 512) { Log.error() << "DSN6File::read(): Could not read next brick. Aborting read." << std::endl; return false; } // and swap its bytes convertBrick_(brick); // code is inspired by the VMD code :-) Size x, y, z; for (z=0; z<8; z++) // iterate over z of the current brick { if ((z + brick_z*8) >= extent_.z) { global_index += (Size)((8-z)*extent_.x*extent_.y); break; } for (y=0; y<8; y++) { if ((y + brick_y*8) >= extent_.y) { global_index += (Size)((8-y)*extent_.x); brick_index += (Size)((8-y)*8); break; } for (x=0; x<8; x++) { if ((x + brick_x*8) >= extent_.x) { global_index += (Size)(8 - x); brick_index += (Size)(8 - x); break; } float brick_value = (float)(*(brick_pointer+brick_index)); density_map[global_index] = factor * (brick_value - plus_); brick_index++; global_index++; } // for x... global_index += (Size)(extent_.x - 8); } // for y... global_index += (Size)(extent_.x*extent_.y - 8*extent_.x); } // for z... global_index += (Size)(8 - 8*extent_.x*extent_.y); } // for brick_x global_index += (Size)(8 * (extent_.x - number_of_bricks_x)); } // for brick_y global_index += (Size)(8 * (extent_.x*extent_.y - extent_.x*brick_y)); } // for brick_z // done. return true; }