/*******************************************************************************
 *  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.DicomV3Factory;
import cdac.medinfo.sdk.dcm30_04.baselibs.EnergyWindowRangeSequence;
import cdac.medinfo.sdk.dcm30_04.baselibs.Tag;
import cdac.medinfo.sdk.dcm30_04.commoninterface.IDataSet;
import cdac.medinfo.sdk.dcm30_04.commoninterface.ITag;
import cdac.medinfo.sdk.dcm30_04.enums.EnumAcquisitionTerminationCondition;
import cdac.medinfo.sdk.dcm30_04.enums.EnumCollimatorType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumCorrectedImage;
import cdac.medinfo.sdk.dcm30_04.enums.EnumCountsSource;
import cdac.medinfo.sdk.dcm30_04.enums.EnumDecayCorrection;
import cdac.medinfo.sdk.dcm30_04.enums.EnumFieldOfViewShape;
import cdac.medinfo.sdk.dcm30_04.enums.EnumRandomsCorrectionMethod;
import cdac.medinfo.sdk.dcm30_04.enums.EnumReprojectionMethod;
import cdac.medinfo.sdk.dcm30_04.enums.EnumSeriesType;
import cdac.medinfo.sdk.dcm30_04.enums.EnumTypeOfDetectorMotion;
import cdac.medinfo.sdk.dcm30_04.enums.EnumUnits;

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.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.ISingleCollection;
import cdac.medinfo.sdk.dcm30_04.utils.SingleCollection;

// TODO: Auto-generated Javadoc
/**
 \* This module describes the attributes in PET Series Module.
 */
public class PETSeriesModule extends Module  
{


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


	/**
	 * Creates PET Series Module with default initialization.
	 * 
	 * @param objIDataSet the obj i data set
	 */
	public PETSeriesModule(IDataSet objIDataSet)
	{
		super(objIDataSet);
	}

	static
	{
		objSingleCollection = new SingleCollection<ITag>();
		objSingleCollection.add(new Tag(0x0008,0x0021));
		objSingleCollection.add(new Tag(0x0008,0x0031));
		objSingleCollection.add(new Tag(0x0018,0x1100));
		objSingleCollection.add(new Tag(0x0018,0x1210));
		objSingleCollection.add(new Tag(0x0018,0x0073));
		objSingleCollection.add(new Tag(0x0018,0x0074));
		objSingleCollection.add(new Tag(0x0018,0x0071));
		objSingleCollection.add(new Tag(0x0018,0x0075));
		objSingleCollection.add(new Tag(0x0018,0x1147));
		objSingleCollection.add(new Tag(0x0018,0x1149));
		objSingleCollection.add(new Tag(0x0018,0x1120));
		objSingleCollection.add(new Tag(0x0018,0x1121));
		objSingleCollection.add(new Tag(0x0018,0x1181));
		objSingleCollection.add(new Tag(0x0018,0x1180));
		objSingleCollection.add(new Tag(0x0028,0x0051));
		objSingleCollection.add(new Tag(0x0054,0x1001));
		objSingleCollection.add(new Tag(0x0054,0x1002));
		objSingleCollection.add(new Tag(0x0054,0x1000));
		objSingleCollection.add(new Tag(0x0054,0x1004));
		objSingleCollection.add(new Tag(0x0054,0x0061));
		objSingleCollection.add(new Tag(0x0054,0x0071));
		objSingleCollection.add(new Tag(0x0054,0x0101));
		objSingleCollection.add(new Tag(0x0054,0x0081));
		objSingleCollection.add(new Tag(0x0054,0x1100));
		objSingleCollection.add(new Tag(0x0054,0x1101));
		objSingleCollection.add(new Tag(0x0054,0x1105));
		objSingleCollection.add(new Tag(0x0054,0x1102));
		objSingleCollection.add(new Tag(0x0054,0x1103));
		objSingleCollection.add(new Tag(0x0054,0x1104));
		objSingleCollection.add(new Tag(0x0054,0x0202));
		objSingleCollection.add(new Tag(0x0054,0x1200));
		objSingleCollection.add(new Tag(0x0054,0x1201));
		objSingleCollection.add(new Tag(0x0054,0x1202));
		objSingleCollection.add(new Tag(0x0054,0x1203));
		objSingleCollection.add(new Tag(0x0054,0x1210));
		objSingleCollection.add(new Tag(0x0054,0x0013));
		objSingleCollection.add(new Tag(0x0054,0x1220));
	}

