New post

Find

Article
· May 2 3m read

Creating a DICOM file and adding a JPG to it

One of the challenges of creating a DICOM message is how to implement putting data in the correct place. Part of it is by inserting the data in the specific DICOM tags, while the other is to insert binary data such as a picture - In this article I will explain both.

To create a DICOM message, you can either use the  EnsLib.DICOM.File class (to create a DICOM file) or the  EnsLib.DICOM.Document class (to create a message that can be sent to PACS directly). In either case, the SetValueAt method will allow you to add your data to the DICOM tags.

A DICOM message consists of two constituent parts, CommandSet and the DataSet.
The CommandSet contains DICOM elements which contain details about the characteristics of the DataSet, while the DataSet contains the data itself - patient's demographic, image etc.

To update the tags in the CommandSet or the DataSet, simply state the value and the name of the property you wish to update using the SetValueAt method:

set tstatus=tDoc.SetValueAt("1.2.840.10008.5.1.4.1.1.7","CommandSet.MediaStorageSOPClassUID")
set tstatus=tDoc.SetValueAt("1.2.392.200059.1.11.11084587.3.35820032317.2.1.56","CommandSet.MediaStorageSOPInstanceUID") 
set tstatus=tDoc.SetValueAt("1.2.276.0.7230010.3.0.3.6.4","CommandSet.ImplementationClassUID") 
set tstatus=tDoc.SetValueAt("OFFIS_DCMTK_364","CommandSet.ImplementationVersionName") 
set tstatus=tDoc.SetValueAt("Morgan^Gina^G","DataSet.PatientName") 
set tstatus=tDoc.SetValueAt("2751","DataSet.PatientID")
set tstatus=tDoc.SetValueAt("19810816","DataSet.PatientBirthDate")	
set tstatus=tDoc.SetValueAt("F","DataSet.PatientSex") 
you can either use the property name or the property tag. For example, those 2 commands are updating the same tag:
	set tstatus=tDoc.SetValueAt("Olympus","DataSet.Manufacturer")		
	set tstatus=tDoc.SetValueAt("Olympus","DataSet.(0008,0070)") 

Once the message is created and transferred to PACS as a document, you can see its data as part of the trace (note that binary data cannot be seen):

In order to add the binary data for the image, it is more complicated that just putting the data in a specific tag, because it needs to be structured in a specific way and measured appropriately. This is why after updating the tags and saving the document, we need to open it as a simple binary file and add the image data at the end of it in a specific manner.

The image is part of the PixelData property in tag (7FE0,0010).

This tag is a sequence - DICOM allows a DataSet to contain other nested DataSets, which are encoded as “sequences”. The point of this structure is to allow repeating groups of data, so whilst such sequences often only contain a single DataSet, the format is defined such that each sequence consists of a set of DataSets.

This structure can be used in recursion, and some DICOM scenarios might use sequences nested 5 or 6 deep.

 

The demo shows a sample of creating a DICOM document with an image in it. The patient's demographic and other details are just for the sake of teh sample. To run this demo, simply put a JPG file in a directory, configure the directory name in the 'FileStorageDirectory' property in the business operation's settings:

 

and run the Business Process. After its completion, you'll see a new dcm file in the same directory where your JPG file was. open it in a DICOM viewer and you'll see the DICOM tags as well as the image in it:

 

Here is a quick demo showing the whole process:

Look for the demo files and instruction in Open Exchange:

https://openexchange.intersystems.com/package/DICOM--Image-Demo

Keren.

Discussion (0)0
Log in or sign up to continue
Discussion
· May 2

Vamos discutir a nova IU para Interoperabilidade e editor de Transformações de Dados

Já faz um tempo desde que a nova interface de usuário para Produções e DTL foi publicada como uma prévia e eu gostaria de saber suas opiniões sobre ela.

AVISO: Esta é uma opinião pessoal, totalmente pessoal e não relacionada com a InterSystems Corporation.

Vou começar com a tela de Interoperabilidade:

Tela de Produção:

O estilo é sóbrio e sem adornos, seguindo a linha do design de serviços de nuvem, eu gosto.

Mas, sempre um mas... ou talvez dois:

Na minha opinião, há informação demais, o menu esquerdo é supérfluo. É verdade que você pode recolhê-lo, mas não quero fazer isso cada vez que uso a tela. Não preciso ver o tempo todo todas as produções no meu NAMESPACE, os Itens de Produção, Conjuntos de Regras e Transformações de Dados. Sinto que os designers sofreram um "horror vacui"

Sobre esses menus, parece que as opções estão muito próximas:

E exibir os editores de Regras e Transformações de Dados na mesma tela para telas pequenas como a de um laptop é um pesadelo de rolagem:

Uma janela pop-up com os editores seria mais "limpa" para o usuário comum. Um ponto positivo é que podemos selecionar como queremos abrir os editores.

Mas talvez tenhamos opções demais.

Editor de DTL:

Bem, eu gosto, o design é simples e claro, talvez, como na tela de Produção, as linhas estejam muito próximas e perdemos o arrastar e soltar para ligar os campos.

