def testDefaultChemicalComposition(self):
        edPluginStrategy = self.createPlugin()

        from XSDataCommon import XSDataAngle
        from XSDataCommon import XSDataLength
        from XSDataMXv1 import XSDataSampleCrystalMM
        from XSDataMXv1 import XSDataCrystal
        from XSDataMXv1 import XSDataCell


        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        xsDataCrystal = XSDataCrystal()
        xsDataCell = XSDataCell(XSDataAngle(90.0),
                                 XSDataAngle(90.0),
                                 XSDataAngle(90.0),
                                 XSDataLength(78.9),
                                 XSDataLength(95.162),
                                 XSDataLength(104.087))
        xsDataCrystal.setCell(xsDataCell)
        xsDataSampleCrystalMM.setCrystal(xsDataCrystal)
        inumOperators = 4

        xsDataSample2 = edPluginStrategy.getDefaultChemicalComposition(xsDataSampleCrystalMM, inumOperators)
        strChainType = xsDataSample2.getStructure().getChain()[0].getType()
        EDAssert.equal("protein", strChainType.getValue())
Example #2
0
    def testDefaultChemicalComposition(self):
        edPluginStrategy = self.createPlugin()

        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        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)
        xsDataSampleCrystalMM.setCrystal(xsDataCrystal)
        inumOperators = 4

        xsDataSample2 = edPluginStrategy.getDefaultChemicalComposition(xsDataSampleCrystalMM, inumOperators)
        pyStrChainType = xsDataSample2.getStructure().getChain()[0].getType()
        EDAssert.equal("protein", pyStrChainType.getValue())
    def testDefaultChemicalComposition(self):
        edPluginStrategy = self.createPlugin()

        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        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)
        xsDataSampleCrystalMM.setCrystal(xsDataCrystal)
        inumOperators = 4

        xsDataSample2 = edPluginStrategy.getDefaultChemicalComposition(xsDataSampleCrystalMM, inumOperators)
        pyStrChainType = xsDataSample2.getStructure().getChain()[0].getType()
        EDAssert.equal("protein", pyStrChainType.getValue())
 def createInputCharacterisationFromSubWedges(self):
     self.DEBUG("EDPluginControlInterfacev1_3.createInputCharacterisationFromSubWedges")
     xsDataResultSubWedgeAssemble = self.edPluginControlSubWedgeAssemble.getDataOutput()
     self.xsDataInputCharacterisation = XSDataInputCharacterisation()
     xsDataCollection = XSDataCollection()
     # Default exposure time (for the moment, this value should be
     # possible to read from the command line)
     if self.xsDataDiffractionPlan is None:
         self.xsDataDiffractionPlan = XSDataDiffractionPlan()
     if (not xsDataResultSubWedgeAssemble is None):
         pyListSubWedge = xsDataResultSubWedgeAssemble.getSubWedge()
         xsDataCollection.setSubWedge(pyListSubWedge)
         for xsDataSubWedge in pyListSubWedge:
             if (self.strComplexity is not None):
                 self.xsDataDiffractionPlan.setComplexity(XSDataString(self.strComplexity))
             if (self.fFlux is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setFlux(XSDataFlux(self.fFlux))
             if (self.fBeamSizeX is not None) and (self.fBeamSizeY is not None):
                 xsDataSize = XSDataSize()
                 xsDataSize.setX(XSDataLength(self.fBeamSizeX))
                 xsDataSize.setY(XSDataLength(self.fBeamSizeY))
                 xsDataSubWedge.getExperimentalCondition().getBeam().setSize(xsDataSize)
             if (self.fApertureSize is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setApertureSize(XSDataLength(self.fApertureSize))
             if (self.fBeamPosX is not None):
                 xsDataSubWedge.getExperimentalCondition().getDetector().setBeamPositionX(XSDataLength(self.fBeamPosX))
             if (self.fBeamPosY is not None):
                 xsDataSubWedge.getExperimentalCondition().getDetector().setBeamPositionY(XSDataLength(self.fBeamPosY))
             if (self.fMinExposureTimePerImage is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setMinExposureTimePerImage(XSDataTime(self.fMinExposureTimePerImage))
             if (self.fTransmission is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setTransmission(XSDataDouble(self.fTransmission))
             if (self.fWavelength is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setWavelength(XSDataWavelength(self.fWavelength))
             if self.fMinOscillationWidth != None:
                 xsDataSubWedge.getExperimentalCondition().getGoniostat().setMinOscillationWidth(XSDataAngle(self.fMinOscillationWidth))
             if self.fMaxOscillationSpeed != None:
                 xsDataSubWedge.getExperimentalCondition().getGoniostat().setMaxOscillationSpeed(XSDataAngularSpeed(self.fMaxOscillationSpeed))
     if (self.strForcedSpaceGroup is not None):
         self.xsDataDiffractionPlan.setForcedSpaceGroup(XSDataString(self.strForcedSpaceGroup))
     self.xsDataDiffractionPlan.setAnomalousData(XSDataBoolean(self.bAnomalousData))
     self.xsDataDiffractionPlan.setMaxExposureTimePerDataCollection(XSDataTime(self.fMaxExposureTimePerDataCollection))
     if (self.strStrategyOption is not None):
         self.xsDataDiffractionPlan.setStrategyOption(XSDataString(self.strStrategyOption))
     xsDataCollection.setDiffractionPlan(self.xsDataDiffractionPlan)
     if self.xsDataSample is not None:
         xsDataCollection.setSample(XSDataSampleCrystalMM.parseString(self.xsDataSample.marshal()))
     self.xsDataInputCharacterisation.setDataCollection(xsDataCollection)
Example #5
0
 def createInputCharacterisationFromSubWedges(self):
     self.DEBUG("EDPluginControlInterfacev1_2.createInputCharacterisationFromSubWedges")
     xsDataResultSubWedgeAssemble = self.edPluginControlSubWedgeAssemble.getDataOutput()
     self.xsDataInputCharacterisation = XSDataInputCharacterisation()
     xsDataCollection = XSDataCollection()
     # Default exposure time (for the moment, this value should be
     # possible to read from the command line)
     if self.xsDataDiffractionPlan is None:
         self.xsDataDiffractionPlan = XSDataDiffractionPlan()
     if (not xsDataResultSubWedgeAssemble is None):
         pyListSubWedge = xsDataResultSubWedgeAssemble.getSubWedge()
         xsDataCollection.setSubWedge(pyListSubWedge)
         for xsDataSubWedge in pyListSubWedge:
             if (self.strComplexity is not None):
                 self.xsDataDiffractionPlan.setComplexity(XSDataString(self.strComplexity))
             if (self.fFlux is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setFlux(XSDataFlux(self.fFlux))
             if (self.fBeamSizeX is not None) and (self.fBeamSizeY is not None):
                 xsDataSize = XSDataSize()
                 xsDataSize.setX(XSDataLength(self.fBeamSizeX))
                 xsDataSize.setY(XSDataLength(self.fBeamSizeY))
                 xsDataSubWedge.getExperimentalCondition().getBeam().setSize(xsDataSize)
             if (self.fBeamPosX is not None):
                 xsDataSubWedge.getExperimentalCondition().getDetector().setBeamPositionX(XSDataLength(self.fBeamPosX))
             if (self.fBeamPosY is not None):
                 xsDataSubWedge.getExperimentalCondition().getDetector().setBeamPositionY(XSDataLength(self.fBeamPosY))
             if (self.fMinExposureTimePerImage is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setMinExposureTimePerImage(XSDataTime(self.fMinExposureTimePerImage))
             if (self.fTransmission is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setTransmission(XSDataDouble(self.fTransmission))
             if (self.fWavelength is not None):
                 xsDataSubWedge.getExperimentalCondition().getBeam().setWavelength(XSDataWavelength(self.fWavelength))
             if self.fMinOscillationWidth != None:
                 xsDataSubWedge.getExperimentalCondition().getGoniostat().setMinOscillationWidth(XSDataAngle(self.fMinOscillationWidth))
             if self.fMaxOscillationSpeed != None:
                 xsDataSubWedge.getExperimentalCondition().getGoniostat().setMaxOscillationSpeed(XSDataAngularSpeed(self.fMaxOscillationSpeed))
     if (self.strForcedSpaceGroup is not None):
         self.xsDataDiffractionPlan.setForcedSpaceGroup(XSDataString(self.strForcedSpaceGroup))
     self.xsDataDiffractionPlan.setAnomalousData(XSDataBoolean(self.bAnomalousData))
     self.xsDataDiffractionPlan.setMaxExposureTimePerDataCollection(XSDataTime(self.fMaxExposureTimePerDataCollection))
     if (self.strStrategyOption is not None):
         self.xsDataDiffractionPlan.setStrategyOption(XSDataString(self.strStrategyOption))
     xsDataCollection.setDiffractionPlan(self.xsDataDiffractionPlan)
     if self.xsDataSample is not None:
         xsDataCollection.setSample(XSDataSampleCrystalMM.parseString(self.xsDataSample.marshal()))
     self.xsDataInputCharacterisation.setDataCollection(xsDataCollection)
     self.xsDataInputCharacterisation.setToken(self.xsDataToken)
Example #6
0
class EDPluginControlStrategyv1_2(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """
    def __init__(self):
        """
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputStrategy)

        self._strPluginRaddoseName = "EDPluginRaddosev10"
        self._edPluginRaddose = None
        self._edHandlerXSDataRaddose = None

        self._strPluginBestName = "EDPluginBestv1_2"
        self._edPluginBest = None
        self._edHandlerXSDataBest = None

        self._strPluginPlotGleName = "EDPluginExecPlotGlev1_0"
        self._edPluginPlotGle = None

        self._strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self._strSymopHome = None

        self._xsDataSampleCopy = None

        # For default chemical composition
        self._fAverageAminoAcidVolume = 135.49
        self._fAverageCrystalSolventContent = 0.47
        self._fAverageSulfurContentPerAminoacid = 0.05
        self._fAverageSulfurConcentration = 314

        # This varaible determines if Raddose should be executed or not
        self._bEstimateRadiationDamage = None

        # Raddose log file
        self.xsDataFileRaddoseLog = None

    def setSymopHome(self, _strSymopHome):
        self._strSymopHome = _strSymopHome

    def getSymopHome(self):
        return self._strSymopHome

    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if (xsDataSampleCrystalMM is None):
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if (xsDataCrystal is not None):
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue(
                ):
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find(
                        "-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam(
            ).getFlux() is None:
                strWarningMessage = "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                EDVerbose.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True

        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam(
            ).getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                EDVerbose.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if (self._edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: " +
                                self._strPluginRaddoseName +
                                " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput(
                ).getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper()
                    EDVerbose.DEBUG(
                        "EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: "
                        + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                            strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                            'EDPluginControlStrategyv1_2.preProcess',
                            "Problem to calculate Number of symmetry operators",
                            detail)
                        EDVerbose.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError, strErrorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlStrategyv1_2.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self._xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d"
                            % iSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(iSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlStrategyv1_2.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
class EDPluginControlKappaStrategyv2_0(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """
    def __init__(self):
        EDPluginControl.__init__(self)
        #self.setXSDataInputClass(EDList)

        self.setRequiredToHaveConfiguration(True)

        self.strPluginRaddoseName = "EDPluginRaddosev10"
        self.edPluginRaddose = None
        self.edHandlerXSDataRaddose = None

        self.strPluginBestName = "EDPluginBestv1_2"
        self.edPluginBest = None
        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2
        self.edHandlerXSDataBest = EDHandlerXSDataBestv1_2()

        self.strPluginAlignmentName = "EDPluginSTACAlignmentv2_0"
        self.edPluginAlignment = None
        self.edHandlerXSDataAlignment = None

        self.strPluginKappaStrategyName = "EDPluginSTACStrategyv2_0"
        self.edPluginKappaStrategy = None
        self.edHandlerXSDataKappaStrategy = None

        self.setXSDataInputClass(XSDataInputStrategy, "mxv1InputStrategy")
        EDFactoryPluginStatic.loadModule("XSDataMXv2")
        import XSDataMXv2
        self.setXSDataInputClass(XSDataMXv2.XSDataCollection,
                                 "mxv2DataCollection")
        import XSDataMXv1
        self.setXSDataInputClass(XSDataMXv1.XSDataIndexingResult,
                                 "mxv1IndexingResult")

        #disable kappa by default
        self.KappaStrategy = 0

        self.strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self.strSymopHome = os.path.normpath("/opt/pxsoft/ccp4-6.0.2/lib/data")

        self.xsDataSampleCopy = None

        # For default chemical composition
        self.fAverageAminoAcidVolume = 135.49
        self.fAverageCrystalSolventContent = 0.47
        self.fAverageSulfurContentPerAminoacid = 0.05
        self.fAverageSulfurConcentration = 314

    def setSymopHome(self, _strSymopHome):
        self.strSymopHome = _strSymopHome

    def getSymopHome(self):
        return self.strSymopHome

    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess...")
        self.edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput(
            "mxv1InputStrategy")[0].getSample()

        if (xsDataSampleCrystalMM is None):
            self.xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput(
            "mxv1InputStrategy")[0].getCrystalRefined()
        if (xsDataCrystal is not None):
            self.xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if (self.getDataInput("mxv1InputStrategy")
            [0].getExperimentalCondition().getBeam().getFlux() is None):
            strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                'EDPluginControlKappaStrategyv2_0.preProcess',
                self.strPluginRaddoseName, "Beam Flux not set")
            EDVerbose.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)

        else:
            self.edPluginRaddose = self.loadPlugin(self.strPluginRaddoseName)

            if (self.edPluginRaddose is not None):
                EDVerbose.DEBUG(
                    "EDPluginControlKappaStrategyv2_0.preProcess: " +
                    self.strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput(
                    "mxv1InputStrategy")[0].getDiffractionPlan(
                    ).getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                strNumOperators = None
                strSpaceGroup = None
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue()
                    EDVerbose.DEBUG(
                        "EDPluginControlKappaStrategyv2_0.preProcess: Forced Space Group Found: "
                        + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                            strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                            'EDPluginControlKappaStrategyv2_0.preProcess',
                            "Problem to calculate Number of symmetry operators",
                            detail)
                        EDVerbose.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError, strErrorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroup = self.xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup, strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlKappaStrategyv2_0.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        dSpaceGroupITNumber = self.xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Number Found by indexing: %d"
                            % dSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(dSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlKappaStrategyv2_0.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
Example #8
0
    def testUpdateChemicalCompositionWithNativeSulfurAtom(self):
        """
        """
        from XSDataCommon import XSDataAngle
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataInteger
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataFloat
        from XSDataMXv1 import XSDataStructure
        from XSDataMXv1 import XSDataChain
        from XSDataMXv1 import XSDataAtom
        from XSDataMXv1 import XSDataLigand
        from XSDataMXv1 import XSDataSampleCrystalMM
        from XSDataMXv1 import XSDataChemicalCompositionMM
        from XSDataMXv1 import XSDataAtomicComposition
        from XSDataMXv1 import XSDataSolvent
        from XSDataMXv1 import XSDataCell
        from XSDataMXv1 import XSDataSpaceGroup

        edPluginStrategy = self.createPlugin()
        xsPluginItemGood01 = self.getPluginConfiguration(
            os.path.join(self.strDataPath, "XSConfiguration_ESRF.xml"))
        edPluginStrategy.setConfiguration(xsPluginItemGood01)
        edPluginStrategy.configure()

        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()
        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataFloat(2))
        xsDataChain.setNumberOfMonomers(XSDataFloat(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())

        xsDataSampleCrystalMM = XSDataSampleCrystalMM()
        xsDataStructure = XSDataStructure()
        xsDataComposition = XSDataChemicalCompositionMM()
        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfCopies(XSDataFloat(2))
        xsDataChain.setNumberOfMonomers(XSDataFloat(60))
        xsDataAtom1 = XSDataAtom()
        xsDataAtom1.setSymbol(XSDataString("Se"))
        xsDataAtom1.setNumberOf(XSDataFloat(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:
            EDVerbose.unitTest(heavyAtom.getSymbol().getValue() + " : " +
                               str(heavyAtom.getNumberOf().getValue()))
            if (heavyAtom.getSymbol().getValue() == "S"):
                EDAssert.equal(3, heavyAtom.getNumberOf().getValue())
Example #9
0
 def buildChildren(self, child_, nodeName_):
     if child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'experimentalCondition':
         obj_ = XSDataExperimentalCondition()
         obj_.build(child_)
         self.setExperimentalCondition(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'diffractionPlan':
         obj_ = XSDataDiffractionPlan()
         obj_.build(child_)
         self.setDiffractionPlan(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'sample':
         obj_ = XSDataSampleCrystalMM()
         obj_.build(child_)
         self.setSample(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'imagePath':
         obj_ = XSDataFile()
         obj_.build(child_)
         self.imagePath.append(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'flux':
         obj_ = XSDataFloat()
         obj_.build(child_)
         self.setFlux(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'minExposureTimePerImage':
         obj_ = XSDataTime()
         obj_.build(child_)
         self.setMinExposureTimePerImage(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'beamSize':
         obj_ = XSDataLength()
         obj_.build(child_)
         self.setBeamSize(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'beamSizeX':
         obj_ = XSDataLength()
         obj_.build(child_)
         self.setBeamSizeX(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'beamSizeY':
         obj_ = XSDataLength()
         obj_.build(child_)
         self.setBeamSizeY(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'apertureSize':
         obj_ = XSDataLength()
         obj_.build(child_)
         self.setApertureSize(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'templateMode':
         obj_ = XSDataBoolean()
         obj_.build(child_)
         self.setTemplateMode(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'generatedTemplateFile':
         obj_ = XSDataFile()
         obj_.build(child_)
         self.setGeneratedTemplateFile(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'resultsFilePath':
         obj_ = XSDataFile()
         obj_.build(child_)
         self.setResultsFilePath(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'beamPosX':
         obj_ = XSDataFloat()
         obj_.build(child_)
         self.setBeamPosX(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'beamPosY':
         obj_ = XSDataFloat()
         obj_.build(child_)
         self.setBeamPosY(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'wavelength':
         obj_ = XSDataWavelength()
         obj_.build(child_)
         self.setWavelength(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'transmission':
         obj_ = XSDataDouble()
         obj_.build(child_)
         self.setTransmission(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'dataCollectionId':
         obj_ = XSDataInteger()
         obj_.build(child_)
         self.setDataCollectionId(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'shortComments':
         obj_ = XSDataString()
         obj_.build(child_)
         self.setShortComments(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'comments':
         obj_ = XSDataString()
         obj_.build(child_)
         self.setComments(obj_)
     elif child_.nodeType == Node.ELEMENT_NODE and \
         nodeName_ == 'inputCharacterisation':
         obj_ = XSDataInputCharacterisation()
         obj_.build(child_)
         self.setInputCharacterisation(obj_)
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess...")
        self.__edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if(xsDataSampleCrystalMM is None):
            self.__xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.__xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if(xsDataCrystal is not None):
            self.__xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if(self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None):
            warningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % ('EDPluginControlStrategyv10.preProcess', self.__strPluginRaddoseName, "Beam Flux not set")
            EDVerbose.warning(warningMessage)
            self.addWarningMessage(warningMessage)

        else:
            self.__edPluginRaddose = self.loadPlugin(self.__strPluginRaddoseName)

            if (self.__edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: " + self.__strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                if(xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue()
                    EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: Forced Space Group Found: " + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        errorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv10.preProcess', "Problem to calculate Number of symmetry operators", detail)
                        EDVerbose.error(errorMessage)
                        self.addErrorMessage(errorMessage)
                        raise RuntimeError, errorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: Space Group IT Name found by indexing: " + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            errorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv10.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(errorMessage)
                            self.addErrorMessage(errorMessage)
                            raise RuntimeError, errorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        strSpaceGroupITNumber = str(self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue())
class EDPluginControlKappaStrategyv2_0(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """
    def __init__(self):
        EDPluginControl.__init__(self)

        self.setRequiredToHaveConfiguration(True)

        self.strPluginRaddoseName = "EDPluginRaddosev10"
        self.edPluginRaddose = None
        self.edHandlerXSDataRaddose = None

        self.strPluginBestName = "EDPluginBestv1_2"
        self.edPluginBest = None
        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2
        self.edHandlerXSDataBest = EDHandlerXSDataBestv1_2()

        self.strPluginAlignmentName = "EDPluginSTACAlignmentv2_0"
        self.edPluginAlignment = None
        self.edHandlerXSDataAlignment = None

        self.strPluginKappaStrategyName = "EDPluginSTACStrategyv2_0"
        self.edPluginKappaStrategy = None
        self.edHandlerXSDataKappaStrategy = None

        self.setXSDataInputClass(XSDataInputStrategy, "mxv1InputStrategy")
        EDFactoryPluginStatic.loadModule("XSDataMXv2")
        import XSDataMXv2
        self.setXSDataInputClass(XSDataMXv2.XSDataCollection,
                                 "mxv2DataCollection")
        import XSDataMXv1
        self.setXSDataInputClass(XSDataMXv1.XSDataIndexingResult,
                                 "mxv1IndexingResult")

        # disable kappa by default
        self.KappaStrategy = 0

        self.xsDataSampleCopy = None

        # For default chemical composition
        self.fAverageAminoAcidVolume = 135.49
        self.fAverageCrystalSolventContent = 0.47
        self.fAverageSulfurContentPerAminoacid = 0.05
        self.fAverageSulfurConcentration = 314

    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        self.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess...")
        self.edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput(
            "mxv1InputStrategy")[0].getSample()

        if (xsDataSampleCrystalMM is None):
            self.xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput(
            "mxv1InputStrategy")[0].getCrystalRefined()
        if (xsDataCrystal is not None):
            self.xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if (self.getDataInput("mxv1InputStrategy")
            [0].getExperimentalCondition().getBeam().getFlux() is None):
            strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                'EDPluginControlKappaStrategyv2_0.preProcess',
                self.strPluginRaddoseName, "Beam Flux not set")
            self.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)

        else:
            self.edPluginRaddose = self.loadPlugin(self.strPluginRaddoseName)

            if (self.edPluginRaddose is not None):
                self.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess: " +
                           self.strPluginRaddoseName +
                           " Found... setting Data Input")

                xsDataStringSpaceGroup = self.getDataInput(
                    "mxv1InputStrategy")[0].getDiffractionPlan(
                    ).getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                strNumOperators = None
                strSpaceGroup = None
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue()
                    self.DEBUG(
                        "EDPluginControlKappaStrategyv2_0.preProcess: Forced Space Group Found: "
                        + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                            strSpaceGroup)
                    except Exception as detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                            'EDPluginControlKappaStrategyv2_0.preProcess',
                            "Problem to calculate Number of symmetry operators",
                            detail)
                        self.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError(strErrorMessage)
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroup = self.xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        self.DEBUG(
                            "EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup)
                        except Exception as detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlKappaStrategyv2_0.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        dSpaceGroupITNumber = self.xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        self.DEBUG(
                            "EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Number Found by indexing: %d"
                            % dSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(dSpaceGroupITNumber))
                        except Exception as detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlKappaStrategyv2_0.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)

                if (strNumOperators is not None):
                    iNumOperators = int(strNumOperators)
                else:
                    strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                        'EDPluginControlKappaStrategyv2_0.preProcess',
                        "No symmetry operators found for Space Group: ",
                        strSpaceGroup)
                    self.error(strErrorMessage)
                    self.addErrorMessage(strErrorMessage)
                    raise RuntimeError(strErrorMessage)

                xsDataChemicalComposition = self.xsDataSampleCopy.getChemicalComposition(
                )

                if (xsDataChemicalComposition is None):
                    # create a default chemical composition and assign it to the sample
                    xsDataDefaultChemicalComposition = self.getDefaultChemicalComposition(
                        self.xsDataSampleCopy, iNumOperators)
                    self.xsDataSampleCopy.setChemicalComposition(
                        xsDataDefaultChemicalComposition)
                else:
                    # Check for Sulfur atoms, if none, add native sulfur atoms
                    xsDataUpdatedChemicalComposition = self.updateChemicalComposition(
                        xsDataChemicalComposition)
                    self.xsDataSampleCopy.setChemicalComposition(
                        xsDataUpdatedChemicalComposition)

                # create Data Input for Raddose
                from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10
                self.edHandlerXSDataRaddose = EDHandlerXSDataRaddosev10()
                xsDataBeam = self.getDataInput("mxv1InputStrategy")[
                    0].getExperimentalCondition().getBeam()

                xsDataRaddoseInput = None
                iNumberOfImages = 1
                self.warning("Number of images for RADDOSE forced to 1")
                try:
                    xsDataRaddoseInput = self.edHandlerXSDataRaddose.getXSDataRaddoseInput(
                        xsDataBeam, self.xsDataSampleCopy, iNumOperators,
                        iNumberOfImages)

                except Exception as detail:
                    strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                        'EDPluginControlKappaStrategyv2_0.preProcess',
                        self.strPluginRaddoseName,
                        "EDHandlerXSDataRaddose : " + detail)
                    self.warning(strWarningMessage)
                    self.addWarningMessage(strWarningMessage)

                if (xsDataRaddoseInput is not None):
                    self.edPluginRaddose.setDataInput(xsDataRaddoseInput)
                    self.edPluginRaddose.setBaseDirectory(
                        self.getWorkingDirectory())
                    self.edPluginRaddose.setBaseName(self.strPluginRaddoseName)

                    # More checks?
#                    try:
#                        self.edPluginRaddose.setDataInput( xsDataRaddoseInput )
#                        self.edPluginRaddose.setBaseDirectory( self.getWorkingDirectory() )
#                        self.edPluginRaddose.setBaseName( self.strPluginRaddoseName )
#
#                    except Exception, detail:
#                        strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % ('EDPluginControlStrategyv1_1.preProcess', self.strPluginRaddoseName,  detail ) )
#                        self.warning( strWarningMessage )
#                        self.addWarningMessage( strWarningMessage )

            else:
                strErrorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                    'EDPluginControlKappaStrategyv2_0.preProcess',
                    self.strPluginRaddoseName)
                self.error(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                raise RuntimeError(strErrorMessage)

        self.edPluginBest = self.loadPlugin(self.strPluginBestName)
        if (self.edPluginBest is None):
            strErrorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                'EDPluginControlKappaStrategyv2_0.preProcess',
                self.strPluginBestName)
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)
        else:
            self.edPluginBest.setBaseDirectory(self.getWorkingDirectory())
            self.edPluginBest.setBaseName(self.strPluginBestName)

        if (self.KappaStrategy):
            # Alignment
            self.edPluginAlignment = self.loadPlugin(
                self.strPluginAlignmentName)
            if (self.edPluginAlignment is None):
                errorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                    'EDPluginControlKappaStrategyv2_0.preProcess',
                    self.strPluginAlignmentName)
                self.error(errorMessage)
                self.addErrorMessage(errorMessage)
                # do not kill the application just because this feature is not available
                # raise RuntimeError, errorMessage
            else:
                self.edPluginAlignment.setBaseDirectory(
                    self.getWorkingDirectory())
                self.edPluginAlignment.setBaseName(self.strPluginAlignmentName)

            # KappaStaregy
            self.edPluginKappaStrategy = self.loadPlugin(
                self.strPluginKappaStrategyName)
            if (self.edPluginKappaStrategy is None):
                errorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                    'EDPluginControlKappaStrategyv2_0.preProcess',
                    self.strPluginKappaStrategyName)
                self.error(errorMessage)
                self.addErrorMessage(errorMessage)
                # raise RuntimeError, errorMessage
            else:
                self.edPluginKappaStrategy.setBaseDirectory(
                    self.getWorkingDirectory())
                self.edPluginKappaStrategy.setBaseName(
                    self.strPluginKappaStrategyName)

    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlKappaStrategyv2_0.configure")
        bKappaOn = self.config.get("KAPPA")
        if bKappaOn:
            # self.strPluginStrategyName = "EDPluginControlStrategyv10"
            # self.strPluginStrategyName = "EDPluginControlStrategyv2_0"
            self.KappaStrategy = 1
        else:
            self.KappaStrategy = 0

    def process(self, _edObject=None):
        """
        """
        EDPluginControl.process(self, _edObject)
        self.DEBUG("EDPluginControlKappaStrategyv2_0.process...")

        # In case Beam Flux has not been set, The plugin Raddose has not been created, so it could be None
        # and it won't be launched in this case
        if (self.edPluginRaddose is not None):
            self.connectProcess(self.edPluginRaddose.executeSynchronous)
            self.edPluginRaddose.connectSUCCESS(self.doRaddoseToBestTransition)
            self.edPluginRaddose.connectFAILURE(self.doFailureActionRaddose)
        else:
            # The plugin Best should not be None as this has been checked in the preProcess method... Double check it anyway
            if (self.edPluginBest is not None):
                self.connectProcess(self.executeBest)

        # Launches Best anyway whether Raddose has been launched or not
        # The plugin Best should not be None as this has been checked in the preProcess method... Double check it anyway
        if (self.edPluginBest is not None):
            self.edPluginBest.connectSUCCESS(self.doSuccessActionBest)
            self.edPluginBest.connectFAILURE(self.doFailureActionBest)

        # Kappa strategy calculation
        if self.hasDataInput("mxv2DataCollection"):
            if self.edPluginAlignment is not None:
                self.connectProcess(self.doBestToAlignmentTransition)
