#ifndef DETECTOR_TYPE_HPP_INCLUDED
#define DETECTOR_TYPE_HPP_INCLUDED

#include <iostream>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include <NBO/NBO/AnnotationRef.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/DetectorID_Type.h>
#include <NBO/NBO/DetectorMount_Type.h>
#include <NBO/NBO/DetectorNoiseModel_Type.h>
#include <NBO/NBO/DigitizerType_Type.h>
#include <NBO/NBO/LensRef_Type.h>
#include <NBO/NBO/ManufacturerSpec_Type.h>
#include <NBO/NBO/UnitsElectricCurrent_Type.h>
#include <NBO/NBO/UnitsRatio_Type.h>
#include <NBO/NBO/UnitsTemperature_Type.h>
#include <NBO/NBO/PositiveFloat_Type.h>
#include <NBO/NBO/UnitsLength_Type.h>
#include <NBO/NBO/ENBOType.h>
#include <NBO/NBOGlobal.h>
#include <NBO/Shared/Base/NBOBaseClass.h>


namespace Inscoper::NBO {

/*!
* \brief Represents the XML complex type Detector.
*
* This element describes a Detector available for this Instrument. An Instrument may have more than one Detector of different types, such as a Photomultiplier, or a Camera. The Detector ID can be used as a reference within the Channel element. The values stored in Detector represent the fixed values, variable values modified during the Acquisition go in DetectorSettings.
*/
class NBO_EXPORT Detector_Type : public ManufacturerSpec_Type {

public:
	/*!
	* \brief Represents the XML element WavelengthRange.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*/
	class NBO_EXPORT InlineWavelengthRange : public NBOBaseClass {
	
	public:
		
		InlineWavelengthRange();
		~InlineWavelengthRange();
	
		/*!
		* \brief Cast a NBOBaseClass to a InlineWavelengthRange.
		*
		* \param base The base class to cast
		* \return The casted element, or nullptr if the cast fails
		*/
		static std::shared_ptr<InlineWavelengthRange> fromBase(NBOBaseClassPtr base);
	
		/*!
		* \brief Returns the class type name.
		*
		* \return The class type name
		*/
		std::string getTypeName() const override;
	
		/*!
		* \brief Returns the XML element name corresponding to this class.
		*
		* \return The XML element name
		*/
		std::string getXMLName() const override;
	
		/*!
		* \brief Returns the NBO Type corresponding to this class.
		*
		* \return The NBO Type value
		*/
		ENBOType getNBOType() const override;
	
		/*!
		* \brief Returns a list of all classes derived from this class.
		*
		* \return The list of derived classes
		*/
		std::vector<NBOBaseClassPtr> getChildren() const override;
	
		/*!
		* \brief Returns a list of all child elements contained in this class.
		*
		* \return The list of child classes
		*/
		std::vector<NBOBaseClassPtr> getSubElements() const override;
	
		/*!
		* \brief Populates this object from a JSON file.
		*
		* \param path The path to the JSON file
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void fromJsonFile(const std::string& path, bool validate = true);
	
		/*!
		* \brief Populates this object from a JSON string.
		*
		* \param json_string The JSON content as a string
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void fromJsonString(const std::string& json_string, bool validate = true);
	
		/*!
		* \brief Populates this object from a XML file.
		*
		* \param path The path to the XML file
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void fromXmlFile(const std::string& path, bool validate = true);
	
		/*!
		* \brief Populates this object from a XML string.
		*
		* \param xml_string The XML content as a string
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void fromXmlString(const std::string& xml_string, bool validate = true);
	
		/*!
		* \brief Serializes this object to an XML file.
		*
		* \param filename The path to the output XML file
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void toXmlFile(const std::string& filename, bool validate = true) const;
	
		/*!
		* \brief Serializes this object to an XML string.
		*
		* \param validate If true, validates constraints on value. Default is true.
		* \return A string containing the XML representation of this object
		*/
		std::string toXmlString(bool validate = true) const;
	
