Example #1
0
 def testRasterConfiguration(self):
     strPathToTestConfigFile = os.path.join(self.strUnitTestDataHome,
                                            "XSConfiguration_raster.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(self.getPluginName())
     xsDataMOSFLMInput = XSDataMOSFLMInput()
     xsDataMOSFLMBeam = XSDataMOSFLMBeamPosition()
     xsDataMOSFLMBeam.setX(XSDataLength(1.0))
     xsDataMOSFLMBeam.setY(XSDataLength(2.0))
     xsDataMOSFLMInput.setBeam(xsDataMOSFLMBeam)
     xsDataMOSFLMDetector = XSDataMOSFLMDetector()
     xsDataMOSFLMDetector.setType(XSDataString("ADSC"))
     xsDataMOSFLMInput.setDetector(xsDataMOSFLMDetector)
     xsDataMOSFLMInput.setDirectory(XSDataString("/tmp"))
     xsDataMOSFLMInput.setTemplate(XSDataString("testdata_1_###.img"))
     xsDataMOSFLMInput.setWavelength(XSDataWavelength(1.1111))
     xsDataMOSFLMInput.setDistance(XSDataLength(222.22))
     edPluginMOSFLMv10 = self.createPlugin()
     edPluginMOSFLMv10.setScriptExecutable("cat")
     edPluginMOSFLMv10.setConfig(dictItem, _bLocal=True)
     edPluginMOSFLMv10.configure()
     edPluginMOSFLMv10.setXSDataInputClass(XSDataMOSFLMInput)
     edPluginMOSFLMv10.setDataInput(xsDataMOSFLMInput)
     edPluginMOSFLMv10.generateMOSFLMCommands()
     edListCommands = edPluginMOSFLMv10.getListCommandExecution()
     edListCommandsReference = [
         'WAVELENGTH 1.1111', 'DISTANCE 222.22', 'BEAM 1.0 2.0',
         'DETECTOR ADSC', 'DIRECTORY /tmp', 'TEMPLATE testdata_1_###.img',
         'RASTER 15 15 3 3 3'
     ]
     EDAssert.equal(edListCommandsReference, edListCommands,
                    "MOSFLM commands with ratser configured")
 def testRasterConfiguration(self):
     strPathToTestConfigFile = os.path.join(self.strUnitTestDataHome, "XSConfiguration_raster.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(self.getPluginName())
     xsDataMOSFLMInput = XSDataMOSFLMInput()
     xsDataMOSFLMBeam = XSDataMOSFLMBeamPosition()
     xsDataMOSFLMBeam.setX(XSDataLength(1.0))
     xsDataMOSFLMBeam.setY(XSDataLength(2.0))
     xsDataMOSFLMInput.setBeam(xsDataMOSFLMBeam)
     xsDataMOSFLMDetector = XSDataMOSFLMDetector()
     xsDataMOSFLMDetector.setType(XSDataString("ADSC"))
     xsDataMOSFLMInput.setDetector(xsDataMOSFLMDetector)
     xsDataMOSFLMInput.setDirectory(XSDataString("/tmp"))
     xsDataMOSFLMInput.setTemplate(XSDataString("testdata_1_###.img"))
     xsDataMOSFLMInput.setWavelength(XSDataWavelength(1.1111))
     xsDataMOSFLMInput.setDistance(XSDataLength(222.22))
     edPluginMOSFLMv10 = self.createPlugin()
     edPluginMOSFLMv10.setScriptExecutable("cat")
     edPluginMOSFLMv10.setConfig(dictItem, _bLocal = True)
     edPluginMOSFLMv10.configure()
     edPluginMOSFLMv10.setXSDataInputClass(XSDataMOSFLMInput)
     edPluginMOSFLMv10.setDataInput(xsDataMOSFLMInput)
     edPluginMOSFLMv10.generateMOSFLMCommands()
     edListCommands = edPluginMOSFLMv10.getListCommandExecution()
     edListCommandsReference = ['WAVELENGTH 1.1111', 'DISTANCE 222.22', 'BEAM 1.0 2.0', 'DETECTOR ADSC', 'DIRECTORY /tmp', 'TEMPLATE testdata_1_###.img', 'RASTER 15 15 3 3 3']
     EDAssert.equal(edListCommandsReference, edListCommands, "MOSFLM commands with ratser configured")
 def testConfigureOK(self):
     edPluginStrategy = self.createPlugin()
     strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration_ESRF.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
     edPluginStrategy.setConfig(dictItem)
     edPluginStrategy.configure()
 def testConfigureOK(self):
     edPluginControlIndexingv10 = self.createPlugin()
     strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(edPluginControlIndexingv10.getPluginName())
     edPluginControlIndexingv10.setConfig(dictItem)
     edPluginControlIndexingv10.configure()
Example #5
0
    def testSetDataModelInput(self):
        edPluginBest = self.createPlugin()
        edConfigurationGood01 = EDConfiguration(os.path.join(self.m_pyStrDataPath, "XSConfiguration.xml"))
        dictItemGood01 = edConfigurationGood01.get(self.getPluginName())
        edPluginBest.setConfig(dictItemGood01, _bLocal = True)
        edPluginBest.setScriptExecutable("cat")
        edPluginBest.configure()

        from XSDataBestv1_2 import XSDataInputBest
        xsDataInputBest = XSDataInputBest()

        from XSDataCommon import XSDataAbsorbedDoseRate
        from XSDataCommon import XSDataDouble
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataTime
        from XSDataCommon import XSDataFile
        from XSDataCommon import XSDataAngularSpeed
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataAngle
        from XSDataCommon import XSDataBoolean

        xsDataInputBest.setCrystalAbsorbedDoseRate(XSDataAbsorbedDoseRate(0.22E+06))
        xsDataInputBest.setCrystalShape(XSDataDouble(1))
        xsDataInputBest.setCrystalSusceptibility(XSDataDouble(1.5))
        xsDataInputBest.setDetectorType(XSDataString("q210-2x"))
        xsDataInputBest.setBeamExposureTime(XSDataTime(1))
        xsDataInputBest.setBeamMaxExposureTime(XSDataTime(10000))
        xsDataInputBest.setBeamMinExposureTime(XSDataTime(0.1))
        xsDataInputBest.setGoniostatMinRotationWidth(XSDataAngle(0.1))
        xsDataInputBest.setGoniostatMaxRotationSpeed(XSDataAngularSpeed(10))
        xsDataInputBest.setAimedResolution(XSDataDouble(2))
        xsDataInputBest.setAimedRedundancy(XSDataDouble(6.5))
        xsDataInputBest.setAimedCompleteness(XSDataDouble(0.9))
        xsDataInputBest.setAimedIOverSigma(XSDataDouble(3))
        xsDataInputBest.setComplexity(XSDataString("min"))
        xsDataInputBest.setAnomalousData(XSDataBoolean(False))
        fileDirectory = edPluginBest.getWorkingDirectory()

        bestFileContentDat = EDUtilsFile.readFile(os.path.join(self.m_pyStrDataPath, "bestfile.dat"))
        xsDataInputBest.setBestFileContentDat(XSDataString(bestFileContentDat))

        bestFileContentPar = EDUtilsFile.readFile(os.path.join(self.m_pyStrDataPath, "bestfile.par"))
        xsDataInputBest.setBestFileContentPar(XSDataString(bestFileContentPar))

        bestFileContentHKL = EDUtilsFile.readFile(os.path.join(self.m_pyStrDataPath, "bestfile1.hkl"))
        xsDataInputBest.addBestFileContentHKL(XSDataString(bestFileContentHKL))

        xsDataInputBest.exportToFile(self.m_edObtainedInputFile)

        pyStrExpectedInput = self.readAndParseFile (self.m_edReferenceInputFile)
        pyStrObtainedInput = self.readAndParseFile (self.m_edObtainedInputFile)

        xsDataInputExpected = XSDataInputBest.parseString(pyStrExpectedInput)
        xsDataInputObtained = XSDataInputBest.parseString(pyStrObtainedInput)

        EDAssert.equal(xsDataInputExpected.marshal(), xsDataInputObtained.marshal())
        EDUtilsFile.deleteFile(self.m_edObtainedInputFile)

        self.cleanUp(edPluginBest)
 def testConfigureOK(self):
     edPluginStrategy = self.createPlugin()
     strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration_ESRF.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
     edPluginStrategy.setConfig(dictItem)
     edPluginStrategy.configure()
     EDAssert.equal("/opt/pxsoft/ccp4-6.0.2/lib/data", edPluginStrategy.getSymopHome())
 def testConfigureOK(self):
     edPluginStrategy = self.createPlugin()
     strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(),
                                            "XSConfiguration_ESRF.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
     edPluginStrategy.setConfig(dictItem)
     edPluginStrategy.configure()
    def testUpdateChemicalCompositionWithNativeSulfurAtom(self):

        edPluginStrategy = self.createPlugin()
        strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(),
                                               "XSConfiguration_ESRF.xml")
        edConfiguration = EDConfiguration(strPathToTestConfigFile)
        dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
        edPluginStrategy.setConfig(dictItem)
        edPluginStrategy.configure()

        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()
        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataDouble(2))
        xsDataChain.setNumberOfMonomers(XSDataDouble(60))
        xsDataStructure.addChain(xsDataChain)
        xsDataComposition.setStructure(xsDataStructure)
        updatedChemicalComposition = edPluginStrategy.updateChemicalComposition(
            xsDataComposition)
        EDAssert.equal(
            3,
            updatedChemicalComposition.getStructure().getChain()
            [0].getHeavyAtoms().getAtom()[0].getNumberOf().getValue())
        EDAssert.equal(
            "S",
            updatedChemicalComposition.getStructure().getChain()
            [0].getHeavyAtoms().getAtom()[0].getSymbol().getValue())

        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()
        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataDouble(2))
        xsDataChain.setNumberOfMonomers(XSDataDouble(60))
        xsDataAtom1 = XSDataAtom()
        xsDataAtom1.setSymbol(XSDataString("Se"))
        xsDataAtom1.setNumberOf(XSDataDouble(4))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomicComposition.addAtom(xsDataAtom1)
        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)
        xsDataStructure.addChain(xsDataChain)
        xsDataComposition.setStructure(xsDataStructure)
        updatedChemicalComposition = edPluginStrategy.updateChemicalComposition(
            xsDataComposition)
        heavyAtoms = updatedChemicalComposition.getStructure().getChain(
        )[0].getHeavyAtoms().getAtom()
        for heavyAtom in heavyAtoms:
            self.unitTest(heavyAtom.getSymbol().getValue() + " : " +
                          str(heavyAtom.getNumberOf().getValue()))
            if (heavyAtom.getSymbol().getValue() == "S"):
                EDAssert.equal(3, heavyAtom.getNumberOf().getValue())
    def testConfigureOK(self):
        edPluginRaddose = self.createPlugin()
        edConfigurationGood01 = EDConfiguration(os.path.join(self.strDataPath, "XSConfiguration.xml"))
        dictItemGood01 = edConfigurationGood01.get(self.getPluginName())
        edPluginRaddose.setConfig(dictItemGood01, _bLocal = True)
        edPluginRaddose.setScriptExecutable("cat")
        edPluginRaddose.configure()
        EDAssert.equal("/bin/bash", edPluginRaddose.getScriptShell())
        EDAssert.equal("cat", edPluginRaddose.getScriptExecutable())
        EDAssert.equal("/opt/pxsoft/ccp4-6.0.2/include/ccp4.setup-bash.orig", edPluginRaddose.getSetupCCP4())
        EDAssert.equal("Verion of Raddose to be tested", edPluginRaddose.getStringVersion())
        #EDAssert.equal(600, edPluginMessage.getTimeOut())

        self.cleanUp(edPluginRaddose)
 def testGenerateMOSFLMIntegrationCommands(self):
     strPathToTestConfigFile = os.path.join(self.strUnitTestDataHome, "XSConfiguration_unitTest.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(self.getPluginName())
     pluginIntegration = self.createPlugin()
     pluginIntegration.setScriptExecutable("cat")
     pluginIntegration.setConfig(dictItem, _bLocal = True)
     pluginIntegration.configure()
     strXMLInputData = self.readAndParseFile (self.strReferenceDataInputFile)
     pluginIntegration.setDataInput(strXMLInputData)
     pluginIntegration.generateMOSFLMCommands()
     listCommandExecution = pluginIntegration.getListCommandExecution()
     listCommandReference = ['WAVELENGTH 0.934', 'DISTANCE 198.440994', 'BEAM 102.478996 104.8862', 'DETECTOR ADSC', 'DIRECTORY ' + self.strDataImagePath, 'TEMPLATE ref-testscale_1_###.img', 'SYMMETRY P222', 'MATRIX ' + pluginIntegration.getScriptBaseName() + '_matrix.mat', 'MOSAIC 0.75', 'HKLOUT process_1_1.mtz', 'PROCESS 1 TO 1 START 0.000000 ANGLE 1.000000', 'BEST ON', 'GO', 'BEST OFF']
     EDAssert.equal(listCommandReference, listCommandExecution)
 def testSetDataInput(self):
     edPluginControlIntegrationv10 = self.createPlugin()
     strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(edPluginControlIntegrationv10.getPluginName())
     edPluginControlIntegrationv10.setConfig(dictItem)
     edPluginControlIntegrationv10.configure()
     xmlInputReference = self.readAndParseFile(self.strReferenceInputFile)
     from XSDataMXv1 import XSDataIntegrationInput
     xsDataIntegrationInputReference = XSDataIntegrationInput.parseString(xmlInputReference)
     edPluginControlIntegrationv10.setDataInput(xmlInputReference)
     xsDataIntegrationv10Input = edPluginControlIntegrationv10.getDataInput()
     EDAssert.equal(xsDataIntegrationInputReference.marshal(), xsDataIntegrationv10Input.marshal())
     self.cleanUp(edPluginControlIntegrationv10)
Example #12
0
 def testConfigureOK(self):
     edPluginBest = self.createPlugin()
     edConfigurationGood01 = EDConfiguration(os.path.join(self.m_pyStrDataPath, "XSConfiguration.xml"))
     dictItemGood01 = edConfigurationGood01.get(self.getPluginName())
     edPluginBest.setConfig(dictItemGood01, _bLocal = True)
     edPluginBest.setScriptExecutable("cat")
     edPluginBest.configure()
     EDAssert.equal("/bin/bash", edPluginBest.getScriptShell())
     EDAssert.equal("cat", edPluginBest.getScriptExecutable())
     EDAssert.equal("/opt/pxsoft/ccp4-6.0.2/include/ccp4.setup-bash.orig", edPluginBest.getSetupCCP4())
     EDAssert.equal("Version of Best to be tested", edPluginBest.getStringVersion())
     EDAssert.equal(600, edPluginBest.getTimeOut())
     EDAssert.equal("/home/sweet/home", edPluginBest.getBestHome())
     EDAssert.equal("export besthome=/home/sweet/home", edPluginBest.getCommandBestHome())
     self.cleanUp(edPluginBest)
    def testSetDataInput(self):
        edPluginControlIndexingv10 = self.createPlugin()
        strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration.xml")
        edConfiguration = EDConfiguration(strPathToTestConfigFile)
        dictItem = edConfiguration.get(edPluginControlIndexingv10.getPluginName())
        edPluginControlIndexingv10.setConfig(dictItem)
        edPluginControlIndexingv10.configure()

        xmlInput = self.readAndParseFile(self.__strReferenceInputFile)
        edPluginControlIndexingv10.setDataInput(xmlInput)

        xsDataIndexingv01Input = edPluginControlIndexingv10.getDataInput()

        xsDataIndexingInputReference = XSDataIndexingInput.parseString(xmlInput)
        EDAssert.equal(xsDataIndexingInputReference.marshal(), xsDataIndexingv01Input.marshal())

        self.cleanUp(edPluginControlIndexingv10)
    def testConfigureOK(self):
        edPluginRaddose = self.createPlugin()
        edConfigurationGood01 = EDConfiguration(
            os.path.join(self.strDataPath, "XSConfiguration.xml"))
        dictItemGood01 = edConfigurationGood01.get(self.getPluginName())
        edPluginRaddose.setConfig(dictItemGood01, _bLocal=True)
        edPluginRaddose.setScriptExecutable("cat")
        edPluginRaddose.configure()
        EDAssert.equal("/bin/bash", edPluginRaddose.getScriptShell())
        EDAssert.equal("cat", edPluginRaddose.getScriptExecutable())
        EDAssert.equal("/opt/pxsoft/ccp4-6.0.2/include/ccp4.setup-bash.orig",
                       edPluginRaddose.getSetupCCP4())
        EDAssert.equal("Verion of Raddose to be tested",
                       edPluginRaddose.getStringVersion())
        #EDAssert.equal(600, edPluginMessage.getTimeOut())

        self.cleanUp(edPluginRaddose)
Example #15
0
 def testConfigureOK(self):
     edPluginBest = self.createPlugin()
     edConfigurationGood01 = EDConfiguration(
         os.path.join(self.strDataPath, "XSConfiguration.xml"))
     dictItemGood01 = edConfigurationGood01.get(self.getPluginName())
     edPluginBest.setConfig(dictItemGood01, _bLocal=True)
     edPluginBest.setScriptExecutable("cat")
     edPluginBest.configure()
     EDAssert.equal("/bin/bash", edPluginBest.getScriptShell())
     EDAssert.equal("cat", edPluginBest.getScriptExecutable())
     EDAssert.equal("/opt/pxsoft/ccp4-6.0.2/include/ccp4.setup-bash.orig",
                    edPluginBest.getSetupCCP4())
     EDAssert.equal("Version of Best to be tested",
                    edPluginBest.getStringVersion())
     EDAssert.equal(600, edPluginBest.getTimeOut())
     EDAssert.equal("/home/sweet/home", edPluginBest.getBestHome())
     EDAssert.equal("export besthome=/home/sweet/home",
                    edPluginBest.getCommandBestHome())
     self.cleanUp(edPluginBest)
    def testUpdateChemicalCompositionWithNativeSulfurAtom(self):

        edPluginStrategy = self.createPlugin()
        strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration_ESRF.xml")
        edConfiguration = EDConfiguration(strPathToTestConfigFile)
        dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
        edPluginStrategy.setConfig(dictItem)
        edPluginStrategy.configure()

        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()
        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataDouble(2))
        xsDataChain.setNumberOfMonomers(XSDataDouble(60))
        xsDataStructure.addChain(xsDataChain)
        xsDataComposition.setStructure(xsDataStructure)
        updatedChemicalComposition = edPluginStrategy.updateChemicalComposition(xsDataComposition)
        EDAssert.equal(3, updatedChemicalComposition.getStructure().getChain()[0].getHeavyAtoms().getAtom()[0].getNumberOf().getValue())
        EDAssert.equal("S", updatedChemicalComposition.getStructure().getChain()[0].getHeavyAtoms().getAtom()[0].getSymbol().getValue())

        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()
        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataDouble(2))
        xsDataChain.setNumberOfMonomers(XSDataDouble(60))
        xsDataAtom1 = XSDataAtom()
        xsDataAtom1.setSymbol(XSDataString("Se"))
        xsDataAtom1.setNumberOf(XSDataDouble(4))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomicComposition.addAtom(xsDataAtom1)
        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)
        xsDataStructure.addChain(xsDataChain)
        xsDataComposition.setStructure(xsDataStructure)
        updatedChemicalComposition = edPluginStrategy.updateChemicalComposition(xsDataComposition)
        heavyAtoms = updatedChemicalComposition.getStructure().getChain()[0].getHeavyAtoms().getAtom()
        for heavyAtom in heavyAtoms:
            self.unitTest(heavyAtom.getSymbol().getValue() + " : " + str(heavyAtom.getNumberOf().getValue()))
            if(heavyAtom.getSymbol().getValue() == "S"):
                EDAssert.equal(3, heavyAtom.getNumberOf().getValue())
 def testGenerateMOSFLMIntegrationCommands(self):
     strPathToTestConfigFile = os.path.join(self.strUnitTestDataHome,
                                            "XSConfiguration_unitTest.xml")
     edConfiguration = EDConfiguration(strPathToTestConfigFile)
     dictItem = edConfiguration.get(self.getPluginName())
     pluginIntegration = self.createPlugin()
     pluginIntegration.setScriptExecutable("cat")
     pluginIntegration.setConfig(dictItem, _bLocal=True)
     pluginIntegration.configure()
     strXMLInputData = self.readAndParseFile(self.strReferenceDataInputFile)
     pluginIntegration.setDataInput(strXMLInputData)
     pluginIntegration.generateMOSFLMCommands()
     listCommandExecution = pluginIntegration.getListCommandExecution()
     listCommandReference = [
         'WAVELENGTH 0.934', 'DISTANCE 198.440994',
         'BEAM 102.478996 104.8862', 'DETECTOR ADSC',
         'DIRECTORY ' + self.strDataImagePath,
         'TEMPLATE ref-testscale_1_###.img', 'SYMMETRY P222',
         'MATRIX ' + pluginIntegration.getScriptBaseName() + '_matrix.mat',
         'MOSAIC 0.75', 'HKLOUT process_1_1.mtz',
         'PROCESS 1 TO 1 START 0.000000 ANGLE 1.000000', 'BEST ON', 'GO',
         'BEST OFF'
     ]
     EDAssert.equal(listCommandReference, listCommandExecution)
