def createStarFile(self, starfile, mrcStackFile): ''' Create a file with the required constant strings in it ''' star = starFile.StarFile(starfile) labels = [ '_rlnImageName', '_rlnMicrographName', '_rlnDefocusU', '_rlnDefocusV', '_rlnDefocusAngle', '_rlnVoltage', '_rlnSphericalAberration', '_rlnAmplitudeContrast', ] valueSets = [] #list of strings for star file partParamsList = self.getStackParticleParams() stackPath = os.path.join(self.params['rundir'], mrcStackFile) for partParams in partParamsList: relionDataLine = ("%d@%s %d %.6f %.6f %.6f %d %.6f %.6f" % ( partParams['ptclnum'], stackPath, partParams['filmNum'], partParams['defocus2'], partParams['defocus1'], partParams['angle_astigmatism'], partParams['kv'], self.params['cs'], partParams['amplitude_contrast'], )) valueSets.append(relionDataLine) star = starFile.StarFile(starfile) star.buildLoopFile("data_", labels, valueSets) star.write()
def parseParticleDataIterationFile(self,paramfile,test=False): ''' parse data.star file from Relion 1.2: ''' if not os.path.isfile(paramfile): apDisplay.printError("Relion data.star file does not exist: %s" % (paramfile)) apDisplay.printMsg("Parsing parameter file: %s" % (paramfile)) # Use the star file class to read the parameter file f = starFile.StarFile( paramfile ) f.read() dataBlock = f.getDataBlock("data_images") loopDict = dataBlock.getLoopDict() # there is only one loop in the data_images block partnum = 1 # partnum starts with 1, not 0 partdict = {} for valueSet in loopDict: paramdict = { 'partnum' : partnum, 'angleRot' : float(valueSet["_rlnAngleRot"]), 'angleTilt' : float(valueSet["_rlnAngleTilt"]), 'anglePsi' : float(valueSet["_rlnAnglePsi"]), 'originX' : float(valueSet["_rlnOriginX"]), 'originY' : float(valueSet["_rlnOriginY"]), } partdict[paramdict['partnum']] = paramdict partnum = partnum + 1 if len(partdict) < 2: apDisplay.printError("No particles found in particle data file %s" % (paramfile)) apDisplay.printMsg("Processed %d particles" % (len(partdict))) return partdict
def convertFSCFileForIteration(self, iteration): ''' RElion FSC info is in recon_it002_model.star and the final recon_model.star file, convert this to 3DEM format For the final iteration, we need to use recon_model.star rather than the iteration specific file to get the actual values. ''' lastiter = self.findLastCompletedIteration() if iteration == lastiter: fscfile = os.path.join(self.projmatchpath, "recon_model.star"%(iteration)) else: fscfile = os.path.join(self.projmatchpath, "recon_it%.3d_half1_model.star"%(iteration)) f = starFile.StarFile( fscfile ) try: f.read() except e: if iteration == lastiter: apDisplay.printWarning("%s file could not be opened, data will NOT be inserted into the database. Relion did NOT run to completion." % fscfile) else: apDisplay.printWarning("%s file could not be opened, data will NOT be inserted into the database" % fscfile) return False dataBlock = f.getDataBlock("data_model_class_1") loopDict = dataBlock.getLoopDict() newfscfile = open(os.path.join(self.resultspath, "recon_%s_it%.3d_vol001.fsc" % (self.params['timestamp'], iteration)), "w") newfscfile.write("### column (1) inverse Angstroms, column (2) Fourier Shell Correlation (FSC)") for valueSet in loopDict: resolution = float(valueSet["_rlnResolution"]) # already in inverse angstrom fsc = float(valueSet["_rlnGoldStandardFsc"]) # should go from a value of 1 to 0 newfscfile.write("%.6f\t%.6f\n" % (resolution, fsc)) newfscfile.close() return True
def readParamsFromOptimiserFile(self, iternum): """ read the recon_it000_optimiser.star file to get iteration parameters, such as symmetry and phase residual cutoff """ iterparams = {'iternum': iternum,} #recondir = os.path.join(self.params['rundir'], "recon") recondir = self.params['rundir'] optimiserfile = "recon_it%03d_optimiser.star"%(iternum) optimiserfilepath = os.path.join(recondir, optimiserfile) # Create a dictionary of parameters found in the optimiser file paramdict = {} ### parse optimiser file to populate dictionary f = starFile.StarFile( optimiserfilepath ) f.read() dataBlock = f.getDataBlock("data_optimiser_general") paramdict = dataBlock.getLabelDict() header = f.getHeader() # Parse the header for the command line options used to run relion sheader = header.strip() bits = sheader.split("--") for bit in bits: params = bit.split() key = params[0] if len(params) > 1 : value = params[1] paramdict[key] = value else: paramdict[key] = True if 'ini_high' not in paramdict: paramdict['ini_high'] = 0 iterparams['ctf'] = self.convertBool(paramdict['_rlnDoCorrectCtf']) if paramdict['_rlnDoCorrectCtf'] else False iterparams['ctf_intact_first_peak'] = self.convertBool(paramdict['_rlnDoIgnoreCtfUntilFirstPeak']) if paramdict['_rlnDoIgnoreCtfUntilFirstPeak'] else False iterparams['ctf_corrected_ref'] = self.convertBool(paramdict['_rlnRefsAreCtfCorrected']) if paramdict['_rlnRefsAreCtfCorrected'] else False iterparams['offset_step'] = int(paramdict['offset_step']) iterparams['auto_local_healpix_order'] = int(paramdict['_rlnAutoLocalSearchesHealpixOrder']) iterparams['healpix_order'] = int(paramdict['healpix_order']) iterparams['offset_range'] = int(paramdict['offset_range']) iterparams['ini_high'] = int(paramdict['ini_high']) iterparams['sym'] = paramdict['sym'] ### convert symetry to Appion symtext = apFrealign.convertFrealignSymToAppionSym(iterparams['sym']) symmdata = apSymmetry.findSymmetry(symtext) apDisplay.printMsg("Found symmetry %s with id %s"%(symmdata['eman_name'], symmdata.dbid)) iterparams['symmdata'] = symmdata return iterparams
def writeLoopDictToStarFile(loopDict, datablockname, starfilename): labels = loopDict[0].keys() valueSets = [] for line in loopDict: params = "" for p in line.values(): params += " %s" % p valueSets.append(params) star = starFile.StarFile(starfilename) star.buildLoopFile(datablockname, labels, valueSets) star.write()
def excludeClassesFromRelionDataFile2(starfile, outlist, *classlist): ### input is Relion data star file, e.g. run1_it025_data.star ### outputs a list without the particles belonging to excluded classes ### list is EMAN-style, particle numbering starts with 0 (note that in Relion particle numbering starts with 1) ### *classlist can be as many classes as you wish separated by comma, e.g. 1 or 1,3,6; classes are numbered Relion format, starting with 1 star = starFile.StarFile(starfile) star.read() dataBlock = star.getDataBlock("data_images") loopDict = dataBlock.getLoopDict() badparts = [] goodparts = [] for i in range(len(loopDict)): rlnpart = float(loopDict[i]['_rlnImageName'].split("@")[0]) # starts with 1 rlnclass = float(loopDict[i]['_rlnClassNumber']) bad = False badpart = 0 for c in classlist: if float(c) == rlnclass: badpart = int(rlnpart) bad = True if bad is True: badparts.append(badpart) for i in range(len(loopDict)): if (i+1) not in badparts: goodparts.append(i+1) f = open(outlist, "w") for gp in goodparts: f.write("%d\n" % (gp-1)) # EMAN-style numbering, starts with 0 f.close() loopDictNew = starFile.LoopBlock # loopDictNew = [] print dir(loopDict), "loop Dict" print dir(loopDictNew), "loop Dict New" print len(loopDict), "length of loop Dict" print loopDict[0] for gp in goodparts: loopDictNew.append(loopDict[gp-1]) print len(loopDictNew), "length of loop Dict New" dataBlockNew = starFile.DataBlock("data_images") dataBlockNew.setLoopBlocks([loopDictNew]) print dir(dataBlockNew) print len(dataBlockNew.loopBlocks) star.setDataBlock(dataBlockNew,"data_images") dbnew = star.getDataBlock("data_images") print dbnew.name, "****" print dir(dbnew) print len(dbnew.loopBlocks) loopDict = dbnew.getLoopDict() print len(loopDict) star.write("destination.star")
def listFileFromRelionStarFile(starfile, outlist, datablock="data_images"): ### write out an EMAN-style list file (numbering starts with 0) based on a relion star file with images and image numbers star = starFile.StarFile(starfile) star.read() dataBlock = star.getDataBlock(datablock) loopDict = dataBlock.getLoopDict() allparts = [] for i in range(len(loopDict)): allparts.append(int(loopDict[i]['_rlnImageName'].split("@")[0])) # starts with 1 allparts.sort() f = open(outlist, "w") for p in allparts: f.write("%d\n" % (p-1)) # EMAN-style numbering, starts with 0 f.close()
def sortRelionStarFileByParticleNumber(instarfile, outstarfile, datablock="data_images"): star = starFile.StarFile(instarfile) star.read() dataBlock = star.getDataBlock(datablock) loopDict = dataBlock.getLoopDict() partdict = {} for i in range(len(loopDict)): rlnpart = (int(loopDict[i]['_rlnImageName'].split("@")[0])) # starts with 1 partdict[rlnpart] = loopDict[i] l = sorted(partdict, key=lambda key: partdict[key]) l.sort() # write sorted star file loopDictNew = [] for val in l: loopDictNew.append(partdict[val]) writeLoopDictToStarFile(loopDictNew, datablock, outstarfile)
def excludeClassesFromRelionDataFile(instarfile, datablock, outlist, outstarfile, *classlist): ### input is Relion data star file, e.g. run1_it025_data.star ### datablock: The start of a data block is defined by the keyword "data_" followed by an optional string for identification (e.g., "data_images") ### outputs a list without the particles belonging to excluded classes ### list is EMAN-style, particle numbering starts with 0 (note that in Relion particle numbering starts with 1) ### outstarfile is the output star file ### *classlist can be as many classes as you wish separated by comma, e.g. 1 or 1,3,6; classes are numbered Relion format, starting with 1 star = starFile.StarFile(instarfile) star.read() dataBlock = star.getDataBlock(datablock) loopDict = dataBlock.getLoopDict() badparts = [] goodparts = [] loopDictNew = [] for i in range(len(loopDict)): rlnpart = float(loopDict[i]['_rlnImageName'].split("@")[0]) # starts with 1 rlnclass = float(loopDict[i]['_rlnClassNumber']) bad = False badpart = 0 for c in classlist: if float(c) == rlnclass: badpart = int(rlnpart) bad = True if bad is True: badparts.append(badpart) else: goodparts.append(int(rlnpart)) loopDictNew.append(loopDict[i]) badparts.sort() goodparts.sort() f = open(outlist, "w") for gp in goodparts: f.write("%d\n" % (gp-1)) # EMAN-style numbering, starts with 0 f.close() # selected star file parameters, write star file with excluded images writeLoopDictToStarFile(loopDictNew, datablock, outstarfile)
def start(self): """ for each particle in the stack, get the information that RELION needs """ stackPartList = apStack.getStackParticlesFromId(self.params['stackid']) nptcls = len(stackPartList) currentImageId = stackPartList[0]['particle']['image'].dbid count = 0 imagenumber = 1 partParamsList = [] sys.stderr.write("reading stack particle data\n") #create list of dictionaries that will be passed to starFile maker later for stackPart in stackPartList: count += 1 if count % 100 == 0: sys.stderr.write(".") if count % 10000 == 0: sys.stderr.write("\nparticle %d of %d\n" % (count, nptcls)) # extra particle number information not read by Relion if count != stackPart['particleNumber']: apDisplay.printWarning( "particle number in database is not in sync") partParams = {} partParams['ptclnum'] = count ### get image data imagedata = stackPart['particle']['image'] if imagedata.dbid != currentImageId: imagenumber += 1 currentImageId = imagedata.dbid partParams['filmNum'] = imagenumber #print partParams['filmNum'] partParams['kv'] = imagedata['scope']['high tension'] / 1000.0 partParams['cs'] = imagedata['scope']['tem']['cs'] * 1000 ### get CTF data from image ctfdata = ctfdb.getBestCtfValue(imagedata, msg=False, sortType='maxconf') if ctfdata is not None: # use defocus & astigmatism values partParams['defocus1'] = abs(ctfdata['defocus1'] * 1e10) partParams['defocus2'] = abs(ctfdata['defocus2'] * 1e10) partParams['angle_astigmatism'] = ctfdata['angle_astigmatism'] partParams['amplitude_contrast'] = ctfdata[ 'amplitude_contrast'] else: apDisplay.printError( "No ctf information for particle %d in image %s" % (count, imagedata['filename'])) partParamsList.append(partParams) ###now make star file #first make header star = starFile.StarFile(self.params['outstar']) labels = [ '_rlnImageName', '_rlnMicrographName', '_rlnDefocusU', '_rlnDefocusV', '_rlnDefocusAngle', '_rlnVoltage', '_rlnSphericalAberration', '_rlnAmplitudeContrast', ] valueSets = [] #list of strings for star file ###now make particle data for partParams in partParamsList: relionDataLine = ( "%[email protected] mic%d %.6f %.6f %.6f %d %.6f %.6f" % ( partParams['ptclnum'], partParams['filmNum'], partParams['defocus2'], partParams['defocus1'], partParams['angle_astigmatism'], partParams['kv'], partParams['cs'], partParams['amplitude_contrast'], )) valueSets.append(relionDataLine) star.buildLoopFile("data_", labels, valueSets) star.write()
def readStarFileDataBlock(starfile, datablock): star = starFile.StarFile(starfile) star.read() dataBlock = star.getDataBlock(datablock) loopDict = dataBlock.getLoopDict() return loopDict