#                self.edPluginAlignment.connectSUCCESS( self.doAlignmentToKappaStrategyTransition )
#                self.edPluginAlignment.connectFAILURE( self.doFailureActionAlignment )
#                self.edPluginKappaStrategy.connectSUCCESS( self.doKappaStrategyMerge )
#                self.edPluginKappaStrategy.connectFAILURE( self.doFailureActionKappaStrategy )

# Kappa strategy calculation
            if self.edPluginKappaStrategy is not None:
                self.connectProcess(self.doAlignmentToStrategyTransition)
#                self.edPluginKappaStrategy.connectSUCCESS( self.doKappaStrategyMerge )
#                self.edPluginKappaStrategy.connectFAILURE( self.doFailureActionKappaStrategy )

    def postProcess(self, _edObject=None):
        """
        """
        EDPluginControl.postProcess(self, _edObject)
        self.DEBUG("EDPluginControlKappaStrategyv2_0.postProcess...")

        xsDataResultBest = self.edPluginBest.getDataOutput()
        xsDataResultStrategy = None

        if (xsDataResultBest is not None):
            xsDataResultStrategy = self.edHandlerXSDataBest.getXSDataResultStrategy(
                xsDataResultBest,
                self.getDataInput("mxv1InputStrategy")
                [0].getExperimentalCondition(), self.xsDataSampleCopy)

        self.setDataOutput(xsDataResultStrategy)

        # possibleAlignments
        try:
            self.setDataOutput(self.edPluginAlignment.getDataOutput(),
                               "possibleOrientations")
        except:
            self.WARNING("Could not get the list of Possible orientations.")

    def doRaddoseToBestTransition(self, _edPlugin):
        """
        """
        self.DEBUG(
            "EDPluginControlKappaStrategyv2_0.doRaddoseToBestTransition")
        self.retrieveSuccessMessages(
            _edPlugin,
            "EDPluginControlKappaStrategyv2_0.doRaddoseToBestTransition")

        xsDataRaddoseOutput = self.edPluginRaddose.getDataOutput()

        # update the strategy data with the data coming from Raddose
        self.xsDataSampleCopy.setAbsorbedDoseRate(
            xsDataRaddoseOutput.getAbsorbedDoseRate())

        # Call the Best Translator layer

        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(
            self.getDataInput("mxv1InputStrategy")[0].marshal())
        xsDataInputStrategyCopy.setSample(self.xsDataSampleCopy)

        xsDataInputBest = self.edHandlerXSDataBest.getXSDataInputBest(
            xsDataInputStrategyCopy)

        self.edPluginBest.setDataInput(xsDataInputBest)
        self.edPluginBest.executeSynchronous()

    def doBestToAlignmentTransition(self, _edPlugin):
        """
        """
        self.DEBUG(
            "EDPluginControlKappaStrategyv2_0.doBestToAlignmentTransition")
        # self.retrieveSuccessMessages( _edPlugin, "EDPluginControlStrategyv01.doRaddoseToBestTransition" )

        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(
            self.getDataInput("mxv1InputStrategy")[0].marshal())
        xsDataInputStrategyCopy.setSample(self.xsDataSampleCopy)

        xsDataInputBest = self.edHandlerXSDataBest.getXSDataInputBest(
            xsDataInputStrategyCopy)
        self.edPluginAlignment.setDataInput(xsDataInputBest, "inputBest")
        self.edPluginAlignment.setDataInput(
            self.getDataInput("mxv2DataCollection")[0], "dataCollection")
        self.edPluginAlignment.setDataInput(
            self.getDataInput("mxv1IndexingResult")[0], "indexingResult")

        self.edPluginAlignment.executeSynchronous()

    def doAlignmentToStrategyTransition(self, _edPlugin):
        """
        """
        self.DEBUG("EDPluginControlKappaStrategyv2_0.doAlignmentToStrategy")
        # self.retrieveSuccessMessages( _edPlugin, "EDPluginControlStrategyv01.doRaddoseToBestTransition" )

        # Call the Best Translator layer
        # from XSDataSTACv01 import kappa_alignment_response
        # from XSDataSTACv01 import kappa_strategy_request
        # from XSDataSTACv01 import strategy_request

        self.xsKappaStrategyRequest = kappa_strategy_request()
        # self.xsKappaStrategyRequest.build(???)

        KappaAlignmentResponse = self.edPluginAlignment.getDataOutput()
        xsDataKappaAlignmentList = KappaAlignmentResponse.getPossible_orientation(
        )
        self.xsKappaStrategyRequest.setDesired_datum(xsDataKappaAlignmentList)

        self.xsksreq = strategy_request()
        self.xsKappaStrategyRequest.setStandard_request(self.xsksreq)

        self.edPluginKappaStrategy.setDataInput(self.xsKappaStrategyRequest,
                                                "kappa_strategy_request")
        self.edPluginKappaStrategy.setDataInput(
            self.getDataInput("mxv2DataCollection")[0], "dataCollection")
        self.edPluginKappaStrategy.setDataInput(
            self.getDataInput("mxv1InputStrategy")[0], "inputBest")

        # self.edPluginKappaStrategy.m_xsDataBestFileContentPar=self.getDataInput()[0].getBestFileContentPar()
        self.edPluginKappaStrategy.executeSynchronous()

    def doFailureActionRaddose(self, _edPlugin):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlKappaStrategyv2_0.doFailureActionRaddose")
        self.retrieveFailureMessages(
            _edPlugin,
            "EDPluginControlKappaStrategyv2_0.doFailureActionRaddose")
        strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
            'EDPluginControlKappaStrategyv2_0.doFailureActionRaddose',
            self.strPluginRaddoseName, "Raddose failure")
        self.warning(strWarningMessage)
        self.addWarningMessage(strWarningMessage)
        self.executeBest(self)

    def executeBest(self, _edPlugin):
        xsDataInputBest = None
        # Call the Best Translator layer

        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2
        self.__edHandlerXSDataBest = EDHandlerXSDataBestv1_2()
        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(
            self.getDataInput("mxv1InputStrategy")[0].marshal())
        xsDataInputStrategyCopy.setSample(self.xsDataSampleCopy)
        xsDataInputBest = self.__edHandlerXSDataBest.getXSDataInputBest(
            xsDataInputStrategyCopy)
        self.edPluginBest.setDataInput(xsDataInputBest)
        self.edPluginBest.executeSynchronous()

    def doSuccessActionBest(self, _edPlugin):
        """
        retrieve the potential warning messages
        """
        self.DEBUG("EDPluginControlKappaStrategyv2_0.doSuccessActionBest")
        self.retrieveSuccessMessages(
            _edPlugin, "EDPluginControlKappaStrategyv2_0.doSuccessActionBest")

    def doFailureActionBest(self, _edPlugin):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlKappaStrategyv2_0.doFailureActionBest")
        self.retrieveFailureMessages(
            _edPlugin, "EDPluginControlKappaStrategyv2_0.doFailureActionBest")

    def getDefaultChemicalComposition(self, _xsDataSample, _inumOperators):
        """
        """
        xsDataCell = _xsDataSample.getCrystal().getCell()
        a = xsDataCell.getLength_a().getValue()
        b = xsDataCell.getLength_b().getValue()
        c = xsDataCell.getLength_c().getValue()
        alpha = math.radians(xsDataCell.getAngle_alpha().getValue())
        beta = math.radians(xsDataCell.getAngle_beta().getValue())
        gamma = math.radians(xsDataCell.getAngle_gamma().getValue())

        fUnitCellVolume = a * b * c * (
            math.sqrt(1 - math.cos(alpha) * math.cos(alpha) - math.cos(beta) *
                      math.cos(beta) - math.cos(gamma) * math.cos(gamma) +
                      2 * math.cos(alpha) * math.cos(beta) * math.cos(gamma)))
        fPolymerVolume = fUnitCellVolume * (1 -
                                            self.fAverageCrystalSolventContent)
        fNumberOfMonomersPerUnitCell = fPolymerVolume / self.fAverageAminoAcidVolume
        fNumberOfMonomersPerAsymmetricUnit = fNumberOfMonomersPerUnitCell / _inumOperators
        iNumberOfSulfurAtom = int(
            round(fNumberOfMonomersPerAsymmetricUnit *
                  self.fAverageSulfurContentPerAminoacid))

        xsDataAtom = XSDataAtom()
        xsDataAtom.setSymbol(XSDataString("S"))
        xsDataAtom.setNumberOf(XSDataDouble(iNumberOfSulfurAtom))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomicComposition.addAtom(xsDataAtom)

        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfMonomers(
            XSDataDouble(round(fNumberOfMonomersPerAsymmetricUnit)))
        xsDataChain.setNumberOfCopies(XSDataDouble(1))
        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)

        xsDataStructure = XSDataStructure()
        xsDataStructure.addChain(xsDataChain)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(1))

        xsDataAtomSolvent = XSDataAtom()
        xsDataAtomSolvent.setSymbol(XSDataString("S"))
        xsDataAtomSolvent.setConcentration(
            XSDataDouble(self.fAverageSulfurConcentration))
        xsDataAtomicCompositionSolvent = XSDataAtomicComposition()
        xsDataAtomicCompositionSolvent.addAtom(xsDataAtomSolvent)
        xsDataSolvent = XSDataSolvent()
        xsDataSolvent.setAtoms(xsDataAtomicCompositionSolvent)

        xsDataChemicalCompositionMM = XSDataChemicalCompositionMM()
        xsDataChemicalCompositionMM.setSolvent(xsDataSolvent)
        xsDataChemicalCompositionMM.setStructure(xsDataStructure)

        return xsDataChemicalCompositionMM

    def updateChemicalComposition(self, _xsDataChemicalComposition):
        """
        """
        xsDataChemicalComposition = _xsDataChemicalComposition

        for chain in xsDataChemicalComposition.getStructure().getChain():
            if (chain.getType().getValue() == "protein"):
                bSulfurExists = False
                xsDataAtomicCompositionHeavyAtoms = chain.getHeavyAtoms()
                if (xsDataAtomicCompositionHeavyAtoms is None):
                    xsDataAtomicCompositionHeavyAtoms = XSDataAtomicComposition(
                    )
                else:
                    for heavyAtom in xsDataAtomicCompositionHeavyAtoms.getAtom(
                    ):
                        if (heavyAtom.getSymbol().getValue() == "S"
                                or heavyAtom.getSymbol().getValue() == "s"):
                            bSulfurExists = True

                # all protein chains should contain sulfur atom as a percentage of the number
                # of amino acids. Add them if the user did not input them.
                if (bSulfurExists == False):
                    iNumberOfSulfurAtom = int(
                        round(chain.getNumberOfMonomers().getValue() * 0.05))
                    xsDataSulfurAtom = XSDataAtom()
                    xsDataSulfurAtom.setSymbol(XSDataString("S"))
                    xsDataSulfurAtom.setNumberOf(
                        XSDataDouble(iNumberOfSulfurAtom))
                    xsDataAtomicCompositionHeavyAtoms.addAtom(xsDataSulfurAtom)
                    chain.setHeavyAtoms(xsDataAtomicCompositionHeavyAtoms)

        return xsDataChemicalComposition

    def generateExecutiveSummary(self, _edPlugin):
        """
        Generates a summary of the execution of the plugin.
        """
        self.DEBUG("EDPluginControlKappaStrategyv2_0.generateExecutiveSummary")
        self.addExecutiveSummaryLine("Summary of kappa strategy:")
        self.addErrorWarningMessagesToExecutiveSummary()

        xsDataResultStrategy = self.getDataOutput()

        if (self.edPluginRaddose is not None):
            if (self.edPluginRaddose.getDataOutput() is not None):
                self.appendExecutiveSummary(self.edPluginRaddose, "Raddose : ")
                self.addExecutiveSummaryLine("")
                self.addExecutiveSummaryLine(
                    "Calculations assuming polymer crystal with:")
                self.addExecutiveSummaryLine(
                    "------------------------------------------")
                self.addExecutiveSummaryLine("")

                xsDataStructure = xsDataResultStrategy.getCollectionPlan(
                )[0].getCollectionStrategy().getSample(
                ).getChemicalComposition().getStructure()

                self.addExecutiveSummaryLine(
                    "Number of structure copies in asymmetric unit: %.2f" %
                    xsDataStructure.getNumberOfCopiesInAsymmetricUnit(
                    ).getValue())
                self.addExecutiveSummaryLine("")

                chains = xsDataStructure.getChain()
                self.addExecutiveSummaryLine("Chains:")
                for chain in chains:
                    strChainType = chain.getType().getValue()
                    self.addExecutiveSummaryLine(
                        "    Type                           : %s" %
                        strChainType)
                    if (strChainType == "protein"):
                        self.addExecutiveSummaryLine(
                            "    Number of residues             : %.2f" %
                            chain.getNumberOfMonomers().getValue())
                    elif (strChainType == "dna" or strChainType == "rna"):
                        self.addExecutiveSummaryLine(
                            "    Number of nucleotides          : %.2f" %
                            chain.getNumberOfMonomers().getValue())
                    strHeavyAtomsChain = "    Number of heavy atoms          :"
                    if (chain.getHeavyAtoms() is not None):
                        heavyAtomsChain = chain.getHeavyAtoms().getAtom()
                        for heavyAtomChain in heavyAtomsChain:
                            strHeavyAtomsChain = strHeavyAtomsChain + " %s=%d" % (
                                heavyAtomChain.getSymbol().getValue(),
                                heavyAtomChain.getNumberOf().getValue())
                    else:
                        strHeavyAtomsChain = strHeavyAtomsChain + " No heavy atoms"
                    self.addExecutiveSummaryLine(strHeavyAtomsChain)

                    self.addExecutiveSummaryLine(
                        "    Number of copies in structure  : %.2f" %
                        chain.getNumberOfCopies().getValue())
                    self.addExecutiveSummaryLine("")

                ligands = xsDataStructure.getLigand()
                if (len(ligands) != 0):
                    self.addExecutiveSummaryLine("Ligands:")

                for ligand in ligands:
                    self.addExecutiveSummaryLine(
                        "    Number of light atoms          : %.2f" %
                        ligand.getNumberOfLightAtoms().getValue())
                    strHeavyAtomsLigand = "    Number of heavy atoms          :"
                    if (ligand.getHeavyAtoms() is not None):
                        heavyAtomsLigand = ligand.getHeavyAtoms().getAtom()
                        for heavyAtomLigand in heavyAtomsLigand:
                            strHeavyAtomsLigand = strHeavyAtomsLigand + " %s=%d" % (
                                heavyAtomLigand.getSymbol().getValue(),
                                heavyAtomLigand.getNumberOf().getValue())
                    else:
                        strHeavyAtomsChain = strHeavyAtomsChain + " No heavy atoms"
                    self.addExecutiveSummaryLine(strHeavyAtomsLigand)
                    self.addExecutiveSummaryLine(
                        "    Number of copies in structure  : %.2f" %
                        chain.getNumberOfCopies().getValue())
                    self.addExecutiveSummaryLine("")

        if (self.edPluginBest is not None):
            if (self.edPluginBest.getDataOutput() is not None):
                self.appendExecutiveSummary(self.edPluginBest, "Best : ")
                self.addExecutiveSummaryLine("")

        if (self.edPluginAlignment is not None):
            # if ( self.edPluginAlignment.getDataOutput() is not None ):
            self.appendExecutiveSummary(self.edPluginAlignment,
                                        "STAC - Alignment : ")
            self.addExecutiveSummaryLine("")

        if (self.edPluginKappaStrategy is not None):
            # if ( self.edPluginAlignment.getDataOutput() is not None ):
            self.appendExecutiveSummary(self.edPluginKappaStrategy,
                                        "STAC - Strategy : ")
            self.addExecutiveSummaryLine("")
