Hello,

 I just made a modification to the PDL::IO::HDF5 package
so it can now read slices or hyperslabs of the file instead
of the whole array

Use the following patch by untarring the PDL-IO-HDF5-0.5.tar.gz file
and "cd  PDL-IO-HDF5-0.5" and then

patch -p1 < ../PDL-IO-HDF5-0.5-hyperslab.patch

patch file attached


Cheers,

Xavier
diff -ur PDL-IO-HDF5-0.5/HDF5/Dataset.pm PDL-IO-HDF5-0.5-new/HDF5/Dataset.pm
--- PDL-IO-HDF5-0.5/HDF5/Dataset.pm	2006-01-10 18:57:43.000000000 +0000
+++ PDL-IO-HDF5-0.5-new/HDF5/Dataset.pm	2007-02-20 14:50:59.301516735 +0000
@@ -345,6 +345,9 @@
 sub get{
 
 	my $self = shift;
+	my $start = shift;
+	my $length = shift;
+	my $stride = shift;
 
 	my $pdl;
 
@@ -423,39 +426,79 @@
 	}
 
 
-	# Initialize Dims structure:
 	my @dims = ( 0..($Ndims-1)); 
-        my $dims = PDL::IO::HDF5::packList(@dims);
-	my $dims2 = PDL::IO::HDF5::packList(@dims);
-
-        my $rc = PDL::IO::HDF5::H5Sget_simple_extent_dims($dataspaceID, $dims, $dims2 );
-
-	if( $rc != $Ndims){
+	my ($mem_space,$file_space);
+	if (not defined $start) {
+	    # Initialize Dims structure:
+	    my $dims = PDL::IO::HDF5::packList(@dims);
+	    my $dims2 = PDL::IO::HDF5::packList(@dims);
+	    
+	    my $rc = PDL::IO::HDF5::H5Sget_simple_extent_dims($dataspaceID, $dims, $dims2 );
+	    
+	    if( $rc != $Ndims){
 		carp("Error getting number of dims in dataspace in ".__PACKAGE__.":get\n");
 		carp("Can't close Datatype in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Tclose($HDF5type) < 0);
 		carp("Can't close DataSpace in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Sclose($dataspaceID) < 0);
 		return undef;
-	}
+	    }
+	    
+	    @dims = PDL::IO::HDF5::unpackList($dims); # get the dim sizes from the binary structure
+	    
+	} else {
+	    
+	    carp("Wrong dimensions in start PDL in ".__PACKAGE__."\n") if ( ($start->getndims != 1) || ($start->getdim(0) != $Ndims) );
+	    my $start2 = PDL::IO::HDF5::packList(reverse($start->list));
+	    carp("No length supplied in ".__PACKAGE__."\n") if (not defined $length);
+	    carp("Wrong dimensions in length PDL in ".__PACKAGE__."\n") if ( ($length->getndims != 1) || ($length->getdim(0) != $Ndims) );
+	    my $length2 = PDL::IO::HDF5::packList(reverse($length->list));
+
+	    if (defined $stride) {
+		carp("Wrong dimensions in stride in ".__PACKAGE__."\n") if ( ($stride->getndims != 1) || ($stride->getdim(0) != $Ndims) );
+		@dims=reverse(($length/$stride)->list);
+	    } else {
+		@dims=reverse($length->list);
+		$stride=PDL::Core::ones($Ndims);
+	    }
+	    my $mem_dims = PDL::IO::HDF5::packList(@dims);
+	    my $stride2 = PDL::IO::HDF5::packList(reverse($stride->list));
+	    my $block=PDL::Core::ones($Ndims);
+	    my $block2 = PDL::IO::HDF5::packList(reverse($block->list));
+
+	    # Slice the data
+	    $file_space = PDL::IO::HDF5::H5Dget_space($datasetID);
+	    $rc=PDL::IO::HDF5::H5Sselect_hyperslab($file_space, 0, 
+			 $start2, $stride2, $length2, $block2);
 
-	@dims = PDL::IO::HDF5::unpackList($dims); # get the dim sizes from the binary structure
+	
+	    if( $rc < 0 ){
+		carp("Error slicing data from file in ".__PACKAGE__.":get\n");
+		carp("Can't close Datatype in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Tclose($HDF5type) < 0);
+		carp("Can't close DataSpace in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Sclose($dataspaceID) < 0);
+		return undef;
+	    }
+	    
+	    $mem_space = PDL::IO::HDF5::H5Screate_simple($Ndims, $mem_dims, 
+							    $mem_dims);
 
+	}
+	
 	$pdl = $ReturnType->null;
 	$pdl->set_datatype($PDLtype);
 	my @pdldims;  # dims of the PDL
 	if( defined( $stringSize )){  # String types
-		
-		@pdldims = ($stringSize,reverse(@dims)); # HDF5 stores columns/rows in reverse order than pdl,
-							      #  1st PDL dim is the string length (for PDL::Char)
+	    
+	    @pdldims = ($stringSize,reverse(@dims)); # HDF5 stores columns/rows in reverse order than pdl,
+	    #  1st PDL dim is the string length (for PDL::Char)
 	}
 	else{ # Normal Numeric types
-		@pdldims = (reverse(@dims)); 		# HDF5 stores columns/rows in reverse order than pdl,
+	    @pdldims = (reverse(@dims)); 		# HDF5 stores columns/rows in reverse order than pdl,
 	}
-
+	
 	$pdl->setdims([EMAIL PROTECTED]);
-
+	
 	my $nelems = 1;
 	foreach (@pdldims){ $nelems *= $_; }; # calculate the number of elements
-
+	
 	my $datasize = $nelems * PDL::howbig($pdl->get_datatype);
 	
 	# Create empty space for the data
@@ -463,21 +506,29 @@
 	my $howBig = PDL::howbig($pdl->get_datatype);
 	my $data = ' ' x $howBig;
 	foreach my $dim(@pdldims){
-		$data = $data x $dim;
+	    $data = $data x $dim;
 	}
-
 	# Read the data:
-        $rc = PDL::IO::HDF5::H5Dread($datasetID, $internalhdf5_type, PDL::IO::HDF5::H5S_ALL(), PDL::IO::HDF5::H5S_ALL(), 
-		   PDL::IO::HDF5::H5P_DEFAULT(),
-                    $data);
+	if (not defined $start) {
+	    $rc = PDL::IO::HDF5::H5Dread($datasetID, $internalhdf5_type, PDL::IO::HDF5::H5S_ALL(), PDL::IO::HDF5::H5S_ALL(), 
+					 PDL::IO::HDF5::H5P_DEFAULT(),
+					 $data);
+	} else {
+
+	    $rc = PDL::IO::HDF5::H5Dread($datasetID, $internalhdf5_type,
+					 $mem_space, $file_space, 
+					 PDL::IO::HDF5::H5P_DEFAULT(),
+					 $data);
+	}
 
+	
 	if( $rc < 0 ){
-		carp("Error reading data from file in ".__PACKAGE__.":get\n");
-		carp("Can't close Datatype in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Tclose($HDF5type) < 0);
-		carp("Can't close DataSpace in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Sclose($dataspaceID) < 0);
+	    carp("Error reading data from file in ".__PACKAGE__.":get\n");
+	    carp("Can't close Datatype in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Tclose($HDF5type) < 0);
+	    carp("Can't close DataSpace in ".__PACKAGE__.":get\n") if( PDL::IO::HDF5::H5Sclose($dataspaceID) < 0);
 		return undef;
 	}
-
+	
 	# Update the PDL data with the data read from the file
 	${$pdl->get_dataref()} = $data;
 	$pdl->upd_data();
diff -ur PDL-IO-HDF5-0.5/hdf5.pd PDL-IO-HDF5-0.5-new/hdf5.pd
--- PDL-IO-HDF5-0.5/hdf5.pd	2006-03-24 20:37:34.000000000 +0000
+++ PDL-IO-HDF5-0.5-new/hdf5.pd	2007-02-20 09:46:01.788379776 +0000
@@ -1166,6 +1166,7 @@
 herr_t H5Sclose(hid_t space_id); 
 int H5Sget_simple_extent_ndims(hid_t space_id);
 int H5Sget_simple_extent_dims(hid_t space_id, hsize_t *dims, hsize_t *maxdims);
+herr_t H5Sselect_hyperslab(hid_t space_id, int op, const hsize_t *start, const hsize_t *stride, const hsize_t *count, const hsize_t *block);
 #
 #
 # Dataset Functions
_______________________________________________
Perldl mailing list
[email protected]
http://mailman.jach.hawaii.edu/mailman/listinfo/perldl

Reply via email to