github.com/janelia-flyem/dvid@v1.0.0/datatype/imageblk/float32_test.go (about) 1 package imageblk 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/json" 7 "fmt" 8 "reflect" 9 "testing" 10 11 "github.com/janelia-flyem/dvid/datastore" 12 "github.com/janelia-flyem/dvid/dvid" 13 "github.com/janelia-flyem/dvid/server" 14 ) 15 16 var ( 17 floatimgT datastore.TypeService 18 ) 19 20 func newFloatVolume(t *testing.T, offset, size dvid.Point3d) *testVolume { 21 var buf bytes.Buffer 22 for i := int64(0); i < size.Prod(); i++ { 23 if err := binary.Write(&buf, binary.LittleEndian, float32(i)); err != nil { 24 t.Fatalf("couldn't write to float volume: %v\n", err) 25 } 26 } 27 return &testVolume{ 28 data: buf.Bytes(), 29 offset: offset, 30 size: size, 31 } 32 } 33 34 func createFloatTestVolume(t *testing.T, uuid dvid.UUID, name string, offset, size dvid.Point3d) *testVolume { 35 volume := newFloatVolume(t, offset, size) 36 37 // Send data over HTTP to populate a data instance 38 volume.put(t, uuid, name) 39 return volume 40 } 41 42 func TestFloatInstanceCreation(t *testing.T) { 43 if err := server.OpenTest(); err != nil { 44 t.Fatalf("can't open test server: %v\n", err) 45 } 46 defer server.CloseTest() 47 48 uuid, _ := datastore.NewTestRepo() 49 50 // Create new voxels instance with optional parameters 51 name := "weights" 52 metadata := fmt.Sprintf(`{ 53 "typename": "float32blk", 54 "dataname": %q, 55 "blocksize": "64,43,28", 56 "VoxelSize": "13.1, 14.2, 15.3", 57 "VoxelUnits": "picometers,nanometers,microns" 58 }`, name) 59 apiStr := fmt.Sprintf("%srepo/%s/instance", server.WebAPIPath, uuid) 60 server.TestHTTP(t, "POST", apiStr, bytes.NewBufferString(metadata)) 61 62 // Get metadata and make sure optional settings have been set. 63 apiStr = fmt.Sprintf("%snode/%s/%s/info", server.WebAPIPath, uuid, name) 64 result := server.TestHTTP(t, "GET", apiStr, nil) 65 var parsed = struct { 66 Base struct { 67 TypeName, Name string 68 } 69 Extended struct { 70 BlockSize dvid.Point3d 71 VoxelSize dvid.NdFloat32 72 VoxelUnits dvid.NdString 73 } 74 }{} 75 if err := json.Unmarshal(result, &parsed); err != nil { 76 t.Fatalf("Error parsing JSON response of new instance metadata: %v\n", err) 77 } 78 if parsed.Base.Name != name { 79 t.Errorf("Parsed new instance has unexpected name: %s != %s (expected)\n", 80 parsed.Base.Name, name) 81 } 82 if parsed.Base.TypeName != "float32blk" { 83 t.Errorf("Parsed new instance has unexpected type name: %s != uint8blk (expected)\n", 84 parsed.Base.TypeName) 85 } 86 if !parsed.Extended.BlockSize.Equals(dvid.Point3d{64, 43, 28}) { 87 t.Errorf("Bad block size in new uint8blk instance: %s\n", parsed.Extended.BlockSize) 88 } 89 if !parsed.Extended.VoxelSize.Equals(dvid.NdFloat32{13.1, 14.2, 15.3}) { 90 t.Errorf("Bad voxel size in new uint8blk instance: %s\n", parsed.Extended.VoxelSize) 91 } 92 if parsed.Extended.VoxelUnits[0] != "picometers" { 93 t.Errorf("Got %q for X voxel units, not picometers\n", parsed.Extended.VoxelUnits[0]) 94 } 95 if parsed.Extended.VoxelUnits[1] != "nanometers" { 96 t.Errorf("Got %q for X voxel units, not picometers\n", parsed.Extended.VoxelUnits[0]) 97 } 98 if parsed.Extended.VoxelUnits[2] != "microns" { 99 t.Errorf("Got %q for X voxel units, not picometers\n", parsed.Extended.VoxelUnits[0]) 100 } 101 } 102 103 func TestFloatDirectCalls(t *testing.T) { 104 if err := server.OpenTest(); err != nil { 105 t.Fatalf("can't open test server: %v\n", err) 106 } 107 defer server.CloseTest() 108 109 uuid, versionID := initTestRepo() 110 111 server.CreateTestInstance(t, uuid, "float32blk", "floatimg", dvid.Config{}) 112 dataservice, err := datastore.GetDataByUUIDName(uuid, "floatimg") 113 if err != nil { 114 t.Fatal(err) 115 } 116 floatimg, ok := dataservice.(*Data) 117 if !ok { 118 t.Fatalf("Can't convert dataservice %v into imageblk.Data\n", dataservice) 119 } 120 ctx := datastore.NewVersionedCtx(floatimg, versionID) 121 122 // Create a block-aligned 8-bit grayscale image 123 offset := dvid.Point3d{512, 32, 1024} 124 size := dvid.Point3d{128, 96, 64} 125 subvol := dvid.NewSubvolume(offset, size) 126 testvol := createFloatTestVolume(t, uuid, "floatimg", offset, size) 127 origData := make([]byte, len(testvol.data)) 128 copy(origData, testvol.data) 129 130 // Store it into datastore at root 131 v, err := floatimg.NewVoxels(subvol, testvol.data) 132 if err != nil { 133 t.Fatalf("Unable to make new floatimg voxels: %v\n", err) 134 } 135 if err = floatimg.IngestVoxels(versionID, 1, v, ""); err != nil { 136 t.Errorf("Unable to put voxels for %s: %v\n", ctx, err) 137 } 138 139 // Read the stored image 140 v2, err := floatimg.NewVoxels(subvol, nil) 141 if err != nil { 142 t.Errorf("Unable to make new grayscale ExtHandler: %v\n", err) 143 } 144 if err = floatimg.GetVoxels(versionID, v2, ""); err != nil { 145 t.Errorf("Unable to get voxels for %s: %v\n", ctx, err) 146 } 147 148 // Make sure the retrieved image matches the original 149 if v.Stride() != v2.Stride() { 150 t.Errorf("Stride in retrieved subvol incorrect\n") 151 } 152 if v.Interpolable() != v2.Interpolable() { 153 t.Errorf("Interpolable bool in retrieved subvol incorrect\n") 154 } 155 if !reflect.DeepEqual(v.Size(), v2.Size()) { 156 t.Errorf("Size in retrieved subvol incorrect: %s vs expected %s\n", 157 v2.Size(), v.Size()) 158 } 159 if v.NumVoxels() != v2.NumVoxels() { 160 t.Errorf("# voxels in retrieved is different: %d vs expected %d\n", 161 v2.NumVoxels(), v.NumVoxels()) 162 } 163 if len(v.Data()) != len(v2.Data()) { 164 t.Errorf("Expected %d bytes in retrieved data, got %d bytes\n", len(v.Data()), len(v2.Data())) 165 } 166 received := v2.Data() 167 //dvid.PrintNonZero("original value", origData) 168 //dvid.PrintNonZero("returned value", data) 169 for i := int64(0); i < v2.NumVoxels(); i++ { 170 if received[i] != origData[i] { 171 t.Logf("Data returned != data stored for voxel %d\n", i) 172 t.Logf("Size of data: %d bytes from GET, %d bytes in PUT\n", len(received), len(origData)) 173 t.Fatalf("GET subvol (%d) != PUT subvol (%d) @ index %d", received[i], origData[i], i) 174 } 175 } 176 } 177 178 func TestFloat32RepoPersistence(t *testing.T) { 179 if err := server.OpenTest(); err != nil { 180 t.Fatalf("can't open test server: %v\n", err) 181 } 182 defer server.CloseTest() 183 184 uuid, _ := initTestRepo() 185 186 // Make grayscale and set various properties 187 config := dvid.NewConfig() 188 config.Set("BlockSize", "12,13,14") 189 config.Set("VoxelSize", "1.1,2.8,11") 190 config.Set("VoxelUnits", "microns,millimeters,nanometers") 191 dataservice, err := datastore.NewData(uuid, floatimgT, "floatimg", config) 192 if err != nil { 193 t.Errorf("Unable to create float32 instance: %s\n", err) 194 } 195 floatimg, ok := dataservice.(*Data) 196 if !ok { 197 t.Errorf("Can't cast float32 data service into Data\n") 198 } 199 oldData := *floatimg 200 201 // Restart test datastore and see if datasets are still there. 202 if err = datastore.SaveDataByUUID(uuid, floatimg); err != nil { 203 t.Fatalf("Unable to save repo during floatimg persistence test: %v\n", err) 204 } 205 datastore.CloseReopenTest() 206 207 dataservice2, err := datastore.GetDataByUUIDName(uuid, "floatimg") 208 if err != nil { 209 t.Fatalf("Can't get floatimg instance from reloaded test db: %v\n", err) 210 } 211 floatimg2, ok := dataservice2.(*Data) 212 if !ok { 213 t.Errorf("Returned new data instance 2 is not imageblk.Data\n") 214 } 215 if !oldData.Equals(floatimg2) { 216 t.Errorf("Expected %v, got %v\n", oldData, *floatimg2) 217 } 218 }