psocake/src/crystalIndexingPanel.py

Go to the documentation of this file.
00001 # Operates in two modes; interactive mode and batch mode
00002 # Interactive mode: temporary list, cxi, geom files are written per update
00003 # Batch mode: Creates a CXIDB file containing hits, turbo index the file, save single stream and delete CXIDB
00004 import numpy as np
00005 from pyqtgraph.Qt import QtCore, QtGui
00006 import subprocess
00007 import pandas as pd
00008 import h5py
00009 import pyqtgraph as pg
00010 from pyqtgraph.dockarea import *
00011 from pyqtgraph.parametertree import Parameter, ParameterTree
00012 import LaunchIndexer
00013 from PSCalib.CalibFileFinder import deploy_calib_file
00014 
00015 class CrystalIndexing(object):
00016     def __init__(self, parent = None):
00017         self.parent = parent
00018 
00019         ## Dock 14: Indexing
00020         self.d14 = Dock("Indexing", size=(1, 1))
00021         self.w21 = ParameterTree()
00022         self.w21.setWindowTitle('Indexing')
00023         self.d14.addWidget(self.w21)
00024         self.w22 = pg.LayoutWidget()
00025         self.launchIndexBtn = QtGui.QPushButton('Launch indexing')
00026         self.w22.addWidget(self.launchIndexBtn, row=0, col=0)
00027         self.synchBtn = QtGui.QPushButton('Deploy CrystFEL geometry')
00028         self.w22.addWidget(self.synchBtn, row=1, col=0)
00029         self.d14.addWidget(self.w22)
00030 
00031 
00032         self.index_grp = 'Crystal indexing'
00033         self.index_on_str = 'Indexing on'
00034         self.index_geom_str = 'CrystFEL geometry'
00035         self.index_peakMethod_str = 'Peak method'
00036         self.index_intRadius_str = 'Integration radii'
00037         self.index_pdb_str = 'PDB'
00038         self.index_method_str = 'Indexing method'
00039         #self.index_minPeaks_str = 'Minimum number of peaks'
00040         #self.index_maxPeaks_str = 'Maximum number of peaks'
00041         #self.index_minRes_str = 'Minimum resolution (pixels)'
00042         self.index_tolerance_str = 'Tolerance'
00043         self.index_extra_str = 'Extra CrystFEL parameters'
00044 
00045         self.launch_grp = 'Batch'
00046         self.outDir_str = 'Output directory'
00047         self.runs_str = 'Runs(s)'
00048         self.sample_str = 'Sample name'
00049         self.tag_str = 'Tag'
00050         self.queue_str = 'Queue'
00051         self.chunkSize_str = 'Chunk size'
00052         self.keepData_str = 'Keep CXI images'
00053         self.noe_str = 'Number of events to process'
00054         (self.psanaq_str,self.psnehq_str,self.psfehq_str,self.psnehprioq_str,self.psfehprioq_str,self.psnehhiprioq_str,self.psfehhiprioq_str,self.psdebugq_str) = \
00055             ('psanaq','psnehq','psfehq','psnehprioq','psfehprioq','psnehhiprioq','psfehhiprioq','psdebugq')
00056 
00057         self.outDir = self.parent.psocakeDir
00058         self.outDir_overridden = False
00059         self.runs = ''
00060         self.sample = 'crystal'
00061         self.tag = ''
00062         self.queue = self.psanaq_str
00063         self.chunkSize = 500
00064         self.noe = -1
00065 
00066         # Indexing
00067         self.showIndexedPeaks = False
00068         self.indexedPeaks = None
00069         self.hiddenCXI = '.temp.cxi'
00070         self.hiddenCrystfelStream = '.temp.stream'
00071         self.hiddenCrystfelList = '.temp.lst'
00072 
00073         self.indexingOn = False
00074         self.numIndexedPeaksFound = 0
00075         self.geom = '.temp.geom'
00076         self.peakMethod = 'cxi'
00077         self.intRadius = '2,3,4'
00078         self.pdb = ''
00079         self.indexingMethod = 'mosflm-noretry,dirax'
00080         #self.minPeaks = 15
00081         #self.maxPeaks = 2048
00082         #self.minRes = 0
00083         self.tolerance = '5,5,5,1.5'
00084         self.extra = ''
00085         self.keepData = True
00086 
00087         #######################
00088         # Mandatory parameter #
00089         #######################
00090         self.params = [
00091             {'name': self.index_grp, 'type': 'group', 'children': [
00092                 {'name': self.index_on_str, 'type': 'bool', 'value': self.indexingOn, 'tip': "Turn on indexing"},
00093                 {'name': self.index_geom_str, 'type': 'str', 'value': self.geom, 'tip': "CrystFEL geometry file"},
00094                 #{'name': self.index_peakMethod_str, 'type': 'str', 'value': self.peakMethod, 'tip': "Turn on indexing"},
00095                 {'name': self.index_intRadius_str, 'type': 'str', 'value': self.intRadius, 'tip': "Integration radii"},
00096                 {'name': self.index_pdb_str, 'type': 'str', 'value': self.pdb, 'tip': "(Optional) CrystFEL unitcell file"},
00097                 {'name': self.index_method_str, 'type': 'str', 'value': self.indexingMethod, 'tip': "comma separated indexing methods"},
00098                 {'name': self.index_tolerance_str, 'type': 'str', 'value': self.tolerance,
00099                  'tip': "Indexing tolerance, default: 5,5,5,1.5"},
00100                 {'name': self.index_extra_str, 'type': 'str', 'value': self.extra,
00101                  'tip': "Other indexing parameters"},
00102                 #{'name': self.index_minPeaks_str, 'type': 'int', 'value': self.minPeaks,
00103                 # 'tip': "Index only if there are more Bragg peaks found"},
00104                 #{'name': self.index_maxPeaks_str, 'type': 'int', 'value': self.maxPeaks,
00105                 # 'tip': "Index only if there are less Bragg peaks found"},
00106                 #{'name': self.index_minRes_str, 'type': 'int', 'value': self.minRes,
00107                 # 'tip': "Index only if Bragg peak resolution is at least this"},
00108             ]},
00109             {'name': self.launch_grp, 'type': 'group', 'children': [
00110                 {'name': self.outDir_str, 'type': 'str', 'value': self.outDir},
00111                 {'name': self.runs_str, 'type': 'str', 'value': self.runs, 'tip': "comma separated or use colon for a range, e.g. 1,3,5:7 = runs 1,3,5,6,7"},
00112                 {'name': self.sample_str, 'type': 'str', 'value': self.sample, 'tip': "name of the sample saved in the cxidb file, e.g. lysozyme"},
00113                 {'name': self.tag_str, 'type': 'str', 'value': self.tag, 'tip': "attach tag to stream, e.g. cxitut13_0010_tag.stream"},
00114                 {'name': self.queue_str, 'type': 'list', 'values': {self.psfehhiprioq_str: self.psfehhiprioq_str,
00115                                                                self.psnehhiprioq_str: self.psnehhiprioq_str,
00116                                                                self.psfehprioq_str: self.psfehprioq_str,
00117                                                                self.psnehprioq_str: self.psnehprioq_str,
00118                                                                self.psfehq_str: self.psfehq_str,
00119                                                                self.psnehq_str: self.psnehq_str,
00120                                                                self.psanaq_str: self.psanaq_str,
00121                                                                self.psdebugq_str: self.psdebugq_str},
00122                  'value': self.queue, 'tip': "Choose queue"},
00123                 {'name': self.chunkSize_str, 'type': 'int', 'value': self.chunkSize, 'tip': "number of patterns to process per worker"},
00124                 {'name': self.keepData_str, 'type': 'bool', 'value': self.keepData, 'tip': "Do not delete cxidb images in cxi file"},
00125             ]},
00126         ]
00127 
00128         self.p9 = Parameter.create(name='paramsCrystalIndexing', type='group', \
00129                                    children=self.params, expanded=True)
00130         self.w21.setParameters(self.p9, showTop=False)
00131         self.p9.sigTreeStateChanged.connect(self.change)
00132 
00133         self.parent.connect(self.launchIndexBtn, QtCore.SIGNAL("clicked()"), self.indexPeaks)
00134         self.parent.connect(self.synchBtn, QtCore.SIGNAL("clicked()"), self.syncGeom)
00135 
00136     # Launch indexing
00137     def indexPeaks(self):
00138         self.parent.thread.append(LaunchIndexer.LaunchIndexer(self.parent))  # send parent parameters with self
00139         self.parent.thread[self.parent.threadCounter].launch(self.parent.experimentName, self.parent.detInfo)
00140         self.parent.threadCounter += 1
00141 
00142     # Update psana geometry
00143     def syncGeom(self):
00144         with pg.BusyCursor():
00145             print "#################################################"
00146             print "Updating psana geometry with CrystFEL geometry"
00147             print "#################################################"
00148             self.parent.geom.findPsanaGeometry()
00149             psanaGeom = self.parent.psocakeRunDir + "/.temp.data"
00150             if self.parent.args.localCalib:
00151                 cmd = ["crystfel2psana",
00152                        "-e", self.parent.experimentName,
00153                        "-r", str(self.parent.runNumber),
00154                        "-d", str(self.parent.det.name),
00155                        "--rootDir", '.',
00156                        "-c", self.geom,
00157                        "-p", psanaGeom,
00158                        "-z", str(self.parent.clen)]
00159             else:
00160                 cmd = ["crystfel2psana",
00161                        "-e", self.parent.experimentName,
00162                        "-r", str(self.parent.runNumber),
00163                        "-d", str(self.parent.det.name),
00164                        "--rootDir", self.parent.rootDir,
00165                        "-c", self.geom,
00166                        "-p", psanaGeom,
00167                        "-z", str(self.parent.clen)]
00168             if self.parent.args.v >= 0: print "cmd: ", cmd
00169             p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
00170             output = p.communicate()[0]
00171             p.stdout.close()
00172             # Reload new psana geometry
00173             cmts = {'exp': self.parent.experimentName, 'app': 'psocake', 'comment': 'converted from crystfel geometry'}
00174             if self.parent.args.localCalib:
00175                 calibDir = './calib'
00176             elif self.parent.args.outDir is None:
00177                 calibDir = self.parent.rootDir + '/calib'
00178             else:
00179                 calibDir = '/reg/d/psdm/' + self.parent.experimentName[:3] + '/' + self.parent.experimentName + '/calib'
00180             deploy_calib_file(cdir=calibDir, src=str(self.parent.det.name), type='geometry',
00181                               run_start=self.parent.runNumber, run_end=None, ifname=psanaGeom, dcmts=cmts, pbits=0)
00182             self.parent.exp.setupExperiment()
00183             self.parent.img.getDetImage(self.parent.eventNumber)
00184             self.parent.geom.updateRings()
00185             self.parent.index.updateIndex()
00186             self.parent.geom.drawCentre()
00187 
00188     # If anything changes in the parameter tree, print a message
00189     def change(self, panel, changes):
00190         for param, change, data in changes:
00191             path = panel.childPath(param)
00192             if self.parent.args.v >= 1:
00193                 print('  path: %s' % path)
00194                 print('  change:    %s' % change)
00195                 print('  data:      %s' % str(data))
00196                 print('  ----------')
00197             self.paramUpdate(path, change, data)
00198 
00199     ##############################
00200     # Mandatory parameter update #
00201     ##############################
00202     def paramUpdate(self, path, change, data):
00203         if path[1] == self.index_on_str:
00204             self.updateIndexStatus(data)
00205         elif path[1] == self.index_geom_str:
00206             self.updateGeom(data)
00207         elif path[1] == self.index_peakMethod_str:
00208             self.updatePeakMethod(data)
00209         elif path[1] == self.index_intRadius_str:
00210             self.updateIntegrationRadius(data)
00211         elif path[1] == self.index_pdb_str:
00212             self.updatePDB(data)
00213         elif path[1] == self.index_method_str:
00214             self.updateIndexingMethod(data)
00215         #elif path[1] == self.index_minPeaks_str:
00216         #    self.updateMinPeaks(data)
00217         #elif path[1] == self.index_maxPeaks_str:
00218         #    self.updateMaxPeaks(data)
00219         #elif path[1] == self.index_minRes_str:
00220         #    self.updateMinRes(data)
00221         elif path[1] == self.index_tolerance_str:
00222             self.updateTolerance(data)
00223         elif path[1] == self.index_extra_str:
00224             self.updateExtra(data)
00225         # launch grp
00226         elif path[1] == self.outDir_str:
00227             self.updateOutputDir(data)
00228         elif path[1] == self.runs_str:
00229             self.updateRuns(data)
00230         elif path[1] == self.sample_str:
00231             self.updateSample(data)
00232         elif path[1] == self.tag_str:
00233             self.updateTag(data)
00234         elif path[1] == self.queue_str:
00235             self.updateQueue(data)
00236         elif path[1] == self.chunkSize_str:
00237             self.updateChunkSize(data)
00238         elif path[1] == self.noe_str:
00239             self.updateNoe(data)
00240         elif path[1] == self.keepData_str:
00241             self.keepData = data
00242 
00243     def updateIndexStatus(self, data):
00244         self.indexingOn = data
00245         self.showIndexedPeaks = data
00246         self.updateIndex()
00247 
00248     def updateGeom(self, data):
00249         self.geom = data
00250         self.updateIndex()
00251 
00252     def updatePeakMethod(self, data):
00253         self.peakMethod = data
00254         if self.indexingOn:
00255             self.updateIndex()
00256 
00257     def updateIntegrationRadius(self, data):
00258         self.intRadius = data
00259         self.updateIndex()
00260 
00261     def updatePDB(self, data):
00262         self.pdb = data
00263         self.updateIndex()
00264 
00265     def updateIndexingMethod(self, data):
00266         self.indexingMethod = data
00267         self.updateIndex()
00268 
00269     #def updateMinPeaks(self, data):
00270     #    self.minPeaks = data
00271     #    self.updateIndex()
00272 
00273     #def updateMaxPeaks(self, data):
00274     #    self.maxPeaks = data
00275     #    self.updateIndex()
00276 
00277     #def updateMinRes(self, data):
00278     #    self.minRes = data
00279     #    self.updateIndex()
00280 
00281     def updateTolerance(self, data):
00282         self.tolerance = data
00283         self.updateIndex()
00284 
00285     def updateExtra(self, data):
00286         self.extra = data
00287         self.updateIndex()
00288 
00289     def updateIndex(self):
00290         if self.indexingOn:
00291             self.indexer = IndexHandler(parent=self.parent)
00292             self.indexer.computeIndex(self.parent.experimentName, self.parent.runNumber, self.parent.detInfo,
00293                                       self.parent.eventNumber, self.geom, self.peakMethod, self.intRadius, self.pdb,
00294                                       self.indexingMethod, self.parent.pk.minPeaks, self.parent.pk.maxPeaks, self.parent.pk.minRes,
00295                                       self.tolerance, self.extra, self.outDir, queue=None)
00296 
00297     def updateOutputDir(self, data):
00298         self.outDir = data
00299         self.outDir_overridden = True
00300 
00301     def updateRuns(self, data):
00302         self.runs = data
00303 
00304     def updateSample(self, data):
00305         self.sample = data
00306 
00307     def updateTag(self, data):
00308         self.tag = data
00309 
00310     def updateQueue(self, data):
00311         self.queue = data
00312 
00313     def updateChunkSize(self, data):
00314         self.chunkSize = data
00315 
00316     def updateNoe(self, data):
00317         self.noe = data
00318 
00319     def clearIndexedPeaks(self):
00320         self.parent.img.w1.getView().removeItem(self.parent.img.abc_text)
00321         self.parent.img.indexedPeak_feature.setData([], [], pxMode=False)
00322         if self.parent.args.v >= 1: print "Done clearIndexedPeaks"
00323 
00324     def displayWaiting(self):
00325         if self.showIndexedPeaks:
00326             if self.numIndexedPeaksFound == 0:  # indexing proceeding
00327                 xMargin = 5  # pixels
00328                 maxX = np.max(self.parent.det.indexes_x(self.parent.evt)) + xMargin
00329                 maxY = np.max(self.parent.det.indexes_y(self.parent.evt))
00330                 # Draw a big X
00331                 cenX = np.array((self.parent.cx,)) + 0.5
00332                 cenY = np.array((self.parent.cy,)) + 0.5
00333                 diameter = 256  # self.peakRadius*2+1
00334                 self.parent.img.indexedPeak_feature.setData(cenX, cenY, symbol='t', \
00335                                                             size=diameter, brush=(255, 255, 255, 0), \
00336                                                             pen=pg.mkPen({'color': "#FF00FF", 'width': 3}),
00337                                                             pxMode=False)
00338                 self.parent.img.abc_text = pg.TextItem(html='', anchor=(0, 0))
00339                 self.parent.img.w1.getView().addItem(self.parent.img.abc_text)
00340                 self.parent.img.abc_text.setPos(maxX, maxY)
00341 
00342     def drawIndexedPeaks(self, latticeType=None, centering=None, numSaturatedPeaks=None, unitCell=None):
00343         self.clearIndexedPeaks()
00344         if self.showIndexedPeaks:
00345             if self.indexedPeaks is not None and self.numIndexedPeaksFound > 0: # indexing succeeded
00346                 cenX = self.indexedPeaks[:,0]+0.5
00347                 cenY = self.indexedPeaks[:,1]+0.5
00348                 cenX = np.concatenate((cenX,cenX,cenX))
00349                 cenY = np.concatenate((cenY,cenY,cenY))
00350                 diameter = np.ones_like(cenX)
00351                 diameter[0:self.numIndexedPeaksFound] = float(self.intRadius.split(',')[0])*2
00352                 diameter[self.numIndexedPeaksFound:2*self.numIndexedPeaksFound] = float(self.intRadius.split(',')[1])*2
00353                 diameter[2*self.numIndexedPeaksFound:3*self.numIndexedPeaksFound] = float(self.intRadius.split(',')[2])*2
00354                 self.parent.img.indexedPeak_feature.setData(cenX, cenY, symbol='o', \
00355                                           size=diameter, brush=(255,255,255,0), \
00356                                           pen=pg.mkPen({'color': "#FF00FF", 'width': 1.5}), pxMode=False)
00357 
00358                 # Write unit cell parameters
00359                 if unitCell is not None:
00360                     xMargin = 5
00361                     yMargin = 400
00362                     maxX   = np.max(self.parent.det.indexes_x(self.parent.evt)) + xMargin
00363                     maxY   = np.max(self.parent.det.indexes_y(self.parent.evt)) - yMargin
00364                     myMessage = '<div style="text-align: center"><span style="color: #FF00FF; font-size: 12pt;">lattice='+\
00365                                 latticeType +'<br>centering=' + centering + '<br>a='+\
00366                                 str(round(float(unitCell[0])*10,2))+'A <br>b='+str(round(float(unitCell[1])*10,2))+'A <br>c='+\
00367                                 str(round(float(unitCell[2])*10,2))+'A <br>&alpha;='+str(round(float(unitCell[3]),2))+\
00368                                 '&deg; <br>&beta;='+str(round(float(unitCell[4]),2))+'&deg; <br>&gamma;='+\
00369                                 str(round(float(unitCell[5]),2))+'&deg; <br></span></div>'
00370 
00371                     self.parent.img.abc_text = pg.TextItem(html=myMessage, anchor=(0,0))
00372                     self.parent.img.w1.getView().addItem(self.parent.img.abc_text)
00373                     self.parent.img.abc_text.setPos(maxX, maxY)
00374             else: # Failed indexing
00375                 xMargin = 5 # pixels
00376                 maxX   = np.max(self.parent.det.indexes_x(self.parent.evt))+xMargin
00377                 maxY   = np.max(self.parent.det.indexes_y(self.parent.evt))
00378                 # Draw a big X
00379                 cenX = np.array((self.parent.cx,))+0.5
00380                 cenY = np.array((self.parent.cy,))+0.5
00381                 diameter = 256 #self.peakRadius*2+1
00382                 self.parent.img.indexedPeak_feature.setData(cenX, cenY, symbol='x', \
00383                                           size=diameter, brush=(255,255,255,0), \
00384                                           pen=pg.mkPen({'color': "#FF00FF", 'width': 3}), pxMode=False)
00385                 self.parent.img.abc_text = pg.TextItem(html='', anchor=(0,0))
00386                 self.parent.img.w1.getView().addItem(self.parent.img.abc_text)
00387                 self.parent.img.abc_text.setPos(maxX,maxY)
00388         else:
00389             self.parent.img.indexedPeak_feature.setData([], [], pxMode=False)
00390         if self.parent.args.v >= 1: print "Done updatePeaks"
00391 
00392     # This function probably doesn't get called
00393     def launchIndexing(self, requestRun=None):
00394         self.batchIndexer = IndexHandler(parent=self.parent)
00395         if requestRun is None:
00396             self.batchIndexer.computeIndex(self.parent.experimentName, self.parent.runNumber, self.parent.detInfo,
00397                                   self.parent.eventNumber, self.geom, self.peakMethod, self.intRadius, self.pdb,
00398                                        self.indexingMethod, self.parent.pk.minPeaks, self.parent.pk.maxPeaks, self.parent.pk.minRes,
00399                                            self.tolerance, self.extra, self.outDir, self.runs, self.sample, self.tag, self.queue, self.chunkSize, self.noe)
00400         else:
00401             self.batchIndexer.computeIndex(self.parent.experimentName, requestRun, self.parent.detInfo,
00402                                   self.parent.eventNumber, self.geom, self.peakMethod, self.intRadius, self.pdb,
00403                                        self.indexingMethod, self.parent.pk.minPeaks, self.parent.pk.maxPeaks, self.parent.pk.minRes,
00404                                            self.tolerance, self.extra, self.outDir, self.runs, self.sample, self.tag, self.queue, self.chunkSize, self.noe)
00405         if self.parent.args.v >= 1: print "Done updateIndex"
00406 
00407 class IndexHandler(QtCore.QThread):
00408     def __init__(self, parent = None):
00409         QtCore.QThread.__init__(self, parent)
00410         self.parent = parent
00411         self.experimentName = None
00412         self.runNumber = None
00413         self.detInfo = None
00414         self.eventNumber = None
00415         self.geom = None
00416         self.peakMethod = None
00417         self.intRadius = None
00418         self.pdb = None
00419         self.indexingMethod = None
00420         self.latticeType = None
00421         self.centering = None
00422         self.numSaturatedPeaks = None
00423         self.unitCell = None
00424         self.minPeaks = None
00425         self.maxPeaks = None
00426         self.minRes = None
00427         # batch
00428         self.outDir = None
00429         self.runs = None
00430         self.sample = None
00431         self.tag = None
00432         self.queue = None
00433         self.chunkSize = None
00434         self.noe = None
00435 
00436     def __del__(self):
00437         if self.parent.args.v >= 1: print "del IndexHandler"
00438         self.exiting = True
00439         self.wait()
00440 
00441     def computeIndex(self, experimentName, runNumber, detInfo, eventNumber, geom, peakMethod, intRadius, pdb, indexingMethod,
00442                      minPeaks, maxPeaks, minRes, tolerance, extra, outDir=None, runs=None, sample=None, tag=None, queue=None,
00443                      chunkSize=None, noe=None):
00444         self.experimentName = experimentName
00445         self.runNumber = runNumber
00446         self.detInfo = detInfo
00447         self.eventNumber = eventNumber
00448         self.geom = geom
00449         self.peakMethod = peakMethod
00450         self.intRadius = intRadius
00451         self.pdb = pdb
00452         self.indexingMethod = indexingMethod
00453         self.minPeaks = minPeaks
00454         self.maxPeaks = maxPeaks
00455         self.minRes = minRes
00456         self.tolerance = tolerance
00457         self.extra = extra
00458         # batch
00459         self.outDir = outDir
00460         self.runs = runs
00461         self.sample = sample
00462         self.tag = tag
00463         self.queue = queue
00464         self.chunkSize = chunkSize
00465         self.noe = noe
00466 
00467         if self.geom is not '':
00468             self.start()
00469 
00470     def getMyUnfairShare(self, numJobs, numWorkers, rank):
00471         """Returns number of events assigned to the slave calling this function."""
00472         assert(numJobs >= numWorkers)
00473         allJobs = np.arange(numJobs)
00474         jobChunks = np.array_split(allJobs,numWorkers)
00475         myChunk = jobChunks[rank]
00476         myJobs = allJobs[myChunk[0]:myChunk[-1]+1]
00477         return myJobs
00478 
00479     def getIndexedPeaks(self):
00480         # Merge all stream files into one
00481         totalStream = self.outDir+"/r"+str(self.runNumber).zfill(4)+"/"+self.experimentName+"_"+str(self.runNumber).zfill(4)+".stream"
00482         with open(totalStream, 'w') as outfile:
00483             for fname in self.myStreamList:
00484                 try:
00485                     with open(fname) as infile:
00486                         outfile.write(infile.read())
00487                 except: # file may not exist yet
00488                     continue
00489 
00490         # Add indexed peaks and remove images in hdf5
00491         f = h5py.File(self.peakFile,'r')
00492         totalEvents = len(f['/entry_1/result_1/nPeaksAll'])
00493         hitEvents = f['/LCLS/eventNumber'].value
00494         f.close()
00495         # Add indexed peaks
00496         fstream = open(totalStream,'r')
00497         content=fstream.readlines()
00498         fstream.close()
00499         indexedPeaks = np.zeros((totalEvents,),dtype=int)
00500         numProcessed = 0
00501         for i,val in enumerate(content):
00502             if "Event: //" in val:
00503                 _evt = int(val.split("Event: //")[-1].strip())
00504             if "indexed_by =" in val:
00505                 _ind = val.split("indexed_by =")[-1].strip()
00506             if "num_peaks =" in val:
00507                 _num = val.split("num_peaks =")[-1].strip()
00508                 numProcessed += 1
00509                 if 'none' in _ind:
00510                     continue
00511                 else:
00512                     indexedPeaks[hitEvents[_evt]] = _num
00513         return indexedPeaks, numProcessed
00514 
00515     def checkJobExit(self, jobID):
00516         cmd = "bjobs -d | grep "+str(jobID)
00517         process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
00518         out, err = process.communicate()
00519         if "EXIT" in out:
00520             "*********** NODE FAILURE ************ ", jobID
00521             return 1
00522         else:
00523             return 0
00524 
00525     def run(self):
00526         if self.queue is None: # interactive indexing
00527             # Check if requirements are met for indexing
00528             if self.parent.pk.numPeaksFound >= self.minPeaks and \
00529                 self.parent.pk.numPeaksFound <= self.maxPeaks and \
00530                 self.parent.pk.peaksMaxRes >= self.minRes:
00531                 print "OK, I'll index this pattern now"
00532 
00533                 if self.parent.args.v >= 1: print "Running indexing!!!!!!!!!!!!"
00534                 # Running indexing ...
00535                 self.parent.index.numIndexedPeaksFound = 0
00536                 self.parent.index.indexedPeaks = None
00537                 self.parent.index.clearIndexedPeaks()
00538                 self.parent.index.displayWaiting()
00539 
00540                 # Write list
00541                 with open(self.parent.index.hiddenCrystfelList, "w") as text_file:
00542                     text_file.write("{} //0".format(self.parent.index.hiddenCXI))
00543 
00544                 # FIXME: convert psana geom to crystfel geom
00545                 cmd = "indexamajig -j 1 -i " + self.parent.index.hiddenCrystfelList + " -g " + self.geom + " --peaks=" + self.peakMethod + \
00546                       " --int-radius=" + self.intRadius + " --indexing=" + self.indexingMethod + \
00547                       " -o " + self.parent.index.hiddenCrystfelStream + " --temp-dir=" + self.outDir + "/r" + str(
00548                       self.runNumber).zfill(4) + " --tolerance=" + str(self.tolerance)
00549                 if self.pdb: cmd += " --pdb=" + self.pdb
00550                 if self.extra: cmd += " " + self.extra
00551 
00552                 print "cmd: ", cmd
00553                 process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
00554                 out, err = process.communicate()
00555 
00556                 mySuccessString = "1 had crystals"
00557                 # Read CrystFEL CSPAD geometry in stream
00558                 if mySuccessString in err:  # success
00559                     if self.parent.args.v >= 1: print "Indexing successful"
00560                     # print "Munging geometry file"
00561                     f = open(self.parent.index.hiddenCrystfelStream)
00562                     content = f.readlines()
00563                     for i, val in enumerate(content):
00564                         if '----- Begin geometry file -----' in val:
00565                             startLine = i
00566                         elif '----- End geometry file -----' in val:
00567                             endLine = i
00568                             break
00569                     geom = content[startLine:endLine]
00570                     numLines = endLine - startLine
00571                     # Remove comments
00572                     for i in np.arange(numLines - 1, -1, -1):  # Start from bottom
00573                         if ';' in geom[i].lstrip(' ')[0]: geom.pop(i)
00574 
00575                     columns = ['min_fs', 'min_ss', 'max_fs', 'max_ss', 'res', 'fs', 'ss', 'corner_x', 'corner_y']
00576                     columnsScan = ['fsx', 'fsy', 'ssx', 'ssy']
00577                     indexScan = []
00578                     if 'cspad' in self.parent.detInfo.lower():
00579                         numQuads = 4
00580                         numAsics = 16
00581                         for i in np.arange(numQuads):
00582                             for j in np.arange(numAsics):
00583                                 indexScan.append('q' + str(i) + 'a' + str(j))
00584                     elif 'rayonix' in self.parent.detInfo.lower():
00585                         numQuads = 1
00586                         numAsics = 1
00587                         for i in np.arange(numQuads):
00588                                 indexScan.append('p' + str(i))
00589 
00590                     dfGeom = pd.DataFrame(np.empty((numQuads * numAsics, len(columns))), index=indexScan,
00591                                           columns=columns)
00592                     dfScan = pd.DataFrame(np.empty((numQuads * numAsics, len(columnsScan))), index=indexScan,
00593                                           columns=columnsScan)
00594                     counter = 0
00595                     for i in np.arange(numQuads):
00596                         for j in np.arange(numAsics):
00597                             myAsic = indexScan[counter]
00598                             for k in columns:
00599                                 myLine = [s for s in geom if myAsic + '/' + k in s]
00600                                 if myLine:  # sometimes elements in columns can be missing
00601                                     myVal = myLine[-1].split('=')[-1].rstrip().lstrip()
00602                                     if k == 'fs' or k == 'ss':
00603                                         dfGeom.loc[myAsic, k] = myVal
00604                                     else:
00605                                         dfGeom.loc[myAsic, k] = float(myVal)
00606                                     if k == 'fs':
00607                                         fsx = float(myVal.split('x')[0])
00608                                         fsy = float(myVal.split('x')[-1].split('y')[0])
00609                                         dfScan.loc[myAsic, 'fsx'] = fsx
00610                                         dfScan.loc[myAsic, 'fsy'] = fsy
00611                                     elif k == 'ss':
00612                                         ssx = float(myVal.split('x')[0])
00613                                         ssy = float(myVal.split('x')[-1].split('y')[0])
00614                                         dfScan.loc[myAsic, 'ssx'] = ssx
00615                                         dfScan.loc[myAsic, 'ssy'] = ssy
00616                                 else:
00617                                     if self.parent.args.v >= 1: print myAsic + '/' + k + " doesn't exist"
00618                             counter += 1
00619                     f.close()
00620                 else:
00621                     if self.parent.args.v >= 1: print "Indexing failed"
00622                     self.parent.index.drawIndexedPeaks()
00623 
00624                 # Read CrystFEL indexed peaks
00625                 if mySuccessString in err:  # success
00626                     f = open(self.parent.index.hiddenCrystfelStream)
00627                     content = f.readlines()
00628                     for i, val in enumerate(content):
00629                         if 'End of peak list' in val:
00630                             endLine = i-1
00631                         elif 'num_saturated_peaks =' in val:
00632                             self.numSaturatedPeaks = int(val.split('=')[-1])
00633                         elif 'lattice_type =' in val:
00634                             self.latticeType = val.split('=')[-1]
00635                         elif 'centering =' in val:
00636                             self.centering = val.split('=')[-1]
00637                         elif 'fs/px   ss/px (1/d)/nm^-1   Intensity  Panel' in val:
00638                             startLine = i + 1
00639                         elif 'Cell parameters' in val:
00640                             (_, _, a, b, c, _, al, be, ga, _) = val.split()
00641                             self.unitCell = (a, b, c, al, be, ga)
00642                         elif 'diffraction_resolution_limit =' in val:
00643                             (_, _, _, _, _, resLim, _) = val.split() # Angstrom
00644                         elif 'End of reflections' in val:
00645                             endReflectionLine = i-1
00646                         elif '   h    k    l          I   sigma(I)       peak background  fs/px  ss/px panel' in val:
00647                             startReflectionLine = i+1
00648 
00649                     numPeaks = endLine-startLine
00650                     numReflections = endReflectionLine-startReflectionLine
00651 
00652                     #print "numReflections: ", numPeaks, numReflections
00653 
00654                     columns = ['fs', 'ss', 'res', 'intensity', 'asic']
00655                     df = pd.DataFrame(np.empty((numPeaks, len(columns))), columns=columns)
00656                     for i in np.arange(numPeaks):
00657                         contentLine = startLine + i
00658                         df['fs'][i] = float(content[contentLine][0:7])
00659                         df['ss'][i] = float(content[contentLine][7:15])
00660                         df['res'][i] = float(content[contentLine][15:26])
00661                         df['intensity'][i] = float(content[contentLine][26:38])
00662                         df['asic'][i] = str(content[contentLine][38:-1])
00663 
00664                     if numReflections > 0:
00665                         columns = ['h', 'k', 'l', 'I', 'sigma', 'peak', 'background', 'fs', 'ss', 'panel']
00666                         dfRefl = pd.DataFrame(np.empty((numReflections, len(columns))), columns=columns)
00667                         for i in np.arange(numReflections):
00668                             contentLine = startReflectionLine + i
00669                             dfRefl['h'][i] = float(content[contentLine][0:4])
00670                             dfRefl['k'][i] = float(content[contentLine][4:9])
00671                             dfRefl['l'][i] = float(content[contentLine][9:14])
00672                             dfRefl['I'][i] = float(content[contentLine][14:25])
00673                             dfRefl['sigma'][i] = str(content[contentLine][25:36])
00674                             dfRefl['peak'][i] = float(content[contentLine][36:47])
00675                             dfRefl['background'][i] = float(content[contentLine][47:58])
00676                             dfRefl['fs'][i] = float(content[contentLine][58:65])
00677                             dfRefl['ss'][i] = float(content[contentLine][65:72])
00678                             dfRefl['panel'][i] = str(content[contentLine][72:-1])
00679                     f.close()
00680 
00681                     # #Convert to CrystFEL coordinates
00682                     # columnsPeaks = ['x', 'y', 'psocakeX', 'psocakeY']
00683                     # dfPeaks = pd.DataFrame(np.empty((numPeaks, len(columnsPeaks))), columns=columnsPeaks)
00684                     # for i in np.arange(numPeaks):
00685                     #    myAsic = df['asic'][i].strip()
00686                     #    x = (df['fs'][i] - dfGeom.loc[myAsic, 'min_fs']) * dfScan.loc[myAsic, 'fsx'] + (df['ss'][i] -
00687                     #                                                                                    dfGeom.loc[
00688                     #                                                                                        myAsic, 'min_ss']) * \
00689                     #                                                                                   dfScan.loc[
00690                     #                                                                                       myAsic, 'ssx']
00691                     #    x += dfGeom.loc[myAsic, 'corner_x']
00692                     #    y = (df['fs'][i] - dfGeom.loc[myAsic, 'min_fs']) * dfScan.loc[myAsic, 'fsy'] + (df['ss'][i] -
00693                     #                                                                                    dfGeom.loc[
00694                     #                                                                                        myAsic, 'min_ss']) * \
00695                     #                                                                                   dfScan.loc[
00696                     #                                                                                       myAsic, 'ssy']
00697                     #    y += dfGeom.loc[myAsic, 'corner_y']
00698                     #    dfPeaks['x'][i] = x
00699                     #    dfPeaks['y'][i] = y
00700                     #
00701                     # # Convert to psocake coordinates
00702                     # for i in np.arange(numPeaks): # numPeaks
00703                     #     dfPeaks['psocakeX'][i] = self.parent.cx - dfPeaks['x'][i]
00704                     #     dfPeaks['psocakeY'][i] = self.parent.cy + dfPeaks['y'][i]
00705                     #
00706                     # if self.parent.index.showIndexedPeaks and self.eventNumber == self.parent.eventNumber:
00707                     #     self.parent.index.numIndexedPeaksFound = numPeaks
00708                     #     self.parent.index.indexedPeaks = dfPeaks[['psocakeX', 'psocakeY']].as_matrix()
00709                     #     self.parent.index.drawIndexedPeaks(self.unitCell)
00710 
00711                     # Convert predicted spots to CrystFEL coordinates
00712                     columnsPeaks = ['x', 'y', 'psocakeX', 'psocakeY']
00713                     dfPeaks = pd.DataFrame(np.empty((numReflections, len(columnsPeaks))), columns=columnsPeaks)
00714                     for i in np.arange(numReflections):
00715                         myAsic = dfRefl['panel'][i].strip()
00716                         x = (dfRefl['fs'][i] - dfGeom.loc[myAsic, 'min_fs']) * dfScan.loc[myAsic, 'fsx'] + (dfRefl['ss'][i] -
00717                                                                                                         dfGeom.loc[
00718                                                                                                             myAsic, 'min_ss']) * \
00719                                                                                                        dfScan.loc[
00720                                                                                                            myAsic, 'ssx']
00721                         x += dfGeom.loc[myAsic, 'corner_x']
00722                         y = (dfRefl['fs'][i] - dfGeom.loc[myAsic, 'min_fs']) * dfScan.loc[myAsic, 'fsy'] + (dfRefl['ss'][i] -
00723                                                                                                         dfGeom.loc[
00724                                                                                                             myAsic, 'min_ss']) * \
00725                                                                                                        dfScan.loc[
00726                                                                                                            myAsic, 'ssy']
00727                         y += dfGeom.loc[myAsic, 'corner_y']
00728                         dfPeaks['x'][i] = x
00729                         dfPeaks['y'][i] = y
00730 
00731                     # Convert to psocake coordinates
00732                     for i in np.arange(numReflections):
00733                         dfPeaks['psocakeX'][i] = self.parent.cx - dfPeaks['x'][i]
00734                         dfPeaks['psocakeY'][i] = self.parent.cy + dfPeaks['y'][i]
00735 
00736                     if self.parent.index.showIndexedPeaks and self.eventNumber == self.parent.eventNumber:
00737                         self.parent.index.numIndexedPeaksFound = numReflections
00738                         self.parent.index.indexedPeaks = dfPeaks[['psocakeX', 'psocakeY']].as_matrix()
00739                         self.parent.index.drawIndexedPeaks(self.latticeType, self.centering, self.numSaturatedPeaks, self.unitCell)
00740             else:
00741                 print "Indexing requirement not met."
00742                 if self.parent.pk.numPeaksFound < self.minPeaks: print "Decrease minimum number of peaks"
00743                 if self.parent.pk.numPeaksFound > self.maxPeaks: print "Increase maximum number of peaks"
00744                 if self.parent.pk.peaksMaxRes < self.minRes: print "Decrease minimum resolution"
00745 
00746 
00747 

Generated on 19 Dec 2016 for PSDMSoftware by  doxygen 1.4.7