Example #18
0
class EDPlugin(EDAction):
    """
    This is the EDNA plugin main class
    An EDNA plugin class:
        - is a configurable entity
        - has a base name (<date>-<random number>-<base name>)
        - handles input/output data (setter, getter, checker)
        - has warning and error messages
        - has a base and a working directory (both are configurable)
        The working directory is the folder from which the plugin is launched
        and should contain all associated files with the plugin execution (edna xml input/output, 3rd party output files)
        The base directory is the parent directory of the working directory. 
        Example: the working directory of a control plugin is the base directory of the plugins that it invokes,
        i.e. the plugins working directories has the control plugin working directory as parent.
    - defines the method that generates an executive summary (user-related output summary) that sub-classes should implement
    """
    CONF_BASE_DIR_LABEL = "baseDirectory"
    CONF_WORKING_DIR_LABEL = "workingDirectory"
    CONF_TIME_OUT = "timeOut"
    CONF_WRITE_XML_INPUT_OUTPUT = "writeXMLInputOutput"
    CONF_WRITE_XML_OUTPUT = "writeXMLOutput"
    CONF_WRITE_XML_INPUT = "writeXMLInput"

    def __init__ (self):
        """
        Initializes plugin related attributes described above
        """
        EDAction.__init__(self)
        self.__xsPluginItem = None
        self.__dictXSDataInputClass = {}
        self.__dictXSDataInput = {}
        self.__dictXSDataOutput = {}
        self.__strDefaultInputDataKey = "defaultInputData"
        self.__strDefaultOutputDataKey = "defaultOutputData"
        self.__edSlotExportDataOutput = EDSlot()
        self.__strBaseDirectory = None
        self.__strWorkingDirectory = None
        self.__strBaseName = None
        self.__listExecutiveSummaryLines = []
        self.__strExecutiveSummarySeparator = "-" * 80
        self.__listErrorMessages = []
        self.__listWarningMessages = []
        self.__isRequiredToHaveConfiguration = False
        self.__bWriteDataXMLInputOutput = True
        self.__bWriteDataXMLOutput = True
        self.__bWriteDataXMLInput = True
        self.__strPluginId = "%s-%08i" % (self.getClassName(), self.getId())
        self.strPathDataInput = None
        self.strPathDataOutput = None
        self.__bUseWarningInsteadOfError = False
        self.__edConfiguration = EDConfigurationStatic()


    def preProcess(self, _edObject=None):
        """
        Writes xml data input in the working dir (if required)
        Connects a slot for generating the executive summary after the plugin execution
        Connects a slot for checking output data to the finally process
        Initialize the base directory
        Configures the plugin
        Checks the input data
        """
        EDAction.preProcess(self, _edObject)
        self.DEBUG("EDPlugin.preProcess")
        self.connectPostProcess(self.exportDataOutput)
        if self.__bWriteDataXMLInputOutput:
            if self.__bWriteDataXMLInput:
                self.connectPreProcess(self.writeDataInput)
        self.connectPostProcess(self.generateExecutiveSummary)
        self.connectFinallyProcess(self.checkDataOutput)
        if (self.__strBaseName is None):
            self.setBaseName(self.createBaseName())
        EDStatus.tellRunning(self.__strPluginId)
        self.connectFinallyProcess(self.tellFinished)
        self.checkParameters()


    def tellFinished(self, _edObject=None):
        """
        Tell EDStatus that the plugin has finished, either in success either in error 
        """
        if self.isFailure():
            EDStatus.tellFailure(self.__strPluginId)
        else:
            EDStatus.tellSuccess(self.__strPluginId)

    def checkDataOutput(self, _edObject=None):
        """
        Checks if output data is available, if not issues a warning and sets an empty XSDataResult as output data
        Writes xml data output in the working dir (if required)
        """
        EDAction.finallyProcess(self, _edObject)
        if self.__dictXSDataOutput == {}:
            strWarningMessage = "Output data for plugin %s not set, using XSDataResult as output" % self.getPluginName()
            self.WARNING(strWarningMessage)
            self.addWarningMessage(strWarningMessage)
            self.setDataOutput(XSDataResult())
        if self.__bWriteDataXMLInputOutput:
            if self.__bWriteDataXMLOutput:
                self.writeDataOutput()


    def synchronize(self):
        """
        This method calls EDAction.synchronize and if a time-out occurs an error message
        is added to the list of error messages.
        """
        EDAction.synchronize(self)
        if self.isTimeOut():
            strErrorMessage = "Timeout when waiting for %s to terminate." % self.getClassName()
            self.addErrorMessage(strErrorMessage)

    def getConfig(self):
        """
        Gets the Plugin Configuration as a dictionary
        """
        # self.DEBUG("EDPlugin.getConfig")
        return self.__edConfiguration.get(self.getPluginName(), {})

    def setConfig(self, _dict, _bLocal=False):
        """
        Receives a dictionary (Plugin Configuration) from the application.
        """
        self.DEBUG("EDPlugin.setConfiguration")
        if _bLocal:
            self.__edConfiguration = EDConfiguration()
        if _dict is not None:
            self.__edConfiguration[self.getPluginName()] = _dict
        else:
            self.__edConfiguration[self.getPluginName()] = {}
    config = property(getConfig, setConfig)


    def configure(self):
        """
        Should be overridden by the Final Plugin If needed
        This method should set its proper members attributes from a Plugin configuration Object
        """
        self.DEBUG("EDPlugin.configure : plugin name = %s, EDNA_SITE = %s" % (self.getPluginName(), EDUtilsPath.EDNA_SITE))

        # set Timeout if different from default one
        if self.getTimeOut() == self.getDefaultTimeOut():
            # Try to get time out from plugin configuration
            iTimeOut = self.config.get(EDPlugin.CONF_TIME_OUT, None)
            if iTimeOut is not None:
                self.DEBUG("EDPlugin.configure: Setting time out to %d s from plugin configuration." % iTimeOut)
                self.setTimeOut(iTimeOut)
        else:
            self.DEBUG("EDPlugin.configure: timeout already set before plugin is configured.")
        # Base directory
        strBaseDirectory = self.getBaseDirectory()
        if (strBaseDirectory is None):
            # Try to get base directory from plugin configuration
            strBaseDirectory = self.config.get(EDPlugin.CONF_BASE_DIR_LABEL, None)
            if(strBaseDirectory is None):
                # Try to get working directory from environment variable
                strBaseDirectory = os.environ.get("EDNA_BASE_DIRECTORY")
                if (strBaseDirectory is None):
                    self.DEBUG("EDPlugin.configure: Using current base directory as working directory.")
                    strBaseDirectory = os.getcwd()
                else:
                    self.DEBUG("EDPlugin.configure: Setting base directory from $EDNA_WORKING_DIRECTORY.")
            else:
                if (strBaseDirectory == "."):
                    self.DEBUG("EDPlugin.configure: Using current base directory as working directory.")
                    strBaseDirectory = os.getcwd()
                else:
                    strBaseDirectory = os.path.abspath(strBaseDirectory)
                    self.DEBUG("EDPlugin.configure: Setting base directory from plugin configuration.")
            self.setBaseDirectory(strBaseDirectory)
        else:
            self.DEBUG("EDPlugin.configure: Base directory already set before plugin is configured.")
        # Working directory
        strWorkingDirectory = self.getWorkingDirectory()
        if (strWorkingDirectory is None):
            # Try to get working directory from plugin configuration
            strWorkingDirectory = self.config.get(EDPlugin.CONF_WORKING_DIR_LABEL, None)
            if(strWorkingDirectory is not None):
                self.DEBUG("EDPlugin.configure: Setting working directory from plugin configuration.")
            else:
                self.DEBUG("EDPlugin.configure: Setting working directory as base directory + base name.")
                strWorkingDirectory = os.path.join(self.getBaseDirectory(), self.getBaseName())
            self.setWorkingDirectory(strWorkingDirectory)
        else:
            self.DEBUG("EDPlugin.configure: Working directory already set before plugin is configured.")
        #
        self.__bWriteDataXMLInputOutput = bool(self.config.get(self.CONF_WRITE_XML_INPUT_OUTPUT, True))
        self.__bWriteDataXMLOutput = bool(self.config.get(self.CONF_WRITE_XML_OUTPUT, True))
        self.__bWriteDataXMLInput = bool(self.config.get(self.CONF_WRITE_XML_INPUT, True))


    def execute(self, _edObject=None):
        # Configure the plugin before starting it's thread
        self.configure()
        EDAction.execute(self, _edObject)


    def checkParameters(self):
        """
        Should be overridden by the Final Plugin If needed
        This method should check that the data input are consistent
        """
        self.DEBUG("EDPlugin.checkParameters")


    def setXSDataInputClass(self, _xsDataInputClass, _strDataInputKey=None):
        """
        This method should be called in the constructor of the derived plugins
        in order to set the XSData type of the input data, e.g. XSDataInputXXX
        """
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInputClass.keys()):
            strErrorMessage = "ERROR: " + self.getPluginName() + ".setXSDataInputClass, Data Input Class already defined for key: " + strDataInputKey
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)
        self.__dictXSDataInputClass[ strDataInputKey ] = _xsDataInputClass


    def getXSDataInputClass(self, _strDataInputKey=None):
        """
        Returns the XSData type of the input data.
        """
        pyXSDataInputClass = None
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInputClass.keys()):
            pyXSDataInputClass = self.__dictXSDataInputClass[ strDataInputKey ]
        return pyXSDataInputClass


    def setDataInput(self, _oDataInput, _strDataInputKey=None):
        """
        Sets the plugin input data.
        _oDataInput could be either an String XML or an XSData object.

        The input data is stored in a dictionary with the key _strDataInputKey.
        If the key is not provided a default key is used.

        If not data input class is defined for the key an exception is raised.
        
        If the key is not the default key, the data object is added to a list which 
        might contain already stored object(s).
        
        If _oDataInput is None the list corresponding to a keyword is deleted.
        """
        self.DEBUG("EDPlugin.setDataInput")
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        # Allow for None input
        if (_oDataInput is None):
            self.DEBUG("EDPlugin.setDataInput: Data input is None")
            self.__dictXSDataInput[ strDataInputKey ] = []
        elif (self.getXSDataInputClass(strDataInputKey) is None):
            strErrorMessage = "ERROR: " + self.getPluginName() + ".setDataInput, Data Input Class not defined for key: " + strDataInputKey
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)
        else:
            # Check the type
            xsDataInput = None
            if isinstance(_oDataInput, (str, unicode)):
                self.DEBUG("EDPlugin.setDataInput: Input Data is string ")
                xsDataInput = self.getXSDataInputClass(strDataInputKey).parseString(_oDataInput)
            elif (isinstance(_oDataInput, self.getXSDataInputClass(strDataInputKey))):
                self.DEBUG("EDPlugin.setDataInput: Input Data is of type " + str(_oDataInput.__class__))
                xsDataInput = _oDataInput
            else:
                strErrorMessage = "ERROR: %s.setDataInput, wrong data type %r for data input key: %s, expected XML string or %r" % \
                                  (self.getPluginName(), _oDataInput.__class__, strDataInputKey, self.getXSDataInputClass(strDataInputKey))
                self.error(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                raise RuntimeError(strErrorMessage)
            # Add the object to a list if its key is not the default key
            if (strDataInputKey != self.__strDefaultInputDataKey) :
                # Check if there's already a list stored
                if (not strDataInputKey in self.__dictXSDataInput.keys()):
                    self.__dictXSDataInput[ strDataInputKey ] = []
                self.__dictXSDataInput[ strDataInputKey ].append(xsDataInput)
            else:
                self.__dictXSDataInput[ strDataInputKey ] = xsDataInput


    def hasDataInput(self, _strDataInputKey=None):
        """
        Returns True if the plugin has Input Data for a particular key.
        If the key is not provided a default key is used.
        """
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInput.keys()):
            return True
        else:
            return False


    def getDataInput(self, _strDataInputKey=None):
        """
        Returns the Plugin Input Data for a particular key.
        If the key is not provided a default key is used.
        """
        oValue = None
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInput.keys()):
            oValue = self.__dictXSDataInput[ strDataInputKey ]
        else:
            strErrorMessage = self.getPluginName() + ".getDataInput, no input data defined for key: " + strDataInputKey
            self.warning(strErrorMessage)
            self.addWarningMessage(strErrorMessage)
        return oValue


    def delDataInput(self, _strDataInputKey=None):
        """
        Deletes the data input for a particular key.
        If the key is not provided a default key is used.
        """
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInput.keys()):
            self.__dictXSDataInput[ strDataInputKey ] = None
        else:
            strErrorMessage = self.getPluginName() + ".delDataInput, no input data defined for key: " + strDataInputKey
            self.warning(strErrorMessage)
            self.addWarningMessage(strErrorMessage)

    # Property for dataInput
    dataInput = property(getDataInput, setDataInput, delDataInput, "Property for dataInput")


    def setDataOutput(self, _xsDataOutput, _strDataOutputKey=None):
        """
        Sets the plugin output data for a particular key.
        If the key is not provided a default key is used.

        If the key is already defined in the dictionary, the corresponding
        data object is added to a list which contains the already stored object(s).
        """
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        # Add the object to a list if its key not the default key
        if (strDataOutputKey == self.__strDefaultOutputDataKey):
            self.__dictXSDataOutput[ strDataOutputKey ] = _xsDataOutput
        else:
            # Check if the _xsDataoutput object is already a list
            if (type(_xsDataOutput) == list):
                self.__dictXSDataOutput[ strDataOutputKey ] = _xsDataOutput
            else:
                # Check if the stored object contains already a list
                if (not strDataOutputKey in self.__dictXSDataOutput.keys()):
                    self.__dictXSDataOutput[ strDataOutputKey ] = []
                self.__dictXSDataOutput[ strDataOutputKey ].append(_xsDataOutput)


    def getDataOutput(self, _strDataOutputKey=None):
        """
        Returns the Plugin Output Data
        """
        oValue = None
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        if (strDataOutputKey in self.__dictXSDataOutput.keys()):
            oValue = self.__dictXSDataOutput[ strDataOutputKey ]
        return oValue


    def hasDataOutput(self, _strDataOutputKey=None):
        """
        Returns True if the plugin has the specified Output Data
        """
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        if (strDataOutputKey in self.__dictXSDataOutput.keys()):
            return True
        else:
            return False


    def delDataOutput(self, _strDataOutputKey=None):
        """
        Deletes the data output for a particular key.
        If the key is not provided a default key is used.
        """
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        if (strDataOutputKey in self.__dictXSDataOutput.keys()):
            self.__dictXSDataOutput[ strDataOutputKey ] = None
        else:
            strErrorMessage = self.getPluginName() + ".delDataOutput, no output data defined for key: " + _strDataOutputKey
            self.warning(strErrorMessage)
            self.addWarningMessage(strErrorMessage)

    # Property for dataOutput
    dataOutput = property(getDataOutput, setDataOutput, delDataOutput, "Property for dataOutput")


    def exportDataOutput(self, _edPlugin=None):
        """
        Deprecated
        Exports the Plugin Output Data to slot
        """
        self.DEBUG("EDPlugin.exportDataOutput")
        self.__edSlotExportDataOutput.call(self.__dictXSDataOutput)


    def connectExportDataOutput(self, _oMethod):
        """
        Deprecated
        """
        self.synchronizeOn()
        if (_oMethod != None):
            self.__edSlotExportDataOutput.connect(_oMethod)
        self.synchronizeOff()


    def generateExecutiveSummary(self, _edPlugin):
        """
        This method, which should be implemented by sub-classes, generates an executive summary (user-related output summary).
        """
        self.DEBUG("EDPlugin.generateExecutiveSummary")


    def addErrorMessage(self, _strErrorMessage):
        """
        Adds an error message to the error messages list
        """
        self.__listErrorMessages.append(_strErrorMessage)


    def getListOfErrorMessages(self):
        """
        Returns the error messages list
        """
        return self.__listErrorMessages


    def addWarningMessage(self, _strWarningMessage):
        """
        Adds a warning message to the warning messages list
        """
        self.DEBUG("EDPlugin.addWarningMessage : " + _strWarningMessage)
        self.__listWarningMessages.append(_strWarningMessage)


    def getListOfWarningMessages(self):
        """
        Returns the warning messages list
        """
        return self.__listWarningMessages


    def writeDataInput(self, _edObject=None):
        """
        Writes the input data object(s) into a working dir xml file 
        """
        self.DEBUG("EDPlugin.writeDataInput")
        strBasename = os.path.join(self.getWorkingDirectory(), self.compactPluginName(self.getPluginName()))
        for strKey in self.__dictXSDataInput.keys():
            if (strKey == self.__strDefaultInputDataKey):  # "Old" style
                xsDataInput = self.__dictXSDataInput[ self.__strDefaultInputDataKey ]
                self.strPathDataInput = strBasename + "_dataInput.xml"
                EDUtilsFile.writeFile(self.strPathDataInput, xsDataInput.marshal())
            else:  # We have a list of objects
                listXSDataInput = self.__dictXSDataInput[ strKey ]
                for iIndex, xsDataInput in enumerate(listXSDataInput):
                    strPathDataInput = "%s_%s_%d_dataInput.xml" % (strBasename, strKey, iIndex)
                    EDUtilsFile.writeFile(strPathDataInput, xsDataInput.marshal())


    def writeDataOutput(self, _edObject=None):
        """
        Writes the output data object(s) into a working dir xml file 
        """
        self.DEBUG("EDPlugin.writeDataOutput")
        for strKey in self.__dictXSDataOutput.keys():
            if (strKey == self.__strDefaultOutputDataKey):  # "Old" style
                xsDataOutput = self.__dictXSDataOutput[ self.__strDefaultOutputDataKey ]
                if (xsDataOutput is not None):
                    self.strPathDataOutput = os.path.join(self.getWorkingDirectory(), self.compactPluginName(self.getPluginName()) + "_dataOutput.xml")
                    EDUtilsFile.writeFile(self.strPathDataOutput, xsDataOutput.marshal())
            else:
                listXSDataOutput = self.__dictXSDataOutput[ strKey ]
                for iIndex, xsDataOutput in enumerate(listXSDataOutput):
                    if (xsDataOutput is not None):
                        strPathDataOutput = os.path.join(self.getWorkingDirectory(), self.compactPluginName(self.getPluginName()) + "_" + strKey + "_%d_dataOutput.xml" % iIndex)
                        EDUtilsFile.writeFile(strPathDataOutput, xsDataOutput.marshal())


    def getBaseName(self):
        """
        Returns the plugin base name
        """
        if (self.__strBaseName is None):
            self.__strBaseName = self.createBaseName()
        return self.__strBaseName


    def setBaseName(self, _strBaseName):
        """
        Sets the plugin base name
        """
        self.__strBaseName = self.compactPluginName(_strBaseName)
        self.setName(self.__strBaseName)
        # Create the directory baseDirectory/baseName which will be used as working directory
        strWorkingDirPath = os.path.join(self.getBaseDirectory(), self.__strBaseName)
        if not os.path.isdir(strWorkingDirPath):
            os.mkdir(strWorkingDirPath)
        self.setWorkingDirectory(strWorkingDirPath)


    def createBaseName(self):
        """
        Generates the plugin base name: (<prefix>-<object ID>)
        """
        # First try to use global instance ID from EDObject
        strBaseName = "%s-%08d" % (self.compactPluginName(self.getPluginName()), self.getId())
        strBaseDir = os.path.join(self.getBaseDirectory(), strBaseName)
        # Try to create the directory...
        try:
            os.mkdir(strBaseDir)
        except Exception as strErrorDetail:
            self.error("EDPlugin.createBaseName: Could not create base directory %s because of %s" % (strBaseDir, strErrorDetail))
            self.warning("EDPlugin.createBaseName: Trying to create alternative base directory...")
            self.writeErrorTrace()
            strTempDir = tempfile.mkdtemp(prefix=strBaseName, dir=self.getBaseDirectory())
            os.chmod(strTempDir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
            strBaseName = os.path.split(strTempDir)[1]
            strBaseDir = os.path.join(self.getBaseDirectory(), strBaseName)
            self.warning("EDPlugin.createBaseName: Alternative base directory created: %s" % strBaseDir)
        self.DEBUG("EDPlugin.createBaseName : Directory created = " + strBaseDir)
        return strBaseName


    def compactPluginName(self, _pluginName):
        """
        The prefix is constructed from the plugin name with the following renaming:
        EDPlugin -> ""
        EDPluginExec -> ""
        EDPluginControl -> "Control"
        """
        strCompactName = _pluginName
        if (strCompactName.startswith("EDPluginExec")):
            strCompactName = strCompactName[12:]
        elif (strCompactName.startswith("EDPluginControl")):
            strCompactName = strCompactName[8:]
        elif (strCompactName.startswith("EDPlugin")):
            strCompactName = strCompactName[8:]
        return strCompactName


    def setBaseDirectory(self, _strBaseDirectory):
        """
        Sets the plugin base directory
        """
        self.DEBUG("EDPlugin.setBaseDirectory : " + _strBaseDirectory)
        if (not os.path.isdir(_strBaseDirectory)):
            self.DEBUG("EDPlugin.setBaseDirectory: base directory %s does dot yet exist! Creating it." % _strBaseDirectory)
            os.mkdir(_strBaseDirectory)
        self.__strBaseDirectory = _strBaseDirectory


    def getBaseDirectory(self):
        """
        Returns the plugin base directory
        """
        self.DEBUG("EDPlugin.getBaseDirectory : %s" % self.__strBaseDirectory)
        if (self.__strBaseDirectory is None):
            self.__strBaseDirectory = os.getcwd()
        return self.__strBaseDirectory


    def setWorkingDirectory(self, _strWorkingDirectory):
        """
        Sets the plugin working directory
        """
        self.DEBUG("EDPlugin.setWorkingDirectory : " + _strWorkingDirectory)
        self.__strWorkingDirectory = _strWorkingDirectory
        if not os.path.isdir(_strWorkingDirectory):
            self.DEBUG("EDPlugin.setWorkingDirectory, creating working directory %s." % _strWorkingDirectory)
            os.mkdir(self.__strWorkingDirectory)


    def getWorkingDirectory(self):
        """
        Returns the plugin base directory
        """
        self.DEBUG("EDPlugin.getWorkingDirectory : %s" % self.__strWorkingDirectory)
        returnValue = None
        if (self.__strWorkingDirectory is not None):
            returnValue = self.__strWorkingDirectory
        return returnValue


    def checkMandatoryParameters(self, _xsData, _strParamName):
        """
        Checks that a mandatory parameter exists in the data
        If not, an error message is added in the list and the plugin fails
        """
        if _xsData is None or (hasattr(_xsData, '__len__') and len(_xsData) == 0):
            strErrorMessage = "%s: input parameter is missing: %s" % (self.getPluginName(), _strParamName)
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)


    def checkImportantParameters(self, _xsData, _strParamName):
        """
        Checks that a specific parameter exists in the data
        If not, a warning message is added in the list
        """
        if(_xsData == None):
            strWarningMessage = "%s: input parameter is missing: %s" % (self.getPluginName(), _strParamName)
            self.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)


    def addExecutiveSummaryLine(self, _strExecutiveSummaryLine):
        """
        Add a line to the executive summary string.
        """
        self.DEBUG("EDPlugin.addExecutiveSummaryLine : %r" % _strExecutiveSummaryLine)
        strExecutiveSummaryLine = _strExecutiveSummaryLine
        if (not strExecutiveSummaryLine == ""):
            if (strExecutiveSummaryLine[-1] == "\n"):
                strExecutiveSummaryLine = strExecutiveSummaryLine[:-1]
        self.__listExecutiveSummaryLines.append(strExecutiveSummaryLine)


    def addExecutiveSummarySeparator(self, _strSeparator=None):
        """
        Adds a separator to split the executive summary into different parts
        Default is a dotted line
        """
        strSeparator = _strSeparator
        if (strSeparator is None):
            strSeparator = self.__strExecutiveSummarySeparator
        # Check that the last line doesn't already contain a separator
        if self.__listExecutiveSummaryLines != []:
            if self.__listExecutiveSummaryLines[-1] != strSeparator:
                self.addExecutiveSummaryLine(strSeparator)
        else:
            self.addExecutiveSummaryLine(strSeparator)


    def getListExecutiveSummaryLines(self):
        """
        Returns the executive summary (list of text lines)
        """
        return self.__listExecutiveSummaryLines


    def verboseScreenExecutiveSummary(self):
        """
        Prints the executive summary on the screen
        """
        for line in self.getListExecutiveSummaryLines():
            self.screen(line)

    def verboseDebug(self, _strMessage):
        self.DEBUG(self.getPluginName() + " : " + _strMessage)


    def getPluginName(self):
        return self.getClassName()


    def getListOfDataInputKeys(self):
        return self.__dictXSDataInput.keys()


    def getListOfDataOutputKeys(self):
        return self.__dictXSDataOutput.keys()


    def getDefaultInputDataKey(self):
        return self.__strDefaultInputDataKey


    def getDefaultOutputDataKey(self):
        return self.__strDefaultOutputDataKey


    def getExecutiveSummarySeparator(self):
        return self.__strExecutiveSummarySeparator


    def isRequiredToHaveConfiguration(self):
        """
        If the return value from this method is true, the plugin 
        is required to have a configuration in order to be executed in a
        plugin execution test case.
        @return: RequiredToHaveConfiguration
        @rtype: boolean
        """
        return self.__isRequiredToHaveConfiguration


    def setRequiredToHaveConfiguration(self, _bValue=True):
        """
        Sets or unsets the plugin to be required to have a configuration
        for execution in a plugin execution test case.
        plugin execution test case.
        @param _bValue: RequiredToHaveConfiguration
        @type: boolean
        """
        self.__isRequiredToHaveConfiguration = _bValue


    def setWriteXMLInputOutput(self, _bValue=True):
        """
        Sets or unsets the plugin to write XML input and output files.
        @param _bValue: WriteDataXMLInputOutput
        @type: boolean
        """
        self.__bWriteDataXMLInputOutput = _bValue

    def setWriteXMLInput(self, _bValue=True):
        """
        Sets or unsets the plugin to write XML input  files.
        @param _bValue: WriteDataXMLInput
        @type: boolean
        """
        self.__bWriteDataXMLInput = _bValue

    def setWriteXMLOutput(self, _bValue=True):
        """
        Sets or unsets the plugin to write XML  output files.
        @param _bValue: WriteDataXMLOutput
        @type: boolean
        """
        self.__bWriteDataXMLOutput = _bValue


    def setUseWarningInsteadOfError(self, _bValue=True):
        """
        Sets or unsets the plugin to use warning messages also for error messages.
        @param _bValue: UseWarningInsteadOfError
        @type: boolean
        """
        self.__bUseWarningInsteadOfError = _bValue

    def error(self, _strErrorMessage):
        """
        Overloaded from EDLogging. If self.__bUseWarningInsteadOfError is True
        a warning message is issued instead of an error message.
        """
        if self.__bUseWarningInsteadOfError:
            self.warning(_strErrorMessage)
        else:
            EDAction.error(self, _strErrorMessage)

    def ERROR(self, _strErrorMessage):
        """
        Uses the overloaded self.error method above.
        """
        self.error(_strErrorMessage)
    def testSetDataModelInput(self):
        edPluginStrategy = self.createPlugin()
        strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(),
                                               "XSConfiguration_ESRF.xml")
        edConfiguration = EDConfiguration(strPathToTestConfigFile)
        dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
        edPluginStrategy.setConfig(dictItem)
        edPluginStrategy.configure()

        xsDataStrategy = XSDataInputStrategy()

        # Beam

        xsExperimentalCondition = XSDataExperimentalCondition()

        xsBeam = XSDataBeam()
        xsBeam.setFlux(XSDataFlux(1e+12))
        xsBeam.setWavelength(XSDataWavelength(2.41))
        xsBeam.setSize(XSDataSize(x=XSDataLength(0.1), y=XSDataLength(0.1)))
        xsBeam.setExposureTime(XSDataTime(1))

        xsExperimentalCondition.setBeam(xsBeam)

        # Detector and Exposure Time

        xsDataDetector = XSDataDetector()
        xsDataDetector.setType(XSDataString("q210-2x"))
        xsExperimentalCondition.setDetector(xsDataDetector)

        xsDataGoniostat = XSDataGoniostat()
        xsDataGoniostat.setRotationAxis(XSDataString("phi"))
        xsExperimentalCondition.setGoniostat(xsDataGoniostat)

        xsDataStrategy.setExperimentalCondition(xsExperimentalCondition)

        # Best Files
        bestFileContentDat = EDUtilsFile.readFile(
            os.path.join(self.strDataPath, "bestfile.dat"))
        xsDataStrategy.setBestFileContentDat(XSDataString(bestFileContentDat))
        bestFileContentPar = EDUtilsFile.readFile(
            os.path.join(self.strDataPath, "bestfile.par"))
        xsDataStrategy.setBestFileContentPar(XSDataString(bestFileContentPar))
        bestFileContentHKL = EDUtilsFile.readFile(
            os.path.join(self.strDataPath, "bestfile1.hkl"))
        xsDataStrategy.addBestFileContentHKL(XSDataString(bestFileContentHKL))

        # Crystal

        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()

        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataDouble(2))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtom1 = XSDataAtom()
        xsDataAtom1.setSymbol(XSDataString("Se"))
        xsDataAtom1.setNumberOf(XSDataDouble(4))
        xsDataAtomicComposition.addAtom(xsDataAtom1)

        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)
        xsDataChain.setNumberOfMonomers(XSDataDouble(100))
        xsDataStructure.addChain(xsDataChain)

        xsDataChain2 = XSDataChain()
        xsDataChain2.setType(XSDataString("rna"))
        xsDataChain2.setNumberOfCopies(XSDataDouble(1))
        xsDataChain2.setNumberOfMonomers(XSDataDouble(60))
        xsDataStructure.addChain(xsDataChain2)

        xsDataLigand = XSDataLigand()
        xsDataLigand.setNumberOfCopies(XSDataDouble(2))
        xsDataLigand.setNumberOfLightAtoms(XSDataDouble(42))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtom2 = XSDataAtom()
        xsDataAtom2.setSymbol(XSDataString("Fe"))
        xsDataAtom2.setNumberOf(XSDataDouble(1))
        xsDataAtomicComposition.addAtom(xsDataAtom2)
        xsDataLigand.setHeavyAtoms(xsDataAtomicComposition)
        xsDataStructure.addLigand(xsDataLigand)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(0.25))

        xsDataSolvent = XSDataSolvent()
        xsDataAtomicComposition = XSDataAtomicComposition()

        xsDataAtom3 = XSDataAtom()
        xsDataAtom3.setSymbol(XSDataString("Na"))
        xsDataAtom3.setConcentration(XSDataDouble(1000))
        xsDataAtom4 = XSDataAtom()
        xsDataAtom4.setSymbol(XSDataString("Cl"))
        xsDataAtom4.setConcentration(XSDataDouble(1000))

        xsDataAtomicComposition.addAtom(xsDataAtom3)
        xsDataAtomicComposition.addAtom(xsDataAtom4)
        xsDataSolvent.setAtoms(xsDataAtomicComposition)

        xsDataComposition.setStructure(xsDataStructure)
        xsDataComposition.setSolvent(xsDataSolvent)
        xsDataSampleCrystalMM.setChemicalComposition(xsDataComposition)

        xsDataSampleCrystalMM.setSize(
            XSDataSize(XSDataLength(0.1), XSDataLength(0.1),
                       XSDataLength(0.1)))

        xsDataCrystal = XSDataCrystal()
        xsDataCell = XSDataCell(angle_alpha=XSDataAngle(90.0),
                                angle_beta=XSDataAngle(90.0),
                                angle_gamma=XSDataAngle(90.0),
                                length_a=XSDataLength(78.9),
                                length_b=XSDataLength(95.162),
                                length_c=XSDataLength(104.087))
        xsDataCrystal.setCell(xsDataCell)

        xsDataSpaceGroup = XSDataSpaceGroup()
        xsDataSpaceGroup.setITNumber(XSDataInteger(16))
        xsDataCrystal.setSpaceGroup(xsDataSpaceGroup)

        xsDataSampleCrystalMM.setSusceptibility(XSDataDouble(1.5))

        xsDataStrategy.setCrystalRefined(xsDataCrystal)

        xsDataStrategy.setSample(xsDataSampleCrystalMM)

        xsDataStrategy.exportToFile(self.strObtainedInputFile)

        pyStrExpectedInput = self.readAndParseFile(self.strReferenceInputFile)
        pyStrObtainedInput = self.readAndParseFile(self.strObtainedInputFile)

        xsDataInputExpected = XSDataInputStrategy.parseString(
            pyStrExpectedInput)
        xsDataInputObtained = XSDataInputStrategy.parseString(
            pyStrObtainedInput)

        EDAssert.equal(xsDataInputExpected.marshal(),
                       xsDataInputObtained.marshal())