class EDPluginControlStrategyv1_2(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """

    def __init__(self):
        """
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputStrategy)

        self._strPluginRaddoseName = "EDPluginRaddosev10"
        self._edPluginRaddose = None
        self._edHandlerXSDataRaddose = None

        self._strPluginBestName = "EDPluginBestv1_2"
        self._edPluginBest = None
        self._edHandlerXSDataBest = None

        self._strPluginPlotGleName = "EDPluginExecPlotGlev1_1"
        self._edPluginPlotGle = None

        self._strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self._strSymopHome = None

        self._xsDataSampleCopy = None

        # For default chemical composition
        self._fAverageAminoAcidVolume = 135.49
        self._fAverageCrystalSolventContent = 0.47
        self._fAverageSulfurContentPerAminoacid = 0.05
        self._fAverageSulfurConcentration = 314

        # This varaible determines if Raddose should be executed or not
        self._bEstimateRadiationDamage = None

        # Raddose log file
        self.xsDataFileRaddoseLog = None

        self.roundUpToEven100 = False

    def setSymopHome(self, _strSymopHome):
        self._strSymopHome = _strSymopHome

    def getSymopHome(self):
        return self._strSymopHome

    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if xsDataSampleCrystalMM is None:
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if xsDataCrystal is not None:
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue():
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find("-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strWarningMessage = (
                    "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                )
                self.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True

        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                self.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if self._edPluginRaddose is not None:
                self.DEBUG(
                    "EDPluginControlStrategyv1_2.preProcess: "
                    + self._strPluginRaddoseName
                    + " Found... setting Data Input"
                )

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                bSpaceGroupForced = False
                if xsDataStringSpaceGroup is not None:
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper().replace(" ", "")
                    if strSpaceGroup != "":
                        self.DEBUG("EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: " + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup, strFileSymop
                            )
                            bSpaceGroupForced = True
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail
                            )
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                if not bSpaceGroupForced:
                    # Space Group has NOT been forced
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if xsDataStringSpaceGroup is not None:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName
                        )
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName, strFileSymop
                            )
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail
                            )
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = (
                            self._xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue()
                        )
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d"
                            % iSpaceGroupITNumber
                        )
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(iSpaceGroupITNumber), strFileSymop
                            )
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail
                            )
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)

                if strNumOperators is not None:
                    iNumOperators = int(strNumOperators)
                else:
                    strErrorMessage = "EDPluginControlStrategyv1_2: No symmetry operators found for Space Group: {0}".format(
                        strNumOperators
                    )
                    self.error(strErrorMessage)
                    self.addErrorMessage(strErrorMessage)
                    raise RuntimeError(strErrorMessage)

                xsDataChemicalComposition = self._xsDataSampleCopy.getChemicalComposition()

                if xsDataChemicalComposition is None:
                    # create a default chemical composition and assign it to the sample
                    xsDataDefaultChemicalComposition = self.getDefaultChemicalComposition(
                        self._xsDataSampleCopy, iNumOperators
                    )
                    self._xsDataSampleCopy.setChemicalComposition(xsDataDefaultChemicalComposition)
                else:
                    # Check for Sulfur atoms, if none, add native sulfur atoms
                    xsDataUpdatedChemicalComposition = self.updateChemicalComposition(xsDataChemicalComposition)
                    self._xsDataSampleCopy.setChemicalComposition(xsDataUpdatedChemicalComposition)

                # create Data Input for Raddose
                from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10

                self._edHandlerXSDataRaddose = EDHandlerXSDataRaddosev10()
                xsDataBeam = self.getDataInput().getExperimentalCondition().getBeam()

                # Calculate number of images (MXSUP-1616):
                iNumberOfImages = None
                xsDataCollection = self.dataInput.dataCollection
                if xsDataCollection is not None:
                    iNumberOfImages = 0
                    for xsDataSubWedge in xsDataCollection.subWedge:
                        xsDataGoniostat = xsDataSubWedge.experimentalCondition.goniostat
                        iOscStart = xsDataGoniostat.rotationAxisStart.value
                        iOscEnd = xsDataGoniostat.rotationAxisEnd.value
                        iOscWidth = xsDataGoniostat.oscillationWidth.value
                        iNumberOfImages += int(round((iOscEnd - iOscStart) / iOscWidth, 0))
                if iNumberOfImages is None:
                    iNumberOfImages = 1
                    self.WARNING("No goniostat information, number of images for RADDOSE set to 1")

                xsDataRaddoseInput = self._edHandlerXSDataRaddose.getXSDataRaddoseInput(
                    xsDataBeam, self._xsDataSampleCopy, iNumOperators, iNumberOfImages
                )
                if xsDataRaddoseInput is not None:
                    self._edPluginRaddose.setDataInput(xsDataRaddoseInput)
                    self._edPluginRaddose.setBaseDirectory(self.getWorkingDirectory())
                    self._edPluginRaddose.setBaseName(self._strPluginRaddoseName)

    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlStrategyv1_2.configure")
        strSymopHome = self.config.get(self._strCONF_SYMOP_HOME)
        if strSymopHome is None:
            strWarningMessage = "EDPluginControlStrategyv1_2: No configuration parameter found for {0}".format(
                self._strCONF_SYMOP_HOME
            )
            self.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)
        else:
            self.setSymopHome(strSymopHome)
        # Even 100 images?
        self.roundUpToEven100 = self.config.get("roundUpToEven100", False)

    def process(self, _edObject=None):
        EDPluginControl.process(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.process...")
        self._edPluginBest.connectSUCCESS(self.doSuccessActionBest)
        self._edPluginBest.connectFAILURE(self.doFailureActionBest)
        if self._bEstimateRadiationDamage:
            self._edPluginRaddose.connectSUCCESS(self.doRaddoseToBestTransition)
            self._edPluginRaddose.connectFAILURE(self.doFailureActionRaddose)
            self._edPluginRaddose.executeSynchronous()
        else:
            self.executeBest()

    def postProcess(self, _edObject=None):
        EDPluginControl.postProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.postProcess...")

        #
        # Create the BEST graphs from the plot mtv file
        #
        # Check if we have GLE files from BEST:
        xsDataResultBest = self._edPluginBest.getDataOutput()
        xsDataInputPlotGle = XSDataInputPlotGle()
        if xsDataResultBest.glePlot != []:
            for xsDataBestGlePlot in xsDataResultBest.glePlot:
                xsDataGlePlot = XSDataGlePlot()
                xsDataGlePlot.script = xsDataBestGlePlot.script
                xsDataGlePlot.data = xsDataBestGlePlot.data
                xsDataInputPlotGle.addGlePlot(xsDataGlePlot)
        else:
            xsDataInputPlotGle.filePlotMtv = xsDataResultBest.pathToPlotMtvFile
        self._edPluginPlotGle.dataInput = xsDataInputPlotGle
        self._edPluginPlotGle.executeSynchronous()

    def finallyProcess(self, _edObject=None):
        EDPluginControl.finallyProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.finallyProcess")
        xsDataResultStrategy = None
        xsDataResultBest = self._edPluginBest.getDataOutput()
        if xsDataResultBest is not None and self.getDataInput().getDiffractionPlan().getStrategyOption() is not None:
            if self.getDataInput().getDiffractionPlan().getStrategyOption().getValue() != "-Bonly":
                xsDataResultStrategy = self._edHandlerXSDataBest.getXSDataResultStrategy(
                    xsDataResultBest,
                    self.getDataInput().getExperimentalCondition(),
                    self._xsDataSampleCopy,
                    roundUpToEven100=self.roundUpToEven100,
                )
        else:
            xsDataResultStrategy = self._edHandlerXSDataBest.getXSDataResultStrategy(
                xsDataResultBest,
                self.getDataInput().getExperimentalCondition(),
                self._xsDataSampleCopy,
                roundUpToEven100=self.roundUpToEven100,
            )

        if self.xsDataFileRaddoseLog is not None:
            xsDataResultStrategy.setRaddoseLogFile(self.xsDataFileRaddoseLog)
        # Plots
        if not self._edPluginPlotGle.isFailure() and self._edPluginPlotGle.dataOutput is not None:
            listFileGraph = self._edPluginPlotGle.dataOutput.fileGraph
            xsDataResultStrategy.bestGraphFile = listFileGraph
        # Sample
        xsDataResultStrategy.setSample(self._xsDataSampleCopy)
        # timeToReachHendersonLimit
        if self._edPluginRaddose is not None:
            xsDataRaddoseOutput = self._edPluginRaddose.dataOutput
            if xsDataRaddoseOutput is not None:
                xsDataResultStrategy.timeToReachHendersonLimit = xsDataRaddoseOutput.timeToReachHendersonLimit
        self.setDataOutput(xsDataResultStrategy)
        self.generateStrategyShortSummary(xsDataResultStrategy)

    def doRaddoseToBestTransition(self, _edPlugin):
        self.DEBUG("EDPluginControlStrategyv1_2.doRaddoseToBestTransition")
        self.retrieveSuccessMessages(_edPlugin, "EDPluginControlStrategyv1_2.doRaddoseToBestTransition")

        xsDataRaddoseOutput = self._edPluginRaddose.getDataOutput()

        # update the strategy data with the data coming from Raddose
        self._xsDataSampleCopy.setAbsorbedDoseRate(xsDataRaddoseOutput.getAbsorbedDoseRate())
        if xsDataRaddoseOutput.getPathToLogFile() != None:
            self.xsDataFileRaddoseLog = xsDataRaddoseOutput.getPathToLogFile()

        # Call the Best Translator layer
        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2

        self._edHandlerXSDataBest = EDHandlerXSDataBestv1_2()

        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(self.getDataInput().marshal())
        xsDataInputStrategyCopy.setSample(self._xsDataSampleCopy)

        xsDataInputBest = self._edHandlerXSDataBest.getXSDataInputBest(xsDataInputStrategyCopy)

        self._edPluginBest.setDataInput(xsDataInputBest)
        self._edPluginBest.executeSynchronous()

    def doFailureActionRaddose(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlStrategyv1_2.doFailureActionRaddose")
        self.retrieveFailureMessages(_edPlugin, "EDPluginControlStrategyv1_2.doFailureActionRaddose")
        strWarningMessage = "EDPluginControlStrategyv1_2: Raddose failure"
        self.warning(strWarningMessage)
        self.addWarningMessage(strWarningMessage)
        self.executeBest(self)

    def executeBest(self, _edPlugin=None):
        # Call the Best Translator layer

        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2

        self._edHandlerXSDataBest = EDHandlerXSDataBestv1_2()
        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(self.getDataInput().marshal())
        xsDataInputStrategyCopy.setSample(self._xsDataSampleCopy)
        xsDataInputBest = self._edHandlerXSDataBest.getXSDataInputBest(xsDataInputStrategyCopy)
        self._edPluginBest.setDataInput(xsDataInputBest)
        self._edPluginBest.executeSynchronous()

    def doSuccessActionBest(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        """
        self.DEBUG("EDPluginControlStrategyv1_2.doSuccessActionBest")
        self.retrieveSuccessMessages(_edPlugin, "EDPluginControlStrategyv1_2.doSuccessActionBest")

    def doFailureActionBest(self, _edPlugin):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlStrategyv1_2.doFailureActionBest")
        self.retrieveFailureMessages(_edPlugin, "BEST failure:")
        self.generateExecutiveSummary(self)
        self.setFailure()

    def getDefaultChemicalComposition(self, _xsDataSample, _inumOperators):
        xsDataCell = _xsDataSample.getCrystal().getCell()
        a = xsDataCell.getLength_a().getValue()
        b = xsDataCell.getLength_b().getValue()
        c = xsDataCell.getLength_c().getValue()
        alpha = math.radians(xsDataCell.getAngle_alpha().getValue())
        beta = math.radians(xsDataCell.getAngle_beta().getValue())
        gamma = math.radians(xsDataCell.getAngle_gamma().getValue())

        fUnitCellVolume = (
            a
            * b
            * c
            * (
                math.sqrt(
                    1
                    - math.cos(alpha) * math.cos(alpha)
                    - math.cos(beta) * math.cos(beta)
                    - math.cos(gamma) * math.cos(gamma)
                    + 2 * math.cos(alpha) * math.cos(beta) * math.cos(gamma)
                )
            )
        )
        fPolymerVolume = fUnitCellVolume * (1 - self._fAverageCrystalSolventContent)
        fNumberOfMonomersPerUnitCell = fPolymerVolume / self._fAverageAminoAcidVolume
        fNumberOfMonomersPerAsymmetricUnit = fNumberOfMonomersPerUnitCell / _inumOperators
        iNumberOfSulfurAtom = int(round(fNumberOfMonomersPerAsymmetricUnit * self._fAverageSulfurContentPerAminoacid))

        xsDataAtom = XSDataAtom()
        xsDataAtom.setSymbol(XSDataString("S"))
        xsDataAtom.setNumberOf(XSDataDouble(iNumberOfSulfurAtom))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomicComposition.addAtom(xsDataAtom)

        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfMonomers(XSDataDouble(round(fNumberOfMonomersPerAsymmetricUnit)))
        xsDataChain.setNumberOfCopies(XSDataDouble(1))
        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)

        xsDataStructure = XSDataStructure()
        xsDataStructure.addChain(xsDataChain)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(1))

        xsDataAtomSolvent = XSDataAtom()
        xsDataAtomSolvent.setSymbol(XSDataString("S"))
        xsDataAtomSolvent.setConcentration(XSDataDouble(self._fAverageSulfurConcentration))
        xsDataAtomicCompositionSolvent = XSDataAtomicComposition()
        xsDataAtomicCompositionSolvent.addAtom(xsDataAtomSolvent)
        xsDataSolvent = XSDataSolvent()
        xsDataSolvent.setAtoms(xsDataAtomicCompositionSolvent)

        xsDataChemicalCompositionMM = XSDataChemicalCompositionMM()
        xsDataChemicalCompositionMM.setSolvent(xsDataSolvent)
        xsDataChemicalCompositionMM.setStructure(xsDataStructure)

        return xsDataChemicalCompositionMM

    def updateChemicalComposition(self, _xsDataChemicalComposition):
        xsDataChemicalComposition = _xsDataChemicalComposition

        for chain in xsDataChemicalComposition.getStructure().getChain():
            if chain.getType().getValue() == "protein":
                bSulfurExists = False
                xsDataAtomicCompositionHeavyAtoms = chain.getHeavyAtoms()
                if xsDataAtomicCompositionHeavyAtoms is None:
                    xsDataAtomicCompositionHeavyAtoms = XSDataAtomicComposition()
                else:
                    for heavyAtom in xsDataAtomicCompositionHeavyAtoms.getAtom():
                        if heavyAtom.getSymbol().getValue() == "S" or heavyAtom.getSymbol().getValue() == "s":
                            bSulfurExists = True

                # all protein chains should contain sulfur atom as a percentage of the number
                # of amino acids. Add them if the user did not input them.
                if bSulfurExists == False:
                    iNumberOfSulfurAtom = int(round(chain.getNumberOfMonomers().getValue() * 0.05))
                    xsDataSulfurAtom = XSDataAtom()
                    xsDataSulfurAtom.setSymbol(XSDataString("S"))
                    xsDataSulfurAtom.setNumberOf(XSDataDouble(iNumberOfSulfurAtom))
                    xsDataAtomicCompositionHeavyAtoms.addAtom(xsDataSulfurAtom)
                    chain.setHeavyAtoms(xsDataAtomicCompositionHeavyAtoms)

        return xsDataChemicalComposition

    def generateExecutiveSummary(self, _edPlugin):
        """
        Generates a summary of the execution of the plugin.
        """
        self.DEBUG("EDPluginControlStrategyv1_2.generateExecutiveSummary")
        self.addExecutiveSummaryLine("Summary of Strategy:")
        self.addErrorWarningMessagesToExecutiveSummary()

        xsDataResultStrategy = self.getDataOutput()

        if self._edPluginRaddose is not None:
            if self._edPluginRaddose.getDataOutput() is not None:

                self.addExecutiveSummaryLine("")
                self.appendExecutiveSummary(self._edPluginRaddose, "Raddose : ")

            if xsDataResultStrategy is not None:
                self.addExecutiveSummaryLine("")
                self.addExecutiveSummaryLine("Calculations assuming polymer crystal with:")
                self.addExecutiveSummaryLine("------------------------------------------")
                self.addExecutiveSummaryLine("")

                xsDataStructure = (
                    xsDataResultStrategy.getCollectionPlan()[0]
                    .getCollectionStrategy()
                    .getSample()
                    .getChemicalComposition()
                    .getStructure()
                )

                self.addExecutiveSummaryLine(
                    "Number of structure copies in asymmetric unit: %.2f"
                    % xsDataStructure.getNumberOfCopiesInAsymmetricUnit().getValue()
                )
                self.addExecutiveSummaryLine("")

                chains = xsDataStructure.getChain()
                self.addExecutiveSummaryLine("Chains:")
                for chain in chains:
                    strChainType = chain.getType().getValue()
                    self.addExecutiveSummaryLine("    Type                           : %s" % strChainType)
                    if strChainType == "protein":
                        self.addExecutiveSummaryLine(
                            "    Number of residues             : %.2f" % chain.getNumberOfMonomers().getValue()
                        )
                    elif strChainType == "dna" or strChainType == "rna":
                        self.addExecutiveSummaryLine(
                            "    Number of nucleotides          : %.2f" % chain.getNumberOfMonomers().getValue()
                        )
                    strHeavyAtomsChain = "    Number of heavy atoms          :"
                    if chain.getHeavyAtoms() is not None:
                        heavyAtomsChain = chain.getHeavyAtoms().getAtom()
                        for heavyAtomChain in heavyAtomsChain:
                            strHeavyAtomsChain = strHeavyAtomsChain + " %s=%d" % (
                                heavyAtomChain.getSymbol().getValue(),
                                heavyAtomChain.getNumberOf().getValue(),
                            )
                    else:
                        strHeavyAtomsChain = strHeavyAtomsChain + " No heavy atoms"
                    self.addExecutiveSummaryLine(strHeavyAtomsChain)

                    self.addExecutiveSummaryLine(
                        "    Number of copies in structure  : %.2f" % chain.getNumberOfCopies().getValue()
                    )
                    self.addExecutiveSummaryLine("")

                ligands = xsDataStructure.getLigand()
                if len(ligands) != 0:
                    self.addExecutiveSummaryLine("Ligands:")

                for ligand in ligands:
                    self.addExecutiveSummaryLine(
                        "    Number of light atoms          : %.2f" % ligand.getNumberOfLightAtoms().getValue()
                    )
                    strHeavyAtomsLigand = "    Number of heavy atoms          :"
                    if ligand.getHeavyAtoms() is not None:
                        heavyAtomsLigand = ligand.getHeavyAtoms().getAtom()
                        for heavyAtomLigand in heavyAtomsLigand:
                            strHeavyAtomsLigand = strHeavyAtomsLigand + " %s=%d" % (
                                heavyAtomLigand.getSymbol().getValue(),
                                heavyAtomLigand.getNumberOf().getValue(),
                            )
                    else:
                        strHeavyAtomsChain = strHeavyAtomsChain + " No heavy atoms"
                    self.addExecutiveSummaryLine(strHeavyAtomsLigand)
                    self.addExecutiveSummaryLine(
                        "    Number of copies in structure  : %.2f" % chain.getNumberOfCopies().getValue()
                    )
                    self.addExecutiveSummaryLine("")

        if self._edPluginBest is not None:
            if self._edPluginBest.getDataOutput() is not None:
                self.appendExecutiveSummary(self._edPluginBest, "Best : ")
                self.addExecutiveSummaryLine("")

    def generateStrategyShortSummary(self, _xsDataResultStrategy):
        """
        Generates a short summary of the BEST strategy
        """
        self.DEBUG("EDPluginControlIntegrationv10.generateIntegrationShortSummary")
        strStrategyShortSummary = ""
        iTotalNoImages = 0
        fTotalExposureTime = 0.0
        xsDataDiffractionPlan = None
        if self.getDataInput():
            if self.getDataInput().getDiffractionPlan():
                xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if self._bEstimateRadiationDamage:
            strStrategyShortSummary += "Strategy: Radiation damage estimated"
            if self._edPluginRaddose.getDataOutput().getTimeToReachHendersonLimit():
                strStrategyShortSummary += (
                    ", time to reach Henderson limit: %.1f s\n"
                    % self._edPluginRaddose.getDataOutput().getTimeToReachHendersonLimit().getValue()
                )
            else:
                strStrategyShortSummary += "\n"

        else:
            strStrategyShortSummary += "Strategy: No radiation damage estimation"
            if xsDataDiffractionPlan:
                if xsDataDiffractionPlan.getMaxExposureTimePerDataCollection():
                    strStrategyShortSummary += (
                        ", max exposure time per data collection: %.1f s\n"
                        % xsDataDiffractionPlan.getMaxExposureTimePerDataCollection().getValue()
                    )
                else:
                    strStrategyShortSummary += "\n"
            else:
                strStrategyShortSummary += "\n"
        if xsDataDiffractionPlan:
            strStrategyShortSummary += "Strategy: Options: "
            listStrategyOptions = []
            if xsDataDiffractionPlan.getAnomalousData():
                if xsDataDiffractionPlan.getAnomalousData().getValue():
                    listStrategyOptions.append("anomalous data")
            if xsDataDiffractionPlan.getAimedCompleteness():
                listStrategyOptions.append(
                    "aimed completeness = %.1f" % xsDataDiffractionPlan.getAimedCompleteness().getValue()
                )
            if xsDataDiffractionPlan.getAimedMultiplicity():
                listStrategyOptions.append(
                    "aimed multiplicity = %d" % xsDataDiffractionPlan.getAimedMultiplicity().getValue()
                )
            if xsDataDiffractionPlan.getAimedResolution():
                listStrategyOptions.append(
                    "aimed resolution = %.2f A" % xsDataDiffractionPlan.getAimedResolution().getValue()
                )
            if xsDataDiffractionPlan.getComplexity():
                listStrategyOptions.append("complexity = %s" % xsDataDiffractionPlan.getComplexity().getValue())
            if xsDataDiffractionPlan.getStrategyOption():
                listStrategyOptions.append(
                    "extra strategy option(s) = %s" % xsDataDiffractionPlan.getStrategyOption().getValue()
                )
            if listStrategyOptions != []:
                for strStrategyOption in listStrategyOptions[:-1]:
                    strStrategyShortSummary += strStrategyOption + ", "
                strStrategyShortSummary += listStrategyOptions[-1]
            strStrategyShortSummary += "\n"
        fResolutionMax = None
        fRankingResolution = None
        for xsDataCollectionPlan in _xsDataResultStrategy.getCollectionPlan():
            iNoCollectionPlan = xsDataCollectionPlan.getCollectionPlanNumber().getValue()
            strStrategyShortSummary += "Strategy: Collection plan %d" % iNoCollectionPlan
            xsDataStrategySummary = xsDataCollectionPlan.getStrategySummary()
            if xsDataStrategySummary.getResolutionReasoning() != None:
                strResolutionResoning = xsDataStrategySummary.getResolutionReasoning().getValue()
                strStrategyShortSummary += ": %s\n" % strResolutionResoning
            else:
                strStrategyShortSummary += "\n"
            xsDataCollectionStrategy = xsDataCollectionPlan.getCollectionStrategy()
            if xsDataStrategySummary.getRankingResolution() is not None:
                fRankingResolution = xsDataStrategySummary.getRankingResolution().getValue()
                strStrategyShortSummary += "Strategy: Ranking resolution: %.2f [A]\n" % fRankingResolution
            for xsDataSubWedge in xsDataCollectionStrategy.getSubWedge():
                iWedgeNo = xsDataCollectionPlan.getCollectionPlanNumber().getValue()
                strStrategyShortSummary += "Strategy: wedge %d: " % iWedgeNo
                xsDataStrategySummary = xsDataCollectionPlan.getStrategySummary()
                fResolution = xsDataStrategySummary.getResolution().getValue()
                if (fResolutionMax is None) or (fResolution < fResolutionMax):
                    fResolutionMax = fResolution
                strStrategyShortSummary += "resolution %.2f [A], " % fResolution
                xsDataStringAction = xsDataSubWedge.getAction()
                if xsDataStringAction is not None:
                    strStrategyShortSummary += "%s, " % xsDataStringAction.getValue()
                iSubWedgeNo = xsDataSubWedge.getSubWedgeNumber().getValue()
                strStrategyShortSummary += "sub wedge %d: " % iSubWedgeNo
                xsDataExperimentalCondition = xsDataSubWedge.getExperimentalCondition()
                xsDataGoniostat = xsDataExperimentalCondition.getGoniostat()
                fRotationStart = xsDataGoniostat.getRotationAxisStart().getValue()
                strStrategyShortSummary += "start %.2f, " % fRotationStart
                fRange = xsDataGoniostat.getOscillationWidth().getValue()
                fRotationEnd = xsDataGoniostat.getRotationAxisEnd().getValue()
                iNoImages = int((fRotationEnd - fRotationStart) / fRange + 0.1)
                strStrategyShortSummary += "images %d, " % iNoImages
                strStrategyShortSummary += "width %.2f, " % fRange
                xsDataBeam = xsDataExperimentalCondition.getBeam()
                fExpTime = xsDataBeam.getExposureTime().getValue()
                strStrategyShortSummary += "time %.2f [s], " % fExpTime
                fTransmission = xsDataBeam.getTransmission().getValue()
                strStrategyShortSummary += "transmission %.2f\n" % fTransmission
                iTotalNoImages += iNoImages
                fTotalExposureTime += fExpTime * iNoImages
            strStrategyShortSummary += "Strategy: total no images %d, total exposure time %.1f [s]\n" % (
                iTotalNoImages,
                fTotalExposureTime,
            )
        if fRankingResolution is not None:
            if (fRankingResolution < fResolutionMax) and (abs(fRankingResolution - fResolutionMax) > 0.1):
                strStrategyShortSummary += "\n"
                strStrategyShortSummary += "NOTE! " * 20 + "\n"
                strStrategyShortSummary += "\n"
                strStrategyShortSummary += (
                    "BEST has calculated that it should be possible to collect data to %.2f A from this sample.\n"
                    % fRankingResolution
                )
                strStrategyShortSummary += (
                    "If you want to calculate a new strategy for data collection to this resolution you\n"
                )
                strStrategyShortSummary += "must first recollect reference images at this resolution.\n"
                strStrategyShortSummary += "\n"
                strStrategyShortSummary += "NOTE! " * 20 + "\n"
                strStrategyShortSummary += "\n"

        self.setDataOutput(XSDataString(strStrategyShortSummary), "strategyShortSummary")
class EDPluginControlStrategyv1_2(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """

    def __init__ (self):
        """
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputStrategy)

        self._strPluginRaddoseName = "EDPluginRaddosev10"
        self._edPluginRaddose = None
        self._edHandlerXSDataRaddose = None

        self._strPluginBestName = "EDPluginBestv1_2"
        self._edPluginBest = None
        self._edHandlerXSDataBest = None

        self._strPluginPlotGleName = "EDPluginExecPlotGlev1_0"
        self._edPluginPlotGle = None

        self._strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self._strSymopHome = None

        self._xsDataSampleCopy = None

        # For default chemical composition
        self._fAverageAminoAcidVolume = 135.49
        self._fAverageCrystalSolventContent = 0.47
        self._fAverageSulfurContentPerAminoacid = 0.05
        self._fAverageSulfurConcentration = 314

        # This varaible determines if Raddose should be executed or not
        self._bEstimateRadiationDamage = None
        
        # Raddose log file
        self.xsDataFileRaddoseLog = None


    def setSymopHome(self, _strSymopHome):
        self._strSymopHome = _strSymopHome


    def getSymopHome(self):
        return self._strSymopHome


    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if(xsDataSampleCrystalMM is None):
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if(xsDataCrystal is not None):
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue():
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find("-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strWarningMessage = "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                EDVerbose.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True


        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                EDVerbose.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if (self._edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: " + self._strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                if(xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper()
                    EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: " + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                        EDVerbose.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError, strErrorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: " + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d" % iSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(str(iSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
    def testGetXSDataRaddoseInput(self):
        """
        """
        from XSDataCommon import XSDataLength
        from XSDataCommon import XSDataWavelength
        from XSDataCommon import XSDataFlux
        from XSDataCommon import XSDataSize
        from XSDataCommon import XSDataDouble
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataAngle
        from XSDataCommon import XSDataTime
        from XSDataCommon import XSDataInteger

        from XSDataMXv1 import XSDataBeam
        from XSDataMXv1 import XSDataStructure
        from XSDataMXv1 import XSDataChain
        from XSDataMXv1 import XSDataAtom
        from XSDataMXv1 import XSDataLigand
        from XSDataMXv1 import XSDataCrystal
        from XSDataMXv1 import XSDataSpaceGroup
        from XSDataMXv1 import XSDataSampleCrystalMM
        from XSDataMXv1 import XSDataChemicalCompositionMM
        from XSDataMXv1 import XSDataAtomicComposition
        from XSDataMXv1 import XSDataSolvent
        from XSDataMXv1 import XSDataCell

        from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10

        EDFactoryPluginStatic.loadModule("XSDataRaddosev10")
        from XSDataRaddosev10 import XSDataRaddoseInput

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

        xsDataSample = 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)
        xsDataAtom2 = XSDataAtom()
        xsDataAtom2.setSymbol(XSDataString("S"))
        xsDataAtom2.setNumberOf(XSDataDouble(5))
        xsDataAtomicComposition.addAtom(xsDataAtom2)
        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()
        xsDataAtom3 = XSDataAtom()
        xsDataAtom3.setSymbol(XSDataString("Fe"))
        xsDataAtom3.setNumberOf(XSDataDouble(1))
        xsDataAtomicComposition.addAtom(xsDataAtom3)
        xsDataLigand.setHeavyAtoms(xsDataAtomicComposition)
        xsDataStructure.addLigand(xsDataLigand)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(0.25))

        xsDataSolvent = XSDataSolvent()
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomNa = XSDataAtom()
        xsDataAtomNa.setSymbol(XSDataString("Na"))
        xsDataAtomNa.setConcentration(XSDataDouble(1000))
        xsDataAtomicComposition.addAtom(xsDataAtomNa)
        xsDataAtomCl = XSDataAtom()
        xsDataAtomCl.setSymbol(XSDataString("Cl"))
        xsDataAtomCl.setConcentration(XSDataDouble(1000))
        xsDataAtomicComposition.addAtom(xsDataAtomCl)
        xsDataSolvent.setAtoms(xsDataAtomicComposition)

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

        xsDataSample.setSize(
            XSDataSize(XSDataLength(0.1), XSDataLength(0.1),
                       XSDataLength(0.1)))
        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 = XSDataCrystal()
        xsDataSpaceGroup = XSDataSpaceGroup()

        xsDataCrystal.setCell(xsDataCell)

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

        xsDataSample.setCrystal(xsDataCrystal)

        iNumSymOperators = 4
        iNumberOfImages = 2

        xsDataRaddosev01Input = EDHandlerXSDataRaddosev10(
        ).getXSDataRaddoseInput(xsDataBeam, xsDataSample, iNumSymOperators,
                                iNumberOfImages)

        xsDataRaddosev01Input.exportToFile(self.strObtainedInputFile2)
        strExpectedInput = EDUtilsTest.readAndParseFile(
            self.strReferenceInputFile2)
        strObtainedInput = EDUtilsTest.readAndParseFile(
            self.strObtainedInputFile2)

        xsDataInputExpected = XSDataRaddoseInput.parseString(strExpectedInput)
        xsDataInputObtained = XSDataRaddoseInput.parseString(strObtainedInput)

        EDAssert.equal(xsDataInputExpected.marshal(),
                       xsDataInputObtained.marshal())
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if xsDataSampleCrystalMM is None:
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if xsDataCrystal is not None:
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue():
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find("-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strWarningMessage = (
                    "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                )
                self.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True

        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                self.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if self._edPluginRaddose is not None:
                self.DEBUG(
                    "EDPluginControlStrategyv1_2.preProcess: "
                    + self._strPluginRaddoseName
                    + " Found... setting Data Input"
                )

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                bSpaceGroupForced = False
                if xsDataStringSpaceGroup is not None:
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper().replace(" ", "")
                    if strSpaceGroup != "":
                        self.DEBUG("EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: " + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup, strFileSymop
                            )
                            bSpaceGroupForced = True
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail
                            )
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                if not bSpaceGroupForced:
                    # Space Group has NOT been forced
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if xsDataStringSpaceGroup is not None:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName
                        )
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName, strFileSymop
                            )
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail
                            )
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = (
                            self._xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue()
                        )
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d"
                            % iSpaceGroupITNumber
                        )
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(iSpaceGroupITNumber), strFileSymop
                            )
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail
                            )
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)

                if strNumOperators is not None:
                    iNumOperators = int(strNumOperators)
                else:
                    strErrorMessage = "EDPluginControlStrategyv1_2: No symmetry operators found for Space Group: {0}".format(
                        strNumOperators
                    )
                    self.error(strErrorMessage)
                    self.addErrorMessage(strErrorMessage)
                    raise RuntimeError(strErrorMessage)

                xsDataChemicalComposition = self._xsDataSampleCopy.getChemicalComposition()

                if xsDataChemicalComposition is None:
                    # create a default chemical composition and assign it to the sample
                    xsDataDefaultChemicalComposition = self.getDefaultChemicalComposition(
                        self._xsDataSampleCopy, iNumOperators
                    )
                    self._xsDataSampleCopy.setChemicalComposition(xsDataDefaultChemicalComposition)
                else:
                    # Check for Sulfur atoms, if none, add native sulfur atoms
                    xsDataUpdatedChemicalComposition = self.updateChemicalComposition(xsDataChemicalComposition)
                    self._xsDataSampleCopy.setChemicalComposition(xsDataUpdatedChemicalComposition)

                # create Data Input for Raddose
                from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10

                self._edHandlerXSDataRaddose = EDHandlerXSDataRaddosev10()
                xsDataBeam = self.getDataInput().getExperimentalCondition().getBeam()

                # Calculate number of images (MXSUP-1616):
                iNumberOfImages = None
                xsDataCollection = self.dataInput.dataCollection
                if xsDataCollection is not None:
                    iNumberOfImages = 0
                    for xsDataSubWedge in xsDataCollection.subWedge:
                        xsDataGoniostat = xsDataSubWedge.experimentalCondition.goniostat
                        iOscStart = xsDataGoniostat.rotationAxisStart.value
                        iOscEnd = xsDataGoniostat.rotationAxisEnd.value
                        iOscWidth = xsDataGoniostat.oscillationWidth.value
                        iNumberOfImages += int(round((iOscEnd - iOscStart) / iOscWidth, 0))
                if iNumberOfImages is None:
                    iNumberOfImages = 1
                    self.WARNING("No goniostat information, number of images for RADDOSE set to 1")

                xsDataRaddoseInput = self._edHandlerXSDataRaddose.getXSDataRaddoseInput(
                    xsDataBeam, self._xsDataSampleCopy, iNumOperators, iNumberOfImages
                )
                if xsDataRaddoseInput is not None:
                    self._edPluginRaddose.setDataInput(xsDataRaddoseInput)
                    self._edPluginRaddose.setBaseDirectory(self.getWorkingDirectory())
                    self._edPluginRaddose.setBaseName(self._strPluginRaddoseName)
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self.__edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if(xsDataSampleCrystalMM is None):
            self.__xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.__xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if(xsDataCrystal is not None):
            self.__xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self.__edPluginBest = self.loadPlugin(self.__strPluginBestName)
        self.__edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self.__edPluginBest.setBaseName(self.__strPluginBestName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue():
                    # Yes, is requested
                    self.__bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self.__bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find("-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self.__bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self.__bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strWarningMessage = "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                EDVerbose.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self.__bEstimateRadiationDamage = False
            else:
                self.__bEstimateRadiationDamage = True


        if self.__bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                EDVerbose.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self.__edPluginRaddose = self.loadPlugin(self.__strPluginRaddoseName)

            if (self.__edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: " + self.__strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                if(xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper()
                    EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: " + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                        EDVerbose.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError, strErrorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: " + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d" % iSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(str(iSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
Example #17
0
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if (xsDataSampleCrystalMM is None):
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if (xsDataCrystal is not None):
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue(
                ):
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find(
                        "-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam(
            ).getFlux() is None:
                strWarningMessage = "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                self.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True

        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam(
            ).getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                self.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if (self._edPluginRaddose is not None):
                self.DEBUG("EDPluginControlStrategyv1_2.preProcess: " +
                           self._strPluginRaddoseName +
                           " Found... setting Data Input")

                xsDataStringSpaceGroup = self.getDataInput(
                ).getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                bSpaceGroupForced = False
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper(
                    ).replace(" ", "")
                    if strSpaceGroup != "":
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: "
                            + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup)
                            bSpaceGroupForced = True
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                if not bSpaceGroupForced:
                    # Space Group has NOT been forced
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName)
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self._xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d"
                            % iSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(iSpaceGroupITNumber))
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)

                if (strNumOperators is not None):
                    iNumOperators = int(strNumOperators)
                else:
                    strErrorMessage = "EDPluginControlStrategyv1_2: No symmetry operators found for Space Group: {0}".format(
                        strNumOperators)
                    self.error(strErrorMessage)
                    self.addErrorMessage(strErrorMessage)
                    raise RuntimeError(strErrorMessage)

                xsDataChemicalComposition = self._xsDataSampleCopy.getChemicalComposition(
                )

                if (xsDataChemicalComposition is None):
                    # create a default chemical composition and assign it to the sample
                    xsDataDefaultChemicalComposition = self.getDefaultChemicalComposition(
                        self._xsDataSampleCopy, iNumOperators)
                    self._xsDataSampleCopy.setChemicalComposition(
                        xsDataDefaultChemicalComposition)
                else:
                    # Check for Sulfur atoms, if none, add native sulfur atoms
                    xsDataUpdatedChemicalComposition = self.updateChemicalComposition(
                        xsDataChemicalComposition)
                    self._xsDataSampleCopy.setChemicalComposition(
                        xsDataUpdatedChemicalComposition)

                # create Data Input for Raddose
                from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10
                self._edHandlerXSDataRaddose = EDHandlerXSDataRaddosev10()
                xsDataBeam = self.getDataInput().getExperimentalCondition(
                ).getBeam()

                # Calculate number of images (MXSUP-1616):
                iNumberOfImages = None
                xsDataCollection = self.dataInput.dataCollection
                if xsDataCollection is not None:
                    iNumberOfImages = 0
                    for xsDataSubWedge in xsDataCollection.subWedge:
                        xsDataGoniostat = xsDataSubWedge.experimentalCondition.goniostat
                        iOscStart = xsDataGoniostat.rotationAxisStart.value
                        iOscEnd = xsDataGoniostat.rotationAxisEnd.value
                        iOscWidth = xsDataGoniostat.oscillationWidth.value
                        iNumberOfImages += int(
                            round((iOscEnd - iOscStart) / iOscWidth, 0))
                if iNumberOfImages is None:
                    iNumberOfImages = 1
                    self.WARNING(
                        "No goniostat information, number of images for RADDOSE set to 1"
                    )

                xsDataRaddoseInput = self._edHandlerXSDataRaddose.getXSDataRaddoseInput(
                    xsDataBeam, self._xsDataSampleCopy, iNumOperators,
                    iNumberOfImages)
                if xsDataRaddoseInput is not None:
                    self._edPluginRaddose.setDataInput(xsDataRaddoseInput)
                    self._edPluginRaddose.setBaseDirectory(
                        self.getWorkingDirectory())
                    self._edPluginRaddose.setBaseName(
                        self._strPluginRaddoseName)
Example #18
0
class EDPluginControlStrategyv1_2(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """
    def __init__(self):
        """
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputStrategy)

        self._strPluginRaddoseName = "EDPluginRaddosev10"
        self._edPluginRaddose = None
        self._edHandlerXSDataRaddose = None

        self._strPluginBestName = "EDPluginBestv1_2"
        self._edPluginBest = None
        self._edHandlerXSDataBest = None

        self._strPluginPlotGleName = "EDPluginExecPlotGlev1_1"
        self._edPluginPlotGle = None

        self._xsDataSampleCopy = None

        # For default chemical composition
        self._fAverageAminoAcidVolume = 135.49
        self._fAverageCrystalSolventContent = 0.47
        self._fAverageSulfurContentPerAminoacid = 0.05
        self._fAverageSulfurConcentration = 314

        # This varaible determines if Raddose should be executed or not
        self._bEstimateRadiationDamage = None

        # Raddose log file
        self.xsDataFileRaddoseLog = None

        self.roundUpToEven100 = False

    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if (xsDataSampleCrystalMM is None):
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if (xsDataCrystal is not None):
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue(
                ):
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find(
                        "-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam(
            ).getFlux() is None:
                strWarningMessage = "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                self.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True

        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam(
            ).getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                self.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if (self._edPluginRaddose is not None):
                self.DEBUG("EDPluginControlStrategyv1_2.preProcess: " +
                           self._strPluginRaddoseName +
                           " Found... setting Data Input")

                xsDataStringSpaceGroup = self.getDataInput(
                ).getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                bSpaceGroupForced = False
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper(
                    ).replace(" ", "")
                    if strSpaceGroup != "":
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: "
                            + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup)
                            bSpaceGroupForced = True
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                if not bSpaceGroupForced:
                    # Space Group has NOT been forced
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName)
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self._xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        self.DEBUG(
                            "EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d"
                            % iSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(iSpaceGroupITNumber))
                        except Exception as detail:
                            strErrorMessage = "EDPluginControlStrategyv1_2: Problem to calculate Number of symmetry operators: {0}".format(
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)

                if (strNumOperators is not None):
                    iNumOperators = int(strNumOperators)
                else:
                    strErrorMessage = "EDPluginControlStrategyv1_2: No symmetry operators found for Space Group: {0}".format(
                        strNumOperators)
                    self.error(strErrorMessage)
                    self.addErrorMessage(strErrorMessage)
                    raise RuntimeError(strErrorMessage)

                xsDataChemicalComposition = self._xsDataSampleCopy.getChemicalComposition(
                )

                if (xsDataChemicalComposition is None):
                    # create a default chemical composition and assign it to the sample
                    xsDataDefaultChemicalComposition = self.getDefaultChemicalComposition(
                        self._xsDataSampleCopy, iNumOperators)
                    self._xsDataSampleCopy.setChemicalComposition(
                        xsDataDefaultChemicalComposition)
                else:
                    # Check for Sulfur atoms, if none, add native sulfur atoms
                    xsDataUpdatedChemicalComposition = self.updateChemicalComposition(
                        xsDataChemicalComposition)
                    self._xsDataSampleCopy.setChemicalComposition(
                        xsDataUpdatedChemicalComposition)

                # create Data Input for Raddose
                from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10
                self._edHandlerXSDataRaddose = EDHandlerXSDataRaddosev10()
                xsDataBeam = self.getDataInput().getExperimentalCondition(
                ).getBeam()

                # Calculate number of images (MXSUP-1616):
                iNumberOfImages = None
                xsDataCollection = self.dataInput.dataCollection
                if xsDataCollection is not None:
                    iNumberOfImages = 0
                    for xsDataSubWedge in xsDataCollection.subWedge:
                        xsDataGoniostat = xsDataSubWedge.experimentalCondition.goniostat
                        iOscStart = xsDataGoniostat.rotationAxisStart.value
                        iOscEnd = xsDataGoniostat.rotationAxisEnd.value
                        iOscWidth = xsDataGoniostat.oscillationWidth.value
                        iNumberOfImages += int(
                            round((iOscEnd - iOscStart) / iOscWidth, 0))
                if iNumberOfImages is None:
                    iNumberOfImages = 1
                    self.WARNING(
                        "No goniostat information, number of images for RADDOSE set to 1"
                    )

                xsDataRaddoseInput = self._edHandlerXSDataRaddose.getXSDataRaddoseInput(
                    xsDataBeam, self._xsDataSampleCopy, iNumOperators,
                    iNumberOfImages)
                if xsDataRaddoseInput is not None:
                    self._edPluginRaddose.setDataInput(xsDataRaddoseInput)
                    self._edPluginRaddose.setBaseDirectory(
                        self.getWorkingDirectory())
                    self._edPluginRaddose.setBaseName(
                        self._strPluginRaddoseName)

    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlStrategyv1_2.configure")
        # Even 100 images?
        self.roundUpToEven100 = self.config.get("roundUpToEven100", False)

    def process(self, _edObject=None):
        EDPluginControl.process(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.process...")
        self._edPluginBest.connectSUCCESS(self.doSuccessActionBest)
        self._edPluginBest.connectFAILURE(self.doFailureActionBest)
        if self._bEstimateRadiationDamage:
            self._edPluginRaddose.connectSUCCESS(
                self.doRaddoseToBestTransition)
            self._edPluginRaddose.connectFAILURE(self.doFailureActionRaddose)
            self._edPluginRaddose.executeSynchronous()
        else:
            self.executeBest()

    def postProcess(self, _edObject=None):
        EDPluginControl.postProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.postProcess...")

        #
        # Create the BEST graphs from the plot mtv file
        #
        # Check if we have GLE files from BEST:
        xsDataResultBest = self._edPluginBest.getDataOutput()
        xsDataInputPlotGle = XSDataInputPlotGle()
        if xsDataResultBest.glePlot != []:
            for xsDataBestGlePlot in xsDataResultBest.glePlot:
                xsDataGlePlot = XSDataGlePlot()
                xsDataGlePlot.script = xsDataBestGlePlot.script
                xsDataGlePlot.data = xsDataBestGlePlot.data
                xsDataInputPlotGle.addGlePlot(xsDataGlePlot)
        else:
            xsDataInputPlotGle.filePlotMtv = xsDataResultBest.pathToPlotMtvFile
        self._edPluginPlotGle.dataInput = xsDataInputPlotGle
        self._edPluginPlotGle.executeSynchronous()

    def finallyProcess(self, _edObject=None):
        EDPluginControl.finallyProcess(self, _edObject)
        self.DEBUG("EDPluginControlStrategyv1_2.finallyProcess")
        xsDataResultStrategy = None
        xsDataResultBest = self._edPluginBest.getDataOutput()
        if (xsDataResultBest is not None and
                self.getDataInput().getDiffractionPlan().getStrategyOption()
                is not None):
            if (self.getDataInput().getDiffractionPlan().getStrategyOption().
                    getValue() != "-Bonly"):
                xsDataResultStrategy = self._edHandlerXSDataBest.getXSDataResultStrategy(
                    xsDataResultBest,
                    self.getDataInput().getExperimentalCondition(),
                    self._xsDataSampleCopy,
                    roundUpToEven100=self.roundUpToEven100)
        else:
            xsDataResultStrategy = self._edHandlerXSDataBest.getXSDataResultStrategy(
                xsDataResultBest,
                self.getDataInput().getExperimentalCondition(),
                self._xsDataSampleCopy,
                roundUpToEven100=self.roundUpToEven100)

        if self.xsDataFileRaddoseLog is not None:
            xsDataResultStrategy.setRaddoseLogFile(self.xsDataFileRaddoseLog)
        # Plots
        if not self._edPluginPlotGle.isFailure(
        ) and self._edPluginPlotGle.dataOutput is not None:
            listFileGraph = self._edPluginPlotGle.dataOutput.fileGraph
            xsDataResultStrategy.bestGraphFile = listFileGraph
        # Sample
        xsDataResultStrategy.setSample(self._xsDataSampleCopy)
        # timeToReachHendersonLimit
        if self._edPluginRaddose is not None:
            xsDataRaddoseOutput = self._edPluginRaddose.dataOutput
            if xsDataRaddoseOutput is not None:
                xsDataResultStrategy.timeToReachHendersonLimit = xsDataRaddoseOutput.timeToReachHendersonLimit
        self.setDataOutput(xsDataResultStrategy)
        self.generateStrategyShortSummary(xsDataResultStrategy)

    def doRaddoseToBestTransition(self, _edPlugin):
        self.DEBUG("EDPluginControlStrategyv1_2.doRaddoseToBestTransition")
        self.retrieveSuccessMessages(
            _edPlugin, "EDPluginControlStrategyv1_2.doRaddoseToBestTransition")

        xsDataRaddoseOutput = self._edPluginRaddose.getDataOutput()

        # update the strategy data with the data coming from Raddose
        self._xsDataSampleCopy.setAbsorbedDoseRate(
            xsDataRaddoseOutput.getAbsorbedDoseRate())
        if xsDataRaddoseOutput.getPathToLogFile() != None:
            self.xsDataFileRaddoseLog = xsDataRaddoseOutput.getPathToLogFile()

        # Call the Best Translator layer
        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2
        self._edHandlerXSDataBest = EDHandlerXSDataBestv1_2()

        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(
            self.getDataInput().marshal())
        xsDataInputStrategyCopy.setSample(self._xsDataSampleCopy)

        xsDataInputBest = self._edHandlerXSDataBest.getXSDataInputBest(
            xsDataInputStrategyCopy)

        self._edPluginBest.setDataInput(xsDataInputBest)
        self._edPluginBest.executeSynchronous()

    def doFailureActionRaddose(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlStrategyv1_2.doFailureActionRaddose")
        self.retrieveFailureMessages(
            _edPlugin, "EDPluginControlStrategyv1_2.doFailureActionRaddose")
        strWarningMessage = "EDPluginControlStrategyv1_2: Raddose failure"
        self.warning(strWarningMessage)
        self.addWarningMessage(strWarningMessage)
        self.executeBest(self)

    def executeBest(self, _edPlugin=None):
        # Call the Best Translator layer

        from EDHandlerXSDataBestv1_2 import EDHandlerXSDataBestv1_2
        self._edHandlerXSDataBest = EDHandlerXSDataBestv1_2()
        xsDataInputStrategyCopy = XSDataInputStrategy.parseString(
            self.getDataInput().marshal())
        xsDataInputStrategyCopy.setSample(self._xsDataSampleCopy)
        xsDataInputBest = self._edHandlerXSDataBest.getXSDataInputBest(
            xsDataInputStrategyCopy)
        self._edPluginBest.setDataInput(xsDataInputBest)
        self._edPluginBest.executeSynchronous()

    def doSuccessActionBest(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        """
        self.DEBUG("EDPluginControlStrategyv1_2.doSuccessActionBest")
        self.retrieveSuccessMessages(
            _edPlugin, "EDPluginControlStrategyv1_2.doSuccessActionBest")

    def doFailureActionBest(self, _edPlugin):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlStrategyv1_2.doFailureActionBest")
        self.retrieveFailureMessages(_edPlugin, "BEST failure:")
        self.generateExecutiveSummary(self)
        self.setFailure()

    def getDefaultChemicalComposition(self, _xsDataSample, _inumOperators):
        xsDataCell = _xsDataSample.getCrystal().getCell()
        a = xsDataCell.getLength_a().getValue()
        b = xsDataCell.getLength_b().getValue()
        c = xsDataCell.getLength_c().getValue()
        alpha = math.radians(xsDataCell.getAngle_alpha().getValue())
        beta = math.radians(xsDataCell.getAngle_beta().getValue())
        gamma = math.radians(xsDataCell.getAngle_gamma().getValue())

        fUnitCellVolume = a * b * c * (math.sqrt(1 - math.cos(alpha) * math.cos(alpha) - \
                                                 math.cos(beta) * math.cos(beta) - \
                                                 math.cos(gamma) * math.cos(gamma) + \
                                                 2 * math.cos(alpha) * math.cos(beta) * math.cos(gamma)))
        fPolymerVolume = fUnitCellVolume * (
            1 - self._fAverageCrystalSolventContent)
        fNumberOfMonomersPerUnitCell = fPolymerVolume / self._fAverageAminoAcidVolume
        fNumberOfMonomersPerAsymmetricUnit = fNumberOfMonomersPerUnitCell / _inumOperators
        iNumberOfSulfurAtom = int(
            round(fNumberOfMonomersPerAsymmetricUnit *
                  self._fAverageSulfurContentPerAminoacid))

        xsDataAtom = XSDataAtom()
        xsDataAtom.setSymbol(XSDataString("S"))
        xsDataAtom.setNumberOf(XSDataDouble(iNumberOfSulfurAtom))
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomicComposition.addAtom(xsDataAtom)

        xsDataChain = XSDataChain()
        xsDataChain.setType(XSDataString("protein"))
        xsDataChain.setNumberOfMonomers(
            XSDataDouble(round(fNumberOfMonomersPerAsymmetricUnit)))
        xsDataChain.setNumberOfCopies(XSDataDouble(1))
        xsDataChain.setHeavyAtoms(xsDataAtomicComposition)

        xsDataStructure = XSDataStructure()
        xsDataStructure.addChain(xsDataChain)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(1))

        xsDataAtomSolvent = XSDataAtom()
        xsDataAtomSolvent.setSymbol(XSDataString("S"))
        xsDataAtomSolvent.setConcentration(
            XSDataDouble(self._fAverageSulfurConcentration))
        xsDataAtomicCompositionSolvent = XSDataAtomicComposition()
        xsDataAtomicCompositionSolvent.addAtom(xsDataAtomSolvent)
        xsDataSolvent = XSDataSolvent()
        xsDataSolvent.setAtoms(xsDataAtomicCompositionSolvent)

        xsDataChemicalCompositionMM = XSDataChemicalCompositionMM()
        xsDataChemicalCompositionMM.setSolvent(xsDataSolvent)
        xsDataChemicalCompositionMM.setStructure(xsDataStructure)

        return xsDataChemicalCompositionMM

    def updateChemicalComposition(self, _xsDataChemicalComposition):
        xsDataChemicalComposition = _xsDataChemicalComposition

        for chain in xsDataChemicalComposition.getStructure().getChain():
            if (chain.getType().getValue() == "protein"):
                bSulfurExists = False
                xsDataAtomicCompositionHeavyAtoms = chain.getHeavyAtoms()
                if (xsDataAtomicCompositionHeavyAtoms is None):
                    xsDataAtomicCompositionHeavyAtoms = XSDataAtomicComposition(
                    )
                else:
                    for heavyAtom in xsDataAtomicCompositionHeavyAtoms.getAtom(
                    ):
                        if (heavyAtom.getSymbol().getValue() == "S"
                                or heavyAtom.getSymbol().getValue() == "s"):
                            bSulfurExists = True

                # all protein chains should contain sulfur atom as a percentage of the number
                # of amino acids. Add them if the user did not input them.
                if (bSulfurExists == False):
                    iNumberOfSulfurAtom = int(
                        round(chain.getNumberOfMonomers().getValue() * 0.05))
                    xsDataSulfurAtom = XSDataAtom()
                    xsDataSulfurAtom.setSymbol(XSDataString("S"))
                    xsDataSulfurAtom.setNumberOf(
                        XSDataDouble(iNumberOfSulfurAtom))
                    xsDataAtomicCompositionHeavyAtoms.addAtom(xsDataSulfurAtom)
                    chain.setHeavyAtoms(xsDataAtomicCompositionHeavyAtoms)

        return xsDataChemicalComposition

    def generateExecutiveSummary(self, _edPlugin):
        """
        Generates a summary of the execution of the plugin.
        """
        self.DEBUG("EDPluginControlStrategyv1_2.generateExecutiveSummary")
        self.addExecutiveSummaryLine("Summary of Strategy:")
        self.addErrorWarningMessagesToExecutiveSummary()

        xsDataResultStrategy = self.getDataOutput()

        if (self._edPluginRaddose is not None):
            if (self._edPluginRaddose.getDataOutput() is not None):

                self.addExecutiveSummaryLine("")
                self.appendExecutiveSummary(self._edPluginRaddose,
                                            "Raddose : ")

            if (xsDataResultStrategy is not None):
                self.addExecutiveSummaryLine("")
                self.addExecutiveSummaryLine(
                    "Calculations assuming polymer crystal with:")
                self.addExecutiveSummaryLine(
                    "------------------------------------------")
                self.addExecutiveSummaryLine("")

                xsDataStructure = xsDataResultStrategy.getCollectionPlan(
                )[0].getCollectionStrategy().getSample(
                ).getChemicalComposition().getStructure()

                self.addExecutiveSummaryLine(
                    "Number of structure copies in asymmetric unit: %.2f" %
                    xsDataStructure.getNumberOfCopiesInAsymmetricUnit(
                    ).getValue())
                self.addExecutiveSummaryLine("")

                chains = xsDataStructure.getChain()
                self.addExecutiveSummaryLine("Chains:")
                for chain in chains:
                    strChainType = chain.getType().getValue()
                    self.addExecutiveSummaryLine(
                        "    Type                           : %s" %
                        strChainType)
                    if (strChainType == "protein"):
                        self.addExecutiveSummaryLine(
                            "    Number of residues             : %.2f" %
                            chain.getNumberOfMonomers().getValue())
                    elif (strChainType == "dna" or strChainType == "rna"):
                        self.addExecutiveSummaryLine(
                            "    Number of nucleotides          : %.2f" %
                            chain.getNumberOfMonomers().getValue())
                    strHeavyAtomsChain = "    Number of heavy atoms          :"
                    if (chain.getHeavyAtoms() is not None):
                        heavyAtomsChain = chain.getHeavyAtoms().getAtom()
                        for heavyAtomChain in heavyAtomsChain:
                            strHeavyAtomsChain = strHeavyAtomsChain + " %s=%d" % (
                                heavyAtomChain.getSymbol().getValue(),
                                heavyAtomChain.getNumberOf().getValue())
                    else:
                        strHeavyAtomsChain = strHeavyAtomsChain + " No heavy atoms"
                    self.addExecutiveSummaryLine(strHeavyAtomsChain)

                    self.addExecutiveSummaryLine(
                        "    Number of copies in structure  : %.2f" %
                        chain.getNumberOfCopies().getValue())
                    self.addExecutiveSummaryLine("")

                ligands = xsDataStructure.getLigand()
                if (len(ligands) != 0):
                    self.addExecutiveSummaryLine("Ligands:")

                for ligand in ligands:
                    self.addExecutiveSummaryLine(
                        "    Number of light atoms          : %.2f" %
                        ligand.getNumberOfLightAtoms().getValue())
                    strHeavyAtomsLigand = "    Number of heavy atoms          :"
                    if (ligand.getHeavyAtoms() is not None):
                        heavyAtomsLigand = ligand.getHeavyAtoms().getAtom()
                        for heavyAtomLigand in heavyAtomsLigand:
                            strHeavyAtomsLigand = strHeavyAtomsLigand + " %s=%d" % (
                                heavyAtomLigand.getSymbol().getValue(),
                                heavyAtomLigand.getNumberOf().getValue())
                    else:
                        strHeavyAtomsChain = strHeavyAtomsChain + " No heavy atoms"
                    self.addExecutiveSummaryLine(strHeavyAtomsLigand)
                    self.addExecutiveSummaryLine(
                        "    Number of copies in structure  : %.2f" %
                        chain.getNumberOfCopies().getValue())
                    self.addExecutiveSummaryLine("")

        if (self._edPluginBest is not None):
            if (self._edPluginBest.getDataOutput() is not None):
                self.appendExecutiveSummary(self._edPluginBest, "Best : ")
                self.addExecutiveSummaryLine("")

    def generateStrategyShortSummary(self, _xsDataResultStrategy):
        """
        Generates a short summary of the BEST strategy
        """
        self.DEBUG(
            "EDPluginControlIntegrationv10.generateIntegrationShortSummary")
        strStrategyShortSummary = ""
        iTotalNoImages = 0
        fTotalExposureTime = 0.0
        xsDataDiffractionPlan = None
        if self.getDataInput():
            if self.getDataInput().getDiffractionPlan():
                xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan(
                )
        if self._bEstimateRadiationDamage:
            strStrategyShortSummary += "Strategy: Radiation damage estimated"
            if self._edPluginRaddose.getDataOutput(
            ).getTimeToReachHendersonLimit():
                strStrategyShortSummary += ", time to reach Henderson limit: %.1f s\n" % self._edPluginRaddose.getDataOutput(
                ).getTimeToReachHendersonLimit().getValue()
            else:
                strStrategyShortSummary += "\n"

        else:
            strStrategyShortSummary += "Strategy: No radiation damage estimation"
            if xsDataDiffractionPlan:
                if xsDataDiffractionPlan.getMaxExposureTimePerDataCollection():
                    strStrategyShortSummary += ", max exposure time per data collection: %.1f s\n" % xsDataDiffractionPlan.getMaxExposureTimePerDataCollection(
                    ).getValue()
                else:
                    strStrategyShortSummary += "\n"
            else:
                strStrategyShortSummary += "\n"
        if xsDataDiffractionPlan:
            strStrategyShortSummary += "Strategy: Options: "
            listStrategyOptions = []
            if xsDataDiffractionPlan.getAnomalousData():
                if xsDataDiffractionPlan.getAnomalousData().getValue():
                    listStrategyOptions.append("anomalous data")
            if xsDataDiffractionPlan.getAimedCompleteness():
                listStrategyOptions.append(
                    "aimed completeness = %.1f" %
                    xsDataDiffractionPlan.getAimedCompleteness().getValue())
            if xsDataDiffractionPlan.getAimedMultiplicity():
                listStrategyOptions.append(
                    "aimed multiplicity = %d" %
                    xsDataDiffractionPlan.getAimedMultiplicity().getValue())
            if xsDataDiffractionPlan.getAimedResolution():
                listStrategyOptions.append(
                    "aimed resolution = %.2f A" %
                    xsDataDiffractionPlan.getAimedResolution().getValue())
            if xsDataDiffractionPlan.getComplexity():
                listStrategyOptions.append(
                    "complexity = %s" %
                    xsDataDiffractionPlan.getComplexity().getValue())
            if xsDataDiffractionPlan.getStrategyOption():
                listStrategyOptions.append(
                    "extra strategy option(s) = %s" %
                    xsDataDiffractionPlan.getStrategyOption().getValue())
            if listStrategyOptions != []:
                for strStrategyOption in listStrategyOptions[:-1]:
                    strStrategyShortSummary += strStrategyOption + ", "
                strStrategyShortSummary += listStrategyOptions[-1]
            strStrategyShortSummary += "\n"
        fResolutionMax = None
        fRankingResolution = None
        for xsDataCollectionPlan in _xsDataResultStrategy.getCollectionPlan():
            iNoCollectionPlan = xsDataCollectionPlan.getCollectionPlanNumber(
            ).getValue()
            strStrategyShortSummary += "Strategy: Collection plan %d" % iNoCollectionPlan
            xsDataStrategySummary = xsDataCollectionPlan.getStrategySummary()
            if xsDataStrategySummary.getResolutionReasoning() != None:
                strResolutionResoning = xsDataStrategySummary.getResolutionReasoning(
                ).getValue()
                strStrategyShortSummary += ": %s\n" % strResolutionResoning
            else:
                strStrategyShortSummary += "\n"
            xsDataCollectionStrategy = xsDataCollectionPlan.getCollectionStrategy(
            )
            if xsDataStrategySummary.getRankingResolution() is not None:
                fRankingResolution = xsDataStrategySummary.getRankingResolution(
                ).getValue()
                strStrategyShortSummary += "Strategy: Ranking resolution: %.2f [A]\n" % fRankingResolution
            for xsDataSubWedge in xsDataCollectionStrategy.getSubWedge():
                iWedgeNo = xsDataCollectionPlan.getCollectionPlanNumber(
                ).getValue()
                strStrategyShortSummary += "Strategy: wedge %d: " % iWedgeNo
                xsDataStrategySummary = xsDataCollectionPlan.getStrategySummary(
                )
                fResolution = xsDataStrategySummary.getResolution().getValue()
                if (fResolutionMax is None) or (fResolution < fResolutionMax):
                    fResolutionMax = fResolution
                strStrategyShortSummary += "resolution %.2f [A], " % fResolution
                xsDataStringAction = xsDataSubWedge.getAction()
                if xsDataStringAction is not None:
                    strStrategyShortSummary += "%s, " % xsDataStringAction.getValue(
                    )
                iSubWedgeNo = xsDataSubWedge.getSubWedgeNumber().getValue()
                strStrategyShortSummary += "sub wedge %d: " % iSubWedgeNo
                xsDataExperimentalCondition = xsDataSubWedge.getExperimentalCondition(
                )
                xsDataGoniostat = xsDataExperimentalCondition.getGoniostat()
                fRotationStart = xsDataGoniostat.getRotationAxisStart(
                ).getValue()
                strStrategyShortSummary += "start %.2f, " % fRotationStart
                fRange = xsDataGoniostat.getOscillationWidth().getValue()
                fRotationEnd = xsDataGoniostat.getRotationAxisEnd().getValue()
                iNoImages = int((fRotationEnd - fRotationStart) / fRange + 0.1)
                strStrategyShortSummary += "images %d, " % iNoImages
                strStrategyShortSummary += "width %.2f, " % fRange
                xsDataBeam = xsDataExperimentalCondition.getBeam()
                fExpTime = xsDataBeam.getExposureTime().getValue()
                strStrategyShortSummary += "time %.2f [s], " % fExpTime
                fTransmission = xsDataBeam.getTransmission().getValue()
                strStrategyShortSummary += "transmission %.2f\n" % fTransmission
                iTotalNoImages += iNoImages
                fTotalExposureTime += fExpTime * iNoImages
            strStrategyShortSummary += "Strategy: total no images %d, total exposure time %.1f [s]\n" % \
                                    (iTotalNoImages, fTotalExposureTime)
        if fRankingResolution is not None:
            if (fRankingResolution < fResolutionMax) and (
                    abs(fRankingResolution - fResolutionMax) > 0.1):
                strStrategyShortSummary += "\n"
                strStrategyShortSummary += "NOTE! " * 20 + "\n"
                strStrategyShortSummary += "\n"
                strStrategyShortSummary += "BEST has calculated that it should be possible to collect data to %.2f A from this sample.\n" % fRankingResolution
                strStrategyShortSummary += "If you want to calculate a new strategy for data collection to this resolution you\n"
                strStrategyShortSummary += "must first recollect reference images at this resolution.\n"
                strStrategyShortSummary += "\n"
                strStrategyShortSummary += "NOTE! " * 20 + "\n"
                strStrategyShortSummary += "\n"

        self.setDataOutput(XSDataString(strStrategyShortSummary),
                           "strategyShortSummary")
    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())
class EDPluginControlStrategyv1_1(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """
    def __init__(self):
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputStrategy)

        self.__strPluginRaddoseName = "EDPluginRaddosev10"
        self.__edPluginRaddose = None
        self.__edHandlerXSDataRaddose = None

        self.__strPluginBestName = "EDPluginBestv1_1"
        self.__edPluginBest = None
        self.__edHandlerXSDataBest = None

        self.__strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self.__strSymopHome = "/opt/pxsoft/ccp4-6.0.2/lib/data"

        self.__xsDataSampleCopy = None

        # For default chemical composition
        self.__fAverageAminoAcidVolume = 135.49
        self.__fAverageCrystalSolventContent = 0.47
        self.__fAverageSulfurContentPerAminoacid = 0.05
        self.__fAverageSulfurConcentration = 314

    def setSymopHome(self, _strSymopHome):
        self.__strSymopHome = _strSymopHome

    def getSymopHome(self):
        return self.__strSymopHome

    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv1_1.preProcess...")
        self.__edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if (xsDataSampleCrystalMM is None):
            self.__xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.__xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if (xsDataCrystal is not None):
            self.__xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if (self.getDataInput().getExperimentalCondition().getBeam().getFlux()
                is None):
            pyStrWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                'EDPluginControlStrategyv1_1.preProcess',
                self.__strPluginRaddoseName, "Beam Flux not set")
            EDVerbose.warning(pyStrWarningMessage)
            self.addWarningMessage(pyStrWarningMessage)

        else:
            self.__edPluginRaddose = self.loadPlugin(
                self.__strPluginRaddoseName)

            if (self.__edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv1_1.preProcess: " +
                                self.__strPluginRaddoseName +
                                " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput(
                ).getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                strNumOperators = None
                strSpaceGroup = None
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper()
                    EDVerbose.DEBUG(
                        "EDPluginControlStrategyv1_1.preProcess: Forced Space Group Found: "
                        + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                            strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        pyStrErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                            'EDPluginControlStrategyv1_1.preProcess',
                            "Problem to calculate Number of symmetry operators",
                            detail)
                        EDVerbose.error(pyStrErrorMessage)
                        self.addErrorMessage(pyStrErrorMessage)
                        self.setFailure()
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.__xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self.__xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlStrategyv1_1.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            pyStrErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlStrategyv1_1.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(pyStrErrorMessage)
                            self.addErrorMessage(pyStrErrorMessage)
                            self.setFailure()
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self.__xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlStrategyv1_1.preProcess: Space Group IT Number Found by indexing: "
                            + str(iSpaceGroupITNumber))
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(iSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            pyStrErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlStrategyv1_1.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(pyStrErrorMessage)
                            self.addErrorMessage(pyStrErrorMessage)
                            self.setFailure()
    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())
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess...")
        self._edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if(xsDataSampleCrystalMM is None):
            self._xsDataSampleCopy = XSDataSampleCrystalMM()
        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self._xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if(xsDataCrystal is not None):
            self._xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Load the Best plugin
        self._edPluginBest = self.loadPlugin(self._strPluginBestName)
        self._edPluginBest.setBaseDirectory(self.getWorkingDirectory())
        self._edPluginBest.setBaseName(self._strPluginBestName)

        # Load the plot gle plugin
        self._edPluginPlotGle = self.loadPlugin(self._strPluginPlotGleName)

        # Check if radiation damage estimation is required or not in the diffraction plan
        xsDataDiffractionPlan = self.getDataInput().getDiffractionPlan()
        if xsDataDiffractionPlan is not None:
            if xsDataDiffractionPlan.getEstimateRadiationDamage():
                if xsDataDiffractionPlan.getEstimateRadiationDamage().getValue():
                    # Yes, is requested
                    self._bEstimateRadiationDamage = True
                else:
                    # No, is explicitly not requested
                    self._bEstimateRadiationDamage = False
            elif xsDataDiffractionPlan.getStrategyOption() is not None:
                if xsDataDiffractionPlan.getStrategyOption().getValue().find("-DamPar") != -1:
                    # The "-DamPar" option requires estimation of radiation damage
                    self._bEstimateRadiationDamage = True

        # Check if we know what to do with radiation damage
        if self._bEstimateRadiationDamage is None:
            # "Force" the estimation of radiation damage if the flux is present
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strWarningMessage = "EDPluginControlStrategyv1_2: Missing flux input - cannot estimate radiation damage."
                EDVerbose.WARNING(strWarningMessage)
                self.addWarningMessage(strWarningMessage)
                self._bEstimateRadiationDamage = False
            else:
                self._bEstimateRadiationDamage = True


        if self._bEstimateRadiationDamage:
            if self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None:
                strErrorMessage = "EDPluginControlStrategyv1_2: Missing flux input. Cannot estimate radiation damage"
                EDVerbose.ERROR(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                self.setFailure()

        if not self.isFailure():

            self._edPluginRaddose = self.loadPlugin(self._strPluginRaddoseName)

            if (self._edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: " + self._strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                bSpaceGroupForced = False
                if(xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper().replace(" ", "")
                    if strSpaceGroup != "":
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Forced Space Group Found: " + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                            bSpaceGroupForced = True
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                if not bSpaceGroupForced:
                    # Space Group has NOT been forced
                    xsDataStringSpaceGroup = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Space Group IT Name found by indexing: " + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self._xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv1_2.preProcess: Space Group IT Number Found by indexing: %d" % iSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(str(iSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv1_2.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
class EDPluginControlStrategyv10(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """

    def __init__ (self):
        EDPluginControl.__init__(self)

        self.__strPluginRaddoseName = "EDPluginRaddosev10"
        self.__oedPluginRaddose = None
        self.__oedHandlerXSDataRaddose = None

        self.__strPluginBestName = "EDPluginBestv10"
        self.__edPluginBest = None
        self.__edHandlerXSDataBest = None

        self.__strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self.__strSymopHome = "/opt/pxsoft/ccp4-6.0.2/lib/data"

        self.__xsDataSampleCopy = None

        # For default chemical composition
        self.__fAverageAminoAcidVolume = 135.49
        self.__fAverageCrystalSolventContent = 0.47
        self.__fAverageSulfurContentPerAminoacid = 0.05
        self.__fAverageSulfurConcentration = 314

        self.setXSDataInputClass(XSDataStrategyInput)


    def setSymopHome(self, _strSymopHome):
        self.__strSymopHome = _strSymopHome


    def getSymopHome(self):
        return self.__strSymopHome


    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess...")
        self.__edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if(xsDataSampleCrystalMM is None):
            self.__xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.__xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if(xsDataCrystal is not None):
            self.__xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if(self.getDataInput().getExperimentalCondition().getBeam().getFlux() is None):
            warningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % ('EDPluginControlStrategyv10.preProcess', self.__strPluginRaddoseName, "Beam Flux not set")
            EDVerbose.warning(warningMessage)
            self.addWarningMessage(warningMessage)

        else:
            self.__edPluginRaddose = self.loadPlugin(self.__strPluginRaddoseName)

            if (self.__edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: " + self.__strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput().getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                if(xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue()
                    EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: Forced Space Group Found: " + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        errorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv10.preProcess', "Problem to calculate Number of symmetry operators", detail)
                        EDVerbose.error(errorMessage)
                        self.addErrorMessage(errorMessage)
                        raise RuntimeError, errorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: Space Group IT Name found by indexing: " + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            errorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv10.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(errorMessage)
                            self.addErrorMessage(errorMessage)
                            raise RuntimeError, errorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        strSpaceGroupITNumber = str(self.__xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue())
                        EDVerbose.DEBUG("EDPluginControlStrategyv10.preProcess: Space Group IT Number Found by indexing: " + strSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(strSpaceGroupITNumber, strFileSymop)
                        except Exception, detail:
                            errorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlStrategyv10.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(errorMessage)
                            self.addErrorMessage(errorMessage)
                            raise RuntimeError, errorMessage
    def testSetDataModelInput(self):
        from XSDataCCP4iv1_1 import XSDataInputCCP4i
        xsDataInputCCP4i = XSDataInputCCP4i()

        # Beam
        from XSDataCommon import XSDataFlux
        from XSDataCommon import XSDataSize
        from XSDataCommon import XSDataLength
        from XSDataCommon import XSDataFloat

        from XSDataMXv1 import XSDataBeam
        from XSDataMXv1 import XSDataExperimentalCondition

        xsExperimentalCondition = XSDataExperimentalCondition()

        xsBeam = XSDataBeam()
        xsBeam.setFlux(XSDataFlux(1e+12))
        xsBeam.setSize(XSDataSize(XSDataLength(0.1), XSDataLength(0.1)))
        xsBeam.setMinExposureTimePerImage(XSDataFloat(0.1))
        xsExperimentalCondition.setBeam(xsBeam)

        # Goniostat
        from XSDataCommon import XSDataSpeed
        from XSDataCommon import XSDataAngle

        from XSDataMXv1 import XSDataGoniostat

        xsDataGoniostat = XSDataGoniostat()
        xsDataGoniostat.setMaxOscillationSpeed(XSDataSpeed(0.2))
        xsDataGoniostat.setMinOscillationWidth(XSDataAngle(0.1))
        xsExperimentalCondition.setGoniostat(xsDataGoniostat)
        xsDataInputCCP4i.setExperimentalCondition(xsExperimentalCondition)

        # Sample
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataFloat
        from XSDataCommon import XSDataString

        from XSDataMXv1 import XSDataStructure
        from XSDataMXv1 import XSDataChain
        from XSDataMXv1 import XSDataAtom
        from XSDataMXv1 import XSDataLigand
        from XSDataMXv1 import XSDataSampleCrystalMM
        from XSDataMXv1 import XSDataChemicalCompositionMM
        from XSDataMXv1 import XSDataAtomicComposition
        from XSDataMXv1 import XSDataSolvent

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

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

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

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

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

        xsDataSolvent = XSDataSolvent()
        xsDataAtomicComposition = XSDataAtomicComposition()

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

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

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

        xsDataSampleCrystalMM.setSize(XSDataSize(XSDataLength(0.2), XSDataLength(0.2), XSDataLength(0.2)))
        xsDataSampleCrystalMM.setSusceptibility(XSDataFloat(1.5))
        xsDataSampleCrystalMM.setShape(XSDataFloat(2))

        xsDataInputCCP4i.setSample(xsDataSampleCrystalMM)

        from XSDataMXv1 import XSDataDiffractionPlan

        xsDataDiffractionPlan = XSDataDiffractionPlan()

        xsDataDiffractionPlan.setAimedCompleteness(XSDataFloat(95.5))
        xsDataDiffractionPlan.setAimedIOverSigmaAtHighestResolution(XSDataFloat(2.5))
        xsDataDiffractionPlan.setAimedMultiplicity(XSDataFloat(95.5))
        xsDataDiffractionPlan.setAimedResolution(XSDataFloat(3))
        xsDataDiffractionPlan.setComplexity(XSDataString("full"))
        xsDataDiffractionPlan.setForcedSpaceGroup(XSDataString("P222"))
        xsDataDiffractionPlan.setMaxExposureTimePerDataCollection(XSDataFloat(10000))

        xsDataInputCCP4i.setDiffractionPlan(xsDataDiffractionPlan)

        from XSDataCommon import XSDataFile

        listInputDataFile = []
        xsDataFile = XSDataFile(XSDataString(self.strXSDataGenerateTemplateFile))
        listInputDataFile.append(xsDataFile)
        xsDataInputCCP4i.setDataFile(listInputDataFile)
    def testGetXSDataRaddoseInput(self):
        """
        """
        from XSDataCommon import XSDataLength
        from XSDataCommon import XSDataWavelength
        from XSDataCommon import XSDataFlux
        from XSDataCommon import XSDataSize
        from XSDataCommon import XSDataDouble
        from XSDataCommon import XSDataString
        from XSDataCommon import XSDataAngle
        from XSDataCommon import XSDataTime
        from XSDataCommon import XSDataInteger

        from XSDataMXv1   import XSDataBeam
        from XSDataMXv1   import XSDataStructure
        from XSDataMXv1   import XSDataChain
        from XSDataMXv1   import XSDataAtom
        from XSDataMXv1   import XSDataLigand
        from XSDataMXv1   import XSDataCrystal
        from XSDataMXv1   import XSDataSpaceGroup
        from XSDataMXv1   import XSDataSampleCrystalMM
        from XSDataMXv1   import XSDataChemicalCompositionMM
        from XSDataMXv1   import XSDataAtomicComposition
        from XSDataMXv1   import XSDataSolvent
        from XSDataMXv1   import XSDataCell

        from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10

        EDFactoryPluginStatic.loadModule("XSDataRaddosev10")
        from XSDataRaddosev10 import XSDataRaddoseInput

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

        xsDataSample = 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)
        xsDataAtom2 = XSDataAtom()
        xsDataAtom2.setSymbol(XSDataString("S"))
        xsDataAtom2.setNumberOf(XSDataDouble(5))
        xsDataAtomicComposition.addAtom(xsDataAtom2)
        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()
        xsDataAtom3 = XSDataAtom()
        xsDataAtom3.setSymbol(XSDataString("Fe"))
        xsDataAtom3.setNumberOf(XSDataDouble(1))
        xsDataAtomicComposition.addAtom(xsDataAtom3)
        xsDataLigand.setHeavyAtoms(xsDataAtomicComposition)
        xsDataStructure.addLigand(xsDataLigand)
        xsDataStructure.setNumberOfCopiesInAsymmetricUnit(XSDataDouble(0.25))

        xsDataSolvent = XSDataSolvent()
        xsDataAtomicComposition = XSDataAtomicComposition()
        xsDataAtomNa = XSDataAtom()
        xsDataAtomNa.setSymbol(XSDataString("Na"))
        xsDataAtomNa.setConcentration(XSDataDouble(1000))
        xsDataAtomicComposition.addAtom(xsDataAtomNa)
        xsDataAtomCl = XSDataAtom()
        xsDataAtomCl.setSymbol(XSDataString("Cl"))
        xsDataAtomCl.setConcentration(XSDataDouble(1000))
        xsDataAtomicComposition.addAtom(xsDataAtomCl)
        xsDataSolvent.setAtoms(xsDataAtomicComposition)

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

        xsDataSample.setSize(XSDataSize(XSDataLength(0.1), XSDataLength(0.1), XSDataLength(0.1)))
        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 = XSDataCrystal()
        xsDataSpaceGroup = XSDataSpaceGroup()

        xsDataCrystal.setCell(xsDataCell)

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

        xsDataSample.setCrystal(xsDataCrystal)

        iNumSymOperators = 4


        xsDataRaddosev01Input = EDHandlerXSDataRaddosev10().getXSDataRaddoseInput(xsDataBeam,
                                                                                      xsDataSample,
                                                                                      iNumSymOperators)


        xsDataRaddosev01Input.exportToFile(self.strObtainedInputFile2)
        strExpectedInput = EDUtilsTest.readAndParseFile (self.strReferenceInputFile2)
        strObtainedInput = EDUtilsTest.readAndParseFile (self.strObtainedInputFile2)

        xsDataInputExpected = XSDataRaddoseInput.parseString(strExpectedInput)
        xsDataInputObtained = XSDataRaddoseInput.parseString(strObtainedInput)

        EDAssert.equal(xsDataInputExpected.marshal(), xsDataInputObtained.marshal())
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        self.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess...")
        self.edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput(
            "mxv1InputStrategy")[0].getSample()

        if (xsDataSampleCrystalMM is None):
            self.xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput(
            "mxv1InputStrategy")[0].getCrystalRefined()
        if (xsDataCrystal is not None):
            self.xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if (self.getDataInput("mxv1InputStrategy")
            [0].getExperimentalCondition().getBeam().getFlux() is None):
            strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                'EDPluginControlKappaStrategyv2_0.preProcess',
                self.strPluginRaddoseName, "Beam Flux not set")
            self.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)

        else:
            self.edPluginRaddose = self.loadPlugin(self.strPluginRaddoseName)

            if (self.edPluginRaddose is not None):
                self.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess: " +
                           self.strPluginRaddoseName +
                           " Found... setting Data Input")

                xsDataStringSpaceGroup = self.getDataInput(
                    "mxv1InputStrategy")[0].getDiffractionPlan(
                    ).getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                strNumOperators = None
                strSpaceGroup = None
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue()
                    self.DEBUG(
                        "EDPluginControlKappaStrategyv2_0.preProcess: Forced Space Group Found: "
                        + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                            strSpaceGroup)
                    except Exception as detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                            'EDPluginControlKappaStrategyv2_0.preProcess',
                            "Problem to calculate Number of symmetry operators",
                            detail)
                        self.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError(strErrorMessage)
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroup = self.xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        self.DEBUG(
                            "EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroup)
                        except Exception as detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlKappaStrategyv2_0.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        dSpaceGroupITNumber = self.xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getITNumber().getValue()
                        self.DEBUG(
                            "EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Number Found by indexing: %d"
                            % dSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(
                                str(dSpaceGroupITNumber))
                        except Exception as detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlKappaStrategyv2_0.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            self.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError(strErrorMessage)

                if (strNumOperators is not None):
                    iNumOperators = int(strNumOperators)
                else:
                    strErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                        'EDPluginControlKappaStrategyv2_0.preProcess',
                        "No symmetry operators found for Space Group: ",
                        strSpaceGroup)
                    self.error(strErrorMessage)
                    self.addErrorMessage(strErrorMessage)
                    raise RuntimeError(strErrorMessage)

                xsDataChemicalComposition = self.xsDataSampleCopy.getChemicalComposition(
                )

                if (xsDataChemicalComposition is None):
                    # create a default chemical composition and assign it to the sample
                    xsDataDefaultChemicalComposition = self.getDefaultChemicalComposition(
                        self.xsDataSampleCopy, iNumOperators)
                    self.xsDataSampleCopy.setChemicalComposition(
                        xsDataDefaultChemicalComposition)
                else:
                    # Check for Sulfur atoms, if none, add native sulfur atoms
                    xsDataUpdatedChemicalComposition = self.updateChemicalComposition(
                        xsDataChemicalComposition)
                    self.xsDataSampleCopy.setChemicalComposition(
                        xsDataUpdatedChemicalComposition)

                # create Data Input for Raddose
                from EDHandlerXSDataRaddosev10 import EDHandlerXSDataRaddosev10
                self.edHandlerXSDataRaddose = EDHandlerXSDataRaddosev10()
                xsDataBeam = self.getDataInput("mxv1InputStrategy")[
                    0].getExperimentalCondition().getBeam()

                xsDataRaddoseInput = None
                iNumberOfImages = 1
                self.warning("Number of images for RADDOSE forced to 1")
                try:
                    xsDataRaddoseInput = self.edHandlerXSDataRaddose.getXSDataRaddoseInput(
                        xsDataBeam, self.xsDataSampleCopy, iNumOperators,
                        iNumberOfImages)

                except Exception as detail:
                    strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                        'EDPluginControlKappaStrategyv2_0.preProcess',
                        self.strPluginRaddoseName,
                        "EDHandlerXSDataRaddose : " + detail)
                    self.warning(strWarningMessage)
                    self.addWarningMessage(strWarningMessage)

                if (xsDataRaddoseInput is not None):
                    self.edPluginRaddose.setDataInput(xsDataRaddoseInput)
                    self.edPluginRaddose.setBaseDirectory(
                        self.getWorkingDirectory())
                    self.edPluginRaddose.setBaseName(self.strPluginRaddoseName)

                    # More checks?
#                    try:
#                        self.edPluginRaddose.setDataInput( xsDataRaddoseInput )
#                        self.edPluginRaddose.setBaseDirectory( self.getWorkingDirectory() )
#                        self.edPluginRaddose.setBaseName( self.strPluginRaddoseName )
#
#                    except Exception, detail:
#                        strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % ('EDPluginControlStrategyv1_1.preProcess', self.strPluginRaddoseName,  detail ) )
#                        self.warning( strWarningMessage )
#                        self.addWarningMessage( strWarningMessage )

            else:
                strErrorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                    'EDPluginControlKappaStrategyv2_0.preProcess',
                    self.strPluginRaddoseName)
                self.error(strErrorMessage)
                self.addErrorMessage(strErrorMessage)
                raise RuntimeError(strErrorMessage)

        self.edPluginBest = self.loadPlugin(self.strPluginBestName)
        if (self.edPluginBest is None):
            strErrorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                'EDPluginControlKappaStrategyv2_0.preProcess',
                self.strPluginBestName)
            self.error(strErrorMessage)
            self.addErrorMessage(strErrorMessage)
            raise RuntimeError(strErrorMessage)
        else:
            self.edPluginBest.setBaseDirectory(self.getWorkingDirectory())
            self.edPluginBest.setBaseName(self.strPluginBestName)

        if (self.KappaStrategy):
            # Alignment
            self.edPluginAlignment = self.loadPlugin(
                self.strPluginAlignmentName)
            if (self.edPluginAlignment is None):
                errorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                    'EDPluginControlKappaStrategyv2_0.preProcess',
                    self.strPluginAlignmentName)
                self.error(errorMessage)
                self.addErrorMessage(errorMessage)
                # do not kill the application just because this feature is not available
                # raise RuntimeError, errorMessage
            else:
                self.edPluginAlignment.setBaseDirectory(
                    self.getWorkingDirectory())
                self.edPluginAlignment.setBaseName(self.strPluginAlignmentName)

            # KappaStaregy
            self.edPluginKappaStrategy = self.loadPlugin(
                self.strPluginKappaStrategyName)
            if (self.edPluginKappaStrategy is None):
                errorMessage = EDMessage.ERROR_PLUGIN_NOT_LOADED_02 % (
                    'EDPluginControlKappaStrategyv2_0.preProcess',
                    self.strPluginKappaStrategyName)
                self.error(errorMessage)
                self.addErrorMessage(errorMessage)
                # raise RuntimeError, errorMessage
            else:
                self.edPluginKappaStrategy.setBaseDirectory(
                    self.getWorkingDirectory())
                self.edPluginKappaStrategy.setBaseName(
                    self.strPluginKappaStrategyName)
    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlStrategyv1_1.preProcess...")
        self.__edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput().getSample()

        if (xsDataSampleCrystalMM is None):
            self.__xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.__xsDataSampleCopy = XSDataSampleCrystalMM.parseString(
                strXmlStringDataSample)

        xsDataCrystal = self.getDataInput().getCrystalRefined()
        if (xsDataCrystal is not None):
            self.__xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if (self.getDataInput().getExperimentalCondition().getBeam().getFlux()
                is None):
            pyStrWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % (
                'EDPluginControlStrategyv1_1.preProcess',
                self.__strPluginRaddoseName, "Beam Flux not set")
            EDVerbose.warning(pyStrWarningMessage)
            self.addWarningMessage(pyStrWarningMessage)

        else:
            self.__edPluginRaddose = self.loadPlugin(
                self.__strPluginRaddoseName)

            if (self.__edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlStrategyv1_1.preProcess: " +
                                self.__strPluginRaddoseName +
                                " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput(
                ).getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                strNumOperators = None
                strSpaceGroup = None
                if (xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue().upper()
                    EDVerbose.DEBUG(
                        "EDPluginControlStrategyv1_1.preProcess: Forced Space Group Found: "
                        + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                            strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        pyStrErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                            'EDPluginControlStrategyv1_1.preProcess',
                            "Problem to calculate Number of symmetry operators",
                            detail)
                        EDVerbose.error(pyStrErrorMessage)
                        self.addErrorMessage(pyStrErrorMessage)
                        self.setFailure()
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.__xsDataSampleCopy.getCrystal(
                    ).getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroupName = self.__xsDataSampleCopy.getCrystal(
                        ).getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG(
                            "EDPluginControlStrategyv1_1.preProcess: Space Group IT Name found by indexing: "
                            + strSpaceGroupName)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(
                                strSpaceGroupName, strFileSymop)
                        except Exception, detail:
                            pyStrErrorMessage = EDMessage.ERROR_EXECUTION_03 % (
                                'EDPluginControlStrategyv1_1.preProcess',
                                "Problem to calculate Number of symmetry operators",
                                detail)
                            EDVerbose.error(pyStrErrorMessage)
                            self.addErrorMessage(pyStrErrorMessage)
                            self.setFailure()
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        iSpaceGroupITNumber = self.__xsDataSampleCopy.getCrystal(
class EDPluginControlKappaStrategyv2_0(EDPluginControl):
    """
    The Plugin that controls the strategy step
    """

    def __init__ (self):
        EDPluginControl.__init__(self)
        #self.setXSDataInputClass(EDList)

        self.setRequiredToHaveConfiguration(True)

        self.strPluginRaddoseName = "EDPluginRaddosev10"
        self.edPluginRaddose = None
        self.edHandlerXSDataRaddose = None

        self.strPluginBestName = "EDPluginBestv1_2"
        self.edPluginBest = None
        from EDHandlerXSDataBestv1_2    import EDHandlerXSDataBestv1_2
        self.edHandlerXSDataBest = EDHandlerXSDataBestv1_2()

        self.strPluginAlignmentName = "EDPluginSTACAlignmentv2_0"
        self.edPluginAlignment = None
        self.edHandlerXSDataAlignment = None

        self.strPluginKappaStrategyName = "EDPluginSTACStrategyv2_0"
        self.edPluginKappaStrategy = None
        self.edHandlerXSDataKappaStrategy = None

        self.setXSDataInputClass(XSDataInputStrategy, "mxv1InputStrategy")
        EDFactoryPluginStatic.loadModule("XSDataMXv2")
        import XSDataMXv2
        self.setXSDataInputClass(XSDataMXv2.XSDataCollection, "mxv2DataCollection")
        import XSDataMXv1
        self.setXSDataInputClass(XSDataMXv1.XSDataIndexingResult, "mxv1IndexingResult")

        #disable kappa by default
        self.KappaStrategy = 0

        self.strCONF_SYMOP_HOME = "symopHome"
        # Default value for the location of the symop table
        self.strSymopHome = os.path.normpath("/opt/pxsoft/ccp4-6.0.2/lib/data")

        self.xsDataSampleCopy = None

        # For default chemical composition
        self.fAverageAminoAcidVolume = 135.49
        self.fAverageCrystalSolventContent = 0.47
        self.fAverageSulfurContentPerAminoacid = 0.05
        self.fAverageSulfurConcentration = 314


    def setSymopHome(self, _strSymopHome):
        self.strSymopHome = _strSymopHome


    def getSymopHome(self):
        return self.strSymopHome


    def preProcess(self, _edObject=None):
        """
        Gets the Configuration Parameters, if found, overrides default parameters
        """
        EDPluginControl.preProcess(self, _edObject)
        EDVerbose.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess...")
        self.edPluginRaddose = None

        xsDataSampleCrystalMM = self.getDataInput("mxv1InputStrategy")[0].getSample()

        if(xsDataSampleCrystalMM is None):
            self.xsDataSampleCopy = XSDataSampleCrystalMM()

        else:
            strXmlStringDataSample = xsDataSampleCrystalMM.marshal()
            self.xsDataSampleCopy = XSDataSampleCrystalMM.parseString(strXmlStringDataSample)

        xsDataCrystal = self.getDataInput("mxv1InputStrategy")[0].getCrystalRefined()
        if(xsDataCrystal is not None):
            self.xsDataSampleCopy.setCrystal(xsDataCrystal)

        # Raddose is enabled only if the beam flux is set
        if(self.getDataInput("mxv1InputStrategy")[0].getExperimentalCondition().getBeam().getFlux() is None):
            strWarningMessage = EDMessage.WARNING_CANNOT_USE_PLUGIN_03 % ('EDPluginControlKappaStrategyv2_0.preProcess', self.strPluginRaddoseName, "Beam Flux not set")
            EDVerbose.warning(strWarningMessage)
            self.addWarningMessage(strWarningMessage)

        else:
            self.edPluginRaddose = self.loadPlugin(self.strPluginRaddoseName)

            if (self.edPluginRaddose is not None):
                EDVerbose.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess: " + self.strPluginRaddoseName + " Found... setting Data Input")

                strFileSymop = os.path.join(self.getSymopHome(), "symop.lib")

                xsDataStringSpaceGroup = self.getDataInput("mxv1InputStrategy")[0].getDiffractionPlan().getForcedSpaceGroup()
                # Space Group has been forced
                # Prepare chemical composition calculation with the forced Space Group (Space Group Name)
                strNumOperators = None
                strSpaceGroup = None
                if(xsDataStringSpaceGroup is not None):
                    strSpaceGroup = xsDataStringSpaceGroup.getValue()
                    EDVerbose.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess: Forced Space Group Found: " + strSpaceGroup)
                    try:
                        strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                    except Exception, detail:
                        strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlKappaStrategyv2_0.preProcess', "Problem to calculate Number of symmetry operators", detail)
                        EDVerbose.error(strErrorMessage)
                        self.addErrorMessage(strErrorMessage)
                        raise RuntimeError, strErrorMessage
                # Space Group has NOT been forced
                else:
                    xsDataStringSpaceGroup = self.xsDataSampleCopy.getCrystal().getSpaceGroup().getName()
                    if (xsDataStringSpaceGroup is not None):
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group Name)
                        strSpaceGroup = self.xsDataSampleCopy.getCrystal().getSpaceGroup().getName().getValue()
                        EDVerbose.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Name found by indexing: " + strSpaceGroup)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupName(strSpaceGroup, strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlKappaStrategyv2_0.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage
                    else:
                        # Prepare chemical composition calculation with the Space Group calculated by indexing (Space Group IT number)
                        dSpaceGroupITNumber = self.xsDataSampleCopy.getCrystal().getSpaceGroup().getITNumber().getValue()
                        EDVerbose.DEBUG("EDPluginControlKappaStrategyv2_0.preProcess: Space Group IT Number Found by indexing: %d" % dSpaceGroupITNumber)
                        try:
                            strNumOperators = EDUtilsSymmetry.getNumberOfSymmetryOperatorsFromSpaceGroupITNumber(str(dSpaceGroupITNumber), strFileSymop)
                        except Exception, detail:
                            strErrorMessage = EDMessage.ERROR_EXECUTION_03 % ('EDPluginControlKappaStrategyv2_0.preProcess', "Problem to calculate Number of symmetry operators", detail)
                            EDVerbose.error(strErrorMessage)
                            self.addErrorMessage(strErrorMessage)
                            raise RuntimeError, strErrorMessage