コード例 #1
0
    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        xsDataInputMXCuBE = self.getDataInput()
        xsDataInputInterface = XSDataInputInterface()
        self.edPluginControlInterface = self.loadPlugin(
            self.strPluginControlInterface)
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                xsDataInputInterface.addImagePath(xsDataFile)

        xsDataInputInterface.setExperimentalCondition(
            xsDataInputMXCuBE.getExperimentalCondition())
        xsDataInputInterface.setDiffractionPlan(
            xsDataInputMXCuBE.getDiffractionPlan())
        xsDataInputInterface.setSample(xsDataInputMXCuBE.getSample())
        xsDataInputInterface.setDataCollectionId(
            xsDataInputMXCuBE.getDataCollectionId())
        self.edPluginControlInterface.setDataInput(xsDataInputInterface)

        #self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(
            self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()
コード例 #2
0
 def process(self, _edObject=None):
     EDPluginControl.process(self)
     self.DEBUG("EDPluginControlMXCuBEWrapperv1_3.process")
     # Check that if image path contains RAW_DATA the current working directory should be PROCESSED_DATA
     strTimeString = time.strftime(
         "%Y%m%d-%H%M%S", time.localtime(
             time.time())) + "-%06d" % random.randint(0, 1000000)
     strWorkingDir = self.getWorkingDirectory()
     strProcessedDataDir = strWorkingDir
     strFirstImagePath = None
     for dataSet in self.dataInput.dataSet:
         for imageFile in dataSet.imageFile:
             strFirstImagePath = imageFile.path.value
             break
     if strFirstImagePath.find("RAW_DATA") != -1:
         strCurrentWorkingDirectory = os.getcwd()
         strCurrentProcessedDataDir = os.path.dirname(
             strCurrentWorkingDirectory)
         strProcessedDataDir = os.path.dirname(
             string.replace(strFirstImagePath, "RAW_DATA",
                            "PROCESSED_DATA"))
         if strCurrentProcessedDataDir != strProcessedDataDir:
             strEDAppliDir = "EDApplication_" + strTimeString
             strNewLogFileName = os.path.join(strProcessedDataDir,
                                              strEDAppliDir + ".log")
             strWorkingDir = os.path.join(strProcessedDataDir,
                                          strEDAppliDir, self.getBaseName())
             if not os.path.exists(strWorkingDir):
                 os.makedirs(strWorkingDir, 0o755)
     # Write out input XML file
     strPathToInputFile = os.path.join(strProcessedDataDir,
                                       "EDNA_Input_%s.xml" % strTimeString)
     strPathToOutputFile = os.path.join(
         strProcessedDataDir, "EDNA_Output_%s.xml" % strTimeString)
     EDUtilsFile.writeFile(strPathToInputFile,
                           self.getDataInput().marshal())
     strScript = "export EDNA_SITE=%s\n" % EDUtilsPath.getEdnaSite()
     strScript += "/opt/pxsoft/bin/edna-plugin-launcher"
     strScript += " --execute %s" % self.strMXCuBEPlugin
     strScript += " --inputFile %s" % strPathToInputFile
     strScript += " --outputFile %s" % strPathToOutputFile
     strScript += " --basedir %s" % strProcessedDataDir
     strScript += " 2>&1\n"
     strScriptFileName = "edna_start_%s.sh" % strTimeString
     strScriptPath = os.path.join(strProcessedDataDir, strScriptFileName)
     EDUtilsFile.writeFile(strScriptPath, strScript)
     # TODO: Make the script executable
     os.system("bash %s" % strScriptPath)
     xsDataResultMXCuBE = XSDataResultMXCuBE()
     if os.path.exists(strPathToOutputFile):
         strOutput = EDUtilsFile.readFile(strPathToOutputFile)
         xsDataResultMXCuBE = XSDataResultMXCuBE.parseString(strOutput)
     self.setDataOutput(xsDataResultMXCuBE)
コード例 #3
0
    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        # self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.edPluginISPyBRetrieveDataCollection = self.loadPlugin(self.strPluginISPyBRetrieveDataCollection, \
                                                                   "ISPyBRetrieveDataCollection")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()
コード例 #4
0
ファイル: EDNACharacterise.py プロジェクト: SOLEILPX/mxcube
 def reallyGetEDNAResults(edna_process_id=edna_process_id, edna_results_file=edna_results_file, storage_dict={"i":0}):
     storage_dict["i"]+=1
     if storage_dict["i"]>=3:
       logging.getLogger().error("Timeout: cannot open EDNA results file (%s)", edna_results_file)
       self.EDNAWaitResultsTimers[edna_process_id].stop()
       del self.EDNAWaitResultsTimers[edna_process_id]
       del self.imagePathProperties[edna_process_id]
     else:
       results = XSDataResultMXCuBE.parseFile(edna_results_file)
       self.EDNAWaitResultsTimers[edna_process_id].stop()
       del self.EDNAWaitResultsTimers[edna_process_id]
       imagePrefix = self.imagePathProperties[edna_process_id]["imagePrefix"]
       imageDir = self.imagePathProperties[edna_process_id]["imageDir"]
       lRunN = self.imagePathProperties[edna_process_id]["lRunN"] 
       del self.imagePathProperties[edna_process_id]
       try:
           html_path = results.htmlPage.path.value
           self.emit('newEDNAHTML', (html_path, imagePrefix, lRunN))
       except:
           logging.getLogger().exception('EDNACharacterize: no html in results')
          
       try:
           screening_id = results.getScreeningId().getValue()
       except:
           screening_id = None 
       self.readEDNAResults(results.getCharacterisationResult(), edna_results_file, imageDir,
                            imagePrefix, lRunN, screeningId = screening_id)
コード例 #5
0
ファイル: EDNAParameters.py プロジェクト: IvarsKarpics/mxcube
 def workflow_state_changed(self, new_state):
     logging.debug("%s: new workflow state is %r", self.name(), new_state)
     if isinstance(new_state, types.ListType) or isinstance(
         new_state, types.TupleType
     ):
         new_state = str(new_state[0])
     if new_state == "ON" and self.previous_workflow_state == "RUNNING":
         # workflow finished, open the output file and use an EDNACaracterize method to
         # continue the work
         if self.workflow_output_file is not None and os.path.exists(
             self.workflow_output_file
         ):
             logging.debug("Workflow finished, sending the results to %r", self.edna)
             logging.debug("Workflow file is %s", self.workflow_output_file)
             try:
                 data = XSDataResultMXCuBE.parseFile(self.workflow_output_file)
                 self.edna.readEDNAResults(
                     data.getCharacterisationResult(),
                     self.workflow_output_file,
                     self.beamline_params["directory"],
                     self.beamline_params["prefix"],
                     int(self.beamline_params["run_number"]),
                     process_dir=self.process_dir,
                     do_inducedraddam=False,
                 )
                 logging.debug("Results sent")
             except BaseException:
                 logging.debug("Malformed or empty results file")
         else:
             logging.debug("Workflow finished, no result file")
         # then remove the current widget with the parameters
         if self.params_widget is not None:
             self.layout().removeChild(self.params_widget)
     self.previous_workflow_state = new_state
コード例 #6
0
    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        xsDataInputMXCuBE = self.getDataInput()
        xsDataInputInterface = XSDataInputInterface()
        self.edPluginControlInterface = self.loadPlugin(self.strPluginControlInterface)
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                xsDataInputInterface.addImagePath(xsDataFile)

        xsDataInputInterface.setExperimentalCondition(xsDataInputMXCuBE.getExperimentalCondition())
        xsDataInputInterface.setDiffractionPlan(xsDataInputMXCuBE.getDiffractionPlan())
        xsDataInputInterface.setSample(xsDataInputMXCuBE.getSample())
        xsDataInputInterface.setDataCollectionId(xsDataInputMXCuBE.getDataCollectionId())
        self.edPluginControlInterface.setDataInput(xsDataInputInterface)

        #self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()
    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        xsDataInputMXCuBE = self.getDataInput()

        self.edPluginControlInterface = self.loadPlugin(self.strPluginControlInterface)
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                strPath = xsDataFile.getPath().getValue()
                self.edPluginControlInterface.setDataInput(XSDataString(strPath), "imagePaths")

        if xsDataInputMXCuBE.getExperimentalCondition() != None:
            self.edPluginControlInterface.setDataInput(str(xsDataInputMXCuBE.getExperimentalCondition().marshal()), "experimentalCondition")
        if xsDataInputMXCuBE.getDiffractionPlan() != None:
            self.edPluginControlInterface.setDataInput(str(xsDataInputMXCuBE.getDiffractionPlan().marshal()), "diffractionPlan")
        if xsDataInputMXCuBE.getSample() != None:
            self.edPluginControlInterface.setDataInput(xsDataInputMXCuBE.getSample().marshal(), "sample")
        if xsDataInputMXCuBE.getDataCollectionId() != None:
            self.edPluginControlInterface.setDataInput(xsDataInputMXCuBE.getDataCollectionId().marshal(), "dataCollectionId")

        self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()
コード例 #8
0
ファイル: EDNAParameters.py プロジェクト: douglasbeniz/mxcube
 def workflow_state_changed(self, new_state):
     logging.debug('%s: new workflow state is %r', self.name(), new_state)
     if type(new_state) == list or type(new_state) == tuple:
         new_state = str(new_state[0])
     if new_state == "ON" and self.previous_workflow_state == "RUNNING":
         # workflow finished, open the output file and use an EDNACaracterize method to
         # continue the work
         if self.workflow_output_file is not None and os.path.exists(
                 self.workflow_output_file):
             logging.debug('Workflow finished, sending the results to %r',
                           self.edna)
             logging.debug('Workflow file is %s', self.workflow_output_file)
             try:
                 data = XSDataResultMXCuBE.parseFile(
                     self.workflow_output_file)
                 self.edna.readEDNAResults(
                     data.getCharacterisationResult(),
                     self.workflow_output_file,
                     self.beamline_params['directory'],
                     self.beamline_params['prefix'],
                     int(self.beamline_params['run_number']),
                     process_dir=self.process_dir,
                     do_inducedraddam=False)
                 logging.debug('Results sent')
             except:
                 logging.debug('Malformed or empty results file')
         else:
             logging.debug('Workflow finished, no result file')
         # then remove the current widget with the parameters
         if self.params_widget is not None:
             self.layout().removeChild(self.params_widget)
     self.previous_workflow_state = new_state
コード例 #9
0
    def characterise(self, edna_input):
        path = edna_input.process_directory

        # if there is no data collection id, the id will be a random number
        # this is to give a unique number to the EDNA input and result files;
        # something more clever might be done to give a more significant
        # name, if there is no dc id.
        try:
            dc_id = edna_input.getDataCollectionId().getValue()
        except:
            dc_id = id(edna_input)

        if hasattr(edna_input, "process_directory"):
            edna_input_file = os.path.join(path, "EDNAInput_%s.xml" % dc_id)
            edna_input.exportToFile(edna_input_file)
            edna_results_file = os.path.join(path, "EDNAOutput_%s.xml" % dc_id)

            if not os.path.isdir(path):
                os.makedirs(path)
        else:
            raise RuntimeError("No process directory specified in edna_input")

        msg = "Starting EDNA using xml file %r", edna_input_file
        logging.getLogger("queue_exec").info(msg)

        edna_processing_thread = \
          EdnaProcessingThread(self.start_edna_command, edna_input_file,
                               edna_results_file, path)

        self.processing_done_event = edna_processing_thread.start()
        self.processing_done_event.wait()
        self.result = XSDataResultMXCuBE.parseFile(edna_results_file)

        return self.result
コード例 #10
0
    def get_result(self):

        jobstatus = self.job.status

        # outname = self.input_file.replace("Input", "Output")
        # outfile = os.path.join( self.edna_directory, outname)

        logging.getLogger("HWR").debug("Job / state is COMPLETED")
        logging.getLogger("HWR").debug("  job status dump: %s" % jobstatus)
        logging.getLogger("HWR").debug("  looking for file: %s" % self.results_file)

        if os.path.exists(self.results_file):
            # job_output = open(outfile).read()
            # logging.getLogger("HWR").debug("     EDNA results file found. loading it")
            # open(self.results_file, "w").write(job_output)
            logging.getLogger("HWR").debug("     EDNA results file found 2")
            result = XSDataResultMXCuBE.parseFile(self.results_file)
            logging.getLogger("HWR").debug("     EDNA results file found 3")
            logging.getLogger("HWR").debug(
                "EDNA Result loaded from file / result is=%s" % str(type(result))
            )
        else:
            logging.getLogger("HWR").debug(
                "EDNA Job finished without success / cannot find output file "
            )
            result = ""

        return result
コード例 #11
0
 def workflow_state_changed(self, new_state):
     logging.debug("%s: new workflow state is %r", self.name(), new_state)
     if isinstance(new_state, types.ListType) or isinstance(
             new_state, types.TupleType):
         new_state = str(new_state[0])
     if new_state == "ON" and self.previous_workflow_state == "RUNNING":
         # workflow finished, open the output file and use an EDNACaracterize method to
         # continue the work
         if self.workflow_output_file is not None and os.path.exists(
                 self.workflow_output_file):
             logging.debug("Workflow finished, sending the results to %r",
                           self.edna)
             logging.debug("Workflow file is %s", self.workflow_output_file)
             try:
                 data = XSDataResultMXCuBE.parseFile(
                     self.workflow_output_file)
                 self.edna.readEDNAResults(
                     data.getCharacterisationResult(),
                     self.workflow_output_file,
                     self.beamline_params["directory"],
                     self.beamline_params["prefix"],
                     int(self.beamline_params["run_number"]),
                     process_dir=self.process_dir,
                     do_inducedraddam=False,
                 )
                 logging.debug("Results sent")
             except BaseException:
                 logging.debug("Malformed or empty results file")
         else:
             logging.debug("Workflow finished, no result file")
         # then remove the current widget with the parameters
         if self.params_widget is not None:
             self.layout().removeChild(self.params_widget)
     self.previous_workflow_state = new_state
コード例 #12
0
ファイル: DataAnalysis.py プロジェクト: alexgobbo/mxcube
    def characterise(self, edna_input):
        process_directory_path = edna_input.process_directory
        
        # if there is no data collection id, the id will be a random number
        # this is to give a unique number to the EDNA input and result files;
        # something more clever might be done to give a more significant
        # name, if there is no dc id.
        try:
            dc_id = edna_input.getDataCollectionId().getValue()
        except:
            dc_id = id(edna_input)
        
        if hasattr(edna_input, "process_directory"):
            edna_input_file = os.path.join(process_directory_path,"EDNAInput_%s.xml" % dc_id)
            edna_input.exportToFile(edna_input_file)
            edna_results_file = os.path.join(process_directory_path, "EDNAOutput_%s.xml" % dc_id)

            if not os.path.isdir(process_directory_path):
                os.makedirs(path)
        else:
            raise RuntimeError, "No process directory specified in edna_input"

        logging.getLogger("queue_exec").info("Starting EDNA using xml file %r", edna_input_file)

        edna_processing_thread = EdnaProcessingThread(self.start_edna_command, \
                                                      edna_input_file, \
                                                      edna_results_file,\
                                                      process_directory_path)
        self.processing_done_event = edna_processing_thread.start()
        self.processing_done_event.wait()
        
        self.result = XSDataResultMXCuBE.parseFile(edna_results_file)
        
        return self.result