Example #20
0
class EDPlugin(EDAction):
    """
    This is the EDNA plugin main class
    An EDNA plugin class:
        - is a configurable entity
        - has a base name (<date>-<random number>-<base name>)
        - handles input/output data (setter, getter, checker)
        - has warning and error messages
        - has a base and a working directory (both are configurable)
        The working directory is the folder from which the plugin is launched
        and should contain all associated files with the plugin execution (edna xml input/output, 3rd party output files)
        The base directory is the parent directory of the working directory. 
        Example: the working directory of a control plugin is the base directory of the plugins that it invokes,
        i.e. the plugins working directories has the control plugin working directory as parent.
    - defines the method that generates an executive summary (user-related output summary) that sub-classes should implement
    """
    CONF_BASE_DIR_LABEL = "baseDirectory"
    CONF_WORKING_DIR_LABEL = "workingDirectory"
    CONF_TIME_OUT = "timeOut"
    CONF_WRITE_XML_INPUT_OUTPUT = "writeXMLInputOutput"
    CONF_WRITE_XML_OUTPUT = "writeXMLOutput"
    CONF_WRITE_XML_INPUT = "writeXMLInput"

    def __init__(self):
        """
        Initializes plugin related attributes described above
        """
        EDAction.__init__(self)
        self.__xsPluginItem = None
        self.__dictXSDataInputClass = {}
        self.__dictXSDataInput = {}
        self.__dictXSDataOutput = {}
        self.__strDefaultInputDataKey = "defaultInputData"
        self.__strDefaultOutputDataKey = "defaultOutputData"
        self.__edSlotExportDataOutput = EDSlot()
        self.__strBaseDirectory = None
        self.__strWorkingDirectory = None
        self.__strBaseName = None
        self.__listExecutiveSummaryLines = []
        self.__strExecutiveSummarySeparator = "-" * 80
        self.__listErrorMessages = []
        self.__listWarningMessages = []
        self.__isRequiredToHaveConfiguration = False
        self.__bWriteDataXMLInputOutput = True
        self.__bWriteDataXMLOutput = True
        self.__bWriteDataXMLInput = True
        self.__strPluginId = "%s-%08i" % (self.getClassName(), self.getId())
        self.strPathDataInput = None
        self.strPathDataOutput = None
        self.__bUseWarningInsteadOfError = False
        self.__edConfiguration = EDConfigurationStatic()

    def preProcess(self, _edObject=None):
        """
        Writes xml data input in the working dir (if required)
        Connects a slot for generating the executive summary after the plugin execution
        Connects a slot for checking output data to the finally process
        Initialize the base directory
        Configures the plugin
        Checks the input data
        """
        EDAction.preProcess(self, _edObject)
        self.DEBUG("EDPlugin.preProcess")
        self.connectPostProcess(self.exportDataOutput)
        if self.__bWriteDataXMLInputOutput:
            if self.__bWriteDataXMLInput:
                self.connectPreProcess(self.writeDataInput)
        self.connectPostProcess(self.generateExecutiveSummary)
        self.connectFinallyProcess(self.checkDataOutput)
        if (self.__strBaseName is None):
            self.setBaseName(self.createBaseName())
        EDStatus.tellRunning(self.__strPluginId)
        self.connectFinallyProcess(self.tellFinished)
        self.checkParameters()

    def tellFinished(self, _edObject=None):
        """
        Tell EDStatus that the plugin has finished, either in success either in error 
        """
        if self.isFailure():
            EDStatus.tellFailure(self.__strPluginId)
        else:
            EDStatus.tellSuccess(self.__strPluginId)

    def checkDataOutput(self, _edObject=None):
        """
        Checks if output data is available, if not issues a warning and sets an empty XSDataResult as output data
        Writes xml data output in the working dir (if required)
        """
        EDAction.finallyProcess(self, _edObject)
        if self.__dictXSDataOutput == {}:
            strWarningMessage = "Output data for plugin %s not set, using XSDataResult as output" % self.getPluginName(
            )
            self.WARNING(strWarningMessage)
            self.addWarningMessage(strWarningMessage)
            self.setDataOutput(XSDataResult())
        if self.__bWriteDataXMLInputOutput:
            if self.__bWriteDataXMLOutput:
                self.writeDataOutput()

    def synchronize(self):
        """
        This method calls EDAction.synchronize and if a time-out occurs an error message
        is added to the list of error messages.
        """
        EDAction.synchronize(self)
        if self.isTimeOut():
            strErrorMessage = "Timeout when waiting for %s to terminate." % self.getClassName(
            )
            self.addErrorMessage(strErrorMessage)

    def getConfig(self):
        """
        Gets the Plugin Configuration as a dictionary
        """
        # self.DEBUG("EDPlugin.getConfig")
        return self.__edConfiguration.get(self.getPluginName(), {})

    def setConfig(self, _dict, _bLocal=False):
        """
        Receives a dictionary (Plugin Configuration) from the application.
        """
        self.DEBUG("EDPlugin.setConfiguration")
        if _bLocal:
            self.__edConfiguration = EDConfiguration()
        if _dict is not None:
            self.__edConfiguration[self.getPluginName()] = _dict
        else:
            self.__edConfiguration[self.getPluginName()] = {}

    config = property(getConfig, setConfig)

    def configure(self):
        """
        Should be overridden by the Final Plugin If needed
        This method should set its proper members attributes from a Plugin configuration Object
        """
        self.DEBUG("EDPlugin.configure : plugin name = %s, EDNA_SITE = %s" %
                   (self.getPluginName(), EDUtilsPath.EDNA_SITE))

        # set Timeout if different from default one
        if self.getTimeOut() == self.getDefaultTimeOut():
            # Try to get time out from plugin configuration
            iTimeOut = self.config.get(EDPlugin.CONF_TIME_OUT, None)
            if iTimeOut is not None:
                self.DEBUG(
                    "EDPlugin.configure: Setting time out to %d s from plugin configuration."
                    % iTimeOut)
                self.setTimeOut(iTimeOut)
        else:
            self.DEBUG(
                "EDPlugin.configure: timeout already set before plugin is configured."
            )
        # Base directory
        strBaseDirectory = self.getBaseDirectory()
        if (strBaseDirectory is None):
            # Try to get base directory from plugin configuration
            strBaseDirectory = self.config.get(EDPlugin.CONF_BASE_DIR_LABEL,
                                               None)
            if (strBaseDirectory is None):
                # Try to get working directory from environment variable
                strBaseDirectory = os.environ.get("EDNA_BASE_DIRECTORY")
                if (strBaseDirectory is None):
                    self.DEBUG(
                        "EDPlugin.configure: Using current base directory as working directory."
                    )
                    strBaseDirectory = os.getcwd()
                else:
                    self.DEBUG(
                        "EDPlugin.configure: Setting base directory from $EDNA_WORKING_DIRECTORY."
                    )
            else:
                if (strBaseDirectory == "."):
                    self.DEBUG(
                        "EDPlugin.configure: Using current base directory as working directory."
                    )
                    strBaseDirectory = os.getcwd()
                else:
                    strBaseDirectory = os.path.abspath(strBaseDirectory)
                    self.DEBUG(
                        "EDPlugin.configure: Setting base directory from plugin configuration."
                    )
            self.setBaseDirectory(strBaseDirectory)
        else:
            self.DEBUG(
                "EDPlugin.configure: Base directory already set before plugin is configured."
            )
        # Working directory
        strWorkingDirectory = self.getWorkingDirectory()
        if (strWorkingDirectory is None):
            # Try to get working directory from plugin configuration
            strWorkingDirectory = self.config.get(
                EDPlugin.CONF_WORKING_DIR_LABEL, None)
            if (strWorkingDirectory is not None):
                self.DEBUG(
                    "EDPlugin.configure: Setting working directory from plugin configuration."
                )
            else:
                self.DEBUG(
                    "EDPlugin.configure: Setting working directory as base directory + base name."
                )
                strWorkingDirectory = os.path.join(self.getBaseDirectory(),
                                                   self.getBaseName())
            self.setWorkingDirectory(strWorkingDirectory)
        else:
            self.DEBUG(
                "EDPlugin.configure: Working directory already set before plugin is configured."
            )
        #
        self.__bWriteDataXMLInputOutput = bool(
            self.config.get(self.CONF_WRITE_XML_INPUT_OUTPUT, True))
        self.__bWriteDataXMLOutput = bool(
            self.config.get(self.CONF_WRITE_XML_OUTPUT, True))
        self.__bWriteDataXMLInput = bool(
            self.config.get(self.CONF_WRITE_XML_INPUT, True))

    def execute(self, _edObject=None):
        # Configure the plugin before starting it's thread
        self.configure()
        EDAction.execute(self, _edObject)

    def checkParameters(self):
        """
        Should be overridden by the Final Plugin If needed
        This method should check that the data input are consistent
        """
        self.DEBUG("EDPlugin.checkParameters")

    def setXSDataInputClass(self, _xsDataInputClass, _strDataInputKey=None):
        """
        This method should be called in the constructor of the derived plugins
        in order to set the XSData type of the input data, e.g. XSDataInputXXX
        """
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInputClass.keys()):
            strErrorMessage = "ERROR: " + self.getPluginName(
            ) + ".setXSDataInputClass, Data Input Class already defined for key: " + strDataInputKey
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)
        self.__dictXSDataInputClass[strDataInputKey] = _xsDataInputClass

    def getXSDataInputClass(self, _strDataInputKey=None):
        """
        Returns the XSData type of the input data.
        """
        pyXSDataInputClass = None
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInputClass.keys()):
            pyXSDataInputClass = self.__dictXSDataInputClass[strDataInputKey]
        return pyXSDataInputClass

    def setDataInput(self, _oDataInput, _strDataInputKey=None):
        """
        Sets the plugin input data.
        _oDataInput could be either an String XML or an XSData object.

        The input data is stored in a dictionary with the key _strDataInputKey.
        If the key is not provided a default key is used.

        If not data input class is defined for the key an exception is raised.
        
        If the key is not the default key, the data object is added to a list which 
        might contain already stored object(s).
        
        If _oDataInput is None the list corresponding to a keyword is deleted.
        """
        self.DEBUG("EDPlugin.setDataInput")
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        # Allow for None input
        if (_oDataInput is None):
            self.DEBUG("EDPlugin.setDataInput: Data input is None")
            self.__dictXSDataInput[strDataInputKey] = []
        elif (self.getXSDataInputClass(strDataInputKey) is None):
            strErrorMessage = "ERROR: " + self.getPluginName(
            ) + ".setDataInput, Data Input Class not defined for key: " + strDataInputKey
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)
        else:
            # Check the type
            xsDataInput = None
            if isinstance(_oDataInput, (str, unicode)):
                self.DEBUG("EDPlugin.setDataInput: Input Data is string ")
                xsDataInput = self.getXSDataInputClass(
                    strDataInputKey).parseString(_oDataInput)
            elif (isinstance(_oDataInput,
                             self.getXSDataInputClass(strDataInputKey))):
                self.DEBUG("EDPlugin.setDataInput: Input Data is of type " +
                           str(_oDataInput.__class__))
                xsDataInput = _oDataInput
            else:
                strErrorMessage = "ERROR: %s.setDataInput, wrong data type %r for data input key: %s, expected XML string or %r" % \
                                  (self.getPluginName(), _oDataInput.__class__, strDataInputKey, self.getXSDataInputClass(strDataInputKey))
                self.error(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                raise RuntimeError(strErrorMessage)
            # Add the object to a list if its key is not the default key
            if (strDataInputKey != self.__strDefaultInputDataKey):
                # Check if there's already a list stored
                if (not strDataInputKey in self.__dictXSDataInput.keys()):
                    self.__dictXSDataInput[strDataInputKey] = []
                self.__dictXSDataInput[strDataInputKey].append(xsDataInput)
            else:
                self.__dictXSDataInput[strDataInputKey] = xsDataInput

    def hasDataInput(self, _strDataInputKey=None):
        """
        Returns True if the plugin has Input Data for a particular key.
        If the key is not provided a default key is used.
        """
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInput.keys()):
            return True
        else:
            return False

    def getDataInput(self, _strDataInputKey=None):
        """
        Returns the Plugin Input Data for a particular key.
        If the key is not provided a default key is used.
        """
        oValue = None
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInput.keys()):
            oValue = self.__dictXSDataInput[strDataInputKey]
        else:
            strErrorMessage = self.getPluginName(
            ) + ".getDataInput, no input data defined for key: " + strDataInputKey
            self.warning(strErrorMessage)
            self.addWarningMessage(strErrorMessage)
        return oValue

    def delDataInput(self, _strDataInputKey=None):
        """
        Deletes the data input for a particular key.
        If the key is not provided a default key is used.
        """
        strDataInputKey = _strDataInputKey
        if (strDataInputKey is None):
            strDataInputKey = self.__strDefaultInputDataKey
        if (strDataInputKey in self.__dictXSDataInput.keys()):
            self.__dictXSDataInput[strDataInputKey] = None
        else:
            strErrorMessage = self.getPluginName(
            ) + ".delDataInput, no input data defined for key: " + strDataInputKey
            self.warning(strErrorMessage)
            self.addWarningMessage(strErrorMessage)

    # Property for dataInput
    dataInput = property(getDataInput, setDataInput, delDataInput,
                         "Property for dataInput")

    def setDataOutput(self, _xsDataOutput, _strDataOutputKey=None):
        """
        Sets the plugin output data for a particular key.
        If the key is not provided a default key is used.

        If the key is already defined in the dictionary, the corresponding
        data object is added to a list which contains the already stored object(s).
        """
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        # Add the object to a list if its key not the default key
        if (strDataOutputKey == self.__strDefaultOutputDataKey):
            self.__dictXSDataOutput[strDataOutputKey] = _xsDataOutput
        else:
            # Check if the _xsDataoutput object is already a list
            if (type(_xsDataOutput) == list):
                self.__dictXSDataOutput[strDataOutputKey] = _xsDataOutput
            else:
                # Check if the stored object contains already a list
                if (not strDataOutputKey in self.__dictXSDataOutput.keys()):
                    self.__dictXSDataOutput[strDataOutputKey] = []
                self.__dictXSDataOutput[strDataOutputKey].append(_xsDataOutput)

    def getDataOutput(self, _strDataOutputKey=None):
        """
        Returns the Plugin Output Data
        """
        oValue = None
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        if (strDataOutputKey in self.__dictXSDataOutput.keys()):
            oValue = self.__dictXSDataOutput[strDataOutputKey]
        return oValue

    def hasDataOutput(self, _strDataOutputKey=None):
        """
        Returns True if the plugin has the specified Output Data
        """
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        if (strDataOutputKey in self.__dictXSDataOutput.keys()):
            return True
        else:
            return False

    def delDataOutput(self, _strDataOutputKey=None):
        """
        Deletes the data output for a particular key.
        If the key is not provided a default key is used.
        """
        strDataOutputKey = _strDataOutputKey
        if (strDataOutputKey is None):
            strDataOutputKey = self.__strDefaultOutputDataKey
        if (strDataOutputKey in self.__dictXSDataOutput.keys()):
            self.__dictXSDataOutput[strDataOutputKey] = None
        else:
            strErrorMessage = self.getPluginName(
            ) + ".delDataOutput, no output data defined for key: " + _strDataOutputKey
            self.warning(strErrorMessage)
            self.addWarningMessage(strErrorMessage)

    # Property for dataOutput
    dataOutput = property(getDataOutput, setDataOutput, delDataOutput,
                          "Property for dataOutput")

    def exportDataOutput(self, _edPlugin=None):
        """
        Deprecated
        Exports the Plugin Output Data to slot
        """
        self.DEBUG("EDPlugin.exportDataOutput")
        self.__edSlotExportDataOutput.call(self.__dictXSDataOutput)

    def connectExportDataOutput(self, _oMethod):
        """
        Deprecated
        """
        self.synchronizeOn()
        if (_oMethod != None):
            self.__edSlotExportDataOutput.connect(_oMethod)
        self.synchronizeOff()

    def generateExecutiveSummary(self, _edPlugin):
        """
        This method, which should be implemented by sub-classes, generates an executive summary (user-related output summary).
        """
        self.DEBUG("EDPlugin.generateExecutiveSummary")

    def addErrorMessage(self, _strErrorMessage):
        """
        Adds an error message to the error messages list
        """
        self.__listErrorMessages.append(_strErrorMessage)

    def getListOfErrorMessages(self):
        """
        Returns the error messages list
        """
        return self.__listErrorMessages

    def addWarningMessage(self, _strWarningMessage):
        """
        Adds a warning message to the warning messages list
        """
        self.DEBUG("EDPlugin.addWarningMessage : " + _strWarningMessage)
        self.__listWarningMessages.append(_strWarningMessage)

    def getListOfWarningMessages(self):
        """
        Returns the warning messages list
        """
        return self.__listWarningMessages

    def writeDataInput(self, _edObject=None):
        """
        Writes the input data object(s) into a working dir xml file 
        """
        self.DEBUG("EDPlugin.writeDataInput")
        strBasename = os.path.join(
            self.getWorkingDirectory(),
            self.compactPluginName(self.getPluginName()))
        for strKey in self.__dictXSDataInput.keys():
            if (strKey == self.__strDefaultInputDataKey):  # "Old" style
                xsDataInput = self.__dictXSDataInput[
                    self.__strDefaultInputDataKey]
                self.strPathDataInput = strBasename + "_dataInput.xml"
                EDUtilsFile.writeFile(self.strPathDataInput,
                                      xsDataInput.marshal())
            else:  # We have a list of objects
                listXSDataInput = self.__dictXSDataInput[strKey]
                for iIndex, xsDataInput in enumerate(listXSDataInput):
                    strPathDataInput = "%s_%s_%d_dataInput.xml" % (
                        strBasename, strKey, iIndex)
                    EDUtilsFile.writeFile(strPathDataInput,
                                          xsDataInput.marshal())

    def writeDataOutput(self, _edObject=None):
        """
        Writes the output data object(s) into a working dir xml file 
        """
        self.DEBUG("EDPlugin.writeDataOutput")
        for strKey in self.__dictXSDataOutput.keys():
            if (strKey == self.__strDefaultOutputDataKey):  # "Old" style
                xsDataOutput = self.__dictXSDataOutput[
                    self.__strDefaultOutputDataKey]
                if (xsDataOutput is not None):
                    self.strPathDataOutput = os.path.join(
                        self.getWorkingDirectory(),
                        self.compactPluginName(self.getPluginName()) +
                        "_dataOutput.xml")
                    EDUtilsFile.writeFile(self.strPathDataOutput,
                                          xsDataOutput.marshal())
            else:
                listXSDataOutput = self.__dictXSDataOutput[strKey]
                for iIndex, xsDataOutput in enumerate(listXSDataOutput):
                    if (xsDataOutput is not None):
                        strPathDataOutput = os.path.join(
                            self.getWorkingDirectory(),
                            self.compactPluginName(self.getPluginName()) +
                            "_" + strKey + "_%d_dataOutput.xml" % iIndex)
                        EDUtilsFile.writeFile(strPathDataOutput,
                                              xsDataOutput.marshal())

    def getBaseName(self):
        """
        Returns the plugin base name
        """
        if (self.__strBaseName is None):
            self.__strBaseName = self.createBaseName()
        return self.__strBaseName

    def setBaseName(self, _strBaseName):
        """
        Sets the plugin base name
        """
        self.__strBaseName = self.compactPluginName(_strBaseName)
        self.setName(self.__strBaseName)
        # Create the directory baseDirectory/baseName which will be used as working directory
        strWorkingDirPath = os.path.join(self.getBaseDirectory(),
                                         self.__strBaseName)
        if not os.path.isdir(strWorkingDirPath):
            os.mkdir(strWorkingDirPath)
        self.setWorkingDirectory(strWorkingDirPath)

    def createBaseName(self):
        """
        Generates the plugin base name: (<prefix>-<object ID>)
        """
        # First try to use global instance ID from EDObject
        strBaseName = "%s-%08d" % (self.compactPluginName(
            self.getPluginName()), self.getId())
        strBaseDir = os.path.join(self.getBaseDirectory(), strBaseName)
        # Try to create the directory...
        try:
            os.mkdir(strBaseDir)
        except Exception as strErrorDetail:
            self.error(
                "EDPlugin.createBaseName: Could not create base directory %s because of %s"
                % (strBaseDir, strErrorDetail))
            self.warning(
                "EDPlugin.createBaseName: Trying to create alternative base directory..."
            )
            self.writeErrorTrace()
            strTempDir = tempfile.mkdtemp(prefix=strBaseName,
                                          dir=self.getBaseDirectory())
            os.chmod(
                strTempDir, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
                | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
            strBaseName = os.path.split(strTempDir)[1]
            strBaseDir = os.path.join(self.getBaseDirectory(), strBaseName)
            self.warning(
                "EDPlugin.createBaseName: Alternative base directory created: %s"
                % strBaseDir)
        self.DEBUG("EDPlugin.createBaseName : Directory created = " +
                   strBaseDir)
        return strBaseName

    def compactPluginName(self, _pluginName):
        """
        The prefix is constructed from the plugin name with the following renaming:
        EDPlugin -> ""
        EDPluginExec -> ""
        EDPluginControl -> "Control"
        """
        strCompactName = _pluginName
        if (strCompactName.startswith("EDPluginExec")):
            strCompactName = strCompactName[12:]
        elif (strCompactName.startswith("EDPluginControl")):
            strCompactName = strCompactName[8:]
        elif (strCompactName.startswith("EDPlugin")):
            strCompactName = strCompactName[8:]
        return strCompactName

    def setBaseDirectory(self, _strBaseDirectory):
        """
        Sets the plugin base directory
        """
        self.DEBUG("EDPlugin.setBaseDirectory : " + _strBaseDirectory)
        if (not os.path.isdir(_strBaseDirectory)):
            self.DEBUG(
                "EDPlugin.setBaseDirectory: base directory %s does dot yet exist! Creating it."
                % _strBaseDirectory)
            os.mkdir(_strBaseDirectory)
        self.__strBaseDirectory = _strBaseDirectory

    def getBaseDirectory(self):
        """
        Returns the plugin base directory
        """
        self.DEBUG("EDPlugin.getBaseDirectory : %s" % self.__strBaseDirectory)
        if (self.__strBaseDirectory is None):
            self.__strBaseDirectory = os.getcwd()
        return self.__strBaseDirectory

    def setWorkingDirectory(self, _strWorkingDirectory):
        """
        Sets the plugin working directory
        """
        self.DEBUG("EDPlugin.setWorkingDirectory : " + _strWorkingDirectory)
        self.__strWorkingDirectory = _strWorkingDirectory
        if not os.path.isdir(_strWorkingDirectory):
            self.DEBUG(
                "EDPlugin.setWorkingDirectory, creating working directory %s."
                % _strWorkingDirectory)
            os.mkdir(self.__strWorkingDirectory)

    def getWorkingDirectory(self):
        """
        Returns the plugin base directory
        """
        self.DEBUG("EDPlugin.getWorkingDirectory : %s" %
                   self.__strWorkingDirectory)
        returnValue = None
        if (self.__strWorkingDirectory is not None):
            returnValue = self.__strWorkingDirectory
        return returnValue

    def checkMandatoryParameters(self, _xsData, _strParamName):
        """
        Checks that a mandatory parameter exists in the data
        If not, an error message is added in the list and the plugin fails
        """
        if _xsData is None or (hasattr(_xsData, '__len__')
                               and len(_xsData) == 0):
            strErrorMessage = "%s: input parameter is missing: %s" % (
                self.getPluginName(), _strParamName)
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)

    def checkImportantParameters(self, _xsData, _strParamName):
        """
        Checks that a specific parameter exists in the data
        If not, a warning message is added in the list
        """
        if (_xsData == None):
            strWarningMessage = "%s: input parameter is missing: %s" % (
                self.getPluginName(), _strParamName)
            self.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)

    def addExecutiveSummaryLine(self, _strExecutiveSummaryLine):
        """
        Add a line to the executive summary string.
        """
        self.DEBUG("EDPlugin.addExecutiveSummaryLine : %r" %
                   _strExecutiveSummaryLine)
        strExecutiveSummaryLine = _strExecutiveSummaryLine
        if (not strExecutiveSummaryLine == ""):
            if (strExecutiveSummaryLine[-1] == "\n"):
                strExecutiveSummaryLine = strExecutiveSummaryLine[:-1]
        self.__listExecutiveSummaryLines.append(strExecutiveSummaryLine)

    def addExecutiveSummarySeparator(self, _strSeparator=None):
        """
        Adds a separator to split the executive summary into different parts
        Default is a dotted line
        """
        strSeparator = _strSeparator
        if (strSeparator is None):
            strSeparator = self.__strExecutiveSummarySeparator
        # Check that the last line doesn't already contain a separator
        if self.__listExecutiveSummaryLines != []:
            if self.__listExecutiveSummaryLines[-1] != strSeparator:
                self.addExecutiveSummaryLine(strSeparator)
        else:
            self.addExecutiveSummaryLine(strSeparator)

    def getListExecutiveSummaryLines(self):
        """
        Returns the executive summary (list of text lines)
        """
        return self.__listExecutiveSummaryLines

    def verboseScreenExecutiveSummary(self):
        """
        Prints the executive summary on the screen
        """
        for line in self.getListExecutiveSummaryLines():
            self.screen(line)

    def verboseDebug(self, _strMessage):
        self.DEBUG(self.getPluginName() + " : " + _strMessage)

    def getPluginName(self):
        return self.getClassName()

    def getListOfDataInputKeys(self):
        return self.__dictXSDataInput.keys()

    def getListOfDataOutputKeys(self):
        return self.__dictXSDataOutput.keys()

    def getDefaultInputDataKey(self):
        return self.__strDefaultInputDataKey

    def getDefaultOutputDataKey(self):
        return self.__strDefaultOutputDataKey

    def getExecutiveSummarySeparator(self):
        return self.__strExecutiveSummarySeparator

    def isRequiredToHaveConfiguration(self):
        """
        If the return value from this method is true, the plugin 
        is required to have a configuration in order to be executed in a
        plugin execution test case.
        @return: RequiredToHaveConfiguration
        @rtype: boolean
        """
        return self.__isRequiredToHaveConfiguration

    def setRequiredToHaveConfiguration(self, _bValue=True):
        """
        Sets or unsets the plugin to be required to have a configuration
        for execution in a plugin execution test case.
        plugin execution test case.
        @param _bValue: RequiredToHaveConfiguration
        @type: boolean
        """
        self.__isRequiredToHaveConfiguration = _bValue

    def setWriteXMLInputOutput(self, _bValue=True):
        """
        Sets or unsets the plugin to write XML input and output files.
        @param _bValue: WriteDataXMLInputOutput
        @type: boolean
        """
        self.__bWriteDataXMLInputOutput = _bValue

    def setWriteXMLInput(self, _bValue=True):
        """
        Sets or unsets the plugin to write XML input  files.
        @param _bValue: WriteDataXMLInput
        @type: boolean
        """
        self.__bWriteDataXMLInput = _bValue

    def setWriteXMLOutput(self, _bValue=True):
        """
        Sets or unsets the plugin to write XML  output files.
        @param _bValue: WriteDataXMLOutput
        @type: boolean
        """
        self.__bWriteDataXMLOutput = _bValue

    def setUseWarningInsteadOfError(self, _bValue=True):
        """
        Sets or unsets the plugin to use warning messages also for error messages.
        @param _bValue: UseWarningInsteadOfError
        @type: boolean
        """
        self.__bUseWarningInsteadOfError = _bValue

    def error(self, _strErrorMessage):
        """
        Overloaded from EDLogging. If self.__bUseWarningInsteadOfError is True
        a warning message is issued instead of an error message.
        """
        if self.__bUseWarningInsteadOfError:
            self.warning(_strErrorMessage)
        else:
            EDAction.error(self, _strErrorMessage)

    def ERROR(self, _strErrorMessage):
        """
        Uses the overloaded self.error method above.
        """
        self.error(_strErrorMessage)
    def testSetDataModelInput(self):
        edPluginStrategy = self.createPlugin()
        strPathToTestConfigFile = os.path.join(self.getPluginTestsDataHome(), "XSConfiguration_ESRF.xml")
        edConfiguration = EDConfiguration(strPathToTestConfigFile)
        dictItem = edConfiguration.get(edPluginStrategy.getPluginName())
        edPluginStrategy.setConfig(dictItem)
        edPluginStrategy.configure()

        xsDataStrategy = XSDataInputStrategy()

        # Beam

        xsExperimentalCondition = XSDataExperimentalCondition()

        xsBeam = XSDataBeam()
        xsBeam.setFlux(XSDataFlux(1e+12))
        xsBeam.setWavelength(XSDataWavelength(2.41))
        xsBeam.setSize(XSDataSize(x=XSDataLength(0.1), y=XSDataLength(0.1)))
        xsBeam.setExposureTime(XSDataTime(1))

        xsExperimentalCondition.setBeam(xsBeam)

        # Detector and Exposure Time

        xsDataDetector = XSDataDetector()
        xsDataDetector.setType(XSDataString("q210-2x"))
        xsExperimentalCondition.setDetector(xsDataDetector)

        xsDataGoniostat = XSDataGoniostat()
        xsDataGoniostat.setRotationAxis(XSDataString("phi"))
        xsExperimentalCondition.setGoniostat(xsDataGoniostat)

        xsDataStrategy.setExperimentalCondition(xsExperimentalCondition)


        # Best Files
        bestFileContentDat = EDUtilsFile.readFile(os.path.join(self.strDataPath, "bestfile.dat"))
        xsDataStrategy.setBestFileContentDat(XSDataString(bestFileContentDat))
        bestFileContentPar = EDUtilsFile.readFile(os.path.join(self.strDataPath, "bestfile.par"))
        xsDataStrategy.setBestFileContentPar(XSDataString(bestFileContentPar))
        bestFileContentHKL = EDUtilsFile.readFile(os.path.join(self.strDataPath, "bestfile1.hkl"))
        xsDataStrategy.addBestFileContentHKL(XSDataString(bestFileContentHKL))

        # Crystal

        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()

        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataDouble(2))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtom1 = XSDataAtom()
        xsDataAtom1.setSymbol(XSDataString("Se"))
        xsDataAtom1.setNumberOf(XSDataDouble(4))
        xsDataAtomicComposition.addAtom(xsDataAtom1)

        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)
        xsDataChain.setNumberOfMonomers(XSDataDouble(100))
        xsDataStructure.addChain(xsDataChain)

        xsDataChain2 = XSDataChain()
        xsDataChain2.setType(XSDataString("rna"))
        xsDataChain2.setNumberOfCopies(XSDataDouble(1))
        xsDataChain2.setNumberOfMonomers(XSDataDouble(60))
        xsDataStructure.addChain(xsDataChain2)

        xsDataLigand = XSDataLigand()
        xsDataLigand.setNumberOfCopies(XSDataDouble(2))
        xsDataLigand.setNumberOfLightAtoms(XSDataDouble(42))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtom2 = XSDataAtom()
        xsDataAtom2.setSymbol(XSDataString("Fe"))
        xsDataAtom2.setNumberOf(XSDataDouble(1))
        xsDataAtomicComposition.addAtom(xsDataAtom2)
        xsDataLigand.setHeavyAtoms(xsDataAtomicComposition)
        xsDataStructure.addLigand(xsDataLigand)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(0.25))

        xsDataSolvent = XSDataSolvent()
        xsDataAtomicComposition = XSDataAtomicComposition()

        xsDataAtom3 = XSDataAtom()
        xsDataAtom3.setSymbol(XSDataString("Na"))
        xsDataAtom3.setConcentration(XSDataDouble(1000))
        xsDataAtom4 = XSDataAtom()
        xsDataAtom4.setSymbol(XSDataString("Cl"))
        xsDataAtom4.setConcentration(XSDataDouble(1000))

        xsDataAtomicComposition.addAtom(xsDataAtom3)
        xsDataAtomicComposition.addAtom(xsDataAtom4)
        xsDataSolvent.setAtoms(xsDataAtomicComposition)

        xsDataComposition.setStructure(xsDataStructure)
        xsDataComposition.setSolvent(xsDataSolvent)
        xsDataSampleCrystalMM.setChemicalComposition(xsDataComposition)

        xsDataSampleCrystalMM.setSize(XSDataSize(XSDataLength(0.1), XSDataLength(0.1), XSDataLength(0.1)))

        xsDataCrystal = XSDataCrystal()
        xsDataCell = XSDataCell(angle_alpha=XSDataAngle(90.0),
                                angle_beta=XSDataAngle(90.0),
                                angle_gamma=XSDataAngle(90.0),
                                length_a=XSDataLength(78.9),
                                length_b=XSDataLength(95.162),
                                length_c=XSDataLength(104.087))
        xsDataCrystal.setCell(xsDataCell)

        xsDataSpaceGroup = XSDataSpaceGroup()
        xsDataSpaceGroup.setITNumber(XSDataInteger(16))
        xsDataCrystal.setSpaceGroup(xsDataSpaceGroup)

        xsDataSampleCrystalMM.setSusceptibility(XSDataDouble(1.5))

        xsDataStrategy.setCrystalRefined(xsDataCrystal)

        xsDataStrategy.setSample(xsDataSampleCrystalMM)

        xsDataStrategy.exportToFile(self.strObtainedInputFile)

        pyStrExpectedInput = self.readAndParseFile (self.strReferenceInputFile)
        pyStrObtainedInput = self.readAndParseFile (self.strObtainedInputFile)

        xsDataInputExpected = XSDataInputStrategy.parseString(pyStrExpectedInput)
        xsDataInputObtained = XSDataInputStrategy.parseString(pyStrObtainedInput)

        EDAssert.equal(xsDataInputExpected.marshal(), xsDataInputObtained.marshal())
Example #22
0
    def testSetDataModelInput(self):
        edPluginBest = self.createPlugin()
        edConfigurationGood01 = EDConfiguration(
            os.path.join(self.strDataPath, "XSConfiguration.xml"))
        dictItemGood01 = edConfigurationGood01.get(self.getPluginName())
        edPluginBest.setConfig(dictItemGood01, _bLocal=True)
        edPluginBest.setScriptExecutable("cat")
        edPluginBest.configure()

        from XSDataBestv1_3 import XSDataInputBest
        xsDataInputBest = XSDataInputBest()

        from XSDataCommon import XSDataAbsorbedDoseRate
        from XSDataCommon import XSDataDouble
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataTime
        from XSDataCommon import XSDataFile
        from XSDataCommon import XSDataAngularSpeed
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataAngle
        from XSDataCommon import XSDataBoolean

        xsDataInputBest.setCrystalAbsorbedDoseRate(
            XSDataAbsorbedDoseRate(0.22E+06))
        xsDataInputBest.setCrystalShape(XSDataDouble(1))
        xsDataInputBest.setCrystalSusceptibility(XSDataDouble(1.5))
        xsDataInputBest.setDetectorType(XSDataString("q210-2x"))
        xsDataInputBest.setBeamExposureTime(XSDataTime(1))
        xsDataInputBest.setBeamMaxExposureTime(XSDataTime(10000))
        xsDataInputBest.setBeamMinExposureTime(XSDataTime(0.1))
        xsDataInputBest.setGoniostatMinRotationWidth(XSDataAngle(0.1))
        xsDataInputBest.setGoniostatMaxRotationSpeed(XSDataAngularSpeed(10))
        xsDataInputBest.setAimedResolution(XSDataDouble(2))
        xsDataInputBest.setAimedRedundancy(XSDataDouble(6.5))
        xsDataInputBest.setAimedCompleteness(XSDataDouble(0.9))
        xsDataInputBest.setAimedIOverSigma(XSDataDouble(3))
        xsDataInputBest.setComplexity(XSDataString("min"))
        xsDataInputBest.setAnomalousData(XSDataBoolean(False))
        fileDirectory = edPluginBest.getWorkingDirectory()

        bestFileContentDat = EDUtilsFile.readFile(
            os.path.join(self.strDataPath, "bestfile.dat"))
        xsDataInputBest.setBestFileContentDat(XSDataString(bestFileContentDat))

        bestFileContentPar = EDUtilsFile.readFile(
            os.path.join(self.strDataPath, "bestfile.par"))
        xsDataInputBest.setBestFileContentPar(XSDataString(bestFileContentPar))

        bestFileContentHKL = EDUtilsFile.readFile(
            os.path.join(self.strDataPath, "bestfile1.hkl"))
        xsDataInputBest.addBestFileContentHKL(XSDataString(bestFileContentHKL))

        xsDataInputBest.exportToFile(self.obtainedInputFile)

        pyStrExpectedInput = self.readAndParseFile(self.referenceInputFile)
        pyStrObtainedInput = self.readAndParseFile(self.obtainedInputFile)

        xsDataInputExpected = XSDataInputBest.parseString(pyStrExpectedInput)
        xsDataInputObtained = XSDataInputBest.parseString(pyStrObtainedInput)

        EDAssert.equal(xsDataInputExpected.marshal(),
                       xsDataInputObtained.marshal())
        EDUtilsFile.deleteFile(self.obtainedInputFile)

        self.cleanUp(edPluginBest)