		/*!
		* \brief Sets the value of the PeakWavelength attribute.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setPeakWavelength(const float& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the PeakWavelength attribute.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*
		* \return The value of the attribute
		*/
		float getPeakWavelength() const;
	
		/*!
		* \brief Resets the PeakWavelength attribute to an unset state.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*/
		void resetPeakWavelength();
	
		/*!
		* \brief Checks whether the PeakWavelength attribute is present.
		*
		* This field records the nominal Wavelength associated with the peak response rate of this device. 
		*
		* \return true if the attribute has been set, false otherwise
		*/
		bool hasPeakWavelength() const;
	
		/*!
		* \brief Sets the value of the PeakWavelengthUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setPeakWavelengthUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the PeakWavelengthUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \return The value of the attribute
		*/
		UnitsLength_TypePtr getPeakWavelengthUnit() const;
	
		/*!
		* \brief Resets the PeakWavelengthUnit attribute to an unset state.
		*
		* No description available in the XSD standard.
		*/
		void resetPeakWavelengthUnit();
	
		/*!
		* \brief Checks whether the optional PeakWavelengthUnit attribute is present.
		*
		* No description available in the XSD standard.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasPeakWavelengthUnit() const;
	
		/*!
		* \brief Sets the value of the CutOn attribute.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setCutOn(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOn attribute.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*
		* \return The value of the attribute
		*/
		PositiveFloat_TypePtr getCutOn() const;
	
		/*!
		* \brief Resets the CutOn attribute to an unset state.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*/
		void resetCutOn();
	
		/*!
		* \brief Checks whether the optional CutOn attribute is present.
		*
		* CutOn is the Wavelength below which the response rate is below 50%.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOn() const;
	
		/*!
		* \brief Sets the value of the CutOnUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setCutOnUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOnUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \return The value of the attribute
		*/
		UnitsLength_TypePtr getCutOnUnit() const;
	
		/*!
		* \brief Resets the CutOnUnit attribute to an unset state.
		*
		* No description available in the XSD standard.
		*/
		void resetCutOnUnit();
	
		/*!
		* \brief Checks whether the optional CutOnUnit attribute is present.
		*
		* No description available in the XSD standard.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOnUnit() const;
	
		/*!
		* \brief Sets the value of the CutOff attribute.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setCutOff(const Inscoper::NBO::PositiveFloat_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOff attribute.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*
		* \return The value of the attribute
		*/
		PositiveFloat_TypePtr getCutOff() const;
	
		/*!
		* \brief Resets the CutOff attribute to an unset state.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*/
		void resetCutOff();
	
		/*!
		* \brief Checks whether the optional CutOff attribute is present.
		*
		* CutOff is the Wavelength above which the response rate is below 50%.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOff() const;
	
		/*!
		* \brief Sets the value of the CutOffUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setCutOffUnit(const Inscoper::NBO::UnitsLength_TypePtr& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the CutOffUnit attribute.
		*
		* No description available in the XSD standard.
		*
		* \return The value of the attribute
		*/
		UnitsLength_TypePtr getCutOffUnit() const;
	
		/*!
		* \brief Resets the CutOffUnit attribute to an unset state.
		*
		* No description available in the XSD standard.
		*/
		void resetCutOffUnit();
	
		/*!
		* \brief Checks whether the optional CutOffUnit attribute is present.
		*
		* No description available in the XSD standard.
		*
		* \return true if the optional attribute has been set, false otherwise
		*/
		bool hasCutOffUnit() const;
	
		/*!
		* \brief Sets the value of the WavelengthProfile attribute.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \param value The value to set
		* \param validate If true, validates constraints on value. Default is true.
		*/
		void setWavelengthProfile(const std::string& value, bool validate = true);
	
		/*!
		* \brief Returns the value of the WavelengthProfile attribute.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \return The value of the attribute
		*/
		std::string getWavelengthProfile() const;
	
		/*!
		* \brief Resets the WavelengthProfile attribute to an unset state.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*/
		void resetWavelengthProfile();
	
