Skip to content

Commit

Permalink
Merge pull request #1 from suyashkumar/main
Browse files Browse the repository at this point in the history
catching up with upstream
  • Loading branch information
kaxap authored Dec 20, 2020
2 parents ea26fb8 + 33d864f commit 1780bba
Show file tree
Hide file tree
Showing 21 changed files with 471 additions and 84 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/bench_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: bench_pr
on: [pull_request]
jobs:
build:
name: Benchmark (PR)
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.15
uses: actions/setup-go@v2
with:
go-version: 1.15
id: go

- name: Check out code
uses: actions/checkout@v1

- name: Get dependencies
run: |
go mod download
- name: Benchmark against GITHUB_BASE_REF
run: |
export PATH=$PATH:$GOBIN
go get golang.org/x/perf/cmd/benchstat
echo "New Commit:"
git log -1 --format="%H"
go test -bench=. -benchtime=.75s -count=8 > $HOME/new.txt
git reset --hard HEAD
git checkout $GITHUB_BASE_REF
echo "Base Commit:"
git log -1 --format="%H"
go test -bench=. -benchtime=.75s -count=8 > $HOME/old.txt
benchstat $HOME/old.txt $HOME/new.txt
33 changes: 33 additions & 0 deletions .github/workflows/bench_push.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: bench_push
on: [push]
jobs:
build:
name: Benchmark (push)
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.15
uses: actions/setup-go@v2
with:
go-version: 1.15
id: go

- name: Check out code
uses: actions/checkout@v1

- name: Get dependencies
run: |
go mod download
- name: Benchmark (against HEAD~1)
run: |
export PATH=$PATH:$GOBIN
go get golang.org/x/perf/cmd/benchstat
echo "New Commit:"
git log -1 --format="%H"
go test -bench=. -benchtime=.75s -count=8 > $HOME/new.txt
git reset --hard HEAD
git checkout HEAD~1
echo "Base Commit:"
git log -1 --format="%H"
go test -bench=. -benchtime=.75s -count=8 > $HOME/old.txt
benchstat $HOME/old.txt $HOME/new.txt
47 changes: 4 additions & 43 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,26 @@ jobs:
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.13
uses: actions/setup-go@v1
- name: Set up Go 1.15
uses: actions/setup-go@v2
with:
go-version: 1.13
go-version: 1.15
id: go

- name: Check out code
uses: actions/checkout@v1