	/**
	 * 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
		{
			/*
			 * Validation Rules for Mandatory Elements
			 */
			if(!isPresent(0x0008,0x0021))
				throw new MandatoryMissingException("0008,0021");
			if(!isPresent(0x0008,0x0031))
				throw new MandatoryMissingException("0008,0031");
			if(!isPresent(0x0054,0x1001))
				throw new MandatoryMissingException("0054,1001");
			if(!isPresent(0x0054,0x1002))
				throw new MandatoryMissingException("0054,1002");
			if(!isPresent(0x0054,0x1000))
				throw new MandatoryMissingException("0054,1000");
			if(!isPresent(0x0054,0x0081))
				throw new MandatoryMissingException("0054,0081");
			if(!isPresent(0x0028,0x0051))
				throw new MandatoryMissingException("0028,0051");
			if(!isPresent(0x0054,0x1102))
				throw new MandatoryMissingException("0054,1102");
			if(!isPresent(0x0018,0x1181))
				throw new MandatoryMissingException("0018,1181");
			String[] strSeriesType = getSeriesType();
			if(strSeriesType[0] != null)
			{
				if(strSeriesType[0].equalsIgnoreCase(EnumSeriesType.Value1.DYNAMIC.getValue()) && !isPresent(0x0054,0x0101))
					throw new ConditionFailedException("0054,0101 is required if Series Type (0054,1000), Value 1 is DYNAMIC.");
				if(strSeriesType[0].equalsIgnoreCase(EnumSeriesType.Value1.GATED.getValue()))
				{
					if(!isPresent(0x0054,0x0071))
						throw new ConditionFailedException("0054,0071 is required if Series Type (0054,1000), Value 1 is GATED.");
					if(!isPresent(0x0054,0x0061))
						throw new ConditionFailedException("0054,0061 is required if Series Type (0054,1000), Value 1 is GATED.");
				}
			}
			if(strSeriesType[1] != null)
			{
				if(strSeriesType[1].equalsIgnoreCase(EnumSeriesType.Value2.REPROJECTION.getValue()) && !isPresent(0x0054,0x0061))
					throw new ConditionFailedException("0054,0061 is required if Series Type (0054,1000), Value 2 is REPROJECTION");
			}
		}
		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);

		}
		return true;
	}

	/**
	 * Sets Date the Series started.
	 * 
	 * @param strSeriesDate Date the Series started.
	 */	
	public void setSeriesDate(String strSeriesDate)
	{
		/*Accept the Series Date value in String format of type DA.
		 * 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(0x0008, 0x0021, DicomConstants.DCM_DT_DA, strSeriesDate);
	}

	/**
	 * Retrieves Series Date.
	 * 
	 * @return String - String value of Series Date
	 */
	public String getSeriesDate()
	{
		Object objectValue = getValue(0x0008, 0x0021);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Time the Series started.
	 * 
	 * @param strSeriesTime Time the Series started.
	 */	
	public void setSeriesTime(String strSeriesTime)
	{
		/*Accept the Series Time value in String format of type TM.
		 * 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(0x0008, 0x0031, DicomConstants.DCM_DT_TM, strSeriesTime);
	}

	/**
	 * Retrieves Series Time.
	 * 
	 * @return String - String value of Series Time.
	 */
	public String getSeriesTime()
	{
		Object objectValue = getValue(0x0008, 0x0031);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Pixel value units.
	 * Defined terms: CNTS, NONE, CM2, PCNT, CPS, BQML, MGMINML, UMOLMINML, MLMING, MLG,1CM, UMOLML, PROPCNTS, PROPCPS,
	 * MLMINML, MLML, GML, STDDEV.
	 * 
	 * @param enumUnits Enum value of Pixel value units.
	 */	
	public void setUnits(EnumUnits enumUnits)
	{
		/* Accept 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 Hash Map
		 */
		addDataElement(0x0054, 0x1001, DicomConstants.DCM_DT_CS, enumUnits.getValue());
	}

	/**
	 * Retrieves Pixel value units.
	 * 
	 * @return String - String value of Pixel value units.
	 */
	public String getUnits()
	{
		Object objectValue = getValue(0x0054, 0x1001);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets the Value Type Defined in Terms of TEXT,NUMERIC,CODE,DATE,TIME,PNAME
	 * @param strValueType Specifies type of the value encoded in this Item
	 */
	public void setSUVType(String strSUVType)
	{
		/*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(0x0054, 0x1006,DicomConstants.DCM_DT_CS, strSUVType);
		
	}
	/**
	 * Retrieves type of the value encoded in this Item
	 * @return String - Type of the value encoded in this Item
	 */
	public String getSUVType()
	{
		Object objValue = getValue(0x0054, 0x1006);
		if(objValue != null)
			return objValue.toString();
		return null;
	}
	
	/**
	 * Sets The primary source of counts.The primary source leads to the underlying image Units (0054,1001),
	 * as opposed to secondary sources which are used during reconstruction correction.
	 * Enumerated Values: EMISSION, TRANSMISSION
	 * 
	 * @param enumCountsSource the enum counts source
	 */	
	public void setCountsSource(EnumCountsSource enumCountsSource)
	{
		/* Accept 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 Hash Map
		 */
		addDataElement(0x0054, 0x1002, DicomConstants.DCM_DT_CS, enumCountsSource.getValue());
	}

	/**
	 * Retrieves The primary source of counts.
	 * 
	 * @return String - String value of primary source of counts.
	 */
	public String getCountsSource()
	{
		Object objectValue = getValue(0x0054, 0x1002);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets A multi-valued indicator of the type of Series.
	 * Value 1 Enumerated Values: STATIC, DYNAMIC, GATED, WHOLE BODY.
	 * Value 2 Enumerated Values: IMAGE, REPROJECTION
	 * 
	 * @param strArrSeriesType String array of Series type.
	 */	
	public void setSeriesType(String[] strArrSeriesType)
	{
		/* Accept 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 Hash Map
		 */
		addDataElement(0x0054, 0x1000, DicomConstants.DCM_DT_CS, strArrSeriesType);
	}

	/**
	 * Retrieves A multi-valued indicator of the type of Series.
	 * 
	 * @return String - String value of A multi-valued indicator of the type of Series.
	 */
	public String[] getSeriesType()
	{
		Object objValue = getValue(0x0054,0x1000);
		if(objValue != null)
			return (String[])objValue;
		return null;
	}

	/**
	 * Sets Method for projecting volumetric data onto planar projection.
	 * Defined terms: SUM, MAX PIXEL
	 * 
	 * @param enumReprojectionMethod Enum value of Reprojection Method.
	 */	
	public void setReprojectionMethod(EnumReprojectionMethod enumReprojectionMethod)
	{
		/* Accept Reprojection Method 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 Hash Map
		 */
		addDataElement(0x0054, 0x1004, DicomConstants.DCM_DT_CS, enumReprojectionMethod.getValue());
	}

	/**
	 * Retrieves Method for projecting volumetric data onto planar projection.
	 * 
	 * @return String - String value of Reprojection Method.
	 */
	public String getReprojectionMethod()
	{
		Object objectValue = getValue(0x0054, 0x1004);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets The maximum number of R-R Intervals that may exist in this Series.
	 * 
	 * @param shNumberOfRRIntervals Short value of Number Of RR Intervals.
	 */
	public void setNumberOfRRIntervals(short shNumberOfRRIntervals)
	{

		/*Accept Number Of R-R Intervals in short  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 Hash Map
		 */
		addDataElement(0x0054, 0x0061, DicomConstants.DCM_DT_US, shNumberOfRRIntervals);
	}

	/**
	 * Retrieves Number of R-R intervals.
	 * 
	 * @return short - Number of R-R intervals.
	 */
	public short getNumberOfRRIntervals()
	{Object objectValue = getValue(0x0054, 0x0061);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets The maximum number of Time Slots that may exist in this Series.
	 * 
	 * @param shNumberOfTimeSlots Short value of Number Of Time Slots.
	 */
	public void setNumberOfTimeSlots(short shNumberOfTimeSlots)
	{

		/*Accept Number Of R-R Time Slots in short  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 Hash Map
		 */
		addDataElement(0x0054, 0x0071, DicomConstants.DCM_DT_US, shNumberOfTimeSlots);
	}

	/**
	 * Retrieves Number of time slots.
	 * 
	 * @return short - Short value of Number of time slots.
	 */
	public short getNumberOfTimeSlots()
	{Object objectValue = getValue(0x0054, 0x0071);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets The maximum number of Time Slices that may exist in this Series.
	 * 
	 * @param shNumberOfTimeSlices Short value of Number of Time Slices.
	 */
	public void setNumberOfTimeSlices(short shNumberOfTimeSlices)
	{

		/* Accept Number Of Time Slots in short  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 Hash Map
		 */
		addDataElement(0x0054,0x0101, DicomConstants.DCM_DT_US, shNumberOfTimeSlices);
	}

	/**
	 * Retrieves The maximum number of Time Slices that may exist in this Series.
	 * 
	 * @return short - Short value of Number of Time Slices.
	 */
	public short getNumberOfTimeSlices()
	{Object objectValue = getValue(0x0054, 0x0101);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets The maximum number of Slices that may exist in this Series.
	 * 
	 * @param shNumberOfTimeSlices Short value of Number Of Time Slices.
	 */
	public void setNumberOfSlices(short shNumberOfTimeSlices)
	{

		/*Accept Number Of Slices in short  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 Hash Map
		 */
		addDataElement(0x0054, 0x0081, DicomConstants.DCM_DT_US, shNumberOfTimeSlices);
	}

	/**
	 * Retrieves The maximum number of Slices that may exist in this Series.
	 * 
	 * @return short - short value of Number of slices..
	 */
	public short getNumberOfSlices()
	{Object objectValue = getValue(0x0054, 0x0081);
		if(objectValue!=null)
			return Short.parseShort(objectValue.toString());
		return DicomConstants.DCM_NO_VALUE;
	}

	/**
	 * Sets A value that indicates , if any, corrections have been applied to the images in this series.
	 * Defined terms:
	 * DECY=decay corrected,
	 * ATTN=attenuation corrected,
	 * SCAT=scatter corrected,
	 * DTIM=dead time corrected,
	 * MOTN=gantry motion corrected(e.g. wobble, clamshell)
	 * PMOT=patient motion corrected
	 * CLN=count loss normalization
	 * RAN=randoms corrected
	 * RADL=non-uniform radial sampling corrected
	 * DCAL=sensitivity calibrated using dose calibrator
	 * NORM=detector normalization
	 * 
	 * @param enumCorrectedImage Enum value of Corrected Image.
	 */
	public void setCorrectedImage(EnumCorrectedImage[] enumCorrectedImage)
	{
		/*Accept Corrected Image 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
		 */
		String[] arrStrCorrectedImage = new String[enumCorrectedImage.length];
		for(int i=0;i < enumCorrectedImage.length ; i++)
		{
			arrStrCorrectedImage[i] = enumCorrectedImage[i].getValue();
		}
		addDataElement(0x0028, 0x0051, DicomConstants.DCM_DT_CS, arrStrCorrectedImage);
	}

	/**
	 * Retrieves A value that indicates , if any, corrections have been applied to the images in this series.
	 * 
	 * @return the corrected image
	 */
	public String[] getCorrectedImage()
	{Object objectValue = getValue(0x0028,0x0051);
		if(objectValue!=null)
			return (String[])objectValue;
		return null;
	}

	/**
	 * Sets Type of randoms correction processing.
	 * Defined terms:
	 * NONE = no randoms correction
	 * DLYD = delayed event subtraction
	 * SING = singles estimation
	 * 
	 * @param enumRandomsCorrectionMethod Enum value of Type of randoms correction processing.
	 */	
	public void setRandomsCorrectionMethod(EnumRandomsCorrectionMethod enumRandomsCorrectionMethod)
	{
		/* Accept Randoms Correction Method 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 Hash Map
		 */
		addDataElement(0x0054, 0x1100, DicomConstants.DCM_DT_CS, enumRandomsCorrectionMethod.getValue());
	}

	/**
	 * Retrieves Type of randoms correction processing.
	 * 
	 * @return String - String value of Type of randoms correction processing.
	 */
	public String getRandomsCorrectionMethod()
	{
		Object objectValue = getValue(0x0054, 0x1100);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets A textual description of the attenuation correction processing. e.g. measured vs. calculated,
	 * transmission source type (ring, line, point), assumed patient geometry
	 * (polygon, ellipse, segmented, attenuation coefficient, skull thickness), post-injection transmission, smoothing.
	 * 
	 * @param strAttenuationCorrectionMethod String value of Attenuation Correction Method.
	 */	
	public void setAttenuationCorrectionMethod(String strAttenuationCorrectionMethod)
	{
		/* Accept Randoms Correction Method 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 Hash Map
		 */
		addDataElement(0x0054, 0x1101, DicomConstants.DCM_DT_LO, strAttenuationCorrectionMethod);
	}

	/**
	 * Retrieves A textual description of the attenuation correction processing.
	 * 
	 * @return String - String value of textual description of the attenuation correction processing.
	 */
	public String getAttenuationCorrectionMethod()
	{
		Object objectValue = getValue(0x0054, 0x1101);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets A textual description of the scatter correction processing. e.g. convolution subtraction,
	 * dual energy window, modelbased,use of attenuation data.
	 * 
	 * @param strScatterCorrectionMethod String value of Scatter Correction Method.
	 */	
	public void setScatterCorrectionMethod(String strScatterCorrectionMethod)
	{
		/* Accept Scatter Correction Method 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 Hash Map
		 */
		addDataElement(0x0054, 0x1105, DicomConstants.DCM_DT_LO, strScatterCorrectionMethod);
	}

	/**
	 * Retrieves A textual description of the scatter correction processing.
	 * 
	 * @return String - String value of textual description of the scatter correction processing.
	 */
	public String getScatterCorrectionMethod()
	{
		Object objectValue = getValue(0x0054, 0x1105);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets The real-world event to which images in this Series were decay corrected.
	 * Defined terms:
	 * NONE = no decay correction
	 * START= acquisition start time
	 * ADMIN = radiopharmaceutical administration time
	 * 
	 * @param enumDecayCorrection Enum value of Decay Correction.
	 */	
	public void setDecayCorrection(EnumDecayCorrection enumDecayCorrection)
	{
		/* Accept Decay Correction 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 Hash Map
		 */
		addDataElement(0x0054, 0x1102, DicomConstants.DCM_DT_CS, enumDecayCorrection.getValue());
	}

	/**
	 * Retrieves The real-world event to which images in this Series were decay corrected.
	 * 
	 * @return String - String value of Decay Correction.
	 */
	public String getDecayCorrection()
	{
		Object objValue = getValue(0x0054,0x1102);
		if(objValue != null)
			return objValue.toString();
		return null;
	}

	/**
	 * The method is used to set Diameter in mm of the region from within
	 * which data were used in creating the reconstruction of the image.
	 * 
	 * @param strReconstructionDiameter String value of Data Reconstruction Diameter
	 */
	public void setReconstructionDiameter(String strReconstructionDiameter)
	{
		/*Accept Reconstruction Diameter of Images 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(0x0018, 0x1100, DicomConstants.DCM_DT_IS, strReconstructionDiameter);
	}

	/**
	 * Return the String value of the attribute Reconstruction Diameter.
	 * 
	 * @return String - returns the Reconstruction Diameter.
	 */
	public String getReconstructionDiameter()
	{
		Object objectValue = getValue(0x0018, 0x1100);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * This method is used to set Textual description of the convolution kernel(s) used to reconstruct the data.
	 * 
	 * @param arrStrConvolutionKernel Image Convolution Kernel
	 */	
	public void setConvolutionKernel(String[] arrStrConvolutionKernel)
	{
		/*Accept the convolution kernel in String Array format of type SH.
		 * 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(0x0018, 0x1210, DicomConstants.DCM_DT_SH, arrStrConvolutionKernel);
	}

	/**
	 * Return the String values of the attribute Convolution Kernel.
	 * 
	 * @return the convolution kernel
	 */
	public String[] getConvolutionKernel()
	{
		 Object objValue = getValue(0x0018,0x1210);
   if(objValue!=null)
      return (String[])objValue;
   return null;

	}

	/**
	 * The method is used to set Textual description of reconstruction processing, e.g. 2D filtered backprojection,
	 * 2D iterative, 3D PROMIS, 3D FAVOR, 3D iterative.
	 * 
	 * @param strReconstructionMethod String value of Reconstruction Method
	 */
	public void setReconstructionMethod(String strReconstructionMethod)
	{
		/* Accept Reconstruction Method 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 Hash Map
		 */
		addDataElement(0x0054, 0x1103, DicomConstants.DCM_DT_LO, strReconstructionMethod);
	}

	/**
	 * Return method is used to set Textual description of reconstruction processing,.
	 * 
	 * @return String - returns the Reconstruction Method.
	 */
	public String getReconstructionMethod()
	{
		Object objectValue = getValue(0x0054, 0x1103);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * The method Textual description of which detector lines of response were used, mashed, or
	 * otherwise processed during tomographic reconstruction.
	 * 
	 * @param strDetectorLinesOfResponseUsed String value of Detector Lines of Response Used
	 */
	public void setDetectorLinesOfResponseUsed(String strDetectorLinesOfResponseUsed)
	{
		/* Accept Detector Lines of Response Used 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 Hash Map
		 */
		addDataElement(0x0054, 0x1104, DicomConstants.DCM_DT_LO, strDetectorLinesOfResponseUsed);
	}

	/**
	 * Return Detector Lines of Response Used.
	 * 
	 * @return String - returns the Detector Lines of Response Used
	 */
	public String getDetectorLinesOfResponseUsed()
	{
		Object objectValue = getValue(0x0054, 0x1104);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Description of how the data collection was started. Defined terms
	 * DENS = density (counts/sec)
	 * RDD = relative density difference(change in counts/sec)
	 * MANU = manual
	 * TIME = time
	 * AUTO = automatic, when ready
	 * TRIG = physiological trigger
	 * 
	 * @param strAcquisitionStartCondition String value of Acquisition Start Condition
	 */
	public void setAcquisitionStartCondition(String strAcquisitionStartCondition)
	{
		/* Accept Acquisition Start Condition 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 Hash Map
		 */
		addDataElement(0x0018, 0x0073, DicomConstants.DCM_DT_CS, strAcquisitionStartCondition);
	}

	/**
	 * Return Description of how the data collection was started.
	 * 
	 * @return String - String value of Acquisition Start Condition
	 */
	public String getAcquisitionStartCondition()
	{
		Object objectValue = getValue(0x0018, 0x0073);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Count density, change in count density, or physiological triggers causing data collection to start.
	 * 
	 * @param strAcquisitionStartConditionData String value of Acquisition Start Condition Data
	 */
	public void setAcquisitionStartConditionData(String strAcquisitionStartConditionData)
	{
		/* Accept Acquisition Start Condition Data 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 Hash Map
		 */
		addDataElement(0x0018, 0x0074, DicomConstants.DCM_DT_IS, strAcquisitionStartConditionData);
	}

	/**
	 * Return  Count density, change in count density, or physiological triggers causing data collection to start.
	 * 
	 * @return String - String value of Acquisition Start Condition Data
	 */
	public String getAcquisitionStartConditionData()
	{
		Object objectValue = getValue(0x0018, 0x0074);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Description of how the data collection was stopped. Defined Terms:
	 * CNTS = counts,DENS = density,MANU = manual,OVFL = data overflow,TIME = time,TRIG = physiological trigger,RDD = relative density difference
	 * 
	 * @param enumAcquisitionTerminationCondition - Specifies how the data collection was stopped
	 */
	public void setAcquisitionTerminationCondition(EnumAcquisitionTerminationCondition enumAcquisitionTerminationCondition)
	{
		/*Accept Acquisition Termination Condition in String 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(0x0018, 0x0071, DicomConstants.DCM_DT_CS, enumAcquisitionTerminationCondition.getValue());
	}

	/**
	 * Returns Description of how the data collection was stopped.
	 * 
	 * @return String - String value of Acquisition Termination Condition
	 */
	public String getAcquisitionTerminationCondition()
	{
		Object objectValue = getValue(0x0018, 0x0071);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Number of counts, count density, change in count density, or physiological triggers causing the termination.
	 * 
	 * @param strAcquisitionTerminationConditionData String value of Acquisition Termination Condition Data
	 */
	public void setAcquisitionTerminationConditionData(String strAcquisitionTerminationConditionData)
	{
		/*Accept Acquisition Termination Condition in String 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(0x0018, 0x0075, DicomConstants.DCM_DT_IS, strAcquisitionTerminationConditionData);
	}

	/**
	 * Returns Acquisition Termination Condition Data.
	 * 
	 * @return String - String value of Acquisition Termination Condition Data
	 */
	public String getAcquisitionTerminationConditionData()
	{
		Object objectValue = getValue(0x0018, 0x0075);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets shape of the Field of View, that is the image pixels stored in Pixel Data (7FE0,0010).
	 * Enumerated Values: RECTANGLE, ROUND, HEXAGONAL.
	 * 
	 * @param enumFieldOfViewShape the enum field of view shape
	 */
	public void setFieldOfViewShape(EnumFieldOfViewShape enumFieldOfViewShape)
	{
		/* Accept Field of View Shape 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 Hash Map
		 */
		addDataElement(0x0018, 0x1147, DicomConstants.DCM_DT_CS, enumFieldOfViewShape.getValue());
	}

	/**
	 * Return shape of the Field of View, that is the image pixels stored in Pixel Data (7FE0,0010).
	 * 
	 * @return -  String value of Field of View Shape
	 */
	public String getFieldOfViewShape()
	{
		Object objectValue = getValue(0x0018, 0x1147);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Dimensions of the Image Intensifier Field of View in mm. If Rectangle, row
	 * dimension followed by column; if Round, diameter.
	 * 
	 * @param arrStrFieldOfViewDimensions - String array of Field of View Dimensions
	 */
	public void setFieldOfViewDimensions(String[] arrStrFieldOfViewDimensions)
	{
		/*Accept Field of View Dimensions 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 Hash Map
		 */
		addDataElement(0x0018,0x1149, DicomConstants.DCM_DT_IS, arrStrFieldOfViewDimensions);
	}

	/**
	 * Returns type of filter(s) inserted into the X-Ray beam.
	 * 
	 * @return - String Array of Field Of View Dimensions
	 */
	public String[] getFieldOfViewDimensions()
	{
		Object objectValue = getValue(0x0018, 0x1149);
		if(objectValue!=null)
			return (String[])objectValue;
		return null;
	}

	/**
	 * The method is used to set Nominal angle of tilt in degrees of the scanning gantry.
	 * 
	 * @param strGantryOrDetectorTilt String value of Nominal angle of tilt
	 */
	public void setGantryOrDetectorTilt(String strGantryOrDetectorTilt)
	{
		/*Accept Nominal angle of tilt 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(0x0018, 0x1120, DicomConstants.DCM_DT_DS, strGantryOrDetectorTilt);
	}

	/**
	 * Return the String value of the attribute Gantry Or DetectorTilt.
	 * 
	 * @return String - returns the Gantry or Detector tilt
	 */
	public String getGantryOrDetectorTilt()
	{
		Object objectValue = getValue(0x0018, 0x1120);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * The method is used to set Angle of slew in degrees of the gantry.
	 * 
	 * @param strGantryDetectorSlew String value Gantry/Detector Slew
	 */
	public void setGantryDetectorSlew(String strGantryDetectorSlew)
	{
		/*Accept Nominal angle of tilt 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(0x0018,0x1121, DicomConstants.DCM_DT_DS, strGantryDetectorSlew);
	}

	/**
	 * Return the String value of the attribute Gantry or Detector Slew.
	 * 
	 * @return String - returns the Gantry or Detector Slew
	 */
	public String getGantryDetectorSlew()
	{Object objectValue = getValue(0x0018,0x1121);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Describes the detector motion during acquisition. Enumerated Values:
	 * STEP AND SHOOT = Interrupted motion,acquire only while stationary.
	 * CONTINUOUS = Gantry motion and acquisition are simultaneous and continuous.
	 * ACQ DURING STEP = Interrupted motion,acquisition is continuous.
	 * 
	 * @param enumTypeOfDetectorMotion -Enum value of Type Of Detector Motion.
	 */
	public void setTypeOfDetectorMotion(EnumTypeOfDetectorMotion enumTypeOfDetectorMotion)
	{
		/*Accept Type of Detector Motion in String 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(0x0054, 0x0202, DicomConstants.DCM_DT_CS, enumTypeOfDetectorMotion.getValue());
	}

	/**
	 * Retrieves the Type of Detector Motion.
	 * 
	 * @return String - returns the type of detector motion
	 */
	public String getTypeOfDetectorMotion()
	{
		Object objectValue = getValue(0x0054, 0x0202);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Collimator Type.
	 * Defined Terms:
	 * NONE = no collimator
	 * RING = transverse septa
	 * 
	 * @param enumCollimatorType Enum value of Collimator Type.
	 */
	public void setCollimatorType(EnumCollimatorType enumCollimatorType)
	{
		/* Accept Collimator Type in String 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(0x0018,0x1181, DicomConstants.DCM_DT_CS, enumCollimatorType.getValue());
	}

	/**
	 * Retrieves the Type of Collimator.
	 * 
	 * @return String - returns the type of Collimator
	 */
	public String getCollimatorType()
	{
		Object objectValue = getValue(0x0018, 0x1181);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Label describing the collimator used.
	 * 
	 * @param strCollimatorGridName String value of Collimator/Grid Name.
	 */
	public void setCollimatorGridName(String strCollimatorGridName)
	{
		/* Accept Collimator Type in String 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(0x0018,0x1180, DicomConstants.DCM_DT_SH, strCollimatorGridName);
	}

	/**
	 * Retrieves Label describing the collimator used.
	 * 
	 * @return String - returns the type of Collimator/Grid Name
	 */
	public String getCollimatorGridName()
	{
		Object objectValue = getValue(0x0018, 0x1180);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Maximum axial angle accepted, in degrees.
	 * 
	 * @param strAxialAcceptance String value of Maximum axial angle accepted, in degrees.
	 */
	public void setAxialAcceptance(String strAxialAcceptance)
	{
		/* Accept Axial Acceptance in String 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(0x0054,0x1200, DicomConstants.DCM_DT_DS, strAxialAcceptance);
	}

	/**
	 * Retrieves Maximum axial angle accepted, in degrees.
	 * 
	 * @return String - returns the type of Axial Acceptance
	 */
	public String getAxialAcceptance()
	{
		Object objectValue = getValue(0x0054, 0x1200);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Number of adjacent axial lines of response mashed together.
	 * 
	 * @param strArrAxialMash String array of Axial Mash.
	 */
	public void setAxialMash(String[] strArrAxialMash)
	{
		/* Accept Axial Acceptance in String 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(0x0054,0x1201, DicomConstants.DCM_DT_IS, strArrAxialMash);
	}

	/**
	 * Retrieves Number of adjacent axial lines of response mashed together.
	 * 
	 * @return String - String array of Axial Mash.
	 */
	public String[] getAxialMash()
	{
		Object objectValue = getValue(0x0054, 0x1201);
		if(objectValue!=null)
			return (String[])objectValue;
		return null;
	}

	/**
	 * Sets Number of adjacent transverse lines of response mashed together.
	 * 
	 * @param strTransverseMash String value of Transverse Mash.
	 */
	public void setTransverseMash(String strTransverseMash)
	{
		/* Accept Transverse Mash in String format of type IS.
		 * 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(0x0054,0x1202, DicomConstants.DCM_DT_IS, strTransverseMash);
	}

	/**
	 * Retrieves Number of adjacent transverse lines of response mashed together.
	 * 
	 * @return String - String value of Transverse Mash.
	 */
	public String getTransverseMash()
	{
		Object objectValue = getValue(0x0054, 0x1202);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Sets Size of an individual detector element, in mm. Transverse dimension followed by axial dimension.
	 * For a discrete crystal, this is the crystal size. For a continuous detector, this is the pixel bin size.
	 * 
	 * @param strArrDetectorElementSize String array of Detector Element Size
	 */
	public void setDetectorElementSize(String[] strArrDetectorElementSize)
	{
		/* Accept Axial Acceptance in String 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(0x0054,0x1203, DicomConstants.DCM_DT_DS, strArrDetectorElementSize);
	}

	/**
	 * Retrieves Size of an individual detector element, in mm.
	 * 
	 * @return String - String array of Detector Element Size.
	 */
	public String[] getDetectorElementSize()
	{
		Object objectValue = getValue(0x0054, 0x1203);
		if(objectValue!=null)
			return (String[])objectValue;
		return null;
	}

	/**
	 * Sets The width of the coincidence timing window, in nsec.
	 * The maximum time difference accepted between two single events.
	 * 
	 * @param strCoincidenceWindowWidth String value of Coincidence Window Width.
	 */
	public void setCoincidenceWindowWidth(String strCoincidenceWindowWidth)
	{
		/* Accept Transverse Mash in String format of type IS.
		 * 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(0x0054,0x1210, DicomConstants.DCM_DT_DS, strCoincidenceWindowWidth);
	}

	/**
	 * Retrieves The width of the coincidence timing window, in nsec.
	 * 
	 * @return String - String value of Coincidence Window Width
	 */
	public String getCoincidenceWindowWidth()
	{
		Object objectValue = getValue(0x0054, 0x1210);
		if(objectValue!=null)
			return objectValue.toString();
		return null;
	}

	/**
	 * Retrieves pre-initialized object of Energy Window Range 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 EnergyWindowRangeSequence - instance of Energy Window Range Sequence.
	 */
	public EnergyWindowRangeSequence getEnergyWindowRangeSequence()
	{
		EnergyWindowRangeSequence objEnergyWindowRangeSequence = (EnergyWindowRangeSequence)getDicomValue(0x0054, 0x0013);
		if(objEnergyWindowRangeSequence == 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();
			objEnergyWindowRangeSequence = (EnergyWindowRangeSequence)objDicomV3Factory.createSequence(0x0054, 0x0013, objITransferSyntax, objIDictionaryReader);
			
			// This will add Data Element of SQ to the DataSet.
			addDataElement(0x0054, 0x0013, DicomConstants.DCM_DT_SQ, objEnergyWindowRangeSequence.getValue());
		}
		return objEnergyWindowRangeSequence;
	}

	/**
	 * Sets Array defining the type of additional counts accumulated during acquisition.
	 * Defined terms:
	 * DLYD=delayed events,
	 * SCAT=scattered events in secondary window
	 * SING=singles
	 * DTIM=events lost due to deadtime
	 * 
	 * @param enumSecondaryCountsType Enum value of Secondary Counts Type.
	 */
	public void setSecondaryCountsType(EnumCorrectedImage[] enumSecondaryCountsType)
	{
		/* Accept Corrected Image 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
		 */
		String[] arrstrSecondaryCountsType = new String[enumSecondaryCountsType.length];
		for(int i=0;i < enumSecondaryCountsType.length ; i++)
		{
			arrstrSecondaryCountsType[i] = enumSecondaryCountsType[i].getValue();
		}
		addDataElement(0x0054,0x1220, DicomConstants.DCM_DT_CS, arrstrSecondaryCountsType);
	}

	/**
	 * Retrieves Array defining the type of additional counts accumulated during acquisition.
	 * 
	 * @return the secondary counts type
	 */
	public String[] getSecondaryCountsType()
	{Object objectValue = getValue(0x0054,0x1220);
		if(objectValue!=null)
			return (String[])objectValue;
		return null;
	}

	/**
	 * Sets the Value Type Defined in Terms of TEXT,NUMERIC,CODE,DATE,TIME,PNAME
	 * @param strValueType Specifies type of the value encoded in this Item
	 */
	public void setScanProgressionDirection(String strSUVType)
	{
		/*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(0x0054, 0x0501,DicomConstants.DCM_DT_CS, strSUVType);
		
	}
	/**
	 * Retrieves type of the value encoded in this Item
	 * @return String - Type of the value encoded in this Item
	 */
	public String getScanProgressionDirection()
	{
		Object objValue = getValue(0x0054, 0x0501);
		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;
	}
}
