personname

package
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2021 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

The personname package provides methods and data types for inspecting Person Name (PN) DICOM Value Representations, as defined here:

http://dicom.nema.org/dicom/2013/output/chtml/part05/sect_6.2.html

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrNullSepLevelInvalid = fmt.Errorf("TrailingNullLevel exceeded maximum")

ErrNullSepLevelInvalid is a sentinel error returned when Info.TrailingNullLevel or GroupInfo.TrailingNullLevel exceeds the maximum allowed value.

View Source
var ErrParseGroupCount = fmt.Errorf(
	"%w: no more than 3 groups with '[Alphabetic]%v[Ideographic]%v[Phonetic]' "+
		"format are allowed",
	ErrParsePersonName,
	groupSep,
	groupSep,
)

ErrParseGroupCount is returned when a value has more than 3 groups, violating the dicom spec. ErrParseGroupCount wraps ErrParsePersonName.

View Source
var ErrParseGroupSegmentCount = fmt.Errorf(
	"%w: no more than 5 segments with"+
		" '[Last]%v[First]%v[Middle]%v[Prefix]%v[Suffix]' format are allowed",
	ErrParsePersonName,
	segmentSep,
	segmentSep,
	segmentSep,
	segmentSep,
)

ErrParseGroupSegmentCount is returned when a group contains more than 5 segments, violating the dicom spec. ErrParseGroupSegmentCount wraps ErrParsePersonName.

View Source
var ErrParsePersonName = errors.New(
	"error parsing PN value",
)

ErrParsePersonName is returned when attempting to parse Info from a string.

Functions

This section is empty.

Types

type GroupInfo

type GroupInfo struct {
	// FamilyName is the person's family or last name.
	FamilyName string
	// GivenName if the person's given or first names.
	GivenName string
	// MiddleName is the person's middle name(s).
	MiddleName string
	// NamePrefix is the person's name prefix (ex: MR., MRS.).
	NamePrefix string
	// NameSuffix is the person's name suffix (ex: Jr, III).
	NameSuffix string

	// TrailingNullLevel contains the highest present null '^' separator in the DCM()
	// value. For most use cases GroupNullLevelAll or GroupNullLevelNone should be used when
	// creating new PN values. Use other levels only if you know what you are doing!
	TrailingNullLevel GroupTrailingNullLevel
}

GroupInfo holds the parsed information for any one of these groups the person name groups specified in the DICOM spec:

  • Alphabetic
  • Ideographic
  • Phonetic

func (GroupInfo) DCM

func (group GroupInfo) DCM() (string, error)

DCM Returns original, formatted string in '[FamilyName]^[GivenName]^[MiddleName]^[NamePrefix]^[NameSuffix]'.

func (GroupInfo) IsEmpty

func (group GroupInfo) IsEmpty() bool

IsEmpty returns true if all group segments are empty, even if Raw value was "^^^^".

func (GroupInfo) MustDCM

func (group GroupInfo) MustDCM() string

MustDCM is as DCM, but panics on error.

MustDCM will only panic if TrailingNullLevel exceeds GroupNullLevelAll.

type GroupTrailingNullLevel

type GroupTrailingNullLevel uint

GroupTrailingNullLevel represents how many null '^' separators are present in the GroupInfo.DCM() return value.

const (
	// GroupNullLevelNone will render no null seps.
	GroupNullLevelNone GroupTrailingNullLevel = iota

	// NullSepGiven will render null separators up to the separator before the
	// GroupInfo.GivenName segment
	GroupNullLevelGiven

	// NullSepGiven will render null separators up to the separator before the
	// GroupInfo.MiddleName segment
	GroupNullLevelMiddle

	// NullSepGiven will render null separators up to the separator before the
	// GroupInfo.NamePrefix segment
	GroupNullLevelPrefix

	// NullSepGiven will render null separators up to the separator before the
	// GroupInfo.NameSuffix segment (ALL possible separators).
	GroupNullLevelAll
)

func (GroupTrailingNullLevel) String

func (level GroupTrailingNullLevel) String() string

