Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Apr 05 16:58

    KarlSjostrand on master

    Update README.md (compare)

  • Apr 05 16:55

    KarlSjostrand on master

    Update README.md (compare)

  • Apr 05 16:55

    KarlSjostrand on develop

    Update README.md (compare)

  • Feb 14 21:42

    KarlSjostrand on develop

    Prepare for release 2.0.2 Post release version bump (compare)

  • Feb 14 21:41

    KarlSjostrand on v2.0.2

    (compare)

  • Feb 14 21:40

    KarlSjostrand on master

    Post release version bump Updated deps Prepare for release 2.0.2 (compare)

  • Feb 14 21:38

    KarlSjostrand on develop

    Updated deps (compare)

  • Feb 11 14:57

    KarlSjostrand on v1.6.1

    (compare)

  • Feb 11 14:56

    KarlSjostrand on v1.6.1

    Backport of S3 bulk delete bug … (compare)

  • Feb 11 13:27

    KarlSjostrand on develop

    Prepare for release 2.0.1 Post release version bump (compare)

  • Feb 11 13:10

    KarlSjostrand on v2.0.1

    (compare)

  • Feb 11 13:08

    KarlSjostrand on master

    Post release version bump Added explicit lengths to anon … Fixed bulk delete. Map only cre… and 7 more (compare)

  • Feb 11 12:37

    KarlSjostrand on develop

    Fixed tests (compare)

  • Feb 09 16:08

    KarlSjostrand on develop

    Another fix for flat series ord… (compare)

  • Feb 09 16:01

    KarlSjostrand on develop

    Another fix for flat series ord… (compare)

  • Feb 09 01:21

    KarlSjostrand on develop

    Fix for flatSeries id problem (compare)

  • Feb 08 21:21

    KarlSjostrand on develop

    Updated deps. Fixed foreign key… (compare)

  • Feb 08 14:14

    KarlSjostrand on 328-bulk-delete

    (compare)

  • Feb 08 14:14

    KarlSjostrand on develop

    Fixed bulk delete. Map only cre… Merge pull request #329 from sl… (compare)

  • Feb 08 14:14
    KarlSjostrand closed #329