- name: Get dependencies
run: |
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export REPO_PATH=$GOPATH/src/github.com/suyashkumar/dicom
mkdir -p $GOBIN
export PATH=$PATH:/home/runner/go/bin
mkdir -p $REPO_PATH
mv $(pwd)/* $REPO_PATH
cd $REPO_PATH
run: |
go mod download
- name: Build
run: |
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export REPO_PATH=$GOPATH/src/github.com/suyashkumar/dicom
export PATH=$PATH:/home/runner/go/bin
cd $REPO_PATH
go build ./...
make build-fast
- name: Test
run: |
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export REPO_PATH=$GOPATH/src/github.com/suyashkumar/dicom
export PATH=$PATH:/home/runner/go/bin
cd $REPO_PATH
make test
- name: Benchmark
run: |
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export REPO_PATH=$GOPATH/src/github.com/suyashkumar/dicom
export PATH=$PATH:/home/runner/go/bin
go get golang.org/x/perf/cmd/benchstat
cd $REPO_PATH
make
go test -bench . > $HOME/new.txt
cd $GITHUB_WORKSPACE
git reset --hard HEAD
git checkout $GITHUB_BASE_REF
rm -rf $REPO_PATH
mkdir -p $REPO_PATH
mv $(pwd)/* $REPO_PATH
cd $REPO_PATH
go test -bench . > $HOME/old.txt
benchstat $HOME/old.txt $HOME/new.txt
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build/
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
BINARY = dicomutil
VERSION = `git describe --tags --always`

.PHONY: build
build:
Expand All @@ -23,10 +24,17 @@ run:
release:
go mod download
$(MAKE) test
GOOS=linux GOARCH=amd64 go build -o build/${BINARY}-linux-amd64 ./cmd/dicomutil;
GOOS=darwin GOARCH=amd64 go build -o build/${BINARY}-darwin-amd64 ./cmd/dicomutil;
GOOS=windows GOARCH=amd64 go build -o build/${BINARY}-windows-amd64.exe ./cmd/dicomutil;
GOOS=linux GOARCH=amd64 go build -ldflags="-X 'main.GitVersion=${VERSION}'" -o build/${BINARY}-linux-amd64 ./cmd/dicomutil;
GOOS=darwin GOARCH=amd64 go build -ldflags="-X 'main.GitVersion=${VERSION}'" -o build/${BINARY}-darwin-amd64 ./cmd/dicomutil;
GOOS=windows GOARCH=amd64 go build -ldflags="-X 'main.GitVersion=${VERSION}'" -o build/${BINARY}-windows-amd64.exe ./cmd/dicomutil;
cd build; \
tar -zcvf ${BINARY}-linux-amd64.tar.gz ${BINARY}-linux-amd64; \
tar -zcvf ${BINARY}-darwin-amd64.tar.gz ${BINARY}-darwin-amd64; \
zip -r ${BINARY}-windows-amd64.exe.zip ${BINARY}-windows-amd64.exe;

bench-diff:
go test -bench . -count 5 > bench_current.txt
git checkout main
go test -bench . -count 5 > bench_main.txt
benchstat bench_main.txt bench_current.txt
git checkout -
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Some notable features:
To use this in your golang project, import `github.com/suyashkumar/dicom`. This repository supports Go modules, and regularly tags releases using semantic versioning. Typical usage is straightforward:
```go

dataset, _ := dicom.ParseFile("testfiles/1.dcm", nil) // See also: dicom.Parse which has a generic io.Reader API.
dataset, _ := dicom.ParseFile("testdata/1.dcm", nil) // See also: dicom.Parse which has a generic io.Reader API.

// Dataset will nicely print the DICOM dataset data out of the box.
fmt.Println(dataset)
Expand Down
10 changes: 10 additions & 0 deletions cmd/dicomutil/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import (
"github.com/suyashkumar/dicom/pkg/tag"
)

// GitVersion is the current version of dicomutil, will be replaced in release step with current git commit hash or tag.
var GitVersion = "unknown"

var (
version = flag.Bool("version", false, "print current version and exit")
filepath = flag.String("path", "", "path")
extractImagesStream = flag.Bool("extract-images-stream", false, "Extract images using frame streaming capability")
printJSON = flag.Bool("json", false, "Print dataset as JSON")
Expand All @@ -28,6 +32,12 @@ const FrameBufferSize = 100

func main() {
flag.Parse()

if *version {
fmt.Printf("dicomutil: %s\n", GitVersion)
os.Exit(0)
}

if len(*filepath) > 0 {

f, err := os.Open(*filepath)
Expand Down
22 changes: 11 additions & 11 deletions parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ import (
"github.com/suyashkumar/dicom"
)

// TestParse is an end-to-end sanity check over DICOMs in testfiles/. Currently it only checks that no error is returned
// TestParse is an end-to-end sanity check over DICOMs in testdata/. Currently it only checks that no error is returned
// when parsing the files.
func TestParse(t *testing.T) {
files, err := ioutil.ReadDir("./testfiles")
files, err := ioutil.ReadDir("./testdata")
if err != nil {
t.Fatalf("unable to read testfiles/: %v", err)
t.Fatalf("unable to read testdata/: %v", err)
}
for _, f := range files {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".dcm") {
t.Run(f.Name(), func(t *testing.T) {
dcm, err := os.Open("./testfiles/" + f.Name())
dcm, err := os.Open("./testdata/" + f.Name())
if err != nil {
t.Errorf("Unable to open %s. Error: %v", f.Name(), err)
}
Expand All @@ -45,16 +45,16 @@ func TestParse(t *testing.T) {
}
}

// BenchmarkParse runs sanity benchmarks over the sample files in testfiles.
// BenchmarkParse runs sanity benchmarks over the sample files in testdata.
func BenchmarkParse(b *testing.B) {
files, err := ioutil.ReadDir("./testfiles")
files, err := ioutil.ReadDir("./testdata")
if err != nil {
b.Fatalf("unable to read testfiles/: %v", err)
b.Fatalf("unable to read testdata/: %v", err)
}
for _, f := range files {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".dcm") {
b.Run(f.Name(), func(b *testing.B) {
dcm, err := os.Open("./testfiles/" + f.Name())
dcm, err := os.Open("./testdata/" + f.Name())
if err != nil {
b.Errorf("Unable to open %s. Error: %v", f.Name(), err)
}
Expand All @@ -76,7 +76,7 @@ func BenchmarkParse(b *testing.B) {

func Example_readFile() {
// See also: dicom.Parse, which uses a more generic io.Reader API.
dataset, _ := dicom.ParseFile("testfiles/1.dcm", nil)
dataset, _ := dicom.ParseFile("testdata/1.dcm", nil)

// Dataset will nicely print the DICOM dataset data out of the box.
fmt.Println(dataset)
Expand All @@ -99,12 +99,12 @@ func Example_streamingFrames() {
}
}()

dataset, _ := dicom.ParseFile("testfiles/1.dcm", frameChan)
dataset, _ := dicom.ParseFile("testdata/1.dcm", frameChan)
fmt.Println(dataset) // The full dataset
}

func Example_getImageFrames() {
dataset, _ := dicom.ParseFile("testfiles/1.dcm", nil)
dataset, _ := dicom.ParseFile("testdata/1.dcm", nil)
pixelDataElement, _ := dataset.FindElementByTag(tag.PixelData)
pixelDataInfo := dicom.MustGetPixelDataInfo(pixelDataElement.Value)
for i, fr := range pixelDataInfo.Frames {
Expand Down
2 changes: 1 addition & 1 deletion pkg/frame/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (n *NativeFrame) GetEncapsulatedFrame() (*EncapsulatedFrame, error) {
func (n *NativeFrame) GetImage() (image.Image, error) {
i := image.NewGray16(image.Rect(0, 0, n.Cols, n.Rows))
for j := 0; j < len(n.Data); j++ {
i.SetGray16(j%n.Cols, j/n.Rows, color.Gray16{Y: uint16(n.Data[j][0])}) // for now, assume we're not overflowing uint16, assume gray image
i.SetGray16(j%n.Cols, j/n.Cols, color.Gray16{Y: uint16(n.Data[j][0])}) // for now, assume we're not overflowing uint16, assume gray image
}
return i, nil
}
93 changes: 93 additions & 0 deletions pkg/frame/native_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package frame_test

import (
"image"
"testing"

"github.com/suyashkumar/dicom/pkg/frame"
)

// point represents a 2D point for testing.
type point struct {
x int
y int
}

func TestNativeFrame_GetImage(t *testing.T) {
cases := []struct {
Name string
NativeFrame frame.NativeFrame
SetPoints []point
}{
{
Name: "Square",
NativeFrame: frame.NativeFrame{
Rows: 2,
Cols: 2,
Data: [][]int{{0}, {0}, {1}, {0}},
},
SetPoints: []point{{0, 1}},
},
{
Name: "Rectangle",
NativeFrame: frame.NativeFrame{
Rows: 3,
Cols: 2,
Data: [][]int{{0}, {0}, {0}, {0}, {1}, {0}},
},
SetPoints: []point{{0, 2}},
},
{
Name: "Rectangle - multiple points",
NativeFrame: frame.NativeFrame{
Rows: 5,
Cols: 3,
Data: [][]int{{0}, {0}, {0}, {0}, {1}, {1}, {0}, {0}, {0}, {0}, {1}, {0}, {0}, {0}, {0}},
},
SetPoints: []point{{1, 1}, {2, 1}, {1, 3}},
},
}

for _, tc := range cases {
t.Run(tc.Name, func(t *testing.T) {
img, err := tc.NativeFrame.GetImage()
if err != nil {
t.Fatalf("GetImage(%v) got unexpected error: %v", tc.NativeFrame, err)
}
imgGray, ok := img.(*image.Gray16)
if !ok {
t.Fatalf("GetImage(%v) did not return an image convertible to Gray16", tc.NativeFrame)
}

// Check that all pixels are zero except at the
// (ExpectedSetPointX, ExpectedSetPointY) point.
for x := 0; x < tc.NativeFrame.Cols; x++ {
for y := 0; y < tc.NativeFrame.Rows; y++ {
currValue := imgGray.Gray16At(x, y).Y
if within(point{x, y}, tc.SetPoints) {
if currValue != 1 {
t.Errorf("GetImage(%v), unexpected value at set point. got: %v, want: %v", tc.NativeFrame, currValue, 1)
}
continue
}

if currValue != 0 {
t.Errorf("GetImage(%v), unexpected value outside of set point. At (%d, %d) got: %v, want: %v", tc.NativeFrame, x, y, currValue, 0)
}

}
}
})

}
}

// within returns true if pt is in the []point
func within(pt point, set []point) bool {
for _, item := range set {
if pt.x == item.x && pt.y == item.y {
return true
}
}
return false
}
Loading

0 comments on commit 1780bba

Please sign in to comment.