String implements fmt.Stringer, giving human-readable names to the trailing null level.

Returns "NONE" if no null separators were present.

Returns "ALL" if the highest possible null separator was present.

Otherwise, returns the name of the section that comes after the highest present null separator.

String will panic if called on a value that exceeds GroupNullLevelAll.

type Info

type Info struct {
	// Alphabetic group information about the Alphabetic group.
	Alphabetic GroupInfo
	// Ideographic group information about the Ideographic group.
	Ideographic GroupInfo
	// Phonetic group information about the Phonetic group.
	Phonetic GroupInfo

	// TrailingNullLevel contains the highest present null '=' separator in the DCM()
	// value. For most use cases InfoNullLevelAll or InfoNullLevelNone should be used when
	// creating new PN values. Use other levels only if you know what you are doing!
	TrailingNullLevel InfoTrailingNullLevel
}

Info holds information from an element with a "PN" VR. See the "PN" entry at: http://dicom.nema.org/dicom/2013/output/chtml/part05/sect_6.2.html

PN values are split into three groups which represent three different ways to represent a name:

- Alphabetic: How a name is formally spelled using a Phonetic alphabet. - Ideographic: How a name is represented using ideograms / ideographs. - Phonetic: How a name is pronounced.

Each of these groups can be inspected to access their individual segments (family name, Given name, etc.)

func Parse

func Parse(valueString string) (Info, error)

Parse PN dicom value into a personname.Info value.

Example

ExampleParse shows how to parse an existing PN value.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	// A Raw PN string value with Alphabetic, Ideographic, and Phonetic information.
	rawPN := "Potter^Harry^James^^=哈利^波特^詹姆^^=hɛər.i^pɒ.tər^dʒeɪmz^^"

	// To parse a PN value, use personName.Parse
	parsedPN, err := personname.Parse(rawPN)
	if err != nil {
		panic(err)
	}

	// PN values are broken into three groups: Alphabetic, Phonetic, and Ideographic;
	// our struct contains a field for each one.
	fmt.Println("ALPHABETIC:", parsedPN.Alphabetic.MustDCM())
	fmt.Println("IDEOGRAPHIC:", parsedPN.Ideographic.MustDCM())
	fmt.Println("PHONETIC:", parsedPN.Phonetic.MustDCM())

	// We can check to what level of trailing null separators were present, because
	// there are no null groups, the level will be NONE.
	fmt.Println("INFO NULL SEPS:", parsedPN.TrailingNullLevel)

	// Each GroupInfo in turn is parsed into discrete fields for each name segment.
	fmt.Println("FAMILY NAME:", parsedPN.Alphabetic.FamilyName)
	fmt.Println("GIVEN NAME: ", parsedPN.Alphabetic.GivenName)
	fmt.Println("MIDDLE NAME:", parsedPN.Alphabetic.MiddleName)
	fmt.Println("NAME PREFIX:", parsedPN.Alphabetic.NamePrefix)
	fmt.Println("NAME SUFFIX:", parsedPN.Alphabetic.NameSuffix)

	// The alphabetic null separators, on the other hand, will be ALL, since there are
	// null separators and the maximum allowed number is present.
	fmt.Println("ALPHABETIC NULL SEPS:", parsedPN.Alphabetic.TrailingNullLevel)

	// To print the original Raw value, simply use the DCM() or MustDCM() methods.
	fmt.Println("DCM OUTPUT :", parsedPN.MustDCM())

	// Outputs:
	// ALPHABETIC: Potter^Harry^James^^
	// IDEOGRAPHIC: 哈利^波特^詹姆^^
	// PHONETIC: hɛər.i^pɒ.tər^dʒeɪmz^^
	// INFO NULL SEPS: NONE
	//
	// FAMILY NAME: Potter
	// GIVEN NAME:  Harry
	// MIDDLE NAME: James
	// NAME PREFIX:
	// NAME SUFFIX:
	// ALPHABETIC NULL SEPS: ALL
	//
	// DCM OUTPUT : Potter^Harry^James^^=哈利^波特^詹姆^^=hɛər.i^pɒ.tər^dʒeɪmz^^
}
Output:

Example (PartialNullSeparators)

ExampleParse_partialNullSeparators shots parsing a name with only a few null separators.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	// This value only has one null separator. While this is a legal value, it's format
	// is somewhat irregular.
	rawPN := "Potter^Harry^"

	// To parse a PN value, use personName.Parse
	parsedPN, err := personname.Parse(rawPN)
	if err != nil {
		panic(err)
	}

	// We can check the null separator level here. When it is not NONE or ALL, it will
	// be the name of the segment that comes after the highest present null separator:
	fmt.Println("NULL SEP LEVEL:", parsedPN.Alphabetic.TrailingNullLevel)

	// Print the MustDCM() method, the missing null separators are preserved.
	fmt.Println("DCM OUTPUT    :", parsedPN.MustDCM())

}
Output:

NULL SEP LEVEL: MiddleName
DCM OUTPUT    : Potter^Harry^

func (Info) DCM

func (info Info) DCM() (string, error)

DCM returns the serialized DICOM representation of the PN value, in '[Alphabetic]=[Ideographic]=[Phonetic]' format.

func (Info) IsEmpty

func (info Info) IsEmpty() bool

IsEmpty returns whether the PN value contains any actual information. This method ignores separator, so both ” and '^^^^=^^^^=^^^^' would return true.

func (Info) MustDCM

func (info Info) MustDCM() string

MustDCM is as DCM, but panics on error.

MustDCM will only panic if TrailingNullLevel exceeds InfoNullLevelAll.

func (Info) WithFormat

func (info Info) WithFormat(
	infoNullSepLevel InfoTrailingNullLevel,
	alphabeticNullSepLevel,
	ideographicNullSepLevel,
	phoneticNullSepLevel GroupTrailingNullLevel,
) Info

WithFormat returns a new Info object with null separator settings applied to the relevant Info / GroupInfo objects.

infoNullSepLevel sets the highest '=' null separator to render between groups.

The remaining options will apply the passed value to their groups respective TrailingNullLevel value.

WithFormat does not mutate its receiver value, instead returning a new value to the caller with the passed settings.

Example

ExampleInfo_WithFormat shows reformatting a PN value to a mix and match of formatting options.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	rawVal := "Potter^Harry^^^=^^^^=^^^^"

	parsedPN, err := personname.Parse(rawVal)
	if err != nil {
		panic(err)
	}

	fmt.Println("ORIGINAL   :", parsedPN.MustDCM())

	reformatted := parsedPN.WithFormat(
		personname.InfoNullLevelNone, // groupTrailingNulls
		// We will keep empty separators for the Alphabetic group.
		personname.GroupNullLevelAll,  // alphabeticTrailingNulls
		personname.GroupNullLevelNone, // ideographicTrailingNulls
		personname.GroupNullLevelNone, // phoneticTrailingNulls
	)
	fmt.Println("REFORMATTED:", reformatted.MustDCM())

}
Output:

ORIGINAL   : Potter^Harry^^^=^^^^=^^^^
REFORMATTED: Potter^Harry^^^

func (*Info) WithTrailingNulls

func (info *Info) WithTrailingNulls() Info

WithTrailingNulls returns a new Info object that will keep trailing separators that surround both null groups AND group segments: (ex: 'Potter^Harry^^^==').

WithTrailingNulls is equivalent to calling WithFormat() with all options set to GroupNullLevelAll.

WithTrailingNulls does not mutate its receiver value, instead returning a new value to the caller with the passed settings.

Example

ExampleInfo_WithTrailingNulls shows reformatting a PN value without trailing separators.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	rawVal := "Potter^Harry"

	parsedPN, err := personname.Parse(rawVal)
	if err != nil {
		panic(err)
	}

	fmt.Println("ORIGINAL   :", parsedPN.MustDCM())

	reformatted := parsedPN.WithTrailingNulls()
	fmt.Println("REFORMATTED:", reformatted.MustDCM())

}
Output:

ORIGINAL   : Potter^Harry
REFORMATTED: Potter^Harry^^^=^^^^=^^^^