		/*!
		* \brief Checks whether the WavelengthProfile attribute is present.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \return true if the attribute has been set, false otherwise
		*/
		bool hasWavelengthProfile() const;
	
		/*!
		* \brief Returns the allowed values for this attribut.
		*
		* The location of a file containing the Wavelength profile of this hardware component.
		*
		* \return The list of allowed values
		*/
		static const std::set<std::string>& getWavelengthProfileAllowedValues();
	
	
	private:
		class Impl;
		std::unique_ptr<Impl> pImpl;
	
	    std::optional<float> PeakWavelength; // Optional attribute
		UnitsLength_TypePtr PeakWavelengthUnit = nullptr; // Optional attribute
		PositiveFloat_TypePtr CutOn = nullptr; // Required attribute
		UnitsLength_TypePtr CutOnUnit = nullptr; // Optional attribute
		PositiveFloat_TypePtr CutOff = nullptr; // Required attribute
		UnitsLength_TypePtr CutOffUnit = nullptr; // Optional attribute
	    std::optional<std::string> WavelengthProfile; // Required attribute
	    static const std::set<std::string> WavelengthProfileAllowedValues;
	};
	
	/*! Shared pointer for InlineWavelengthRange*/
	typedef std::shared_ptr<InlineWavelengthRange> InlineWavelengthRangePtr;
	
	
	Detector_Type();
	~Detector_Type();

	/*!
	* \brief Cast a NBOBaseClass to a Detector_Type.
	*
	* \param base The base class to cast
	* \return The casted element, or nullptr if the cast fails
	*/
	static std::shared_ptr<Detector_Type> fromBase(NBOBaseClassPtr base);

	/*!
	* \brief Returns the class type name.
	*
	* \return The class type name
	*/
	virtual std::string getTypeName() const override;

	/*!
	* \brief Returns the XML element name corresponding to this class.
	*
	* \return The XML element name
	*/
	std::string getXMLName() const override;

	/*!
	* \brief Returns the NBO Type corresponding to this class.
	*
	* \return The NBO Type value
	*/
	ENBOType getNBOType() const override;

	/*!
	* \brief Returns a list of all classes derived from this class.
	*
	* \return The list of derived classes
	*/
	std::vector<NBOBaseClassPtr> getChildren() const override;

	/*!
	* \brief Returns a list of all child elements contained in this class.
	*
	* \return The list of child classes
	*/
	std::vector<NBOBaseClassPtr> getSubElements() const override;

	/*!
	* \brief Populates this object from a JSON file.
	*
	* \param path The path to the JSON file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromJsonFile(const std::string& path, bool validate = true);

	/*!
	* \brief Populates this object from a JSON string.
	*
	* \param json_string The JSON content as a string
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromJsonString(const std::string& json_string, bool validate = true);

	/*!
	* \brief Populates this object from a XML file.
	*
	* \param path The path to the XML file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromXmlFile(const std::string& path, bool validate = true);

	/*!
	* \brief Populates this object from a XML string.
	*
	* \param xml_string The XML content as a string
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void fromXmlString(const std::string& xml_string, bool validate = true);

	/*!
	* \brief Serializes this object to an XML file.
	*
	* \param filename The path to the output XML file
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void toXmlFile(const std::string& filename, bool validate = true) const;

	/*!
	* \brief Serializes this object to an XML string.
	*
	* \param validate If true, validates constraints on value. Default is true.
	* \return A string containing the XML representation of this object
	*/
	std::string toXmlString(bool validate = true) const;

	/*!
	* \brief Sets the value of the ID attribute.
	*
	* A Unique Identifier for this component.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setID(const Inscoper::NBO::DetectorID_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ID attribute.
	*
	* A Unique Identifier for this component.
	*
	* \return The value of the attribute
	*/
	DetectorID_TypePtr getID() const;

	/*!
	* \brief Resets the ID attribute to an unset state.
	*
	* A Unique Identifier for this component.
	*/
	void resetID();