Ghislain Antony Vaillant
@ghisvail
What I meant was: upstream I specified collectAttributesFlow(Seq(Tag1, Tag2, Tag3...)) and downstream I get a DicomAttributes(Seq[DicomAttribute]]). I suppose the mapping between the Seq in collectAttributesFlow and the Seq in DicomAttributes is positional, right?
Or is there a way to do a attributes.get(Tag1) and get the corresponding DicomAttribute (wrapped in a monadic type like Try or Option)?
Ghislain Antony Vaillant
@ghisvail
I am getting some AbruptIOTerminationException on when importing some DICOM files on version 1.4.2, both with Docker and on a host deployment. Do you guys know where it could come from?
Whereas on 1.4.1 I am getting a DicomStreamException due to a unsupported presentation context.
I'd consider it a regression, considering the loss of explicitness in the new error.
Ghislain Antony Vaillant
@ghisvail
After putting the right settings in slicebox.conf (accepted-sop-instances and accepted-transfer-syntaxes), the issue is gone. Still, I think the error message in version 1.4.1 was more informative than in 1.4.2.
Karl Sjöstrand
@KarlSjostrand
@ghisvail Totally agree. It sounds like a regression, I'll take a look.
On your comment about attributes - apologies for not responding yet. I am working on handling of attributes which has no dependency on dcm4che but it is taking me a while to find something that feels right. Work resides in the branch https://github.com/slicebox/dicom-streams/tree/feature/dicom-attributes. I'll update here when it's finished.
Ghislain Antony Vaillant
@ghisvail
No problem Karl, glad you did not forget about me :-)
I am still getting up to speed with akka-streams and dicom-streams
Ghislain Antony Vaillant
@ghisvail
Quick question: in the collectAttributesFlow, is there a reason why the parameter is of tags: Set[Int] and not tags: Set[TagPath] or tags: Set[Tag]? That latter two would yield an interface which is safer and more explicit (any Int vs a DICOM tag).
In particular when discovering the library API via an IDE which provides a type hinter (like Intellij). In my experience, you can tell when a library is well designed, when your are lead nicely by its type signatures.
Karl Sjöstrand
@KarlSjostrand
Good question. That method calls the more general method with parameters (tagCondition: TagPath => Boolean, stopCondition: TagPath => Boolean, maxBufferSize: Int) where tagCondition as you can see is based on tag paths, not Ints. The thinking was that the simplified case would be only for attributes in the root dataset. Type safety is always nice though so a Tag class might make sense. What do you think?
Ghislain Antony Vaillant
@ghisvail
I am confused as to why TagPath would not work here? Afterall, it's a wrapper type over the actual tag value as Int according to the content of the trait. So operation likes Set[Int].max used to find the maximum tag in the input set for collectAttributesFlow should work with a Set[TagPath], assuming the latter implements the necessary ordering functionality, no?
The problem with the Tag class is that it's already taken by dcm4che so you'd be in risk of introducing conflicts to the compiler, I suppose?
Karl Sjöstrand
@KarlSjostrand
I see you point. I made this change in the branch I'm working on and it looks good. Need to test this some more but I'm hoping that this will be merged within a week or so. I am not worried about the naming of the Tag class. If you want to access these classes (Tag, Keyword, UID) from both dcm4che and dicom-streams in the same Scala class you can always rename them when importing, e.g. import org.dcm4che.data.{Tag => CheTag} but I'm hoping that dicom-streams will work without dcm4che in many situations going forward.
Ghislain Antony Vaillant
@ghisvail
Fyi, I just filed #276 regarding the regression of the failure message mentioned earlier.
I see your point. What would be the difference between Tag and TagPath then?
Perhaps #276 could be a good newcomer bug to be fixed by someone like me?
Ghislain Antony Vaillant
@ghisvail
Probably a stupid question. How do you guys communicate between a Slicebox instance running in Docker and the host machine (running storescu / storescp)?
Ghislain Antony Vaillant
@ghisvail
I run docker with docker run -d -p 5000:5000 -p 11112 and left 11112 unbound for SCU / SCP
Karl Sjöstrand
@KarlSjostrand
@ghisvail Regarding #276 we provided a fix last week (slicebox/slicebox@2f286a4), but thanks for offering to submit a PR! Tons of other issues to work on if you can find the time.
Ghislain Antony Vaillant
@ghisvail
If you can tag the ones you consider newcomer friendly, then I'll happily have a look
Karl Sjöstrand
@KarlSjostrand
The Tag class provides a list of tag numbers defined as constants. If you think of a DICOM dataset as a tree of elements with data elements at the leaves and sequence elements elsewhere, then the TagPath data structure describes a path from the root into this tree. You can specify which items of sequences to go into, and also specify "all items" which means that a TagPath can point to multiple branches at once. One example of where this is useful is when modifying attributes. The tag path (0101,0202)[*].(0010,0010) would point to the (0010,0010) tag in all items of the (0101,0202) sequence - if that is what you wish to modify.
Great idea with the newcomer issue label. Looking at the Akka repo, they have labels good first issue and small. Do you prefer one of these?
Ghislain Antony Vaillant
@ghisvail
Thanks for clarifying
Your call for the newcomer tag name :-)
Karl Sjöstrand
@KarlSjostrand
Hmm, I'll add small first and see how we go :smile:
Karl Sjöstrand
@KarlSjostrand
Ok first issue tagged with small.
Michael Kober
@kobmic
@ghisvail Regarding your question about scu/scp and running in docker - I have to admit that I never tested that until now. Easiest way should be docker run -p 5000:5000 -p 11112:11112 or if you want to add multiple scu/scp configs you'd probably define a port range: docker run -p 5000:5000 -p 11110-11119:11110-11119.
Ghislain Antony Vaillant
@ghisvail
I tried using -p 11112:11112 but then the host application (storescu or storescp for instance) complains the port is already bound
Michael Kober
@kobmic
OK, now I see the problem, my scu/scp test was from one sbx to another sbx on different hosts
Ghislain Antony Vaillant
@ghisvail
what would the nominal setup to instantiate a single SCU provider as a Source[ByteString, NotUsed]
I am struggling to extract this logic from the slicebox code base
I'd basically want to call a function or a class where I can pass the SCU parameters (port, aetitle, accepted sop and transfer syntaxes) and get a Source[ByteString, NotUsed] which could then be plugged to an integration pipeline.
Ghislain Antony Vaillant
@ghisvail
Without the overhead of DAO and Actor management
Same issue will happen for the SCP as a Sink[ByteString, Future[Done]]
Ghislain Antony Vaillant
@ghisvail
@KarlSjostrand @kobmic any ideas?
For now, I have got a basic pipeline feeding from a source directory of DICOM files (via Directory.ls from alpakka)
and writing to a target directory
ideally I'd want to replace these source and sink by a rudimentary SCP / SCU
Ghislain Antony Vaillant
@ghisvail
I can't get the tag modification function to work on a simple toy example
I have tried the following:
FileIO.fromPath(Paths.get(path))
    .via(validateFlow)          // Validate the flow as DICOM.
    .via(parseFlow)             // Parse the flow to DICOM parts.
    .via(blacklistFilter(Set(TagPath.fromTag(Tag.PixelData))))
    .via(attributeFlow)
    .via(groupLengthDiscardFilter)
    .via(modifyFlow(
      TagModification.endsWith(TagPath.fromTag(Tag.InstitutionName), _ => updateInstitution, insert = true),
    ))
    .via(fmiGroupLengthFlow)
    .runForeach {
      case DicomAttribute(h, v) if h.tag == Tag.InstitutionName => println(h, v)
      case other => ()
    }
And I am getting:
(DicomHeader (0008,0080) LO length = 8 value length = 0 ByteString(8, 0, -128, 0, 76, 79, 0, 0),List())
where I should be getting the value in updateInstitution
which is defined as val updateInstitution: ByteString = padToEvenLength(ByteString("My Institution"), VR.LO)
Am I doing something wrong here?
Karl Sjöstrand
@KarlSjostrand
@ghisvail Try removing .via(attributeFlow) which groups each header and its value chunks into a single object. The modifyFlow does not modify these combined objects. As a side note, attributeFlow is mostly used as preparation for creating a dcm4che Attributes but I never liked this pattern. This is improved in the dicom-streams repo which will soon be released.