/*******************************************************************************
 *  Copyright 2017-2018 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package cdac.medinfo.sdk.dcm30_04.dicommodel.modules;



import cdac.medinfo.sdk.dcm30_04.baselibs.BeamLimitingDeviceSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.DicomV3Factory;
import cdac.medinfo.sdk.dcm30_04.baselibs.ExposureSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ExposureSequenceItem;
import cdac.medinfo.sdk.dcm30_04.baselibs.FluenceMapSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.ReferencedRTPlanSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.Tag;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IItem;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITag;
import cdac.medinfo.sdk.dcm30_04.enums.EnumBitsAllocated;
import cdac.medinfo.sdk.dcm30_04.enums.EnumBitsStored;
import cdac.medinfo.sdk.dcm30_04.enums.EnumConversionType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumHighBit;
import cdac.medinfo.sdk.dcm30_04.enums.EnumImageType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPhotometricInterpretation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPixelIntensityRelationship;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPixelRepresentation;
import cdac.medinfo.sdk.dcm30_04.enums.EnumPrimaryDosimeterUnit;
import cdac.medinfo.sdk.dcm30_04.enums.EnumRTImagePlane;
import cdac.medinfo.sdk.dcm30_04.enums.EnumReportedValuesOrigin;
import cdac.medinfo.sdk.dcm30_04.enums.EnumSamplesPerPixel;

import cdac.medinfo.sdk.dcm30_04.exceptions.ConditionFailedException;
import cdac.medinfo.sdk.dcm30_04.exceptions.InvalidModuleException;
import cdac.medinfo.sdk.dcm30_04.exceptions.MandatoryMissingException;
import cdac.medinfo.sdk.dcm30_04.exceptions.ValidationException;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConfig;
import cdac.medinfo.sdk.dcm30_04.utils.DicomConstants;
import cdac.medinfo.sdk.dcm30_04.utils.DicomLogger;
import cdac.medinfo.sdk.dcm30_04.utils.ICollectionIterator;
import cdac.medinfo.sdk.dcm30_04.utils.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

// TODO: Auto-generated Javadoc
/**
 \* This module contains attributes that describe RT-specific characteristics of a projection image.
 * The image described by these attributes must be a radiotherapy image acquired or calculated
 * using a conical imaging geometry.

 */
public class RTImageModule extends Module  
{


	/**
	 * The obj single collection.
	 */
	public static ISingleCollection<ITag> objSingleCollection = null;


	/**
	 * Instantiates a new rT image module.
	 * 
	 * @param objIDataSet the obj i data set
	 */
	public RTImageModule(IDataSet objIDataSet)
	{
		super(objIDataSet);
	}

	static
	{
		objSingleCollection = new SingleCollection<ITag>();
		objSingleCollection.add(new Tag(0x0008,0x0008));
		objSingleCollection.add(new Tag(0x0008,0x0064));
		objSingleCollection.add(new Tag(0x0008,0x1070));
		objSingleCollection.add(new Tag(0x0028,0x0002));
		objSingleCollection.add(new Tag(0x0028,0x0004));
		objSingleCollection.add(new Tag(0x0028,0x0100));
		objSingleCollection.add(new Tag(0x0028,0x0101));
		objSingleCollection.add(new Tag(0x0028,0x0102));
		objSingleCollection.add(new Tag(0x0028,0x0103));
		objSingleCollection.add(new Tag(0x3002,0x0002));
		objSingleCollection.add(new Tag(0x3002,0x0003));
		objSingleCollection.add(new Tag(0x3002,0x0004));
		objSingleCollection.add(new Tag(0x3002,0x000A));
		objSingleCollection.add(new Tag(0x3002,0x000C));
		objSingleCollection.add(new Tag(0x3002,0x000D));
		objSingleCollection.add(new Tag(0x3002,0x000E));
		objSingleCollection.add(new Tag(0x3002,0x0010));
		objSingleCollection.add(new Tag(0x3002,0x0011));
		objSingleCollection.add(new Tag(0x3002,0x0012));
		objSingleCollection.add(new Tag(0x3002,0x0020));
		objSingleCollection.add(new Tag(0x3002,0x0022));
		objSingleCollection.add(new Tag(0x3002,0x0024));
		objSingleCollection.add(new Tag(0x3002,0x0026));
		objSingleCollection.add(new Tag(0x3002,0x0028));
		objSingleCollection.add(new Tag(0x3002,0x0029)); 	
		objSingleCollection.add(new Tag(0x3002,0x0030)); 	
		objSingleCollection.add(new Tag(0x3002,0x0040)); 	
		objSingleCollection.add(new Tag(0x300A,0x00B3));
		objSingleCollection.add(new Tag(0x300A,0x011E));
		objSingleCollection.add(new Tag(0x300A,0x0120));
		objSingleCollection.add(new Tag(0x300A,0x0122));
		objSingleCollection.add(new Tag(0x300A,0x0124));
		objSingleCollection.add(new Tag(0x300A,0x0125));
		objSingleCollection.add(new Tag(0x300A,0x0128));
		objSingleCollection.add(new Tag(0x300A,0x0129));
		objSingleCollection.add(new Tag(0x300A,0x012A));
		objSingleCollection.add(new Tag(0x300C,0x0002));
		objSingleCollection.add(new Tag(0x300C,0x0006));
		objSingleCollection.add(new Tag(0x300C,0x0008));
		objSingleCollection.add(new Tag(0x300C,0x0009));
		objSingleCollection.add(new Tag(0x300C,0x0022));
	}