Conclusão:

O design foi modernizado e parece agradável, mas na minha opinião como um ex-desenvolvedor web "menos é mais". Eu gostaria de trabalhar com telas mais simples, com um comportamento bem definido, não preciso acessar todas as funcionalidades de interoperabilidade na mesma tela.

Minha modesta opinião, precisamos equilibrar funcionalidades e uma interface de usuário amigável e moderna, o novo design parece ir nessa direção. Obrigado a toda a equipe envolvida no desenvolvimento!

[OBS.: o texto reflete a opinião pessoal do AUTOR, não do TRADUTOR.]

Discussion (0)1
Log in or sign up to continue
Article
· May 2 3m read

Minify XML in IRIS

In a project I'm working on we need to store some arbitrary XML in the database. This XML does not have any corresponding class in IRIS, we just need to store it as a string (it's relatively small and can fit in a string).
Since there are MANY (millions!) of records in the database I decided to reduce as much as possible the size without compressing. I know that some XML to be stored is indented, some not, it varies.
To reduce the size I decided to minify  the XML, but how do I minify an XML document in IRIS?
I searched across all the classes/utilities and I could not find a ready made code/method, so I had to implement it and it turned out to be fairly simple in IRIS using %XML.TextReader class, frankly simpler than I expected.

Since this can be useful in some other context, I decided to share this little utility with the Developer Community.
I've tested with some fairly complex XML documents and works fine, here is the code.