コード例 #13
0
    def get_result(self):

        jobstatus = self.job.status

        # outname = self.input_file.replace("Input", "Output")
        # outfile = os.path.join( self.edna_directory, outname)

        logging.getLogger("HWR").debug("Job / state is COMPLETED")
        logging.getLogger("HWR").debug("  job status dump: %s" % jobstatus)
        logging.getLogger("HWR").debug("  looking for file: %s" %
                                       self.results_file)

        if os.path.exists(self.results_file):
            # job_output = open(outfile).read()
            # logging.getLogger("HWR").debug("     EDNA results file found. loading it")
            # open(self.results_file, "w").write(job_output)
            logging.getLogger("HWR").debug("     EDNA results file found 2")
            result = XSDataResultMXCuBE.parseFile(self.results_file)
            logging.getLogger("HWR").debug("     EDNA results file found 3")
            logging.getLogger("HWR").debug(
                "EDNA Result loaded from file / result is=%s" %
                str(type(result)))
        else:
            logging.getLogger("HWR").debug(
                "EDNA Job finished without success / cannot find output file ")
            result = ""

        return result
コード例 #14
0
ファイル: EDNAParameters.py プロジェクト: SOLEILPX/mxcube
 def workflow_state_changed(self, new_state):
     logging.debug('%s: new workflow state is %r', self.name(), new_state)
     if type(new_state) == types.ListType or type(new_state) == types.TupleType:
         new_state = str(new_state[0])
     try:
         actor = self.workflow.current_actor.getValue()
         self.refresh_workflow_state(new_state, actor)
     except:
         self.info_label.setText('Lost connection with workflow engine')
     if new_state == "ON" and self.previous_workflow_state == "RUNNING":
         # workflow finished, open the output file and use an EDNACaracterize method to
         # continue the work
         if self.workflow_output_file is not None and os.path.exists(self.workflow_output_file):
             logging.debug('Workflow finished, sending the results to %r', self.edna)
             logging.debug('Workflow file is %s', self.workflow_output_file)
             try:
                 data = XSDataResultMXCuBE.parseFile(self.workflow_output_file)
                 self.edna.readEDNAResults(data.getCharacterisationResult(), self.workflow_output_file,
                                           self.beamline_params['directory'], self.beamline_params['prefix'],
                                           int(self.beamline_params['run_number']),
                                           process_dir=self.process_dir, do_inducedraddam=False)
                 logging.debug('Results sent')
             except:
                 logging.debug('Malformed or empty results file')
         else:
             logging.debug('Workflow finished, no result file')
         # then remove the current widget with the parameters
         if self.params_widget is not None:
             self.layout().removeChild(self.params_widget)
     self.previous_workflow_state = new_state
コード例 #15
0
    def characterise(self, edna_input):

        # if there is no data collection id, the id will be a random number
        # this is to give a unique number to the EDNA input and result files;
        # something more clever might be done to give a more significant
        # name, if there is no dc id.
        try:
            dc_id = edna_input.getDataCollectionId().getValue()
        except:
            dc_id = id(edna_input)

        for dataSet in edna_input.dataSet:
            for imageFile in dataSet.imageFile:
                firstImage = imageFile.path.value
                break

        self.edna_processing_thread = None
        listImageName = os.path.basename(firstImage).split("_")
        prefix = "_".join(listImageName[:-2])
        run_number = listImageName[-2]
        i = 1

        if hasattr(edna_input, "process_directory"):
            edna_directory = os.path.join(
                edna_input.process_directory,
                "characterisation_%s_run%s_%d" % (prefix, run_number, i))
            while os.path.exists(edna_directory):
                i += 1
                edna_directory = os.path.join(
                    edna_input.process_directory,
                    "characterisation_%s_run%s_%d" % (prefix, run_number, i))
            os.makedirs(edna_directory)
        else:
            raise RuntimeError("No process directory specified in edna_input")

        edna_input_file = os.path.join(edna_directory,
                                       "EDNAInput_%s.xml" % dc_id)
        edna_input.exportToFile(edna_input_file)
        edna_results_file = os.path.join(edna_directory,
                                         "EDNAOutput_%s.xml" % dc_id)

        msg = "Starting EDNA using xml file %r", edna_input_file
        logging.getLogger("queue_exec").info(msg)

        self.edna_processing_thread = \
          EdnaProcessingThread(self.start_edna_command, edna_input_file,
                               edna_results_file, edna_directory)

        self.processing_done_event = self.edna_processing_thread.start()
        self.processing_done_event.wait()
        self.result = None
        if os.path.exists(edna_results_file):
            self.result = XSDataResultMXCuBE.parseFile(edna_results_file)

        return self.result
コード例 #16
0
    def _run_edna(self, input_file, results_file, process_directory):
        """Starts EDNA"""
        msg = "Starting EDNA characterisation using xml file %s" % input_file
        logging.getLogger("queue_exec").info(msg)

        args = (self.start_edna_command, input_file, results_file, process_directory)
        subprocess.call("%s %s %s %s" % args, shell=True)

        self.result = None
        if os.path.exists(results_file):
            self.result = XSDataResultMXCuBE.parseFile(results_file)

        return self.result
コード例 #17
0
    def run_edna(self, input_file, results_file, process_directory):

        msg = "Starting EDNA characterisation using xml file %s" % input_file
        logging.getLogger("queue_exec").info(msg)

        args = (self.start_edna_command, input_file, results_file, process_directory)
        subprocess.call("%s %s %s %s" % args, shell=True)

        self.result = None
        if os.path.exists(results_file):
            self.result = XSDataResultMXCuBE.parseFile(results_file)

        return self.result
コード例 #18
0
    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        # self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.edPluginISPyBRetrieveDataCollection = self.loadPlugin(self.strPluginISPyBRetrieveDataCollection, \
                                                                   "ISPyBRetrieveDataCollection")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()
コード例 #19
0
    def characterise(self, edna_input):

        # if there is no data collection id, the id will be a random number
        # this is to give a unique number to the EDNA input and result files;
        # something more clever might be done to give a more significant
        # name, if there is no dc id.
        try:
            dc_id = edna_input.getDataCollectionId().getValue()
        except:
            dc_id = id(edna_input)

        for dataSet in edna_input.dataSet:
            for imageFile in dataSet.imageFile:
                firstImage = imageFile.path.value
                break

        self.edna_processing_thread = None
        listImageName = os.path.basename(firstImage).split("_")
        prefix = "_".join(listImageName[:-2])
        run_number = listImageName[-2]
        i = 1

        if hasattr(edna_input, "process_directory"):
            edna_directory = os.path.join(edna_input.process_directory, "characterisation_%s_run%s_%d" % (prefix, run_number, i))
            while os.path.exists(edna_directory):
                i += 1
                edna_directory = os.path.join(edna_input.process_directory, "characterisation_%s_run%s_%d" % (prefix, run_number, i))
            os.makedirs(edna_directory)
        else:
            raise RuntimeError("No process directory specified in edna_input")

        edna_input_file = os.path.join(edna_directory, "EDNAInput_%s.xml" % dc_id)
        edna_input.exportToFile(edna_input_file)
        edna_results_file = os.path.join(edna_directory, "EDNAOutput_%s.xml" % dc_id)

        msg = "Starting EDNA using xml file %r", edna_input_file
        logging.getLogger("queue_exec").info(msg)

        self.edna_processing_thread = \
          EdnaProcessingThread(self.start_edna_command, edna_input_file,
                               edna_results_file, edna_directory)

        self.processing_done_event = self.edna_processing_thread.start()
        self.processing_done_event.wait()
        self.result = None
        if os.path.exists(edna_results_file):
            self.result = XSDataResultMXCuBE.parseFile(edna_results_file)
    
        return self.result
コード例 #20
0
 def process(self, _edObject=None):
     EDPluginControl.process(self)
     self.DEBUG("EDPluginControlMXCuBEWrapperv1_3.process")
     # Check that if image path contains RAW_DATA the current working directory should be PROCESSED_DATA
     strTimeString = time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time())) + "-%06d" % random.randint(
         0, 1000000
     )
     strWorkingDir = self.getWorkingDirectory()
     strProcessedDataDir = strWorkingDir
     strFirstImagePath = None
     for dataSet in self.dataInput.dataSet:
         for imageFile in dataSet.imageFile:
             strFirstImagePath = imageFile.path.value
             break
     if strFirstImagePath.find("RAW_DATA") != -1:
         strCurrentWorkingDirectory = os.getcwd()
         strCurrentProcessedDataDir = os.path.dirname(strCurrentWorkingDirectory)
         strProcessedDataDir = os.path.dirname(string.replace(strFirstImagePath, "RAW_DATA", "PROCESSED_DATA"))
         if strCurrentProcessedDataDir != strProcessedDataDir:
             strEDAppliDir = "EDApplication_" + strTimeString
             strNewLogFileName = os.path.join(strProcessedDataDir, strEDAppliDir + ".log")
             strWorkingDir = os.path.join(strProcessedDataDir, strEDAppliDir, self.getBaseName())
             if not os.path.exists(strWorkingDir):
                 os.makedirs(strWorkingDir, 0755)
     # Write out input XML file
     strPathToInputFile = os.path.join(strProcessedDataDir, "EDNA_Input_%s.xml" % strTimeString)
     strPathToOutputFile = os.path.join(strProcessedDataDir, "EDNA_Output_%s.xml" % strTimeString)
     EDUtilsFile.writeFile(strPathToInputFile, self.getDataInput().marshal())
     strScript = "export EDNA_SITE=%s\n" % EDUtilsPath.getEdnaSite()
     strScript += "/opt/pxsoft/bin/edna-plugin-launcher"
     strScript += " --execute %s" % self.strMXCuBEPlugin
     strScript += " --inputFile %s" % strPathToInputFile
     strScript += " --outputFile %s" % strPathToOutputFile
     strScript += " --basedir %s" % strProcessedDataDir
     strScript += " 2>&1\n"
     strScriptFileName = "edna_start_%s.sh" % strTimeString
     strScriptPath = os.path.join(strProcessedDataDir, strScriptFileName)
     EDUtilsFile.writeFile(strScriptPath, strScript)
     # TODO: Make the script executable
     os.system("bash %s" % strScriptPath)
     xsDataResultMXCuBE = XSDataResultMXCuBE()
     if os.path.exists(strPathToOutputFile):
         strOutput = EDUtilsFile.readFile(strPathToOutputFile)
         xsDataResultMXCuBE = XSDataResultMXCuBE.parseString(strOutput)
     self.setDataOutput(xsDataResultMXCuBE)
コード例 #21
0
    def get_result(self, state):
        if state == "COMPLETED": 
            outfile = os.path.join( self.edna_directory, "ControlInterfaceToMXCuBEv1_3_dataOutput.xml")

            logging.getLogger("HWR").debug("Job / state is COMPLETED")
            logging.getLogger("HWR").debug("  looking for file: %s" % outfile)
            if os.path.exists(outfile):
                job_output = open(outfile).read()
                open(self.results_file, "w").write(job_output)
                result = XSDataResultMXCuBE.parseFile(self.results_file)
            else:
                logging.getLogger("HWR").debug("EDNA Job finished without success / cannot find output file ") 
                result = ""
        else:
            logging.getLogger("HWR").debug("EDNA Job finished without success / state was %s" % (job.state))
            result = ""
        
        return result
コード例 #22
0
    def get_result(self, state):
        if state == "COMPLETED":
            outfile = os.path.join(
                self.edna_directory, "ControlInterfaceToMXCuBEv1_3_dataOutput.xml"
            )

            logging.getLogger("HWR").debug("Job / state is COMPLETED")
            logging.getLogger("HWR").debug("  looking for file: %s" % outfile)
            if os.path.exists(outfile):
                job_output = open(outfile).read()
                open(self.results_file, "w").write(job_output)
                result = XSDataResultMXCuBE.parseFile(self.results_file)
            else:
                logging.getLogger("HWR").debug(
                    "EDNA Job finished without success / cannot find output file "
                )
                result = ""
        else:
            logging.getLogger("HWR").debug(
                "EDNA Job finished without success / state was %s" % (job.state)
            )
            result = ""

        return result