	/**
	 * This method validates each Attribute in the Module according to the Type
	 * of the Attribute.Attributes are of 5 types.
	 * Type 1,Type 2 are Mandatory:
	 * Mandatory Attributes have to present in the Module.
	 * Type 1C,2C are Conditional:
	 * Conditional Attributes' presence depend on a condition.
	 * If the condition is satisfied the Attribute has to be present.
	 * Type 3 are Optional
	 * Optional Attributes can be added as and when required.
	 * 
	 * @return boolean - returns validation status as success or failure
	 * 
	 * @throws InvalidModuleException - If validation of Module fails
	 */
	public  boolean validateModule() throws InvalidModuleException
	{

		try
		{	
			if(isPresent(0x300A,0x012C))
				if(!isPresent(0x0018,0x5100))
					throw new ConditionFailedException("Element 0018,5100 is required if Isocenter Position (300A,012C) is present.");
			if(isPresent(0x0028,0x1040))
				if(!isPresent(0x0028,0x1041))
					throw new ConditionFailedException("Element 0028,1041 is required if Pixel Intensity Relationship (0028,1040) is present.");
			
			
			//Check for the Type 1,2 Mandatory Attributes.
			//Type 1 Elements
			if(!isPresent(0x0028,0x0002))
				throw new MandatoryMissingException("0028,0002 ");
			else if(!isPresent(0x0028,0x0004))
				throw new MandatoryMissingException("0028,0004");
			else if(!isPresent(0x0028,0x0100))
				throw new MandatoryMissingException("0028,0100");
			else if(!isPresent(0x0028,0x0101))
				throw new MandatoryMissingException("0028,0101");
			else if(!isPresent(0x0028,0x0102))
				throw new MandatoryMissingException("0028,0102");
			else if(!isPresent(0x0028,0x0103))
				throw new MandatoryMissingException("0028,0103");
			else if(!isPresent(0x3002,0x0002))
				throw new MandatoryMissingException("3002,0002");			
			else if(!isPresent(0x0008,0x1070))
				throw new MandatoryMissingException("0008,1070");
			else if(!isPresent(0x0008,0x0008))
				throw new MandatoryMissingException("0008,0008");		
			else if(!isPresent(0x0008,0x0064))
				throw new MandatoryMissingException("0008,0064");	
			else if(!isPresent(0x3002,0x000C))
				throw new MandatoryMissingException("3002,000C");
			//Type 2 Elements
			else if(!isPresent(0x3002,0x000E))
				throw new MandatoryMissingException("3002,000E");
			else if(!isPresent(0x3002,0x0011))
				throw new MandatoryMissingException("3002,0011");
			else if(!isPresent(0x3002,0x0012))
				throw new MandatoryMissingException("3002,0012");
			else if(!isPresent(0x3002,0x0020))
				throw new MandatoryMissingException("3002,0020");
			else if(!isPresent(0x300A,0x00B3))
				throw new MandatoryMissingException("300A,00B3");
			else if(!isPresent(0x3002,0x0022))
				throw new MandatoryMissingException("3002,0022");
			else if(!isPresent(0x3002,0x0026))
				throw new MandatoryMissingException("3002,0026");

			String[] arrStrImageType = getImageType();

			if(arrStrImageType != null )
			{
				if((arrStrImageType[2].equalsIgnoreCase(EnumImageType.Value3.SIMULATOR.getValue())||arrStrImageType[2].equalsIgnoreCase(EnumImageType.Value3.PORTAL.getValue())) && !(isPresent(0x3002,0x000A)))
					throw new ConditionFailedException("value of conditional Element ImageType(0008,0008) should be SIMULATOR or PORTAL, required for element Reported Values Origin(3002,000A)");

				if(arrStrImageType[2].equalsIgnoreCase(EnumImageType.Value3.FLUENCE.getValue()) && !(isPresent(0x3002,0x0040)))
					throw new ConditionFailedException("If value of Element ImageType(0008,0008) is FLUENCE ,then element Reported Values Origin(3002,000A) is required");
			}

			String strRTImagePlane = getRTImagePlane();

			if(strRTImagePlane.equalsIgnoreCase(EnumRTImagePlane.NON_NORMAL.getValue()) && !isPresent(0x3002, 0x0010))
				throw new ConditionFailedException("If value of Element RT Image Plane(3002,000C) is NON_NORMAL,then RT Image Orientation(3002,0010) is required");

			// Sequence Validation in Module.
			ICollectionIterator<IItem> objExposureSequenceIterator = getExposureSequence().iterator();
			ExposureSequenceItem objExposureSequenceItem = null;
			while(objExposureSequenceIterator.hasNext())
			{
				objExposureSequenceItem = (ExposureSequenceItem)objExposureSequenceIterator.next();
				ICollectionIterator<IItem> objBeamLimitingDeviceSequenceIterator = objExposureSequenceItem.getBeamLimitingDeviceSequence().iterator();
				BeamLimitingDeviceSequenceItem objBeamLimitingDeviceSequenceItem = null;
				while(objBeamLimitingDeviceSequenceIterator.hasNext())
				{
					objBeamLimitingDeviceSequenceItem = (BeamLimitingDeviceSequenceItem)objBeamLimitingDeviceSequenceIterator.next();
					if(!objBeamLimitingDeviceSequenceItem.contains(0x300A,0x011C))
						throw new ConditionFailedException("Element 300A,011C is mandatory in BeamLimitingDeviceSequence for this Module");
				}
			}
		}
		catch(MandatoryMissingException mme)
		{
			if(DicomConfig.createInstance().isLoggingOn())
				DicomLogger.getLogger().log(mme.getMessage());

			
				throw new InvalidModuleException(this.getClass().getSimpleName(),mme);

		}
		catch(ConditionFailedException cfe)
		{
			if(DicomConfig.createInstance().isLoggingOn())
				DicomLogger.getLogger().log(cfe.getMessage());

			
				throw new InvalidModuleException(this.getClass().getSimpleName(),cfe);

		}
		catch(ValidationException ve)
		{
			if(DicomConfig.createInstance().isLoggingOn())
				DicomLogger.getLogger().log(ve.getMessage());

			
				throw new InvalidModuleException(this.getClass().getSimpleName(),ve);

		}
		return true;
	}

