from CCP4ReportParser import *
import sys
from lxml import etree

class import_mosflm_report(Report):
    # Specify which gui task and/or pluginscript this applies to
    TASKNAME = 'import_mosflm'
    RUNNING = False
    def __init__(self,xmlnode=None,jobInfo={},jobStatus=None,**kw):
        Report. __init__(self,xmlnode=xmlnode,jobInfo=jobInfo,**kw)
        
        if jobStatus.lower()=="nooutput": return

        if not self.xmlnode.haspath('//integration_result'):
            self.append('No integration data found from iMosflm')
            return
                
        detectorFold = self.addFold(label="Detector and beam", initiallyOpen=True)
        detectorDiv = detectorFold.addDiv(style="border:2px solid black;display:inline-block;width:900px;")
        graphLineChooser = detectorDiv.addGraphLineChooser(tableWidth='220px',contentWidth='260px',height='270px',style='float:left;')
        self.beamGraph(parent=graphLineChooser)
        self.centralSpotProfile(parent=detectorDiv)

        clearingDiv = self.addDiv(style="clear:both;")
    
        crystalFold = self.addFold(label="Crystal", initiallyOpen=True)
        crystalDiv = crystalFold.addDiv(style="border:2px solid black;display:inline-block;width:900px;")
        otherGraphLineChooser = crystalDiv.addGraphLineChooser(tableWidth='220px',contentWidth='260px',height='270px',style='float:left;')
        self.crystalGraph(parent=otherGraphLineChooser)
        self.blockProfiles(parent=crystalDiv)
        
        clearingDiv = self.addDiv(style="clear:both;")

        dataFold = self.addFold(label="Data", initiallyOpen=True)
        dataDiv = dataFold.addDiv(style="border:2px solid black;display:inline-block;width:900px;")
        thirdGraphLineChooser = dataDiv.addGraphLineChooser(tableWidth='220px',contentWidth='260px',height='270px',style='float:left;')
        self.dataGraph(parent=thirdGraphLineChooser)
        self.histograms(parent=dataDiv)
    
    def beamGraph(self, parent=None):
        if parent is None: parent = self
        graph = parent.addGraph(xmlnode=None, title='Hellow',style="width:260px;height:270px;")
        tableData = [("beam_x",u"Beam\u00A0x"), ("beam_y",u"Beam\u00A0y"), ("distance","Distance"), ("yscale","Y-scale"),("tilt","Tilt"),("twist","Twist"),("tangential_offset",u"Tangential\u00A0offset"),("radial_offset",u"Radial\u00A0offset"),("global_absolute_rms_residual",u"RMS\u00A0residual"),("central_absolute_rms_residual",u"RMS\u00A0res.\u00A0(central)"),("global_weighted_rms_residual",u"RMS\u00A0res.\u00A0(weighted)")]
        dataTuples = []
        imageCount = 0
        integrationNode = self.xmlnode.xpath('//integration_result')[-1]
        for key, label in tableData:
            correspondingData = integrationNode.get(key).split()
            imageCount = len(correspondingData)
            dataTuple = (label,correspondingData)
            dataTuples += (dataTuple,)
        dataTuples.insert(0, ('Image_number',[i for i in range(imageCount)]))
        for title, data in dataTuples:
            graph.addData(title=title, data=data)

        plot = graph.addPlotObject()
        plot.append('title','Beam positional variation across run')
        plot.append('plottype','xy')
        colors = ['red','green','blue','cyan','magenta','yellow','pink','orange','grey']
        for iLine in range(len(tableData)):
            color = colors[iLine%len(colors)]
            if tableData[iLine][0] in ['beam_x','beam_y']: plotLine = plot.append('plotline',xcol=1,ycol=iLine+2)
            else: plotLine = plot.append('plotline',xcol=1,ycol=iLine+2,ignore=True)
            plotLine.append('colour',color)

    def centralSpotProfile(self,parent=None):
        if parent is None: parent = self
        
        gallery = parent.addObjectGallery(height='270px',contentWidth='270px',style='float:left;width:400px;')
        
        profileNodes = self.xmlnode.xpath('//profile')
        iImage = 0
        
        drawingWidth=250
        drawingHeight=250
        
        firstOne = True
        for iProfile, profileNode in enumerate(profileNodes):
            dataDiv = gallery.addDrawnDiv(data=etree.tostring(profileNode),renderer="mosflm.profileRenderer",require='mosflm',initiallyDrawn=firstOne, title=str(iProfile))
            firstOne = False

    def crystalGraph(self, parent=None):
        if parent is None: parent = self
        graph = parent.addGraph(xmlnode=None, title='Hellow',style="width:260px;height:270px;")
        tableData = [("phi_x",u"\u03D5(x)"), ("phi_y",u"\u03D5(y)"), ("phi_z",u"\u03D5(z)"), ("cell_a",u"a"), ("cell_b","b"),("cell_c","c"),("cell_alpha",u"\u03B1"),("cell_beta",u"\u03B2"),("cell_gamma",u"\u0263"),("mosaicity","Mosaicity")]
        dataTuples = []
        imageCount = 0
        integrationNode = self.xmlnode.xpath('//integration_result')[-1]
        for key, label in tableData:
            try: correspondingData = integrationNode.get(key).split()
            except:
                print key
                break
            imageCount = len(correspondingData)
            dataTuple = (label,correspondingData)
            dataTuples += (dataTuple,)
        dataTuples.insert(0, ('Image_number',[i for i in range(imageCount)]))
        for title, data in dataTuples:
            graph.addData(title=title, data=data)
        
        plot = graph.addPlotObject()
        plot.append('title','Beam positional variation across run')
        plot.append('plottype','xy')
        colors = ['red','green','blue','cyan','magenta','yellow','pink','orange','grey']
        for iLine in range(len(tableData)):
            color = colors[iLine%len(colors)]
            if tableData[iLine][0] in ['phi_x','phi_y','phi_z','mosaicity']: plotLine = plot.append('plotline',xcol=1,ycol=iLine+2)
            else: plotLine = plot.append('plotline',xcol=1,ycol=iLine+2,ignore=True)
            plotLine.append('colour',color)

    def blockProfiles(self,parent=None):
        from lxml import etree
        if parent is None: parent = self
        
        gallery = parent.addObjectGallery(height='270px',contentWidth='270px',style='float:left;width:400px;')
        
        profileGridNodes = self.xmlnode.xpath('//profile_grid')
        firstOne = True
        for iProfileGridNode, profileGridNode in enumerate(profileGridNodes):
            dataDiv = gallery.addDrawnDiv(data=etree.tostring(profileGridNode),renderer='mosflm.profileGridRenderer',require='mosflm', initiallyDrawn=firstOne, title=str(iProfileGridNode))
            firstOne = False

    def dataGraph(self, parent=None):
        if parent is None: parent = self
        graph = parent.addGraph(xmlnode=None, title='Hellow',style="width:260px;height:270px;")
        tableData = [("mean_profile_fitted_fulls",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(prf,full)"),
                     ("mean_profile_fitted_partials",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(prf,partials)"),
                     ("mean_summation_integration_fulls",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(sum,full)"),
                     ("mean_summation_integration_partials",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(sum,partials)"),
                     ("total_spot_count_fulls",u"Reflections(full)"),
                     ("total_spot_count_partials",u"Reflections(partials)"),
                     ("outer_profile_fitted_fulls",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(prf,full)\u00A0HR"),
                     ("outer_profile_fitted_partials",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(prf,partials)\u00A0HR"),
                     ("outer_summation_integration_fulls",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(sum,full)\u00A0HR"),
                     ("outer_summation_integration_partials",u"\u003C\u00A0I\u002F\u03c3(I)\u003E(sum,partials)\u00A0HR"),
                     ("outer_spot_count_fulls",u"Reflections(full)\u00A0HR"),
                     ("outer_spot_count_partials",u"Reflections(partials)\u00A0HR"),
                     ]
        '''
            ("overloads_fulls",u"Overloads(full)\u00A0HR"),
            ("overloads_partials",u"Overloads(partials)\u00A0HR"),
            ("badspots_fulls",u"Bad\u00A0spots(full)\u00A0HR"),
            ("badspots_partials",u"Bad\u00A0spots(partials)\u00A0HR"),
            ("soverlaps_fulls",u"Spatial\u00A0overlaps(full)\u00A0HR"),
            ("soverlaps_partials",u"Spatial\u00A0overlaps(partials)\u00A0HR"),
        '''
        dataTuples = []
        imageCount = 0
        integrationNode = self.xmlnode.xpath('//integration_result')[-1]
        for key, label in tableData:
            try: correspondingData = integrationNode.get(key).split()
            except: print key
            imageCount = len(correspondingData)
            dataTuple = (label,correspondingData)
            dataTuples += (dataTuple,)
        dataTuples.insert(0, ('Image_number',[i for i in range(imageCount)]))
        for title, data in dataTuples:
            graph.addData(title=title, data=data)
        
        plot = graph.addPlotObject()
        plot.append('title','Data statistics')
        colors = ['red','green','blue','cyan','magenta','yellow','pink','orange','grey']
        for iLine in range(len(tableData)):
            color = colors[iLine%len(colors)]
            if tableData[iLine][0] in ['mean_profile_fitted_fulls']: plotLine = plot.append('plotline',xcol=1,ycol=iLine+2)
            else: plotLine = plot.append('plotline',xcol=1,ycol=iLine+2,ignore=True)
            plotLine.append('colour',color)

    def histograms(self,parent=None):
        from lxml import etree
        import math
        if parent is None: parent = self
        
        gallery = parent.addObjectGallery(height='270px',contentWidth='270px',style='float:left;width:400px;')
        integrationNode = self.xmlnode.xpath('//integration_result')[-1]
        histogramsText = integrationNode.get('histograms')
        histogramDataRows = histogramsText.split('}')
        collectedData = {}
        for histogramDataRow in histogramDataRows:
            try:
                imageName, histogramData = histogramDataRow.split(',')
                histogramType, dataText = histogramData.split('{')
                imageName = imageName.strip()
                histogramType=histogramType.strip()
                dataText=dataText.strip()
                #print '['+imageName+']['+histogramType+']['+dataText+']'
                if not imageName in collectedData:
                    collectedData[imageName]={}
                collectedData[imageName][histogramType] = dataText
                #print imageName, ' has ', data
            except Exception as e:
                pass
    
        imageNames = sorted([imageName for imageName in collectedData])
        firstOne = True
        for iImageName, imageName in enumerate(imageNames):
            imageHistograms = collectedData[imageName]
            graph = Graph(title=str(iImageName))
            resolutionNumbers = imageHistograms['bin_resolution_limits'].split()[1:-1]
            graph.addData(title='resolution', data=resolutionNumbers)
            coordinate = 2
            colors=['red','green','blue','cyan','magenta','yellow']
            for histogramLabels, plotTitle in [
                                               (['summation_integration_partials','summation_integration_fulls'],'Summation_integration'),
                                               (['profile_fitted_partials','profile_fitted_fulls'],'profile_fitted'),
                                               (['overloads_partials','overloads_fulls'],'overloads'),
                                               (['spot_count_partials','spot_count_fulls'],'spot_count'),
                                               (['soverlaps_partials','soverlaps_fulls'],'soverlaps'),
                                               ]:
                plotObject = graph.addPlotObject()
                plotObject.append('title',plotTitle)
                plotObject.append('plottype','xy')
                plotObject.append('xscale','oneoversqrt')
                plotObject.append('xintegral','false')
                for iHistogramLabel in range(len(histogramLabels)):
                    histogramLabel = histogramLabels[iHistogramLabel]
                    if histogramLabel in imageHistograms:
                        graph.addData(title = histogramLabel, data=imageHistograms[histogramLabel].split()[:-1])
                        plotLine = plotObject.append('plotline',xcol=1,ycol=coordinate,colour=colors[iHistogramLabel%len(colors)])
                        coordinate += 1
            graph.makeTableText()
            drawnDiv = gallery.addDrawnDiv(data=etree.tostring(graph.data_as_etree()),renderer="CCP4i2Widgets.CCP4i2Graph",require='CCP4i2Widgets',initiallyDrawn=firstOne, width='260px',  height='260px', title=str(iImageName))
            firstOne = False




            