	/*!
	* \brief Checks whether the optional ID attribute is present.
	*
	* A Unique Identifier for this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasID() const;

	/*!
	* \brief Sets the value of the Name attribute.
	*
	* A User-defined Name for this component.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setName(const Inscoper::NBO::Denomination_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Name attribute.
	*
	* A User-defined Name for this component.
	*
	* \return The value of the attribute
	*/
	Denomination_TypePtr getName() const;

	/*!
	* \brief Resets the Name attribute to an unset state.
	*
	* A User-defined Name for this component.
	*/
	void resetName();

	/*!
	* \brief Checks whether the optional Name attribute is present.
	*
	* A User-defined Name for this component.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasName() const;

	/*!
	* \brief Sets the value of the Mount attribute.
	*
	* This field records the type of Mount used to connect this detector to the Microscope Stand.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMount(const Inscoper::NBO::DetectorMount_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the Mount attribute.
	*
	* This field records the type of Mount used to connect this detector to the Microscope Stand.
	*
	* \return The value of the attribute
	*/
	DetectorMount_TypePtr getMount() const;

	/*!
	* \brief Resets the Mount attribute to an unset state.
	*
	* This field records the type of Mount used to connect this detector to the Microscope Stand.
	*/
	void resetMount();

	/*!
	* \brief Checks whether the optional Mount attribute is present.
	*
	* This field records the type of Mount used to connect this detector to the Microscope Stand.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasMount() const;

	/*!
	* \brief Sets the value of the MaxBitDepth attribute.
	*
	* This field records the Maximum Bit Depth provided by the Detector's Analog to Digital Converter (ADC; also referred to as Digitizer).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setMaxBitDepth(const Inscoper::NBO::DigitizerType_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the MaxBitDepth attribute.
	*
	* This field records the Maximum Bit Depth provided by the Detector's Analog to Digital Converter (ADC; also referred to as Digitizer).
	*
	* \return The value of the attribute
	*/
	DigitizerType_TypePtr getMaxBitDepth() const;

	/*!
	* \brief Resets the MaxBitDepth attribute to an unset state.
	*
	* This field records the Maximum Bit Depth provided by the Detector's Analog to Digital Converter (ADC; also referred to as Digitizer).
	*/
	void resetMaxBitDepth();

	/*!
	* \brief Checks whether the optional MaxBitDepth attribute is present.
	*
	* This field records the Maximum Bit Depth provided by the Detector's Analog to Digital Converter (ADC; also referred to as Digitizer).
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasMaxBitDepth() const;

	/*!
	* \brief Sets the value of the QuantumEfficiency attribute.
	*
	* This field records the Quantum Efficiency observed at Peak Wavelength, according to the Manufacturer. Quantum Efficiency is generally defined as is the ratio of incident photons to converted electrons. Typically expressed as a number between 0 and 1.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setQuantumEfficiency(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the QuantumEfficiency attribute.
	*
	* This field records the Quantum Efficiency observed at Peak Wavelength, according to the Manufacturer. Quantum Efficiency is generally defined as is the ratio of incident photons to converted electrons. Typically expressed as a number between 0 and 1.
	*
	* \return The value of the attribute
	*/
	float getQuantumEfficiency() const;

	/*!
	* \brief Resets the QuantumEfficiency attribute to an unset state.
	*
	* This field records the Quantum Efficiency observed at Peak Wavelength, according to the Manufacturer. Quantum Efficiency is generally defined as is the ratio of incident photons to converted electrons. Typically expressed as a number between 0 and 1.
	*/
	void resetQuantumEfficiency();

	/*!
	* \brief Checks whether the QuantumEfficiency attribute is present.
	*
	* This field records the Quantum Efficiency observed at Peak Wavelength, according to the Manufacturer. Quantum Efficiency is generally defined as is the ratio of incident photons to converted electrons. Typically expressed as a number between 0 and 1.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasQuantumEfficiency() const;

	/*!
	* \brief Sets the value of the ElectronicConversionFactor attribute.
	*
	* This field records the Electron-Conversion Factor for this Detector, as specified by the Manufacturer. The Electron Conversion Factor relates the actual number of electrons generated by the Detector with the digital number associated with each Pixel. It is expressed in electrons/Analog-to-Digital-Unit (ADU). Note that ADU can also be referred to as Digital Number (DN) or Binary Number. It is sometimes referred to as Digital Gain or, in case of CCD cameras as CCD Gain.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setElectronicConversionFactor(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ElectronicConversionFactor attribute.
	*
	* This field records the Electron-Conversion Factor for this Detector, as specified by the Manufacturer. The Electron Conversion Factor relates the actual number of electrons generated by the Detector with the digital number associated with each Pixel. It is expressed in electrons/Analog-to-Digital-Unit (ADU). Note that ADU can also be referred to as Digital Number (DN) or Binary Number. It is sometimes referred to as Digital Gain or, in case of CCD cameras as CCD Gain.
	*
	* \return The value of the attribute
	*/
	float getElectronicConversionFactor() const;

	/*!
	* \brief Resets the ElectronicConversionFactor attribute to an unset state.
	*
	* This field records the Electron-Conversion Factor for this Detector, as specified by the Manufacturer. The Electron Conversion Factor relates the actual number of electrons generated by the Detector with the digital number associated with each Pixel. It is expressed in electrons/Analog-to-Digital-Unit (ADU). Note that ADU can also be referred to as Digital Number (DN) or Binary Number. It is sometimes referred to as Digital Gain or, in case of CCD cameras as CCD Gain.
	*/
	void resetElectronicConversionFactor();

	/*!
	* \brief Checks whether the ElectronicConversionFactor attribute is present.
	*
	* This field records the Electron-Conversion Factor for this Detector, as specified by the Manufacturer. The Electron Conversion Factor relates the actual number of electrons generated by the Detector with the digital number associated with each Pixel. It is expressed in electrons/Analog-to-Digital-Unit (ADU). Note that ADU can also be referred to as Digital Number (DN) or Binary Number. It is sometimes referred to as Digital Gain or, in case of CCD cameras as CCD Gain.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasElectronicConversionFactor() const;

	/*!
	* \brief Sets the value of the ReadOutNoise attribute.
	*
	* This field captures the Read-out Noise associated with this Detector, as specified by the Manufacturer. Read-out Noise is a constant amount of noise and it includes thermal noise build-up and clock induced charge added by the CCD chip, the readout amplifier and surrounding electronics. It is generally expressed in photo-electrons (i.e., e- root-mean-square).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setReadOutNoise(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the ReadOutNoise attribute.
	*
	* This field captures the Read-out Noise associated with this Detector, as specified by the Manufacturer. Read-out Noise is a constant amount of noise and it includes thermal noise build-up and clock induced charge added by the CCD chip, the readout amplifier and surrounding electronics. It is generally expressed in photo-electrons (i.e., e- root-mean-square).
	*
	* \return The value of the attribute
	*/
	float getReadOutNoise() const;

	/*!
	* \brief Resets the ReadOutNoise attribute to an unset state.
	*
	* This field captures the Read-out Noise associated with this Detector, as specified by the Manufacturer. Read-out Noise is a constant amount of noise and it includes thermal noise build-up and clock induced charge added by the CCD chip, the readout amplifier and surrounding electronics. It is generally expressed in photo-electrons (i.e., e- root-mean-square).
	*/
	void resetReadOutNoise();

	/*!
	* \brief Checks whether the ReadOutNoise attribute is present.
	*
	* This field captures the Read-out Noise associated with this Detector, as specified by the Manufacturer. Read-out Noise is a constant amount of noise and it includes thermal noise build-up and clock induced charge added by the CCD chip, the readout amplifier and surrounding electronics. It is generally expressed in photo-electrons (i.e., e- root-mean-square).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasReadOutNoise() const;

	/*!
	* \brief Sets the value of the ReadNoiseUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setReadNoiseUnit(const Inscoper::NBO::UnitsElectricCurrent_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the ReadNoiseUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsElectricCurrent_TypePtr getReadNoiseUnit() const;

	/*!
	* \brief Resets the ReadNoiseUnit attribute to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetReadNoiseUnit();

	/*!
	* \brief Checks whether the optional ReadNoiseUnit attribute is present.
	*
	* No description available in the XSD standard.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasReadNoiseUnit() const;

	/*!
	* \brief Sets the value of the DetectorNoiseModel attribute.
	*
	* This field records the Noise Model associated with this Detector.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDetectorNoiseModel(const Inscoper::NBO::DetectorNoiseModel_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the DetectorNoiseModel attribute.
	*
	* This field records the Noise Model associated with this Detector.
	*
	* \return The value of the attribute
	*/
	DetectorNoiseModel_TypePtr getDetectorNoiseModel() const;

	/*!
	* \brief Resets the DetectorNoiseModel attribute to an unset state.
	*
	* This field records the Noise Model associated with this Detector.
	*/
	void resetDetectorNoiseModel();

	/*!
	* \brief Checks whether the optional DetectorNoiseModel attribute is present.
	*
	* This field records the Noise Model associated with this Detector.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDetectorNoiseModel() const;

	/*!
	* \brief Sets the value of the DarkCurrentRate attribute.
	*
	* This field records the Dark Current Rate of this Detector as specified by the Manufacturer. The Dark Current Rate is the median current detected in the absence of light. Generally expressed in e-/Pixel/sec.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDarkCurrentRate(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the DarkCurrentRate attribute.
	*
	* This field records the Dark Current Rate of this Detector as specified by the Manufacturer. The Dark Current Rate is the median current detected in the absence of light. Generally expressed in e-/Pixel/sec.
	*
	* \return The value of the attribute
	*/
	float getDarkCurrentRate() const;

	/*!
	* \brief Resets the DarkCurrentRate attribute to an unset state.
	*
	* This field records the Dark Current Rate of this Detector as specified by the Manufacturer. The Dark Current Rate is the median current detected in the absence of light. Generally expressed in e-/Pixel/sec.
	*/
	void resetDarkCurrentRate();

	/*!
	* \brief Checks whether the DarkCurrentRate attribute is present.
	*
	* This field records the Dark Current Rate of this Detector as specified by the Manufacturer. The Dark Current Rate is the median current detected in the absence of light. Generally expressed in e-/Pixel/sec.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDarkCurrentRate() const;

	/*!
	* \brief Sets the value of the DarkCurrentRateUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDarkCurrentRateUnit(const Inscoper::NBO::UnitsElectricCurrent_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the DarkCurrentRateUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsElectricCurrent_TypePtr getDarkCurrentRateUnit() const;

	/*!
	* \brief Resets the DarkCurrentRateUnit attribute to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetDarkCurrentRateUnit();

	/*!
	* \brief Checks whether the optional DarkCurrentRateUnit attribute is present.
	*
	* No description available in the XSD standard.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDarkCurrentRateUnit() const;

	/*!
	* \brief Sets the value of the DynamicRange attribute.
	*
	* This field records the Dynamic Range of this Detector in deciBel (dB).
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDynamicRange(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the DynamicRange attribute.
	*
	* This field records the Dynamic Range of this Detector in deciBel (dB).
	*
	* \return The value of the attribute
	*/
	float getDynamicRange() const;

	/*!
	* \brief Resets the DynamicRange attribute to an unset state.
	*
	* This field records the Dynamic Range of this Detector in deciBel (dB).
	*/
	void resetDynamicRange();

	/*!
	* \brief Checks whether the DynamicRange attribute is present.
	*
	* This field records the Dynamic Range of this Detector in deciBel (dB).
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasDynamicRange() const;

	/*!
	* \brief Sets the value of the DynamicRangeUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setDynamicRangeUnit(const Inscoper::NBO::UnitsRatio_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the DynamicRangeUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsRatio_TypePtr getDynamicRangeUnit() const;

	/*!
	* \brief Resets the DynamicRangeUnit attribute to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetDynamicRangeUnit();

	/*!
	* \brief Checks whether the optional DynamicRangeUnit attribute is present.
	*
	* No description available in the XSD standard.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasDynamicRangeUnit() const;

	/*!
	* \brief Sets the value of the AmbientOperatingTemperature attribute.
	*
	* This field records the Ambient Temperature at which this Detector is designed to operate, according to the Manufacturer.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAmbientOperatingTemperature(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the AmbientOperatingTemperature attribute.
	*
	* This field records the Ambient Temperature at which this Detector is designed to operate, according to the Manufacturer.
	*
	* \return The value of the attribute
	*/
	float getAmbientOperatingTemperature() const;

	/*!
	* \brief Resets the AmbientOperatingTemperature attribute to an unset state.
	*
	* This field records the Ambient Temperature at which this Detector is designed to operate, according to the Manufacturer.
	*/
	void resetAmbientOperatingTemperature();

	/*!
	* \brief Checks whether the AmbientOperatingTemperature attribute is present.
	*
	* This field records the Ambient Temperature at which this Detector is designed to operate, according to the Manufacturer.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasAmbientOperatingTemperature() const;

	/*!
	* \brief Sets the value of the AmbientOperatingTemperatureUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAmbientOperatingTemperatureUnit(const Inscoper::NBO::UnitsTemperature_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the AmbientOperatingTemperatureUnit attribute.
	*
	* No description available in the XSD standard.
	*
	* \return The value of the attribute
	*/
	UnitsTemperature_TypePtr getAmbientOperatingTemperatureUnit() const;

	/*!
	* \brief Resets the AmbientOperatingTemperatureUnit attribute to an unset state.
	*
	* No description available in the XSD standard.
	*/
	void resetAmbientOperatingTemperatureUnit();

	/*!
	* \brief Checks whether the optional AmbientOperatingTemperatureUnit attribute is present.
	*
	* No description available in the XSD standard.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasAmbientOperatingTemperatureUnit() const;

	/*!
	* \brief Sets the value of the AmbientOperatingHumidity attribute.
	*
	* This field records the Ambient Humidity at which this detector is designed to operate, according to the Manufacturer.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAmbientOperatingHumidity(const float& value, bool validate = true);

	/*!
	* \brief Returns the value of the AmbientOperatingHumidity attribute.
	*
	* This field records the Ambient Humidity at which this detector is designed to operate, according to the Manufacturer.
	*
	* \return The value of the attribute
	*/
	float getAmbientOperatingHumidity() const;

	/*!
	* \brief Resets the AmbientOperatingHumidity attribute to an unset state.
	*
	* This field records the Ambient Humidity at which this detector is designed to operate, according to the Manufacturer.
	*/
	void resetAmbientOperatingHumidity();

	/*!
	* \brief Checks whether the AmbientOperatingHumidity attribute is present.
	*
	* This field records the Ambient Humidity at which this detector is designed to operate, according to the Manufacturer.
	*
	* \return true if the attribute has been set, false otherwise
	*/
	bool hasAmbientOperatingHumidity() const;

	/*!
	* \brief Sets the value of the RelayLensRef element.
	*
	* This is a reference to a lens positioned at the mount connecting this detector to the microscope body.
	*
	* \param value The value to set
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setRelayLensRef(const Inscoper::NBO::LensRef_TypePtr& value, bool validate = true);

	/*!
	* \brief Returns the value of the RelayLensRef element.
	*
	* This is a reference to a lens positioned at the mount connecting this detector to the microscope body.
	*
	* \return The value of the element
	*/
	Inscoper::NBO::LensRef_TypePtr getRelayLensRef() const;

	/*!
	* \brief Resets the RelayLensRef element to an unset state.
	*
	* This is a reference to a lens positioned at the mount connecting this detector to the microscope body.
	*/
	void resetRelayLensRef();

	/*!
	* \brief Checks whether the optional RelayLensRef element is present.
	*
	* This is a reference to a lens positioned at the mount connecting this detector to the microscope body.
	*
	* \return true if the optional attribute has been set, false otherwise
	*/
	bool hasRelayLensRef() const;

	/*!
	* \brief Sets the list of AnnotationRef elements.
	*
	* No description available in the XSD standard.
	*
	* \param value The new list of AnnotationRef elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setAnnotationRef_List(const std::vector<Inscoper::NBO::AnnotationRefPtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of AnnotationRef elements.
	*
	* No description available in the XSD standard.
	*
	* \return The list of AnnotationRef elements
	*/
	std::vector<Inscoper::NBO::AnnotationRefPtr> getAnnotationRef_List() const;

	/*!
	* \brief Adds a new AnnotationRef element to this object.
	*
	* No description available in the XSD standard.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToAnnotationRef_List(const Inscoper::NBO::AnnotationRefPtr& value, bool validate = true);

	/*!
	* \brief Clear the list of AnnotationRef.
	*
	* No description available in the XSD standard.
	*/
	void clearAnnotationRef_List();

	/*!
	* \brief Sets the list of WavelengthRange elements.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*
	* \param value The new list of WavelengthRange elements
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void setWavelengthRange_List(const std::vector<Inscoper::NBO::Detector_Type::InlineWavelengthRangePtr>& value, bool validate = true);

	/*!
	* \brief Returns the list of WavelengthRange elements.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*
	* \return The list of WavelengthRange elements
	*/
	std::vector<Inscoper::NBO::Detector_Type::InlineWavelengthRangePtr> getWavelengthRange_List() const;

	/*!
	* \brief Adds a new WavelengthRange element to this object.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*
	* \param value The element to add
	* \param validate If true, validates constraints on value. Default is true.
	*/
	void addToWavelengthRange_List(const Inscoper::NBO::Detector_Type::InlineWavelengthRangePtr& value, bool validate = true);

	/*!
	* \brief Clear the list of WavelengthRange.
	*
	* This element records the Range of Wavelengths this device is designed for, according to the Manufacturer. Multiple of this element may be used.
	*/
	void clearWavelengthRange_List();


private:
	class Impl;
	std::unique_ptr<Impl> pImpl;

	DetectorID_TypePtr ID = nullptr; // Required attribute
	Denomination_TypePtr Name = nullptr; // Optional attribute
	DetectorMount_TypePtr Mount = nullptr; // Optional attribute
	DigitizerType_TypePtr MaxBitDepth = nullptr; // Required attribute
    std::optional<float> QuantumEfficiency; // Required attribute
    std::optional<float> ElectronicConversionFactor; // Required attribute
    std::optional<float> ReadOutNoise; // Required attribute
	UnitsElectricCurrent_TypePtr ReadNoiseUnit = nullptr; // Optional attribute
	DetectorNoiseModel_TypePtr DetectorNoiseModel = nullptr; // Required attribute
    std::optional<float> DarkCurrentRate; // Required attribute
	UnitsElectricCurrent_TypePtr DarkCurrentRateUnit = nullptr; // Optional attribute
    std::optional<float> DynamicRange; // Optional attribute
	UnitsRatio_TypePtr DynamicRangeUnit = nullptr; // Optional attribute
    std::optional<float> AmbientOperatingTemperature; // Optional attribute
	UnitsTemperature_TypePtr AmbientOperatingTemperatureUnit = nullptr; // Optional attribute
    std::optional<float> AmbientOperatingHumidity; // Optional attribute
    Inscoper::NBO::LensRef_TypePtr RelayLensRef = nullptr;
    std::vector<Inscoper::NBO::AnnotationRefPtr> AnnotationRef_List;
    std::vector<Inscoper::NBO::Detector_Type::InlineWavelengthRangePtr> WavelengthRange_List;
};

/*! Shared pointer for Detector_Type*/
typedef std::shared_ptr<Detector_Type> Detector_TypePtr;

} // namespace Inscoper::NBO

#endif // DETECTOR_TYPE_HPP_INCLUDED