	/**
	 * Sets Samples per Pixel (0028,0002) is the number of separate planes in the image. One, three, and
	 * four image planes are defined. For monochrome (gray scale) and palette color images, the number of planes is 1. For RGB and
	 * other three vector color models, the value of this attribute is 3. For four vector color models, the
	 * value of this attribute is 4.
	 * 
	 * @param enumSamplesPerPixel - enum value of samples per pixel in the image
	 */
	public void setSamplesPerPixel(EnumSamplesPerPixel enumSamplesPerPixel)
	{
		/*Accept Number of samples (planes) in this image in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x0002, DicomConstants.DCM_DT_US, enumSamplesPerPixel.getValue());
	}

	/**
	 * Retrieves the samples per pixel.
	 * 
	 * @return short - short value of Samples per pixel.
	 */
	public short getSamplesPerPixel()
	{
		Object objectValue = getValue(0x0028, 0x0002);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets the intended interpretation of the pixel data.
	 * 
	 * @param enumPhotometricInterpretation - Enum value of Photometric Interpretation.
	 */
	public void setPhotometricInterpretation(EnumPhotometricInterpretation enumPhotometricInterpretation)
	{
		/*Accept Specifies the intended interpretation of the pixel data in String format of type ST.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x0004, DicomConstants.DCM_DT_CS, enumPhotometricInterpretation.getValue());
	}

	/**
	 * Retrieves the photometric interpretation.
	 * 
	 * @return String - returns the photometric interpretation.
	 */
	public String getPhotometricInterpretation()
	{
		Object objectValue = getValue(0x0028, 0x0004);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Number of bits allocated for each pixel sample. Each sample shall have the same
	 * number of bits allocated.
	 * 
	 * @param enumBitsAllocated - enum value of number of bits allocated.
	 */
	public void setBitsAllocated(EnumBitsAllocated enumBitsAllocated)
	{
		/*Accept bits allocated for each pixel in this image in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x0100, DicomConstants.DCM_DT_US, enumBitsAllocated.getValue());
	}

	/**
	 * Retrieves the number of bits allocated.
	 * 
	 * @return short - short value of number of bits allocated.
	 */
	public short getBitsAllocated()
	{
		Object objectValue = getValue(0x0028, 0x0100);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets Number of bits stored for each pixel sample. Each sample shall have the same
	 * number of bits stored.
	 * 
	 * @param enumBitsStored - enum value of the number of bits stored.
	 */
	public void setBitsStored(EnumBitsStored enumBitsStored)
	{
		/*Accept bits stored for each pixel in this image in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x0101, DicomConstants.DCM_DT_US, enumBitsStored.getValue());
	}

	/**
	 * Retrieves the number of bits stored.
	 * 
	 * @return short - short value of the number of bits stored.
	 */
	public short getBitsStored()
	{
		Object objectValue = getValue(0x0028, 0x0101);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets Most significant bit for each pixel sample. Each sample shall have the same high bit.
	 * 
	 * @param enumHighBit - enum value of High Bit.
	 */
	public void setHighBit(EnumHighBit enumHighBit)
	{
		/*Accept Most significant bit for pixel in this image in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x0102, DicomConstants.DCM_DT_US, enumHighBit.getValue());
	}

	/**
	 * Retrieves High Bit.
	 * 
	 * @return short - short value of High Bit.
	 */
	public short getHighBit()
	{
		Object objectValue = getValue(0x0028, 0x0102);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets Data representation of the pixel samples.
	 * 
	 * @param enumPixelRepresentation - Enum value of Pixel Representation.
	 */
	public void setPixelRepresentation(EnumPixelRepresentation enumPixelRepresentation)
	{
		/*Accept Data representation of pixel in this image in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x0103, DicomConstants.DCM_DT_US, enumPixelRepresentation.getValue());
	}

	/**
	 * Retrieves the Pixel Representation.
	 * 
	 * @return String - returns the Pixel Representation.
	 */
	public short getPixelRepresentation()
	{
		Object objectValue = getValue(0x0028, 0x0103);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Sets PixelIntensityRelationship
	 * 
	 * @param enumPixelIntensityRelationship - Enum value of PixelIntensityRelationship
	 */
	public void setPixelIntensityRelationship(EnumPixelIntensityRelationship enumPixelIntensityRelationship)
	{
		/*Accept PixelIntensityRelationship in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x1040, DicomConstants.DCM_DT_CS, enumPixelIntensityRelationship.getValue());
	}

	/**
	 * Retrieves the PixelIntensityRelationship
	 * 
	 * @return String - returns the PixelIntensityRelationship
	 */
	public short getPixelIntensityRelationship()
	{
		Object objectValue = getValue(0x0028, 0x1040);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	
	/**
	 * Sets PixelIntensityRelationshipSign
	 * 
	 * @param enumPixelIntensityRelationshipSign - Enum value of PixelIntensityRelationshipSign
	 */
	public void setPixelIntensityRelationshipSign(EnumPixelIntensityRelationship enumPixelIntensityRelationshipSign)
	{
		/*Accept PixelIntensityRelationshipSign in short format of type US.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0028, 0x1041, DicomConstants.DCM_DT_SS, enumPixelIntensityRelationshipSign.getValue());
	}

	/**
	 * Retrieves the PixelIntensityRelationshipSign
	 * 
	 * @return String - returns the PixelIntensityRelationshipSign
	 */
	public short getPixelIntensityRelationshipSign()
	{
		Object objectValue = getValue(0x0028, 0x1041);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	
	/**
	 * Sets the user-defined label for RT Image.
	 * 
	 * @param strRTImageLabel - String value of RT Image Label.
	 */
	public void setRTImageLabel(String strRTImageLabel)
	{
		/* Accept RT Image Label in String format of type SH.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0002, DicomConstants.DCM_DT_SH, strRTImageLabel);
	}

	/**
	 * Retrieves User-defined label for RT Image.
	 * 
	 * @return String - String value of RT Image Label.
	 */
	public String getRTImageLabel()
	{
		Object objectValue = getValue(0x3002, 0x0002);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets user-defined name for RT Image.
	 * 
	 * @param strRTImageName - String value RT Image Name.
	 */
	public void setRTImageName(String strRTImageName)
	{
		/* Accept RT Image Name in String format of type LO.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0003, DicomConstants.DCM_DT_LO, strRTImageName);
	}

	/**
	 * Retrieves user-defined name for RT Image.
	 * 
	 * @return String - String value RT Image Name.
	 */
	public String getRTImageName()
	{
		Object objectValue = getValue(0x3002, 0x0003);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets user-defined description for RT Image.
	 * 
	 * @param strRTImageDescription - String value of RT Image Description.
	 */
	public void setRTImageDescription(String strRTImageDescription)
	{
		/* Accept RT Image Description in String format of type ST.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0004, DicomConstants.DCM_DT_ST, strRTImageDescription);
	}

	/**
	 * Retrieves user-defined description for RT Image.
	 * 
	 * @return String - String value of RT Image Description.
	 */
	public String getRTImageDescription()
	{
		Object objectValue = getValue(0x3002, 0x0004);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}


	/**
	 * Sets image identification characteristics.
	 * 
	 * @param arrStrImageType - String array of image identification characteristics.
	 */	
	public void setImageType(String[] arrStrImageType)
	{
		/*Accept Image identification characteristics in String Array format of type CS.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x0008, 0x0008, DicomConstants.DCM_DT_CS, arrStrImageType);
	}

	/**
	 * Return image identification characteristics.
	 * 
	 * @return the image type
	 */
	public String[] getImageType()
	{
		 Object objValue = getValue(0x0008,0x0008);
   if(objValue!=null)
      return (String[])objValue;
   return null;

	}

	/**
	 * Sets describes the kind of image conversion.
	 * Defined Terms:
	 * 1) DV = Digitized Video
	 * 2) DI = Digital Interface
	 * 3) DF = Digitized Film
	 * 4) WSD = Workstation
	 * 
	 * @param enumConversionType - Enum value of Conversion Type.
	 */
	public void setConversionType(EnumConversionType enumConversionType)
	{
		/* Accept Conversion Type in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0008, 0x0064, DicomConstants.DCM_DT_CS, enumConversionType.getValue());
	}

	/**
	 * Retrieves describes the kind of image conversion.
	 * 
	 * @return String - String value of Conversion Type.
	 */
	public String getConversionType()
	{
		Object objectValue = getValue(0x0008, 0x0064);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets the origin of the parameter values reported in the image. Required if
	 * Value 3 of Image Type (0008,0008) is SIMULATOR or PORTAL.
	 * Enumerated Values:
	 * 1) OPERATOR = manually entered by operator.
	 * 2) PLAN = planned parameter values.
	 * 3) ACTUAL = electronically recorded.
	 * 
	 * @param enumReportedValuesOrigin - enum value of Reported Values Origin.
	 */
	public void setReportedValuesOrigin(EnumReportedValuesOrigin enumReportedValuesOrigin)
	{
		/* Accept Reported Values Origin in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x000A, DicomConstants.DCM_DT_CS, enumReportedValuesOrigin.getValue());
	}

	/**
	 * Retrieves the origin of the parameter values reported in the image.
	 * 
	 * @return String - String value of Reported Values Origin.
	 */
	public String getReportedValuesOrigin()
	{
		 Object objValue = getValue(0x3002,0x000A);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets whether or not image plane is normal to beam axis.
	 * Enumerated Values:
	 * 1) NORMAL = image plane normal to beam axis.
	 * 2) NON_NORMAL = image plane non-normal to beam axis.
	 * 
	 * @param enumRTImagePlane - Enum value of RT Image Plane.
	 */
	public void setRTImagePlane(EnumRTImagePlane enumRTImagePlane)
	{
		/* Accept RT Image Plane in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x000C, DicomConstants.DCM_DT_CS, enumRTImagePlane.getValue());
	}

	/**
	 * Retrieves whether or not image plane is normal to beam axis.
	 * 
	 * @return String - String value of RT Image Plane.
	 */
	public String getRTImagePlane()
	{
		 Object objValue = getValue(0x3002,0x000C);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets position in (x,y,z) coordinates of origin of IEC X-RAY IMAGE RECEPTOR System in
	 * the IEC GANTRY coordinate system (mm).
	 * 
	 * @param arrStrXRayImageReceptorTranslation - String value of X-Ray Image Receptor Translation.
	 */	
	public void setXRayImageReceptorTranslation(String[] arrStrXRayImageReceptorTranslation)
	{
		/* Accept the X-Ray Image Receptor Translation value in String Array format of type DS.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x3002, 0x000D, DicomConstants.DCM_DT_DS, arrStrXRayImageReceptorTranslation);
	}

	/**
	 * Retrieves position in (x,y,z) coordinates of origin of IEC X-RAY IMAGE RECEPTOR System in
	 * the IEC GANTRY coordinate system (mm).
	 * 
	 * @return  String[] - String value of String value of X-Ray Image Receptor Translation.
	 */
	public String[] getXRayImageReceptorTranslation()
	{
		 Object objValue = getValue(0x3002,0x000D);
   if(objValue!=null)
      return (String[])objValue;
   return null;

	}

	/**
	 * Sets X-Ray Image Receptor Angle i.e. orientation of IEC X-RAY IMAGE
	 * RECEPTOR coordinate system with respect to IEC GANTRY coordinate system (degrees).
	 * 
	 * @param strXRayImageReceptorAngle - String value of X-Ray Image Receptor Angle.
	 */
	public void setXRayImageReceptorAngle(String strXRayImageReceptorAngle)
	{
		/* Accept X-Ray Image Receptor Angle in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x000E, DicomConstants.DCM_DT_DS, strXRayImageReceptorAngle);
	}

	/**
	 * Retrieves X-Ray Image Receptor Angle i.e. orientation of IEC X-RAY IMAGE
	 * RECEPTOR coordinate system with respect to IEC GANTRY coordinate system (degrees).
	 * 
	 * @return String - String value of X-Ray Image Receptor Angle.
	 */
	public String getXRayImageReceptorAngle()
	{
		 Object objValue = getValue(0x3002,0x000E);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets the direction cosines of the first row and the first column with respect to the IEC XRAY
	 * IMAGE RECEPTOR coordinate system. Required if RT Image Plane (3002,000C) is NON_NORMAL.
	 * 
	 * @param arrStrXRayImageOrientation - String array of RT Image Orientation.
	 */	
	public void setRTImageOrientation(String[] arrStrXRayImageOrientation)
	{
		/* Accept the RT Image Orientation value in String Array format of type DS.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x3002, 0x0010, DicomConstants.DCM_DT_DS, arrStrXRayImageOrientation);
	}

	/**
	 * The direction cosines of the first row and the first column with respect to the IEC XRAY IMAGE RECEPTOR coordinate system.
	 * 
	 * @return  String[] - String value of RT Image Orientation.
	 */
	public String[] getRTImageOrientation()
	{
		 Object objValue = getValue(0x3002,0x0010);
   if(objValue!=null)
      return (String[])objValue;
   return null;

	}

	/**
	 * Sets physical distance (in mm) between the center of each image pixel, specified by a
	 * numeric pair - adjacent row spacing (delimiter) adjacent column spacing.
	 * 
	 * @param arrStrImagePlanePixelSpacing - String array of Image Plane Pixel Spacing.
	 */	
	public void setImagePlanePixelSpacing(String[] arrStrImagePlanePixelSpacing)
	{
		/* Accept the Image Plane Pixel Spacing value in String Array format of type DS.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x3002, 0x0011, DicomConstants.DCM_DT_DS, arrStrImagePlanePixelSpacing);
	}

	/**
	 * Retrieves physical distance (in mm) between the center of each image pixel, specified by a
	 * numeric pair - adjacent row spacing (delimiter) adjacent column spacing.
	 * 
	 * @return  String[] - String array of Image Plane Pixel Spacing.
	 */
	public String[] getImagePlanePixelSpacing()
	{
		 Object objValue = getValue(0x3002,0x0011);
   if(objValue!=null)
      return (String[])objValue;
   return null;

	}

	/**
	 * Sets the x and y coordinates (in mm) of the upper left hand corner of the image, in the
	 * IEC X-RAY IMAGE RECEPTOR coordinate system. This is the center of the first pixel transmitted.
	 * 
	 * @param arrStrRTImagePosition - String array of RT Image Position.
	 */	
	public void setRTImagePosition(String[] arrStrRTImagePosition)
	{
		/* Accept the RT Image Position value in String Array format of type DS.
		 * Read the Transfer Syntax and check to create ImplicitDE or ExplicitDE .
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x3002, 0x0012, DicomConstants.DCM_DT_DS, arrStrRTImagePosition);
	}

	/**
	 * Retrieves the x and y coordinates (in mm) of the upper left hand corner of the image, in the
	 * IEC X-RAY IMAGE RECEPTOR coordinate system.
	 * 
	 * @return  String[] - String array of RT Image Position.
	 */
	public String[] getRTImagePosition()
	{
		 Object objValue = getValue(0x3002,0x0012);
   if(objValue!=null)
      return (String[])objValue;
   return null;

	}

	/**
	 * Sets user-defined name identifying radiation machine used in acquiring or computing
	 * image (i.e. name of conventional simulator, electron accelerator, X-ray device, or
	 * machine modeled when calculating DRR).
	 * 
	 * @param strRadiationMachineName - String value of Radiation Machine Name.
	 */
	public void setRadiationMachineName(String strRadiationMachineName)
	{
		/* Accept Radiation Machine Name in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0020, DicomConstants.DCM_DT_SH, strRadiationMachineName);
	}

	/**
	 * Retrieves user-defined name identifying radiation machine used in acquiring or computing
	 * image (i.e. name of conventional simulator, electron accelerator, X-ray device, or
	 * machine modeled when calculating DRR).
	 * 
	 * @return String - String value of Radiation Machine Name.
	 */
	public String getRadiationMachineName()
	{
		Object objectValue = getValue(0x3002, 0x0020);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets measurement unit of machine dosimeter.
	 * Enumerated Values:
	 * 1) MU = Monitor Unit
	 * 2) MINUTE = minute
	 * 
	 * @param enumPrimaryDosimeterUnit - enum value of Primary Dosimeter Unit.
	 */
	public void setPrimaryDosimeterUnit(EnumPrimaryDosimeterUnit enumPrimaryDosimeterUnit)
	{
		/* Accept Primary Dosimeter Unit in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300A, 0x00B3, DicomConstants.DCM_DT_CS, enumPrimaryDosimeterUnit.getValue());
	}

	/**
	 * Retrieves measurement unit of machine dosimeter.
	 * 
	 * @return String - String value of Primary Dosimeter Unit.
	 */
	public String getPrimaryDosimeterUnit()
	{
		 Object objValue = getValue(0x300A,0x00B3);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets radiation source to Gantry rotation axis distance of radiation machine used in
	 * acquiring or computing image (mm).
	 * 
	 * @param strRadiationMachineSAD - String value of Radiation Machine SAD.
	 */
	public void setRadiationMachineSAD(String strRadiationMachineSAD)
	{
		/* Accept Radiation Machine SAD in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0022, DicomConstants.DCM_DT_DS, strRadiationMachineSAD);
	}

	/**
	 * Retrieves radiation source to Gantry rotation axis distance of radiation machine used in
	 * acquiring or computing image (mm).
	 * 
	 * @return the radiation machine sad
	 */
	public String getRadiationMachineSAD()
	{
		Object objectValue = getValue(0x3002, 0x0022);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets source to patient surface distance (in mm) of radiation machine used in acquiring or
	 * computing image.
	 * 
	 * @param strRadiationMachineSSD - String value of Radiation Machine SSD.
	 */
	public void setRadiationMachineSSD(String strRadiationMachineSSD)
	{
		/* Accept Radiation Machine SSD in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0024, DicomConstants.DCM_DT_DS, strRadiationMachineSSD);
	}

	/**
	 * Retrieves source to patient surface distance (in mm) of radiation machine used in acquiring or
	 * computing image.
	 * 
	 * @return the radiation machine ssd
	 */
	public String getRadiationMachineSSD()
	{
		Object objectValue = getValue(0x3002, 0x0024);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets distance from radiation machine source to image plane (in mm) along radiation beam axis.
	 * 
	 * @param strRTImageSID - String value of RT Image SID.
	 */
	public void setRTImageSID(String strRTImageSID)
	{
		/* Accept RT Image SID in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0026, DicomConstants.DCM_DT_DS, strRTImageSID);
	}

	/**
	 * Retrieves distance from radiation machine source to image plane (in mm) along radiation beam axis.
	 * 
	 * @return the RT image sid
	 */
	public String getRTImageSID()
	{
		Object objectValue = getValue(0x3002, 0x0026);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets source to reference object distance (in mm), as used for magnification calculation
	 * of RADIOGRAPH and SIMULATOR images.
	 * 
	 * @param strSourceToReferenceObjectDistance - String value of Source to Reference Object Distance.
	 */
	public void setSourceToReferenceObjectDistance(String strSourceToReferenceObjectDistance)
	{
		/* Accept Source to Reference Object Distance in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0028, DicomConstants.DCM_DT_DS, strSourceToReferenceObjectDistance);
	}

	/**
	 * Retrieves source to reference object distance (in mm), as used for magnification calculation
	 * of RADIOGRAPH and SIMULATOR images.
	 * 
	 * @return the source to reference object distance
	 */
	public String getSourceToReferenceObjectDistance()
	{
		Object objectValue = getValue(0x3002, 0x0028);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Returns provides the pre-initialized object of Referenced RT Plan Sequence.
	 * If the module contains the sequence object it returns the same otherwise it creates the
	 * sequence adds to the module with proper initialization and then returns the object of sequence.
	 * 
	 * @return ReferencedRTPlanSequence - object of Referenced RT Plan Sequence.
	 */
	public ReferencedRTPlanSequence getReferencedRTPlanSequence()
	{
		ReferencedRTPlanSequence objReferencedRTPlanSequence = (ReferencedRTPlanSequence)getDicomValue(0x300C,0002);
		if(objReferencedRTPlanSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objReferencedRTPlanSequence = (ReferencedRTPlanSequence)objDicomV3Factory.createSequence(0x300C,0002, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x300C,0002, DicomConstants.DCM_DT_SQ, objReferencedRTPlanSequence.getValue());
		}
		return objReferencedRTPlanSequence;
	}

	/**
	 * Sets uniquely identifies the corresponding Nsegment treatment beam specified by
	 * Beam Number (300A,00C0) within Beam Sequence in RT Beams Module within the
	 * RT Plan referenced in Referenced RT Plan Sequence (300C,0002).
	 * 
	 * @param strReferencedBeamNumber - String value of Referenced Beam Number.
	 */
	public void setReferencedBeamNumber(String strReferencedBeamNumber)
	{
		/* Accept Referenced Beam Number in String format of type IS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300C, 0x0006, DicomConstants.DCM_DT_IS, strReferencedBeamNumber);
	}

	/**
	 * Retrieves uniquely identifies the corresponding Nsegment treatment beam specified by
	 * Beam Number (300A,00C0) within Beam Sequence in RT Beams Module within the
	 * RT Plan referenced in Referenced RT Plan Sequence (300C,0002).
	 * 
	 * @return the referenced beam number
	 */
	public String getReferencedBeamNumber()
	{
		 Object objValue = getValue(0x300C,0x0006);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}


	/**
	 * Sets identifier of Fraction Group within RT Plan referenced in Referenced RT Plan
	 * Sequence (300C,0002).
	 * 
	 * @param strReferencedFractionGroupNumber - String value of Referenced Fraction Group Number.
	 */
	public void setReferencedFractionGroupNumber(String strReferencedFractionGroupNumber)
	{
		/* Accept Referenced Fraction Group Number in String format of type IS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300C, 0x0022, DicomConstants.DCM_DT_IS, strReferencedFractionGroupNumber);
	}

	/**
	 * Retrieves identifier of Fraction Group within RT Plan referenced in Referenced RT Plan
	 * Sequence (300C,0002).
	 * 
	 * @return the referenced fraction group number
	 */
	public String getReferencedFractionGroupNumber()
	{
		 Object objValue = getValue(0x300C,0x0022);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets Fraction Number of fraction during which image was acquired, within Fraction Group
	 * referenced by Referenced Fraction Group Number (300C,0022) within RT Plan
	 * referenced in Referenced RT Plan Sequence (300C,0002).
	 * 
	 * @param strFractionNumber - String value of Fraction Number.
	 */
	public void setFractionNumber(String strFractionNumber)
	{
		/* Accept Fraction Number in String format of type IS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x3002, 0x0029, DicomConstants.DCM_DT_IS, strFractionNumber);
	}

	/**
	 * Retrieves Fraction Number of fraction during which image was acquired, within Fraction Group
	 * referenced by Referenced Fraction Group Number (300C,0022) within RT Plan
	 * referenced in Referenced RT Plan Sequence (300C,0002).
	 * 
	 * @return the fraction number
	 */
	public String getFractionNumber()
	{
		Object objectValue = getValue(0x3002, 0x0029);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Cumulative Meterset Weight within Beam referenced by Referenced Beam Number
	 * (300C,0006) at which image acquisition starts.
	 * 
	 * @param strStartCumulativeMetersetWeight - String value of Start Cumulative Meterset Weight.
	 */
	public void setStartCumulativeMetersetWeight(String strStartCumulativeMetersetWeight)
	{
		/* Accept Start Cumulative Meterset Weight in String format of type IS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300C, 0x0008, DicomConstants.DCM_DT_DS, strStartCumulativeMetersetWeight);
	}

	/**
	 * Retrieves Cumulative Meterset Weight within Beam referenced by Referenced Beam Number
	 * (300C,0006) at which image acquisition starts.
	 * 
	 * @return the start cumulative meterset weight
	 */
	public String getStartCumulativeMetersetWeight()
	{
		 Object objValue = getValue(0x300C,0x0008);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets Cumulative Meterset Weight within Beam referenced by Referenced Beam Number
	 * (300C,0006) at which image acquisition ends.
	 * 
	 * @param strEndCumulativeMetersetWeight - String value of End Cumulative Meterset Weight.
	 */
	public void setEndCumulativeMetersetWeight(String strEndCumulativeMetersetWeight)
	{
		/* Accept Start Cumulative Meterset Weight in String format of type IS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300C, 0x0009, DicomConstants.DCM_DT_DS, strEndCumulativeMetersetWeight);
	}

	/**
	 * Retrieves Cumulative Meterset Weight within Beam referenced by Referenced Beam Number
	 * (300C,0006) at which image acquisition ends.
	 * 
	 * @return the end cumulative meterset weight
	 */
	public String getEndCumulativeMetersetWeight()
	{
		 Object objValue = getValue(0x300C,0x0009);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Returns provides the pre-initialized object of {@link ExposureSequence}.
	 * If the module contains the sequence object it returns the same otherwise it creates the
	 * sequence adds to the module with proper initialization and then returns the object of sequence.
	 * 
	 * @return ExposureSequence - object of Exposure Sequence.
	 */
	public ExposureSequence getExposureSequence()
	{
		ExposureSequence objExposureSequence = (ExposureSequence)getDicomValue(0x3002, 0x0030);
		if(objExposureSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objExposureSequence = (ExposureSequence)objDicomV3Factory.createSequence(0x3002, 0x0030, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x3002, 0x0030, DicomConstants.DCM_DT_SQ, objExposureSequence.getValue());
		}
		return objExposureSequence;
	}

	/**
	 * Returns provides the pre-initialized object of {@link FluenceMapSequence}.
	 * If the module contains the sequence object it returns the same otherwise it creates the
	 * sequence adds to the module with proper initialization and then returns the object of sequence.
	 * 
	 * @return - object of Fluence Map Sequence.
	 */
	public FluenceMapSequence getFluenceMapSequence()
	{
		FluenceMapSequence objFluenceMapSequence = (FluenceMapSequence)getDicomValue(0x3002, 0x0040);
		if(objFluenceMapSequence == null)
		{
			/*
			 * If the sequence object is not present in the DataSet, a new sequence object is created and
			 * the TransferSyntax and DictionaryReader is set into it as it is set in the Module. This ensures that 
			 * the DataElements getting added in the DataSet follow the same TransferSyntax and use the same
			 * DictionaryReader object as that of the module.
			 */
			DicomV3Factory objDicomV3Factory = DicomV3Factory.createInstance();
			objFluenceMapSequence = (FluenceMapSequence)objDicomV3Factory.createSequence(0x3002, 0x0040, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x3002, 0x0040, DicomConstants.DCM_DT_SQ, objFluenceMapSequence.getValue());
		}
		return objFluenceMapSequence;
	}

	/**
	 * Sets treatment machine gantry angle, i.e. orientation of IEC GANTRY coordinate
	 * system with respect to IEC FIXED REFERENCE coordinate system (degrees).
	 * 
	 * @param strGantryAngle - String value of Gantry Angle.
	 */
	public void setGantryAngle(String strGantryAngle)
	{
		/* Accept Gantry Angle in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x011E, DicomConstants.DCM_DT_DS, strGantryAngle);
	}

	/**
	 * Return treatment machine gantry angle, i.e. orientation of IEC GANTRY coordinate
	 * system with respect to IEC FIXED REFERENCE coordinate system (degrees).
	 * 
	 * @return String - String value of Gantry Angle.
	 */
	public String getGantryAngle()
	{
		 Object objValue = getValue(0x300A,0x011E);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets the Gantry Pitch Angle. i.e., the rotation of the IEC GANTRY coordinatesystem about the X-axis of the IEC GANTRY coordinate system(degrees).
	 * @param fGantryPitchAngle Float value of Gantry Pitch Angle. i.e., the rotation of the IEC GANTRY coordinatesystem about the X-axis of the IEC GANTRY coordinate system(degrees).
	 */
	public void setGantryPitchAngle( float fGantryPitchAngle)
	{
		/*
		 * Accept the Gantry Pitch Angle in String format of type FL.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300A, 0x014A, DicomConstants.DCM_DT_FL,fGantryPitchAngle);
	}
	/**
	 * Retrieves the Gantry Pitch Angle. i.e., the rotation of the IEC GANTRY coordinatesystem about the X-axis of the IEC GANTRY coordinate system(degrees).
	 * @return float - Float value of the Gantry Pitch Angle
	 */
	public float getGantryPitchAngle()
	{
		Object objValue = getValue(0x0070,0x014A);
		if(objValue != null)
			return Float.parseFloat(objValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}
	/**
	 * Sets treatment machine beam limiting device (collimator) angle, i.e. orientation of IEC
	 * BEAM LIMITING DEVICE coordinate system with respect to IEC GANTRY coordinate system (degrees).
	 * 
	 * @param strBeamLimitingDeviceAngle - String value of Beam Limiting Device Angle.
	 */
	public void setBeamLimitingDeviceAngle(String strBeamLimitingDeviceAngle)
	{
		/* Accept Beam Limiting Device Angle in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x0120, DicomConstants.DCM_DT_DS, strBeamLimitingDeviceAngle);
	}

	/**
	 * Return treatment machine beam limiting device (collimator) angle, i.e. orientation of IEC
	 * BEAM LIMITING DEVICE coordinate system with respect to IEC GANTRY coordinate system (degrees).
	 * 
	 * @return String - String value of Beam Limiting Device Angle.
	 */
	public String getBeamLimitingDeviceAngle()
	{
		 Object objValue = getValue(0x300A,0x0120);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets patient support angle, i.e. orientation of IEC PATIENT SUPPORT coordinate
	 * system with respect to IEC FIXED REFERENCE coordinate system (degrees).
	 * 
	 * @param strPatientSupportAngle - String value of Patient Support Angle.
	 */
	public void setPatientSupportAngle(String strPatientSupportAngle)
	{
		/* Accept Patient Support Angle in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x0122, DicomConstants.DCM_DT_DS, strPatientSupportAngle);
	}

	/**
	 * Return Patient Support angle, i.e. orientation of IEC PATIENT SUPPORT coordinate
	 * system with respect to IEC FIXED REFERENCE coordinate system (degrees).
	 * 
	 * @return String - String value of Patient Support Angle.
	 */
	public String getPatientSupportAngle()
	{
		 Object objValue = getValue(0x300A,0x0122);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets distance (positive) from the IEC PATIENT SUPPORT vertical axis to the IEC TABLE
	 * TOP ECCENTRIC vertical axis (mm).
	 * 
	 * @param strTableTopEccentricAxisDistance - String value of Table Top Eccentric Axis Distance.
	 */
	public void setTableTopEccentricAxisDistance(String strTableTopEccentricAxisDistance)
	{
		/* Accept Table Top Eccentric Axis Distance in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x0124, DicomConstants.DCM_DT_DS, strTableTopEccentricAxisDistance);
	}

	/**
	 * Return distance (positive) from the IEC PATIENT SUPPORT vertical axis to the IEC TABLE
	 * TOP ECCENTRIC vertical axis (mm).
	 * 
	 * @return String -String value of Table Top Eccentric Axis Distance.
	 */
	public String getTableTopEccentricAxisDistance()
	{
		 Object objValue = getValue(0x300A,0x0124);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets distance (positive) from the IEC PATIENT SUPPORT vertical axis to the IEC TABLE
	 * TOP ECCENTRIC vertical axis (mm).
	 * 
	 * @param strTableTopEccentricAngle the str table top eccentric angle
	 */
	public void setTableTopEccentricAngle(String strTableTopEccentricAngle)
	{
		/* Accept Table Top Eccentric Angle in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x0125, DicomConstants.DCM_DT_DS, strTableTopEccentricAngle);
	}

	/**
	 * Return distance (positive) from the IEC PATIENT SUPPORT vertical axis to the IEC TABLE
	 * TOP ECCENTRIC vertical axis (mm).
	 * 
	 * @return String -String value of Table Top Eccentric Axis Angle.
	 */
	public String getTableTopEccentricAngle()
	{
		 Object objValue = getValue(0x300A,0x0125);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets Table Top Vertical position in IEC TABLE TOP coordinate system (mm).
	 * 
	 * @param strTableTopVerticalPosition - String value of Table Top Vertical Position.
	 */
	public void setTableTopVerticalPosition(String strTableTopVerticalPosition)
	{
		/* Accept Table Top Vertical Position in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x0128, DicomConstants.DCM_DT_DS, strTableTopVerticalPosition);
	}

	/**
	 * Return Table Top Vertical position in IEC TABLE TOP coordinate system (mm).
	 * 
	 * @return String - String value of Table Top Vertical Position.
	 */
	public String getTableTopVerticalPosition()
	{
		 Object objValue = getValue(0x300A,0x0128);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets Table Top Longitudinal position in IEC TABLE TOP coordinate system (mm).
	 * 
	 * @param strTableTopLongitudinalPosition - String value of Table Top Longitudinal Position.
	 */
	public void setTableTopLongitudinalPosition(String strTableTopLongitudinalPosition)
	{
		/* Accept Table Top Longitudinal Position in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x0129, DicomConstants.DCM_DT_DS, strTableTopLongitudinalPosition);
	}

	/**
	 * Return Table Top Longitudinal position in IEC TABLE TOP coordinate system (mm).
	 * 
	 * @return the table top longitudinal position
	 */
	public String getTableTopLongitudinalPosition()
	{
		 Object objValue = getValue(0x300A,0x0129);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}

	/**
	 * Sets Table Top Lateral position in IEC TABLE TOP coordinate system (mm).
	 * 
	 * @param strTableTopLateralPosition - String value of Table Top Lateral Position.
	 */
	public void setTableTopLateralPosition(String strTableTopLateralPosition)
	{
		/* Accept Table Top Lateral Position in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create.
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Hash Map
		 */
		addDataElement(0x300A, 0x012A, DicomConstants.DCM_DT_DS, strTableTopLateralPosition);
	}

	/**
	 * Return Table Top Lateral position in IEC TABLE TOP coordinate system (mm).
	 * 
	 * @return the table top lateral position
	 */
	public String getTableTopLateralPosition()
	{
		 Object objValue = getValue(0x300A,0x012A);
   if(objValue!=null)
      return objValue.toString();
   return null;

	}
	
	/**
	 * Sets Isocenter Position
	 * @param strIsocenterPosition String value of Isocenter Position
	 */
	public void setIsocenterPosition(String[] strIsocenterPosition)
	{
		/*Accept the SliceThickness in String format of type DS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x300A, 0x012C, DicomConstants.DCM_DT_DS,strIsocenterPosition);
	}
	/**
	 * Retrieves Isocenter Position
	 * @return String - value of Isocenter Position
	 */
	public String[] getIsocenterPosition()
	{
		Object objValue = getValue(0x300A,0x012C);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}
	/**
	 * Sets Patient Position
	 * @param strPatientPosition Specifies type of the value Patient Position
	 */
	public void setPatientPosition(String strPatientPosition)
	{
		/*Accept the Value Type in String format of type CS.
		 * Read the Transfer Syntax and check if ImplicitDE or ExplicitDE to create
		 * Set the iGroupNumber and iElementNumber to ImplicitDE object 
		 * Set the iVRType
		 * Set length from the element
		 * Add this element to the Data Set
		 */
		addDataElement(0x0018, 0x5100, DicomConstants.DCM_DT_CS,strPatientPosition);
	}
	/**
	 * Retrieves type of the value Patient Position
	 * @return String - Type of the value Patient Position
	 */
	public String getPatientPosition()
	{
		Object objValue = getValue(0x0018, 0x5100);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	/**
	 * This method returns the vector of keys representing the DataElements
	 * that belong to this module.
	 * 
	 * @return vector of Tags - returns the vector containing the collection of tags
	 */
	public ISingleCollection<ITag> getVectorOfKeys()
	{
		return objSingleCollection;
	}
}