/// Minify an XML document passed in the XmlIn Stream, the minified XML is returned in XmlOut Stream
/// If XmlOut Stream is passed, then the minified XML is stored in the passed Stream, otherwise a %Stream.TmpCharacter in returned in XmlOut.
/// Collapse = 1 (default), empty elements are collapsed, e.g. <tag></tag> is returned as <tag/>
/// ExcludeComments = 1 (default), comments are not returned in the minified XML
ClassMethod MinifyXML(XmlIn As %Stream, ByRef XmlOut As %Stream = "", Collapse As %Boolean = 1, ExcludeComments As %Boolean = 1) As %Status
{
	#Include %occSAX
	Set sc=$$$OK
	Try {
		Set Mask=$$$SAXSTARTELEMENT+$$$SAXENDELEMENT+$$$SAXCHARACTERS+$$$SAXCOMMENT
		Set sc=##class(%XML.TextReader).ParseStream(XmlIn,.reader,,$$$SAXNOVALIDATION,Mask)
		#dim reader as %XML.TextReader
		If $$$ISERR(sc) Quit
		If '$IsObject(XmlOut) {
			Set XmlOut=##class(%Stream.TmpCharacter).%New()
		}
		While reader.Read() {
			Set type=reader.NodeType
			If ((type="error")||(type="fatalerror")) {
				Set sc=$$$ERROR($$$GeneralError,"Error loading XML "_type_"-"_reader.Value)
				Quit
			}
			If type="element" {
				Do XmlOut.Write("<"_reader.Name)
				If Collapse && reader.IsEmptyElement {
					; collapse empty element
					Do XmlOut.Write("/>")
					Set ElementEnded=1
				} Else {
					; add attributes
					For k=1:1:reader.AttributeCount {
						Do reader.MoveToAttributeIndex(k)
						Do XmlOut.Write(" "_reader.Name_"="""_reader.Value_"""")
					}
					Do XmlOut.Write(">")
				}
			} ElseIf type="chars" {
				Set val=reader.Value
				Do XmlOut.Write($select((val["<")||(val[">")||(val["&"):"<![CDATA["_$replace(val,"]]>","]]]]><![CDATA[>")_"]]>",1:val))
			} ElseIf type="endelement" {
				If $g(ElementEnded) {
					; ended by collapsing
					Set ElementEnded=0
				} Else {
					Do XmlOut.Write("</"_reader.Name_">")
				}
			} ElseIf 'ExcludeComments && (type="comment") {
				Do XmlOut.Write("<!--"_reader.Value_"-->")
			}
		}
	} Catch CatchError {
		#dim CatchError as %Exception.SystemException
		Set sc=CatchError.AsStatus()
	}
	Quit sc
}

P.S.: anyone know if there is other/simpler way to minify XML in IRIS?

3 new Comments
Discussion (3)1
Log in or sign up to continue
Question
· May 2

Gorakhpur to Nepal Tour Package

Explore the captivating beauty and rich cultural heritage of Nepal – a destination known for its majestic landscapes, spiritual energy, and exciting experiences. Whether it’s the historic temples, scenic mountains, or local flavours, Nepal promises a journey like no other.

Our Gorakhpur to Nepal Tour Package is the perfect opportunity to explore the vibrant culture, majestic landscapes, and spiritual essence of Nepal, all starting from Gorakhpur! Whether you are planning a family holiday, a honeymoon, or an adventure trip, this package promises a memorable journey at the best prices with our private transportation, following well-planned and flexible itineraries tailored to your preferences, indulging in delicious meals throughout your trip, and exploring Nepal’s top attractions with guided sightseeing

Discussion (0)1
Log in or sign up to continue
Question
· May 2

Side Table vs. End Table: What’s the Difference and Which One Do You Need?

When it comes to furnishing a living room, small details can make a big impact. Among those essentials, the side table and end table often steal the spotlight. At first glance, they might seem interchangeable—both are compact, functional, and stylish. But understanding the subtle differences between a side table and an end table can help you make a more informed, intentional choice that enhances both the look and functionality of your space.

So, what sets them apart? And how do you decide which one is the right fit for your home? Let’s dive in.

 


What Is a Side Table?

A side table is a versatile piece of furniture typically placed next to a sofa, chair, or along the wall. It's designed to hold everyday items like books, décor, lamps, or beverages. A side table for living room is often more decorative and can come in various shapes and materials—from glass and metal to marble and wood.

Key Features:

  • Available in different heights and widths
  • Positioned beside furniture but not necessarily at the "end"
  • Serves both aesthetic and functional purposes
  • Can stand alone or be used in pairs

What Is an End Table?

An end table is a specific type of side table traditionally placed at the end of a sofa or sectional. Its primary function is to provide easy access to essentials like drinks, remotes, or table lamps. While all end tables are side tables, not all side tables are end tables.

Key Features:

  • Usually similar in height to the arm of the sofa
  • Placed at the ends of seating furniture
  • Often comes in pairs to create symmetry
  • Focuses more on functionality than decoration

Side Table vs. End Table: Spotting the Differences

While the differences can be subtle, here are a few defining factors that separate side tables from end tables:

Feature Side Table End Table
Placement Anywhere beside seating, wall, or bed At the end of a sofa or sectional
Functionality Multipurpose – decorative and functional Primarily functional
Design Flexibility Wide range of styles and heights Generally standardized for sofa alignment
Pairing Often used solo or mismatched Commonly used in symmetrical pairs


Which One Do You Need?

1. For a Functional Living Room Setup

If your goal is to create a practical and user-friendly living room, end tables might be your best bet. Placed at either end of a couch or seating arrangement, they offer convenient storage and surface space for frequently used items.

Pro Tip: Use matching end tables to frame a three-seater sofa and balance the layout visually.

2. For a Decorative Touch

If you’re more focused on aesthetics, a side table for living room adds flair and personality. Think of a sculptural metal stand, a colorful ceramic pedestal, or a chic wooden side table that showcases indoor plants or art pieces.

Pro Tip: Choose a side table in an accent color or unique texture to serve as a statement piece.


Different Types of Side Tables and Where to Use Them

Sofa Side Table

These are slim, vertical tables designed to slide close to the arm of the sofa. Perfect for placing a laptop, coffee mug, or book, a sofa side table is ideal for compact spaces.

  • Great for: Small apartments, reading nooks, modern interiors
  • Best material: Wooden side table or metal with a sleek finish

Corner Table for Living Room

Designed specifically to fit into unused corners, a corner table for living room optimizes space while adding utility. These tables are great for displaying vases, table lamps, or framed photos.

  • Great for: Square rooms or areas with awkward angles
  • Best material: Wood or glass to reflect light and expand space visually

Wooden Side Table

Timeless and sturdy, a wooden side table suits almost any decor theme—be it rustic, vintage, or modern. These tables often come with drawers or shelves for added storage.

  • Great for: Family rooms, traditional interiors, eco-friendly homes
  • Style tip: Pair with matching wooden furniture for a cohesive look

Tips for Choosing the Right Table

1. Measure Before You Buy

Whether you’re going for a side table or end table, make sure it complements the height of your sofa or chair. Ideally, the tabletop should be level with or slightly lower than the arm of the seating furniture.

2. Consider Material and Finish

If you're going for a wooden side table, ensure it matches or complements your existing furniture. Metal or marble is better for modern, minimalistic aesthetics.

3. Think About Storage

Some side tables for living room come with drawers, shelves, or even hidden compartments. If storage is a priority, choose a piece that offers more than just a flat surface.

4. Balance Form and Function

Your choice should reflect both your lifestyle and your décor goals. Do you need a space to hold magazines and remote controls? Or do you simply want to elevate the room’s style with a visually stunning piece?


Styling Ideas

- For a Minimalist Look:

Choose a sleek, geometric sofa side table in black or white. Keep the surface clear with only one or two decorative items.

- For a Cozy, Rustic Feel:

Opt for a wooden side table with a natural finish. Style it with a small lamp, a stack of books, and a potted plant.

- For a Maximalist Setup:

Mix and match different side tables for living room in varying materials and heights. Use them to display candles, sculptures, books, and framed photos for a layered, curated look.


Conclusion

Though they may look similar, side tables and end tables serve distinct roles in home décor and functionality. A well-chosen table—whether it’s a practical corner table for living room or an eye-catching wooden side table—can elevate your space in meaningful ways.

When selecting between the two, consider your layout, usage needs, and design preferences. Whether you need a sofa side table for everyday convenience or an accent side table for living room charm, there's a perfect piece waiting to complete your space.

Discussion (0)1
Log in or sign up to continue