class EDPluginControlInterfaceToMXCuBEv1_3(EDPluginControl):
    """
    This is the plugin interface to launch the MXv1 characterisation from an MXCuBE gui.
    It is for the moment a wrapper for the EDPluginControlCCP4iv1_1 plugin, which also
    runs the ISPyB control plugin if a data collection id is available.
    """

    EDNA_CONTACT_EMAIL = "contactEmail"
    EDNA_EMAIL_SENDER = "emailSender"


    def __init__ (self):
        """
        Initialisation of EDPluginControlInterfaceToMXCuBEv1_3:
        - Input data type class : XSDataInputMXCuBE
        - Name of default characterisation plugin : EDPluginControlCharacterisationv1_1
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputMXCuBE)
        self.strPluginControlInterface = "EDPluginControlInterfacev1_2"
        self.edPluginControlInterface = None
        self.strPluginControlISPyB = "EDPluginControlISPyBv1_1"
        self.edPluginControlISPyB = None
        self.xsDataResultMXCuBE = None
        self.xsDataIntegerDataCollectionId = None
        self.strPluginExecOutputHTMLName = "EDPluginExecOutputHTMLv1_0"
        self.edPluginExecOutputHTML = None
        self.strPluginExecSimpleHTMLName = "EDPluginExecSimpleHTMLPagev1_0"
        self.edPluginExecSimpleHTML = None
        self.strEDNAContactEmail = None
        self.strEDNAEmailSender = "*****@*****.**"
        self.tStart = None
        self.tStop = None


    def checkParameters(self):
        """
        Checks the mandatory input parameters :
        - dataSet
        - outputFileDirectory
        """
        self.verboseDebug("EDPluginControlInterfaceToMXCuBEv1_3.checkParameters")
        self.checkMandatoryParameters(self.getDataInput(), "Data Input is None")
        self.checkMandatoryParameters(self.getDataInput().getDataSet(), "dataSet")


    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.configure")
        xsPluginItem = self.getConfiguration()
        if xsPluginItem == None:
            self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.configure: No plugin item defined.")
        else:
            self.strEDNAContactEmail = EDConfiguration.getStringParamValue(xsPluginItem, EDPluginControlInterfaceToMXCuBEv1_3.EDNA_CONTACT_EMAIL)
            self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.configure: EDNAContactEmail = %s" % self.strEDNAContactEmail)
            strEDNAEmailSender = EDConfiguration.getStringParamValue(xsPluginItem, self.EDNA_EMAIL_SENDER)
            if strEDNAEmailSender:
                self.strEDNAEmailSender = strEDNAEmailSender



    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        xsDataInputMXCuBE = self.getDataInput()

        self.edPluginControlInterface = self.loadPlugin(self.strPluginControlInterface)
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                strPath = xsDataFile.getPath().getValue()
                self.edPluginControlInterface.setDataInput(XSDataString(strPath), "imagePaths")

        if xsDataInputMXCuBE.getExperimentalCondition() != None:
            self.edPluginControlInterface.setDataInput(str(xsDataInputMXCuBE.getExperimentalCondition().marshal()), "experimentalCondition")
        if xsDataInputMXCuBE.getDiffractionPlan() != None:
            self.edPluginControlInterface.setDataInput(str(xsDataInputMXCuBE.getDiffractionPlan().marshal()), "diffractionPlan")
        if xsDataInputMXCuBE.getSample() != None:
            self.edPluginControlInterface.setDataInput(xsDataInputMXCuBE.getSample().marshal(), "sample")
        if xsDataInputMXCuBE.getDataCollectionId() != None:
            self.edPluginControlInterface.setDataInput(xsDataInputMXCuBE.getDataCollectionId().marshal(), "dataCollectionId")

        self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()


    def process(self, _edPlugin=None):
        EDPluginControl.process(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.process...")

        if self.edPluginControlInterface is not None:
            self.connectProcess(self.edPluginControlInterface.executeSynchronous)
            self.edPluginControlInterface.connectSUCCESS(self.doSuccessActionInterface)
            self.edPluginControlInterface.connectFAILURE(self.doFailureActionInterface)


    def finallyProcess(self, _edPlugin=None):
        EDPluginControl.finallyProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.postProcess...")
        self.setDataOutput(self.xsDataResultMXCuBE)


    def doSuccessActionInterface(self, _edPlugin=None):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface...")
        self.retrieveSuccessMessages(self.edPluginControlInterface, "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface")
        if self.edPluginControlInterface.hasDataOutput("characterisation"):
            xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput("characterisation")[0]
            self.xsDataResultMXCuBE.setCharacterisationResult(xsDataResultCharacterisation)
            strPathCharacterisationResult = os.path.join(self.getWorkingDirectory(), "CharacterisationResult.xml")
            xsDataResultCharacterisation.outputFile(strPathCharacterisationResult)
            self.xsDataResultMXCuBE.setListOfOutputFiles(XSDataString(strPathCharacterisationResult))
            # For the moment, create "DNA" style output directory
            strPathToDNAFileDirectory = self.createDNAFileDirectoryPath(xsDataResultCharacterisation)
            xsDataDictionaryLogFile = None
            if (self.createDNAFileDirectory(strPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(xsDataResultCharacterisation, strPathToDNAFileDirectory)
            strPyArchPathToDNAFileDirectory = self.createPyArchDNAFilePath(strPathToDNAFileDirectory)
            if (self.createDNAFileDirectory(strPyArchPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(xsDataResultCharacterisation, strPyArchPathToDNAFileDirectory)
            self.xsDataResultMXCuBE.setOutputFileDictionary(xsDataDictionaryLogFile)
            # Send success email message (MXSUP-183):
            self.tStop = time.time()
            strSubject = "%s : SUCCESS! (%.1f s)" % (EDUtilsPath.getEdnaSite(), self.tStop-self.tStart)
            strMessage = "Characterisation success!"
            if xsDataResultCharacterisation.getStatusMessage():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getStatusMessage().getValue()
            if xsDataResultCharacterisation.getShortSummary():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getShortSummary().getValue()
            self.sendEmail(strSubject, strMessage)
            # Fix for bug EDNA-55 : If burning strategy EDNA2html shouldn't be run
            bRunExecOutputHTML = True
            xsDataInputMXCuBE = self.getDataInput()
            xsDataDiffractionPlan = xsDataInputMXCuBE.getDiffractionPlan()
            if xsDataDiffractionPlan.getStrategyOption() is not None:
                strStrategyOption = xsDataDiffractionPlan.getStrategyOption().getValue()
                if strStrategyOption.find("-DamPar") != -1:
                    bRunExecOutputHTML = False
            if (self.edPluginExecOutputHTML is not None) and bRunExecOutputHTML:
                self.edPluginExecOutputHTML.executeSynchronous()
                if not self.edPluginExecOutputHTML.isFailure() and self.edPluginExecOutputHTML.hasDataOutput("htmlFile"):
                    strPathToHTMLFile = self.edPluginExecOutputHTML.getDataOutput("htmlFile")[0].getPath().getValue()
                    strPathToHTMLDir = self.edPluginExecOutputHTML.getDataOutput("htmlDir")[0].getPath().getValue()
                    strPathToDNAIndexDirectory = os.path.join(strPathToDNAFileDirectory, "index")
                    if os.path.exists(strPathToHTMLFile):
                        try:
                            os.mkdir(strPathToDNAIndexDirectory)
                            shutil.copy(strPathToHTMLFile, os.path.join(strPathToDNAIndexDirectory, "index.html"))
                            shutil.copytree(strPathToHTMLDir, os.path.join(strPathToDNAIndexDirectory, os.path.basename(strPathToHTMLDir)))
                            if strPyArchPathToDNAFileDirectory is not None:
                                strPathToPyArchIndexDirectory = os.path.join(strPyArchPathToDNAFileDirectory, "index")
                                os.mkdir(strPathToPyArchIndexDirectory)
                                shutil.copy(strPathToHTMLFile, os.path.join(strPathToPyArchIndexDirectory, "index.html"))
                                shutil.copytree(strPathToHTMLDir, os.path.join(strPathToPyArchIndexDirectory, os.path.basename(strPathToHTMLDir)))
                        except Exception, e:
                            self.DEBUG("Exception caught: %r" % e)
            # Fix for bug MXSUP-251: Put the BEST .par file in the EDNA characterisation root directory
            xsDataIntegrationResult = xsDataResultCharacterisation.getIntegrationResult()
            if xsDataIntegrationResult:
                listXSDataIntegrationSubWedgeResult = xsDataIntegrationResult.getIntegrationSubWedgeResult()
                if listXSDataIntegrationSubWedgeResult:
                    if listXSDataIntegrationSubWedgeResult != []:
                        strBestfilePar = listXSDataIntegrationSubWedgeResult[0].getBestfilePar().getValue()
                        # Put the file one directory above the mxCuBE v1.3 plugin working directory:
                        strDir = os.path.dirname(self.getWorkingDirectory())
                        strPath = os.path.join(strDir, "bestfile.par")
                        EDUtilsFile.writeFile(strPath, strBestfilePar)
            # Execute plugin which creates a simple HTML page
            self.executeSimpleHTML(xsDataResultCharacterisation)    
コード例 #24
0
class EDPluginControlInterfaceToMXCuBEv1_3(EDPluginControl):
    """
    This is the plugin interface to launch the MXv1 characterisation from an MXCuBE gui.
    It is for the moment a wrapper for the EDPluginControlCCP4iv1_1 plugin, which also
    runs the ISPyB control plugin if a data collection id is available.
    """

    EDNA_CONTACT_EMAIL = "contactEmail"
    EDNA_EMAIL_SENDER = "emailSender"


    def __init__ (self):
        """
        Initialisation of EDPluginControlInterfaceToMXCuBEv1_3:
        - Input data type class : XSDataInputMXCuBE
        - Name of default characterisation plugin : EDPluginControlCharacterisationv1_1
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputMXCuBE)
        self.strPluginControlInterface = "EDPluginControlInterfacev1_2"
        self.edPluginControlInterface = None
        self.strPluginControlISPyB = "EDPluginControlISPyBv1_4"
        self.edPluginControlISPyB = None
        self.xsDataResultMXCuBE = None
        self.xsDataIntegerDataCollectionId = None
        self.strPluginExecOutputHTMLName = "EDPluginExecOutputHTMLv1_0"
        self.edPluginExecOutputHTML = None
        self.strPluginExecSimpleHTMLName = "EDPluginExecSimpleHTMLPagev1_0"
        self.edPluginExecSimpleHTML = None
        self.strPluginISPyBRetrieveDataCollection = "EDPluginISPyBRetrieveDataCollectionv1_4"
        self.edPluginISPyBRetrieveDataCollection = None
        self.strEDNAContactEmail = None
        self.strEDNAEmailSender = "*****@*****.**"
        self.tStart = None
        self.tStop = None
        self.fFluxThreshold = 1e3


    def checkParameters(self):
        """
        Checks the mandatory input parameters :
        - dataSet
        - outputFileDirectory
        """
        self.verboseDebug("EDPluginControlInterfaceToMXCuBEv1_3.checkParameters")
        self.checkMandatoryParameters(self.getDataInput(), "Data Input is None")
        self.checkMandatoryParameters(self.getDataInput().getDataSet(), "dataSet")


    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.configure")
        self.strEDNAEmailSender = self.config.get(self.EDNA_EMAIL_SENDER, self.strEDNAEmailSender)
        self.strEDNAContactEmail = self.config.get(self.EDNA_CONTACT_EMAIL, self.strEDNAContactEmail)



    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        # self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.edPluginISPyBRetrieveDataCollection = self.loadPlugin(self.strPluginISPyBRetrieveDataCollection, \
                                                                   "ISPyBRetrieveDataCollection")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()



    def process(self, _edPlugin=None):
        EDPluginControl.process(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.process...")

        xsDataInputMXCuBE = self.getDataInput()
        xsDataInputInterface = XSDataInputInterface()
        self.edPluginControlInterface = self.loadPlugin(self.strPluginControlInterface)
        xsDataFirstImage = None
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                xsDataInputInterface.addImagePath(xsDataFile)
                if xsDataFirstImage is None:
                    xsDataFirstImage = xsDataFile
        
        xsDataExperimentalCondition = self.getFluxAndBeamSizeFromISPyB(xsDataFirstImage, \
                                                            xsDataInputMXCuBE.getExperimentalCondition())
        
        xsDataInputInterface.setExperimentalCondition(xsDataExperimentalCondition)
        xsDataInputInterface.setDiffractionPlan(xsDataInputMXCuBE.getDiffractionPlan())
        xsDataInputInterface.setSample(xsDataInputMXCuBE.getSample())
        xsDataInputInterface.setDataCollectionId(xsDataInputMXCuBE.getDataCollectionId())
        self.edPluginControlInterface.setDataInput(xsDataInputInterface)

        if self.edPluginControlInterface is not None:
            self.connectProcess(self.edPluginControlInterface.executeSynchronous)
            self.edPluginControlInterface.connectSUCCESS(self.doSuccessActionInterface)
            self.edPluginControlInterface.connectFAILURE(self.doFailureActionInterface)


    def finallyProcess(self, _edPlugin=None):
        EDPluginControl.finallyProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.postProcess...")
        self.setDataOutput(self.xsDataResultMXCuBE)


    def doSuccessActionInterface(self, _edPlugin=None):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface...")
        self.retrieveSuccessMessages(self.edPluginControlInterface, "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface")
        # Send success email message (MXSUP-183):
        self.tStop = time.time()
        strSubject = "%s : SUCCESS! (%.1f s)" % (EDUtilsPath.getEdnaSite(), self.tStop - self.tStart)
        strMessage = "Characterisation success!"
        self.storeResultsInISPyB(strSubject, strMessage)
        
    def doFailureActionInterface(self, _edPlugin=None):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionInterface...")
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "Characterisation FAILURE!"
        self.storeResultsInISPyB(strSubject, strMessage)
        # self.setFailure()
#        xsDataResultCharacterisation = None
#        if self.edPluginControlInterface.hasDataOutput("characterisation"):
#            xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput("characterisation")[0]
#        # Execute plugin which creates a simple HTML page
#        self.executeSimpleHTML(xsDataResultCharacterisation)            
#        xsDataResultCharacterisation = self.edPluginControlInterface.dataOutput.resultCharacterisation
#        if xsDataResultCharacterisation is not None:
#            self.xsDataResultMXCuBE.characterisationResult = xsDataResultCharacterisation
#            if xsDataResultCharacterisation.getStatusMessage():
#                strMessage += "\n\n"
#                strMessage += xsDataResultCharacterisation.getStatusMessage().getValue()
#            if xsDataResultCharacterisation.getShortSummary():
#                strMessage += "\n\n"
#                strMessage += xsDataResultCharacterisation.getShortSummary().getValue()
#        self.sendEmail(strSubject, strMessage)
        
        
    def storeResultsInISPyB(self, _strSubject, _strMessage):
        strSubject = _strSubject
        strMessage = _strMessage
        xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput().getResultCharacterisation()
        self.xsDataResultMXCuBE.setCharacterisationResult(xsDataResultCharacterisation)
        xsDataResultControlISPyB = self.edPluginControlInterface.getDataOutput().getResultControlISPyB()
        if xsDataResultControlISPyB != None:
            self.xsDataResultMXCuBE.setScreeningId(xsDataResultControlISPyB.getScreeningId())
        if xsDataResultCharacterisation != None:
            self.xsDataResultMXCuBE.characterisationResult = xsDataResultCharacterisation
            strPathCharacterisationResult = os.path.join(self.getWorkingDirectory(), "CharacterisationResult.xml")
            xsDataResultCharacterisation.exportToFile(strPathCharacterisationResult)
            self.xsDataResultMXCuBE.setListOfOutputFiles(XSDataString(strPathCharacterisationResult))
            # For the moment, create "DNA" style output directory
            strPathToDNAFileDirectory = self.createDNAFileDirectoryPath(xsDataResultCharacterisation)
            xsDataDictionaryLogFile = None
            if (self.createDNAFileDirectory(strPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(xsDataResultCharacterisation, strPathToDNAFileDirectory)
            strPyArchPathToDNAFileDirectory = self.createPyArchDNAFilePath(strPathToDNAFileDirectory)
            if (self.createDNAFileDirectory(strPyArchPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(xsDataResultCharacterisation, strPyArchPathToDNAFileDirectory)
            self.xsDataResultMXCuBE.setOutputFileDictionary(xsDataDictionaryLogFile)
            if xsDataResultCharacterisation.getStatusMessage():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getStatusMessage().getValue()
            if xsDataResultCharacterisation.getShortSummary():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getShortSummary().getValue()
            self.sendEmail(strSubject, strMessage)
            # Fix for bug EDNA-55 : If burning strategy EDNA2html shouldn't be run
            bRunExecOutputHTML = False
            xsDataInputMXCuBE = self.getDataInput()
            xsDataDiffractionPlan = xsDataInputMXCuBE.getDiffractionPlan()
            if xsDataDiffractionPlan.getStrategyOption() is not None:
                strStrategyOption = xsDataDiffractionPlan.getStrategyOption().getValue()
                if strStrategyOption.find("-DamPar") != -1:
                    bRunExecOutputHTML = False
            if (self.edPluginExecOutputHTML is not None) and bRunExecOutputHTML:
                self.edPluginExecOutputHTML.setDataInput(XSDataFile(XSDataString(strPathToDNAFileDirectory)), "dnaFileDirectory")
                self.edPluginExecOutputHTML.execute()
            # Fix for bug MXSUP-251: Put the BEST .par file in the EDNA characterisation root directory
            xsDataIntegrationResult = xsDataResultCharacterisation.getIntegrationResult()
            if xsDataIntegrationResult:
                listXSDataIntegrationSubWedgeResult = xsDataIntegrationResult.getIntegrationSubWedgeResult()
                if listXSDataIntegrationSubWedgeResult:
                    if listXSDataIntegrationSubWedgeResult != []:
                        strBestfilePar = listXSDataIntegrationSubWedgeResult[0].getBestfilePar().getValue()
                        # Put the file one directory above the mxCuBE v1.3 plugin working directory:
                        strDir = os.path.dirname(self.getWorkingDirectory())
                        strPath = os.path.join(strDir, "bestfile.par")
                        EDUtilsFile.writeFile(strPath, strBestfilePar)
            # Execute plugin which creates a simple HTML page
            self.executeSimpleHTML(xsDataResultCharacterisation)    
                    





    def doSuccessActionISPyB(self, _edPlugin):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionISPyB...")
        self.retrieveSuccessMessages(self.edPluginControlISPyB, "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionISPyB")


    def doFailureActionISPyB(self, _edPlugin=None):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionISpyB...")
        self.retrieveFailureMessages(self.edPluginControlISPyB, "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionISpyB")
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "ISPyB FAILURE!"
        self.sendEmail(strSubject, strMessage)


    def createDNAFileDirectoryPath(self, _xsDataResultCharacterisation):
        """
        This method creates a "DNA" style directory path, i.e. in the same directory were the 
        images are located a new directory is created with the following convention:
        
          dnafiles_prefix_runNumber
        
        The path to this directory is returned if the directory was successfully created.
        """
        # First extract all reference image directory paths and names
        xsDataCollection = _xsDataResultCharacterisation.getDataCollection()
        listImageDirectoryPath = []
        listImagePrefix = []
        for xsDataSubWedge in xsDataCollection.getSubWedge():
            for xsDataImage in xsDataSubWedge.getImage():
                strImagePath = xsDataImage.getPath().getValue()
                listImageDirectoryPath.append(os.path.dirname(strImagePath))
                listImagePrefix.append(EDUtilsImage.getPrefix(strImagePath))
        # TODO: Check that all paths and prefixes are the same
        strImageDirectory = listImageDirectoryPath[0]
        strPrefix = listImagePrefix[0]
        # Remove any "ref-" or "postref-" from the prefix in order to make it fully
        # compatitble with DNA standards:
        if (strPrefix is not None):
            if (strPrefix.startswith("ref-")):
                strPrefix = strPrefix[4:]
            elif (strPrefix.startswith("postref-")):
                strPrefix = strPrefix[8:]
        strDNAFileDirectoryPath = os.path.join(strImageDirectory, "%s_dnafiles" % strPrefix)
        return strDNAFileDirectoryPath



    def createPyArchDNAFilePath(self, _strDNAFileDirectoryPath):
        """
        This method translates from a "visitor" path to a "pyarch" path:
        /data/visitor/mx415/id14eh1/20100209 -> /data/pyarch/id14eh1/mx415/20100209
        """
        strPyarchDNAFilePath = None
        listOfDirectories = _strDNAFileDirectoryPath.split(os.sep)
        listBeamlines = ["bm14", "id14eh1", "id14eh2", "id14eh3", "id14eh4", "id23eh1", "id23eh2", "id29"]
        # Check that we have at least four levels of directories:
        if (len(listOfDirectories) > 4):
            strDataDirectory = listOfDirectories[ 1 ]
            strSecondDirectory = listOfDirectories[ 2 ]
            strProposal = None
            strBeamline = None
            if ((strDataDirectory == "data") and (strSecondDirectory == "visitor")):
                strProposal = listOfDirectories[ 3 ]
                strBeamline = listOfDirectories[ 4 ]
            elif ((strDataDirectory == "data") and (strSecondDirectory in listBeamlines)):
                strBeamline = strSecondDirectory
                strProposal = listOfDirectories[ 4 ]
            if (strProposal != None) and (strBeamline != None):
                strPyarchDNAFilePath = os.path.join(os.sep, "data")
                strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath, "pyarch")
                strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath, strBeamline)
                strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath, strProposal)
                for strDirectory in listOfDirectories[ 5: ]:
                    strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath, strDirectory)
        if (strPyarchDNAFilePath is None):
            self.WARNING("EDPluginControlInterfaceToMXCuBEv1_3.createPyArchDNAFilePath: path not converted for pyarch: %s " % _strDNAFileDirectoryPath)
        return strPyarchDNAFilePath



    def createDNAFileDirectory(self, _strDNAFileDirectoryPath):
        """
        Create a "DNA-files" directory - if possible.
        """
        bSuccess = False
        if (_strDNAFileDirectoryPath is not None):
            if (os.path.exists(_strDNAFileDirectoryPath)):
                self.warning("Removing existing DNA files directory: %s" % _strDNAFileDirectoryPath)
                if (os.access(_strDNAFileDirectoryPath, os.W_OK)):
                    shutil.rmtree(_strDNAFileDirectoryPath)
                else:
                    self.warning("Cannot remove existing DNA files directory!")
            if (_strDNAFileDirectoryPath is not None):
                # Check if directory one level up is writeable
                strDNAFileBaseDirectory = os.path.split(_strDNAFileDirectoryPath)[0]
                if (os.access(strDNAFileBaseDirectory, os.W_OK)):
                    self.DEBUG("Creating DNA files directory: %s" % _strDNAFileDirectoryPath)
                    os.mkdir(_strDNAFileDirectoryPath)
                    bSuccess = True
                else:
                    self.warning("Cannot create DNA files directory: %s" % _strDNAFileDirectoryPath)
        return bSuccess



    def splitHeadDirectory(self, _strPath):
        """
        This method works like os.path.split except that it splits the head directory
        from the rest of the path. Example:
        "/" -> [ None, None]
        "/data" -> ["data", None]
        "/data/visitor" -> ["data", "visitor"]
        "/data/visitor/mx415/id14eh2/20100212" -> ["data", "visitor/mx415/id14eh2/20100212"]
        """
        listOfDirectories = _strPath.split(os.sep)
        strTail = None
        strHead = None
        if (len(listOfDirectories) > 1):
            strHead = listOfDirectories[1]
            if (strHead == ""):
                strHead = None
            if (len(listOfDirectories) > 1):
                for strEntry in listOfDirectories[2:]:
                    if (strTail is None):
                        strTail = strEntry
                    else:
                        strTail = os.path.join(strTail, strEntry)
        return [ strHead, strTail ]


    def createOutputFileDictionary(self, _xsDataResultCharacterisation, _strPathToLogFileDirectory=None):
        """
        This method creates an XSDataDictionary containing the name and locations of the 
        characterisation output files.
        """
        xsDataDictionaryLogFile = XSDataDictionary()
        # Start with the prediction images
        xsDataIndexingResult = _xsDataResultCharacterisation.getIndexingResult()
        if xsDataIndexingResult is not None:
            xsDataGeneratePredictionResult = xsDataIndexingResult.getPredictionResult()
            if xsDataGeneratePredictionResult is not None:
                listXSDataImagePrediction = xsDataGeneratePredictionResult.getPredictionImage()
                for xsDataImagePrediction in listXSDataImagePrediction:
                    xsDataKeyValuePair = XSDataKeyValuePair()
                    iPredictionImageNumber = xsDataImagePrediction.getNumber().getValue()
                    xsDataStringKey = XSDataString("predictionImage_%d" % iPredictionImageNumber)
                    xsDataStringValue = None
                    strPredictionImagePath = xsDataImagePrediction.getPath().getValue()
                    if (_strPathToLogFileDirectory is not None):
                        strPredictionImageFileName = EDUtilsFile.getBaseName(strPredictionImagePath)
                        strNewPredictionImagePath = os.path.join(_strPathToLogFileDirectory, strPredictionImageFileName)
                        EDUtilsFile.copyFile(strPredictionImagePath, strNewPredictionImagePath)
                        xsDataStringValue = XSDataString(strNewPredictionImagePath)
                    else:
                        xsDataStringValue = XSDataString(strPredictionImageFileName)
                    xsDataKeyValuePair.setKey(xsDataStringKey)
                    xsDataKeyValuePair.setValue(xsDataStringValue)
                    xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)
        # Best log file
        strPathToBESTLogFile = None
        strPathToExecutiveSummary = None
        if _xsDataResultCharacterisation.getStrategyResult() is not None:
            if _xsDataResultCharacterisation.getStrategyResult().getBestLogFile() != None:
                strPathToBESTLogFile = _xsDataResultCharacterisation.getStrategyResult().getBestLogFile().getPath().getValue()
            if strPathToBESTLogFile is not None:
                xsDataStringKey = XSDataString("logFileBest")
                xsDataStringValue = None
                if (_strPathToLogFileDirectory is not None):
                    strNewBestLogPath = os.path.join(_strPathToLogFileDirectory, "best.log")
                    EDUtilsFile.copyFile(strPathToBESTLogFile, strNewBestLogPath)
                    xsDataStringValue = XSDataString(strNewBestLogPath)
                else:
                    xsDataStringValue = XSDataString(strPathToBESTLogFile)
                xsDataKeyValuePair = XSDataKeyValuePair()
                xsDataKeyValuePair.setKey(xsDataStringKey)
                xsDataKeyValuePair.setValue(xsDataStringValue)
                xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)
            if (strPathToExecutiveSummary is not None):
                xsDataStringKey = XSDataString("executiveSummary")
                xsDataStringValue = None
                if (_strPathToLogFileDirectory is not None):
                    strExecutiveSummaryFileName = EDUtilsFile.getBaseName(strPathToExecutiveSummary)
                    strNewExecutiveSummaryPath = os.path.join(_strPathToLogFileDirectory, strExecutiveSummaryFileName)
                    EDUtilsFile.copyFile(strPathToExecutiveSummary, strNewExecutiveSummaryPath)
                    xsDataStringValue = XSDataString(strNewExecutiveSummaryPath)
                    # Copy also the executive summary file to "dna_log.txt"...
                    strNewExecutiveSummaryPath = os.path.join(_strPathToLogFileDirectory, "dna_log.txt")
                    EDUtilsFile.copyFile(strPathToExecutiveSummary, strNewExecutiveSummaryPath)
                else:
                    xsDataStringValue = XSDataString(strPathToExecutiveSummary)
                xsDataKeyValuePair = XSDataKeyValuePair()
                xsDataKeyValuePair.setKey(xsDataStringKey)
                xsDataKeyValuePair.setValue(xsDataStringValue)
                xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)

        return xsDataDictionaryLogFile





    def doFailureActionCharacterisation(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG("EDPluginControlInterfacev1_3.doFailureActionCharacterisation")
        self.setFailure()
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "Characterisation FAILURE!"
        self.sendEmail(strSubject, strMessage)
        

    def getFluxAndBeamSizeFromISPyB(self, _xsDataFirstImage, _xsDataExperimentalCondition):
        """
        This method retrieves the flux and beamsize from ISPyB
        """
        xsDataExperimentalCondition = None
        if (_xsDataExperimentalCondition is not None):
            bFoundValidFlux = False
            xsDataExperimentalCondition = _xsDataExperimentalCondition.copy()
            xsDataInputRetrieveDataCollection = XSDataInputRetrieveDataCollection()
            xsDataInputRetrieveDataCollection.setImage(XSDataImage(_xsDataFirstImage.getPath()))
            self.edPluginISPyBRetrieveDataCollection.setDataInput(xsDataInputRetrieveDataCollection)
            self.edPluginISPyBRetrieveDataCollection.executeSynchronous()
            xsDataResultRetrieveDataCollection = self.edPluginISPyBRetrieveDataCollection.getDataOutput()
            if xsDataResultRetrieveDataCollection is not None:
                xsDataISPyBDataCollection = xsDataResultRetrieveDataCollection.getDataCollection()
                if xsDataISPyBDataCollection is not None:
                    fFlux = xsDataISPyBDataCollection.getFlux()
                    if fFlux is not None:
                        self.screen("ISPyB reports flux to be: %g photons/sec" % fFlux)
                        if fFlux > self.fFluxThreshold:
                            xsDataExperimentalCondition.getBeam().setFlux(XSDataFlux(fFlux))
                            bFoundValidFlux = True
                    fBeamSizeAtSampleX = xsDataISPyBDataCollection.beamSizeAtSampleX
                    fBeamSizeAtSampleY = xsDataISPyBDataCollection.beamSizeAtSampleY
                    if fBeamSizeAtSampleX is not None and fBeamSizeAtSampleY is not None:
                        self.screen("ISPyB reports beamsize X to be: %.3f mm" % fBeamSizeAtSampleX)
                        self.screen("ISPyB reports beamsize Y to be: %.3f mm" % fBeamSizeAtSampleY)
                        xsDataSize = XSDataSize()
                        xsDataSize.x = XSDataLength(fBeamSizeAtSampleX)
                        xsDataSize.y = XSDataLength(fBeamSizeAtSampleY)
                        xsDataExperimentalCondition.getBeam().setSize(xsDataSize)
            if not bFoundValidFlux:
                self.screen("No valid flux could be retrieved from ISPyB! Trying to obtain flux from input data.")
                xsDataBeam = xsDataExperimentalCondition.getBeam()
                xsDataBeamFlux = xsDataBeam.getFlux()
                if xsDataBeamFlux is not None:
                    fFluxMXCuBE = xsDataBeamFlux.getValue()
                    self.screen("MXCuBE reports flux to be: %g photons/sec" % fFluxMXCuBE)
                    if fFluxMXCuBE < self.fFluxThreshold:
                        self.screen("MXCuBE flux invalid!")
        return xsDataExperimentalCondition
                            
                            




    def updateDataInputCharacterisation(self, _xsDataInputCharacterisation):
        """
        This method updates the xsDataInputCharacterisation object given as argument with the following
        parameters (if available) goven as input:
        - Diffraction plan
        - Beam size
        - Beam flux
        - Min exposure time per image
        - Max oscillation speed
        - Min oscillation width
        - Sample information
        """
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.createDataInputCharacterisationFromDataSets")
        xsDataCollection = _xsDataInputCharacterisation.getDataCollection()
        if (_xsDataInputCharacterisation is not None):
            xsDataInputCCP4i = self.getDataInput()
            # Update with diffraction plan
            xsDiffactionPlan = xsDataInputCCP4i.getDiffractionPlan()
            if(xsDiffactionPlan is not None):
                xsDataCollection.setDiffractionPlan(xsDiffactionPlan)
            # Update the data collection subwedges with additional experimental conditions
            for xsDataSubWedge in xsDataCollection.getSubWedge():
                xsDataExperimentalCondition = xsDataInputCCP4i.getExperimentalCondition()
                if(xsDataExperimentalCondition is not None):
                    xsDataBeam = xsDataExperimentalCondition.getBeam()
                    if(xsDataBeam is not None):
                        xsDataBeamSize = xsDataBeam.getSize()
                        if(xsDataBeamSize is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam().setSize(xsDataBeamSize)
                        xsDataBeamFlux = xsDataBeam.getFlux()
                        if(xsDataBeamFlux is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam().setFlux(xsDataBeamFlux)
                        xsDataMinExposureTime = xsDataBeam.getMinExposureTimePerImage()
                        if(xsDataMinExposureTime is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam().setMinExposureTimePerImage(xsDataMinExposureTime)
                    xsDataGoniostat = xsDataExperimentalCondition.getGoniostat()
                    if(xsDataGoniostat is not None):
                        xsDataMaxOscSpeed = xsDataGoniostat.getMaxOscillationSpeed()
                        if(xsDataMaxOscSpeed is not None):
                            xsDataSubWedge.getExperimentalCondition().getGoniostat().setMaxOscillationSpeed(xsDataMaxOscSpeed)
                        xsDataMinOscWidth = xsDataGoniostat.getMinOscillationWidth()
                        if(xsDataMinOscWidth is not None):
                            xsDataSubWedge.getExperimentalCondition().getGoniostat().setMinOscillationWidth(xsDataMinOscWidth)
            # Update with the sample
            xsDataSample = xsDataInputCCP4i.getSample()
            if(xsDataSample is not None):
                xsDataCollection.setSample(xsDataSample)


    def sendEmail(self, _strSubject, _strMessage):
        """Sends an email to the EDNA contact person (if configured)."""

        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Subject = %s" % _strSubject)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Message:")
        self.DEBUG(_strMessage)
        if self.strEDNAContactEmail == None:
            self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: No email address configured!")
        elif not EDUtilsPath.getEdnaSite().startswith("ESRF"):
            self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Not executed at the ESRF! EDNA_SITE=%s" % EDUtilsPath.getEdnaSite())
        else:
            try:
                self.DEBUG("Sending message to %s." % self.strEDNAContactEmail)
                self.DEBUG("Message: %s" % _strMessage)
                strMessage = """
EDNA_HOME = %s
EDNA_SITE = %s
PLUGIN_NAME = %s
working_dir = %s
%s

""" % (EDUtilsPath.getEdnaHome(), EDUtilsPath.getEdnaSite(), self.getPluginName(), self.getWorkingDirectory(), _strMessage)
                strEmailMsg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (self.strEDNAEmailSender, \
                                                                                self.strEDNAContactEmail, \
                                                                                _strSubject, strMessage))
                server = smtplib.SMTP("localhost")
                server.sendmail(self.strEDNAEmailSender, self.strEDNAContactEmail, strEmailMsg)
                server.quit()
            except:
                self.ERROR("Error when sending email message!")
                self.writeErrorTrace()


    def executeSimpleHTML(self, _xsDataResultCharacterisation):
        xsDataInputSimpleHTMLPage = XSDataInputSimpleHTMLPage()
        xsDataInputSimpleHTMLPage.setCharacterisationResult(_xsDataResultCharacterisation)
        self.edPluginExecSimpleHTML.setDataInput(xsDataInputSimpleHTMLPage)
        self.edPluginExecSimpleHTML.connectSUCCESS(self.doSuccessSimpleHTML)
        self.edPluginExecSimpleHTML.connectFAILURE(self.doFailureSimpleHTML)
        self.executePluginSynchronous(self.edPluginExecSimpleHTML)


    def doSuccessSimpleHTML(self, _edPlugin=None):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doSuccessSimpleHTML...")
        self.retrieveSuccessMessages(_edPlugin, "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessSimpleHTML")
        self.xsDataResultMXCuBE.setHtmlPage(_edPlugin.getDataOutput().getPathToHTMLFile())

    def doFailureSimpleHTML(self, _edPlugin=None):
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.doFailureSimpleHTML...")
コード例 #25
0
class EDPluginControlInterfaceToMXCuBEv1_3(EDPluginControl):
    """
    This is the plugin interface to launch the MXv1 characterisation from an MXCuBE gui.
    It is for the moment a wrapper for the EDPluginControlCCP4iv1_1 plugin, which also
    runs the ISPyB control plugin if a data collection id is available.
    """

    EDNA_CONTACT_EMAIL = "contactEmail"
    EDNA_EMAIL_SENDER = "emailSender"

    def __init__(self):
        """
        Initialisation of EDPluginControlInterfaceToMXCuBEv1_3:
        - Input data type class : XSDataInputMXCuBE
        - Name of default characterisation plugin : EDPluginControlCharacterisationv1_1
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputMXCuBE)
        self.strPluginControlInterface = "EDPluginControlInterfacev1_2"
        self.edPluginControlInterface = None
        self.strPluginControlISPyB = "EDPluginControlISPyBv1_4"
        self.edPluginControlISPyB = None
        self.xsDataResultMXCuBE = None
        self.xsDataIntegerDataCollectionId = None
        self.strPluginExecOutputHTMLName = "EDPluginExecOutputHTMLv1_0"
        self.edPluginExecOutputHTML = None
        self.strPluginExecSimpleHTMLName = "EDPluginExecSimpleHTMLPagev1_0"
        self.edPluginExecSimpleHTML = None
        self.strPluginISPyBRetrieveDataCollection = "EDPluginISPyBRetrieveDataCollectionv1_4"
        self.edPluginISPyBRetrieveDataCollection = None
        self.strEDNAContactEmail = None
        self.strEDNAEmailSender = "*****@*****.**"
        self.tStart = None
        self.tStop = None
        self.fFluxThreshold = 1e3

    def checkParameters(self):
        """
        Checks the mandatory input parameters :
        - dataSet
        - outputFileDirectory
        """
        self.verboseDebug(
            "EDPluginControlInterfaceToMXCuBEv1_3.checkParameters")
        self.checkMandatoryParameters(self.getDataInput(),
                                      "Data Input is None")
        self.checkMandatoryParameters(self.getDataInput().getDataSet(),
                                      "dataSet")

    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.configure")
        self.strEDNAEmailSender = self.config.get(self.EDNA_EMAIL_SENDER,
                                                  self.strEDNAEmailSender)
        self.strEDNAContactEmail = self.config.get(self.EDNA_CONTACT_EMAIL,
                                                   self.strEDNAContactEmail)

    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        # self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(
            self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.edPluginISPyBRetrieveDataCollection = self.loadPlugin(self.strPluginISPyBRetrieveDataCollection, \
                                                                   "ISPyBRetrieveDataCollection")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()

    def process(self, _edPlugin=None):
        EDPluginControl.process(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.process...")

        xsDataInputMXCuBE = self.getDataInput()
        xsDataInputInterface = XSDataInputInterface()
        self.edPluginControlInterface = self.loadPlugin(
            self.strPluginControlInterface)
        xsDataFirstImage = None
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                xsDataInputInterface.addImagePath(xsDataFile)
                if xsDataFirstImage is None:
                    xsDataFirstImage = xsDataFile

        xsDataExperimentalCondition = self.getFluxAndBeamSizeFromISPyB(xsDataFirstImage, \
                                                            xsDataInputMXCuBE.getExperimentalCondition())

        xsDataInputInterface.setExperimentalCondition(
            xsDataExperimentalCondition)
        xsDataInputInterface.setDiffractionPlan(
            xsDataInputMXCuBE.getDiffractionPlan())
        xsDataInputInterface.setSample(xsDataInputMXCuBE.getSample())
        xsDataInputInterface.setDataCollectionId(
            xsDataInputMXCuBE.getDataCollectionId())
        self.edPluginControlInterface.setDataInput(xsDataInputInterface)

        if self.edPluginControlInterface is not None:
            self.connectProcess(
                self.edPluginControlInterface.executeSynchronous)
            self.edPluginControlInterface.connectSUCCESS(
                self.doSuccessActionInterface)
            self.edPluginControlInterface.connectFAILURE(
                self.doFailureActionInterface)

    def finallyProcess(self, _edPlugin=None):
        EDPluginControl.finallyProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.postProcess...")
        self.setDataOutput(self.xsDataResultMXCuBE)

    def doSuccessActionInterface(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface...")
        self.retrieveSuccessMessages(
            self.edPluginControlInterface,
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface")
        # Send success email message (MXSUP-183):
        self.tStop = time.time()
        strSubject = "SUCCESS"
        strMessage = "Characterisation success!"
        self.storeResultsInISPyB(strSubject, strMessage)

    def doFailureActionInterface(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionInterface...")
        # Send failure email message (MXSUP-183):
        self.tStop = time.time()
        strSubject = "FAILURE"
        strMessage = "Characterisation FAILURE!"
        self.storeResultsInISPyB(strSubject, strMessage)
        # self.setFailure()
#        xsDataResultCharacterisation = None
#        if self.edPluginControlInterface.hasDataOutput("characterisation"):
#            xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput("characterisation")[0]
#        # Execute plugin which creates a simple HTML page
#        self.executeSimpleHTML(xsDataResultCharacterisation)
#        xsDataResultCharacterisation = self.edPluginControlInterface.dataOutput.resultCharacterisation
#        if xsDataResultCharacterisation is not None:
#            self.xsDataResultMXCuBE.characterisationResult = xsDataResultCharacterisation
#            if xsDataResultCharacterisation.getStatusMessage():
#                strMessage += "\n\n"
#                strMessage += xsDataResultCharacterisation.getStatusMessage().getValue()
#            if xsDataResultCharacterisation.getShortSummary():
#                strMessage += "\n\n"
#                strMessage += xsDataResultCharacterisation.getShortSummary().getValue()
#        self.sendEmail(strSubject, strMessage)

    def storeResultsInISPyB(self, _strSubject, _strMessage):
        strSubject = _strSubject
        strMessage = _strMessage
        xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput(
        ).getResultCharacterisation()
        self.xsDataResultMXCuBE.setCharacterisationResult(
            xsDataResultCharacterisation)
        xsDataResultControlISPyB = self.edPluginControlInterface.getDataOutput(
        ).getResultControlISPyB()
        if xsDataResultControlISPyB != None:
            self.xsDataResultMXCuBE.setScreeningId(
                xsDataResultControlISPyB.getScreeningId())
        if xsDataResultCharacterisation != None:
            self.xsDataResultMXCuBE.characterisationResult = xsDataResultCharacterisation
            strPathCharacterisationResult = os.path.join(
                self.getWorkingDirectory(), "CharacterisationResult.xml")
            xsDataResultCharacterisation.exportToFile(
                strPathCharacterisationResult)
            self.xsDataResultMXCuBE.setListOfOutputFiles(
                XSDataString(strPathCharacterisationResult))
            # For the moment, create "DNA" style output directory
            strPathToDNAFileDirectory = self.createDNAFileDirectoryPath(
                xsDataResultCharacterisation)
            xsDataDictionaryLogFile = None
            if not EDUtilsPath.isALBA:
                if (self.createDNAFileDirectory(strPathToDNAFileDirectory)):
                    xsDataDictionaryLogFile = self.createOutputFileDictionary(
                        xsDataResultCharacterisation,
                        strPathToDNAFileDirectory)
            strPyArchPathToDNAFileDirectory = EDHandlerESRFPyarchv1_0.createPyarchFilePath(
                strPathToDNAFileDirectory)
            if (self.createDNAFileDirectory(strPyArchPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(
                    xsDataResultCharacterisation,
                    strPyArchPathToDNAFileDirectory)
            self.xsDataResultMXCuBE.setOutputFileDictionary(
                xsDataDictionaryLogFile)
            if xsDataResultCharacterisation.getStatusMessage():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getStatusMessage(
                ).getValue()
            if xsDataResultCharacterisation.getShortSummary():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getShortSummary(
                ).getValue()
            self.sendEmail(strSubject, strMessage)
            # Fix for bug EDNA-55 : If burning strategy EDNA2html shouldn't be run
            bRunExecOutputHTML = False
            xsDataInputMXCuBE = self.getDataInput()
            xsDataDiffractionPlan = xsDataInputMXCuBE.getDiffractionPlan()
            if xsDataDiffractionPlan.getStrategyOption() is not None:
                strStrategyOption = xsDataDiffractionPlan.getStrategyOption(
                ).getValue()
                if strStrategyOption.find("-DamPar") != -1:
                    bRunExecOutputHTML = False
            if (self.edPluginExecOutputHTML
                    is not None) and bRunExecOutputHTML:
                self.edPluginExecOutputHTML.setDataInput(
                    XSDataFile(XSDataString(strPathToDNAFileDirectory)),
                    "dnaFileDirectory")
                self.edPluginExecOutputHTML.execute()
            # Fix for bug MXSUP-251: Put the BEST .par file in the EDNA characterisation root directory
            xsDataIntegrationResult = xsDataResultCharacterisation.getIntegrationResult(
            )
            if xsDataIntegrationResult:
                listXSDataIntegrationSubWedgeResult = xsDataIntegrationResult.getIntegrationSubWedgeResult(
                )
                for xsDataIntegrationSubWedgeResult in listXSDataIntegrationSubWedgeResult:
                    if xsDataIntegrationSubWedgeResult.getBestfilePar(
                    ) is not None:
                        strBestfilePar = xsDataIntegrationSubWedgeResult.getBestfilePar(
                        ).getValue()
                        # Put the file one directory above the mxCuBE v1.3 plugin working directory:
                        strDir = os.path.dirname(self.getWorkingDirectory())
                        strPath = os.path.join(strDir, "bestfile.par")
                        EDUtilsFile.writeFile(strPath, strBestfilePar)
                        break
            # Execute plugin which creates a simple HTML page
            self.executeSimpleHTML(xsDataResultCharacterisation)
            # Upload the best wilson plot path to ISPyB
            strBestWilsonPlotPath = EDHandlerXSDataISPyBv1_4.getBestWilsonPlotPath(
                xsDataResultCharacterisation)
            if strBestWilsonPlotPath is not None and strPyArchPathToDNAFileDirectory is not None:
                # Copy wilson path to Pyarch
                strBestWilsonPlotPyarchPath = os.path.join(
                    strPyArchPathToDNAFileDirectory,
                    os.path.basename(strBestWilsonPlotPath))
                if not os.path.exists(strBestWilsonPlotPyarchPath):
                    if not os.path.exists(
                            os.path.dirname(strBestWilsonPlotPyarchPath)):
                        os.makedirs(
                            os.path.dirname(strBestWilsonPlotPyarchPath), 755)
                    shutil.copy(strBestWilsonPlotPath,
                                strBestWilsonPlotPyarchPath)
                self.DEBUG("Best wilson pyarch path: %s " %
                           strBestWilsonPlotPyarchPath)
                if self.edPluginControlInterface.dataOutput.resultControlISPyB is not None:
                    xsDataInputISPyBSetBestWilsonPlotPath = XSDataInputISPyBSetBestWilsonPlotPath(
                    )
                    xsDataInputISPyBSetBestWilsonPlotPath.dataCollectionId = self.edPluginControlInterface.dataOutput.resultControlISPyB.dataCollectionId
                    xsDataInputISPyBSetBestWilsonPlotPath.bestWilsonPlotPath = XSDataString(
                        strBestWilsonPlotPyarchPath)
                    edPluginSetBestWilsonPlotPath = self.loadPlugin(
                        "EDPluginISPyBSetBestWilsonPlotPathv1_4",
                        "ISPyBSetBestWilsonPlotPath")
                    edPluginSetBestWilsonPlotPath.dataInput = xsDataInputISPyBSetBestWilsonPlotPath
                    edPluginSetBestWilsonPlotPath.executeSynchronous()

    def doSuccessActionISPyB(self, _edPlugin):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionISPyB...")
        self.retrieveSuccessMessages(
            self.edPluginControlISPyB,
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionISPyB")

    def doFailureActionISPyB(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionISpyB...")
        self.retrieveFailureMessages(
            self.edPluginControlISPyB,
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionISpyB")
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "ISPyB FAILURE!"
        self.sendEmail(strSubject, strMessage)

    def createDNAFileDirectoryPath(self, _xsDataResultCharacterisation):
        """
        This method creates a "DNA" style directory path, i.e. in the same directory were the 
        images are located a new directory is created with the following convention:
        
          dnafiles_prefix_runNumber
        
        The path to this directory is returned if the directory was successfully created.
        """
        # First extract all reference image directory paths and names
        xsDataCollection = _xsDataResultCharacterisation.getDataCollection()
        listImageDirectoryPath = []
        listImagePrefix = []
        for xsDataSubWedge in xsDataCollection.getSubWedge():
            for xsDataImage in xsDataSubWedge.getImage():
                strImagePath = xsDataImage.getPath().getValue()
                listImageDirectoryPath.append(os.path.dirname(strImagePath))
                listImagePrefix.append(EDUtilsImage.getPrefix(strImagePath))
        # TODO: Check that all paths and prefixes are the same
        strImageDirectory = listImageDirectoryPath[0]
        strPrefix = listImagePrefix[0]
        # Remove any "ref-" or "postref-" from the prefix in order to make it fully
        # compatitble with DNA standards:
        if (strPrefix is not None):
            if (strPrefix.startswith("ref-")):
                strPrefix = strPrefix[4:]
            elif (strPrefix.startswith("postref-")):
                strPrefix = strPrefix[8:]
        strDNAFileDirectoryPath = os.path.join(strImageDirectory,
                                               "%s_dnafiles" % strPrefix)
        return strDNAFileDirectoryPath

    def createDNAFileDirectory(self, _strDNAFileDirectoryPath):
        """
        Create a "DNA-files" directory - if possible.
        """
        bSuccess = False
        if (_strDNAFileDirectoryPath is not None):
            if (os.path.exists(_strDNAFileDirectoryPath)):
                self.warning("Removing existing DNA files directory: %s" %
                             _strDNAFileDirectoryPath)
                if (os.access(_strDNAFileDirectoryPath, os.W_OK)):
                    shutil.rmtree(_strDNAFileDirectoryPath)
                else:
                    self.warning("Cannot remove existing DNA files directory!")
            if (_strDNAFileDirectoryPath is not None):
                # Check if directory one level up is writeable
                strDNAFileBaseDirectory = os.path.split(
                    _strDNAFileDirectoryPath)[0]
                if (os.access(strDNAFileBaseDirectory, os.W_OK)):
                    self.DEBUG("Creating DNA files directory: %s" %
                               _strDNAFileDirectoryPath)
                    os.makedirs(_strDNAFileDirectoryPath, mode=0o755)
                    bSuccess = True
                else:
                    self.warning("Cannot create DNA files directory: %s" %
                                 _strDNAFileDirectoryPath)
        return bSuccess

    def splitHeadDirectory(self, _strPath):
        """
        This method works like os.path.split except that it splits the head directory
        from the rest of the path. Example:
        "/" -> [ None, None]
        "/data" -> ["data", None]
        "/data/visitor" -> ["data", "visitor"]
        "/data/visitor/mx415/id14eh2/20100212" -> ["data", "visitor/mx415/id14eh2/20100212"]
        """
        listOfDirectories = _strPath.split(os.sep)
        strTail = None
        strHead = None
        if (len(listOfDirectories) > 1):
            strHead = listOfDirectories[1]
            if (strHead == ""):
                strHead = None
            if (len(listOfDirectories) > 1):
                for strEntry in listOfDirectories[2:]:
                    if (strTail is None):
                        strTail = strEntry
                    else:
                        strTail = os.path.join(strTail, strEntry)
        return [strHead, strTail]

    def createOutputFileDictionary(self,
                                   _xsDataResultCharacterisation,
                                   _strPathToLogFileDirectory=None):
        """
        This method creates an XSDataDictionary containing the name and locations of the 
        characterisation output files.
        """
        xsDataDictionaryLogFile = XSDataDictionary()
        # Start with the prediction images
        xsDataIndexingResult = _xsDataResultCharacterisation.getIndexingResult(
        )
        if xsDataIndexingResult is not None:
            xsDataGeneratePredictionResult = xsDataIndexingResult.getPredictionResult(
            )
            if xsDataGeneratePredictionResult is not None:
                listXSDataImagePrediction = xsDataGeneratePredictionResult.getPredictionImage(
                )
                for xsDataImagePrediction in listXSDataImagePrediction:
                    xsDataKeyValuePair = XSDataKeyValuePair()
                    iPredictionImageNumber = xsDataImagePrediction.getNumber(
                    ).getValue()
                    xsDataStringKey = XSDataString("predictionImage_%d" %
                                                   iPredictionImageNumber)
                    xsDataStringValue = None
                    strPredictionImagePath = xsDataImagePrediction.getPath(
                    ).getValue()
                    if (_strPathToLogFileDirectory is not None):
                        strPredictionImageFileName = EDUtilsFile.getBaseName(
                            strPredictionImagePath)
                        strNewPredictionImagePath = os.path.join(
                            _strPathToLogFileDirectory,
                            strPredictionImageFileName)
                        EDUtilsFile.copyFile(strPredictionImagePath,
                                             strNewPredictionImagePath)
                        xsDataStringValue = XSDataString(
                            strNewPredictionImagePath)
                    else:
                        xsDataStringValue = XSDataString(
                            strPredictionImageFileName)
                    xsDataKeyValuePair.setKey(xsDataStringKey)
                    xsDataKeyValuePair.setValue(xsDataStringValue)
                    xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)
        # Best log file
        strPathToBESTLogFile = None
        strPathToExecutiveSummary = None
        if _xsDataResultCharacterisation.getStrategyResult() is not None:
            if _xsDataResultCharacterisation.getStrategyResult(
            ).getBestLogFile() != None:
                strPathToBESTLogFile = _xsDataResultCharacterisation.getStrategyResult(
                ).getBestLogFile().getPath().getValue()
            if strPathToBESTLogFile is not None:
                xsDataStringKey = XSDataString("logFileBest")
                xsDataStringValue = None
                if (_strPathToLogFileDirectory is not None):
                    strNewBestLogPath = os.path.join(
                        _strPathToLogFileDirectory, "best.log")
                    EDUtilsFile.copyFile(strPathToBESTLogFile,
                                         strNewBestLogPath)
                    xsDataStringValue = XSDataString(strNewBestLogPath)
                else:
                    xsDataStringValue = XSDataString(strPathToBESTLogFile)
                xsDataKeyValuePair = XSDataKeyValuePair()
                xsDataKeyValuePair.setKey(xsDataStringKey)
                xsDataKeyValuePair.setValue(xsDataStringValue)
                xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)
            if (strPathToExecutiveSummary is not None):
                xsDataStringKey = XSDataString("executiveSummary")
                xsDataStringValue = None
                if (_strPathToLogFileDirectory is not None):
                    strExecutiveSummaryFileName = EDUtilsFile.getBaseName(
                        strPathToExecutiveSummary)
                    strNewExecutiveSummaryPath = os.path.join(
                        _strPathToLogFileDirectory,
                        strExecutiveSummaryFileName)
                    EDUtilsFile.copyFile(strPathToExecutiveSummary,
                                         strNewExecutiveSummaryPath)
                    xsDataStringValue = XSDataString(
                        strNewExecutiveSummaryPath)
                    # Copy also the executive summary file to "dna_log.txt"...
                    strNewExecutiveSummaryPath = os.path.join(
                        _strPathToLogFileDirectory, "dna_log.txt")
                    EDUtilsFile.copyFile(strPathToExecutiveSummary,
                                         strNewExecutiveSummaryPath)
                else:
                    xsDataStringValue = XSDataString(strPathToExecutiveSummary)
                xsDataKeyValuePair = XSDataKeyValuePair()
                xsDataKeyValuePair.setKey(xsDataStringKey)
                xsDataKeyValuePair.setValue(xsDataStringValue)
                xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)

        return xsDataDictionaryLogFile

    def doFailureActionCharacterisation(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionCharacterisation"
        )
        self.setFailure()
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "Characterisation FAILURE!"
        self.sendEmail(strSubject, strMessage)

    def getFluxAndBeamSizeFromISPyB(self, _xsDataFirstImage,
                                    _xsDataExperimentalCondition):
        """
        This method retrieves the flux and beamsize from ISPyB
        """
        xsDataExperimentalCondition = None
        if (_xsDataExperimentalCondition is not None):
            bFoundValidFlux = False
            xsDataExperimentalCondition = _xsDataExperimentalCondition.copy()
            xsDataInputRetrieveDataCollection = XSDataInputRetrieveDataCollection(
            )
            xsDataInputRetrieveDataCollection.setImage(
                XSDataImage(_xsDataFirstImage.getPath()))
            self.edPluginISPyBRetrieveDataCollection.setDataInput(
                xsDataInputRetrieveDataCollection)
            self.edPluginISPyBRetrieveDataCollection.executeSynchronous()
            xsDataResultRetrieveDataCollection = self.edPluginISPyBRetrieveDataCollection.getDataOutput(
            )
            if xsDataResultRetrieveDataCollection is not None:
                xsDataISPyBDataCollection = xsDataResultRetrieveDataCollection.getDataCollection(
                )
                if xsDataISPyBDataCollection is not None:
                    fFlux = xsDataISPyBDataCollection.getFlux_end()
                    if fFlux is not None:
                        self.screen(
                            "ISPyB reports flux to be: %g photons/sec" % fFlux)
                        if fFlux > self.fFluxThreshold:
                            xsDataExperimentalCondition.getBeam().setFlux(
                                XSDataFlux(fFlux))
                            bFoundValidFlux = True
                    fBeamSizeAtSampleX = xsDataISPyBDataCollection.beamSizeAtSampleX
                    fBeamSizeAtSampleY = xsDataISPyBDataCollection.beamSizeAtSampleY
                    if fBeamSizeAtSampleX is not None and fBeamSizeAtSampleY is not None:
                        self.screen("ISPyB reports beamsize X to be: %.3f mm" %
                                    fBeamSizeAtSampleX)
                        self.screen("ISPyB reports beamsize Y to be: %.3f mm" %
                                    fBeamSizeAtSampleY)
                        xsDataSize = XSDataSize()
                        xsDataSize.x = XSDataLength(fBeamSizeAtSampleX)
                        xsDataSize.y = XSDataLength(fBeamSizeAtSampleY)
                        xsDataExperimentalCondition.getBeam().setSize(
                            xsDataSize)
                    # Get transmission if it's not already there
                    if xsDataExperimentalCondition.beam.transmission is None:
                        fTransmission = xsDataISPyBDataCollection.transmission
                        xsDataExperimentalCondition.beam.transmission = XSDataDouble(
                            fTransmission)
            if not bFoundValidFlux:
                self.screen(
                    "No valid flux could be retrieved from ISPyB! Trying to obtain flux from input data."
                )
                xsDataBeam = xsDataExperimentalCondition.getBeam()
                xsDataBeamFlux = xsDataBeam.getFlux()
                if xsDataBeamFlux is not None:
                    fFluxMXCuBE = xsDataBeamFlux.getValue()
                    self.screen("MXCuBE reports flux to be: %g photons/sec" %
                                fFluxMXCuBE)
                    if fFluxMXCuBE < self.fFluxThreshold:
                        self.screen(
                            "MXCuBE flux lower than threshold flux %g photons/s!"
                            % self.fFluxThreshold)
                        self.screen("Forcing flux to 0.0 photons/s")
                        xsDataExperimentalCondition.getBeam().setFlux(
                            XSDataFlux(0.0))
                else:
                    # Force missing flux to 0.0
                    self.screen(
                        "No flux neither in ISPyB nor in mxCuBE, forcing flux to 0.0 photon/s"
                    )
                    xsDataExperimentalCondition.getBeam().setFlux(
                        XSDataFlux(0.0))

        return xsDataExperimentalCondition

    def updateDataInputCharacterisation(self, _xsDataInputCharacterisation):
        """
        This method updates the xsDataInputCharacterisation object given as argument with the following
        parameters (if available) goven as input:
        - Diffraction plan
        - Beam size
        - Beam flux
        - Min exposure time per image
        - Max oscillation speed
        - Min oscillation width
        - Sample information
        """
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.createDataInputCharacterisationFromDataSets"
        )
        xsDataCollection = _xsDataInputCharacterisation.getDataCollection()
        if (_xsDataInputCharacterisation is not None):
            xsDataInputCCP4i = self.getDataInput()
            # Update with diffraction plan
            xsDiffactionPlan = xsDataInputCCP4i.getDiffractionPlan()
            if (xsDiffactionPlan is not None):
                xsDataCollection.setDiffractionPlan(xsDiffactionPlan)
            # Update the data collection subwedges with additional experimental conditions
            for xsDataSubWedge in xsDataCollection.getSubWedge():
                xsDataExperimentalCondition = xsDataInputCCP4i.getExperimentalCondition(
                )
                if (xsDataExperimentalCondition is not None):
                    xsDataBeam = xsDataExperimentalCondition.getBeam()
                    if (xsDataBeam is not None):
                        xsDataBeamSize = xsDataBeam.getSize()
                        if (xsDataBeamSize is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam(
                            ).setSize(xsDataBeamSize)
                        xsDataBeamFlux = xsDataBeam.getFlux()
                        if (xsDataBeamFlux is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam(
                            ).setFlux(xsDataBeamFlux)
                        xsDataMinExposureTime = xsDataBeam.getMinExposureTimePerImage(
                        )
                        if (xsDataMinExposureTime is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam(
                            ).setMinExposureTimePerImage(xsDataMinExposureTime)
                    xsDataGoniostat = xsDataExperimentalCondition.getGoniostat(
                    )
                    if (xsDataGoniostat is not None):
                        xsDataMaxOscSpeed = xsDataGoniostat.getMaxOscillationSpeed(
                        )
                        if (xsDataMaxOscSpeed is not None):
                            xsDataSubWedge.getExperimentalCondition(
                            ).getGoniostat().setMaxOscillationSpeed(
                                xsDataMaxOscSpeed)
                        xsDataMinOscWidth = xsDataGoniostat.getMinOscillationWidth(
                        )
                        if (xsDataMinOscWidth is not None):
                            xsDataSubWedge.getExperimentalCondition(
                            ).getGoniostat().setMinOscillationWidth(
                                xsDataMinOscWidth)
            # Update with the sample
            xsDataSample = xsDataInputCCP4i.getSample()
            if (xsDataSample is not None):
                xsDataCollection.setSample(xsDataSample)

    def getBeamlineProposalFromPath(self, _strPathToImage):
        """ESRF specific code for extracting the beamline name and prefix from the path"""
        listPath = _strPathToImage.split("/")
        strPrefix = EDUtilsImage.getPrefix(_strPathToImage).replace("ref-", "")
        if listPath[2] == "visitor":
            strBeamline = listPath[4]
            strProposal = listPath[3]
        elif listPath[3] == "inhouse":
            strBeamline = listPath[2]
            strProposal = listPath[4]
        else:
            strBeamline = "nobeamline"
            strProposal = "noproposal"
        return (strBeamline, strProposal, strPrefix)

    def sendEmail(self, _strSubject, _strMessage):
        """Sends an email to the EDNA contact person (if configured)."""
        strTime = "%.1f s" % (self.tStop - self.tStart)
        if EDUtilsPath.isESRF():
            strPathImage = None
            for dataSet in self.dataInput.dataSet:
                for imageFile in dataSet.imageFile:
                    strPathImage = imageFile.path.value
                    break
            if strPathImage is not None:
                (strBeamline, strProposal,
                 strPrefix) = self.getBeamlineProposalFromPath(strPathImage)
            else:
                strBeamline = "Unknown"
                strProposal = "Unknown"
                strPrefix = "Unknown"
            strHost = socket.gethostname()
            strSubject = "EDNA ch %s %s %s %s %s (%s)" % (
                _strSubject, strBeamline, strProposal, strPrefix, strHost,
                strTime)
        else:
            strSubject = "EDNA %s : %s (%s)" % (
                _strSubject, EDUtilsPath.getEdnaSite(), strTime)
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Subject = %s" %
            strSubject)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Message:")
        self.DEBUG(_strMessage)
        if self.strEDNAContactEmail == None:
            self.DEBUG(
                "EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: No email address configured!"
            )
        elif not EDUtilsPath.getEdnaSite().startswith("ESRF"):
            self.DEBUG(
                "EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Not executed at the ESRF! EDNA_SITE=%s"
                % EDUtilsPath.getEdnaSite())
        else:
            try:
                self.DEBUG("Sending message to %s." % self.strEDNAContactEmail)
                self.DEBUG("Message: %s" % _strMessage)
                strMessage = "EDNA_HOME = %s\n" % EDUtilsPath.getEdnaHome()
                strMessage += "EDNA_SITE = %s\n" % EDUtilsPath.getEdnaSite()
                strMessage += "PLUGIN_NAME = %s\n" % self.getPluginName()
                strMessage += "working_dir = %s\n\n" % self.getWorkingDirectory(
                )
                strMessage += "Reference images:\n"
                xsDataInputMXCuBE = self.getDataInput()
                for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
                    for xsDataFile in xsDataSetMXCuBE.getImageFile():
                        strMessage += "%s\n" % xsDataFile.getPath().getValue()
                strMessage += "\n"
                strMessage += _strMessage
                strEmailMsg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (self.strEDNAEmailSender, \
                                                                                self.strEDNAContactEmail, \
                                                                                strSubject, strMessage))
                server = smtplib.SMTP("localhost")
                server.sendmail(self.strEDNAEmailSender,
                                self.strEDNAContactEmail, strEmailMsg)
                server.quit()
            except:
                self.ERROR("Error when sending email message!")
                self.writeErrorTrace()

    def executeSimpleHTML(self, _xsDataResultCharacterisation):
        xsDataInputSimpleHTMLPage = XSDataInputSimpleHTMLPage()
        xsDataInputSimpleHTMLPage.setCharacterisationResult(
            _xsDataResultCharacterisation)
        self.edPluginExecSimpleHTML.setDataInput(xsDataInputSimpleHTMLPage)
        self.edPluginExecSimpleHTML.connectSUCCESS(self.doSuccessSimpleHTML)
        self.edPluginExecSimpleHTML.connectFAILURE(self.doFailureSimpleHTML)
        self.executePluginSynchronous(self.edPluginExecSimpleHTML)

    def doSuccessSimpleHTML(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessSimpleHTML...")
        self.retrieveSuccessMessages(
            _edPlugin,
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessSimpleHTML")
        # Copy files from working directory
        if self.dataInput.htmlDir is None:
            self.xsDataResultMXCuBE.setHtmlPage(
                _edPlugin.dataOutput.pathToHTMLFile)
        else:
            htmlDir = self.dataInput.htmlDir.path.value
            if os.path.exists(htmlDir):
                # Potentially unsafe but very unlikely that this will cause problems
                htmlDir = tempfile.mktemp(prefix=os.path.basename(htmlDir),
                                          dir=os.path.dirname(htmlDir))
            shutil.copytree(
                os.path.dirname(
                    _edPlugin.dataOutput.pathToHTMLFile.path.value), htmlDir)
            htmlPage = os.path.join(
                htmlDir,
                os.path.basename(
                    _edPlugin.dataOutput.pathToHTMLFile.path.value))
            self.xsDataResultMXCuBE.setHtmlPage(
                XSDataFile(XSDataString(htmlPage)))

    def doFailureSimpleHTML(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureSimpleHTML...")
コード例 #26
0
class EDPluginControlInterfaceToMXCuBEv1_3(EDPluginControl):
    """
    This is the plugin interface to launch the MXv1 characterisation from an MXCuBE gui.
    It is for the moment a wrapper for the EDPluginControlCCP4iv1_1 plugin, which also
    runs the ISPyB control plugin if a data collection id is available.
    """

    EDNA_CONTACT_EMAIL = "contactEmail"
    EDNA_EMAIL_SENDER = "emailSender"

    def __init__(self):
        """
        Initialisation of EDPluginControlInterfaceToMXCuBEv1_3:
        - Input data type class : XSDataInputMXCuBE
        - Name of default characterisation plugin : EDPluginControlCharacterisationv1_1
        """
        EDPluginControl.__init__(self)
        self.setXSDataInputClass(XSDataInputMXCuBE)
        self.strPluginControlInterface = "EDPluginControlInterfacev1_2"
        self.edPluginControlInterface = None
        self.strPluginControlISPyB = "EDPluginControlISPyBv1_4"
        self.edPluginControlISPyB = None
        self.xsDataResultMXCuBE = None
        self.xsDataIntegerDataCollectionId = None
        self.strPluginExecOutputHTMLName = "EDPluginExecOutputHTMLv1_0"
        self.edPluginExecOutputHTML = None
        self.strPluginExecSimpleHTMLName = "EDPluginExecSimpleHTMLPagev1_0"
        self.edPluginExecSimpleHTML = None
        self.strEDNAContactEmail = None
        self.strEDNAEmailSender = "*****@*****.**"
        self.tStart = None
        self.tStop = None

    def checkParameters(self):
        """
        Checks the mandatory input parameters :
        - dataSet
        - outputFileDirectory
        """
        self.verboseDebug(
            "EDPluginControlInterfaceToMXCuBEv1_3.checkParameters")
        self.checkMandatoryParameters(self.getDataInput(),
                                      "Data Input is None")
        self.checkMandatoryParameters(self.getDataInput().getDataSet(),
                                      "dataSet")

    def configure(self):
        EDPluginControl.configure(self)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.configure")
        xsPluginItem = self.getConfiguration()
        if xsPluginItem == None:
            self.DEBUG(
                "EDPluginControlInterfaceToMXCuBEv1_3.configure: No plugin item defined."
            )
        else:
            self.strEDNAContactEmail = EDConfiguration.getStringParamValue(
                xsPluginItem,
                EDPluginControlInterfaceToMXCuBEv1_3.EDNA_CONTACT_EMAIL)
            self.DEBUG(
                "EDPluginControlInterfaceToMXCuBEv1_3.configure: EDNAContactEmail = %s"
                % self.strEDNAContactEmail)
            strEDNAEmailSender = EDConfiguration.getStringParamValue(
                xsPluginItem, self.EDNA_EMAIL_SENDER)
            if strEDNAEmailSender:
                self.strEDNAEmailSender = strEDNAEmailSender

    def preProcess(self, _edPlugin=None):
        """
        This method prepares the input for the CCP4i plugin and loads it.
        """
        EDPluginControl.preProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.preProcess...")

        self.tStart = time.time()

        xsDataInputMXCuBE = self.getDataInput()
        xsDataInputInterface = XSDataInputInterface()
        self.edPluginControlInterface = self.loadPlugin(
            self.strPluginControlInterface)
        for xsDataSetMXCuBE in xsDataInputMXCuBE.getDataSet():
            for xsDataFile in xsDataSetMXCuBE.getImageFile():
                xsDataInputInterface.addImagePath(xsDataFile)

        xsDataInputInterface.setExperimentalCondition(
            xsDataInputMXCuBE.getExperimentalCondition())
        xsDataInputInterface.setDiffractionPlan(
            xsDataInputMXCuBE.getDiffractionPlan())
        xsDataInputInterface.setSample(xsDataInputMXCuBE.getSample())
        xsDataInputInterface.setDataCollectionId(
            xsDataInputMXCuBE.getDataCollectionId())
        self.edPluginControlInterface.setDataInput(xsDataInputInterface)

        #self.edPluginExecOutputHTML = self.loadPlugin(self.strPluginExecOutputHTMLName, "OutputHTML")
        self.edPluginExecSimpleHTML = self.loadPlugin(
            self.strPluginExecSimpleHTMLName, "SimpleHTML")
        self.xsDataResultMXCuBE = XSDataResultMXCuBE()

    def process(self, _edPlugin=None):
        EDPluginControl.process(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.process...")

        if self.edPluginControlInterface is not None:
            self.connectProcess(
                self.edPluginControlInterface.executeSynchronous)
            self.edPluginControlInterface.connectSUCCESS(
                self.doSuccessActionInterface)
            self.edPluginControlInterface.connectFAILURE(
                self.doFailureActionInterface)

    def finallyProcess(self, _edPlugin=None):
        EDPluginControl.finallyProcess(self, _edPlugin)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.postProcess...")
        self.setDataOutput(self.xsDataResultMXCuBE)

    def doSuccessActionInterface(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface...")
        self.retrieveSuccessMessages(
            self.edPluginControlInterface,
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionInterface")
        xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput(
        ).getResultCharacterisation()
        self.xsDataResultMXCuBE.setCharacterisationResult(
            xsDataResultCharacterisation)
        xsDataResultControlISPyB = self.edPluginControlInterface.getDataOutput(
        ).getResultControlISPyB()
        if xsDataResultControlISPyB != None:
            self.xsDataResultMXCuBE.setScreeningId(
                xsDataResultControlISPyB.getScreeningId())
        if xsDataResultCharacterisation != None:
            strPathCharacterisationResult = os.path.join(
                self.getWorkingDirectory(), "CharacterisationResult.xml")
            xsDataResultCharacterisation.exportToFile(
                strPathCharacterisationResult)
            self.xsDataResultMXCuBE.setListOfOutputFiles(
                XSDataString(strPathCharacterisationResult))
            # For the moment, create "DNA" style output directory
            strPathToDNAFileDirectory = self.createDNAFileDirectoryPath(
                xsDataResultCharacterisation)
            xsDataDictionaryLogFile = None
            if (self.createDNAFileDirectory(strPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(
                    xsDataResultCharacterisation, strPathToDNAFileDirectory)
            strPyArchPathToDNAFileDirectory = self.createPyArchDNAFilePath(
                strPathToDNAFileDirectory)
            if (self.createDNAFileDirectory(strPyArchPathToDNAFileDirectory)):
                xsDataDictionaryLogFile = self.createOutputFileDictionary(
                    xsDataResultCharacterisation,
                    strPyArchPathToDNAFileDirectory)
            self.xsDataResultMXCuBE.setOutputFileDictionary(
                xsDataDictionaryLogFile)
            # Send success email message (MXSUP-183):
            self.tStop = time.time()
            strSubject = "%s : SUCCESS! (%.1f s)" % (EDUtilsPath.getEdnaSite(),
                                                     self.tStop - self.tStart)
            strMessage = "Characterisation success!"
            if xsDataResultCharacterisation.getStatusMessage():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getStatusMessage(
                ).getValue()
            if xsDataResultCharacterisation.getShortSummary():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getShortSummary(
                ).getValue()
            self.sendEmail(strSubject, strMessage)
            # Fix for bug EDNA-55 : If burning strategy EDNA2html shouldn't be run
            bRunExecOutputHTML = False
            xsDataInputMXCuBE = self.getDataInput()
            xsDataDiffractionPlan = xsDataInputMXCuBE.getDiffractionPlan()
            if xsDataDiffractionPlan.getStrategyOption() is not None:
                strStrategyOption = xsDataDiffractionPlan.getStrategyOption(
                ).getValue()
                if strStrategyOption.find("-DamPar") != -1:
                    bRunExecOutputHTML = False
            if (self.edPluginExecOutputHTML
                    is not None) and bRunExecOutputHTML:
                self.edPluginExecOutputHTML.setDataInput(
                    XSDataFile(XSDataString(strPathToDNAFileDirectory)),
                    "dnaFileDirectory")
                self.edPluginExecOutputHTML.execute()
            # Fix for bug MXSUP-251: Put the BEST .par file in the EDNA characterisation root directory
            xsDataIntegrationResult = xsDataResultCharacterisation.getIntegrationResult(
            )
            if xsDataIntegrationResult:
                listXSDataIntegrationSubWedgeResult = xsDataIntegrationResult.getIntegrationSubWedgeResult(
                )
                if listXSDataIntegrationSubWedgeResult:
                    if listXSDataIntegrationSubWedgeResult != []:
                        strBestfilePar = listXSDataIntegrationSubWedgeResult[
                            0].getBestfilePar().getValue()
                        # Put the file one directory above the mxCuBE v1.3 plugin working directory:
                        strDir = os.path.dirname(self.getWorkingDirectory())
                        strPath = os.path.join(strDir, "bestfile.par")
                        EDUtilsFile.writeFile(strPath, strBestfilePar)
            # Execute plugin which creates a simple HTML page
            self.executeSimpleHTML(xsDataResultCharacterisation)

    def doFailureActionInterface(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionInterface...")
        self.setFailure()
        xsDataResultCharacterisation = None
        if self.edPluginControlInterface.hasDataOutput("characterisation"):
            xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput(
                "characterisation")[0]
        # Execute plugin which creates a simple HTML page
        self.executeSimpleHTML(xsDataResultCharacterisation)
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "Interface FAILURE!"
        if self.edPluginControlInterface.hasDataOutput("characterisation"):
            xsDataResultCharacterisation = self.edPluginControlInterface.getDataOutput(
                "characterisation")[0]
            if xsDataResultCharacterisation.getStatusMessage():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getStatusMessage(
                ).getValue()
            if xsDataResultCharacterisation.getShortSummary():
                strMessage += "\n\n"
                strMessage += xsDataResultCharacterisation.getShortSummary(
                ).getValue()
        self.sendEmail(strSubject, strMessage)

    def doSuccessActionISPyB(self, _edPlugin):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionISPyB...")
        self.retrieveSuccessMessages(
            self.edPluginControlISPyB,
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessActionISPyB")

    def doFailureActionISPyB(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionISpyB...")
        self.retrieveFailureMessages(
            self.edPluginControlISPyB,
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureActionISpyB")
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "ISPyB FAILURE!"
        self.sendEmail(strSubject, strMessage)

    def createDNAFileDirectoryPath(self, _xsDataResultCharacterisation):
        """
        This method creates a "DNA" style directory path, i.e. in the same directory were the 
        images are located a new directory is created with the following convention:
        
          dnafiles_prefix_runNumber
        
        The path to this directory is returned if the directory was successfully created.
        """
        # First extract all reference image directory paths and names
        xsDataCollection = _xsDataResultCharacterisation.getDataCollection()
        listImageDirectoryPath = []
        listImagePrefix = []
        for xsDataSubWedge in xsDataCollection.getSubWedge():
            for xsDataImage in xsDataSubWedge.getImage():
                strImagePath = xsDataImage.getPath().getValue()
                listImageDirectoryPath.append(os.path.dirname(strImagePath))
                listImagePrefix.append(EDUtilsImage.getPrefix(strImagePath))
        # TODO: Check that all paths and prefixes are the same
        strImageDirectory = listImageDirectoryPath[0]
        strPrefix = listImagePrefix[0]
        # Remove any "ref-" or "postref-" from the prefix in order to make it fully
        # compatitble with DNA standards:
        if (strPrefix is not None):
            if (strPrefix.startswith("ref-")):
                strPrefix = strPrefix[4:]
            elif (strPrefix.startswith("postref-")):
                strPrefix = strPrefix[8:]
        strDNAFileDirectoryPath = os.path.join(strImageDirectory,
                                               "%s_dnafiles" % strPrefix)
        return strDNAFileDirectoryPath

    def createPyArchDNAFilePath(self, _strDNAFileDirectoryPath):
        """
        This method translates from a "visitor" path to a "pyarch" path:
        /data/visitor/mx415/id14eh1/20100209 -> /data/pyarch/id14eh1/mx415/20100209
        """
        strPyarchDNAFilePath = None
        listOfDirectories = _strDNAFileDirectoryPath.split(os.sep)
        listBeamlines = [
            "bm14", "id14eh1", "id14eh2", "id14eh3", "id14eh4", "id23eh1",
            "id23eh2", "id29"
        ]
        # Check that we have at least four levels of directories:
        if (len(listOfDirectories) > 4):
            strDataDirectory = listOfDirectories[1]
            strSecondDirectory = listOfDirectories[2]
            strProposal = None
            strBeamline = None
            if ((strDataDirectory == "data")
                    and (strSecondDirectory == "visitor")):
                strProposal = listOfDirectories[3]
                strBeamline = listOfDirectories[4]
            elif ((strDataDirectory == "data")
                  and (strSecondDirectory in listBeamlines)):
                strBeamline = strSecondDirectory
                strProposal = listOfDirectories[4]
            if (strProposal != None) and (strBeamline != None):
                strPyarchDNAFilePath = os.path.join(os.sep, "data")
                strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath,
                                                    "pyarch")
                strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath,
                                                    strBeamline)
                strPyarchDNAFilePath = os.path.join(strPyarchDNAFilePath,
                                                    strProposal)
                for strDirectory in listOfDirectories[5:]:
                    strPyarchDNAFilePath = os.path.join(
                        strPyarchDNAFilePath, strDirectory)
        if (strPyarchDNAFilePath is None):
            self.WARNING(
                "EDPluginControlInterfaceToMXCuBEv1_3.createPyArchDNAFilePath: path not converted for pyarch: %s "
                % _strDNAFileDirectoryPath)
        return strPyarchDNAFilePath

    def createDNAFileDirectory(self, _strDNAFileDirectoryPath):
        """
        Create a "DNA-files" directory - if possible.
        """
        bSuccess = False
        if (_strDNAFileDirectoryPath is not None):
            if (os.path.exists(_strDNAFileDirectoryPath)):
                self.warning("Removing existing DNA files directory: %s" %
                             _strDNAFileDirectoryPath)
                if (os.access(_strDNAFileDirectoryPath, os.W_OK)):
                    shutil.rmtree(_strDNAFileDirectoryPath)
                else:
                    self.warning("Cannot remove existing DNA files directory!")
            if (_strDNAFileDirectoryPath is not None):
                # Check if directory one level up is writeable
                strDNAFileBaseDirectory = os.path.split(
                    _strDNAFileDirectoryPath)[0]
                if (os.access(strDNAFileBaseDirectory, os.W_OK)):
                    self.DEBUG("Creating DNA files directory: %s" %
                               _strDNAFileDirectoryPath)
                    os.mkdir(_strDNAFileDirectoryPath)
                    bSuccess = True
                else:
                    self.warning("Cannot create DNA files directory: %s" %
                                 _strDNAFileDirectoryPath)
        return bSuccess

    def splitHeadDirectory(self, _strPath):
        """
        This method works like os.path.split except that it splits the head directory
        from the rest of the path. Example:
        "/" -> [ None, None]
        "/data" -> ["data", None]
        "/data/visitor" -> ["data", "visitor"]
        "/data/visitor/mx415/id14eh2/20100212" -> ["data", "visitor/mx415/id14eh2/20100212"]
        """
        listOfDirectories = _strPath.split(os.sep)
        strTail = None
        strHead = None
        if (len(listOfDirectories) > 1):
            strHead = listOfDirectories[1]
            if (strHead == ""):
                strHead = None
            if (len(listOfDirectories) > 1):
                for strEntry in listOfDirectories[2:]:
                    if (strTail is None):
                        strTail = strEntry
                    else:
                        strTail = os.path.join(strTail, strEntry)
        return [strHead, strTail]

    def createOutputFileDictionary(self,
                                   _xsDataResultCharacterisation,
                                   _strPathToLogFileDirectory=None):
        """
        This method creates an XSDataDictionary containing the name and locations of the 
        characterisation output files.
        """
        xsDataDictionaryLogFile = XSDataDictionary()
        # Start with the prediction images
        xsDataIndexingResult = _xsDataResultCharacterisation.getIndexingResult(
        )
        xsDataGeneratePredictionResult = xsDataIndexingResult.getPredictionResult(
        )
        listXSDataImagePrediction = xsDataGeneratePredictionResult.getPredictionImage(
        )
        for xsDataImagePrediction in listXSDataImagePrediction:
            xsDataKeyValuePair = XSDataKeyValuePair()
            iPredictionImageNumber = xsDataImagePrediction.getNumber(
            ).getValue()
            xsDataStringKey = XSDataString("predictionImage_%d" %
                                           iPredictionImageNumber)
            xsDataStringValue = None
            strPredictionImagePath = xsDataImagePrediction.getPath().getValue()
            if (_strPathToLogFileDirectory is not None):
                strPredictionImageFileName = EDUtilsFile.getBaseName(
                    strPredictionImagePath)
                strNewPredictionImagePath = os.path.join(
                    _strPathToLogFileDirectory, strPredictionImageFileName)
                EDUtilsFile.copyFile(strPredictionImagePath,
                                     strNewPredictionImagePath)
                xsDataStringValue = XSDataString(strNewPredictionImagePath)
            else:
                xsDataStringValue = XSDataString(strPredictionImageFileName)
            xsDataKeyValuePair.setKey(xsDataStringKey)
            xsDataKeyValuePair.setValue(xsDataStringValue)
            xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)
        # Best log file
        strPathToBESTLogFile = None
        strPathToExecutiveSummary = None
        if _xsDataResultCharacterisation.getStrategyResult().getBestLogFile(
        ) != None:
            strPathToBESTLogFile = _xsDataResultCharacterisation.getStrategyResult(
            ).getBestLogFile().getPath().getValue()
        if strPathToBESTLogFile is not None:
            xsDataStringKey = XSDataString("logFileBest")
            xsDataStringValue = None
            if (_strPathToLogFileDirectory is not None):
                strNewBestLogPath = os.path.join(_strPathToLogFileDirectory,
                                                 "best.log")
                EDUtilsFile.copyFile(strPathToBESTLogFile, strNewBestLogPath)
                xsDataStringValue = XSDataString(strNewBestLogPath)
            else:
                xsDataStringValue = XSDataString(strPathToBESTLogFile)
            xsDataKeyValuePair = XSDataKeyValuePair()
            xsDataKeyValuePair.setKey(xsDataStringKey)
            xsDataKeyValuePair.setValue(xsDataStringValue)
            xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)
        if (strPathToExecutiveSummary is not None):
            xsDataStringKey = XSDataString("executiveSummary")
            xsDataStringValue = None
            if (_strPathToLogFileDirectory is not None):
                strExecutiveSummaryFileName = EDUtilsFile.getBaseName(
                    strPathToExecutiveSummary)
                strNewExecutiveSummaryPath = os.path.join(
                    _strPathToLogFileDirectory, strExecutiveSummaryFileName)
                EDUtilsFile.copyFile(strPathToExecutiveSummary,
                                     strNewExecutiveSummaryPath)
                xsDataStringValue = XSDataString(strNewExecutiveSummaryPath)
                # Copy also the executive summary file to "dna_log.txt"...
                strNewExecutiveSummaryPath = os.path.join(
                    _strPathToLogFileDirectory, "dna_log.txt")
                EDUtilsFile.copyFile(strPathToExecutiveSummary,
                                     strNewExecutiveSummaryPath)
            else:
                xsDataStringValue = XSDataString(strPathToExecutiveSummary)
            xsDataKeyValuePair = XSDataKeyValuePair()
            xsDataKeyValuePair.setKey(xsDataStringKey)
            xsDataKeyValuePair.setValue(xsDataStringValue)
            xsDataDictionaryLogFile.addKeyValuePair(xsDataKeyValuePair)

        return xsDataDictionaryLogFile

    def doFailureActionCharacterisation(self, _edPlugin=None):
        """
        retrieve the potential warning messages
        retrieve the potential error messages
        """
        self.DEBUG(
            "EDPluginControlInterfacev1_3.doFailureActionCharacterisation")
        self.setFailure()
        # Send failure email message (MXSUP-183):
        strSubject = "%s : FAILURE!" % EDUtilsPath.getEdnaSite()
        strMessage = "Characterisation FAILURE!"
        self.sendEmail(strSubject, strMessage)

    def updateDataInputCharacterisation(self, _xsDataInputCharacterisation):
        """
        This method updates the xsDataInputCharacterisation object given as argument with the following
        parameters (if available) goven as input:
        - Diffraction plan
        - Beam size
        - Beam flux
        - Min exposure time per image
        - Max oscillation speed
        - Min oscillation width
        - Sample information
        """
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.createDataInputCharacterisationFromDataSets"
        )
        xsDataCollection = _xsDataInputCharacterisation.getDataCollection()
        if (_xsDataInputCharacterisation is not None):
            xsDataInputCCP4i = self.getDataInput()
            # Update with diffraction plan
            xsDiffactionPlan = xsDataInputCCP4i.getDiffractionPlan()
            if (xsDiffactionPlan is not None):
                xsDataCollection.setDiffractionPlan(xsDiffactionPlan)
            # Update the data collection subwedges with additional experimental conditions
            for xsDataSubWedge in xsDataCollection.getSubWedge():
                xsDataExperimentalCondition = xsDataInputCCP4i.getExperimentalCondition(
                )
                if (xsDataExperimentalCondition is not None):
                    xsDataBeam = xsDataExperimentalCondition.getBeam()
                    if (xsDataBeam is not None):
                        xsDataBeamSize = xsDataBeam.getSize()
                        if (xsDataBeamSize is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam(
                            ).setSize(xsDataBeamSize)
                        xsDataBeamFlux = xsDataBeam.getFlux()
                        if (xsDataBeamFlux is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam(
                            ).setFlux(xsDataBeamFlux)
                        xsDataMinExposureTime = xsDataBeam.getMinExposureTimePerImage(
                        )
                        if (xsDataMinExposureTime is not None):
                            xsDataSubWedge.getExperimentalCondition().getBeam(
                            ).setMinExposureTimePerImage(xsDataMinExposureTime)
                    xsDataGoniostat = xsDataExperimentalCondition.getGoniostat(
                    )
                    if (xsDataGoniostat is not None):
                        xsDataMaxOscSpeed = xsDataGoniostat.getMaxOscillationSpeed(
                        )
                        if (xsDataMaxOscSpeed is not None):
                            xsDataSubWedge.getExperimentalCondition(
                            ).getGoniostat().setMaxOscillationSpeed(
                                xsDataMaxOscSpeed)
                        xsDataMinOscWidth = xsDataGoniostat.getMinOscillationWidth(
                        )
                        if (xsDataMinOscWidth is not None):
                            xsDataSubWedge.getExperimentalCondition(
                            ).getGoniostat().setMinOscillationWidth(
                                xsDataMinOscWidth)
            # Update with the sample
            xsDataSample = xsDataInputCCP4i.getSample()
            if (xsDataSample is not None):
                xsDataCollection.setSample(xsDataSample)

    def sendEmail(self, _strSubject, _strMessage):
        """Sends an email to the EDNA contact person (if configured)."""

        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Subject = %s" %
            _strSubject)
        self.DEBUG("EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Message:")
        self.DEBUG(_strMessage)
        if self.strEDNAContactEmail == None:
            self.DEBUG(
                "EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: No email address configured!"
            )
        elif not EDUtilsPath.getEdnaSite().startswith("ESRF"):
            self.DEBUG(
                "EDPluginControlInterfaceToMXCuBEv1_3.sendEmail: Not executed at the ESRF! EDNA_SITE=%s"
                % EDUtilsPath.getEdnaSite())
        else:
            try:
                self.DEBUG("Sending message to %s." % self.strEDNAContactEmail)
                self.DEBUG("Message: %s" % _strMessage)
                strMessage = """
EDNA_HOME = %s
EDNA_SITE = %s
PLUGIN_NAME = %s
working_dir = %s
%s

""" % (EDUtilsPath.getEdnaHome(), EDUtilsPath.getEdnaSite(),
                self.getPluginName(), self.getWorkingDirectory(), _strMessage)
                strEmailMsg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (self.strEDNAEmailSender, \
                                                                                self.strEDNAContactEmail, \
                                                                                _strSubject, strMessage))
                server = smtplib.SMTP("localhost")
                server.sendmail(self.strEDNAEmailSender,
                                self.strEDNAContactEmail, strEmailMsg)
                server.quit()
            except:
                self.ERROR("Error when sending email message!")
                self.writeErrorTrace()

    def executeSimpleHTML(self, _xsDataResultCharacterisation):
        xsDataInputSimpleHTMLPage = XSDataInputSimpleHTMLPage()
        xsDataInputSimpleHTMLPage.setCharacterisationResult(
            _xsDataResultCharacterisation)
        self.edPluginExecSimpleHTML.setDataInput(xsDataInputSimpleHTMLPage)
        self.edPluginExecSimpleHTML.connectSUCCESS(self.doSuccessSimpleHTML)
        self.edPluginExecSimpleHTML.connectFAILURE(self.doFailureSimpleHTML)
        self.executePluginSynchronous(self.edPluginExecSimpleHTML)

    def doSuccessSimpleHTML(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessSimpleHTML...")
        self.retrieveSuccessMessages(
            _edPlugin,
            "EDPluginControlInterfaceToMXCuBEv1_3.doSuccessSimpleHTML")
        self.xsDataResultMXCuBE.setHtmlPage(
            _edPlugin.getDataOutput().getPathToHTMLFile())

    def doFailureSimpleHTML(self, _edPlugin=None):
        self.DEBUG(
            "EDPluginControlInterfaceToMXCuBEv1_3.doFailureSimpleHTML...")