func (Info) WithoutEmptyGroups

func (info Info) WithoutEmptyGroups() Info

WithoutEmptyGroups sets Info.TrailingNullLevel to false, then checks each group, and if it contains no actual information, sets that group's TrailingNullLevel to GroupNullLevelNone.

Groups with Partial information will retain their null separators.

Example

ExampleInfo_WithoutEmptyGroups demos removing groups with no actual information, and the Alphabetic group has partial information.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	rawVal := "Potter^Harry^^^=^^^^=^^^^"

	parsedPN, err := personname.Parse(rawVal)
	if err != nil {
		panic(err)
	}

	fmt.Println("ORIGINAL   :", parsedPN.MustDCM())

	reformatted := parsedPN.WithoutEmptyGroups()
	fmt.Println("REFORMATTED:", reformatted.MustDCM())

}
Output:

ORIGINAL   : Potter^Harry^^^=^^^^=^^^^
REFORMATTED: Potter^Harry^^^
Example (HasPhonetic)

ExampleInfo_WithoutEmptyGroups demos removing groups with no actual information when both the Alphabetic and Phonetic group has partial information, but bot the ideographic group.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	rawVal := "Potter^Harry^^^=^^^^=hɛər.i^pɒ.tər^dʒeɪmz^^"

	parsedPN, err := personname.Parse(rawVal)
	if err != nil {
		panic(err)
	}

	fmt.Println("ORIGINAL   :", parsedPN.MustDCM())

	reformatted := parsedPN.WithoutEmptyGroups()
	fmt.Println("REFORMATTED:", reformatted.MustDCM())

}
Output:

ORIGINAL   : Potter^Harry^^^=^^^^=hɛər.i^pɒ.tər^dʒeɪmz^^
REFORMATTED: Potter^Harry^^^==hɛər.i^pɒ.tər^dʒeɪmz^^

func (*Info) WithoutTrailingNulls

func (info *Info) WithoutTrailingNulls() Info

WithoutTrailingNulls returns a new Info object that will remove trailing separators that surround both null groups AND group segments: (ex: 'Potter^Harry').

WithoutTrailingNulls is equivalent to calling WithFormat() with all options set to GroupNullLevelNone.

WithoutTrailingNulls does not mutate its receiver value, instead returning a new value to the caller with the passed settings.

Example

ExampleInfo_WithoutTrailingNulls shows reformatting a PN values without trailing separators.

package main

import (
	"fmt"

	"github.com/LawyZheng/dicom/pkg/personname"
)

func main() {
	rawVal := "Potter^Harry^^^=^^^^=^^^^"

	parsedPN, err := personname.Parse(rawVal)
	if err != nil {
		panic(err)
	}

	fmt.Println("ORIGINAL   :", parsedPN.MustDCM())

	reformatted := parsedPN.WithoutTrailingNulls()
	fmt.Println("REFORMATTED:", reformatted.MustDCM())

}
Output:

ORIGINAL   : Potter^Harry^^^=^^^^=^^^^
REFORMATTED: Potter^Harry

type InfoTrailingNullLevel

type InfoTrailingNullLevel uint

InfoTrailingNullLevel represents how many null '=' separators are present in the Info.DCM() return value.

const (
	// InfoNullLevelNone will render no null seps.
	InfoNullLevelNone InfoTrailingNullLevel = iota

	// InfoNullLevelIdeographic will render null separators up to the separator before the
	// Info.Ideographic segment
	InfoNullLevelIdeographic

	// InfoNullLevelAll will render null separators up to the separator before the
	// Info.Phonetic segment, or ALL possible separators.
	InfoNullLevelAll
)

func (InfoTrailingNullLevel) String

func (level InfoTrailingNullLevel) String() string

String implements fmt.Stringer, giving human-readable names to the null sep level.

Returns "NONE" if no null separators were present.

Returns "ALL" if the highest possible null separator was present.

Otherwise, returns the name of the section that comes after the highest present null separator.

String will panic if called on a value that exceeds InfoNullLevelAll.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL