Beispiel #1
0
def main():
	print "I have entered main"
	#progname = os.path.basename(sys.argv[0])
	#usage = """Aligns a 3d volume to another by executing e2spt_classaverage.py and then calculates the FSC between them by calling e2proc3d.py . It returns both a number for the resolution based on the FSC0.5 
	#criterion(on the screen) and a plot as an image in .png format."""
	
	progname = os.path.basename(sys.argv[0])
	usage = """Aligns a 3d volume to another by executing e2spt_classaverage.py and then calculates the FSC between them by calling e2proc3d.py . It returns both a number for the resolution based on the FSC0.5 
	criterion(on the screen) and a plot as an image in .png format."""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
		
	parser.add_argument("--alistack", type=str, default='', help="""Default=None. Stack of particles aligned with e2spt_classaverage.p.y""")
	
	parser.add_argument("--scores",type=str,default='',help="""Default=None. Text file containing a list of correlations scores.""")
	
	parser.add_argument("--nbins", type=int,default=0,help="""Used for histogram plot. Default=0 (not used). Number of bins for histogram. If not provided, the optimal bin number will be automatically calculated based on bin-width, computed using Scott's normal reference rule, width = (3.5*std)/cuberoot(n), where 'std' is the standard deviation of the distribution of scores and n is the number of values considered. Then, bins will be nbins = (max(scores) - min(scores)) / width.""")
	
	parser.add_argument("--cutoff", type=float, help="""Fraction of particles (as a decimal, where 1.0 is the entire set, 0.8 is 80 percent. 0.5 is 50 percent, etc); 
														where to make the cutoff to divide the set into two groups. For example, if you specify 
														--cutoff=0.2, the 20 percent of particles with the highest correlation scores will be bundled into the first group, 
														and the remaining 80 percent into the second group.""", default=None)
	
	parser.add_argument("--lowpass",type=str,default='default',help="""Filter applied to averages when --groups is used. Default=filter.lowpass.gauss:cutoff_freq=1/F, where F is Nyquist frequency, automatically calculated. To disable type --lowpass=None""")
	
	parser.add_argument("--groups", type=int, help="Number of groups you want the data to be divided into based on correlation.", default=None)
	
	parser.add_argument("--topn", type=int, help="Number of particles from best to worst that you want to be written as a substack, averaged, and generate a coordinates .txt file with their coordinates.", default=None)

	parser.add_argument("--sigmaprune", type=float, default=0.0, help = """Number of standard deviations below the mean to cut off particles; 
																		that is, the mean cross correlation coefficient of all particles will be computed, and those that are 
																		--sigmaprune=N standard deviations below the mean will not be considered.""")
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	
	parser.add_argument("--path", type=str, help="Results directory. If not specified, defaults to e2sptcoeff/", default='sptcoeff')
	
	parser.add_argument("--normalizeplot",action="store_true", help="Make maximum correlation value on plot equal to 1 and the minimum equal to 0, and scale all other values accordingly.", default=False)

	
	(options, args) = parser.parse_args()
	
	if options.groups and (options.cutoff or options.topn):
		print "ERROR: you cannot specify --cutoff, --groups and --topn all at the same time. Choose one."
		sys.exit()

	if options.cutoff and (options.groups or options.topn):
		print "ERROR: you cannot specify --cutoff, --groups and --topn all at the same time. Choose one."
		sys.exit()
		
	if options.topn and (options.cutoff or options.groups):
		print "ERROR: you cannot specify --cutoff, --groups and --topn all at the same time. Choose one."
		sys.exit()
		
	logger = E2init(sys.argv, options.ppid)
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath( options, 'sptcoeff')
	
	print "\nI have read the parameters"
	
	scores=[]
	dataset={}
	#x=[]
	
	k = 0
	usenewstack = False
	newstack = options.alistack.replace('.hdf','_prepruned.hdf')
	
	if options.alistack:
		n = EMUtil.get_image_count(options.alistack)
		
		for i in range(n):
			ahdr = EMData(options.alistack,i,True)
			#print "ahdr is", ahdr	
			score = None

			if options.verbose:
				print  "\nanalyzing header for particle", i
			
			if 'spt_score' in ahdr.get_attr_dict():
				score=-1*ahdr['spt_score']
				print "spt_score is", score
			elif 'spt_coefficient' in ahdr.get_attr_dict():
				score=ahdr['spt_coefficient']*-1
				print "spt_coefficient is", score
			else:
				print "\nERROR: no score found in header for particle %d. Skipping it! A prepruned stack will be made with all the particles that did have score info in their header" %(i)
				a = EMData( options.alistack, i )
				a.write_image( newstack, k )
				usenewstack = True
			
			if score:
				scores.append( score )
		
	elif options.scores and not options.alistack:
		f = open( options.scores,'r')
		lines=f.readlines()
		f.close()
		scores = [ round(float(line.replace('\n','')),6) for line in lines]
	
	elif not options.scores and not options.alistack:
		print "\n(e2spt_coeffplot)(main) ERROR: you need to supply either --alistack or --scores, with the former taking precedence over the latter."
		sys.exit()
	
	
	if usenewstack:
		options.alistack = newstack
	
	n = len(scores)
	
	nstack = EMUtil.get_image_count( options.alistack )
	
	if n != nstack:
		print "\n!!!! WARNING: the number of scores %d does not match the number of images %d in the stack %s" %( n, nstack, options.alistack )

	if scores and n > 1:
		print "\nThe set has these many particles", len( scores )
	else:
		print "\nERROR: There seems to be no information on particle scores. The number of scores must be larger than one to do any statistics with them."
		sys.exit()
		
	for i in range( n ):
		#dataset.append({'score':float(score), 'particle':a})
		dataset.update({i:scores[i]})
		#x.append(i)

	dataset = sorted( dataset.items(), key=itemgetter(1), reverse=True )
	
	if options.normalizeplot:
		#for s in scores:
			#val = values[ele]
		minv1 = min(scores)
		#maxv1 = max(scores)
		#print "Min max before normalization was", minv,maxv1
		for k in range(len(scores)):
			scores[k] = scores[k] - minv1
		
		#minv2 = min(scores)
		maxv2 = max(scores)
		#print "After subtracting min, the are", minv2,maxv
		#print "Max before normalization was", maxv
		for k in range(len(scores)):
			scores[k] = scores[k] / maxv2
	
	
	scores.sort()
	scores.reverse()
	#scores=scores[:-2]

	'''
	c:plot the distribution of scores
	'''
	import matplotlib.pyplot as plt
	import pylab
	import matplotlib
	
	std = np.std( scores )
	mean = np.mean( scores )
	statistics = ['mean='+str(mean) + ' std='+str(std) + '\n']

	print "\nthe standard deviation %.6f, mean %.6f" %( std, mean )
	
	if not std:
		print "\nERROR: std=0, which means all intensity values are the same."
		sys.exit()
	
	cuberoot = np.power(len( scores ),1.0/3.0)
	width = (3.5*std)/cuberoot
	print "\naccording to Scott's normal reference rule, width = (3.5*std)/cuberoot(n), the width of the histogram bins will be", width
	
	calcbins = ( max(scores) - min( scores )) / width
	
	if options.nbins:
		calcbins = options.nbins
		print "\overwriting number of bins to be", options.nbins
	
	print "\nand the number of bins n = ( max(scores) - min(scores) ) / width will thus be", calcbins
	calcbins = round(calcbins)
	print "rounding to", calcbins
	
	statistics.append( 'bins=' + str( calcbins ) + ' , binwidth=' + str( width ) + '\n')
		
	if not calcbins:
		print "WARNING: nbins=0, which means max and min intensity are the same, which probably means all scores are zero. Defaulting nbins to number of partilces."
		calcbins = len( scores )
	
	datafile = ''
	if options.alistack:
		datafile = os.path.basename( options.alistack )
	elif options.scores:
		datafile = os.path.basename( options.scores )
		
	f=open(options.path + '/stats.txt','w')
	f.writelines(statistics)
	f.close()
	
	plt.hist( scores, calcbins, alpha=0.30, label=datafile)	

	plottitle = os.path.basename( options.alistack ).replace('.hdf','') + ' CC scores distribution histogram'
	plt.title( plottitle )

  	matplotlib.rc('xtick', labelsize=16) 
	matplotlib.rc('ytick', labelsize=16) 
  		 	
  	font = {'weight':'bold','size':16}
	matplotlib.rc('font', **font)
  		 	
	pylab.rc("axes", linewidth=2.0)
		
	pylab.xlabel('CC score (au)', fontsize=16, fontweight='bold')
  	pylab.ylabel('Number of particles', fontsize=16, fontweight='bold')
  	
  	plt.savefig( options.path + '/scores_histogram.png' )
  	plt.clf()
  	
  	
  	'''
  	c:plot decay in ranked correlation scores
  	'''
  	x = [i for i in range(len(scores))]
  	
	plt.plot(x, scores, color='k', linewidth=3)
	plottitle = os.path.basename( options.alistack ).replace('.hdf','') + ' CC scores decay' 
	plt.title( plottitle )
	
	pylab.xlim([min(x),max(x)+0.1*max(x)])
	font = {'weight':'bold','size':16}
	matplotlib.rc('font', **font)

	pylab.xlabel('Particle index', fontsize=16, fontweight='bold')
  	pylab.ylabel('CC score (au)', fontsize=16, fontweight='bold')

	plt.savefig( options.path + '/scores_decay.png')
	plt.clf()
	
	
	'''
  	c:plot the distance to mean value in # of standard deviations
  	'''
	distancestomean = [ (scores[i]-mean)/std for i in range(len(scores))]
	plt.plot(x, distancestomean, color='b', linewidth=2,)
	
	plottitle = os.path.basename( options.alistack ).replace('.hdf','') + ' CC scores distance to mean'
	plt.title( plottitle )
	
	pylab.xlim([min(x),max(x)+0.1*max(x)])
	
	font = {'weight':'bold','size':16}
	matplotlib.rc('font', **font)
	
	pylab.xlabel('Particle index', fontsize=16, fontweight='bold')
  	pylab.ylabel('Distance from mean (sigmas)', fontsize=16, fontweight='bold')
	
	plt.savefig( options.path + '/scores_distance2mean.png')
	plt.clf()
	
	
	'''
  	c:plot the distance to max value in # of standard deviations
  	'''
	maxi = max(scores)
	distancestomax = [ (maxi-scores[i])/std for i in range(len(scores))]
	plt.plot(x, distancestomax, color='b', linewidth=2,)
	
	plottitle = os.path.basename( options.alistack ).replace('.hdf','') + ' CC scores distance to max'
	plt.title( plottitle )
	
	pylab.xlim([min(x),max(x)+0.1*max(x)])
	
	font = {'weight':'bold','size':16}
	matplotlib.rc('font', **font)
	
	pylab.xlabel('Particle index', fontsize=16, fontweight='bold')
  	pylab.ylabel('Distance from max (sigmas)', fontsize=16, fontweight='bold')
	
	plt.savefig( options.path + '/scores_distance2max.png')
	plt.clf()
	
	
	print 'sorted dataset is', dataset
	
	'''
	c:prune and/or divide into groups
	'''		
	newscores=[]
	if options.sigmaprune:

		#print "Will analyze scores to remove aberrantly low ones"
	
		#mu=numpy.mean(scores)
		#sigma=numpy.std(scores)
			
		mu=mean
		sigma=std
		
		print "\nMean is", mu
		print "Std is", sigma
		filter = mu - sigma * (options.sigmaprune)
		print "Therefore, filter is", filter

		for d in dataset:
			if float(d['score']) < float(filter):
				dataset.remove(d)
				print "I have removed this aberrant particle from the dataset due to its low score", d['score']
			else:
				newscores.append(float(d['score']))
				print "This score is high enough to survive", d['score']
		
		newscores.sort()
		newscores.reverse()
		x=range(len(newscores))
	
		plottitle = os.path.basename(options.alistack).replace('.hdf', '_prunedSCORES')
		plt.plot(x, newscores,color='k', linewidth=2)
		pylab.xlim([min(x),max(x)+0.1*max(x)])
		#plt.title(plottitle)
		plt.ylabel('CC coefficient')
		plt.xlabel('Particle number')
		#a = plt.gca()
		plotfile = options.path + '/' + plottitle + '.png'
		plt.savefig(plotfile)
		plt.clf()
		
	newN=len(dataset)
	
	if options.lowpass:
		if options.lowpass == "default":
			hdr = EMData( options.alistack, 0, True )
			apix=hdr['apix_x']
			nyquist = 1.0/2.0*apix
			options.lowpass = '******'+str(nyquist)+':apix='+str(apix)
			if apix =='1.0':
				print "\nWARNING: apix is 1.0, most likely wrong (default empty value). You can fix/change it with e2fixheaderparam.py"
		
		if options.lowpass and options.lowpass != 'None' and options.lowpass != 'none': 
			options.lowpass=parsemodopt(options.lowpass)
		elif 'None' in options.lowpass or 'none' in options.lowpass:
			options.lowpass=None
		
	if options.groups:
		
		if not options.alistack:
			print "\nERROR: --groups requires --alistack"
			sys.exit()
	
		halfptclnum= int(round(n/2.0))
		halfptcl = dataset[halfptclnum][0]
		print "half ptclnum is", halfptclnum
		print "which happens to be ptcl indx", halfptcl
		halfscore = dataset[halfptcl][1]
		print "with halfscore being", halfscore
		
		subdatasetsSET=[]
		N=len(dataset)
		#print "THe type of dataset is", type(dataset)
		print "The len of the dataset is", N
		subN = N/options.groups
		print "The len of each subset, except the last, should be", subN
		for g in range(options.groups):
			#subscores = scores[g*subN : (g+1)*subN]
			subdataset = dataset[g*subN : (g+1)*subN]			
			if g == options.groups -1:
				subdataset = dataset[g*subN :]
			subdatasetsSET.append(subdataset)
	
		kk=0
		for subdataset in subdatasetsSET:
			print "The len of subset %d is %d" % (kk, len(subdataset))
			jj = 0		
			groupname = options.path + '/' + os.path.basename(options.alistack).replace('.', '_'+ str(kk).zfill(len(str(options.groups))) + '.')
			particleLIST = []			
			lines = []
			
			avgr = Averagers.get('mean.tomo')
			for element in subdataset:
				#particle = element['particle']
				
				ptclnum = element[0]
				img = EMData( options.alistack, ptclnum )
				img.write_image(groupname,jj)
				jj+=1
				particleLIST.append( ptclnum )
				
				avgr.add_image( img )
				
			averageNAME = groupname.replace('.hdf','_AVG.hdf')		
			
			average = avgr.finish()
			
			average['origin_x'] = 0
			average['origin_y'] = 0
			average['origin_z'] = 0
			
			average.process_inplace('normalize.edgemean')
			if options.lowpass:
				print "(e2spt_coeffplot)(main) --lowpass provided:", options.lowpass
				average.process_inplace(options.lowpass[0],options.lowpass[1])
			
			average.write_image(averageNAME,0)
			#print "\nThe group average has been written to", averageNAME
			kk+=1	
			
	if options.cutoff:
	
		if not options.alistack:
			print "\nERROR: --cutoff requires --alistack"
			sys.exit()
	
		threshptclnum=int(round(newN/(1/options.cutoff)))
		threshptcl=dataset[threshptclnum]	
		print "The new threshptcl is", threshptcl
		threshscore = dataset[threshptclnum][1]

		threshlabel="%0.2f" %(options.cutoff)
		threshlabel=str(threshlabel).replace('.','p')	
		group1=[]
		group2=[]
		k1=0
		k2=0
		g1name = options.path + '/' + os.path.basename(options.alistack).replace('.', '_G1.')
		g2name = options.path + '/' + os.path.basename(options.alistack).replace('.', '_G2.')
		avgr1 = avgr = Averagers.get('mean.tomo')
		avgr2 = avgr = Averagers.get('mean.tomo')
		for i in dataset:
			img = EMData( options.alistack, i[0] )
			
			if i[1] >= threshscore:
				group1.append( i[0] )
				img.write_image(g1name,k1)
				avgr1.add_image( img )
				k1+=1
			else:
				group2.append( i[0] )
				img.write_image(g2name,k2)
				avgr2.add_image( img )
				k2+=1
				#else:
				#	print "\n\n@@@@ Found a garbage particle, and thus did not consider it!\n\n"	

		if group1:
			g1avg = avgr1.finish()
			g1avg.write_image(g1name.replace('.hdf','_avg.hdf'),0)

		if group2:
			g2avg = avgr1.finish()
			g2avg.write_image(g2name.replace('.hdf','_avg.hdf'),0)
	
	if options.topn:
	
		if not options.alistack:
			print "\nERROR: --topn requires --alistack"
			sys.exit()
			
		topndataset = dataset[0:options.topn]
		bottomdataset = dataset[options.topn:]
		
		outnamestack = options.path + '/' + os.path.basename(options.alistack).replace('.','top' + str(options.topn) + '.')
		
		coordsname = options.path + '/' + os.path.basename(outnamestack).split('.')[0] + '_coords.txt'
		
		indxsname = options.path + '/' + os.path.basename(coordsname).replace('coords','indxs')
		
		k=0
		linescoords=[]
		linesindxs=[]
		topptcls=[]
		
		avgr = Averagers.get('mean.tomo')
		for ptcl in topndataset:
			p = ptcl[0]
			img = EMData( options.alistack, p )
			img.write_image(outnamestack,k)
			avgr.add_imag(img)
			topptcls.append(p)
			linescoords.append(str(p['ptcl_source_coord'])+ '\n')
			linesindxs.append(str(p['source_n'])+ '\n')
			k+=1
		
		avg = avgr.finish()
		avgname = options.path + '/' + os.path.basename(outnamestack).replace('.','_avg.') 
		
		avg.write_image(avgname,0)
		f=open(coordsname,'w')
		f.writelines(linescoords)
		f.close()
	
		f=open(indxsname,'w')
		f.writelines(linesindxs)
		f.close()
	
	#x=range(len(scores))
	
	#plottitle = os.path.basename(options.alistack).replace('.hdf', '_prunedSCORES')
	#plt.plot(x, scores, marker='o', color='r', linewidth=2)
	#plt.title(plottitle)
	#plt.ylabel('score')
	#plt.xlabel('n ptcl')
	#a = plt.gca()
	
	#plotfile = options.path + '/' + plottitle + '.png'
	#plt.savefig(plotfile)
	#plt.clf()
	
	E2end(logger)

	return()
Beispiel #2
0
def main():
    #import pylab
    #import matplotlib.mlab as mlab
    import matplotlib.pyplot as plt

    progname = os.path.basename(sys.argv[0])
    usage = """Produces mean intensity histograms of stack of sub-volumes"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--input",
        type=str,
        default='',
        help=
        """Default=None. Comma-separated stacks of images whose mean intensity distribution you want to plot."""
    )

    parser.add_argument(
        "--subset",
        type=int,
        default=0,
        help=
        """Default=0 (not used). N > 2 number of particles to from each stack provided through --input to consider."""
    )

    parser.add_argument(
        "--path",
        type=str,
        default='',
        help=
        "Directory to store results in. The default is a numbered series of directories containing the prefix 'sptsim'; for example, sptsim_02 will be the directory by default if 'sptsim_01' already exists."
    )

    #parser.add_argument("--output",type=str,default='',help="""Name of output plot if comparing two populations or more.""")

    parser.add_argument(
        "--shrink",
        type=int,
        default=1,
        help=
        "Default=1 (no shrinking). Optionally shrink the input volumes by an integer amount n > 1."
    )

    parser.add_argument(
        "--bins",
        type=int,
        default=0,
        help=
        """Default=0 (not used). Number of bins for histogram. If not provided, the optimal bin number will be automatically calculated based on bin-width, computed using Scott's normal reference rule, width = (3.5*std)/cuberoot(n), where 'std' is the standard deviation of the mean intensity distribution of population and n is the number of mean intensity values considered (this is affected by --removesigma). Then, bins will be nbins = (max(intensities) - min(intensities)) / width."""
    )

    #parser.add_argument("--sym", type=str, default='c1', help = "Symmetry to enforce before computing mean intensity in the box. Note that this should only be used if the particles are properly aligned to the symmetry axis.")

    parser.add_argument(
        "--mask",
        type=str,
        default="mask.sharp:outer_radius=-2",
        help=
        "Default=mask.sharp:outer_radius=-2. Mask processor applied to the particles before alignment. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py)."
    )

    parser.add_argument(
        "--maskfile",
        type=str,
        default='',
        help=
        """Default=None. An image file containing an additional mask to apply besides --mask."""
    )

    parser.add_argument(
        "--clip",
        type=int,
        default=0,
        help=
        """Default=0 (not used). Boxsize to clip particles to before computing mean and standard deviation values for each image. (This can act as a mask, as you'd want to clip the boxes to a smaller size than their current, original size, excluding neighboring particles and background pixels/voxels)."""
    )

    parser.add_argument(
        "--preprocess",
        type=str,
        default='',
        help=
        """Any processor to be applied to each image before computing mean and standard deviation values. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py)."""
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        default='',
        help=
        """Default=None. A lowpass filtering processor to be applied before computing mean and standard deviation values for each image. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py)."""
    )

    parser.add_argument(
        "--highpass",
        type=str,
        default='',
        help=
        """Default=None. A highpass filtering processor to be applied before computing mean and standard deviation values for each image. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py)."""
    )

    parser.add_argument(
        "--threshold",
        type=str,
        default='',
        help=
        """A thresholding processor to be applied before computing mean and standard deviation values for each image. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py)."""
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default="normalize.edgemean",
        help=
        """Default=normalize.edgemean. Normalization processor applied to particles before computing mean and standard deviation values for each iamge. If normalize.mask is used, --mask will be passed in automatically. If you want to turn normalization off specify \'None\'. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py)."""
    )

    parser.add_argument(
        "--savepreprocessed",
        action="store_true",
        default=False,
        help=
        """Default=False. If provided, this option will save the image stacks in --input after all preprocessing options (lowpass, highpass, preprocess, masking, etc.) have been applied."""
    )

    parser.add_argument(
        "--normalizeplot",
        action="store_true",
        default=False,
        help=
        """Default=False. This will normalize the intensity values of the distribution to be between 0 and 1"""
    )

    parser.add_argument(
        "--removesigma",
        type=int,
        default=0,
        help=
        """Default=0. Provide a value for the number of standard deviations away from the mean to consider values to exclude. For example, if --removesigma=3, values further than 3 standard deviations away from the mean will be excluded."""
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help=
        "Default=1. Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        type=int,
        default=0,
        help=
        "Default 0. Verbose level [0-9], higner number means higher level of verboseness",
        dest="verbose",
        action="store",
        metavar="n")

    (options, args) = parser.parse_args()

    logger = E2init(sys.argv, options.ppid)
    '''
	if options.mask: 
		options.mask=parsemodopt(options.mask)
	
	if options.preprocess: 
		options.preprocess=parsemodopt(options.preprocess)
		
	if options.lowpass: 
		options.lowpass=parsemodopt(options.lowpass)
	
	if options.highpass: 
		options.highpass=parsemodopt(options.highpass)
	
	if options.threshold: 
		options.threshold=parsemodopt(options.threshold)
		
	if options.normproc: 
		options.normproc=parsemodopt(options.normproc)
	'''

    from e2spt_classaverage import sptOptionsParser
    options = sptOptionsParser(options)

    datafiles = options.input.split(',')

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'meanintensityplots')

    intensitiesSeveral = []
    iwzSeveral = []
    iminsSeveral = []
    imaxsSeveral = []
    istdsSeveral = []

    means = []
    stds = []

    from e2spt_classaverage import writeParameters
    cmdwp = writeParameters(options, 'e2spt_meanintensityplot.py',
                            'sptmeanintensity')

    for datafile in datafiles:
        n = EMUtil.get_image_count(datafile)

        if options.subset:
            if options.subset < 3:
                print "ERROR:Subset must be > 2."
                sys.exit(1)

            n = options.subset

        if n < 3:
            print "ERROR: All stacks must have at least 3 particles in them. This one doesn't:", datafile
            sys.exit(1)

    for datafile in datafiles:
        ret = calcintensities(options, datafile)

        intensitiesSingle = ret[0]
        iwz = ret[1]
        imins = ret[2]
        imaxs = ret[3]
        istds = ret[4]

        intensitiesSeveral.append([datafile, list(intensitiesSingle)])

        iwzSeveral.append([datafile, list(iwz)])
        iminsSeveral.append([datafile, list(imins)])
        imaxsSeveral.append([datafile, list(imaxs)])
        istdsSeveral.append([datafile, list(istds)])

        intensitiesSingleNorm = intensitiesSingle

        if options.normalizeplot:
            intensitiesSingleNorm = normintensities(intensitiesSingle, 0, 0)

        #print "\]n\\n\nIntensities before plotting are", intensitiesSingleNorm
        #print "\n\n\n\n\n"

        ret = plotintensities(intensitiesSingleNorm, options, datafile)
        mean = ret[0]
        std = ret[1]
        means.append(mean)
        stds.append(std)

        ret = plotintensities(iwz, options, datafile, 'wz')
        ret = plotintensities(imins, options, datafile, 'mins')
        ret = plotintensities(imaxs, options, datafile, 'maxs')
        ret = plotintensities(istds, options, datafile, 'stds')

    #print "\nIntensities several len is", len( intensitiesSeveral )
    if len(intensitiesSeveral) > 1:

        datafile1 = intensitiesSeveral[0][0]
        datafile2 = intensitiesSeveral[1][0]

        intensities1 = intensitiesSeveral[0][1]
        intensities2 = intensitiesSeveral[1][1]
        n1 = len(intensities1)
        n2 = len(intensities2)

        zscore = (means[0] - means[1]) / np.sqrt((stds[0] * stds[0]) / n1 +
                                                 (stds[1] * stds[1]) / n2)

        g = open(options.path + '/MIboth_INFO.txt', 'w')
        zscoreline = 'zscore=' + str(
            zscore) + ' for ' + datafile1 + ' vs ' + datafile2 + ' \n'
        lines = [zscoreline]
        g.writelines(lines)
        g.close()

        print "\nzzzzzzz\n%s" % (zscoreline)

        absmax = absmin = 0
        if options.normalizeplot:

            minses = []
            maxes = []
            for intenS in intensitiesSeveral:
                minS = float(min(intenS[1]))
                maxS = float(max(intenS[1]))

                minses.append(minS)
                maxes.append(maxS)

            absmin = min(minses)
            absmax = max(maxes) - absmin

        for intensities in intensitiesSeveral:
            print "Type and len of intensities is", type(intensities[1]), len(
                intensities[1])

            intensitiesNorm = intensities[1]
            if options.normalizeplot:
                print "Normalizeplot on"
                intensitiesNorm = normintensities(intensities[1], absmin,
                                                  absmax)

            plotintensities(intensitiesNorm, options, datafile, 'no')

        plt.savefig(options.path + '/MIbothPlot.png')
        plt.clf()

    E2end(logger)
Beispiel #3
0
def main():
	
	progname = os.path.basename(sys.argv[0])
	usage = """
		This program takes a subtomgoram tiltseries (subtiltseries) as extracted with
		e2spt_subtilt.py, and computes the resolution of two volumes reconstructed with
		the even and the odd images in the tilt series. Must be in HDF format.
		Note that the apix in the header must be accurate to get sensible results.
		(You can fix the header of an image with e2fixheaderparam.py).
		"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--inputstem", type=str, default='', help="""Default=None. Aligned tilt series. String common to all files to be processed, in the current folder. For example, if you have many subtiltseries named subt00.hdf, subt01.hdf, ...subt99.hdf, you would supply --stem=subt to have all these processed.""")
	
	parser.add_argument('--path',type=str,default='sptintrafsc',help="""Default=sptintrafsc. Directory to save the results.""")
		
	parser.add_argument('--nonewpath',action='store_true',default=False,help="""Default=False. If True, a new --path directory will not be made. Therefore, whatever is sepcified in --path will be used as the output directory. Note that this poses the risk of overwriting data.""")
		
	parser.add_argument('--input',type=str,default='',help="""Default=None. Subtiltseries file to process. If processing a single file, --inputstem will work too, but you can also just provide the entire filename here --input=subt00.hdf""")
		
	parser.add_argument('--savehalftiltseries',action='store_true',default=False,help="""Default=False. If this parameter is on, the odd and even subtiltseries will be saved.""")
		
	parser.add_argument('--savehalfvolumes',action='store_true',default=False,help="""Default=False. If this parameter is on, the odd and even volumes will be saved.""")
	
	parser.add_argument("--reconstructor", type=str,default="fourier:mode=gauss_2",help="""Default=fourier:mode=gauss_2. The reconstructor to use to reconstruct the tilt series into a tomogram. Type 'e2help.py reconstructors' at the command line to see all options and parameters available. To specify the interpolation scheme for the fourier reconstructor, specify 'mode'. Options are 'nearest_neighbor', 'gauss_2', 'gauss_3', 'gauss_5'. For example --reconstructor=fourier:mode=gauss_5 """)
	
	parser.add_argument("--pad2d", type=float,default=0.0,help="""Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the 2d images in the tilt series for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though).""")

	parser.add_argument("--pad3d", type=float,default=0.0,help="""Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the volumes for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though).""")
	
	parser.add_argument("--averager",type=str,default="mean.tomo",help="""Default=mean.tomo. The type of averager used to produce the class average.""")
	
	parser.add_argument("--averagehalves",action="store_true", default=False,help="""Default=False. This will averager the even and odd volumes.""")
	
	parser.add_argument("--ppid", type=int, default=-1, help="""default=-1. Set the PID of the parent process, used for cross platform PPID.""")
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	
	parser.add_argument("--nolog",action="store_true",default=False,help="Default=False. Turn off recording of the command ran for this program onto the .eman2log.txt file") 
	
	(options, args) = parser.parse_args()	
	
	#if options.reconstructor == 'None' or options.reconstructor == 'none':
	#	options.reconstructor = None
	
	#if options.reconstructor and options.reconstructor != 'None' and options.reconstructor != 'none': 
	#	options.reconstructor=parsemodopt(options.reconstructor)
	
	#if options.averager: 
	#	options.averager=parsemodopt(options.averager)
	
	from e2spt_classaverage import sptOptionsParser
	options = sptOptionsParser( options )
	
	logger = E2init( sys.argv, options.ppid )
	
	'''
	Make the directory where to create the database where the results will be stored
	'''
	
	if not options.nonewpath:
		from e2spt_classaverage import sptmakepath
		options = sptmakepath (options, 'sptintrafsc')
	else:
		try:
			findir = os.lisdir( options.path )
		except:
			print "ERROR: The path specified %s does not exist" %( options.path )
			sys.exit()
	
	inputfiles = []
	
	if options.inputstem:
		c = os.getcwd()
		findir = os.listdir( c )

		for f in findir:
			if '.hdf' in f and options.inputstem in f:
				if options.verbose > 8:
					print "\nFound tiltseries!", f
				inputfiles.append( f )			#C:The input files are put into a dictionary in the format {originalseriesfile:[originalseriesfile,volumefile]}

	elif options.input:
		inputfiles.append( options.input )	
	
	for fi in inputfiles:
		
		#genOddAndEvenVols( options, fi )
		
		ret = genOddAndEvenVols( options, fi,[] )
		volOdd = ret[1]
		volEven = ret[0]
			
		if options.savehalfvolumes and volOdd and volEven:
			volOdd.write_image( options.path + '/' + fi.replace('.hdf','_ODDVOL.hdf'), 0 )
			volEven.write_image( options.path + '/' + fi.replace('.hdf','_EVENVOL.hdf'), 0 )
		
		retfsc = fscOddVsEven( options, fi, volOdd, volEven )
		
		fscfilename = retfsc[0]
		fscarea = retfsc[1]
		
		if options.averagehalves:
			avgr = Averagers.get( options.averager[0], options.averager[1] )
			avgr.add_image( recOdd )
			avgr.add_image( recEven )
			
			avg = avgr.finish()
			avg['origin_x'] = 0
			avg['origin_y'] = 0
			avg['origin_z'] = 0
			avg['apix_x'] = apix
			avg['apix_y'] = apix
			avg['apix_z'] = apix
			
			avgfile = options.path + '/AVG.hdf'
			avg.write_image( avgfile, 0 )
		
	E2end(logger)
	
	return
Beispiel #4
0
def main():

    progname = os.path.basename(sys.argv[0])
    usage = """This program allows you to examine density variations along one or more given volume (at the same time).
				It calculates the mean intensity either for slices (planes) along any the three cartesian axes (X, Y or Z), or for radial consecutive shells of increasing radius, 
				or for cylindrical shells of varying or fixed height, starting from the center of the volume. 
				All mean density values are saved to .txt files, and plots are produced with them and saved as .png images. In fact, to compare different volumes you can plot all curves in a single plot."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument('--path',
                        type=str,
                        default='spt_radialplot',
                        help="""Directory to save 
		the results.""")

    parser.add_argument("--input",
                        type=str,
                        help="""Volume whose radial density plot you 
		want to compute. For multiple volumes, either provide them as an .hdf stack, or 
		separate them by commas --vols=first.hdf,second.hdf,etc...""",
                        default='')

    parser.add_argument("--mode",
                        type=str,
                        help="""provide --mode=x, y, or z to get the 
		average density per slice in the indicated direction. 
		--mode=cylinder for concentric cylindrical shell; default is --mode=sphere.
		For MULTIPLE modes, separate them by commas, for example --mode=x,y,z,cylinder""",
                        default='sphere')

    parser.add_argument("--fixedcylinderheight",
                        type=int,
                        help="""Works only if --mode=cylinder, 
		and keeps the height of the cylinder at a constant value, while varying the radius.""",
                        default=0)

    parser.add_argument("--mask",
                        type=str,
                        help="""Masking processor (see e2help.py --verbose=10) 
		applied to each volume prior to radial density plot computation. Default=None.""",
                        default='')

    parser.add_argument("--normproc",
                        type=str,
                        help="""Normalization processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation. Default is None.
		If normalize.mask is used, results of the mask option will be passed in automatically.""",
                        default='')

    parser.add_argument("--preprocess",
                        type=str,
                        help="""Any processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""",
                        default='')

    parser.add_argument("--lowpass",
                        type=str,
                        help="""Default=None. A lowpass filtering processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""",
                        default='')

    parser.add_argument("--highpass",
                        type=str,
                        help="""Default=None. A highpass filtering processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""",
                        default='')

    parser.add_argument("--threshold",
                        type=str,
                        help="""Default=None. A threshold  processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""",
                        default='')

    parser.add_argument(
        "--shrink",
        type=int,
        default=1,
        help="""Default=1 (no shrinking). Optionally shrink the input 
		volumes by an integer amount.""")

    #parser.add_argument("--apix", type=float, help="Provide --apix to overrride the value found in the volumes' header paramter.", default=0)

    parser.add_argument("--singleplotperfile",
                        action="store_true",
                        default=False,
                        help="""
		Plot all the Radial Density Profiles of the volumes provided in each .hdf stack in 
		one single plot.""")

    parser.add_argument("--singlefinalplot",
                        action="store_true",
                        default=False,
                        help="""Plot 
		all the Radial Density Profiles of the volumes provided in all .hdf stacks in one 
		FINAL single 'master' plot.""")

    parser.add_argument("--normalizeplot",
                        action="store_true",
                        default=False,
                        help="""This 
		will make the maximum density in each plot or curve equal to 1.""")

    parser.add_argument("--savetxt",
                        action="store_true",
                        default=False,
                        help="""Save plot
		files as .txt, so that they can be replotted with other software if necessary."""
                        )

    parser.add_argument("--ppid",
                        type=int,
                        help="""Set the PID of the parent process, 
		used for cross platform PPID""",
                        default=-1)

    parser.add_argument("--verbose",
                        "-v",
                        default=0,
                        help="""Verbose level [0-9], higner 
		number means higher level of verboseness""",
                        dest="verbose",
                        action="store",
                        metavar="n",
                        type=int)

    parser.add_argument("--sym",
                        dest="sym",
                        default='c1',
                        help="""Symmetry to impose 
		- choices are: c<n>, d<n>, h<n>, tet, oct, icos.
		For this to make any sense in the context of this program, the particles need to be
		aligned to the symmetry axis first, which can be accomplished by running them 
		through e2symsearch3d.py.""")

    parser.add_argument("--classifymaxpeaks",
                        type=int,
                        default=0,
                        help="""Number of highest 
		peaks to consider for classification. Amongst the n peaks provided, --classifymaxpeaks=n,
		the peak occurring at the largest radius will be used as the classifier.
		If --classifymaxpeaks=1, the highest peak will be the classifier.
		To smooth the radial density curve consider low pass filtering through --lowpass.
		To remove aberrant peaks consider masking with --mask.""")

    parser.add_argument("--subset",
                        type=int,
                        default=0,
                        help="""An n-subset of particles from
		--input to use.""")

    (options, args) = parser.parse_args()

    import matplotlib.pyplot as plt
    #from matplotlib.ticker import MaxNLocator

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'spt_radialplot')

    if not options.input:
        parser.print_help()
        exit(0)
    elif options.subset:
        subsetStack = options.path + '/subset' + str(options.subset).zfill(
            len(str(options.subset))) + '.hdf'
        print "\nSubset to be written to", subsetStack

        subsetcmd = 'e2proc3d.py ' + options.input + ' ' + subsetStack + ' --first=0 --last=' + str(
            options.subset - 1)
        print "Subset cmd is", subsetcmd

        p = subprocess.Popen(subsetcmd,
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        text = p.communicate()
        p.stdout.close()

        options.input = subsetStack

    logger = E2init(sys.argv, options.ppid)

    if options.normproc:
        options.normproc = parsemodopt(options.normproc)

    if options.mask:
        options.mask = parsemodopt(options.mask)

    if options.preprocess:
        options.preprocess = parsemodopt(options.preprocess)

    if options.lowpass:
        options.lowpass = parsemodopt(options.lowpass)

    if options.highpass:
        options.highpass = parsemodopt(options.highpass)

    if options.threshold:
        options.threshold = parsemodopt(options.threshold)

    files = options.input
    files = files.split(',')

    for i in xrange(0, len(files)):
        for j in range(i + 1, len(files)):
            if files[i] == files[j]:
                print "ERROR: You have supplied a file twice, see", files[
                    i], files[j]
                sys.exit()
    modes = options.mode.split(',')

    for m in modes:
        options.mode = m
        modetag = '_MODE' + m
        finalvalues = {}
        imgsperstack = 1

        names = []
        finalvalues = []
        maxsall = {}
        minsall = {}

        for i in files:
            n = EMUtil.get_image_count(i)

            print "The stack %s has %d images in it" % (i, n)

            kk = 0
            stack = {}
            stackvalues = []
            suffix = modetag
            for j in range(n):
                ptcl = EMData(i, j)
                if n > 1:
                    suffix = modetag + str(kk).zfill(len(str(n)))

                values = calcvalues(ptcl, options)

                ret = calcmaxima(values)
                maxima = ret[
                    0]  #These are a list of lists [[pixel,value],[pixel,value],...] with all maxima and minima
                minima = ret[-1]

                uniquetag = i + '_indxtag' + str(j)
                maxsall.update({uniquetag: maxima})
                minsall.update({uniquetag: minima})

                print "For file %s img number %d the max is %f" % (i, j,
                                                                   max(values))

                if options.normalizeplot:

                    minv = min(values)
                    for v in range(len(values)):
                        values[v] = values[v] - minv

                    maxv = max(values)
                    for v in range(len(values)):
                        values[v] = values[v] / maxv
                    print "Therefore, max is", max(values)

                id = i.replace('.', suffix + '.')
                stackvalues.append([id, values])
                kk += 1
            stack.update({i: stackvalues})
            finalvalues.append(stack)

        plotname = 'finalplot_MODE' + m + '.png'
        fileid = ''

        if options.classifymaxpeaks:
            classifymax(options, maxsall)

        cc = 0
        for ele in finalvalues:
            i = ele.keys()[0]
            key = i

            n = EMUtil.get_image_count(i)

            if options.singleplotperfile:
                fileid = i.split('.')[0]
                plotname = fileid + modetag + '.png'

            kk = 0
            for f in range(n):
                apix = EMData(i, f, True)['apix_x']

                values = ele[key][f][1]
                id = ele[key][f][0]

                x = range(len(values))

                for j in range(len(x)):
                    x[j] = int(round(x[j] * apix))

                if options.savetxt:
                    txtname = options.path + '/' + i.split(
                        '.')[0] + modetag + str(kk).zfill(len(str(n))) + '.txt'
                    txtf = open(txtname, 'w')
                    lines = []
                    for v in range(len(values)):
                        line = str(v) + ' ' + str(values[v]) + '\n'
                        lines.append(line)
                    txtf.writelines(lines)
                    txtf.close()

                plt.plot(x, values, linewidth=2, alpha=0.5)

                if not options.singleplotperfile and not options.singlefinalplot:
                    #plotname=i.split('.')[0]+str(kk).zfill(len(str(n))) + '.png'
                    plotname = id.split('.')[0] + '.png'
                    fileid = plotname.split('.')[0]

                if options.mode == 'sphere':
                    plt.title("Spherical radial density plot " + fileid)
                    plt.xlabel("Radius (angstroms)")
                    plt.ylabel("Density (arbitrary units)")

                if options.mode == 'x':
                    plt.title("Density plot of slices along x-axis " + fileid)
                    plt.xlabel("X (angstroms)")
                    plt.ylabel("Density (arbitrary units)")

                if options.mode == 'y':
                    plt.title("Density plot of slices along y-axis " + fileid)
                    plt.xlabel("Y (angstroms)")
                    plt.ylabel("Density (arbitrary units)")

                if options.mode == 'z':
                    plt.title("Density plot of slices along z-axis " + fileid)
                    plt.xlabel("Z (angstroms)")
                    plt.ylabel("Density (arbitrary units)")

                if options.mode == 'cylinder':
                    plt.title(
                        "Density plot of concentric cylyndrical shells " +
                        fileid)
                    plt.xlabel("Radius (angstroms)")
                    plt.ylabel("Density (arbitrary units)")

                if not options.singleplotperfile and not options.singlefinalplot:
                    if options.path not in plotname:
                        plotname = options.path + '/' + plotname
                    plt.savefig(plotname)
                    plt.clf()
                else:
                    pass
                kk += 1
                cc += 1

            if options.singleplotperfile:
                if options.path not in plotname:
                    plotname = options.path + '/' + plotname
                plt.savefig(plotname)
                plt.clf()

        if options.singlefinalplot:
            if options.path not in plotname:
                plotname = options.path + '/' + plotname
            plt.savefig(plotname)
            plt.clf()
    return
Beispiel #5
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] 
	This program aligns a paricle to its symmetry axis. There are two algorithmic modes. 
	A coarse search followed by simplex minimization (not yet implimented) OR monte carlo course 
	search followed by simplex minimization. The Goal is to align the paricle to its 
	symmetry axis so symmetry can be applied for avergaing and for alignment speed up 
	(it is only necessary to search over one asymmetric unit!
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_header(
        name="symsearch3dheader",
        help="""Options below this label are specific to e2symsearch3d""",
        title="### e2symsearch3d options ###",
        row=3,
        col=0,
        rowspan=1,
        colspan=2)

    parser.add_argument(
        "--input",
        dest="input",
        default='',
        type=str,
        help="""The name of input volume or hdf stack of volumes""",
        guitype='filebox',
        browser="EMBrowserWidget(withmodal=True,multiselect=False)",
        row=0,
        col=0,
        rowspan=1,
        colspan=2)

    #parser.add_argument("--output", dest="output", default="""e2symsearch3d_OUTPUT.hdf""", type=str, help="The name of the output volume", guitype='strbox', filecheck=False, row=1, col=0, rowspan=1, colspan=2)

    parser.add_argument(
        "--ref",
        type=str,
        default='',
        help=
        """Default=None. If provided and --average is also provided and --keep < 1.0 or --keepsig is specified, 'good particles' will be determined by correlation to --ref."""
    )

    parser.add_argument(
        "--mirror",
        type=str,
        default='',
        help=
        """Axis across of which to generate a mirrored copy of --ref. All particles will be compared to it in addition to the unmirrored image in --ref if --keepsig is provided or if --keep < 1.0."""
    )

    parser.add_argument("--path",
                        type=str,
                        default='',
                        help="""Name of path for output file""",
                        guitype='strbox',
                        row=2,
                        col=0,
                        rowspan=1,
                        colspan=2)

    parser.add_argument(
        "--plots",
        action='store_true',
        default=False,
        help=
        """Default=False. Turn this option on to generate a plot of the ccc scores if --average is supplied. Running on a cluster or via ssh remotely might not support plotting."""
    )

    parser.add_argument(
        "--sym",
        dest="sym",
        default="c1",
        help=
        """Specify symmetry -choices are: c<n>, d<n>, h<n>, tet, oct, icos. For asymmetric reconstruction ommit this option or specify c1.""",
        guitype='symbox',
        row=4,
        col=0,
        rowspan=1,
        colspan=2)

    parser.add_argument(
        "--shrink",
        dest="shrink",
        type=int,
        default=0,
        help=
        """Optionally shrink the input particles by an integer amount prior to computing similarity scores. For speed purposes. Default=0, no shrinking""",
        guitype='shrinkbox',
        row=5,
        col=0,
        rowspan=1,
        colspan=1)

    parser.add_argument(
        "--mask",
        type=str,
        help=
        """Mask processor applied to particles before alignment. Default is mask.sharp:outer_radius=-2. IF using --clipali, make sure to express outer mask radii as negative pixels from the edge.""",
        returnNone=True,
        default="mask.sharp:outer_radius=-2",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'mask\')',
        row=11,
        col=0,
        rowspan=1,
        colspan=3)

    parser.add_argument(
        "--maskfile",
        type=str,
        default='',
        help=
        """Mask file (3D IMAGE) applied to particles before alignment. Must be in HDF format. Default is None."""
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default='',
        help=
        """Normalization processor applied to particles before alignment. Default is to use normalize. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'"""
    )

    parser.add_argument(
        "--threshold",
        default='',
        type=str,
        help=
        """A threshold applied to the subvolumes after normalization. For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=10,
        col=0,
        rowspan=1,
        colspan=3)

    parser.add_argument(
        "--preprocess",
        default='',
        type=str,
        help=
        """Any processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=10,
        col=0,
        rowspan=1,
        colspan=3)

    parser.add_argument(
        "--lowpass",
        type=str,
        default='',
        help=
        """A lowpass filtering processor (from e2proc3d.py; see e2help.py processors) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=17,
        col=0,
        rowspan=1,
        colspan=3)

    parser.add_argument(
        "--highpass",
        type=str,
        default='',
        help=
        """A highpass filtering processor (from e2proc3d.py, see e2help.py processors) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=18,
        col=0,
        rowspan=1,
        colspan=3)

    parser.add_argument(
        "--clipali",
        type=int,
        default=0,
        help=
        """Boxsize to clip particles as part of preprocessing to speed up alignment. For example, the boxsize of the particles might be 100 pixels, but the particles are only 50 pixels in diameter. Aliasing effects are not always as deleterious for all specimens, and sometimes 2x padding isn't necessary; still, there are some benefits from 'oversampling' the data during averaging; so you might still want an average of size 2x, but perhaps particles in a box of 1.5x are sufficiently good for alignment. In this case, you would supply --clipali=75"""
    )

    parser.add_argument(
        "--savepreprocessed",
        action="store_true",
        default=False,
        help=
        """Default=False. Will save stacks of preprocessed particles (one for coarse alignment and one for fine alignment if preprocessing options are different)."""
    )

    parser.add_argument(
        "--average",
        action='store_true',
        default=False,
        help=
        """Default=False. If supplied and a stack is provided through --input, the average of the aligned and/or symmetrized stack will also be saved."""
    )

    parser.add_argument(
        "--averager",
        type=str,
        default="mean.tomo",
        help=
        """Default=mean.tomo. The type of averager used to produce the class average. Default=mean.tomo."""
    )

    parser.add_argument(
        "--keep",
        type=float,
        default=1.0,
        help=
        """Fraction of particles to include if --average is on, after correlating the particles with the average."""
    )

    parser.add_argument(
        "--keepsig",
        action="store_true",
        default=False,
        help=
        """Default=False. Causes theoptions.keep argument to be interpreted in standard deviations.""",
        guitype='boolbox',
        row=6,
        col=1,
        rowspan=1,
        colspan=1,
        mode='alignment,breaksym')

    parser.add_argument(
        "--avgiter",
        type=int,
        default=1,
        help=
        """Default=1. If --keep is different from 1.0 and --average is on, the initial average will include all the particles, but then the percent specified byoptions.keep will be kept (the rest thrown away) and a new average will be computed. If --avgiter > 1, this new average will be compared again against all the particles. The procedure will be repeated for however many iterations --avgiter is given, or the process will stop automatically if in two consecutive rounds exactly the same particles are kept"""
    )

    parser.add_argument(
        '--subset',
        type=int,
        default=0,
        help=
        """Number of particles in a subset of particles from the --input stack of particles to run the alignments on."""
    )

    parser.add_argument("--steps",
                        dest="steps",
                        type=int,
                        default=10,
                        help="""Number of steps (for the MC). Default=10.""",
                        guitype='intbox',
                        row=5,
                        col=1,
                        rowspan=1,
                        colspan=1)

    parser.add_argument("--symmetrize",
                        default=False,
                        action="store_true",
                        help="""Symmetrize volume after alignment.""",
                        guitype='boolbox',
                        row=6,
                        col=0,
                        rowspan=1,
                        colspan=1)

    parser.add_argument(
        "--cmp",
        type=str,
        help=
        """The name of a 'cmp' to be used in comparing the symmtrized object to unsymmetrized""",
        default="ccc",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_cmps_list(),\'tomo\', True)',
        row=7,
        col=0,
        rowspan=1,
        colspan=2)

    parser.add_argument(
        "--parallel",
        "-P",
        type=str,
        help=
        """Run in parallel, specify type:<option>=<value>:<option>:<value>""",
        default=None,
        guitype='strbox',
        row=8,
        col=0,
        rowspan=1,
        colspan=2)

    parser.add_argument(
        "--ppid",
        type=int,
        help=
        """Set the PID of the parent process, used for cross platform PPID.""",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        """verbose level [0-9], higner number means higher level ofoptions.verboseness."""
    )

    parser.add_argument(
        "--nopath",
        action='store_true',
        default=False,
        help=
        """If supplied, this option will save results in the directory where the command is run. A directory to store the results will not be made."""
    )

    parser.add_argument(
        "--nolog",
        action='store_true',
        default=False,
        help=
        """If supplied, this option will prevent logging the command run in .eman2log.txt."""
    )

    parser.add_argument(
        "--saveali",
        action='store_true',
        default=False,
        help="""Save the stack of aligned/symmetrized particles.""")

    parser.add_argument(
        "--savesteps",
        action='store_true',
        default=False,
        help=
        """If --avgiter > 1, save all intermediate averages and intermediate aligned kept stacks."""
    )

    parser.add_argument(
        "--notmatchimgs",
        action='store_true',
        default=False,
        help=
        """Default=True. This option prevents applying filter.match.to to one image so that it matches the other's spectral profile during preprocessing for alignment purposes."""
    )

    parser.add_argument(
        "--preavgproc1",
        type=str,
        default='',
        help=
        """Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)"""
    )

    parser.add_argument(
        "--preavgproc2",
        type=str,
        default='',
        help=
        """Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)"""
    )

    parser.add_argument(
        "--weighbytiltaxis",
        type=str,
        default='',
        help=
        """Default=None. A,B, where A is an integer number and B a decimal. A represents the location of the tilt axis in the tomogram in pixels (eg.g, for a 4096x4096xZ tomogram, this value should be 2048), and B is the weight of the particles furthest from the tomogram. For example, --weighbytiltaxis=2048,0.5 means that praticles at the tilt axis (with an x coordinate of 2048) will have a weight of 1.0 during averaging, while the distance in the x coordinates of particles not-on the tilt axis will be used to weigh their contribution to the average, with particles at the edge(0+radius or 4096-radius) weighing 0.5, as specified by the value provided for B."""
    )

    parser.add_argument(
        "--weighbyscore",
        action='store_true',
        default=False,
        help=
        """Default=False. This option will weigh the contribution of each subtomogram to the average by score/bestscore."""
    )

    parser.add_argument(
        "--align",
        type=str,
        default='symalignquat',
        help=
        """Default=symalignquat. WARNING: The aligner cannot be changed for this program currently. Option ignored."""
    )

    parser.add_argument(
        "--tweak",
        action='store_true',
        default=False,
        help=
        """WARNING: Not used for anything yet. This will perform a final alignment with no downsampling [without using --shrink or --shrinkfine] if --shrinkfine > 1."""
    )

    (options, args) = parser.parse_args()

    if not options.input:
        parser.print_help()
        sys.exit(0)

    #If no failures up until now, initialize logger
    log = 0
    if not options.nolog:
        logid = E2init(sys.argv, options.ppid)
        log = 1

    #inimodeldir = os.path.join(".",options.path)
    #if not os.access(inimodeldir, os.R_OK):
    #	os.mkdir(options.path)

    #Make directory to save results
    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'symsearch')

    if options.nopath:
        options.path = '.'

    rootpath = os.getcwd()

    if rootpath not in options.path:
        options.path = rootpath + '/' + options.path

    from e2spt_classaverage import preprocessing
    from EMAN2PAR import EMTaskCustomer
    from e2spt_classaverage import sptOptionsParser

    options = sptOptionsParser(options)

    avgr = Averagers.get(options.averager[0], options.averager[1])
    results = {}
    scores = []

    outputstack = options.path + '/all_ptcls_ali.hdf'

    #Determine number of particles in the stack
    n = EMUtil.get_image_count(options.input)
    if options.subset and options.subset < n:
        n = options.subset

    for i in range(n):

        print "\nI'll look for symmetry in particle number", i
        #Load particle and make a copy to modify if preprocessing options are specified
        volume = EMData(options.input, i)
        preprocvol = volume.copy()

        #Preprocess volume if any preprocessing options are specified
        if (
                options.shrink and options.shrink > 1
        ) or options.mask or options.maskfile or options.lowpass or options.highpass or options.normproc or options.preprocess or options.threshold or options.clipali:
            print "\nHowever, I will first preprocess particle number", i

            print "\nWill call preprocessing on ptcl", i
            preprocvol = preprocessing(preprocvol, options, i)
            #preprocessing(s2image,options, ptclindx, savetagp ,'no',round)

            print "\nDone preprocessing on ptcl", i

        if options.parallel:
            etc = EMTaskCustomer(options.parallel)
        else:
            etc = EMTaskCustomer("thread:1")

        symalgorithm = SymALignStrategy(preprocvol, options.sym, options.steps,
                                        options.cmp, etc)
        ret = symalgorithm.execute()
        symxform = ret[0]
        score = ret[1]
        scores.append(score)
        results.update({score: [symxform, i]})

        print "\nWriting output for best alignment found for particle number", i

        if options.shrink and options.shrink > 1:
            trans = symxform.get_trans()
            symxform.set_trans(trans[0] * options.shrink,
                               trans[1] * options.shrink,
                               trans[2] * options.shrink)

        print "\nWrittng to output ptcl", i

        #Rotate volume to the best orientation found, set the orientation in the header, apply symmetry if specified and write out the aligned (and symmetrized) particle to the output stack
        output = volume.process('xform', {'transform': symxform})
        output.set_attr('symxform', symxform)
        print "\nApplying this transform to particle", symxform
        if options.symmetrize:
            output = output.process('xform.applysym', {'sym': options.sym})

        output['spt_score'] = score
        output.write_image(outputstack, -1)

        #Averaging here only makes sense if all particles are going to be kept. Otherwise, different code is needed (below)
        if options.average and options.keep == 1.0 and not options.keepsig:
            avgr.add_image(output)

    #Finalize average of all particles if non were set to be excluded. Otherwise, determine the discrimination threshold and then average the particles that pass it.
    if options.average:

        final_avg = avgr.finish()

        final_avg['origin_x'] = 0
        final_avg[
            'origin_y'] = 0  #The origin needs to be reset to ZERO to avoid display issues in Chimera
        final_avg['origin_z'] = 0
        final_avg['xform.align3d'] = Transform()

        if options.keep == 1.0 and not options.keepsig:
            final_avg.write_image(options.path + '/final_avg.hdf', 0)

            if options.avgiter > 1:
                print """WARNING: --avgiter > 1 must be accompanied by --keepsig, or by --keep < 1.0"""

        elif options.keep < 1.0 or options.keepsig:

            if options.ref:
                ref = EMData(options.ref, 0)
                refComp(options, outputstack, ref, results, '')

                if options.mirror:
                    ref.process_inplace('xform.mirror',
                                        {'axis': options.mirror})
                    refComp(options, outputstack, ref, results, '_vs_mirror')
            else:
                ref2compare = final_avg
                refComp(options, outputstack, final_avg, results, '')

    if log:
        E2end(logid)

    return
Beispiel #6
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog <output> [options]
	Program to build an initial subtomogram average by averaging pairs from the largest subset
	in --input that is a power of 2. For example, if you supply an input stack with 100 subtomograms,
	this program will build an initial reference using 64, since 64 is the largest power of 2 contained in 100.
	In the first iteration, particle 1 will be averaged with 2, 3 with 4, 5 with 6... etc.
	32 new averages (each an average of 2 subtomograms) will be used for the second iteration.
	Again, 1 will be averaged with 2, 3 with 4, etc... yielding 16 new averages.
	The algorithm continues until the entire subset (64) has been merged into 1 average.
	
	This program imports 'preprocfunc' from e2spt_preproc.py and 'alignment' from e2spt_classaverage.py
	
	--mask=mask.sharp:outer_radius=<safe radius>
	--preprocess=filter.lowpass.gauss:cutoff_freq=<1/resolution in A>
	"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_header(name="sptbtheader", help="""Options below this label are specific to 
		sptbinarytree""", title="### sptbinarytree options ###", row=6, col=0, rowspan=1, colspan=3,mode="align")
	
	parser.add_header(name="caheader", help="""Options below this label are specific to sptclassaverage""", title="### sptclassaverage options ###", row=3, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--path",type=str,default='spt',help="""Default=spt. Directory to store results in. The default is a numbered series of directories containing the prefix 'spt'; for example, spt_02 will be the directory by default if 'spt_01' already exists.""")
	
	parser.add_argument("--input", type=str, default='',help="""Default=None. The name of the input volume stack. MUST be HDF since volume stack support is required.""", guitype='filebox', browser='EMSubTomosTable(withmodal=True,multiselect=False)', row=0, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--npeakstorefine", type=int, help="""Default=1. The number of best coarse alignments to refine in search of the best final alignment. Default=1.""", default=4, guitype='intbox', row=9, col=0, rowspan=1, colspan=1, nosharedb=True, mode='alignment,breaksym[1]')

	parser.add_argument("--parallel",default="thread:1",help="""default=thread:1. Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel""", guitype='strbox', row=19, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--ppid", type=int, help="""Default=-1. Set the PID of the parent process, used for cross platform PPID""",default=-1)
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n", type=int, default=0, help="""Default=0. Verbose level [0-9], higner number means higher level of verboseness""")
		
	#parser.add_argument("--resume",type=str,default='',help="""(Not working currently). tomo_fxorms.json file that contains alignment information for the particles in the set. If the information is incomplete (i.e., there are less elements in the file than particles in the stack), on the first iteration the program will complete the file by working ONLY on particle indexes that are missing. For subsequent iterations, all the particles will be used.""")
															
	parser.add_argument("--plots", action='store_true', default=False,help="""Default=False. Turn this option on to generatea plot of the ccc scores during each iteration. Running on a cluster or via ssh remotely might not support plotting.""")

	parser.add_argument("--subset",type=int,default=0,help="""Default=0 (not used). Refine only this substet of particles from the stack provided through --input""")
	
	parser.add_argument("--preavgproc1",type=str,default='',help="""Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)""")
	
	parser.add_argument("--preavgproc2",type=str,default='',help="""Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)""")

	parser.add_argument("--weighbytiltaxis",type=str,default='',help="""Default=None. A,B, where A is an integer number and B a decimal. A represents the location of the tilt axis in the tomogram in pixels (eg.g, for a 4096x4096xZ tomogram, this value should be 2048), and B is the weight of the particles furthest from the tomogram. For example, --weighbytiltaxis=2048,0.5 means that praticles at the tilt axis (with an x coordinate of 2048) will have a weight of 1.0 during averaging, while the distance in the x coordinates of particles not-on the tilt axis will be used to weigh their contribution to the average, with particles at the edge(0+radius or 4096-radius) weighing 0.5, as specified by the value provided for B.""")
	
	parser.add_argument("--weighbyscore",action='store_true',default=False,help="""Default=False. This option will weigh the contribution of each subtomogram to the average by score/bestscore.""")
	
	parser.add_argument("--align",type=str,default="rotate_translate_3d:search=8:delta=12:dphi=12",help="""This is the aligner used to align particles to the previous class average. Default is rotate_translate_3d:search=8:delta=12:dphi=12, specify 'None' (with capital N) to disable.""", returnNone=True,guitype='comboparambox', choicelist='re_filter_list(dump_aligners_list(),\'3d\')', row=12, col=0, rowspan=1, colspan=3, nosharedb=True, mode="alignment,breaksym['rotate_symmetry_3d']")
	
	parser.add_argument("--aligncmp",type=str,default="ccc.tomo.thresh",help="""Default=ccc.tomo.thresh. The comparator used for the --align aligner. Do not specify unless you need to use anotherspecific aligner.""",guitype='comboparambox',choicelist='re_filter_list(dump_cmps_list(),\'tomo\')', row=13, col=0, rowspan=1, colspan=3,mode="alignment,breaksym")
	
	
	#parser.add_argument("--output", type=str, default='avg.hdf', help="""Default=avg.hdf. The name of the output class-average stack. MUST be HDF since volume stack support is required.""", guitype='strbox', row=2, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	#parser.add_argument("--classmx", type=str, default='', help="""Default=None. The name of the classification matrix specifying how particles in 'input' should be grouped. If omitted, all particles will be averaged.""")
	
	#parser.add_argument("--ref", type=str, default='', help="""Default=None. Reference image(s). Used as an initial alignment reference and for final orientation adjustment if present. This is typically the projections that were used for classification.""", guitype='filebox', browser='EMBrowserWidget(withmodal=True,multiselect=True)', filecheck=False, row=1, col=0, rowspan=1, colspan=3, mode='alignment')
	
	#parser.add_argument("--refpreprocess",action="store_true",default=False,help="""Default=False. This will preprocess the reference identically to the particles. It is off by default, but it is internally turned on when no reference is supplied.""")
	
	#parser.add_argument("--resultmx",type=str,default=None,help="""Default=Npone. Specify an output image to store the result matrix. This is in the same format as the classification matrix. http://blake.bcm.edu/emanwiki/EMAN2/ClassmxFiles""")
	
	#parser.add_argument("--refinemultireftag", type=str, default='', help="""Default=''. DO NOT USE THIS PARAMETER. It is passed on from e2spt_refinemulti.py if needed.""")

	'''
	ADVANCED parameters
	
	'''
	parser.add_argument("--averager",type=str,default="mean.tomo",help="""Default=mean.tomo. The type of averager used to produce the class average. Default=mean.tomo.""")

	'''
	PRE-FFT processing parameters
	'''
	
	#parser.add_argument("--nopreprocprefft",action="store_true",default=False,help="""Turns off all preprocessing that happens only once before alignment (--normproc, --mask, --maskfile, --clipali, --threshold; i.e., all preprocessing excepting filters --highpass, --lowpass, --preprocess, and --shrink.""")

	parser.add_argument("--shrink", type=int,default=1,help="""Default=1 (no shrinking). Optionally shrink the input volumes by an integer amount for coarse alignment.""", guitype='shrinkbox', row=5, col=1, rowspan=1, colspan=1, mode='alignment,breaksym')
	
	parser.add_argument("--shrinkfine", type=int,default=1,help="""Default=1 (no shrinking). Optionally shrink the input volumes by an integer amount for refine alignment.""", guitype='intbox', row=5, col=2, rowspan=1, colspan=1, mode='alignment')
	
	parser.add_argument("--threshold",type=str,default='',help="""Default=None. A threshold applied to the subvolumes after normalization. For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=10, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--mask",type=str,default='', help="""Default=None. Masking processor applied to particles before alignment. IF using --clipali, make sure to express outer mask radii as negative pixels from the edge.""", returnNone=True, guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'mask\')', row=11, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--maskfile",type=str,default='',help="""Default=None. Mask file (3D IMAGE) applied to particles before alignment. Must be in HDF format. Default is None.""")
	
	parser.add_argument("--normproc",type=str, default='',help="""Default=None (see 'e2help.py processors -v 10' at the command line). Normalization processor applied to particles before alignment. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'""")
	
	parser.add_argument("--clipali",type=int,default=0,help="""Default=0 (which means it's not used). Boxsize to clip particles as part of preprocessing to speed up alignment. For example, the boxsize of the particles might be 100 pixels, but the particles are only 50 pixels in diameter. Aliasing effects are not always as deleterious for all specimens, and sometimes 2x padding isn't necessary; still, there are some benefits from 'oversampling' the data during averaging; so you might still want an average of size 2x, but perhaps particles in a box of 1.5x are sufficiently good for alignment. In this case, you would supply --clipali=75""")

	
	'''
	POST-FFT filtering parameters
	'''
	parser.add_argument("--preprocess",type=str,default='',help="""Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=10, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--preprocessfine",type=str,default='',help="""Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging.""")
	
	parser.add_argument("--lowpass",type=str,default='',help="""Default=None. A lowpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=17, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--lowpassfine",type=str,default='',help="""Default=None. A lowpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging.""")

	parser.add_argument("--highpass",type=str,default='',help="""Default=None. A highpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=18, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--highpassfine",type=str,default='',help="""Default=None. A highpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging.""")

	parser.add_argument("--matchimgs",action='store_true',default=False,help="""Default=False. Applies filter.matchto to one image so that it matches the other's spectral profile during preprocessing for pair-wise alignment purposes.""")
	
	parser.add_argument("--filterbyfsc",action='store_true',default=False,help="""Default=False. If on, this parameter will use dynamic FSC filtering. --lowpass will be used to build initial references if no --ref supplied, then, the FSC between the even and odd initial references will be used to filter the data during preprocessing. If --ref is supplied, --lowpass will be used during the first iteration to align the particles against the reference. Thereafter, the FSC between the most current particle average and the original reference (--ref) will be used in the next iteration.""")

	
	'''
	OTHER ADVANCED parameters
	'''
	parser.add_argument("--radius", type=float, default=0, help="""Default=0 (which means it's not used by default). Hydrodynamic radius of the particle in Angstroms. This will be used to automatically calculate the angular steps to use in search of the best alignment. Make sure the apix is correct on the particles' headers, sine the radius will be converted from Angstroms to pixels. Then, the fine angular step is equal to 360/(2*pi*radius), and the coarse angular step 4 times that.""")
	
	parser.add_argument("--precision",type=float,default=1.0,help="""Default=1.0. Precision in pixels to use when figuring out alignment parameters automatically using --radius. Precision would be the number of pixels that the the edge of the specimen is moved (rotationally) during the finest sampling, --falign. If precision is 1, then the precision of alignment will be that of the sampling (apix of your images) times the --shrinkfine factor specified.""")
	
	parser.add_argument("--search", type=int,default=8,help=""""Default=8. During COARSE alignment translational search in X, Y and Z, in pixels. Default=8. This WILL overwrite any search: provided through --align, EXCEPT if you provide --search=8, which is the default. In general, just avoid providing search twice (through here and through the aligner, --align). If you do, just be careful to make them consistent to minimize misinterpretation and error.""")
	
	parser.add_argument("--searchfine", type=int,default=2,help=""""Default=2. During FINE alignment translational search in X, Y and Z, in pixels. Default=2. This WILL overwrite any search: provided through --falign, EXCEPT if you provide --searchfine=2, which is the default. In general, just avoid providing search twice (through here and through the fine aligner --falign). If you do, just be careful to make them consistent to minimize misinterpretation and error.""")
	
	#parser.add_argument("--donotaverage",action="store_true", help="""If e2spt_refinemulti.py is calling e2spt_classaverage.py, the latter need not average any particles, but rather only yield the alignment results.""", default=False)
	
	parser.add_argument("--iterstop", type=int, default=0, help="""Default=0. (Not used). The program is called to convergence by default (all particles merge into one final average). To stop at an intermediate iteration, provide this parameter. For example, --iterstop=1, will only allow the algorithm to complete 1 iteration; --iterstop=2 will allow it to go through 2, etc.""")
	
	parser.add_argument("--savesteps",action="store_true", default=False, help="""Default=False. If set, will save the average after each iteration to class_#.hdf. Each class in a separate file. Appends to existing files.""", guitype='boolbox', row=4, col=0, rowspan=1, colspan=1, mode='alignment,breaksym')
	
	parser.add_argument("--saveali",action="store_true", default=False, help="""Default=False. If set, will save the aligned particle volumes in class_ptcl.hdf. Overwrites existing file.""", guitype='boolbox', row=4, col=1, rowspan=1, colspan=1, mode='alignment,breaksym')
	
	parser.add_argument("--saveallalign",action="store_true", default=False, help="""Default=False. If set, will save the alignment parameters after each iteration""", guitype='boolbox', row=4, col=2, rowspan=1, colspan=1, mode='alignment,breaksym')
	
	parser.add_argument("--sym", dest = "sym", default='', help = """Default=None (equivalent to c1). Symmetry to impose -choices are: c<n>, d<n>, h<n>, tet, oct, icos""", guitype='symbox', row=9, col=1, rowspan=1, colspan=2, mode='alignment,breaksym')
	
	parser.add_argument("--postprocess",type=str,default='',help="""A processor to be applied to the FINAL volume after averaging the raw volumes in their FINAL orientations, after all iterations are done.""",guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=16, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	
	parser.add_argument("--procfinelikecoarse",action='store_true',default=False,help="""If you supply this parameters, particles for fine alignment will be preprocessed identically to particles for coarse alignment by default. If you supply this, but want specific parameters for preprocessing particles for also supply: fine alignment, nd supply fine alignment parameters, such as --lowpassfine, --highpassfine, etc; to preprocess the particles for FINE alignment differently than for COARSE alignment.""")
	
	
	
	parser.add_argument("--falign",type=str,default='',help="""Default=None. This is the second stage aligner used to fine-tune the first alignment.""", returnNone=True, guitype='comboparambox', choicelist='re_filter_list(dump_aligners_list(),\'refine.*3d\')', row=14, col=0, rowspan=1, colspan=3, nosharedb=True, mode='alignment,breaksym[None]')
		
	parser.add_argument("--faligncmp",type=str,default="ccc.tomo.thresh",help="""Default=ccc.tomo.thresh. The comparator used by the second stage aligner.""", guitype='comboparambox', choicelist='re_filter_list(dump_cmps_list(),\'tomo\')', row=15, col=0, rowspan=1, colspan=3,mode="alignment,breaksym")		
		
	
	#parser.add_argument("--nopreprocprefft",action="store_true",default=False,help="""Turns off all preprocessing that happens only once before alignment (--normproc, --mask, --maskfile, --clipali, --threshold; i.e., all preprocessing excepting filters --highpass, --lowpass, --preprocess, and --shrink.""")
	
	#parser.add_argument("--keep",type=float,default=1.0,help="""Default=1.0 (all particles kept). The fraction of particles to keep in each class.""", guitype='floatbox', row=6, col=0, rowspan=1, colspan=1, mode='alignment,breaksym')
	
	#parser.add_argument("--keepsig", action="store_true", default=False,help="""Default=False. Causes the keep argument to be interpreted in standard deviations.""", guitype='boolbox', row=6, col=1, rowspan=1, colspan=1, mode='alignment,breaksym')

	#parser.add_argument("--inixforms",type=str,default="",help="""Default=None. .json file containing a dict of transforms to apply to 'pre-align' the particles.""", guitype='dirbox', dirbasename='spt_|sptsym_', row=7, col=0,rowspan=1, colspan=2, nosharedb=True, mode='breaksym')
	
	parser.add_argument("--breaksym",action="store_true", default=False,help="""Default=False. Break symmetry. Do not apply symmetrization after averaging, even if searching the asymmetric unit provided through --sym only for alignment. Default=False""", guitype='boolbox', row=7, col=2, rowspan=1, colspan=1, nosharedb=True, mode=',breaksym[True]')
	
	#parser.add_argument("--groups",type=int,default=0,help="""Default=0 (not used; data not split). This parameter will split the data into a user defined number of groups. For purposes of gold-standard FSC computation later, select --group=2.""")
		
	parser.add_argument("--randomizewedge",action="store_true",  default=False,help="""Default=False. This parameter is EXPERIMENTAL. It randomizes the position of the particles BEFORE alignment, to minimize missing wedge bias and artifacts during symmetric alignment where only a fraction of space is scanned""")
	
	#parser.add_argument("--savepreproc",action="store_true",  default=False,help="""Default=False. Will save stacks of preprocessed particles (one for coarse alignment and one for fine alignment if preprocessing options are different).""")
	
	parser.add_argument("--autocenter",type=str, default='',help="""Default=None. Autocenters each averaged pair during initial average generation with --btref and --hacref. Will also autocenter the average of all particles after each iteration of iterative refinement. Options are --autocenter=xform.centerofmass (self descriptive), or --autocenter=xform.centeracf, which applies auto-convolution on the average.""")
	
	parser.add_argument("--autocentermask",type=str, default='',help="""Default=None. Masking processor to apply before autocentering. See 'e2help.py processors -v 10' at the command line.""")
	
	parser.add_argument("--autocenterpreprocess",action='store_true', default=False,help="""Default=False. This will apply a highpass filter at a frequency of half the box size times the apix, shrink by 2, and apply a low pass filter at half nyquist frequency to any computed average for autocentering purposes if --autocenter is provided. Default=False.""")
	
	
	
	parser.add_argument("--tweak",action='store_true',default=False,help="""WARNING: BUGGY. This will perform a final alignment with no downsampling [without using --shrink or --shrinkfine] if --shrinkfine > 1.""")


	'''
	BT SPECIFIC PARAMETERS
	'''
	
		
	parser.add_argument("--nseedlimit",type=int,default=0,help="""Maximum number of particles
		to use. For example, if you supply a stack with 150 subtomograms, the program will
		automatically select 128 as the limit to use because it's the largest power of 2 that is
		smaller than 150. But if you provide, say --nseedlimit=100, then the number of particles
		used will be 64, because it's the largest power of 2 that is still smaller than 100.""")
	
	

	(options, args) = parser.parse_args()
	
	options.nopreprocprefft = False
	
	
	if options.shrink < options.shrinkfine:
		options.shrink = options.shrinkfine
		print "\n(e2spt_binarytree)(main) it makes no sense for shrinkfine to be larger than shrink; therefore, shrink will be made to match shrinkfine"
	
	from e2spt_classaverage import checksaneimagesize	
	checksaneimagesize( options, options.input )
	
	'''
	Make the directory where to create the database where the results will be stored
	'''
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'spt_bt')
	
	rootpath = os.getcwd()
	if rootpath not in options.path:
		options.path = rootpath + '/' + options.path
	
	
	if not options.input:
		parser.print_help()
		exit(0)
	elif options.subset:
		subsetStack = options.path + '/subset' + str( options.subset ).zfill( len( str( options.subset))) + '.hdf' 
		print "\nSubset to be written to", subsetStack
		
		subsetcmd = 'e2proc3d.py ' + options.input + ' ' + subsetStack + ' --first=0 --last=' + str(options.subset-1) 
		print "Subset cmd is", subsetcmd
		
		p=subprocess.Popen( subsetcmd, shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE )
		text=p.communicate()	
		p.stdout.close()
		
		options.input = subsetStack
		
	from e2spt_classaverage import sptParseAligner
	options = sptParseAligner( options )

	'''
	If --radius of the particle is provided, we calculate the optimal alignment steps for 
	coarse and fine alignment rounds using --shrink and --shrinkfine options and apix info
	'''
	
	if options.radius:
		from e2spt_classaverage import calcAliStep
		options = calcAliStep(options)
	
	'''
	Parse parameters such that "None" or "none" are adequately interpreted to turn of an option
	'''
	
	from e2spt_classaverage import sptOptionsParser
	options = sptOptionsParser( options )
	
	from e2spt_classaverage import writeParameters
	writeParameters(options,'e2spt_binarytree.py', 'bt')
	
					
	hdr = EMData(options.input,0,True)
	nx = hdr["nx"]
	ny = hdr["ny"]
	nz = hdr["nz"]
	if nx!=ny or ny!=nz :
		print "ERROR, input volumes are not cubes"
		sys.exit(1)
		
	logger = E2init(sys.argv, options.ppid)
	
	
	'''
	Initialize parallelism if being used
	'''
	
	if options.parallel :
	
		if options.parallel == 'none' or options.parallel == 'None' or options.parallel == 'NONE':
			options.parallel = ''
			etc = ''
		
		else:
			print "\n\n(e2spt_classaverage.py) INITIALIZING PARALLELISM!"
			print "\n\n"

			from EMAN2PAR import EMTaskCustomer
			etc=EMTaskCustomer(options.parallel)

			pclist=[options.input]

			etc.precache(pclist)
		
	else:
		etc=''
	
	
	options.raw = options.input
	
	"""
	if 'tree' in options.align:
		options.falign = None
		options.mask = None
		options.lowpass = None
		options.highpass = None
		options.normproc = None
		options.lowpassfine = None
		options.highpassfine = None
		options.preprocess = None
		options.preprocessfine = None

	else:
		from e2spt_classaverage import cmdpreproc
		cmpreproc( options.input, options, False )
	"""
	
	nptcl=EMUtil.get_image_count(options.input)
	if nptcl < 1: 
		print "ERROR : at least 2 particles required in input stack"
		sys.exit(1)
	
	ptclnums=range(nptcl)
	nptclForRef = len(ptclnums)
	
	nseed=2**int(floor(log(len(ptclnums),2)))	# we stick with powers of 2 for this to make the tree easier to collapse
	
	if options.nseedlimit:
		nseed=2**int(floor(log( options.nseedlimit , 2)))
		
	#binaryTreeRef(options,nptclForRef,nseed,-1,etc)

	binaryTreeRef(options,nptclForRef,nseed,etc)
		
	print "Will end logger"	
	E2end(logger)
	
	print "logger ended"
	sys.stdout.flush()
	
	return
Beispiel #7
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] 
	This program takes a .json file produced by e2spt_classaverage.py and a stack of raw,
	unaligned 3-D images (or "subtomograms") and applies the transforms indicated in the .json file
	to average the particles in the stack.
	Alternatively, if the aligned stack is supplied and there's alignment information in
	the headers of the particles, a .json file with the alignment parameters can be produced.
	"""
	
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--input", default='',type=str, help="The name of the hdf stack of volumes to process.")
	#parser.add_argument("--output", default="avg.hdf",type=str, help="The name of the output average volume.")
	parser.add_argument("--rotationtype", default="eman",type=str, help="Valid options are: eman,imagic,mrc,spider,quaternion,sgirot,spi,xyz")
	
	parser.add_argument("--averager",type=str,help="The type of averager used to produce the class average. Default=mean",default="mean")
	
	parser.add_argument("--sym", type=str, default='', help = "Symmetry to impose - choices are: c<n>, d<n>, h<n>, tet, oct, icos")

	parser.add_argument("--path",default='',type=str,help="Name of directory where to save the output file.")
	parser.add_argument("--alifile",default='',type=str,help=".json file with alingment parameters, if raw stack supplied via --input.")
	parser.add_argument("--extractcoords",default=False,action='store_true',help="""If you
		provide this option, a coordinates file can be written with the original coordinates
		stored on the header of a subtomogram stack""")
	
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")

	parser.add_argument("--saveali",action="store_true", default=False,help="""If set, will save the 
		aligned particle volumes.""")

	parser.add_argument("--extractsymsearch",action="store_true", default=False,help="""If set, this will look for the symxform among the particles' header parameters to produce a .json file with alignment info from e2symsearch3d.py. Works only if --alifile is NOT provided.""")

	(options, args) = parser.parse_args()


	if options.averager: 
		options.averager=parsemodopt(options.averager)

	if not options.input:
		parser.print_help()
		sys.exit(0)

	#if ".hdf" not in options.output and ".mrc" not in options.output:
	#	print "ERROR. The output must contain a valid format ending, for example '.hdf.' TERMINATING!"
	#	sys.exit()
	
	if ".hdf" not in options.input:
		print "ERROR. HDF is the only supported input format."
		sys.exit()
	
	logid=E2init(sys.argv,options.ppid)
	

	n = EMUtil.get_image_count( options.input )

	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'sptextractali')

	if options.extractcoords:
		lines=[]
		tomograms={}
		for i in range(n):
			#You only need to load the ptcl header
			a=EMData( options.input , i ,True )
			
			coords=a['ptcl_source_coord']
			tomogram=a['ptcl_source_image']
			try:
				tomogram=a['spt_tomogram']
			except:
				pass
			
			if tomogram not in tomograms:
				print "Indentified a new tomogram",tomogram
				tomograms.update({tomogram:[]})
				
			line = str(coords[0]) + ' ' + str(coords[1]) + ' ' + str(coords[2]) + '\n'
			#lines.append(line)
			print "Line of coordinates to add",line
			tomograms[tomogram].append(line)
			
		for tomogram in tomograms.keys():
			#coordsfile = options.path + '/' + options.input.replace('.hdf','_coords.txt')
			coordsfile = options.path + '/' + tomogram.split('.')[0] + '_coords.txt'

			f=open(coordsfile,'w')
			f.writelines(tomograms[tomogram])
			f.close()
	
	if not options.alifile:
		a=Transform({"type":"eman","alt":1.0})
		#k=list(a.get_rotation(sys.argv[2]).keys())
	
		#k=list(a.get_rotation( options.rotationtype ).keys())

		#k.remove("type")
		#if len(k)==3: 
		#	print "#{},{},{}".format(*k)
		#else: 
		#	print "#{},{},{},{}".format(k)

		jsAliParamsPath = options.path + '/xform_align3d.json'
		jsA = js_open_dict( jsAliParamsPath )
		if options.extractsymsearch:
			symjsAliParamsPath = options.path + '/symxform.json'
			symjsA = js_open_dict( symjsAliParamsPath )

		for i in range(n):
			#You only need to load the header
			im=EMData( options.input ,i, True)
			#xf=im["spt_ali_param"]
			
			xf=im['xform.align3d']
			#score=1.0
			
			score=im['spt_score']
			if options.extractsymsearch:
				symxformslabel = 'subtomo_' + str( i ).zfill( len( str( n ) ) )			
				symxf=Transform()
				
				try:
					symxf=im['symxform']
					#symscore=im['spt_symsearch_score']
					
				except:
					print "\nERROR: particle %d does not have 'symxform' parameter in its header. Defaulting to identity transform."
				symjsA.setval( symxformslabel, [ symxf , score ] )

			
			xformslabel = 'subtomo_' + str( 0 ).zfill( len( str( n ) ) )			
			jsA.setval( xformslabel, [ xf , score ] )

			#r=xf.get_rotation( options.rotationtype )
			#print "{}".format(i),
			#for j in k: 
			#	print ", {}".format(r[j]),
			#print ""
		
		jsA.close()
		if options.extractsymsearch:
			symjsA.close()

	
	elif options.alifile:
		preOrientationsDict = js_open_dict(options.alifile)
			
		avgr=Averagers.get(options.averager[0], options.averager[1])
	
		for i in range(n):	
			print "reading particle"		
			a=EMData( options.input, i)
			
			ptcl = a.copy()
			
			'''
			#The first case works with .json files from e2spt_hac.py
			#The second works for .json files from e2spt_classaverage.py
			try:
				ID=unicode(i)
				#print "ID is", ID
				t = preOrientationsDict[0][ID]
				#print "t 1 is",t
			except:
				ID='subtomo_' + str(i).zfill(len(str(n)))
				#print "ID is", ID
				t = preOrientationsDict[ID][0]
				#print "t 2 is", t
			'''
			ID='subtomo_' + str(i).zfill(len(str(n)))
			t = preOrientationsDict[ID][0]	
			print "\nfor particle",i
			print "transform is", t
			
			ptcl['origin_x'] = 0
			ptcl['origin_y'] = 0
			ptcl['origin_z'] = 0
			ptcl['xform.align3d'] = Transform()
			
			if t:
				ptcl.transform(t)
				ptcl['xform.align3d'] = t
				alistack = os.path.basename(options.input).replace('.hdf','_ali.hdf')
				if options.saveali:
					print "\nsaving aligned particle",i
					ptcl.write_image(options.path + '/' + alistack, i )
			
			avgr.add_image(ptcl)
			
			#if options.saveali:
				
				#pass
				
		avg=avgr.finish()

		if options.sym and options.sym is not 'c1' and options.sym is not 'C1':
			avg.process_inplace('xform.applysym',{'sym':options.sym})
		avg.process_inplace('normalize.edgemean')
		
		output = os.path.basename(options.input).replace('.hdf','_recomp.hdf')
		avg.write_image( options.path + '/' + output, 0 )
		
		preOrientationsDict.close()			
	
	E2end(logid)
	
	return
Beispiel #8
0
def main():
    print "I have entered main"
    #progname = os.path.basename(sys.argv[0])
    #usage = """Aligns a 3d volume to another by executing e2spt_classaverage.py and then calculates the FSC between them by calling e2proc3d.py . It returns both a number for the resolution based on the FSC0.5
    #criterion(on the screen) and a plot as an image in .png format."""

    progname = os.path.basename(sys.argv[0])
    usage = """Aligns a 3d volume to another by executing e2spt_classaverage.py and then calculates the FSC between them by calling e2proc3d.py . It returns both a number for the resolution based on the FSC0.5 
	criterion(on the screen) and a plot as an image in .png format."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--alistack",
        type=str,
        default='',
        help=
        """Default=None. Stack of particles aligned with e2spt_classaverage.p.y"""
    )

    parser.add_argument(
        "--scores",
        type=str,
        default='',
        help=
        """Default=None. Text file containing a list of correlations scores."""
    )

    parser.add_argument(
        "--nbins",
        type=int,
        default=0,
        help=
        """Used for histogram plot. Default=0 (not used). Number of bins for histogram. If not provided, the optimal bin number will be automatically calculated based on bin-width, computed using Scott's normal reference rule, width = (3.5*std)/cuberoot(n), where 'std' is the standard deviation of the distribution of scores and n is the number of values considered. Then, bins will be nbins = (max(scores) - min(scores)) / width."""
    )

    parser.add_argument(
        "--cutoff",
        type=float,
        help=
        """Fraction of particles (as a decimal, where 1.0 is the entire set, 0.8 is 80 percent. 0.5 is 50 percent, etc); 
														where to make the cutoff to divide the set into two groups. For example, if you specify 
														--cutoff=0.2, the 20 percent of particles with the highest correlation scores will be bundled into the first group, 
														and the remaining 80 percent into the second group.""",
        default=None)

    parser.add_argument(
        "--lowpass",
        type=str,
        default='default',
        help=
        """Filter applied to averages when --groups is used. Default=filter.lowpass.gauss:cutoff_freq=1/F, where F is Nyquist frequency, automatically calculated. To disable type --lowpass=None"""
    )

    parser.add_argument(
        "--groups",
        type=int,
        help=
        "Number of groups you want the data to be divided into based on correlation.",
        default=None)

    parser.add_argument(
        "--averager",
        type=str,
        default="mean.tomo",
        help=
        """Default=mean.tomo. The type of averager used to produce the class average. Default=mean.tomo."""
    )

    parser.add_argument(
        "--topn",
        type=int,
        help=
        "Number of particles from best to worst that you want to be written as a substack, averaged, and generate a coordinates .txt file with their coordinates.",
        default=None)

    parser.add_argument(
        "--sigmaprune",
        type=float,
        default=0.0,
        help=
        """Number of standard deviations below the mean to cut off particles; 
																		that is, the mean cross correlation coefficient of all particles will be computed, and those that are 
																		--sigmaprune=N standard deviations below the mean will not be considered."""
    )
    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness")

    parser.add_argument(
        "--path",
        type=str,
        help="Results directory. If not specified, defaults to e2sptcoeff/",
        default='sptcoeff')

    parser.add_argument(
        "--normalizeplot",
        action="store_true",
        help=
        "Make maximum correlation value on plot equal to 1 and the minimum equal to 0, and scale all other values accordingly.",
        default=False)

    (options, args) = parser.parse_args()

    if options.groups and (options.cutoff or options.topn):
        print "ERROR: you cannot specify --cutoff, --groups and --topn all at the same time. Choose one."
        sys.exit()

    if options.cutoff and (options.groups or options.topn):
        print "ERROR: you cannot specify --cutoff, --groups and --topn all at the same time. Choose one."
        sys.exit()

    if options.topn and (options.cutoff or options.groups):
        print "ERROR: you cannot specify --cutoff, --groups and --topn all at the same time. Choose one."
        sys.exit()

    logger = E2init(sys.argv, options.ppid)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'sptcoeff')

    print "\nI have read the parameters"

    if options.lowpass:
        if options.lowpass == "default":
            hdr = EMData(options.alistack, 0, True)
            apix = hdr['apix_x']
            nyquist = 2.0 * apix
            nyquistfreq = 1.0 / nyquist
            options.lowpass = '******' + str(
                nyquistfreq) + ':apix=' + str(apix)
            if apix == '1.0':
                print "\nWARNING: apix is 1.0, most likely wrong (default empty value). You can fix/change it with e2fixheaderparam.py"
        elif 'None' in options.lowpass or 'none' in options.lowpass:
            options.lowpass = None

    if options.averager:
        options.align = parsemodopt(options.averager)
    if options.lowpass:
        options.lowpass = parsemodopt(options.lowpass)

    scores = []
    dataset = {}
    #x=[]

    k = 0
    usenewstack = False
    newstack = options.alistack.replace('.hdf', '_prepruned.hdf')

    if options.alistack:
        n = EMUtil.get_image_count(options.alistack)

        for i in range(n):
            ahdr = EMData(options.alistack, i, True)
            #print "ahdr is", ahdr
            score = None

            if options.verbose:
                print "\nanalyzing header for particle", i

            if 'spt_score' in ahdr.get_attr_dict():
                score = -1 * ahdr['spt_score']
                print "spt_score is", score
            elif 'spt_coefficient' in ahdr.get_attr_dict():
                score = ahdr['spt_coefficient'] * -1
                print "spt_coefficient is", score
            else:
                print "\nERROR: no score found in header for particle %d. Skipping it! A prepruned stack will be made with all the particles that did have score info in their header" % (
                    i)
                a = EMData(options.alistack, i)
                a.write_image(newstack, k)
                usenewstack = True

            if score:
                scores.append(score)

    elif options.scores and not options.alistack:
        f = open(options.scores, 'r')
        lines = f.readlines()
        f.close()
        scores = [round(float(line.replace('\n', '')), 6) for line in lines]

    elif not options.scores and not options.alistack:
        print "\n(e2spt_coeffplot)(main) ERROR: you need to supply either --alistack or --scores, with the former taking precedence over the latter."
        sys.exit()

    if usenewstack:
        options.alistack = newstack

    n = len(scores)

    nstack = EMUtil.get_image_count(options.alistack)

    if n != nstack:
        print "\n!!!! WARNING: the number of scores %d does not match the number of images %d in the stack %s" % (
            n, nstack, options.alistack)

    if scores and n > 1:
        print "\nThe set has these many particles", len(scores)
    else:
        print "\nERROR: There seems to be no information on particle scores. The number of scores must be larger than one to do any statistics with them."
        sys.exit()

    for i in range(n):
        #dataset.append({'score':float(score), 'particle':a})
        dataset.update({i: scores[i]})
        #x.append(i)

    dataset = sorted(dataset.items(), key=itemgetter(1), reverse=True)

    if options.normalizeplot:
        #for s in scores:
        #val = values[ele]
        minv1 = min(scores)
        #maxv1 = max(scores)
        #print "Min max before normalization was", minv,maxv1
        for k in range(len(scores)):
            scores[k] = scores[k] - minv1

        #minv2 = min(scores)
        maxv2 = max(scores)
        #print "After subtracting min, the are", minv2,maxv
        #print "Max before normalization was", maxv
        for k in range(len(scores)):
            scores[k] = scores[k] / maxv2

    scores.sort()
    scores.reverse()
    #scores=scores[:-2]
    '''
	c:plot the distribution of scores
	'''
    import matplotlib.pyplot as plt
    import pylab
    import matplotlib

    std = np.std(scores)
    mean = np.mean(scores)
    statistics = ['mean=' + str(mean) + ' std=' + str(std) + '\n']

    print "\nthe standard deviation %.6f, mean %.6f" % (std, mean)

    if not std:
        print "\nERROR: std=0, which means all intensity values are the same."
        sys.exit()

    cuberoot = np.power(len(scores), 1.0 / 3.0)
    width = (3.5 * std) / cuberoot
    print "\naccording to Scott's normal reference rule, width = (3.5*std)/cuberoot(n), the width of the histogram bins will be", width

    calcbins = (max(scores) - min(scores)) / width

    if options.nbins:
        calcbins = options.nbins
        print "\overwriting number of bins to be", options.nbins

    print "\nand the number of bins n = ( max(scores) - min(scores) ) / width will thus be", calcbins
    calcbins = round(calcbins)
    print "rounding to", calcbins

    statistics.append('bins=' + str(calcbins) + ' , binwidth=' + str(width) +
                      '\n')

    if not calcbins:
        print "WARNING: nbins=0, which means max and min intensity are the same, which probably means all scores are zero. Defaulting nbins to number of partilces."
        calcbins = len(scores)

    datafile = ''
    if options.alistack:
        datafile = os.path.basename(options.alistack)
    elif options.scores:
        datafile = os.path.basename(options.scores)

    f = open(options.path + '/stats.txt', 'w')
    f.writelines(statistics)
    f.close()

    plt.hist(scores, calcbins, alpha=0.30, label=datafile)

    plottitle = os.path.basename(options.alistack).replace(
        '.hdf', '') + ' CC scores distribution histogram'
    plt.title(plottitle)

    matplotlib.rc('xtick', labelsize=16)
    matplotlib.rc('ytick', labelsize=16)

    font = {'weight': 'bold', 'size': 16}
    matplotlib.rc('font', **font)

    pylab.rc("axes", linewidth=2.0)

    pylab.xlabel('CC score (au)', fontsize=16, fontweight='bold')
    pylab.ylabel('Number of particles', fontsize=16, fontweight='bold')

    plt.savefig(options.path + '/scores_histogram.png')
    plt.clf()
    '''
  	c:plot decay in ranked correlation scores
  	'''
    x = [i for i in range(len(scores))]

    plt.plot(x, scores, color='k', linewidth=3)
    plottitle = os.path.basename(options.alistack).replace(
        '.hdf', '') + ' CC scores decay'
    plt.title(plottitle)

    pylab.xlim([min(x), max(x) + 0.1 * max(x)])
    font = {'weight': 'bold', 'size': 16}
    matplotlib.rc('font', **font)

    pylab.xlabel('Particle index', fontsize=16, fontweight='bold')
    pylab.ylabel('CC score (au)', fontsize=16, fontweight='bold')

    plt.savefig(options.path + '/scores_decay.png')
    plt.clf()
    '''
  	c:plot the distance to mean value in # of standard deviations
  	'''
    distancestomean = [(scores[i] - mean) / std for i in range(len(scores))]
    plt.plot(
        x,
        distancestomean,
        color='b',
        linewidth=2,
    )

    plottitle = os.path.basename(options.alistack).replace(
        '.hdf', '') + ' CC scores distance to mean'
    plt.title(plottitle)

    pylab.xlim([min(x), max(x) + 0.1 * max(x)])

    font = {'weight': 'bold', 'size': 16}
    matplotlib.rc('font', **font)

    pylab.xlabel('Particle index', fontsize=16, fontweight='bold')
    pylab.ylabel('Distance from mean (sigmas)', fontsize=16, fontweight='bold')

    plt.savefig(options.path + '/scores_distance2mean.png')
    plt.clf()
    '''
  	c:plot the distance to max value in # of standard deviations
  	'''
    maxi = max(scores)
    distancestomax = [(maxi - scores[i]) / std for i in range(len(scores))]
    plt.plot(
        x,
        distancestomax,
        color='b',
        linewidth=2,
    )

    plottitle = os.path.basename(options.alistack).replace(
        '.hdf', '') + ' CC scores distance to max'
    plt.title(plottitle)

    pylab.xlim([min(x), max(x) + 0.1 * max(x)])

    font = {'weight': 'bold', 'size': 16}
    matplotlib.rc('font', **font)

    pylab.xlabel('Particle index', fontsize=16, fontweight='bold')
    pylab.ylabel('Distance from max (sigmas)', fontsize=16, fontweight='bold')

    plt.savefig(options.path + '/scores_distance2max.png')
    plt.clf()

    print 'sorted dataset is', dataset
    '''
	c:prune and/or divide into groups
	'''
    newscores = []
    if options.sigmaprune:

        #print "Will analyze scores to remove aberrantly low ones"

        #mu=numpy.mean(scores)
        #sigma=numpy.std(scores)

        mu = mean
        sigma = std

        print "\nMean is", mu
        print "Std is", sigma
        filter = mu - sigma * (options.sigmaprune)
        print "Therefore, filter is", filter

        for d in dataset:
            if float(d['score']) < float(filter):
                dataset.remove(d)
                print "I have removed this aberrant particle from the dataset due to its low score", d[
                    'score']
            else:
                newscores.append(float(d['score']))
                print "This score is high enough to survive", d['score']

        newscores.sort()
        newscores.reverse()
        x = range(len(newscores))

        plottitle = os.path.basename(options.alistack).replace(
            '.hdf', '_prunedSCORES')
        plt.plot(x, newscores, color='k', linewidth=2)
        pylab.xlim([min(x), max(x) + 0.1 * max(x)])
        #plt.title(plottitle)
        plt.ylabel('CC coefficient')
        plt.xlabel('Particle number')
        #a = plt.gca()
        plotfile = options.path + '/' + plottitle + '.png'
        plt.savefig(plotfile)
        plt.clf()

    newN = len(dataset)

    if options.groups:

        if not options.alistack:
            print "\nERROR: --groups requires --alistack"
            sys.exit()

        halfptclnum = int(round(n / 2.0))
        halfptcl = dataset[halfptclnum][0]
        print "half ptclnum is", halfptclnum
        print "which happens to be ptcl indx", halfptcl
        halfscore = dataset[halfptcl][1]
        print "with halfscore being", halfscore

        subdatasetsSET = []
        N = len(dataset)
        #print "THe type of dataset is", type(dataset)
        print "The len of the dataset is", N
        subN = N / options.groups
        print "The len of each subset, except the last, should be", subN
        for g in range(options.groups):
            #subscores = scores[g*subN : (g+1)*subN]
            subdataset = dataset[g * subN:(g + 1) * subN]
            if g == options.groups - 1:
                subdataset = dataset[g * subN:]
            subdatasetsSET.append(subdataset)

        kk = 0
        for subdataset in subdatasetsSET:
            print "The len of subset %d is %d" % (kk, len(subdataset))
            jj = 0
            groupname = options.path + '/' + os.path.basename(
                options.alistack).replace(
                    '.', '_' + str(kk).zfill(len(str(options.groups))) + '.')
            particleLIST = []
            lines = []
            print "options.averager is", options.averager
            #avgr = Averagers.get(options.averager[0], options.averager[1])
            avgr = Averagers.get('mean.tomo')

            for element in subdataset:
                #particle = element['particle']

                ptclnum = element[0]
                img = EMData(options.alistack, ptclnum)
                img.write_image(groupname, jj)
                jj += 1
                particleLIST.append(ptclnum)

                avgr.add_image(img)

            averageNAME = groupname.replace('.hdf', '_AVG.hdf')

            average = avgr.finish()

            average['origin_x'] = 0
            average['origin_y'] = 0
            average['origin_z'] = 0

            average.process_inplace('normalize.edgemean')

            if options.lowpass:
                print "(e2spt_coeffplot)(main) --lowpass provided:", options.lowpass
                average.process_inplace(options.lowpass[0], options.lowpass[1])

            average.write_image(averageNAME, 0)

            cmd = 'cd ' + options.path + ' && e2orthoproject.py --input ' + os.path.basename(
                averageNAME)
            cmd += ' && e2slicer.py --input ' + os.path.basename(averageNAME)

            runcmd(options, cmd)
            #print "\nThe group average has been written to", averageNAME
            kk += 1

    if options.cutoff:

        if not options.alistack:
            print "\nERROR: --cutoff requires --alistack"
            sys.exit()

        threshptclnum = int(round(newN / (1 / options.cutoff)))
        threshptcl = dataset[threshptclnum]
        print "The new threshptcl is", threshptcl
        threshscore = dataset[threshptclnum][1]

        threshlabel = "%0.2f" % (options.cutoff)
        threshlabel = str(threshlabel).replace('.', 'p')
        group1 = []
        group2 = []
        k1 = 0
        k2 = 0
        g1name = options.path + '/' + os.path.basename(
            options.alistack).replace('.', '_G1.')
        g2name = options.path + '/' + os.path.basename(
            options.alistack).replace('.', '_G2.')
        avgr1 = avgr = Averagers.get('mean.tomo')
        avgr2 = avgr = Averagers.get('mean.tomo')
        for i in dataset:
            img = EMData(options.alistack, i[0])

            if i[1] >= threshscore:
                group1.append(i[0])
                img.write_image(g1name, k1)
                avgr1.add_image(img)
                k1 += 1
            else:
                group2.append(i[0])
                img.write_image(g2name, k2)
                avgr2.add_image(img)
                k2 += 1
                #else:
                #	print "\n\n@@@@ Found a garbage particle, and thus did not consider it!\n\n"

        if group1:
            g1avg = avgr1.finish()
            g1avg.write_image(g1name.replace('.hdf', '_avg.hdf'), 0)

        if group2:
            g2avg = avgr1.finish()
            g2avg.write_image(g2name.replace('.hdf', '_avg.hdf'), 0)

    if options.topn:

        if not options.alistack:
            print "\nERROR: --topn requires --alistack"
            sys.exit()

        topndataset = dataset[0:options.topn]
        bottomdataset = dataset[options.topn:]

        outnamestack = options.path + '/' + os.path.basename(
            options.alistack).replace('.', 'top' + str(options.topn) + '.')

        coordsname = options.path + '/' + os.path.basename(outnamestack).split(
            '.')[0] + '_coords.txt'

        indxsname = options.path + '/' + os.path.basename(coordsname).replace(
            'coords', 'indxs')

        k = 0
        linescoords = []
        linesindxs = []
        topptcls = []

        avgr = Averagers.get('mean.tomo')
        for ptcl in topndataset:
            p = ptcl[0]
            img = EMData(options.alistack, p)
            img.write_image(outnamestack, k)
            avgr.add_imag(img)
            topptcls.append(p)
            linescoords.append(str(p['ptcl_source_coord']) + '\n')
            linesindxs.append(str(p['source_n']) + '\n')
            k += 1

        avg = avgr.finish()
        avgname = options.path + '/' + os.path.basename(outnamestack).replace(
            '.', '_avg.')

        avg.write_image(avgname, 0)
        f = open(coordsname, 'w')
        f.writelines(linescoords)
        f.close()

        f = open(indxsname, 'w')
        f.writelines(linesindxs)
        f.close()

    #x=range(len(scores))

    #plottitle = os.path.basename(options.alistack).replace('.hdf', '_prunedSCORES')
    #plt.plot(x, scores, marker='o', color='r', linewidth=2)
    #plt.title(plottitle)
    #plt.ylabel('score')
    #plt.xlabel('n ptcl')
    #a = plt.gca()

    #plotfile = options.path + '/' + plottitle + '.png'
    #plt.savefig(plotfile)
    #plt.clf()

    E2end(logger)

    return
Beispiel #9
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] 
	This program extracts parts of 3D maps from specific coordinates with the shape of a 
	user-defined mask, or from symmetry-related positions based on a defined radius and, 
	again, a user-defined mask.
	"""
	
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--input", default='',type=str, help="""3D map or stack of maps to extract smaller regions from.""")
	
	parser.add_argument("--output", default='extracts',type=str, help="""String to use as the 'stem' for naming output volumes. Note that for each input volume, you'll get a stack of subvolumes. For example, if you provide a stack with 3 volumes, and you extract 12 subvolumes from each of these, you'll have 3 stacks of extracted subvolumes.""")
		
	parser.add_argument("--path",type=str,help=""""Name of directory where to store the output file(s)""",default="melonscoops")
	
	parser.add_argument("--sym", dest = "sym", default="c1", help = """Specify symmetry. Choices are: c<n>, d<n>, h<n>, tet, oct, icos. For asymmetric reconstruction ommit this option or specify c1.""")
	
	parser.add_argument("--vertices", action='store_true', default=False,help="""Only works if --sym=icos. This flag will make the program extract only the 12 vertices from among all 60 symmetry related units.""") 
	
	parser.add_argument("--mask",type=str,help="""Mask processor to define the shape of regions to extract. Default is None.""", default="")
		
	parser.add_argument("--maskfile",type=str,help="""Precomputed mask to use to extract subvolumes from the locations specified through --coords or through --radius and --sym""", default="")
		
	parser.add_argument("--savescoops",action='store_true',default='',help="""Save extracted parts from each particle into a per-particle stack, with extracted subvolumes centered in a box of the size specified by --boxsize, and rotated so that each subvolume is pointing along Z.""")
	
	parser.add_argument("--savescoopsinplace",action='store_true',default='',help="""Save extracted parts from each particle into a per-particle stack, with extracted subvolumes 'in-situ'; that is, with the same size and orientation as in the original volume.""")		
		
	parser.add_argument("--coords",type=str,help="""File with coordinates from where to extract subvolumes.""", default="")
		
	parser.add_argument("--radius",type=int,help="""Radius (in pixels) where to center the mask for subvolume extraction. Works only for cases in which the asymmetric unit of interest lies along z (for example, vertexes of an icosahedral virus aligned to the symmetry axes such that a vertex lies along z). Supplying --tz should achieve the same results.""", default=0)
	
	parser.add_argument("--tx",type=int,help="""Translation (in pixels) along x to define the mask's center. If supplied with --radius, the latter will be ignored.""", default=0)

	parser.add_argument("--ty",type=int,help="""Translation (in pixels) along y to define the masks's center. If supplied with --radius, the latter will be ignored.""", default=0)

	parser.add_argument("--tz",type=int,help="""Translation (in pixels) along z to define the masks's center. If supplied with --radius, the latter will be ignored.""", default=0)
	
	#parser.add_argument("--normproc",type=str,default='',help="Normalization processor applied to particles before alignment. Default is to use normalize. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'")
	#
	#parser.add_argument("--threshold",default='',type=str,help="""A threshold applied to the subvolumes after normalization. 
	#												For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=10, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
	#
	#parser.add_argument("--preprocess",default='',type=str,help="Any processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=10, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
		
	#parser.add_argument("--lowpass",type=str,default='',help="A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=17, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')

	#parser.add_argument("--highpass",type=str,default='',help="A highpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=18, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')

	parser.add_argument("--boxsize",type=int,default=0,help="""If specified, the output subvolumes will be clipped to this size and centered in the box; otherwise, they will be saved in a boxsize equal to the volume they came from.""")
	
	#parser.add_argument("--parallel","-P",type=str,help="Run in parallel, specify type:<option>=<value>:<option>:<value>",default=None, guitype='strbox', row=8, col=0, rowspan=1, colspan=2, mode="align")
	
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")	

	(options, args) = parser.parse_args()
	
	if options.mask: 
		options.mask=parsemodopt(options.mask)
	
	if not options.input:
		parser.print_help()
		sys.exit(0)
	
	
	if options.savescoops and not options.boxsize:
		print """ERROR: Specify the box size through --boxsize for the saved
		scoops."""	
		sys.exit()

	#If no failures up until now, initialize logger
	logid=E2init(sys.argv,options.ppid)
	
	inputhdr = EMData(options.input,0,True)
	
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,options.path)
	
	
	if not options.mask and not options.maskfile:
		print "\nERROR: You must define --mask or supply a volume through --maskfile"
		sys.exit()
	
	mask = EMData(inputhdr['nx'],inputhdr['ny'],inputhdr['nz'])
	mask.to_one()
	
	if options.mask:	
		mask.process_inplace(options.mask[0],options.mask[1])
	
	elif options.maskfile:
		mask = EMData( options.maskfile )
		
		'''
		Center of maskfile
		'''
		maskcx = mask['nx']
		maskcy = mask['ny']
		maskcz = mask['nz']
		
		'''
		Clip to data's boxsize
		'''
		r=Region( (2*maskcx - inputhdr['nx'])/2, (2*maskcx - inputhdr['ny'])/2, (2*maskcx - inputhdr['nz'])/2, inputhdr['nx'],inputhdr['ny'],inputhdr['nz'])
		mask.clip_inplace( r )
	
	print "\nMask done"
	
	if options.radius:
		mask.translate(0,0, float(options.radius) )
		print "\nMask translated by radius %d along z" %( options.radius )

	else:
		mask.translate( options.tx, options.ty, options.tz )
		print "\nMask translated by tx=%d, ty=%d, tz=%d,", options.tx, options.ty, options.tz
	
	symnames = ['oct','OCT','icos','ICOS','tet','TET']
	
	orientations = []
	#transforms = []
	anglelines = []
	
	if options.sym:
		print "\nsym found", options.sym
	
		symnum = 0
		
		if options.sym not in symnames:
			
			symletter = options.sym
			symnum = options.sym
			
			for x in options.sym:
				if x.isalpha():
					symnum = symnum.replace(x,'')
					
			for x in options.sym:
				if x.isdigit():
					symletter = symletter.replace(x,'')
			
			
			print "\nThe letter for sym is", symletter
			print "\nThe num for sym is", symnum
		
		if options.sym == 'oct' or options.sym == 'OCT':
			symnum = 8
			
		if options.sym == 'tet' or options.sym == 'TET':
			symnum = 12	
			
		if options.sym == 'icos' or options.sym == 'ICOS':
			symnum = 60	
		
		symnum = int(symnum)
			
		t = Transform()
		
		if symnum:
			print "\nsymnum determined",symnum
			print "while symletter is", symletter
			
			if symletter == 'd' or symletter == 'D':
				symnum *= 2
				print "\nsymnum corrected, because symmetry is d",symnum
				
			#if options.save
			
			for i in range(symnum):
				orientation = t.get_sym( options.sym , i )
				orientations.append( orientation )
					
				rot = orientation.get_rotation()
				az = rot['az']
				alt = rot['alt']
				phi = rot['phi']
				
				anglesline = 'az=' + str(az) + 'alt=' + str(alt) + 'phi=' + str(phi) + '\n'
				anglelines.append(anglesline)
				
				#transforms.append( Transform({'type':'eman','az':az,'alt':alt,'phi':phi}) )
					
	n = EMUtil.get_image_count( options.input )
	
	centers = {}
	masks = {}
	
	if orientations:
		print "\ngenerated these many orientations", len (orientations)
		if options.sym == 'icos' or options.sym == 'ICOS':
			if options.vertices:

				print "\nbut fetching vertices only"
			
				#orientations = genicosvertices ( orientations )

				orientations = genicosverticesnew ( orientations )
			
			
		centerx = 0.0
		centery = 0.0
		centerz = float( options.radius )
		
		if not options.radius:
			centerx = options.tx 
			centery = options.ty 
			centerz = options.tz
		
		groundv = Vec3f(centerx,centery,centerz)
		
		finalmask = EMData(mask['nx'],mask['ny'],mask['nz'])
		finalmask.to_zero()
		
		centersmap = EMData( mask['nx'],mask['ny'],mask['nz'] )
		centersmap.to_zero()
		
		centerstxt = options.path + '/centers.txt'
		f = open( centerstxt, 'a')
		for k in range( len(orientations) ):
			t =  orientations[k]
			
			print "\nWorking with this orientation",t
			
			tmpmask = mask.copy()
			tmpmask.transform( t )
			
			tmpmask['origin_x'] = 0
			tmpmask['origin_y'] = 0
			tmpmask['origin_z'] = 0
			
			finalmask = finalmask + tmpmask
			
			center = t*groundv
			centers.update( {k: center} )
			
			newcenterx = int( round(center[0] + mask['nx']/2.0 )) 
			newcentery = int( round(center[1] + mask['ny']/2.0 ))
			newcenterz = int( round(center[2] + mask['nz']/2.0 ))
			
			tout = Transform()
			rot = t.get_rotation()
			
			tout.set_rotation( rot )
			tout.set_trans( newcenterx, newcentery, newcenterz )
			
			tmpmask['spt_scoop_center'] = [ newcenterx, newcentery, newcenterz ]
			tmpmask['xform.align3d'] = tout
			
			tmpmask.write_image(options.path + '/masks.hdf',k)
			
			masks.update( {k:[tmpmask,tout,[newcenterx,newcentery,newcenterz]]} )
			
			
			centerline = str(newcenterx) + ' ' + str(newcentery) + ' ' + str(newcenterz) + '\n'
			
			f.write(centerline)
			
			centersmap.set_value_at( int( round(center[0] + mask['nx']/2.0 )) , int( round(center[1] + mask['ny']/2.0 )), int( round(center[2] + mask['nz']/2.0 )), 1.0 )
		
			
			
			#print "setting indx and t are", k, t
			#print "whereas mask t is", tout
		
		f.close()
			
		finalmask.write_image(options.path + '/finalmask.hdf',0)
		centersmap.write_image(options.path + '/centersmap.hdf',0)
		
		for i in range(n):
			ptcl = EMData(options.input,i)
			
			ptclnumtag = str(i).zfill(len( str(n) ))
			
			scoopsinplacestack = 'ptcl' + ptclnumtag + '_scoopsOrigBox.hdf'
			
			scoopsstack = 'ptcl' + ptclnumtag + '_scoops.hdf'

			ptclglobalmsk = ptcl.copy()
			ptclglobalmsk.mult( finalmask )
			
			ptclglobalmsk.write_image( options.path + '/' + 'ptcls_globallymasked.hdf',i)
			
			for key in masks.keys():
			
				scoopinplace = ptcl.copy()
				scoop = ptcl.copy()
				
				thismask = masks[key][0]
				
				t = masks[key][1]
				
				#tapp = Transform()
				#rot = t.get_rotation()
				#tapp.set_rotation( rot )
				
				#print "key and t are", key, tapp
				sx = masks[key][-1][0]
				sy = masks[key][-1][1]
				sz = masks[key][-1][2]
				
				if options.savescoopsinplace:
					
					#scoopinplace.mult( thismask )
					scoopinplace.process_inplace('normalize.edgemean')
					scoopinplace.mult( thismask )
					
					
					scoopinplace['origin_x'] = 0
					scoopinplace['origin_y'] = 0
					scoopinplace['origin_z'] = 0
					
					scoopinplace['spt_scoop_x'] = sx
					scoopinplace['spt_scoop_y'] = sy
					scoopinplace['spt_scoop_z'] = sz
					
					scoopinplace['spt_score'] = 0
					
					scoopinplace['xform.align3d'] = t
					
					scoopinplace.write_image( options.path + '/' + scoopsinplacestack, key )
					print "\nWrote this scoop 'in place' ", key
					
				if options.savescoops:
					
					scoop.mult( thismask )
					
					box = options.boxsize
		
					extra = math.fabs( math.sqrt(2.0) * ( box/2.0 - 1.0 ) - ( box/2.0 - 1 ) )	
					paddedbox = int( math.ceil( float(box) + extra ) )
					
					#print "Center for region is", sx,sy,sz
						
					print "\nExtracting this scoop", key
					print "With a padded box of this size", paddedbox
					bigr = Region( (sx*2 - paddedbox)/2 ,  (sy*2 - paddedbox)/2 ,  (sz*2 - paddedbox)/2, paddedbox,paddedbox,paddedbox)
					bigscoop = scoop.get_clip(bigr)
					
					#bigscoop.write_image( options.path + '/bigscoops.hdf', key)
					
					bigscoop['origin_x'] = 0
					bigscoop['origin_y'] = 0
					bigscoop['origin_z'] = 0
					
					print "\nOrienting the subscoop with this transform", t
					
					t2use = Transform()
					rot = t.get_rotation()
					
					t2use.set_rotation( rot )
					
					ti = t2use.inverse()
					bigscoop.transform( ti )
					
					#bigscoop.write_image( options.path + '/bigscoopsOriented.hdf', key)
					
					sxB = bigscoop['nx']/2
					syB = bigscoop['ny']/2
					szB = bigscoop['nz']/2
					
					print "\nCenter of bigs scoops is", sxB,syB,szB
					
					scoop = clip3D( bigscoop, box )
					
					#r = Region( (sxB*2 - box)/2 ,  (syB*2 - box)/2 ,  (szB*2 - box)/2, box,box,box)
					#scoop = bigscoop.get_clip(r)
					
					#print "\nTherefore region for small scoop is", r
					
					print "\nClipping the extracted and oriented scoop back to the desired boxsize", box
					
					defaultmask = EMData( scoop['nx'], scoop['ny'],scoop['nz'])
					defaultmask.to_one()
					defaultmask.process_inplace('mask.sharp',{'outer_radius':-1})
					
					#scoop.mult(defaultmask)
					#scoop.process_inplace('normalize.edgemean')
					scoop.mult(defaultmask)
					
					scoop['origin_x'] = 0
					scoop['origin_y'] = 0
					scoop['origin_z'] = 0
					
					scoop['spt_score'] = 0
					
					trans = t.get_trans()
					transi = -1 * trans
					
					ti2write = Transform()
					ti2write.set_rotation( ti.get_rotation() )
	 
					ti2write.set_trans( transi )
					
					scoop['xform.align3d'] = ti2write
					
					
					
					scoop['spt_scoop_center'] = [sx, sy, sz]
					
					scoop.write_image( options.path + '/' + scoopsstack, key)	
		
	E2end(logid)
	
	return
Beispiel #10
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog <stack of particles> [options] . This programs autocenters particles
		using autocorrelation or spherical averages."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument("--input",
                        type=str,
                        default='',
                        help="""Input stack in HDF format.""")

    parser.add_argument("--path",
                        type=str,
                        default='spt_autoc',
                        help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'sptautobox'; 
		for example, sptautobox_01 will be the directory by default if 'sptautobox' already exists."""
                        )

    parser.add_argument("--boxclip",
                        type=int,
                        default=0,
                        help="""The boxsize to clip the FINAL boxes 
		down to after auto-centering, so that they contain no empty pixels. Default=0 or 'off'"""
                        )

    parser.add_argument(
        "--iter",
        type=int,
        help="The number of iterations to perform. Default is 1.",
        default=1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness")

    #parser.add_argument("--averager",type=str,help="The type of averager used to produce the class average. Default=mean",default="mean")

    parser.add_argument(
        "--parallel",
        help="Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel",
        default="thread:1")

    parser.add_argument(
        "--mask",
        type=str,
        default='',
        help=
        "Mask to apply to the dataset average before spherically averaging it."
    )

    parser.add_argument(
        "--shrink",
        type=int,
        default=0,
        help="Optionally shrink the volume(s) to have the FFTs go faster")

    parser.add_argument(
        "--lowpass",
        type=str,
        help=
        "A filter applied to the average of the dataset before spherically averaging it",
        default='')

    parser.add_argument(
        "--highpass",
        type=str,
        help=
        "A filter applied to the average of the dataset before spherically averaging it",
        default='')

    parser.add_argument(
        "--preprocess",
        type=str,
        help=
        "A filter applied to the average of the dataset before spherically averaging it",
        default='')

    parser.add_argument(
        "--threshold",
        type=str,
        help=
        "A filter applied to the average of the dataset before spherically averaging it",
        default='')

    parser.add_argument(
        "--processptcls",
        type=int,
        default=0,
        help=
        "Apply all pre-processing (mask, shrink, filter, etc...) on the particles before aligning them to the previous spherical average."
    )

    parser.add_argument(
        "--averager",
        type=str,
        help=
        "The type of averager used to produce the class average. Default=mean",
        default="mean.tomo")

    parser.add_argument(
        "--normproc",
        type=str,
        help=
        "Normalization processor applied to particles before alignment. Default is to use normalize.mask. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'",
        default="normalize.mask")

    parser.add_argument(
        "--savesteps",
        action="store_true",
        help=
        "If set, will save the average after each iteration to class_#.hdf. Each class in a separate file. Appends to existing files.",
        default=False)

    parser.add_argument(
        "--saveali",
        action="store_true",
        help=
        "If set, will save the aligned particle volumes in class_ptcl.hdf. Overwrites existing file.",
        default=False)
    #parser.add_argument("--align", help="Set by default",default="translational:intonly=1")

    parser.add_argument(
        "--aligncmp",
        type=str,
        help=
        "The comparator used for the --align aligner. Default is the internal tomographic ccc. Do not specify unless you need to use another specific aligner.",
        default="ccc.tomo")

    parser.add_argument("--mode",
                        type=str,
                        default='autocorr',
                        help="""Provide --mode=sphere or --mode=autocorr.
		The first one iteratively aligns the sperical averages of individual particles to 
		the speherical average of the entire set-average. 
		The second generates mirror images of each particle in 3-D and 2-D and uses
		autocorrelation to center the particles.
		You can actually provide both modes and they will be applied sequentially in the
		order you provided them. For example, --mode=autocorr,spherical""")

    parser.add_argument(
        "--align",
        help="Set by default",
        default=
        "rotate_translate_3d_grid:alt0=0:alt1=1:az0=0:az1=1:dalt=2:daz=2:dotrans=1:dphi=2:phi0=0:phi1=1:search=10:verbose=1"
    )

    (options, args) = parser.parse_args()

    hdr = EMData(options.input, 0, True)
    nx = hdr["nx"]
    ny = hdr["ny"]
    nz = hdr["nz"]
    if nx != ny or ny != nz:
        print "ERROR, input volumes are not cubes"
        sys.exit(1)
    oldbox = nx

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options)

    if options.averager:
        options.averager = parsemodopt(options.averager)

    if options.mask:
        options.mask = parsemodopt(options.mask)

    if options.lowpass:
        options.lowpass = parsemodopt(options.lowpass)

    if options.highpass:
        options.highpass = parsemodopt(options.highpass)

    if options.preprocess:
        options.preprocess = parsemodopt(options.preprocess)

    if options.normproc:
        options.normproc = parsemodopt(options.normproc)

    if options.align:
        options.align = parsemodopt(options.align)

    if options.aligncmp:
        options.aligncmp = parsemodopt(options.aligncmp)

    n = EMUtil.get_image_count(options.input)

    modes = options.mode.split(',')

    for m in modes:
        if 'autocorr' in m:
            print "Mode is", m
            print "Number of ptcls to autocenter is", n
            print "In file", options.input
            for i in range(n):
                print "Autocentering ptcl number", i
                e = EMData(options.input, i)

                ret = autocorrcenter(e, options)
                outname = options.input.replace('.hdf', '_centered.hdf')

                ret[0].write_image(options.path + '/' + outname, i)
                ret[1].write_image(options.path + '/' + 'prjsTopRaw.hdf', i)
                ret[2].write_image(options.path + '/' + 'prjsSideRaw.hdf', i)
                ret[3].write_image(options.path + '/' + 'prjsTopCent.hdf', i)
                ret[4].write_image(options.path + '/' + 'prjsSideCent.hdf', i)

        elif 'sphere' in m:
            print "Mode is", m
            spherical(options)

    return
def main():
	#import pylab
	#import matplotlib.mlab as mlab
	import matplotlib.pyplot as plt

	progname = os.path.basename(sys.argv[0])
	usage = """Produces mean intensity histograms of stack of sub-volumes"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--input",type=str,default='',help="""Default=None. Comma-separated stacks of images whose mean intensity distribution you want to plot.""")

	parser.add_argument("--subset",type=int,default=0,help="""Default=0 (not used). N > 2 number of particles to from each stack provided through --input to consider.""")

	parser.add_argument("--path",type=str,default='',help="Directory to store results in. The default is a numbered series of directories containing the prefix 'sptsim'; for example, sptsim_02 will be the directory by default if 'sptsim_01' already exists.")

	#parser.add_argument("--output",type=str,default='',help="""Name of output plot if comparing two populations or more.""")
	
	parser.add_argument("--shrink", type=int,default=1,help="Default=1 (no shrinking). Optionally shrink the input volumes by an integer amount n > 1.")
	
	parser.add_argument("--bins", type=int,default=0,help="""Default=0 (not used). Number of bins for histogram. If not provided, the optimal bin number will be automatically calculated based on bin-width, computed using Scott's normal reference rule, width = (3.5*std)/cuberoot(n), where 'std' is the standard deviation of the mean intensity distribution of population and n is the number of mean intensity values considered (this is affected by --removesigma). Then, bins will be nbins = (max(intensities) - min(intensities)) / width.""")
	
	#parser.add_argument("--sym", type=str, default='c1', help = "Symmetry to enforce before computing mean intensity in the box. Note that this should only be used if the particles are properly aligned to the symmetry axis.")
	
	parser.add_argument("--mask",type=str,default="mask.sharp:outer_radius=-2",help="Default=mask.sharp:outer_radius=-2. Mask processor applied to the particles before alignment. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py).")
	
	parser.add_argument("--maskfile",type=str,default='',help="""Default=None. An image file containing an additional mask to apply besides --mask.""")
		
	parser.add_argument("--clip",type=int,default=0,help="""Default=0 (not used). Boxsize to clip particles to before computing mean and standard deviation values for each image. (This can act as a mask, as you'd want to clip the boxes to a smaller size than their current, original size, excluding neighboring particles and background pixels/voxels).""")	
	
	parser.add_argument("--preprocess",type=str,default='',help="""Any processor to be applied to each image before computing mean and standard deviation values. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py).""")
	
	parser.add_argument("--lowpass",type=str,default='',help="""Default=None. A lowpass filtering processor to be applied before computing mean and standard deviation values for each image. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py).""")
	
	parser.add_argument("--highpass",type=str,default='',help="""Default=None. A highpass filtering processor to be applied before computing mean and standard deviation values for each image. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py).""")

	parser.add_argument("--threshold",type=str,default='',help="""A thresholding processor to be applied before computing mean and standard deviation values for each image. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py).""")
		
	parser.add_argument("--normproc",type=str,default="normalize.edgemean",help="""Default=normalize.edgemean. Normalization processor applied to particles before computing mean and standard deviation values for each iamge. If normalize.mask is used, --mask will be passed in automatically. If you want to turn normalization off specify \'None\'. (See 'e2help.py processors' at the command line for a list of processors that can be applied through e2proc3d.py).""")

	parser.add_argument("--savepreprocessed",action="store_true",default=False,help="""Default=False. If provided, this option will save the image stacks in --input after all preprocessing options (lowpass, highpass, preprocess, masking, etc.) have been applied.""")
		
	parser.add_argument("--normalizeplot",action="store_true",default=False,help="""Default=False. This will normalize the intensity values of the distribution to be between 0 and 1""")

	parser.add_argument("--removesigma",type=int,default=0,help="""Default=0. Provide a value for the number of standard deviations away from the mean to consider values to exclude. For example, if --removesigma=3, values further than 3 standard deviations away from the mean will be excluded.""")
	
	parser.add_argument("--ppid", type=int, help="Default=1. Set the PID of the parent process, used for cross platform PPID",default=-1)

	parser.add_argument("--verbose", "-v", type=int, default=0, help="Default 0. Verbose level [0-9], higner number means higher level of verboseness",dest="verbose", action="store", metavar="n")

	(options, args) = parser.parse_args()
	
	logger = E2init(sys.argv, options.ppid)
	
	'''
	if options.mask: 
		options.mask=parsemodopt(options.mask)
	
	if options.preprocess: 
		options.preprocess=parsemodopt(options.preprocess)
		
	if options.lowpass: 
		options.lowpass=parsemodopt(options.lowpass)
	
	if options.highpass: 
		options.highpass=parsemodopt(options.highpass)
	
	if options.threshold: 
		options.threshold=parsemodopt(options.threshold)
		
	if options.normproc: 
		options.normproc=parsemodopt(options.normproc)
	'''
	
	from e2spt_classaverage import sptOptionsParser
	options = sptOptionsParser( options )
	
	datafiles = options.input.split(',')
	
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath( options, 'meanintensityplots')
	
	
	intensitiesSeveral = []
	iwzSeveral = []
	iminsSeveral = []
	imaxsSeveral = []
	istdsSeveral = []
	
	means = []
	stds = []
	
	from e2spt_classaverage import writeParameters
	cmdwp = writeParameters(options,'e2spt_meanintensityplot.py', 'sptmeanintensity')
	
	for datafile in datafiles:
		n = EMUtil.get_image_count(datafile)
		
		if options.subset:
			if options.subset < 3:
				print "ERROR:Subset must be > 2."
				sys.exit(1)
			
			n = options.subset
			
		if n < 3:
			print "ERROR: All stacks must have at least 3 particles in them. This one doesn't:", datafile
			sys.exit(1)
	
	for datafile in datafiles:
		ret = calcintensities( options, datafile )
		
		intensitiesSingle = ret[0]
		iwz = ret[1]
		imins = ret[2]
		imaxs = ret[3]
		istds = ret[4]
		
		intensitiesSeveral.append( [ datafile, list( intensitiesSingle ) ] )
		
		iwzSeveral.append( [ datafile, list( iwz ) ] )
		iminsSeveral.append( [ datafile, list( imins ) ] ) 
		imaxsSeveral.append( [ datafile, list( imaxs ) ] ) 
		istdsSeveral.append( [ datafile, list( istds ) ] ) 
				
		
		intensitiesSingleNorm = intensitiesSingle
		
		if options.normalizeplot:
			intensitiesSingleNorm = normintensities( intensitiesSingle, 0, 0 )
		
		#print "\]n\\n\nIntensities before plotting are", intensitiesSingleNorm
		#print "\n\n\n\n\n"
		
		ret = plotintensities( intensitiesSingleNorm, options, datafile )
		mean = ret[0]
		std = ret[1]
		means.append(mean)
		stds.append(std)
		
		
		ret = plotintensities( iwz, options, datafile,'wz' )
		ret = plotintensities( imins, options, datafile,'mins' )
		ret = plotintensities( imaxs, options, datafile,'maxs' )
		ret = plotintensities( istds, options, datafile,'stds' )
		
	#print "\nIntensities several len is", len( intensitiesSeveral )
	if len( intensitiesSeveral ) > 1:
		
		datafile1 = intensitiesSeveral[0][0]
		datafile2 = intensitiesSeveral[1][0]
		
		intensities1 = intensitiesSeveral[0][1]
		intensities2 = intensitiesSeveral[1][1]
		n1 = len( intensities1 )
		n2 = len( intensities2 )
		
		zscore = ( means[0]-means[1] )/ np.sqrt( (stds[0]*stds[0])/n1 + (stds[1]*stds[1])/n2 )
		
		g = open(options.path + '/MIboth_INFO.txt','w')
		zscoreline = 'zscore=' + str(zscore)+' for ' + datafile1 + ' vs ' + datafile2 + ' \n'
		lines=[ zscoreline ]
		g.writelines(lines)
		g.close()
		
		print "\nzzzzzzz\n%s" %( zscoreline )
		
		absmax = absmin = 0
		if options.normalizeplot:
		
			minses = []
			maxes = []
			for intenS in intensitiesSeveral:
				minS = float(min( intenS[1] ))
				maxS = float(max( intenS[1] ))
				
				minses.append( minS )
				maxes.append( maxS )
	
			absmin = min( minses )
			absmax = max( maxes ) - absmin
		
		for intensities in intensitiesSeveral:	
			print "Type and len of intensities is", type(intensities[1]), len(intensities[1])
			
			intensitiesNorm = intensities[1]			
			if options.normalizeplot:
				print "Normalizeplot on"	
				intensitiesNorm = normintensities( intensities[1], absmin, absmax )
				
			plotintensities( intensitiesNorm, options, datafile, 'no' )
	
		plt.savefig(options.path + '/MIbothPlot.png')
		plt.clf()
		
	E2end(logger)
Beispiel #12
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options]

	This program runs different spt programs quickly, in testing mode, such that crashes
	can be identified more easily.
	"""
	
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)

	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n", type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	
	parser.add_argument("--testn",type=int,default=6,help="""default=6. size of dataset to run tests with; cannot be < 6, since initial model generation with HAC for gold-standard refinement requires at least 3 particles for the even set and 3 for the odd set.""")
	
	parser.add_argument("--path",type=str,default='spttests',help="""Default=spttests. Directory to store results in. The default is a numbered series of directories containing the prefix 'spttests'; for example, spttests_02 will be the directory by default if 'spttests_01' already exists.""")
	
	parser.add_argument("--parallel",type=str,default='',help="""the program will detect the number of cores available and use threaded parallelism by default. To use only one core, supply --parallel=thread:1. For MPI on clusters, see parallelism at http://blake.bcm.edu/emanwiki/EMAN2/Parallel""")
	
	#parser.add_argument("--testsim",action='store_true',default=False,help="""default=False. If supplied, this option will test e2spt_simulation.py as well and use the generated simulated particles for subsequent tests, opposed to random volumes that do not have a missing wedge, noise or CTF.""")
	
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
		
	(options, args) = parser.parse_args()

	logger = E2init(sys.argv, options.ppid)
	
	if not options.parallel:
		import multiprocessing
		nparallel = multiprocessing.cpu_count()
		options.parallel = 'thread:' + str(nparallel)
		print "\nfound %d cores" %(nparallel)
		print "setting --parallel to", options.parallel
	
	if options.testn < 6:
		print "\nERROR: --testn must be > 5."
		sys.exit()
	
	
	'''
	Make the directory where to create the database where the results will be stored
	'''
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'spt_bt')
	
	from e2spt_classaverage import writeParameters
	writeParameters(options,'e2spt_test.py', 'spttests')
	
	for i in range( options.testn ):
		a = test_image_3d()
		t=Transform()
		if i > 0:
			az = random.randint(0,360)
			alt = random.randint(0,180)
			phi = random.randint(0,360)
			tx = random.randint(-5,5)
			ty = random.randint(-5,5)
			tz = random.randint(-5,5)
			t = Transform({'type':'eman','tx':tx,'ty':ty,'tz':tz,'alt':alt,'az':az,'phi':phi})
			a.transform(t)
		
		a.process_inplace('math.meanshrink',{'n':4})
		a['spt_randT'] = t
		a.write_image(options.path + '/testimgs.hdf',-1)
		
		if i==0:
			a.write_image(options.path + '/testimg_ref.hdf',0)
		
	cmds = []
	
	rootpath = os.getcwd()
	
	
	os.system('touch ' + options.path + '/output.txt')
	
	#input = rootpath + '/' + options.path + '/testimgs.hdf'
	#if options.testsim:
	
	simcmd = 'e2spt_simulation.py --input=' + options.path + '/testimg_ref.hdf --nptcls ' + str(options.testn) + ' --tiltrange 60 --nslices 25 --saveprjs --applyctf --snr 2' + ' --parallel=' +options.parallel + ' --path testsim'
	if options.verbose:
		simcmd += ' --verbose ' + str(options.verbose)
	
	cmds.append( simcmd )
	simcmd2 = 'mv testsim ' + options.path
	cmds.append( simcmd2 )

	input = rootpath + '/' + options.path +'/testsim/simptcls.hdf'
	
	
	btcmd = 'e2spt_binarytree.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --parallel=' +options.parallel + ' --path testbt'
	cmds.append( btcmd )
	btcmd2 = 'mv testbt ' + rootpath + '/' + options.path + '/'
	cmds.append( btcmd2 )
	
	haccmd = 'e2spt_hac.py  --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --parallel=' +options.parallel + ' --path testhac'
	cmds.append( haccmd )
	haccmd2 = 'mv testhac ' + rootpath + '/' + options.path + '/'
	cmds.append( haccmd2 )
	
	ssacmd = 'e2symsearch3d.py  --input ' + input + ' --sym icos --steps 2 --parallel=' +options.parallel + ' --path testssa'
	cmds.append( ssacmd )
	ssacmd2 = 'mv testssa ' + rootpath + '/' + options.path + '/'
	cmds.append( ssacmd2 )
	
	
	sptdefaultcmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --parallel=' +options.parallel + ' --path testsptdefaultgoldoff'
	cmds.append( sptdefaultcmdgoldoff )
	sptdefaultcmdgoldoff2 = 'mv testsptdefaultgoldoff ' + rootpath + '/' + options.path + '/'
	cmds.append( sptdefaultcmdgoldoff2 )
	
	sptrefbtcmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --btref 2 --parallel=' +options.parallel + ' --path testsptrefbtgoldoff'
	cmds.append( sptrefbtcmdgoldoff )
	sptrefbtcmdgoldoff2 = 'mv testsptrefbtgoldoff ' + rootpath + '/' + options.path + '/'
	cmds.append( sptrefbtcmdgoldoff2 )
	
	sptrefssacmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --ssaref 2 --parallel=' +options.parallel + ' --path testsptrefssagoldoff'
	cmds.append( sptrefssacmdgoldoff )
	sptrefssacmdgoldoff2 = 'mv testsptrefssagoldoff ' + rootpath + '/' + options.path + '/'
	cmds.append( sptrefssacmdgoldoff2 )
	
	sptrefhaccmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --hacref 3 --parallel=' +options.parallel + ' --path testsptrefhacgoldoff'
	cmds.append( sptrefhaccmdgoldoff )
	sptrefhaccmdgoldoff2 = 'mv testsptrefhacgoldoff ' + rootpath + '/' + options.path + '/'
	cmds.append( sptrefhaccmdgoldoff2 )
	
	
	sptdefaultcmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --parallel=' +options.parallel + ' --path testsptdefaultgoldon'
	cmds.append( sptdefaultcmdgoldon )
	sptdefaultcmdgoldon2 = 'mv testsptdefaultgoldon ' + rootpath + '/' + options.path + '/'
	cmds.append( sptdefaultcmdgoldon2 )
	
	sptrefbtcmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --btref 4 --parallel=' +options.parallel + ' --path testsptrefbtgoldon'
	cmds.append( sptrefbtcmdgoldon )
	sptrefbtcmdgoldon2 = 'mv testsptrefbtgoldon ' + rootpath + '/' + options.path + '/'
	cmds.append( sptrefbtcmdgoldon2 )
	
	sptrefssacmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --ssaref 4 --parallel=' +options.parallel + ' --path testsptrefssagoldon'
	cmds.append( sptrefssacmdgoldon )
	sptrefssacmdgoldon2 = 'mv testsptrefssagoldon ' + rootpath + '/' + options.path + '/'
	cmds.append( sptrefssacmdgoldon2 )
	
	sptrefhaccmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --hacref 6 --parallel=' +options.parallel + ' --path testsptrefhacgoldon'
	cmds.append( sptrefhaccmdgoldon )
	sptrefhaccmdgoldon2 = 'mv testsptrefhacgoldon ' + rootpath + '/' + options.path + '/'
	cmds.append( sptrefhaccmdgoldon2 )
	
	for cmd in cmds:
		runcmd( options, cmd )
	

	E2end(logger)
	sys.stdout.flush()
	
	
	
	return
Beispiel #13
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] 
	This program extracts parts of 3D maps from specific coordinates with the shape of a 
	user-defined mask, or from symmetry-related positions based on a defined radius and, 
	again, a user-defined mask.
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--input",
        default='',
        type=str,
        help="""3D map or stack of maps to extract smaller regions from.""")

    parser.add_argument(
        "--output",
        default='extracts',
        type=str,
        help=
        """String to use as the 'stem' for naming output volumes. Note that for each input volume, you'll get a stack of subvolumes. For example, if you provide a stack with 3 volumes, and you extract 12 subvolumes from each of these, you'll have 3 stacks of extracted subvolumes."""
    )

    parser.add_argument(
        "--path",
        type=str,
        help=""""Name of directory where to store the output file(s)""",
        default="melonscoops")

    parser.add_argument(
        "--sym",
        dest="sym",
        default="c1",
        help=
        """Specify symmetry. Choices are: c<n>, d<n>, h<n>, tet, oct, icos. For asymmetric reconstruction ommit this option or specify c1."""
    )

    parser.add_argument(
        "--vertices",
        action='store_true',
        default=False,
        help=
        """Only works if --sym=icos. This flag will make the program extract only the 12 vertices from among all 60 symmetry related units."""
    )

    parser.add_argument(
        "--mask",
        type=str,
        help=
        """Mask processor to define the shape of regions to extract. Default is None.""",
        default="")

    parser.add_argument(
        "--maskfile",
        type=str,
        help=
        """Precomputed mask to use to extract subvolumes from the locations specified through --coords or through --radius and --sym""",
        default="")

    parser.add_argument(
        "--savescoops",
        action='store_true',
        default='',
        help=
        """Save extracted parts from each particle into a per-particle stack, with extracted subvolumes centered in a box of the size specified by --boxsize, and rotated so that each subvolume is pointing along Z."""
    )

    parser.add_argument(
        "--savescoopsinplace",
        action='store_true',
        default='',
        help=
        """Save extracted parts from each particle into a per-particle stack, with extracted subvolumes 'in-situ'; that is, with the same size and orientation as in the original volume."""
    )

    parser.add_argument(
        "--coords",
        type=str,
        help="""File with coordinates from where to extract subvolumes.""",
        default="")

    parser.add_argument(
        "--radius",
        type=int,
        help=
        """Radius (in pixels) where to center the mask for subvolume extraction. Works only for cases in which the asymmetric unit of interest lies along z (for example, vertexes of an icosahedral virus aligned to the symmetry axes such that a vertex lies along z). Supplying --tz should achieve the same results.""",
        default=0)

    parser.add_argument(
        "--tx",
        type=int,
        help=
        """Translation (in pixels) along x to define the mask's center. If supplied with --radius, the latter will be ignored.""",
        default=0)

    parser.add_argument(
        "--ty",
        type=int,
        help=
        """Translation (in pixels) along y to define the masks's center. If supplied with --radius, the latter will be ignored.""",
        default=0)

    parser.add_argument(
        "--tz",
        type=int,
        help=
        """Translation (in pixels) along z to define the masks's center. If supplied with --radius, the latter will be ignored.""",
        default=0)

    #parser.add_argument("--normproc",type=str,default='',help="Normalization processor applied to particles before alignment. Default is to use normalize. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'")
    #
    #parser.add_argument("--threshold",default='',type=str,help="""A threshold applied to the subvolumes after normalization.
    #												For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=10, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')
    #
    #parser.add_argument("--preprocess",default='',type=str,help="Any processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=10, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')

    #parser.add_argument("--lowpass",type=str,default='',help="A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=17, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')

    #parser.add_argument("--highpass",type=str,default='',help="A highpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.", guitype='comboparambox', choicelist='re_filter_list(dump_processors_list(),\'filter\')', row=18, col=0, rowspan=1, colspan=3, mode='alignment,breaksym')

    parser.add_argument(
        "--boxsize",
        type=int,
        default=0,
        help=
        """If specified, the output subvolumes will be clipped to this size and centered in the box; otherwise, they will be saved in a boxsize equal to the volume they came from."""
    )

    #parser.add_argument("--parallel","-P",type=str,help="Run in parallel, specify type:<option>=<value>:<option>:<value>",default=None, guitype='strbox', row=8, col=0, rowspan=1, colspan=2, mode="align")

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )

    (options, args) = parser.parse_args()

    if options.mask:
        options.mask = parsemodopt(options.mask)

    if not options.input:
        parser.print_help()
        sys.exit(0)

    if options.savescoops and not options.boxsize:
        print """ERROR: Specify the box size through --boxsize for the saved
		scoops."""
        sys.exit()

    #If no failures up until now, initialize logger
    logid = E2init(sys.argv, options.ppid)

    inputhdr = EMData(options.input, 0, True)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, options.path)

    if not options.mask and not options.maskfile:
        print "\nERROR: You must define --mask or supply a volume through --maskfile"
        sys.exit()

    mask = EMData(inputhdr['nx'], inputhdr['ny'], inputhdr['nz'])
    mask.to_one()

    if options.mask:
        mask.process_inplace(options.mask[0], options.mask[1])

    elif options.maskfile:
        mask = EMData(options.maskfile)
        '''
		Center of maskfile
		'''
        maskcx = mask['nx']
        maskcy = mask['ny']
        maskcz = mask['nz']
        '''
		Clip to data's boxsize
		'''
        r = Region((2 * maskcx - inputhdr['nx']) / 2,
                   (2 * maskcx - inputhdr['ny']) / 2,
                   (2 * maskcx - inputhdr['nz']) / 2, inputhdr['nx'],
                   inputhdr['ny'], inputhdr['nz'])
        mask.clip_inplace(r)

    print "\nMask done"

    if options.radius:
        mask.translate(0, 0, float(options.radius))
        print "\nMask translated by radius %d along z" % (options.radius)

    else:
        mask.translate(options.tx, options.ty, options.tz)
        print "\nMask translated by tx=%d, ty=%d, tz=%d,", options.tx, options.ty, options.tz

    symnames = ['oct', 'OCT', 'icos', 'ICOS', 'tet', 'TET']

    orientations = []
    #transforms = []
    anglelines = []

    if options.sym:
        print "\nsym found", options.sym

        symnum = 0

        if options.sym not in symnames:

            symletter = options.sym
            symnum = options.sym

            for x in options.sym:
                if x.isalpha():
                    symnum = symnum.replace(x, '')

            for x in options.sym:
                if x.isdigit():
                    symletter = symletter.replace(x, '')

            print "\nThe letter for sym is", symletter
            print "\nThe num for sym is", symnum

        if options.sym == 'oct' or options.sym == 'OCT':
            symnum = 8

        if options.sym == 'tet' or options.sym == 'TET':
            symnum = 12

        if options.sym == 'icos' or options.sym == 'ICOS':
            symnum = 60

        symnum = int(symnum)

        t = Transform()

        if symnum:
            print "\nsymnum determined", symnum
            print "while symletter is", symletter

            if symletter == 'd' or symletter == 'D':
                symnum *= 2
                print "\nsymnum corrected, because symmetry is d", symnum

            #if options.save

            for i in range(symnum):
                orientation = t.get_sym(options.sym, i)
                orientations.append(orientation)

                rot = orientation.get_rotation()
                az = rot['az']
                alt = rot['alt']
                phi = rot['phi']

                anglesline = 'az=' + str(az) + 'alt=' + str(
                    alt) + 'phi=' + str(phi) + '\n'
                anglelines.append(anglesline)

                #transforms.append( Transform({'type':'eman','az':az,'alt':alt,'phi':phi}) )

    n = EMUtil.get_image_count(options.input)

    centers = {}
    masks = {}

    if orientations:
        print "\ngenerated these many orientations", len(orientations)
        if options.sym == 'icos' or options.sym == 'ICOS':
            if options.vertices:

                print "\nbut fetching vertices only"

                #orientations = genicosvertices ( orientations )

                orientations = genicosverticesnew(orientations)

        centerx = 0.0
        centery = 0.0
        centerz = float(options.radius)

        if not options.radius:
            centerx = options.tx
            centery = options.ty
            centerz = options.tz

        groundv = Vec3f(centerx, centery, centerz)

        finalmask = EMData(mask['nx'], mask['ny'], mask['nz'])
        finalmask.to_zero()

        centersmap = EMData(mask['nx'], mask['ny'], mask['nz'])
        centersmap.to_zero()

        centerstxt = options.path + '/centers.txt'
        f = open(centerstxt, 'a')
        for k in range(len(orientations)):
            t = orientations[k]

            print "\nWorking with this orientation", t

            tmpmask = mask.copy()
            tmpmask.transform(t)

            tmpmask['origin_x'] = 0
            tmpmask['origin_y'] = 0
            tmpmask['origin_z'] = 0

            finalmask = finalmask + tmpmask

            center = t * groundv
            centers.update({k: center})

            newcenterx = int(round(center[0] + mask['nx'] / 2.0))
            newcentery = int(round(center[1] + mask['ny'] / 2.0))
            newcenterz = int(round(center[2] + mask['nz'] / 2.0))

            tout = Transform()
            rot = t.get_rotation()

            tout.set_rotation(rot)
            tout.set_trans(newcenterx, newcentery, newcenterz)

            tmpmask['spt_scoop_center'] = [newcenterx, newcentery, newcenterz]
            tmpmask['xform.align3d'] = tout

            tmpmask.write_image(options.path + '/masks.hdf', k)

            masks.update(
                {k: [tmpmask, tout, [newcenterx, newcentery, newcenterz]]})

            centerline = str(newcenterx) + ' ' + str(newcentery) + ' ' + str(
                newcenterz) + '\n'

            f.write(centerline)

            centersmap.set_value_at(int(round(center[0] + mask['nx'] / 2.0)),
                                    int(round(center[1] + mask['ny'] / 2.0)),
                                    int(round(center[2] + mask['nz'] / 2.0)),
                                    1.0)

            #print "setting indx and t are", k, t
            #print "whereas mask t is", tout

        f.close()

        finalmask.write_image(options.path + '/finalmask.hdf', 0)
        centersmap.write_image(options.path + '/centersmap.hdf', 0)

        for i in range(n):
            ptcl = EMData(options.input, i)

            ptclnumtag = str(i).zfill(len(str(n)))

            scoopsinplacestack = 'ptcl' + ptclnumtag + '_scoopsOrigBox.hdf'

            scoopsstack = 'ptcl' + ptclnumtag + '_scoops.hdf'

            ptclglobalmsk = ptcl.copy()
            ptclglobalmsk.mult(finalmask)

            ptclglobalmsk.write_image(
                options.path + '/' + 'ptcls_globallymasked.hdf', i)

            for key in masks.keys():

                scoopinplace = ptcl.copy()
                scoop = ptcl.copy()

                thismask = masks[key][0]

                t = masks[key][1]

                #tapp = Transform()
                #rot = t.get_rotation()
                #tapp.set_rotation( rot )

                #print "key and t are", key, tapp
                sx = masks[key][-1][0]
                sy = masks[key][-1][1]
                sz = masks[key][-1][2]

                if options.savescoopsinplace:

                    #scoopinplace.mult( thismask )
                    scoopinplace.process_inplace('normalize.edgemean')
                    scoopinplace.mult(thismask)

                    scoopinplace['origin_x'] = 0
                    scoopinplace['origin_y'] = 0
                    scoopinplace['origin_z'] = 0

                    scoopinplace['spt_scoop_x'] = sx
                    scoopinplace['spt_scoop_y'] = sy
                    scoopinplace['spt_scoop_z'] = sz

                    scoopinplace['spt_score'] = 0

                    scoopinplace['xform.align3d'] = t

                    scoopinplace.write_image(
                        options.path + '/' + scoopsinplacestack, key)
                    print "\nWrote this scoop 'in place' ", key

                if options.savescoops:

                    scoop.mult(thismask)

                    box = options.boxsize

                    extra = math.fabs(
                        math.sqrt(2.0) * (box / 2.0 - 1.0) - (box / 2.0 - 1))
                    paddedbox = int(math.ceil(float(box) + extra))

                    #print "Center for region is", sx,sy,sz

                    print "\nExtracting this scoop", key
                    print "With a padded box of this size", paddedbox
                    bigr = Region(
                        (sx * 2 - paddedbox) / 2, (sy * 2 - paddedbox) / 2,
                        (sz * 2 - paddedbox) / 2, paddedbox, paddedbox,
                        paddedbox)
                    bigscoop = scoop.get_clip(bigr)

                    #bigscoop.write_image( options.path + '/bigscoops.hdf', key)

                    bigscoop['origin_x'] = 0
                    bigscoop['origin_y'] = 0
                    bigscoop['origin_z'] = 0

                    print "\nOrienting the subscoop with this transform", t

                    t2use = Transform()
                    rot = t.get_rotation()

                    t2use.set_rotation(rot)

                    ti = t2use.inverse()
                    bigscoop.transform(ti)

                    #bigscoop.write_image( options.path + '/bigscoopsOriented.hdf', key)

                    sxB = bigscoop['nx'] / 2
                    syB = bigscoop['ny'] / 2
                    szB = bigscoop['nz'] / 2

                    print "\nCenter of bigs scoops is", sxB, syB, szB

                    scoop = clip3D(bigscoop, box)

                    #r = Region( (sxB*2 - box)/2 ,  (syB*2 - box)/2 ,  (szB*2 - box)/2, box,box,box)
                    #scoop = bigscoop.get_clip(r)

                    #print "\nTherefore region for small scoop is", r

                    print "\nClipping the extracted and oriented scoop back to the desired boxsize", box

                    defaultmask = EMData(scoop['nx'], scoop['ny'], scoop['nz'])
                    defaultmask.to_one()
                    defaultmask.process_inplace('mask.sharp',
                                                {'outer_radius': -1})

                    #scoop.mult(defaultmask)
                    #scoop.process_inplace('normalize.edgemean')
                    scoop.mult(defaultmask)

                    scoop['origin_x'] = 0
                    scoop['origin_y'] = 0
                    scoop['origin_z'] = 0

                    scoop['spt_score'] = 0

                    trans = t.get_trans()
                    transi = -1 * trans

                    ti2write = Transform()
                    ti2write.set_rotation(ti.get_rotation())

                    ti2write.set_trans(transi)

                    scoop['xform.align3d'] = ti2write

                    scoop['spt_scoop_center'] = [sx, sy, sz]

                    scoop.write_image(options.path + '/' + scoopsstack, key)

    E2end(logid)

    return
Beispiel #14
0
def main():
	
	progname = os.path.basename(sys.argv[0])
	usage = """WARNING:  **PRELIMINARY** program, still heavily under development. 
				Autoboxes globular particles from tomograms.
				Note that self-generated spherical templates generated by this program
				are 'white'; which means you have to provide the tomogram with inverted (or 'white') contrast, and the same goes for any stacks
				provided (specimen particles, gold, carbon and/or background)."""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--apix",type=float,default=0.0,help="""Default=0.0 (not used). Use this apix value where relevant instead of whatever is in the header of the reference and the particles.""")

	parser.add_argument("--automask",action='store_true',default=False,help="""Applies loose automask at threshold=2.0""")
	
	parser.add_argument("--averager",type=str,default="mean.tomo",help="""Default=mean.tomo. The type of averager used to produce the class average.""")

	parser.add_argument("--clip",type=float,default=0,help="""Default=0 (not used). Size to clip the box to before calculating FSCs. If particle of 64 pixels in diameter are in a 128x128x128 box, it's safe to provide --clip 70 or so""")

	parser.add_argument("--inputeven", type=str, default='',help="""Default=None. The name of the EVEN aligned volume stack after gold-standard SPT refinement. MUST be HDF since volume stack support is required.""")

	parser.add_argument("--inputodd", type=str, default='',help="""Default=None. The name of the ODD aligned volume stack after gold-standard SPT refinement. MUST be HDF since volume stack support is required.""")
	
	parser.add_argument("--mask",action='store_true',default=False,help="""Applies soft mask beyond the radius of the particle assumed to be 1/4 + 0.2*1/4 of the box size.""")

	parser.add_argument("--path",type=str,default='sptbfactor',help="""Default=spt. Directory to store results in. The default is a numbered series of directories containing the prefix 'spt'; for example, spt_02 will be the directory by default if 'spt_01' already exists.""")

	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	parser.add_argument("--runningavg",action='store_true',default=False,help="""Computes running average of particles weighing properly, instead of computing each average (as N grows) from scratch.""")

	parser.add_argument("--step",type=int,default=1,help="""Number of particles to increase from one data point to the next. For example, --step=10 will compute the B-factor averaging 10 particles from the even set and 10 from the odd set; then 20; then 40; etc.""")

	parser.add_argument("--sym", type=str, default='', help="""Default=None (equivalent to c1). Symmetry to impose -choices are: c<n>, d<n>, h<n>, tet, oct, icos""")
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	
	(options, args) = parser.parse_args()	#c:this parses the options or "arguments" listed 
											#c:above so that they're accesible in the form of option.argument; 
											#c:for example, the input for --template would be accesible as options.template
		
	logger = E2init(sys.argv, options.ppid)	#c:this initiates the EMAN2 logger such that the execution
											#of the program with the specified parameters will be logged
											#(written) in the invisible file .eman2log.txt
	
	
	options.averager=parsemodopt(options.averager)
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'sptbfactor')

	ne = EMUtil.get_image_count( options.inputeven )
	no = EMUtil.get_image_count( options.inputodd )

	hdr = EMData( options.inputeven, 0, True )
	box = hdr['nx']
	radius = box/4
	
	print "\nradius is", radius
	radius_expanded = radius + math.ceil(0.2*radius)
	
	print "\nradius expanded is", radius_expanded
	
	nfinal = (ne+no)/2
	if ne < nfinal:
		nfinal = ne
	elif no < nfinal:
		nfinal = no
	
	fscareas = []
	fscareasdict={}
	
	
	preve = EMData( options.inputeven, 0 )
	prevo = EMData( options.inputodd, 0 )
	
	avge = preve.copy()
	avgo = prevo.copy()
	
	avge.process_inplace('normalize.edgemean')
	avgo.process_inplace('normalize.edgemean')
	
	for thisn in xrange( 1, nfinal+1, options.step ):
		
		indx = thisn-1
		
		if options.runningavg:
			if indx > 0:
				avge = runningavg( options.inputeven, preve, options, indx )
				avgo = runningavg( options.inputodd, prevo, options, indx )
				
				preve = avge.copy()
				prevo = avge.copy()
		else:
			avge = averagerfunc( options.inputeven, options, thisn )
			avgo = averagerfunc( options.inputodd, options, thisn )
		
		if options.mask:
			avge.process_inplace('mask.soft',{'outer_radius':radius_expanded})
			avgo.process_inplace('mask.soft',{'outer_radius':radius_expanded})
		if options.automask:
			avge.process_inplace('mask.auto3d',{'radius':1,'nmaxseed':10,'nshells':1,'nshellsgauss':10,'threshold':2.0})
			avgo.process_inplace('mask.auto3d',{'radius':1,'nmaxseed':10,'nshells':1,'nshellsgauss':10,'threshold':2.0})

		avge_w = avge.copy()
		avgo_w = avgo.copy()
		if options.sym:
			avge_w.process_inplace('xform.applysym',{'sym':options.sym})
			avgo_w.process_inplace('xform.applysym',{'sym':options.sym})
		
		fscarea = calcfsc( options, avge_w, avgo_w )

		fscareas.append( fscarea )
		fscareasdict.update({indx:fscarea})
		
		f = open( options.path +'/n_vs_fsc.txt','w' )
		fsclines = []
		
		x=0
		sortedfscareasdict = collections.OrderedDict(sorted(fscareasdict.items()))
		
		#for fscarea in fscareas:
		for k in sortedfscareasdict:
			fscareak = sortedfscareasdict[k]
			fscline = str(x) + '\t'+ str(fscareak) + '\n'
			fsclines.append( fscline )
			x+=1
	
		f.writelines( fsclines )
		f.close()
		print "\ndone with fsc %d/%d" %(thisn,nfinal)

	
	
	
	'''	
	ccc
	ccc.tomo.thresh
	ccc.tomo
	fsc.tomo.auto
	'''
	
	return
Beispiel #15
0
def main():

	usage = """e2orthoproject.py <options> . 
			The options should be supplied in "--option=value", replacing "option" for a valid option name, and "value" for an acceptable value for that option. 
			This program produces orthogonal projections of an EM volume.
			"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)	
	
	parser.add_argument("--path",type=str,default=None,help="""Directory to store results in. The default is a numbered series of directories containing the prefix 'orthoproject';
														for example, orthoproject_02 will be the directory by default if 'orthoproject_01' already exists.""")

	parser.add_argument("--onlyx",action='store_true',default=False,help="Only projection of the YZ plane will be generated [a 'side view'].")
	parser.add_argument("--onlyy",action='store_true',default=False,help="Only projection of the XZ plane will be generated [another 'side view'].")
	parser.add_argument("--onlyz",action='store_true',default=False,help="Only projection of the XY plane will be generated a 'top view']")
	
	parser.add_argument("--shrink",type=int,default=False,help="Integer value to shrink the models by before generating projections.")

	
	parser.add_argument("--saverotvol",action='store_true',default=False,help="Will save the volume in each rotated position used to generate a projection.")

	parser.add_argument("--input", type=str, help="""The name of the input volume from which you want to generate orthogonal projections.
													You can supply more than one model either by providing an .hdf stack of models, or by providing multiple files
													separated by commas.""", default=None)

	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")

	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	parser.add_argument("--mask",type=str,help="Mask processor applied to particles before alignment. Default is None", default=None)
	parser.add_argument("--lowpass",type=str,help="A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.", default=None)

	parser.add_argument("--transformsfile",type=str,help="A text files containing lines with one triplet of az,alt,phi values each, representing the transforms to use to project a single volume supplied. ", default='')
	parser.add_argument("--angles",type=str,help="A single comma or space separated triplet of az,alt,phi values representing the particle rotation to apply before projecting it.", default='')
	parser.add_argument("--tag",type=str,help="When supplying --angles, tag the output projection with a string provided through --tag", default='')

	parser.add_argument("--normproc",type=str,help="""Normalization processor applied to particles before alignment. 
													Default is to use normalize.mask. If normalize.mask is used, results of the mask option will be passed in automatically. 
													If you want to turn this option off specify \'None\'""", default="normalize.edgemean")


	(options, args) = parser.parse_args()	
	
	
	if not options.input:
		#print "ERROR: Supply volume(s) through --input=."
		
		try:
			options.input = sys.argv[1]
			EMData(options.input,0,True)
		except:
			print "ERROR: input file %s seems to have an invalid format" %( options.input )
			sys.exit()
	
	if options.transformsfile:
		n=EMUtil.get_image_count(options.input)
		if n>1:
			print "ERROR: You cannot supply --transformsfile for particle stacks; it only works for individual volumes."
			sys.exit()
	
	'''
	Check for sanity of some supplied parameters
	'''

	if options.onlyz:
		if options.onlyx or options.onlyy:
			print "ERROR: You can only supply one of --onlyx, --onlyy or --onlyz at a time."
			sys.exit()
	
	if options.onlyx:
		if options.onlyy or options.onlyz:
			print "ERROR: You can only supply one of --onlyx, --onlyy or --onlyz at a time."
			sys.exit()
			
	if options.onlyy:
		if options.onlyx or options.onlyz:
			print "ERROR: You can only supply one of --onlyx, --onlyy or --onlyz at a time."
			sys.exit()


	if options.onlyz and options.onlyx:
		print "ERROR: Cannot supply --onlyz and --onlyx at the same time"
		sys.exit()
	if options.onlyz and options.onlyy:
		print "ERROR: Cannot supply --onlyz and --onlyy at the same time"
		sys.exit()
	if options.onlyy and options.onlyx:
		print "ERROR: Cannot supply --onlyy and --onlyx at the same time"
		sys.exit()
	
	'''
	Generate projection transforms
	'''
	
	projectiondirections = []
	
	if options.onlyz:
		pz = Transform({'type':'eman','az':0,'alt':0,'phi':0})
		projectiondirections={'pz':pz}
	elif options.onlyx:
		px = Transform({'type':'eman','az':90,'alt':-90,'phi':0})
		projectiondirections={'px':px}
	elif options.onlyy:
		py = Transform({'type':'eman','az':0,'alt':90,'phi':0})

		projectiondirections={'py':py}
	else:	
		pz = Transform({'type':'eman','az':0,'alt':0,'phi':0})
		px = Transform({'type':'eman','az':90,'alt':-90,'phi':0})
		py = Transform({'type':'eman','az':0,'alt':90,'phi':0})
		projectiondirections = {'pz':pz,'px':px,'py':py}

	if options.transformsfile:
		f = open(options.transformsfile, 'r')
		lines = f.readlines()
		f.close()
		
		np = len(lines)
		k=0
		for line in lines:
			line=line.replace(',',' ')
			line=line.replace('\n','')
			line=line.replace('\t',' ')
			line=line.split()
			t=Transform({'type':'eman','az':float(line[0]),'alt':float(line[1]),'phi':float(line[2])})
			tag = 'p' + str(k).zfill(len(str(np)))
			projectiondirections.update({ tag:t })
			k+=1
	
	#elif options.angles:
	#	angles=options.angles
	#	angles=angles.replace(',',' ')
	#	angles=angles.split()
	#	t=Transform({'type':'eman','az':float(angles[0]),'alt':float(angles[1]),'phi':float(angles[2])})
		
	#	tag = 'p' + 'az' + str(int(round(float( angles[0] )))) + 'alt' + str(int(round(float( angles[1] ))))  + 'phi' + str(int(round(float( angles[2] ))))  
	#	if options.tag:
	#		tag = options.tag
		
		#projectiondirections.update({ tag:t })
		
	

	logger = E2init(sys.argv, options.ppid)

	if options.mask: 
		options.mask=parsemodopt(options.mask)
		
	if options.lowpass: 
		options.lowpass=parsemodopt(options.lowpass)
		
	if options.normproc: 
		options.normproc=parsemodopt(options.normproc)
	'''
	Make a directory where to store the results
	'''
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'orthoprjs')
	

	'''
	Read input
	'''

	print "options.input",options.input
	models=options.input.split(',')
	
	rootpath = os.getcwd()
	path = rootpath + '/' + options.path
	
	for model in models:
		n = EMUtil.get_image_count(model)	
		
		newpath = path
		if len(models) > 1:
			newpath = path + '/' + model.split('.hdf')[0]
			os.system('mkdir ' + newpath)
		
		kstack=0
		for i in range(n):
			subpath = newpath
			submodelname = subpath + '/' + model.split('.')[0] + '_prjs.hdf'
			if n > 1:
				if not options.onlyx and not options.onlyy and not options.onlyz:
					subpath = newpath + '/ptcl' + str(i).zfill(len(str(n)))
					os.system('mkdir ' + subpath)
					submodelname = subpath + '/' + model.split('.')[0] + '_ptcl' + str(i).zfill(len(str(n))) + '_prjs.hdf'
				else:
					if options.onlyx:
						submodelname = subpath + '/' + model.split('.hdf')[0] + '_Xprjs.hdf'
					if options.onlyy:
						submodelname = subpath + '/' + model.split('.hdf')[0] + '_Yprjs.hdf'
					if options.onlyz:
						submodelname = subpath + '/' + model.split('.hdf')[0] + '_Zprjs.hdf'
		
			submodel = EMData(model,i)
			if options.angles:
				angles = options.angles
				angles = angles.replace(',',' ')
				angles = angles.split()
				t=Transform({'type':'eman','az':float(angles[0]),'alt':float(angles[1]),'phi':float(angles[2])})
			
				submodel.transform(t)
			
			apix = submodel['apix_x']
			'''
			Pre-process/enhance subvolume if specified
			'''
			
			# Make the mask first, use it to normalize (optionally), then apply it 
			mask=EMData(submodel["nx"],submodel["ny"],submodel["nz"])
			mask.to_one()
			
			if options.mask:
				#print "This is the mask I will apply: mask.process_inplace(%s,%s)" %(options.mask[0],options.mask[1]) 
				mask.process_inplace(options.mask[0],options.mask[1])
			
			# normalize
			if options.normproc:
				if options.normproc[0]=="normalize.mask": 
					options.normproc[1]["mask"]=mask
				
				submodel.process_inplace(options.normproc[0],options.normproc[1])
			
			'''
			#Mask after normalizing with the mask you just made, which is just a box full of 1s if no mask is specified
			'''
			submodel.mult(mask)
			
			'''
			#If normalizing, it's best to do mask-normalize-mask
			'''
			if options.normproc:
				#if options["normproc"][0]=="normalize.mask": 
				#	options["normproc"][1]["mask"]=mask
				
				submodel.process_inplace(options.normproc[0],options.normproc[1])
			
				submodel.mult(mask)
			
			if options.lowpass:
				submodel.process_inplace(options.lowpass[0],options.lowpass[1])
			
			if options.shrink:
				submodel.process_inplace('math.meanshrink',{'n':options.shrink})
			
			kindividual=0
			for d in projectiondirections:	
				print "\nThis is the projection direction", d
				print "And this the corresponding transform",projectiondirections[d]		
				print "\n"
				prj = submodel.project("standard",projectiondirections[d])
				prj.set_attr('xform.projection',projectiondirections[d])
				prj['apix_x']=apix
				prj['apix_y']=apix
			
				#print "The size of the prj is", prj['nx']
			
				#prj.process_inplace('normalize')
				
				tag=''
				
				if options.angles:
					if options.tag:
						tag=options.tag
				
				if options.onlyx or options.onlyy or options.onlyz:
					if options.onlyx:
						tag ='onlyx'
					elif options.onlyy:
						tag ='onlyy'
					elif options.onlyz:
						tag ='onlyz'
					
					k = kstack
				
				else:
					k = kindividual
						
				prj.write_image(submodelname.replace('.hdf','_' + tag + '.hdf'),k)
				
				#print "Options.saverotvol is", options.saverotvol
				if options.saverotvol:
					submodel_rot = submodel.copy()
					submodel_rot.transform(projectiondirections[d])
					
					volname = submodelname.replace('_prjs.', '_vol' + d + '.')
					#print "I will save the rotated volume to this file", volname
					submodel_rot.write_image( volname , 0)
					
				kindividual+=1
				kstack+=1
			
	return()	
Beispiel #16
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] 
	This program aligns a paricle to its symmetry axis. There are two algorithmic modes. 
	A coarse search followed by simplex minimization (not yet implimented) OR monte carlo course 
	search followed by simplex minimization. The Goal is to align the paricle to its 
	symmetry axis so symmetry can be applied for avergaing and for alignment speed up 
	(it is only necessary to search over one asymmetric unit!
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_header(
        name="symsearch3dheader",
        help="""Options below this label are specific to e2symsearch3d""",
        title="### e2symsearch3d options ###",
        row=3,
        col=0,
        rowspan=1,
        colspan=2,
    )

    parser.add_argument(
        "--input",
        dest="input",
        default="",
        type=str,
        help="""The name of input volume or hdf stack of volumes""",
        guitype="filebox",
        browser="EMBrowserWidget(withmodal=True,multiselect=False)",
        row=0,
        col=0,
        rowspan=1,
        colspan=2,
    )

    # parser.add_argument("--output", dest="output", default="""e2symsearch3d_OUTPUT.hdf""", type=str, help="The name of the output volume", guitype='strbox', filecheck=False, row=1, col=0, rowspan=1, colspan=2)

    parser.add_argument(
        "--ref",
        type=str,
        default="",
        help="""Default=None. If provided and --average is also provided and --keep < 1.0 or --keepsig is specified, 'good particles' will be determined by correlation to --ref.""",
    )

    parser.add_argument(
        "--mirror",
        type=str,
        default="",
        help="""Axis across of which to generate a mirrored copy of --ref. All particles will be compared to it in addition to the unmirrored image in --ref if --keepsig is provided or if --keep < 1.0.""",
    )

    parser.add_argument(
        "--path",
        type=str,
        default="",
        help="""Name of path for output file""",
        guitype="strbox",
        row=2,
        col=0,
        rowspan=1,
        colspan=2,
    )

    parser.add_argument(
        "--plots",
        action="store_true",
        default=False,
        help="""Default=False. Turn this option on to generate a plot of the ccc scores if --average is supplied. Running on a cluster or via ssh remotely might not support plotting.""",
    )

    parser.add_argument(
        "--sym",
        dest="sym",
        default="c1",
        help="""Specify symmetry -choices are: c<n>, d<n>, h<n>, tet, oct, icos. For asymmetric reconstruction ommit this option or specify c1.""",
        guitype="symbox",
        row=4,
        col=0,
        rowspan=1,
        colspan=2,
    )

    parser.add_argument(
        "--shrink",
        dest="shrink",
        type=int,
        default=0,
        help="""Optionally shrink the input particles by an integer amount prior to computing similarity scores. For speed purposes. Default=0, no shrinking""",
        guitype="shrinkbox",
        row=5,
        col=0,
        rowspan=1,
        colspan=1,
    )

    parser.add_argument(
        "--mask",
        type=str,
        help="""Mask processor applied to particles before alignment. Default is mask.sharp:outer_radius=-2. IF using --clipali, make sure to express outer mask radii as negative pixels from the edge.""",
        returnNone=True,
        default="mask.sharp:outer_radius=-2",
        guitype="comboparambox",
        choicelist="re_filter_list(dump_processors_list(),'mask')",
        row=11,
        col=0,
        rowspan=1,
        colspan=3,
    )

    parser.add_argument(
        "--maskfile",
        type=str,
        default="",
        help="""Mask file (3D IMAGE) applied to particles before alignment. Must be in HDF format. Default is None.""",
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default="",
        help="""Normalization processor applied to particles before alignment. Default is to use normalize. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'""",
    )

    parser.add_argument(
        "--nopreprocprefft",
        action="store_true",
        default=False,
        help="""Turns off all preprocessing that happens only once before alignment (--normproc, --mask, --maskfile, --clipali, --threshold; i.e., all preprocessing excepting filters --highpass, --lowpass, --preprocess, and --shrink.""",
    )

    parser.add_argument(
        "--threshold",
        default="",
        type=str,
        help="""A threshold applied to the subvolumes after normalization. For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""",
        guitype="comboparambox",
        choicelist="re_filter_list(dump_processors_list(),'filter')",
        row=10,
        col=0,
        rowspan=1,
        colspan=3,
    )

    parser.add_argument(
        "--preprocess",
        default="",
        type=str,
        help="""Any processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype="comboparambox",
        choicelist="re_filter_list(dump_processors_list(),'filter')",
        row=10,
        col=0,
        rowspan=1,
        colspan=3,
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        default="",
        help="""A lowpass filtering processor (from e2proc3d.py; see e2help.py processors) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype="comboparambox",
        choicelist="re_filter_list(dump_processors_list(),'filter')",
        row=17,
        col=0,
        rowspan=1,
        colspan=3,
    )

    parser.add_argument(
        "--highpass",
        type=str,
        default="",
        help="""A highpass filtering processor (from e2proc3d.py, see e2help.py processors) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype="comboparambox",
        choicelist="re_filter_list(dump_processors_list(),'filter')",
        row=18,
        col=0,
        rowspan=1,
        colspan=3,
    )

    parser.add_argument(
        "--clipali",
        type=int,
        default=0,
        help="""Boxsize to clip particles as part of preprocessing to speed up alignment. For example, the boxsize of the particles might be 100 pixels, but the particles are only 50 pixels in diameter. Aliasing effects are not always as deleterious for all specimens, and sometimes 2x padding isn't necessary; still, there are some benefits from 'oversampling' the data during averaging; so you might still want an average of size 2x, but perhaps particles in a box of 1.5x are sufficiently good for alignment. In this case, you would supply --clipali=75""",
    )

    parser.add_argument(
        "--savepreproc",
        action="store_true",
        default=False,
        help="""Default=False. Will save stacks of preprocessed particles (one for coarse alignment and one for fine alignment if preprocessing options are different).""",
    )

    parser.add_argument(
        "--average",
        action="store_true",
        default=False,
        help="""Default=False. If supplied and a stack is provided through --input, the average of the aligned and/or symmetrized stack will also be saved.""",
    )

    parser.add_argument(
        "--averager",
        type=str,
        default="mean.tomo",
        help="""Default=mean.tomo. The type of averager used to produce the class average. Default=mean.tomo.""",
    )

    parser.add_argument(
        "--keep",
        type=float,
        default=1.0,
        help="""Fraction of particles to include if --average is on, after correlating the particles with the average.""",
    )

    parser.add_argument(
        "--keepsig",
        action="store_true",
        default=False,
        help="""Default=False. Causes theoptions.keep argument to be interpreted in standard deviations.""",
        guitype="boolbox",
        row=6,
        col=1,
        rowspan=1,
        colspan=1,
        mode="alignment,breaksym",
    )

    parser.add_argument(
        "--avgiter",
        type=int,
        default=1,
        help="""Default=1. If --keep is different from 1.0 and --average is on, the initial average will include all the particles, but then the percent specified byoptions.keep will be kept (the rest thrown away) and a new average will be computed. If --avgiter > 1, this new average will be compared again against all the particles. The procedure will be repeated for however many iterations --avgiter is given, or the process will stop automatically if in two consecutive rounds exactly the same particles are kept""",
    )

    parser.add_argument(
        "--subset",
        type=int,
        default=0,
        help="""Number of particles in a subset of particles from the --input stack of particles to run the alignments on.""",
    )

    parser.add_argument(
        "--steps",
        dest="steps",
        type=int,
        default=10,
        help="""Number of steps (for the MC). Default=10.""",
        guitype="intbox",
        row=5,
        col=1,
        rowspan=1,
        colspan=1,
    )

    parser.add_argument(
        "--symmetrize",
        default=False,
        action="store_true",
        help="""Symmetrize volume after alignment.""",
        guitype="boolbox",
        row=6,
        col=0,
        rowspan=1,
        colspan=1,
    )

    parser.add_argument(
        "--cmp",
        type=str,
        help="""The name of a 'cmp' to be used in comparing the symmtrized object to unsymmetrized""",
        default="ccc",
        guitype="comboparambox",
        choicelist="re_filter_list(dump_cmps_list(),'tomo', True)",
        row=7,
        col=0,
        rowspan=1,
        colspan=2,
    )

    parser.add_argument(
        "--parallel",
        "-P",
        type=str,
        help="""Run in parallel, specify type:<option>=<value>:<option>:<value>""",
        default=None,
        guitype="strbox",
        row=8,
        col=0,
        rowspan=1,
        colspan=2,
    )

    parser.add_argument(
        "--ppid", type=int, help="""Set the PID of the parent process, used for cross platform PPID.""", default=-1
    )

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help="""verbose level [0-9], higner number means higher level ofoptions.verboseness.""",
    )

    parser.add_argument(
        "--nopath",
        action="store_true",
        default=False,
        help="""If supplied, this option will save results in the directory where the command is run. A directory to store the results will not be made.""",
    )

    parser.add_argument(
        "--nolog",
        action="store_true",
        default=False,
        help="""If supplied, this option will prevent logging the command run in .eman2log.txt.""",
    )

    parser.add_argument(
        "--saveali", action="store_true", default=False, help="""Save the stack of aligned/symmetrized particles."""
    )

    parser.add_argument(
        "--savesteps",
        action="store_true",
        default=False,
        help="""If --avgiter > 1, save all intermediate averages and intermediate aligned kept stacks.""",
    )

    parser.add_argument(
        "--notmatchimgs",
        action="store_true",
        default=False,
        help="""Default=True. This option prevents applying filter.match.to to one image so that it matches the other's spectral profile during preprocessing for alignment purposes.""",
    )

    parser.add_argument(
        "--preavgproc1",
        type=str,
        default="",
        help="""Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)""",
    )

    parser.add_argument(
        "--preavgproc2",
        type=str,
        default="",
        help="""Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)""",
    )

    parser.add_argument(
        "--weighbytiltaxis",
        type=str,
        default="",
        help="""Default=None. A,B, where A is an integer number and B a decimal. A represents the location of the tilt axis in the tomogram in pixels (eg.g, for a 4096x4096xZ tomogram, this value should be 2048), and B is the weight of the particles furthest from the tomogram. For example, --weighbytiltaxis=2048,0.5 means that praticles at the tilt axis (with an x coordinate of 2048) will have a weight of 1.0 during averaging, while the distance in the x coordinates of particles not-on the tilt axis will be used to weigh their contribution to the average, with particles at the edge(0+radius or 4096-radius) weighing 0.5, as specified by the value provided for B.""",
    )

    parser.add_argument(
        "--weighbyscore",
        action="store_true",
        default=False,
        help="""Default=False. This option will weigh the contribution of each subtomogram to the average by score/bestscore.""",
    )

    parser.add_argument(
        "--align",
        type=str,
        default="symalignquat",
        help="""Default=symalignquat. WARNING: The aligner cannot be changed for this program currently. Option ignored.""",
    )

    parser.add_argument(
        "--tweak",
        action="store_true",
        default=False,
        help="""WARNING: Not used for anything yet. This will perform a final alignment with no downsampling [without using --shrink or --shrinkfine] if --shrinkfine > 1.""",
    )

    (options, args) = parser.parse_args()

    if not options.input:
        parser.print_help()
        sys.exit(0)

        # If no failures up until now, initialize logger
    log = 0
    if not options.nolog:
        logid = E2init(sys.argv, options.ppid)
        log = 1

        # inimodeldir = os.path.join(".",options.path)
        # if not os.access(inimodeldir, os.R_OK):
        # 	os.mkdir(options.path)

        # Make directory to save results
    from e2spt_classaverage import (
        sptmakepath,
        preprocessingprefft,
        Preprocprefft3DTask,
        get_results_preproc,
        preprocfilter,
        sptOptionsParser,
    )

    options = sptmakepath(options, "symsearch")

    if options.nopath:
        options.path = "."

    rootpath = os.getcwd()

    if rootpath not in options.path:
        options.path = rootpath + "/" + options.path

    if options.parallel:
        from EMAN2PAR import EMTaskCustomer

    options = sptOptionsParser(options)

    avgr = Averagers.get(options.averager[0], options.averager[1])
    resultsdict = {}
    scores = []

    outputstack = options.path + "/all_ptcls_ali.hdf"

    # Determine number of particles in the stack
    n = EMUtil.get_image_count(options.input)
    if options.subset and options.subset < n:
        n = options.subset

    options.raw = options.input

    if not options.nopreprocprefft:

        if options.mask or options.normproc or options.threshold or options.clipali:

            preprocprefftstack = options.path + "/" + os.path.basename(options.input).replace(".hdf", "_preproc.hdf")

            # save "dummy" images for preproc images
            for i in range(n):
                dimg = EMData(8, 8, 8)
                dimg.to_one()
                dimg.write_image(preprocprefftstack, i)

            originalsavepreproc = options.savepreproc

            options.savepreproc = True

            print "\n(e2spt_hac.py) (allvsall) Initializing parallelism for preprocessing"
            if options.parallel:  # Initialize parallelism if being used
                # from EMAN2PAR import EMTaskCustomer
                etc = EMTaskCustomer(options.parallel)
                pclist = [options.input]
                etc.precache(pclist)

            tasks = []
            results = []

            # preprocprefftstack = options.path + '/' + options.input.replace('.hdf','_preproc.hdf')

            for i in range(n):

                img = EMData(options.input, i)

                if options.parallel:
                    task = Preprocprefft3DTask(["cache", options.input, i], options, i, preprocprefftstack)
                    tasks.append(task)

                else:
                    pimg = preprocessingprefft(img, options)
                    pimg.write_image(preprocprefftstack, i)

            print "\nthere are these many tasks to send", len(tasks)
            if options.parallel and tasks:
                tids = etc.send_tasks(tasks)
                print "therefore these many tids", len(tids)

                if options.verbose:
                    print "%d preprocessing tasks queued" % (len(tids))

            results = get_results_preproc(etc, tids, options.verbose)

            print "results are", results

            options.input = preprocprefftstack

            options.savepreproc = originalsavepreproc

    for i in range(n):

        print "\nI'll look for symmetry in particle number", i
        # Load particle and make a copy to modify if preprocessing options are specified
        volume = EMData(options.input, i)
        preprocvol = volume.copy()

        # Preprocess volume if any preprocessing options are specified

        preprocprefftstack = options.path + "/" + os.path.basename(options.input).replace(".hdf", "_preproc.hdf")

        if (
            (options.shrink and options.shrink > 1)
            or options.lowpass
            or options.highpass
            or options.normproc
            or options.preprocess
            or options.threshold
            or options.clipali
        ):
            print "\nHowever, I will first preprocess particle number", i

            print "\nWill call preprocessing on ptcl", i
            preprocvol = preprocfilter(preprocvol, options, i)

            if options.savepreproc:
                preprocvol.write_image(preprocprefftstack, i)
                # preprocessing(s2image,options, ptclindx, savetagp ,'no',round)

            print "\nDone preprocessing on ptcl", i

        if options.parallel:
            etc = EMTaskCustomer(options.parallel)
        else:
            etc = EMTaskCustomer("thread:1")

        symalgorithm = SymALignStrategy(preprocvol, options.sym, options.steps, options.cmp, etc)
        ret = symalgorithm.execute()
        symxform = ret[0]
        score = ret[1]
        scores.append(score)

        resultsdict.update({score: [symxform, i]})

        print "\nWriting output for best alignment found for particle number", i

        if options.shrink and options.shrink > 1:
            trans = symxform.get_trans()
            symxform.set_trans(trans[0] * options.shrink, trans[1] * options.shrink, trans[2] * options.shrink)

        print "\nWrittng to output ptcl", i

        # Rotate volume to the best orientation found, set the orientation in the header, apply symmetry if specified and write out the aligned (and symmetrized) particle to the output stack
        output = volume.process("xform", {"transform": symxform})
        output.set_attr("symxform", symxform)
        print "\nApplying this transform to particle", symxform
        if options.symmetrize:
            output = output.process("xform.applysym", {"sym": options.sym})

        output["spt_score"] = score
        output.write_image(outputstack, -1)

        # Averaging here only makes sense if all particles are going to be kept. Otherwise, different code is needed (below)
        if options.average:
            avgr.add_image(output)

            # Finalize average of all particles if non were set to be excluded. Otherwise, determine the discrimination threshold and then average the particles that pass it.
    if options.average:

        final_avg = avgr.finish()

        final_avg["origin_x"] = 0
        final_avg["origin_y"] = 0  # The origin needs to be reset to ZERO to avoid display issues in Chimera
        final_avg["origin_z"] = 0
        final_avg["xform.align3d"] = Transform()

        if options.keep == 1.0 and not options.keepsig:
            final_avg.write_image(options.path + "/final_avg.hdf", 0)

            if options.avgiter > 1:
                print """WARNING: --avgiter > 1 must be accompanied by --keepsig, or by --keep < 1.0"""

        elif options.keep < 1.0 or options.keepsig:

            if options.ref:
                ref = EMData(options.ref, 0)
                refComp(options, outputstack, ref, resultsdict, "")

                if options.mirror:
                    ref.process_inplace("xform.mirror", {"axis": options.mirror})
                    refComp(options, outputstack, ref, results, "_vs_mirror")
            else:
                ref2compare = final_avg
                refComp(options, outputstack, final_avg, resultsdict, "")

        del final_avg

    if log:
        E2end(logid)

    return
Beispiel #17
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """UNDER DEVELOPOMENT. Extracts particles from each image in an aligned tilt 
		series based on A) their position in the reconstructed tomogram
		or B) their position in the 0 degrees tilt image of a tilt series."""

	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	'''
	Parameters for adding ctf and noise
	'''
	parser.add_argument('--tiltseries',type=str,default='',help="""File in .ali, .mrc or .hdf format of the aligned tiltseries.""")
		
	parser.add_argument('--tiltangles',type=str,default='',help="""File in .tlt or .txt format containing the tilt angle of each tilt image in the tiltseries.""")
		
	parser.add_argument('--coords3d',type=str,default='',help="""File in .txt format containing the coordinates of particles determined from the reconstructed tomogram of the supplied tiltseries.""")
	
	parser.add_argument('--coords2d',type=str,default='',help="""File in .txt format containing the coordinates of particles determined from the aligned 0 tilt image in the supplied tiltseries.""")
	
	parser.add_argument('--zerotiltindx',type=int,default=-1,help="""The default is the image at the middle of the stack. Since the stack might have more images to the left or the right of the actual 0-tilt (or lowest tilt) image, you can explicitly provide the index of the lowest tilt image here. This is used for tracking images.""")
	
	parser.add_argument('--centerzerotilt',action='store_true',default=False,help="""Default=False. If specified, this option will center the zerotilt (or least tilted image) for each particle by using as a reference a sharp-circle of radius=box/2 or the value specified through --radius.""")
	
	parser.add_argument('--excludeedge',type=float,default=0.0,help="""Integer number of pixels away from the edge of each image in the tilt series to not extract particles from. For example, if you specify 100, and the images are 4096x4096 pixels, any particle with its center lying between 0 and 200 or 3896 and 4096 will nto be extracted.""") 
	
	parser.add_argument('--cshrink', type=int, default=1, help="""Specifies the factor by which to multiply the coordinates in the coordinates file, so that they can be at the same scale as the tomogram. For example, provide 2 if the coordinates are on a 2K x 2K scale, but you want to extract the particles' subtiltseries from the UN-shrunk 4K x 4Ktiltseries.""")
	
	parser.add_argument('--tomogram',type=str,default='',help="""Path to raw, unbinned tomogram.""")
	
	parser.add_argument('--saveanglestacks',type=str,default='',help="""Default=None. Comma separated values of tilt angle indexes for which you want to save all particles as a stack. For example, if you want all particles from the 0 tilt image, you would provide the index for that image in the tilt series. In a tilt series with 61 images (1-61), the 0 tilt image is probably image number 31, so you would say --saveanglestakcs=31, and all the particles from the 0 tilt image would be put into a single HDF stack.""")

	parser.add_argument('--tiltaxislocation',type=int,default=-1,help="""By default, the tilt axis will be assumed to run through the middle of the tomogram in X, parallel to the Y axis. For example, if the dimensions of the tomogram are 4096x3000x500, the tilt axis will be assumed to be at X=2048. Provide a different integer number to change the location of the tilt axis (it will still be assumed to be parallel to Y though).""") 
	
	parser.add_argument('--tiltaxisptcls',type=int,default=-1,help="""Specifies the distance from the tilt axis to consider particles for extraction. By default, all particles will be extracted. However, if you provide, for example, --tiltaxisptls=10, only particles with centers -10 to 10 pixels away from the tilt axis will be extracted.""")
	
	parser.add_argument('--ntiltslow',type=int,default=0,help="""Default=0 (not used). If you supply an even number 1 will be added to it (for example, 4 will be turned into 5). If --ntiltslow>0, it specifies the number of tiltimages to keep in each subtiltseries, starting from the zero-tilt image and incorporating particles from right and left, one at a time. For example, in a tiltseries from -60 to 60 degress with a step size of 2 degrees, --ntiltslow=5 would keep tiltimages at angles 0,2,-2,-4,-4.""")
	
	parser.add_argument('--ntiltslowneg',type=int,default=0,help="""Default=0 (not used). If --ntiltslowneg>0, it specifies the number of tiltimages to keep in each subtiltseries, starting from the zero-tilt image and progressively incorporating particles from negatively tilted images only. For example, in a tiltseries from -60 to 60 degress with a step size of 2 degrees, --ntiltslowneg=5 would keep tiltimages at angles 0,-2,-4,-6,-8.""")

	parser.add_argument('--ntiltslowpos',type=int,default=0,help="""Default=0 (not used). If --ntiltslowpos>0, it specifies the number of tiltimages to keep in each subtiltseries, starting from the zero-tilt image and progressively incorporating particles from positively tilted images only. For example, in a tiltseries from -60 to 60 degress with a step size of 2 degrees, --ntiltslowpos=5 would keep tiltimages at angles 0,+2,+4,+6,+8.""")
	
	#parser.add_argument('--ntiltshighneg',type=int,default=0,help="""Default=0 (not used). If --ntiltshighneg>0, it specifies the number of tiltimages to keep in each subtiltseries, starting from the zero-tilt image and progressively incorporating particles from negatively tilted images only. For example, in a tiltseries from -60 to 60 degress with a step size of 2 degrees, --ntiltshighneg=5 would keep tiltimages at angles -60,-58,-56,-54,-52.""")

	#parser.add_argument('--ntiltshighpos',type=int,default=0,help="""Default=0 (not used). If --ntiltshighpos>0, it specifies the number of tiltimages to keep in each subtiltseries, starting from the zero-tilt image and progressively incorporating particles from positvely tilted images only. For example, in a tiltseries from -60 to 60 degress with a step size of 2 degrees, --ntiltshighpos=5 would keep tiltimages at angles  +60,+58,+56,+54,+52.""")
	
	parser.add_argument('--tomosides',type=str,default='',help="""Comma separated values for the tomogram dimensions. Alternatively, provide the path to the tomogram itself through --tomogram.""")
		
	parser.add_argument("--icethicknessauto",action='store_true',default=False,help="""Default=False. If supplied, the thickness of the tomogram in Z will be calculated by computing the difference between the largest and the smallest Z coordinate found in the --coords3d coordinates file.""")
	
	parser.add_argument("--zshift",type=str,default='half',help="""By default, the tomogram will be shifted -half the ice thickness so that the middle of the tomogram is at z=0. Provide a positive or negative integer to shift the z position by a different amount""")
	
	parser.add_argument("--radius",type=int,default=0,help="""Default=0 (not used). Radius of the particle in pixels. 2*radius will be added to the icethickness if --radius AND --icethicknessauto are supplied.""") 
	
	parser.add_argument("--invertangles",action='store_true',default=False,help="""Default=False. If True, this will multiple all angles by -1, in case the directionality is messed up.""")
	
	parser.add_argument('--path',type=str,default='spt_subtilt',help="""Directory to save the results.""")
	
	parser.add_argument('--boxsize',type=int,default=128,help="""Size of the 2D "tiles" or images for each particle from each image in the tiltseries.""")
	
	parser.add_argument('--apix',type=float,default=0.0,help="""If provided, this value will be used for apix instead of the one read from the header of --tiltseries""")
		
	parser.add_argument("--ppid", type=int, help="""Set the PID of the parent process, used for cross platform PPID""",default=-1)
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	
	parser.add_argument('--subset', type=int, default=0, help='''Specify how many sub-tiltseries (or particles) from the coordinates file you want to extract; e.g, if you specify 10, the first 10 particles will be boxed.\n0 means "box them all" because it makes no sense to box none''')
	
	#parser.add_argument('--tomogramthickness',type=int,default=None,help='Z dimension of the reconstructed tomogram.')
		
	#parser.add_argument("--everyother", type=int, help="""Pick every other tilt. For example, --tilt=3 would pick every third tilt only.""",default=-1)

	parser.add_argument("--subtractbackground",action='store_true',default=False,help="""(Experimental. Not working yet). This will extract a box from the tomogram much larger than the subtomogram. Projections will be generated. You MUST provide --tomogram for this.""")

	parser.add_argument("--normproc",type=str,default='',help="""WARNING: Not used anywhere yet. Default=None""")
	
	#parser.add_argument("--yshort",action='store_true',help="""Not used anywhere yet. Default=False""", default=False)
	
	parser.add_argument("--shrink", type=int,default=1,help="""Default=1 (no shrinking). Integer shrinking factor, part of preprocessing to facilitate particle tracking.""")
	
	parser.add_argument("--lowpass", type=str,default='',help="""Default=None. Requires --track. Low pass filtering processor (see e2help.py processors at the command line), part of preprocessing to facilitate particle tracking.""")

	parser.add_argument("--highpass", type=str,default='',help="""Default=None (no highpass). High pass filtering processor (see e2help.py processors at the command line), part of preprocessing to facilitate particle tracking.""")
	
	parser.add_argument("--mask", type=str,default='',help="""Default=None. Requires --track. Masking processor (see e2help.py processors at the command line), part of preprocessing to facilitate particle tracking.""")

	parser.add_argument("--threshold", type=str,default='',help="""Default=None (no threshold). Requires --track. Thresholding processor (see e2help.py processors at the command line), part of preprocessing to facilitate particle tracking.""")

	parser.add_argument("--preprocess", type=str,default='',help="""Default=None (no additional preprocessing). Requires --track. Any additional preprocessing processor (see e2help.py processors at the command line), part of preprocessing to facilitate particle tracking.""")
	
	parser.add_argument("--track",action='store_true',default=False,help="""Default=False (not used). If supplied, this option will track particles from one tilt image to another.""")
	
	parser.add_argument("--trackytoo",action='store_true',default=False,help="""Default=False (not used). In theory, particles should not drift in Y with tilt angle. Still, this option can turn Y tracking on.""")

	
	(options, args) = parser.parse_args()
	
	if options.ntiltslow:
		if options.ntiltslowneg:
			print "ERROR: Cannot specify --ntiltslow and --ntiltslowneg at the same time"
			sys.exit()
		if options.ntiltslowpos:
			print "ERROR: Cannot specify --ntiltslow and --ntiltslowpos at the same time"
			sys.exit()
		
	if options.ntiltslowneg:
		if options.ntiltslow:
			print "ERROR: Cannot specify --ntiltslowneg and --ntiltslow at the same time"
			sys.exit()
		if options.ntiltslowpos:
			print "ERROR: Cannot specify --ntiltslowneg and --ntiltslowpos at the same time"
			sys.exit()
	
	if options.ntiltslowpos:
		if options.ntiltslow:
			print "ERROR: Cannot specify --ntiltslowpos and --ntiltslow at the same time"
			sys.exit()
		if options.ntiltslowneg:
			print "ERROR: Cannot specify --ntiltslowpos and --ntiltslowneg at the same time"
			sys.exit()
		
		
	print "\nI've read the options"	
	
	'''
	Check that all needed parameters are properly supplied
	'''
	if not options.tiltseries:  
		print "ERROR: You must provide --tiltseries."
		sys.exit()
	
	if not options.tiltangles:
		print "ERROR: You must provide --tiltangles."
		sys.exit()
	
	if not options.coords2d and not options.coords3d:
		print "ERROR: You must provide EITHER --coords2d OR --coords3d." 
		sys.exit()
	
	if options.coords2d and options.coords3d:
		print "ERROR: You must provide EITHER --coords2d OR --coords3d, not both." 
		sys.exit()
	
	if not options.tomogram and not options.tomosides:
		print "ERROR: You must provide EITHER --tomogram OR --tomosides." 
		sys.exit()
		
	if options.tomogram and options.tomosides:
		print "ERROR: You must provide EITHER --tomogram OR --tomosides, not both." 
		sys.exit()
	
	'''
	Parse tilt angles from file supplied via --tiltangles
	'''
	anglesfile = open(options.tiltangles,'r')				#Open tilt angles file
	alines = anglesfile.readlines()							#Read its lines
	anglesfile.close()										#Close the file
	
	#tiltangles = [ alines[i].replace('\n','') for i in range(len(alines)) ]	#Eliminate trailing return character, '\n', for each line in the tiltangles file
	
	tiltanglesfloatabs = []
	for line in alines:
		print "line is", line
		ang = math.fabs( float( line.replace('\n','') ) )
		print "ang is", ang
		tiltanglesfloatabs.append( ang )
	#tiltanglesfloatabs = [ math.fabs( float( alines[i].replace('\n','') ) ) for i in range(len(alines)) ]

	tiltanglesfloat = [ float( alines[i].replace('\n','') ) for i in range(len(alines)) ]
	
	#if options.invertangles:
	#	tiltanglesfloat = [ -1*float( alines[i].replace('\n','') ) for i in range(len(alines)) ]
	#	print "INVERTED tiltanglesfloat", tiltanglesfloat
	#else:
	print "tiltanglesfloat", tiltanglesfloat

		
	
	#tiltanglesfloat.sort()
	
	#print "sorted tiltangles",tiltanglesfloat
	
	ntiltangles = len( tiltanglesfloat )
	
	'''
	Check that there are as many images in --tiltseries as angles in --tiltangles
	'''
	serieshdr = EMData(options.tiltseries,0,True)
	nslices = serieshdr['nz']
	
	if int( nslices ) != int( ntiltangles ):
		print """ERROR: The tiltangles file doesn't seem to correspond to the tiltseries provided.
				The number of images in --tiltseries (z dimension of MRC stack) must be equal to the number
				of lines in --tiltangles."""
		sys.exit()
	
	'''
	Get apix
	'''
	nx = serieshdr['nx']
	ny = serieshdr['ny']
	apix = serieshdr['apix_x']
	if options.apix:
		apix=options.apix
	
	'''
	If error free up to this point, make path to store results
	'''
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'sptSubtilt')
	
	'''
	Start logging this run of the program at this point
	'''
	logger = E2init(sys.argv, options.ppid)
	
	
	#"""
	#(CRAZY)
	#You do not need to keep track of the mathematics of tilting and rotating and find the correspondence between
	#the tomogram and each image in the tilt series.
	#Instead, let's make a simple 3D model, containing a bright dot at the position of each particle.
	#Then, rotate that using the known tilt angles, generate a projection for each, and find the dots (maxima) in each.
	#Use the location of these maxima, to extract each particle from each image in the tilt series.
	#Would fail if they overlap though
	#"""
	
	tomox=tomoy=tomoz=0
	if options.tomosides:							#Read tomogram dimensions.
		sides=options.tomosides.split(',')
		tomox = int(sides[0])
		tomoy = int(sides[1])
		tomoz = int(sides[2])
	
	elif options.tomogram:
		tomohdr = EMData(options.tomogram,0,True)	#Read tomogram dimensions from tomogram header, if the tomogram is provided.
		tomox = int(tomohdr['nx'])
		tomoy = int(tomohdr['ny'])
		tomoz = int(tomohdr['nz'])

	icethickness = tomoz
	
	#if float( options.shrink ) > 1.0:								#The 'MODEL' to build for the coordinates need not use the full size of the tomogram.
	#	tomox = int(tomox)/options.shrink
	#	tomoy = int(tomoy)/options.shrink
	#	tomoz = int(tomoz)/options.shrink
	
	#tomovol = EMData(tomox,tomoy,tomoz)			#Create empty volume for the MODEL to build
	#tomovol.to_zero()								#Make sure it's empty
	
	clines=[]
	if options.coords2d:
		cfile = open(options.coords2d,'r')				
		clines = cfile.readlines()						
		cfile.close()									
	
	elif options.coords3d:
		cfile = open(options.coords3d,'r')				
		clines = cfile.readlines()						
		cfile.close()									
		
	
	'''
	Clean the coordinate file lines (clines) if there's garbage in them.
	Some people might manually make ABERRANT coordinates files with commas, tabs, or more 
	than one space in between coordinates. Then, parse each clean line.
	'''
	ppp = 0	
	cleanlines=[]
	zs = []
	
	for line in clines:
		
		if options.subset:
			if int( ppp ) >= (options.subset):
				break
			
		line =line.replace(", ",' ')	
		line = line.replace(",",' ')
		line = line.replace("x",'')
		line = line.replace("y",'')
		line = line.replace("z",'')
		line = line.replace("=",'')
		line = line.replace("_",' ')
		line = line.replace("\n",'')
		line = line.replace("\t",' ')
		line = line.replace("  ",' ')
		
		finallineelements=line.split(' ')
		
		if options.coords3d:
			if line and len(finallineelements) == 3:
				cleanlines.append(line)
				zs.append( int( line.split()[-1] ))		
				ppp += 1
			else:
				print "\nBad line removed", line
	
		elif options.coords2d:
			if line and len(finallineelements) == 2:
				cleanlines.append(line)
				ppp += 1
			else:
				print "\nBad line removed", line
	
	print "icethicknessauto before if is", options.icethicknessauto
	if zs and options.icethicknessauto and not options.tomogram and not options.tomosides:
		print "icethicknessauto after if is", options.icethicknessauto
	
		icethicknessfile = options.path + '/icethickness_estimate.txt'
	
		itf = open( icethicknessfile, 'w' )
	
		autoIcethickness = max( zs ) -  min( zs )
	
		autoIceLine = 'max(z) - min(z) = ' + str( autoIcethickness ) + ' pixels '
	
		autoIcethicknessUnshrunk = autoIcethickness
		if options.cshrink and options.cshrink > 1:
			autoIcethicknessUnshrunk = autoIcethickness * options.cshrink
			autoIceLine += ' , unshrunk = ' + str( autoIcethicknessUnshrunk ) + ' pixels'
	
		icethickness = autoIcethicknessUnshrunk
		print "\nIce thickness has been estimated from z coordinates to be", icethickness
	
		autoIcethicknessInApix = autoIcethicknessUnshrunk*apix
		autoIceLine += ' , ' + str( autoIcethicknessInApix ) + ' angstroms'
		
		itf.write( autoIceLine )
	
		itf.close()		
	
	'''
	Iterate over the correct number of viable lines from the coordinates file.
	'''
	
	nptcls = len(cleanlines)
	if int( options.subset ) > 0:
		if int( options.subset ) > len(cleanlines):
			print """WARNING: The total amount of lines in the coordinates files is LESS 
				than the --subset of particles to box you specified; therefore, ALL particles 
				will be extracted."""
		else:
			nptcls = int(options.subset)
			print "\nThe SUBSET of particles to work with is", nptcls
	else:
		print """\nBased on the number of coordinates, the size of the ENTIRE SET of 
			subtiltseries to extract is""", nptcls
	
	#print "There are these many clean lines", len(cleanlines)
	#print "Clean lines are", cleanlines
	
	#everyotherfactor = 1
	#if options.everyother > 1:
	#	everyotherfactor = options.everyother
	
	
	maxtilt=0
	
	
	if options.subtractbackground:
		maxtilt = max( tiltanglesfloat )
		print "\n(e2spt_subtilt.py) maxtilt is", maxtilt
		
		from e2spt_boxer import unbinned_extractor
		
		bgboxsize = (2 * options.boxsize / math.cos( math.radians(maxtilt+5)  )) + 10
		invert=0
		center=0
	
	
	
	
	tiltaxisloc = tomox/2.0 
	if options.tiltaxislocation > -1:
		tiltaxisloc = options.tiltaxislocation/2.0 
	
	xclowerthresh = 0
	xcupperthresh = tomox
	
	if options.radius and options.tiltaxisptcls == -1:
		xclowerthresh = options.radius
		xcupperthresh = tomox - options.radius
	
	if options.tiltaxisptcls > -1:
		xclowerthresh = tiltaxisloc - options.tiltaxisptcls
		xcupperthresh = tiltaxisloc + options.tiltaxisptcls
	
	
	'''
	Divide the tiltangles into negative and positive ranges since iterations will progress
	from the 0 tilt angle and then gradually 1 to the left, 1 to the right, etc, etc.
	Figure out which side has the most angles too.
	'''
	nimgsOriginal = EMData( options.tiltseries, 0, True )['nz']
	middleIndx = nimgsOriginal/2
	
	absangles = []	#absolute value of all angles
	
	for ang in tiltanglesfloat:
		
		absangles.append( math.fabs( ang ) )
	
	zerotiltangleabs = min( absangles )
	zerotiltindx = absangles.index( zerotiltangleabs )
	zerotiltangle = tiltanglesfloat[ zerotiltindx ]
	
	print "\nBy middle tilt series index, and by smallest tilt angle index, zerotilt is at", middleIndx, zerotiltindx
	print "And zerotiltangle is", zerotiltangle
	
	
	anglesBelowZeroTilt = []
	anglesAboveZeroTilt = []

	for ang in tiltanglesfloat:
		#print "\nAngle is", ang
		if float(ang) < float(zerotiltangle):
			#if not options.invertangles:
			anglesBelowZeroTilt.append( float(ang) )
			#else:
			#	anglesAboveZeroTilt.append( -1*float(ang) )
				
			#print "Therefore it was added to the below group"
		elif float(ang) > float(zerotiltangle):
			#if not options.invertangles:
			anglesAboveZeroTilt.append( float(ang) )
			#else:
			#	anglesBelowZeroTilt.append( -1*float(ang) )
			#print "Therefore it was added to the above group"
	
	nLangles = len( anglesBelowZeroTilt )
	nUangles = len( anglesAboveZeroTilt )
	mostangles = max( nLangles, nUangles )
	
	#if not options.invertangles:
	print "anglesBelowZeroTilt", anglesBelowZeroTilt
	print "anglesAboveZeroTilt", anglesAboveZeroTilt
	#else:
	#print "INVERTED anglesBelowZeroTilt", anglesBelowZeroTilt
	#print "INVERTED anglesAboveZeroTilt", anglesAboveZeroTilt
	#print "nLangles and nUangles are", nLangles, nUangles
	#sys.exit()
	anglestackslist = options.saveanglestacks.split(',')


	ptclNum3D = ptclNum = 0
	
	if options.ntiltslow:				#To pick a symmetric number of tilt images, left and right of the middle tilt?
		if not options.ntiltslow %2:
			options.ntiltslow += 1
	
	for line in cleanlines:
		line = line.split()	
		
		print "\n\n\n\n\n+=================+\nAnalyzing particle number\n+=================+\n", ptclNum3D
		xc = 0
		yc = 0
		zc = 0
		if len(line) == 3:
			xc = float(line[0])				#Determine x y z coordinates for each line
			yc = float(line[1])
			zc = float(line[2])	
		elif len(line) == 2:
			xc = float(line[0])				#Determine x y coordinates for each line, and default zc to 0 if --coords2d supplied instead of coords3d
			yc = float(line[1])
			zc = 0
		else:	
			print "\nThere's still an aberrant line in your coordinates file, see", line
			sys.exit()
		
		if options.verbose:
			print "\nRead these coordinates", xc,yc,zc
	
		if options.cshrink:
			xc*=options.cshrink
			yc*=options.cshrink
			zc*=options.cshrink
			
			if options.verbose:
				print "\nThe real coordinates after multiplying cshrink are", xc, yc, zc
		
		print "Before entering algorithm, xc, yc, zc are", xc,yc,zc
		print "Both conditions xc > lowerth and xc < upperth together are", int(xc) > int( xclowerthresh ) and int(xc) < int( xcupperthresh )
		
		if int(xc) > int( xclowerthresh ) and int(xc) < int( xcupperthresh ):
		
			
		
			#outIndx=0
			#ret=0
			wholebox=0
			
			
			'''
			The middle or zero-tilt or lowest-tilt image will serve to align all the rest if --track is on.
			If --centerzerotilt is on, find it, extract it, recenter it using autocentering based on mirror images, and reextract.
			'''
			
			retm = extract2D( options, zerotiltangle, icethickness, tomox, xc, yc, zc, 0, 0, zerotiltindx )
			middleslice = retm[0]
			
			if options.coords3d:
				sptcoords = ( xc, yc, zc )
				middleslice['ptcl_source_coord']=sptcoords

			cumulativeLdx = cumulativeLdy = cumulativeUdx = cumulativeUdy = 0	
			
			ptclfile = options.path + '/subtiltPtcl_' + str(ptclNum).zfill( len( str( len (cleanlines)))) + '.hdf'
				
			print "Found least tilted image at index and angle ", zerotiltindx, zerotiltangle
			
			'''
			print "Autocentering it"
			
			midslicemirrorX = middleslice.process('xform.mirror',{'axis':'x'})
			midslicemirrorY = middleslice.process('xform.mirror',{'axis':'y'})
			
			
			
			ccfpmx = middleslice.calc_ccf( midslicemirrorX )
			ccfpmy = middleslice.calc_ccf( midslicemirrorY )

			ccfpmxC = ccfpmx.process('xform.phaseorigin.tocorner')
			ccfpmyC = ccfpmy.process('xform.phaseorigin.tocorner')

			maxccfpmxC = ccfpmxC.calc_max_location()
			maxccfpmyC = ccfpmyC.calc_max_location()
			
			
			
			midsxt = -1 * ( middleslice['nx'] /2.0 - maxccfpmxC[0])/ 2.0
			midsyt = -1 * ( middleslice['ny'] /2.0 - maxccfpmyC[1])/ 2.0
			
			print "Autocentering translations for tilt 0 are", midsxt, midsyt
			retm2 = extract2D( options, zerotiltangle, icethickness, tomox, xc, yc, zc, midsxt, midsyt, zerotiltindx )
			
			middleslice = retm2[0]
			'''
			
			midscoordx = xc
			midscoordy = yc
			
			if options.centerzerotilt:					
				box = middleslice['nx']
				radius = box / 4.0
				
				if options.radius:
					radius = options.radius
				else:
					print """WARNING: --centerzerotilt requires --radius. Since the latter wasn't provided, it will be assumed to be 1/4 of the --boxsize"""
					
				template = EMData( box, box )
				template.to_one()
				template.process_inplace('mask.sharp',{'outer_radius':radius})
				template.mult(-1)
			
				if options.lowpass or options.highpass or options.mask or options.shrink or options.preprocess or options.threshold:
					middleslice = preprocImg( middleslice, options )
			
				ccft = middleslice.calc_ccf( template )
				ccftC = ccft.process('xform.phaseorigin.tocorner')
				maxccftC = ccftC.calc_max_location()
			
				midsxt = -1 * ( middleslice['nx'] /2.0 - maxccftC[0])			
				midsyt = -1 * ( middleslice['nx'] /2.0 - maxccftC[1])
				print "Autocentering translations for tilt 0 are", midsxt, midsyt
				#cumulativeLdx += midsxt
				#cumulativeLdy += midsyt
			
				retm2 = extract2D( options, zerotiltangle, icethickness, tomox, xc, yc, zc, midsxt, midsyt, zerotiltindx )
			
				middleslice = retm2[0]
				midscoordx = retm2[1]
				midscoordy = retm2[2]
				
				if options.coords3d:
					sptcoords = ( midscoordx, midscoordy, zc )
					middleslice['ptcl_source_coord']=sptcoords
			
			
			#middleslice.process_inplace('normalize')
			
			middleslice['spt_tiltangle'] = zerotiltangle
			middleslice['spt_tiltaxis'] = 'y'
			middleslice['spt_subtilt_x'] = midscoordx
			middleslice['spt_subtilt_y'] = midscoordy
			middleslice['origin_x'] = middleslice['nx']/2.0
			middleslice['origin_y'] = middleslice['ny']/2.0
			middleslice['origin_z'] = 0

			middleslice['apix_x'] = apix
			middleslice['apix_y'] = apix
			middleslice['apix_z'] = apix
			
			
				
			middleslice.write_image( ptclfile, 0 )
			
			if str(zerotiltindx) in anglestackslist and options.saveanglestacks:	
				zeroanglestackname = options.path + '/anglestack_' + str(zerotiltindx) + '_angle' + str(int(zerotiltangle)) + '.hdf' 
				middleslice.write_image( zeroanglestackname, -1 )
			
			
			print "Iteration over all tilt angles (other than the least tilted one) starting now."
			
			refL = middleslice.copy()
			refU = middleslice.copy()
			
			print "mostangles is", mostangles
			print "nLangles is", nLangles
			print "nUangles is", nUangles
			print "tiltanglesfloat are", tiltanglesfloat
			
			
			leftanglesN = len( tiltanglesfloat[ 0: zerotiltindx ] )
			
			rightanglesN = len( tiltanglesfloat[ zerotiltindx: -1 ] )
			
			for k in range( mostangles ):
				
				if options.ntiltslow:
					if k == options.ntiltslow:
						break
				
				elif options.ntiltslowneg:
					if k == options.ntiltslowneg:
						break
				
				elif options.ntiltslowpos:
					if k == options.ntiltslowpos:
						break
				
				if k < leftanglesN and not options.ntiltslowpos: # and zerotiltindx - (k+1) > -1:
					#print "\n k and nLangles are", k, nLangles
					lowerindx = zerotiltindx - (k+1)
					
					#if not options.negativetiltseries:
					#	lowerindx = zerotiltindx + (k+1)
						
					
					#if options.ntiltslow:
					#	lowerindx = zerotiltindx - (k+1) - zerotiltiltidx
					
					lowerangle = tiltanglesfloat[ lowerindx ]
					
					#if options.invertangles:
					#	lowerangle *= -1
					#	print "stacking INVERTED lowerangle", lowerangle
					
					print "stacking angle %f from the LEFT of lowest tiltangle in the angles list" %( lowerangle )
					print "found at lowerindx", lowerindx
					
					retL = write2D( options, lowerangle, icethickness, tomox, tomoy, xc, yc, zc, cumulativeLdx, cumulativeLdy, refL, apix, 'lower', ptclfile, maxtilt, lowerindx )
					
					if retL:
						refL = retL[0]
						cumulativeLdx = retL[1]
						cumulativeLdy = retL[2]
				
						if str(lowerindx) in anglestackslist and options.saveanglestacks:	
							anglestackname = options.path + '/anglestack_' + str(lowerindx) + '_angle' + str(int(lowerangle)) + '.hdf' 
							
							
							
							
							#middleslice['spt_tiltangle'] = zerotiltangle
							#middleslice['spt_tiltaxis'] = 'y'
							#middleslice['spt_subtilt_x'] = midscoordx
							#middleslice['spt_subtilt_y'] = midscoordy
							#middleslice['origin_x'] = middleslice['nx']/2.0
							#middleslice['origin_y'] = middleslice['ny']/2.0
							#middleslice['origin_z'] = 0

							#middleslice['apix_x'] = apix
							#middleslice['apix_y'] = apix
							#middleslice['apix_z'] = apix
							
							
							
							refL.write_image( anglestackname, -1 )
				
				if k < rightanglesN and not options.ntiltslowneg:
					#print "\n k and nUangles are", k, nUangles
					upperindx = zerotiltindx + (k+1)
					#if not options.negativetiltseries:
					#	upperindx = zerotiltindx - (k+1)
					
					upperangle = tiltanglesfloat[ upperindx ]
					
					#if options.invertangles:
					#	upperangle *= -1
					#	print "stacking INVERTED upperangle", upperangle
						
					print "stacking angle %f from the RIGHT lowest tiltangle in the angles list" %( upperangle )
					print "found at upperindx", upperindx
					retU = write2D( options, upperangle, icethickness, tomox, tomoy, xc, yc, zc, cumulativeUdx, cumulativeUdy, refU, apix, 'upper', ptclfile, maxtilt, upperindx )
					if retU:
						refU = retU[0]
						cumulativeUdx = retU[1]
						cumulativeUdy = retU[2]
				
						if str(upperindx) in anglestackslist and options.saveanglestacks:	
							anglestackname = options.path + '/anglestack_' + str(upperindx) + '_angle' + str(int(upperangle)) + '.hdf' 
							refU.write_image( anglestackname, -1 )
				
			
			ptclNum += 1	
			
		else:
			print "Particle skipped because it's center in X, xc=%d, is outside the lower and upper boundaries to consider [%d,%d]; i.e., too far away from the tilt axis" % ( xc, xclowerthresh, xcupperthresh ) 
			print "First condition, xc > lowerthresh", int(xc) > int( xclowerthresh )
			print "First condition, xc < upperthresh", int(xc) < int( xcupperthresh )
		
			print "Both conditions", int(xc) > int( xclowerthresh ) and int(xc) < int( xcupperthresh )
			print "IF all true you shouldn't be reading this message!"
		
		
		
		ptclNum3D += 1
	
	E2end(logger)
	
	return
Beispiel #18
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog <output> [options]
	Program to build an initial subtomogram average by averaging pairs from the largest subset
	in --input that is a power of 2. For example, if you supply an input stack with 100 subtomograms,
	this program will build an initial reference using 64, since 64 is the largest power of 2 contained in 100.
	In the first iteration, particle 1 will be averaged with 2, 3 with 4, 5 with 6... etc.
	32 new averages (each an average of 2 subtomograms) will be used for the second iteration.
	Again, 1 will be averaged with 2, 3 with 4, etc... yielding 16 new averages.
	The algorithm continues until the entire subset (64) has been merged into 1 average.
	
	This program depends on e2spt_classaverage.py because it imports the preprocessing 
	and alignment functions from it.
	
	--mask=mask.sharp:outer_radius=<safe radius>
	--preprocess=filter.lowpass.gauss:cutoff_freq=<1/resolution in A>
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_header(name="sptbtheader",
                      help="""Options below this label are specific to 
		sptbinarytree""",
                      title="### sptbinarytree options ###",
                      row=6,
                      col=0,
                      rowspan=1,
                      colspan=3,
                      mode="align")

    parser.add_header(
        name="caheader",
        help="""Options below this label are specific to sptclassaverage""",
        title="### sptclassaverage options ###",
        row=3,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--path",
        type=str,
        default='spt',
        help=
        """Default=spt. Directory to store results in. The default is a numbered series of directories containing the prefix 'spt'; for example, spt_02 will be the directory by default if 'spt_01' already exists."""
    )

    parser.add_argument(
        "--input",
        type=str,
        default='',
        help=
        """Default=None. The name of the input volume stack. MUST be HDF since volume stack support is required.""",
        guitype='filebox',
        browser='EMSubTomosTable(withmodal=True,multiselect=False)',
        row=0,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--output",
        type=str,
        default='avg.hdf',
        help=
        """Default=avg.hdf. The name of the output class-average stack. MUST be HDF since volume stack support is required.""",
        guitype='strbox',
        row=2,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    #parser.add_argument("--classmx", type=str, default='', help="""Default=None. The name of the classification matrix specifying how particles in 'input' should be grouped. If omitted, all particles will be averaged.""")

    #parser.add_argument("--ref", type=str, default='', help="""Default=None. Reference image(s). Used as an initial alignment reference and for final orientation adjustment if present. This is typically the projections that were used for classification.""", guitype='filebox', browser='EMBrowserWidget(withmodal=True,multiselect=True)', filecheck=False, row=1, col=0, rowspan=1, colspan=3, mode='alignment')

    #parser.add_argument("--refpreprocess",action="store_true",default=False,help="""Default=False. This will preprocess the reference identically to the particles. It is off by default, but it is internally turned on when no reference is supplied.""")

    #parser.add_argument("--resultmx",type=str,default=None,help="""Default=Npone. Specify an output image to store the result matrix. This is in the same format as the classification matrix. http://blake.bcm.edu/emanwiki/EMAN2/ClassmxFiles""")

    #parser.add_argument("--refinemultireftag", type=str, default='', help="""Default=''. DO NOT USE THIS PARAMETER. It is passed on from e2spt_refinemulti.py if needed.""")

    parser.add_argument(
        "--radius",
        type=float,
        default=0,
        help=
        """Default=0 (which means it's not used by default). Hydrodynamic radius of the particle in Angstroms. This will be used to automatically calculate the angular steps to use in search of the best alignment. Make sure the apix is correct on the particles' headers, sine the radius will be converted from Angstroms to pixels. Then, the fine angular step is equal to 360/(2*pi*radius), and the coarse angular step 4 times that."""
    )

    parser.add_argument(
        "--precision",
        type=float,
        default=1.0,
        help=
        """Default=1.0. Precision in pixels to use when figuring out alignment parameters automatically using --radius. Precision would be the number of pixels that the the edge of the specimen is moved (rotationally) during the finest sampling, --falign. If precision is 1, then the precision of alignment will be that of the sampling (apix of your images) times the --shrinkfine factor specified."""
    )

    parser.add_argument(
        "--search",
        type=int,
        default=8,
        help=
        """"Default=8. During COARSE alignment translational search in X, Y and Z, in pixels. Default=8. This WILL overwrite any search: provided through --align, EXCEPT if you provide --search=8, which is the default. In general, just avoid providing search twice (through here and through the aligner, --align). If you do, just be careful to make them consistent to minimize misinterpretation and error."""
    )

    parser.add_argument(
        "--searchfine",
        type=int,
        default=2,
        help=
        """"Default=2. During FINE alignment translational search in X, Y and Z, in pixels. Default=2. This WILL overwrite any search: provided through --falign, EXCEPT if you provide --searchfine=2, which is the default. In general, just avoid providing search twice (through here and through the fine aligner --falign). If you do, just be careful to make them consistent to minimize misinterpretation and error."""
    )

    #parser.add_argument("--donotaverage",action="store_true", help="""If e2spt_refinemulti.py is calling e2spt_classaverage.py, the latter need not average any particles, but rather only yield the alignment results.""", default=False)

    parser.add_argument(
        "--iterstop",
        type=int,
        default=0,
        help=
        """Default=0. (Not used). The program is called to convergence by default (all particles merge into one final average). To stop at an intermediate iteration, provide this parameter. For example, --iterstop=1, will only allow the algorithm to complete 1 iteration; --iterstop=2 will allow it to go through 2, etc."""
    )

    parser.add_argument(
        "--savesteps",
        action="store_true",
        default=False,
        help=
        """Default=False. If set, will save the average after each iteration to class_#.hdf. Each class in a separate file. Appends to existing files.""",
        guitype='boolbox',
        row=4,
        col=0,
        rowspan=1,
        colspan=1,
        mode='alignment,breaksym')

    parser.add_argument(
        "--saveali",
        action="store_true",
        default=False,
        help=
        """Default=False. If set, will save the aligned particle volumes in class_ptcl.hdf. Overwrites existing file.""",
        guitype='boolbox',
        row=4,
        col=1,
        rowspan=1,
        colspan=1,
        mode='alignment,breaksym')

    parser.add_argument(
        "--saveallalign",
        action="store_true",
        default=False,
        help=
        """Default=False. If set, will save the alignment parameters after each iteration""",
        guitype='boolbox',
        row=4,
        col=2,
        rowspan=1,
        colspan=1,
        mode='alignment,breaksym')

    parser.add_argument(
        "--sym",
        dest="sym",
        default='',
        help=
        """Default=None (equivalent to c1). Symmetry to impose -choices are: c<n>, d<n>, h<n>, tet, oct, icos""",
        guitype='symbox',
        row=9,
        col=1,
        rowspan=1,
        colspan=2,
        mode='alignment,breaksym')

    parser.add_argument(
        "--mask",
        type=str,
        default="mask.sharp:outer_radius=-2",
        help=
        """Default is mask.sharp:outer_radius=-2. Masking processor applied to particles before alignment. IF using --clipali, make sure to express outer mask radii as negative pixels from the edge.""",
        returnNone=True,
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'mask\')',
        row=11,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--maskfile",
        type=str,
        default='',
        help=
        """Default=None. Mask file (3D IMAGE) applied to particles before alignment. Must be in HDF format. Default is None."""
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default='normalize.edgemean',
        help=
        """Default is 'normalize.edgemean' (see 'e2help.py processors -v 10' at the command line). Normalization processor applied to particles before alignment. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'"""
    )

    parser.add_argument(
        "--threshold",
        type=str,
        default='',
        help=
        """Default=None. A threshold applied to the subvolumes after normalization. For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=10,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--preprocess",
        type=str,
        default='',
        help=
        """Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=10,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--preprocessfine",
        type=str,
        default='',
        help=
        """Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging."""
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        default='',
        help=
        """Default=None. A lowpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=17,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--lowpassfine",
        type=str,
        default='',
        help=
        """Default=None. A lowpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging."""
    )

    parser.add_argument(
        "--highpass",
        type=str,
        default='',
        help=
        """Default=None. A highpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=18,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--highpassfine",
        type=str,
        default='',
        help=
        """Default=None. A highpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging."""
    )

    parser.add_argument(
        "--shrink",
        type=int,
        default=1,
        help=
        """Default=1 (no shrinking). Optionally shrink the input volumes by an integer amount for coarse alignment.""",
        guitype='shrinkbox',
        row=5,
        col=1,
        rowspan=1,
        colspan=1,
        mode='alignment,breaksym')

    parser.add_argument(
        "--shrinkfine",
        type=int,
        default=1,
        help=
        """Default=1 (no shrinking). Optionally shrink the input volumes by an integer amount for refine alignment.""",
        guitype='intbox',
        row=5,
        col=2,
        rowspan=1,
        colspan=1,
        mode='alignment')

    parser.add_argument(
        "--clipali",
        type=int,
        default=0,
        help=
        """Default=0 (which means it's not used). Boxsize to clip particles as part of preprocessing to speed up alignment. For example, the boxsize of the particles might be 100 pixels, but the particles are only 50 pixels in diameter. Aliasing effects are not always as deleterious for all specimens, and sometimes 2x padding isn't necessary; still, there are some benefits from 'oversampling' the data during averaging; so you might still want an average of size 2x, but perhaps particles in a box of 1.5x are sufficiently good for alignment. In this case, you would supply --clipali=75"""
    )

    parser.add_argument(
        "--postprocess",
        type=str,
        default='',
        help=
        """A processor to be applied to the FINAL volume after averaging the raw volumes in their FINAL orientations, after all iterations are done.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_processors_list(),\'filter\')',
        row=16,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--procfinelikecoarse",
        action='store_true',
        default=False,
        help=
        """If you supply this parameters, particles for fine alignment will be preprocessed identically to particles for coarse alignment by default. If you supply this, but want specific parameters for preprocessing particles for also supply: fine alignment, nd supply fine alignment parameters, such as --lowpassfine, --highpassfine, etc; to preprocess the particles for FINE alignment differently than for COARSE alignment."""
    )

    parser.add_argument(
        "--npeakstorefine",
        type=int,
        help=
        """Default=1. The number of best coarse alignments to refine in search of the best final alignment. Default=1.""",
        default=4,
        guitype='intbox',
        row=9,
        col=0,
        rowspan=1,
        colspan=1,
        nosharedb=True,
        mode='alignment,breaksym[1]')

    parser.add_argument(
        "--align",
        type=str,
        default="rotate_translate_3d:search=8:delta=12:dphi=12",
        help=
        """This is the aligner used to align particles to the previous class average. Default is rotate_translate_3d:search=8:delta=12:dphi=12, specify 'None' (with capital N) to disable.""",
        returnNone=True,
        guitype='comboparambox',
        choicelist='re_filter_list(dump_aligners_list(),\'3d\')',
        row=12,
        col=0,
        rowspan=1,
        colspan=3,
        nosharedb=True,
        mode="alignment,breaksym['rotate_symmetry_3d']")

    parser.add_argument(
        "--aligncmp",
        type=str,
        default="ccc.tomo",
        help=
        """Default=ccc.tomo. The comparator used for the --align aligner. Do not specify unless you need to use anotherspecific aligner.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_cmps_list(),\'tomo\')',
        row=13,
        col=0,
        rowspan=1,
        colspan=3,
        mode="alignment,breaksym")

    parser.add_argument(
        "--falign",
        type=str,
        default="refine_3d_grid:delta=3:range=15:search=2",
        help=
        """Default="refine_3d_grid:delta=3:range=15:search=2". This is the second stage aligner used to fine-tune the first alignment. Specify 'None' to disable.""",
        returnNone=True,
        guitype='comboparambox',
        choicelist='re_filter_list(dump_aligners_list(),\'refine.*3d\')',
        row=14,
        col=0,
        rowspan=1,
        colspan=3,
        nosharedb=True,
        mode='alignment,breaksym[None]')

    parser.add_argument(
        "--faligncmp",
        type=str,
        default="ccc.tomo",
        help=
        """Default=ccc.tomo. The comparator used by the second stage aligner.""",
        guitype='comboparambox',
        choicelist='re_filter_list(dump_cmps_list(),\'tomo\')',
        row=15,
        col=0,
        rowspan=1,
        colspan=3,
        mode="alignment,breaksym")

    parser.add_argument(
        "--averager",
        type=str,
        default="mean.tomo",
        help=
        """Default=mean.tomo. The type of averager used to produce the class average. Default=mean.tomo."""
    )

    #parser.add_argument("--keep",type=float,default=1.0,help="""Default=1.0 (all particles kept). The fraction of particles to keep in each class.""", guitype='floatbox', row=6, col=0, rowspan=1, colspan=1, mode='alignment,breaksym')

    #parser.add_argument("--keepsig", action="store_true", default=False,help="""Default=False. Causes the keep argument to be interpreted in standard deviations.""", guitype='boolbox', row=6, col=1, rowspan=1, colspan=1, mode='alignment,breaksym')

    #parser.add_argument("--inixforms",type=str,default="",help="""Default=None. .json file containing a dict of transforms to apply to 'pre-align' the particles.""", guitype='dirbox', dirbasename='spt_|sptsym_', row=7, col=0,rowspan=1, colspan=2, nosharedb=True, mode='breaksym')

    parser.add_argument(
        "--breaksym",
        action="store_true",
        default=False,
        help=
        """Default=False. Break symmetry. Do not apply symmetrization after averaging, even if searching the asymmetric unit provided through --sym only for alignment. Default=False""",
        guitype='boolbox',
        row=7,
        col=2,
        rowspan=1,
        colspan=1,
        nosharedb=True,
        mode=',breaksym[True]')

    #parser.add_argument("--groups",type=int,default=0,help="""Default=0 (not used; data not split). This parameter will split the data into a user defined number of groups. For purposes of gold-standard FSC computation later, select --group=2.""")

    parser.add_argument(
        "--randomizewedge",
        action="store_true",
        default=False,
        help=
        """Default=False. This parameter is EXPERIMENTAL. It randomizes the position of the particles BEFORE alignment, to minimize missing wedge bias and artifacts during symmetric alignment where only a fraction of space is scanned"""
    )

    parser.add_argument(
        "--savepreprocessed",
        action="store_true",
        default=False,
        help=
        """Default=False. Will save stacks of preprocessed particles (one for coarse alignment and one for fine alignment if preprocessing options are different)."""
    )

    parser.add_argument(
        "--autocenter",
        type=str,
        default='',
        help=
        """Default=None. Autocenters each averaged pair during initial average generation with --btref and --hacref. Will also autocenter the average of all particles after each iteration of iterative refinement. Options are --autocenter=xform.centerofmass (self descriptive), or --autocenter=xform.centeracf, which applies auto-convolution on the average."""
    )

    parser.add_argument(
        "--autocentermask",
        type=str,
        default='',
        help=
        """Default=None. Masking processor to apply before autocentering. See 'e2help.py processors -v 10' at the command line."""
    )

    parser.add_argument(
        "--autocenterpreprocess",
        action='store_true',
        default=False,
        help=
        """Default=False. This will apply a highpass filter at a frequency of half the box size times the apix, shrink by 2, and apply a low pass filter at half nyquist frequency to any computed average for autocentering purposes if --autocenter is provided. Default=False."""
    )

    parser.add_argument(
        "--parallel",
        default="thread:1",
        help=
        """default=thread:1. Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel""",
        guitype='strbox',
        row=19,
        col=0,
        rowspan=1,
        colspan=3,
        mode='alignment,breaksym')

    parser.add_argument(
        "--ppid",
        type=int,
        help=
        """Default=-1. Set the PID of the parent process, used for cross platform PPID""",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        """Default=0. Verbose level [0-9], higner number means higher level of verboseness"""
    )

    #parser.add_argument("--resume",type=str,default='',help="""(Not working currently). tomo_fxorms.json file that contains alignment information for the particles in the set. If the information is incomplete (i.e., there are less elements in the file than particles in the stack), on the first iteration the program will complete the file by working ONLY on particle indexes that are missing. For subsequent iterations, all the particles will be used.""")

    parser.add_argument(
        "--plots",
        action='store_true',
        default=False,
        help=
        """Default=False. Turn this option on to generatea plot of the ccc scores during each iteration. Running on a cluster or via ssh remotely might not support plotting."""
    )

    parser.add_argument(
        "--subset",
        type=int,
        default=0,
        help=
        """Default=0 (not used). Refine only this substet of particles from the stack provided through --input"""
    )

    parser.add_argument(
        "--notmatchimgs",
        action='store_true',
        default=False,
        help=
        """Default=True. This option prevents applying filter.match.to to one image so that it matches the other's spectral profile during preprocessing for alignment purposes."""
    )

    parser.add_argument(
        "--preavgproc1",
        type=str,
        default='',
        help=
        """Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)"""
    )

    parser.add_argument(
        "--preavgproc2",
        type=str,
        default='',
        help=
        """Default=None. A processor (see 'e2help.py processors -v 10' at the command line) to be applied to the raw particle after alignment but before averaging (for example, a threshold to exclude extreme values, or a highphass filter if you have phaseplate data.)"""
    )

    parser.add_argument(
        "--weighbytiltaxis",
        type=str,
        default='',
        help=
        """Default=None. A,B, where A is an integer number and B a decimal. A represents the location of the tilt axis in the tomogram in pixels (eg.g, for a 4096x4096xZ tomogram, this value should be 2048), and B is the weight of the particles furthest from the tomogram. For example, --weighbytiltaxis=2048,0.5 means that praticles at the tilt axis (with an x coordinate of 2048) will have a weight of 1.0 during averaging, while the distance in the x coordinates of particles not-on the tilt axis will be used to weigh their contribution to the average, with particles at the edge(0+radius or 4096-radius) weighing 0.5, as specified by the value provided for B."""
    )

    parser.add_argument(
        "--weighbyscore",
        action='store_true',
        default=False,
        help=
        """Default=False. This option will weigh the contribution of each subtomogram to the average by score/bestscore."""
    )

    parser.add_argument(
        "--tweak",
        action='store_true',
        default=False,
        help=
        """WARNING: BUGGY. This will perform a final alignment with no downsampling [without using --shrink or --shrinkfine] if --shrinkfine > 1."""
    )
    '''
	BT SPECIFIC PARAMETERS
	'''

    parser.add_argument("--nseedlimit",
                        type=int,
                        default=0,
                        help="""Maximum number of particles
		to use. For example, if you supply a stack with 150 subtomograms, the program will
		automatically select 128 as the limit to use because it's the largest power of 2 that is
		smaller than 150. But if you provide, say --nseedlimit=100, then the number of particles
		used will be 64, because it's the largest power of 2 that is still smaller than 100."""
                        )

    (options, args) = parser.parse_args()
    '''
	Make the directory where to create the database where the results will be stored
	'''
    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'spt_bt')

    rootpath = os.getcwd()
    if rootpath not in options.path:
        options.path = rootpath + '/' + options.path

    if not options.input:
        parser.print_help()
        exit(0)
    elif options.subset:
        subsetStack = options.path + '/subset' + str(options.subset).zfill(
            len(str(options.subset))) + '.hdf'
        print "\nSubset to be written to", subsetStack

        subsetcmd = 'e2proc3d.py ' + options.input + ' ' + subsetStack + ' --first=0 --last=' + str(
            options.subset - 1)
        print "Subset cmd is", subsetcmd

        p = subprocess.Popen(subsetcmd,
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        text = p.communicate()
        p.stdout.close()

        options.input = subsetStack

    from e2spt_classaverage import sptParseAligner
    options = sptParseAligner(options)
    '''
	If --radius of the particle is provided, we calculate the optimal alignment steps for 
	coarse and fine alignment rounds using --shrink and --shrinkfine options and apix info
	'''

    if options.shrink < options.shrinkfine:
        options.shrink = options.shrinkfine
        print "It makes no sense for shrinkfine to be larger than shrink; therefore, shrink will be made to match shrinkfine"

    if options.radius:
        from e2spt_classaverage import calcAliStep
        options = calcAliStep(options)
    '''
	Parse parameters such that "None" or "none" are adequately interpreted to turn of an option
	'''

    from e2spt_classaverage import sptOptionsParser
    options = sptOptionsParser(options)

    from e2spt_classaverage import writeParameters
    writeParameters(options, 'e2spt_binarytree.py', 'bt')

    hdr = EMData(options.input, 0, True)
    nx = hdr["nx"]
    ny = hdr["ny"]
    nz = hdr["nz"]
    if nx != ny or ny != nz:
        print "ERROR, input volumes are not cubes"
        sys.exit(1)

    logger = E2init(sys.argv, options.ppid)
    '''
	Initialize parallelism if being used
	'''

    if options.parallel:

        if options.parallel == 'none' or options.parallel == 'None' or options.parallel == 'NONE':
            options.parallel = ''
            etc = ''

        else:
            print "\n\n(e2spt_classaverage.py) INITIALIZING PARALLELISM!"
            print "\n\n"

            from EMAN2PAR import EMTaskCustomer
            etc = EMTaskCustomer(options.parallel)

            pclist = [options.input]

            etc.precache(pclist)

    else:
        etc = ''

    nptcl = EMUtil.get_image_count(options.input)
    if nptcl < 1:
        print "ERROR : at least 2 particles required in input stack"
        sys.exit(1)

    ptclnums = range(nptcl)
    nptclForRef = len(ptclnums)

    nseed = 2**int(
        floor(log(len(ptclnums), 2))
    )  # we stick with powers of 2 for this to make the tree easier to collapse

    if options.nseedlimit:
        nseed = 2**int(floor(log(options.nseedlimit, 2)))

    binaryTreeRef(options, nptclForRef, nseed, -1, etc)

    print "Will end logger"
    E2end(logger)

    print "logger ended"
    sys.stdout.flush()

    return
Beispiel #19
0
def main():

    progname = os.path.basename(sys.argv[0])
    usage = """
		This program takes a subtomgoram tiltseries (subtiltseries) as extracted with
		e2spt_subtilt.py, and computes the resolution of two volumes reconstructed with
		the even and the odd images in the tilt series. Must be in HDF format.
		Note that the apix in the header must be accurate to get sensible results.
		(You can fix the header of an image with e2fixheaderparam.py).
		"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--inputstem",
        type=str,
        default='',
        help=
        """Default=None. Aligned tilt series. String common to all files to be processed, in the current folder. For example, if you have many subtiltseries named subt00.hdf, subt01.hdf, ...subt99.hdf, you would supply --stem=subt to have all these processed."""
    )

    parser.add_argument(
        '--path',
        type=str,
        default='sptintrafsc',
        help="""Default=sptintrafsc. Directory to save the results.""")

    parser.add_argument(
        '--nonewpath',
        action='store_true',
        default=False,
        help=
        """Default=False. If True, a new --path directory will not be made. Therefore, whatever is sepcified in --path will be used as the output directory. Note that this poses the risk of overwriting data."""
    )

    parser.add_argument(
        '--input',
        type=str,
        default='',
        help=
        """Default=None. Subtiltseries file to process. If processing a single file, --inputstem will work too, but you can also just provide the entire filename here --input=subt00.hdf"""
    )

    parser.add_argument(
        '--savehalftiltseries',
        action='store_true',
        default=False,
        help=
        """Default=False. If this parameter is on, the odd and even subtiltseries will be saved."""
    )

    parser.add_argument(
        '--savehalfvolumes',
        action='store_true',
        default=False,
        help=
        """Default=False. If this parameter is on, the odd and even volumes will be saved."""
    )

    parser.add_argument(
        "--reconstructor",
        type=str,
        default="fourier:mode=gauss_2",
        help=
        """Default=fourier:mode=gauss_2. The reconstructor to use to reconstruct the tilt series into a tomogram. Type 'e2help.py reconstructors' at the command line to see all options and parameters available. To specify the interpolation scheme for the fourier reconstructor, specify 'mode'. Options are 'nearest_neighbor', 'gauss_2', 'gauss_3', 'gauss_5'. For example --reconstructor=fourier:mode=gauss_5 """
    )

    parser.add_argument(
        "--pad2d",
        type=float,
        default=0.0,
        help=
        """Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the 2d images in the tilt series for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though)."""
    )

    parser.add_argument(
        "--pad3d",
        type=float,
        default=0.0,
        help=
        """Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the volumes for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though)."""
    )

    parser.add_argument(
        "--averager",
        type=str,
        default="mean.tomo",
        help=
        """Default=mean.tomo. The type of averager used to produce the class average."""
    )

    parser.add_argument(
        "--averagehalves",
        action="store_true",
        default=False,
        help="""Default=False. This will averager the even and odd volumes.""")

    parser.add_argument(
        "--ppid",
        type=int,
        default=-1,
        help=
        """default=-1. Set the PID of the parent process, used for cross platform PPID."""
    )

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness")

    parser.add_argument(
        "--nolog",
        action="store_true",
        default=False,
        help=
        "Default=False. Turn off recording of the command ran for this program onto the .eman2log.txt file"
    )

    (options, args) = parser.parse_args()

    #if options.reconstructor == 'None' or options.reconstructor == 'none':
    #	options.reconstructor = None

    #if options.reconstructor and options.reconstructor != 'None' and options.reconstructor != 'none':
    #	options.reconstructor=parsemodopt(options.reconstructor)

    #if options.averager:
    #	options.averager=parsemodopt(options.averager)

    from e2spt_classaverage import sptOptionsParser
    options = sptOptionsParser(options)

    logger = E2init(sys.argv, options.ppid)
    '''
	Make the directory where to create the database where the results will be stored
	'''

    if not options.nonewpath:
        from e2spt_classaverage import sptmakepath
        options = sptmakepath(options, 'sptintrafsc')
    else:
        try:
            findir = os.lisdir(options.path)
        except:
            print "ERROR: The path specified %s does not exist" % (
                options.path)
            sys.exit()

    inputfiles = []

    if options.inputstem:
        c = os.getcwd()
        findir = os.listdir(c)

        for f in findir:
            if '.hdf' in f and options.inputstem in f:
                if options.verbose > 8:
                    print "\nFound tiltseries!", f
                inputfiles.append(
                    f
                )  #C:The input files are put into a dictionary in the format {originalseriesfile:[originalseriesfile,volumefile]}

    elif options.input:
        inputfiles.append(options.input)

    for fi in inputfiles:

        #genOddAndEvenVols( options, fi )

        ret = genOddAndEvenVols(options, fi, [])
        volOdd = ret[1]
        volEven = ret[0]

        if options.savehalfvolumes and volOdd and volEven:
            volOdd.write_image(
                options.path + '/' + fi.replace('.hdf', '_ODDVOL.hdf'), 0)
            volEven.write_image(
                options.path + '/' + fi.replace('.hdf', '_EVENVOL.hdf'), 0)

        retfsc = fscOddVsEven(options, fi, volOdd, volEven)

        fscfilename = retfsc[0]
        fscarea = retfsc[1]

        if options.averagehalves:
            avgr = Averagers.get(options.averager[0], options.averager[1])
            avgr.add_image(recOdd)
            avgr.add_image(recEven)

            avg = avgr.finish()
            avg['origin_x'] = 0
            avg['origin_y'] = 0
            avg['origin_z'] = 0
            avg['apix_x'] = apix
            avg['apix_y'] = apix
            avg['apix_z'] = apix

            avgfile = options.path + '/AVG.hdf'
            avg.write_image(avgfile, 0)

    E2end(logger)

    return
Beispiel #20
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog [options] 
	This program takes aligned stacks produced by e2spt_classaverage.py and raw tomograms
	to recompute averages with different options (such as extracting recentered particles,
	and possibly with a larger or smaller boxisze).
	All the necessary files (aligned stacks in HDF format and raw tomograms in MRC format 
	ending in .rec, as produced by IMOD) should be in the running directory.
	"""
	
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--stacks", default='',type=str, help="""Comma separated list of HDF image stacks to process.""")
	
	parser.add_argument("--tomograms", default='',type=str, help="""Comma separated list of tomograms with REC extension from which all particles in --stacks came from.""")
	
	#parser.add_argument("--output", default="avg.hdf",type=str, help="The name of the output average volume.")
	#parser.add_argument("--rotationtype", default="eman",type=str, help="Valid options are: eman,imagic,mrc,spider,quaternion,sgirot,spi,xyz")
	
	#parser.add_argument("--averager",type=str,help="The type of averager used to produce the class average. Default=mean",default="mean")
	
	parser.add_argument("--sym", type=str, default='', help = "Symmetry to impose - choices are: c<n>, d<n>, h<n>, tet, oct, icos")

	parser.add_argument("--path",default='',type=str,help="Name of directory where to save the output file.")
	#parser.add_argument("--alifile",default='',type=str,help=".json file with alingment parameters, if raw stack supplied via --input.")
	
	parser.add_argument("--boxsize","-B",type=int,default=0,help="""Default=0 (option not used). Provide a value for the boxsize of the output average in pixels. If not provided, the boxsize of --stacks will be used.""")
	
	parser.add_argument("--normproc",type=str,default='normalize.edgemean',help="""Normalization processor applied to particles before extraction. Default=normalize.edgemean. If using the latter, you must provide --masknorm, otherwise, a default --masknorm=mask.sharp:outer_radius=-2 will be used.""")
	
	parser.add_argument("--threshold",type=str,help="""Threshold processor to apply to particles before writing them out to get rid of too high and/or too low pixel values.""", default='')
	
	parser.add_argument("--usetomograms",action='store_true',default=False,help=""""Re-extract particles from the original tomogram.""")
	
	parser.add_argument("--useinverseali",action='store_true',default=False,help=""""Use the inverse of the value stored in xform.align3d in the header of each particle.""")
	
	parser.add_argument('--shrink', type=int, default=1, help="""Shrink factor to shrink particles before averaging. Default=1, which means no shrinking.""")
	
	parser.add_argument("--lowpass",type=str,help="""Lowpass filtering processor to apply to particles before averaging. Default=None.""",default='')
	
	parser.add_argument("--preprocess",type=str,help="""A processor (as in e2proc3d.py) to be applied to the tomogram before opening it. \nFor example, a specific filter with specific parameters you might like. \nType 'e2proc3d.py --processors' at the commandline to see a list of the available processors and their usage""",default=None)
		
	parser.add_argument('--invert', action="store_true", default=False, help='''Default=False. This parameer indicates you want the contrast to me inverted while boxing, AND for the extracted sub-volumes. Remember that EMAN2 **MUST** work with "white" protein. You can very easily figure out what the original color\nof the protein is in your data by looking at the gold fiducials or the edge of the carbon hole in your tomogram. If they look black you MUST specify this option''')

	parser.add_argument("--averager",type=str,help="""The type of averager used to produce the class average. Default=mean.tomo""", default='mean.tomo')
	
	parser.add_argument("--keep",type=float,help="""The fraction of particles to keep in each class. Default=1.0""",default=1.0)
	
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")

	#parser.add_argument("--saveali",action="store_true", default=False,help="""If set, will save the 
	#	aligned particle volumes in class_ptcl.hdf. Overwrites existing file.""")

	(options, args) = parser.parse_args()
	
	
	from e2spt_classaverage import sptOptionsParser
	options = sptOptionsParser( options )
	
	'''
	if options.normproc: 
		options.normproc=parsemodopt(options.normproc)
		
	if options.threshold: 
		options.threshold=parsemodopt(options.threshold)
		
	if options.lowpass: 
		options.lowpass=parsemodopt(options.lowpass)
	
	if options.preprocess: 
		options.preprocess=parsemodopt(options.preprocess)
		
	if options.averager: 
		options.averager=parsemodopt(options.averager)
	'''
	
	#if not options.boxsize:
	#	print "\n(e2spt_recompute.py) (main) ERROR: Boxsize must be greater than zero. It is:", options.boxsize
	#	sys.exit()
	
	logid=E2init(sys.argv,options.ppid)
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'sptrecompute')
	
	c = os.getcwd()					#Get current directory
	
	findir = os.listdir( c ) 		#Get list of files in current directory
	
	stacks = set([]) 				#Make list set to store particle stacks
	if options.stacks:
		stacks = set( options.stacks.split(',') )
		
		if not options.boxsize:
			boxesdict = {}
			boxes = []
			for sta in stacks:
				box = EMData( sta, 0 )['nx']
				boxesdict.update({sta:box})
				boxes.append( box )
			boxes = set(boxes)
			if len(boxes) >1:
				print "ERROR: Your stacks are not all the same boxsize. There are %d many different boxsizes" %(len(boxes))
				print "which are", boxes
				print "all input stacks in --stacks must have the same boxsize; otherwise, specify a unique boxsize through --boxsize."
				sys.exit()		
	else:	
		for f in findir:
			if '.hdf' in f:
				stacks.add(f)

	tomograms = set([])
	tomogramsbases = set([])
	if options.usetomograms:		#Make list set to store tomograms
		if options.tomograms:
			tomograms = set( options.tomograms.split(',') )
			for tom in tomograms:
				tombase = os.path.basename(tom)
				tomogramsbases.append(tombase)	
		
		else:
			for f in findir:
				if '.rec' in f:
					tomograms.add(f)
	
	for stack in stacks:								#Loop over stacks
		n = EMUtil.get_image_count( stack )				#Determine number of particles in stack
		avgr = Averagers.get(options.averager[0], options.averager[1])	#initialize averager
		
		print "\n(e2spt_recompute.py) (main) Processing stack",stack
		
		for i in range(n):								#Loop over particles in stack
			hdr = EMData( stack, i, True)				#Load particle header by providing 'True' flag
			
			a = None
			
			box = hdr['nx']
			if options.boxsize:
				box = options.boxsize
			
			if options.usetomograms and tomograms:
				tomogram = hdr['ptcl_source_image']			#Determine what tomogram a particle comes from
				if tomogram not in tomogramsbases and tomogram not in tomograms:
					print "\n(e2spt_recompute.py) (main) ERROR: Tomogram %s not found" %( tomogram )
					sys.exit()
			
				print "\n(e2spt_recompute.py) (main) Processing particle %d in stack %s which should come from tomogram %s" %(i, stack, tomogram )
			
				coords = hdr['ptcl_source_coord']			#And from what location exactly
				x = coords[0]								#Parse coordinates
				y = coords[1]
				z = coords[2]					
			
				r = Region((2*x-box)/2,(2*y-box)/2, (2*z-box)/2, box, box, box)		#Define extraction region based on boxsize
			
				a = EMData()
				a.read_image(tomogram,0,False,r)									#Actually 'read'/extract particle data
																					#Preprocess as needed
			else:
				a = EMData( stack, i )
			
			if a:
				if options.normproc:
					a.process_inplace(options.normproc[0],options.normproc[1])
			
				if options.invert:
					a.mult(-1)
		
				t = None
				try:
					t = hdr['xform.align3d']												#Rotate particle into aligned orientation
				except:
					print "WARNING: 'xform.align3d' not found in header of particle %d" % (i)
				
				try:
					t = hdr['sptsim_randT']
				except:
					print "ERROR: 'sptsim_randT also not found in header or particle %d" %(i)
				
				if t:
					tf = t
					if options.useinverseali:
						tf = t.inverse()
						print "t is", t
						print "and its inverse is", tf
		
					#print "Applied this transform",tf
					a.transform(tf)
			
					if options.threshold:
						a.process_inplace(options.threshold[0],options.threshold[1])

					if options.lowpass:
						a.process_inplace(options.lowpass[0],options.lowpass[1])

					if options.preprocess:
						a.process_inplace(options.preprocess[0],options.preprocess[1])

					if options.shrink and int(options.shrink) > 1:
						shrinkfactor = options.shrink 
						a.process_inplace('math.meanshrink',{'n':shrinkfactor})
				
					#a['origin_x'] = 0
					#a['origin_y'] = 0
					#a['origin_z'] = 0
			
					#a['ptcl_source_image'] = hdr['ptcl_source_image']	
					#a['ptcl_source_coord'] = hdr['ptcl_source_coord']
			
					avgr.add_image(a)
				else:
					print "skipping particle", i
					
		avg = avgr.finish()
		
		avg.process_inplace('normalize')
		
		if options.sym and not breaksym:
			avg.process_inplace('xform.applysym',{'sym':options.sym})
			
		outname = options.path + '/' + stack.replace('.hdf','_AVG.hdf')
		avg.write_image(outname,0)	


	E2end(logid)

	return
def main():

	progname = os.path.basename(sys.argv[0])
	usage = """This program allows you to examine density variations along one or more given volume (at the same time).
				It calculates the mean intensity either for slices (planes) along any the three cartesian axes (X, Y or Z), or for radial consecutive shells of increasing radius, 
				or for cylindrical shells of varying or fixed height, starting from the center of the volume. 
				All mean density values are saved to .txt files, and plots are produced with them and saved as .png images. In fact, to compare different volumes you can plot all curves in a single plot."""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument('--path',type=str,default='spt_radialplot',help="""Directory to save 
		the results.""")
		
	parser.add_argument("--input", type=str, help="""Volume whose radial density plot you 
		want to compute. For multiple volumes, either provide them as an .hdf stack, or 
		separate them by commas --vols=first.hdf,second.hdf,etc...""", default='')
	
	parser.add_argument("--mode", type=str, help="""provide --mode=x, y, or z to get the 
		average density per slice in the indicated direction. 
		--mode=cylinder for concentric cylindrical shell; default is --mode=sphere.
		For MULTIPLE modes, separate them by commas, for example --mode=x,y,z,cylinder""", default='sphere')
	
	parser.add_argument("--fixedcylinderheight", type=int, help="""Works only if --mode=cylinder, 
		and keeps the height of the cylinder at a constant value, while varying the radius.""", default=0)
	
	parser.add_argument("--mask",type=str,help="""Masking processor (see e2help.py --verbose=10) 
		applied to each volume prior to radial density plot computation. Default=None.""", default='')
	
	parser.add_argument("--normproc",type=str,help="""Normalization processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation. Default is None.
		If normalize.mask is used, results of the mask option will be passed in automatically.""", default='')
	
	parser.add_argument("--preprocess",type=str,help="""Any processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""", default='')
	
	parser.add_argument("--lowpass",type=str,help="""Default=None. A lowpass filtering processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""", default='')
	
	parser.add_argument("--highpass",type=str,help="""Default=None. A highpass filtering processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""", default='')	
		
	parser.add_argument("--threshold",type=str,help="""Default=None. A threshold  processor 
		(see e2help.py --verbose=10) applied to each volume prior to radial density plot 
		computation.""", default='')
	
	parser.add_argument("--shrink", type=int,default=1,help="""Default=1 (no shrinking). Optionally shrink the input 
		volumes by an integer amount.""")	
	
	#parser.add_argument("--apix", type=float, help="Provide --apix to overrride the value found in the volumes' header paramter.", default=0)
	
	parser.add_argument("--singleplotperfile", action="store_true",default=False,help="""
		Plot all the Radial Density Profiles of the volumes provided in each .hdf stack in 
		one single plot.""")	
	
	parser.add_argument("--singlefinalplot", action="store_true",default=False,help="""Plot 
		all the Radial Density Profiles of the volumes provided in all .hdf stacks in one 
		FINAL single 'master' plot.""")	

	parser.add_argument("--normalizeplot", action="store_true",default=False,help="""This 
		will make the maximum density in each plot or curve equal to 1.""")
	
	parser.add_argument("--savetxt", action="store_true",default=False,help="""Save plot
		files as .txt, so that they can be replotted with other software if necessary.""")
	
	parser.add_argument("--ppid", type=int, help="""Set the PID of the parent process, 
		used for cross platform PPID""",default=-1)
	
	parser.add_argument("--verbose", "-v", default=0, help="""Verbose level [0-9], higner 
		number means higher level of verboseness""",dest="verbose", action="store", metavar="n",type=int)
	
	parser.add_argument("--sym", dest = "sym", default='c1', help = """Symmetry to impose 
		- choices are: c<n>, d<n>, h<n>, tet, oct, icos.
		For this to make any sense in the context of this program, the particles need to be
		aligned to the symmetry axis first, which can be accomplished by running them 
		through e2symsearch3d.py.""")
	
	parser.add_argument("--classifymaxpeaks",type=int,default=0, help="""Number of highest 
		peaks to consider for classification. Amongst the n peaks provided, --classifymaxpeaks=n,
		the peak occurring at the largest radius will be used as the classifier.
		If --classifymaxpeaks=1, the highest peak will be the classifier.
		To smooth the radial density curve consider low pass filtering through --lowpass.
		To remove aberrant peaks consider masking with --mask.""")
	
	parser.add_argument("--subset",type=int,default=0,help="""An n-subset of particles from
		--input to use.""")
	
	(options, args) = parser.parse_args()
	
	import matplotlib.pyplot as plt
	#from matplotlib.ticker import MaxNLocator
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'spt_radialplot')
	
	if not options.input:
		parser.print_help()
		exit(0)
	elif options.subset:
		subsetStack = options.path + '/subset' + str( options.subset ).zfill( len( str( options.subset))) + '.hdf' 
		print "\nSubset to be written to", subsetStack
		
		subsetcmd = 'e2proc3d.py ' + options.input + ' ' + subsetStack + ' --first=0 --last=' + str(options.subset-1) 
		print "Subset cmd is", subsetcmd
		
		p=subprocess.Popen( subsetcmd, shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE )
		text=p.communicate()	
		p.stdout.close()
		
		options.input = subsetStack
	
	
	logger = E2init(sys.argv, options.ppid)

	if options.normproc: 
		options.normproc=parsemodopt(options.normproc)
	
	if options.mask: 
		options.mask=parsemodopt(options.mask)
	
	if options.preprocess: 
		options.preprocess=parsemodopt(options.preprocess)
		
	if options.lowpass: 
		options.lowpass=parsemodopt(options.lowpass)
	
	if options.highpass: 
		options.highpass=parsemodopt(options.highpass)
	
	if options.threshold: 
		options.threshold=parsemodopt(options.threshold)
			
	files = options.input
	files = files.split(',')
	
	for i in xrange(0,len(files)):
		for j in range(i+1,len(files)):
			if files[i] == files[j]:
				print "ERROR: You have supplied a file twice, see", files[i],files[j]
				sys.exit()
	modes=options.mode.split(',')
	
	for m in modes:
		options.mode=m
		modetag = '_MODE' + m
		finalvalues = {}
		imgsperstack=1
		
		names=[]
		finalvalues=[]
		maxsall={}
		minsall={}
		
		for i in files:	
			n = EMUtil.get_image_count(i)
			
			print "The stack %s has %d images in it" % ( i, n ) 
			
			kk=0
			stack={}
			stackvalues = []
			suffix = modetag
			for j in range(n):
				ptcl = EMData(i,j)
				if n > 1:
					suffix = modetag + str(kk).zfill(len(str(n)))
				
				values = calcvalues(ptcl,options)
				
				ret = calcmaxima( values )
				maxima=ret[0]				#These are a list of lists [[pixel,value],[pixel,value],...] with all maxima and minima
				minima=ret[-1]
				
				uniquetag = i+'_indxtag'+str(j)
				maxsall.update({ uniquetag:maxima })
				minsall.update({ uniquetag:minima })	

				print "For file %s img number %d the max is %f" %(i,j,max(values))
				
				if options.normalizeplot:
					
					minv = min(values)
					for v in range(len(values)):
						values[v] = values[v] - minv
					
					maxv = max(values)
					for v in range(len(values)):	
						values[v] = values[v]/maxv	
					print "Therefore, max is", max(values)
				
				id=i.replace('.',suffix + '.')
				stackvalues.append([id,values])
				kk+=1
			stack.update({i:stackvalues})
			finalvalues.append(stack)
			 		
		plotname = 'finalplot_MODE' + m + '.png'
		fileid=''
		
		if options.classifymaxpeaks:
			classifymax( options, maxsall )
	
		cc=0
		for ele in finalvalues:
			i = ele.keys()[0]
			key = i
			
			n = EMUtil.get_image_count(i)
			
			if options.singleplotperfile:
				fileid=i.split('.')[0]	
				plotname = fileid + modetag + '.png'
				
			kk=0
			for f in range(n):
				apix = EMData(i,f,True)['apix_x']
				
				values = ele[key][f][1]
				id = ele[key][f][0]
				
				x = range(len(values))				
					
				for j in range(len(x)):
					x[j] = int(round(x[j] * apix))				
				
				if options.savetxt:
					txtname = options.path + '/' + i.split('.')[0] + modetag + str(kk).zfill(len(str(n))) + '.txt'
					txtf = open(txtname,'w')
					lines = []	
					for v in range(len(values)):
						line = str(v) +  ' ' + str(values[v]) + '\n'
						lines.append(line)
					txtf.writelines(lines)
					txtf.close()
				
				plt.plot(x,values,linewidth=2,alpha=0.5)
				
				if not options.singleplotperfile and not options.singlefinalplot:
					#plotname=i.split('.')[0]+str(kk).zfill(len(str(n))) + '.png'
					plotname=id.split('.')[0] + '.png'
					fileid = plotname.split('.')[0]
				
				if options.mode == 'sphere':
					plt.title("Spherical radial density plot " + fileid)
					plt.xlabel("Radius (angstroms)")
					plt.ylabel("Density (arbitrary units)")
				
				if options.mode == 'x':
					plt.title("Density plot of slices along x-axis "+ fileid)
					plt.xlabel("X (angstroms)")
					plt.ylabel("Density (arbitrary units)")

				if options.mode == 'y':
					plt.title("Density plot of slices along y-axis "+ fileid)
					plt.xlabel("Y (angstroms)")
					plt.ylabel("Density (arbitrary units)")

				if options.mode == 'z':
					plt.title("Density plot of slices along z-axis "+ fileid)
					plt.xlabel("Z (angstroms)")
					plt.ylabel("Density (arbitrary units)")
				
				if options.mode == 'cylinder':
					plt.title("Density plot of concentric cylyndrical shells "+ fileid)
					plt.xlabel("Radius (angstroms)")
					plt.ylabel("Density (arbitrary units)")			
								
				if not options.singleplotperfile and not options.singlefinalplot:
					if options.path not in plotname:
						plotname = options.path + '/' + plotname
					plt.savefig( plotname )
					plt.clf()
				else:
					pass
				kk+=1
				cc+=1
			
			if options.singleplotperfile:
				if options.path not in plotname:
					plotname = options.path + '/' + plotname
				plt.savefig( plotname )
				plt.clf()
	
		if options.singlefinalplot:
			if options.path not in plotname:
				plotname = options.path + '/' + plotname
			plt.savefig( plotname )
			plt.clf()
	return			
Beispiel #22
0
def main():
	
	progname = os.path.basename(sys.argv[0])
	usage = """WARNING:  **PRELIMINARY** program, still heavily under development. 
				Autoboxes globular particles from tomograms.
				Note that self-generated spherical templates generated by this program
				are 'white'; which means you have to provide the tomogram with inverted (or 'white') contrast, and the same goes for any stacks
				provided (specimen particles, gold, carbon and/or background)."""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	
	parser.add_argument("--parallel",type=str,default='',help="""Default=Auto. This program will detect the number of CPU cores on your machine and parallelize some of the tasks using all of them. To disable, provide --parallel=None""")
	
	parser.add_argument("--input", type=str,default='', help="""Default=None. HDF stack of volumes to translate""")

	parser.add_argument("--alistack", type=str,default='', help="""Default=None. HDF stack of volumes with alignment parameters on the header from which translations will be read and applied to --input.""")

	parser.add_argument("--alifile", type=str,default='', help=""".json file from where to read alignment parameters. Alternative to --alistack.""")

	parser.add_argument("--path",default='',type=str,help="Default=spttranslate. Name of directory where to save the output file.")

	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	
	parser.add_argument("--subset",type=int,default=0,help="""default=0 (not used). Subset of particles to process.""")
	(options, args) = parser.parse_args()	#c:this parses the options or "arguments" listed 
											#c:above so that they're accesible in the form of option.argument; 
											#c:for example, the input for --template would be accesible as options.template
		
	logger = E2init(sys.argv, options.ppid)	#c:this initiates the EMAN2 logger such that the execution
											#of the program with the specified parameters will be logged
											#(written) in the invisible file .eman2log.txt
	
	'''
	c:make a directory to store output generated by this program
	'''
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'spttranslate')

	n = EMUtil.get_image_count( options.input )
	orign = n
	print "\nnumber of particles in stack %s is %d" %(options.input,n)
	
	if options.subset:
		n = options.subset

	if options.alistack:
		n2 = EMUtil.get_image_count( options.alistack )
		if n > n2:
			print """\nERROR: there are fewer particles in --alistack, %d, than in --input, %d. 
				Use --subset and set it to a number equal to or smaller than the number or particles in --alistack""" %(n2,n)
			sys.exit(1)

	if options.alifile:
		preOrientationsDict = js_open_dict(options.alifile)

	txs=[]
	tys=[]
	tzs=[]
	trs=[]

	outstack = options.path + '/' + os.path.basename(options.input).replace('.hdf','_trans.hdf')

	for i in range(n):	
		print "\nreading particle %d" %(i)	
		a=EMData( options.input, i)
		
		ptcl = a.copy()
		
		t=None
		if options.alifile:
			ID ='subtomo_' + str(i).zfill(len(str( orign )))
			t = preOrientationsDict[ID][0]
		elif options.alistack:
			b=EMData(options.alistack,i,True)
			t = b['xform.align3d']
		
		ptcl['origin_x'] = 0
		ptcl['origin_y'] = 0
		ptcl['origin_z'] = 0
		ptcl['xform.align3d'] = Transform()
		
		if t:
			print "transform is t",t
			trans = t.get_trans()
			rot = t.get_rotation()
			
			az = rot['az']
			alt = rot['alt']
			phi = rot['phi']

			trot = Transform({'type':'eman','az':az,'alt':alt,'phi':phi})
			troti = trot.inverse()

			transi =troti*trans 	#translations are in the frame of the rotated particle.
									#to apply translations only, you need to convert them to the unrotated frame

			tx = transi[0]
			txs.append(math.fabs(tx))

			ty = transi[1]
			tys.append(math.fabs(ty))

			tz = transi[2]
			tzs.append(math.fabs(tz))

			tr=math.sqrt(tx*tx+ty*ty+tz*tz)
			trs.append(tr)

			newt = Transform({'type':'eman','tx':tx,'ty':ty,'tz':tz})
			print "new transform is", newt

			ptcl.transform(newt)
			ptcl['xform.align3d'] = newt
			#if options.saveali:
			print "\nsaving translated particle",i
			ptcl.write_image( outstack, i )
		
	
	outavg = options.path + '/' + os.path.basename(options.input).replace('.hdf','_trans_avg.hdf')
	cmd = 'e2proc3d.py ' + outstack + ' ' + outavg + ' --average'
	cmd += ' && e2proc3d.py ' + outavg + ' ' + outavg + ' --process normalize.edgemean'	
	os.system( cmd )

	if options.alifile:
		preOrientationsDict.close()			
	
	from e2spt_classaverage import textwriter

	if txs:
		txs.sort()
		textwriter(txs,options,'x_trans.txt')

	if tys:
		tys.sort()
		textwriter(tys,options,'y_trans.txt')

	if tzs:
		tzs.sort()
		textwriter(tzs,options,'z_trans.txt')
	
	if trs:
		trs.sort()
		textwriter(trs,options,'r_trans.txt')


	E2end(logger)
	
	return 
Beispiel #23
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] 
	This program takes aligned stacks produced by e2spt_classaverage.py and raw tomograms
	to recompute averages with different options (such as extracting recentered particles,
	and possibly with a larger or smaller boxisze).
	All the necessary files (aligned stacks in HDF format and raw tomograms in MRC format 
	ending in .rec, as produced by IMOD) should be in the running directory.
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--stacks",
        default='',
        type=str,
        help="""Comma separated list of HDF image stacks to process.""")

    parser.add_argument(
        "--tomograms",
        default='',
        type=str,
        help=
        """Comma separated list of tomograms with REC extension from which all particles in --stacks came from."""
    )

    #parser.add_argument("--output", default="avg.hdf",type=str, help="The name of the output average volume.")
    #parser.add_argument("--rotationtype", default="eman",type=str, help="Valid options are: eman,imagic,mrc,spider,quaternion,sgirot,spi,xyz")

    #parser.add_argument("--averager",type=str,help="The type of averager used to produce the class average. Default=mean",default="mean")

    parser.add_argument(
        "--sym",
        type=str,
        default='',
        help=
        "Symmetry to impose - choices are: c<n>, d<n>, h<n>, tet, oct, icos")

    parser.add_argument(
        "--path",
        default='',
        type=str,
        help="Name of directory where to save the output file.")
    #parser.add_argument("--alifile",default='',type=str,help=".json file with alingment parameters, if raw stack supplied via --input.")

    parser.add_argument(
        "--boxsize",
        "-B",
        type=int,
        default=0,
        help=
        """Default=0 (option not used). Provide a value for the boxsize of the output average in pixels. If not provided, the boxsize of --stacks will be used."""
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default='normalize.edgemean',
        help=
        """Normalization processor applied to particles before extraction. Default=normalize.edgemean. If using the latter, you must provide --masknorm, otherwise, a default --masknorm=mask.sharp:outer_radius=-2 will be used."""
    )

    parser.add_argument(
        "--threshold",
        type=str,
        help=
        """Threshold processor to apply to particles before writing them out to get rid of too high and/or too low pixel values.""",
        default='')

    parser.add_argument(
        "--usetomograms",
        action='store_true',
        default=False,
        help=""""Re-extract particles from the original tomogram.""")

    parser.add_argument(
        "--useinverseali",
        action='store_true',
        default=False,
        help=
        """"Use the inverse of the value stored in xform.align3d in the header of each particle."""
    )

    parser.add_argument(
        '--shrink',
        type=int,
        default=1,
        help=
        """Shrink factor to shrink particles before averaging. Default=1, which means no shrinking."""
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        help=
        """Lowpass filtering processor to apply to particles before averaging. Default=None.""",
        default='')

    parser.add_argument(
        "--preprocess",
        type=str,
        help=
        """A processor (as in e2proc3d.py) to be applied to the tomogram before opening it. \nFor example, a specific filter with specific parameters you might like. \nType 'e2proc3d.py --processors' at the commandline to see a list of the available processors and their usage""",
        default=None)

    parser.add_argument(
        '--invert',
        action="store_true",
        default=False,
        help=
        '''Default=False. This parameer indicates you want the contrast to me inverted while boxing, AND for the extracted sub-volumes. Remember that EMAN2 **MUST** work with "white" protein. You can very easily figure out what the original color\nof the protein is in your data by looking at the gold fiducials or the edge of the carbon hole in your tomogram. If they look black you MUST specify this option'''
    )

    parser.add_argument(
        "--averager",
        type=str,
        help=
        """The type of averager used to produce the class average. Default=mean.tomo""",
        default='mean.tomo')

    parser.add_argument(
        "--keep",
        type=float,
        help="""The fraction of particles to keep in each class. Default=1.0""",
        default=1.0)

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )

    #parser.add_argument("--saveali",action="store_true", default=False,help="""If set, will save the
    #	aligned particle volumes in class_ptcl.hdf. Overwrites existing file.""")

    (options, args) = parser.parse_args()

    from e2spt_classaverage import sptOptionsParser
    options = sptOptionsParser(options)
    '''
	if options.normproc: 
		options.normproc=parsemodopt(options.normproc)
		
	if options.threshold: 
		options.threshold=parsemodopt(options.threshold)
		
	if options.lowpass: 
		options.lowpass=parsemodopt(options.lowpass)
	
	if options.preprocess: 
		options.preprocess=parsemodopt(options.preprocess)
		
	if options.averager: 
		options.averager=parsemodopt(options.averager)
	'''

    #if not options.boxsize:
    #	print "\n(e2spt_recompute.py) (main) ERROR: Boxsize must be greater than zero. It is:", options.boxsize
    #	sys.exit()

    logid = E2init(sys.argv, options.ppid)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'sptrecompute')

    c = os.getcwd()  #Get current directory

    findir = os.listdir(c)  #Get list of files in current directory

    stacks = set([])  #Make list set to store particle stacks
    if options.stacks:
        stacks = set(options.stacks.split(','))

        if not options.boxsize:
            boxesdict = {}
            boxes = []
            for sta in stacks:
                box = EMData(sta, 0)['nx']
                boxesdict.update({sta: box})
                boxes.append(box)
            boxes = set(boxes)
            if len(boxes) > 1:
                print "ERROR: Your stacks are not all the same boxsize. There are %d many different boxsizes" % (
                    len(boxes))
                print "which are", boxes
                print "all input stacks in --stacks must have the same boxsize; otherwise, specify a unique boxsize through --boxsize."
                sys.exit()
    else:
        for f in findir:
            if '.hdf' in f:
                stacks.add(f)

    tomograms = set([])
    tomogramsbases = set([])
    if options.usetomograms:  #Make list set to store tomograms
        if options.tomograms:
            tomograms = set(options.tomograms.split(','))
            for tom in tomograms:
                tombase = os.path.basename(tom)
                tomogramsbases.append(tombase)

        else:
            for f in findir:
                if '.rec' in f:
                    tomograms.add(f)

    for stack in stacks:  #Loop over stacks
        n = EMUtil.get_image_count(
            stack)  #Determine number of particles in stack
        avgr = Averagers.get(options.averager[0],
                             options.averager[1])  #initialize averager

        print "\n(e2spt_recompute.py) (main) Processing stack", stack

        for i in range(n):  #Loop over particles in stack
            hdr = EMData(stack, i,
                         True)  #Load particle header by providing 'True' flag

            a = None

            box = hdr['nx']
            if options.boxsize:
                box = options.boxsize

            if options.usetomograms and tomograms:
                tomogram = hdr[
                    'ptcl_source_image']  #Determine what tomogram a particle comes from
                if tomogram not in tomogramsbases and tomogram not in tomograms:
                    print "\n(e2spt_recompute.py) (main) ERROR: Tomogram %s not found" % (
                        tomogram)
                    sys.exit()

                print "\n(e2spt_recompute.py) (main) Processing particle %d in stack %s which should come from tomogram %s" % (
                    i, stack, tomogram)

                coords = hdr[
                    'ptcl_source_coord']  #And from what location exactly
                x = coords[0]  #Parse coordinates
                y = coords[1]
                z = coords[2]

                r = Region((2 * x - box) / 2, (2 * y - box) / 2,
                           (2 * z - box) / 2, box, box,
                           box)  #Define extraction region based on boxsize

                a = EMData()
                a.read_image(tomogram, 0, False,
                             r)  #Actually 'read'/extract particle data
                #Preprocess as needed
            else:
                a = EMData(stack, i)

            if a:
                if options.normproc:
                    a.process_inplace(options.normproc[0], options.normproc[1])

                if options.invert:
                    a.mult(-1)

                t = None
                try:
                    t = hdr[
                        'xform.align3d']  #Rotate particle into aligned orientation
                except:
                    print "WARNING: 'xform.align3d' not found in header of particle %d" % (
                        i)

                try:
                    t = hdr['sptsim_randT']
                except:
                    print "ERROR: 'sptsim_randT also not found in header or particle %d" % (
                        i)

                if t:
                    tf = t
                    if options.useinverseali:
                        tf = t.inverse()
                        print "t is", t
                        print "and its inverse is", tf

                    #print "Applied this transform",tf
                    a.transform(tf)

                    if options.threshold:
                        a.process_inplace(options.threshold[0],
                                          options.threshold[1])

                    if options.lowpass:
                        a.process_inplace(options.lowpass[0],
                                          options.lowpass[1])

                    if options.preprocess:
                        a.process_inplace(options.preprocess[0],
                                          options.preprocess[1])

                    if options.shrink and int(options.shrink) > 1:
                        shrinkfactor = options.shrink
                        a.process_inplace('math.meanshrink',
                                          {'n': shrinkfactor})

                    #a['origin_x'] = 0
                    #a['origin_y'] = 0
                    #a['origin_z'] = 0

                    #a['ptcl_source_image'] = hdr['ptcl_source_image']
                    #a['ptcl_source_coord'] = hdr['ptcl_source_coord']

                    avgr.add_image(a)
                else:
                    print "skipping particle", i

        avg = avgr.finish()

        avg.process_inplace('normalize')

        if options.sym and not breaksym:
            avg.process_inplace('xform.applysym', {'sym': options.sym})

        outname = options.path + '/' + stack.replace('.hdf', '_AVG.hdf')
        avg.write_image(outname, 0)

    E2end(logid)

    return
Beispiel #24
0
def main():

	usage = """Program to generate a cylindrical mask. It can also create a cylindrical shell if
			you specify the --height_inner and --radius_inner parameters, in addition to the
			required outer --height and --radius.
			"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)	
	
	parser.add_argument("--path",type=str,default=None,help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'cylmask';
		for example, cylmask_02 will be the directory by default if 'cylmask_01' 
		already exists.""")

	parser.add_argument("--verbose", "-v", help="""verbose level [0-9], higner number means 
		higher level of verboseness. Default=0.""",dest="verbose", action="store", metavar="n",type=int, default=0)

	parser.add_argument("--ppid", type=int, help="""Set the PID of the parent process, 
		used for cross platform PPID""",default=-1)

	parser.add_argument("--height", type=int, default=0,help="""Height of the cylindrical mask.""")
	parser.add_argument("--heightinner", type=int, default=0,help="""Height for the inner boundary
		if creating a cylindrical shell mask.""")

	parser.add_argument("--radius",type=int,default=0,help="""Radius of the cylindrical mask.
		Default=boxsize/2.""")
	parser.add_argument("--radiusinner",type=int,default=0,help="""Radius for the inner boundary 
		if creating a cylindrical shell mask.
		Default=boxsize/2.""")

	parser.add_argument("--boxsize", type=int, default=0,help="""Size of the boxsize where the
		cylindrical mask will live.""")
	
	parser.add_argument("--axes",type=str,default='z',help="""Axes along which the mask will be
		oriented. Default=z. You can supply more than one, separated with commas. For example:
		--axes=x,y,z.""")
		
	parser.add_argument("--rotation",type=str,default='',help="""Three comma separated Euler angles
		 az,alt,phi, to rotate the masks by before writing them out.""")
		
	parser.add_argument("--translation",type=str,default='',help="""Three comma separated coordinates
		x,y,z, to translate the masks by before writing them out.""")
		
	parser.add_argument("--rotavg",action='store_true',default=False,help="""This will compute the rotational average of the mask(s) in addition to writing the cylindrical mask itself out.""")
	
	(options, args) = parser.parse_args()	
	
	
	if not options.boxsize:
		print "You must provide --boxsize > 4"
		sys.exit(1)
	elif options.boxsize < 5:
		print "You must provide --boxsize > 4"
		sys.exit(1)		
	
	if options.heightinner and not options.radiusinner:
		print "If specifying --heightinner, you must also specify --radiusinner."
		sys.exit(1)	
	if options.radiusinner and not options.heightinner:
		print "If specifying --radiusinner, you must also specify --heightinner."
		sys.exit(1)	
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath( options, 'cylmask')
	
	logger = E2init(sys.argv, options.ppid)
	
	axes = options.axes.split(',')
	
	print "After splitting, axes=", axes
	
	#axisdict ={}
	#for axis in axes:
	#	axisdict.update( { 'z } )
	ts = {}
	
	mask = cylinder(options)
	
	rt=Transform()
	if options.rotation or options.translation:
		az=alt=phi=xc=yc=zc=0
		if options.rotation:
			angles=options.rotation.split(',')
			az=float(angles[0])
			alt=float(angles[1])
			phi=float(angles[2])
		if options.translation:
			trans=options.translation.split(',')
			xc=float(trans[0])
			yc=float(trans[1])
			zc=float(trans[2])
		rt=Transform({'type':'eman','az':az,'alt':alt,'phi':phi,'tx':xc,'ty':yc,'tz':zc})
		mask.transform( rt )
		
	
	for axis in axes:
		print "axis is", axis
		if 'z' in axis or 'Z' in axis:
			tz = Transform({'type':'eman','az':0,'alt':0,'phi':0})
			print "added z transform"
			ts.update({'z':tz})
		if 'x' in axis or 'X' in axis:
			
			tx = Transform({'type':'eman','az':0,'alt':90,'phi':90})
			ts.update({'x':tx})
			print "added x transform"
		
		if 'y' in axis or 'Y' in axis:
			ty = Transform({'type':'eman','az':0,'alt':90,'phi':0})
			ts.update({'y':ty})
			print "added y transform"
	
	masknamebase = options.path + '/cylmask.hdf'
	
	for a in ts:
		maskt = mask.copy()
		tag = 'R'+str( options.radius ).zfill( len( str( options.radius))) + 'H'+str( options.height ).zfill( len( str( options.radius)))
		if options.radiusinner:
			tag+='RI'+str( options.radiusinner ).zfill( len( str( options.radius))) 
		if options.heightinner:
			 'HI'+str( options.height ).zfill( len( str( options.radius)))
		
		if a == 'z':
			maskz=mask.copy()
			maskname=masknamebase.replace('.hdf','_Z_') + tag + '.hdf'
			maskz.transform( ts[a] )
			maskz.write_image( maskname, 0 )
			
			if options.rotavg:
				rotavgname = maskname.replace('.','_ROTAVG.')
				maskzrotavg = maskz.rotavg_i()
				maskzrotavg.write_image( rotavgname , 0 )
				
		if a == 'x':
			maskx=mask.copy()
			maskx.transform( ts[a] )
			maskname=masknamebase.replace('.hdf','_X_') + tag + '.hdf'
			maskx.write_image( maskname, 0 )
			
			if options.rotavg:
				rotavgname = maskname.replace('.','_ROTAVG.')
				maskxrotavg = maskx.rotavg_i()
				maskxrotavg.write_image( rotavgname , 0 )
		
		if a == 'y':
			masky=mask.copy()
			masky.transform( ts[a] )
			maskname=masknamebase.replace('.hdf','_Y_') + tag + '.hdf'	
			masky.write_image( maskname, 0 )

			if options.rotavg:
				rotavgname = maskname.replace('.','_ROTAVG.')
				maskyrotavg = masky.rotavg_i()
		
				maskyrotavg.write_image( rotavgname , 0 )
	
	E2end(logger)
	return
Beispiel #25
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog <output> [options]

	This program is used to preprocess subtomograms before aligning them. The same can be accomplished with 
	e2proc3d, except that this program is parallelized and thus should be substantially faster for large subtomograms.
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--input",
        type=str,
        default='',
        help=
        """Default=None. The name of the input volume stack. MUST be HDF since volume stack support is required."""
    )

    parser.add_argument(
        "--output",
        type=str,
        default='',
        help=
        """Default=None. Specific name of HDF file to write processed particles to."""
    )

    parser.add_argument(
        "--parallel",
        type=str,
        default='',
        help=
        """default=None. Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel"""
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help=
        """Default=-1. Set the PID of the parent process, used for cross platform PPID""",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        """Default=0. Verbose level [0-9], higner number means higher level of verboseness"""
    )

    parser.add_argument(
        "--subset",
        type=int,
        default=0,
        help=
        """Default=0 (not used). Refine only this substet of particles from the stack provided through --input"""
    )

    parser.add_argument(
        "--apix",
        type=float,
        default=0.0,
        help=
        """Default=0.0 (not used). Use this apix value where relevant instead of whatever is in the header of the reference and the particles. Will overwrite particle header as well."""
    )

    parser.add_argument(
        "--shrink",
        type=int,
        default=0,
        help=
        """Default=0 (no shrinking). Optionally shrink the input volumes by an integer amount for coarse alignment."""
    )

    parser.add_argument(
        "--threshold",
        type=str,
        default='',
        help=
        """Default=None. A threshold applied to the subvolumes after normalization. For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score."""
    )

    parser.add_argument(
        "--mask",
        type=str,
        default='',
        help=
        """Default=None. Masking processor applied to particles before alignment. IF using --clip, make sure to express outer mask radii as negative pixels from the edge."""
    )

    parser.add_argument(
        "--maskfile",
        type=str,
        default='',
        help=
        """Default=None. Mask file (3D IMAGE) applied to particles before alignment. Must be in HDF format. Default is None."""
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default='',
        help=
        """Default=None (see 'e2help.py processors -v 10' at the command line). Normalization processor applied to particles before alignment. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'"""
    )

    parser.add_argument(
        "--preprocess",
        type=str,
        default='',
        help=
        """Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging."""
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        default='',
        help=
        """Default=None. A lowpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging."""
    )

    parser.add_argument(
        "--highpass",
        type=str,
        default='',
        help=
        """Default=None. A highpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging."""
    )

    parser.add_argument(
        "--clip",
        type=int,
        default=0,
        help=
        """Default=0 (which means it's not used). Boxsize to clip particles. For example, the boxsize of the particles might be 100 pixels, but the particles are only 50 pixels in diameter. Aliasing effects are not always as deleterious for all specimens, and sometimes 2x padding isn't necessary."""
    )

    parser.add_argument(
        "--nopath",
        action='store_true',
        default=False,
        help=
        """If supplied, this option will save results in the directory where the command is run. A directory to store the results will not be made."""
    )

    parser.add_argument(
        "--path",
        type=str,
        default='sptpreproc',
        help=
        """Default=spt. Directory to store results in. The default is a numbered series of directories containing the prefix 'sptpreproc'; for example, sptpreproc_02 will be the directory by default if 'sptpreproc_01' already exists."""
    )

    (options, args) = parser.parse_args()

    logger = E2init(sys.argv, options.ppid)
    print "\n(e2spt_preproc)(main) started log"

    from e2spt_classaverage import sptmakepath

    if options.path and not options.nopath:

        options = sptmakepath(options, 'sptpreproc')

    if options.parallel == 'None' or options.parallel == 'none':
        options.parallel = None

    if not options.input:
        try:
            options.input = sys.argv[1]
        except:
            print "\n(e2spt_preproc)(main) ERROR: invalid input file"

    if options.mask or options.maskfile or options.threshold or options.clip or options.threshold or options.normproc or options.preprocess or options.lowpass or options.highpass or int(
            options.shrink) > 1:

        preprocstack = str(
            os.path.basename(options.input).replace('.hdf', '_preproc.hdf'))

        if options.path and not options.nopath:
            preprocstack = options.path + '/' + preprocstack

        if options.output:
            if '.hdf' in options.output[-4:]:
                preprocstack = options.output
            else:
                print "\n(e2spt_preproc)(main) ERROR: '.hdf' must be the last four characters of the output filename."

        print "\n(e2spt_preproc)(main) output stack will be %s" % (
            preprocstack)

        n = 0
        try:
            n = EMUtil.get_image_count(options.input)
        except:
            print "\n(e2spt_preproc)(main) ERROR: --input stack seems to be invalid"
            sys.exit()

        print "\n(e2spt_preproc)(main) number of particles is %d" % (n)

        c = os.getcwd()

        findir = os.listdir(c)

        if preprocstack not in findir:

            dimg = EMData(8, 8, 8)
            dimg.to_one()

            for i in range(n):
                dimg.write_image(preprocstack, i)

        else:
            print "\n(e2spt_preproc)(main) WARNING: a file with the name of the output stack %s is already in the current directory and will be DELETED" % (
                preprocstack)
            os.remove(preprocstack)

            dimg = EMData(8, 8, 8)
            dimg.to_one()

            for i in range(n):
                dimg.write_image(preprocstack, i)

        finalbox = EMData(options.input, 0, True)['nx']
        if options.clip:
            finalbox = options.clip

        #dimglarge=EMData(finalbox,finalbox,finalbox)
        #dimglarge.to_one()
        #dimglarge.write_image(preprocstack,0)
        #n=EMUtil.get_image_count(options.input)
        #if options.subset:
        #	n=options.subset
        #dimglarge.write_image(preprocstack,n-1)

        if options.verbose:
            print "\n(e2spt_preproc)(main) wrote dummy ptcls to %s" % (
                preprocstack)

        print "\n(e2spt_preproc)(main) - INITIALIZING PARALLELISM!\n"

        if options.parallel:
            from EMAN2PAR import EMTaskCustomer
            etc = EMTaskCustomer(options.parallel)
            pclist = [options.input]

            etc.precache(pclist)
            print "\n(e2spt_preproc)(main) - precaching --input"

            tasks = []
            results = []

        from e2spt_classaverage import sptOptionsParser
        options = sptOptionsParser(options)

        for j in range(n):
            #print "processing  particle", j

            img = EMData(options.input, j)

            if options.parallel:
                #task = Preproc3DTask( ["cache",options.input,j], options, j, preprocstack )
                task = Preproc3DTask(img, options, j, preprocstack)
                tasks.append(task)

            else:
                img = EMData(options.input, j)
                pimg = preprocfunc(img, options, j, preprocstack)

        if options.parallel and tasks:
            tids = etc.send_tasks(tasks)
            if options.verbose:
                print "\n(e2spt_preproc)(main) preprocessing %d tasks queued" % (
                    len(tids))

            results = get_results(etc, tids, options)
        #print "\n(e2spt_preproc)(main) preprocessing results are", results

        #print "\n(e2spt_preproc)(main) input changing to preprocstack"
        #options.input = preprocstack

        #cache needs to be reloaded with the new options.input

    else:
        print "\n(e2spt_preproc)(main) Nothing to do. No preprocessing parameters specified."

    E2end(logger)

    return
Beispiel #26
0
def main():

    progname = os.path.basename(sys.argv[0])
    usage = """Program for individual subtomogram refinement (ISR) based on subtiltseries
	for each subtomogram extracted with e2spt_subtilt.py."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--input",
        type=str,
        default="",
        help="""Comma separated files in .ali, .st .hdf format of the aligned subtiltseries.""",
    )

    parser.add_argument(
        "--inputstem",
        type=str,
        default="",
        help="""Alternative to supplying --input. This is a string common to multiple files to be processed in the CURERENT directory. The common string doesn't need to be at a particular location in the filenames. For example, a series of files "tiltA.hdf, tiltB.hdf, tiltC.hdf" could have either 'hdf', '.hdf', 't,','ti', 'til', 'tilt', etc., as a common string. The key is to choose a string shared ONLY by the files of interest. The files should be multiple subtiltseries in .hdf format; each file should correspond to an individual subtiltseries for a different particle: That is, each file should be a subtiltseries corresponding to an individual subtomogram, as extracted by e2spt_subtilt.py, or as simulated by e2spt_simulation.py""",
    )

    parser.add_argument(
        "--inputdir",
        type=str,
        default="",
        help="""Alternative to --input and --inputstem. Path to a directory containing individual subtiltseries stacks.""",
    )

    parser.add_argument(
        "--path",
        type=str,
        default="",
        help="Directory to store results in. The default is a numbered series of directories containing the prefix 'sptisr'; for example, sptisr02 will be the directory by default if 'sptisr_01' already exists.",
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help="Default=1. Set the PID of the parent process, used for cross platform PPID",
        default=-1,
    )

    parser.add_argument(
        "--verbose",
        "-v",
        type=int,
        default=0,
        help="Default 0. Verbose level [0-9], higner number means higher level of verboseness",
        dest="verbose",
        action="store",
        metavar="n",
    )

    parser.add_argument(
        "--reconstructor",
        type=str,
        default="fourier:mode=gauss_2",
        help="""Default=fourier:mode=gauss_2. The reconstructor to use to reconstruct the tilt series into a tomogram. Type 'e2help.py reconstructors' at the command line to see all options and parameters available. To specify the interpolation scheme for the fourier reconstructor, specify 'mode'. Options are 'nearest_neighbor', 'gauss_2', 'gauss_3', 'gauss_5'. For example --reconstructor=fourier:mode=gauss_5 """,
    )

    parser.add_argument("--iter", type=int, default=1, help="""Number of iterations to run algorithm for.""")

    parser.add_argument(
        "--tltfile",
        type=str,
        default="",
        help="""IMOD-like .tlt file with tilt angles for the aligned tiltseries (or set of subtiltseries).""",
    )

    parser.add_argument(
        "--tiltaxis",
        type=str,
        default="y",
        help="""Axis to produce projections about. Default is 'y'; the only other valid option is 'x'.""",
    )

    parser.add_argument(
        "--pad2d",
        type=float,
        default=0.0,
        help="""Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the 2d images in the tilt series for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though).""",
    )

    parser.add_argument(
        "--pad3d",
        type=float,
        default=0.0,
        help="""Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the volumes for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though).""",
    )

    parser.add_argument(
        "--savevols",
        action="store_true",
        default=False,
        help="""This option will save the reconstructed volumes at each iteration.""",
    )

    parser.add_argument(
        "--outxsize",
        type=int,
        default=0,
        help="""Clip the output volume in x to this size. The default size is the nx size of the input images.""",
    )

    parser.add_argument(
        "--outysize",
        type=int,
        default=0,
        help="""Clip the output volume in y to this size. The default size is the ny size of the input images.""",
    )

    parser.add_argument(
        "--outzsize",
        type=int,
        default=0,
        help="""Clip the output volume in z to this size. The default size is the nx size of the input images.""",
    )

    parser.add_argument(
        "--mask",
        type=str,
        help="""Default=None. Masking processor (see e2help.py --verbose=10) applied to the images to aid alignment. Default=None.""",
    )

    parser.add_argument(
        "--preprocess",
        type=str,
        help="""Default=None. Any processor (see e2help.py --verbose=10) applied to the images to aid alignment.""",
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        default="",
        help="""Default=None. A lowpass filtering processor (see e2help.py --verbose=10) applied to each volume prior to reprojection generation..""",
    )

    parser.add_argument(
        "--highpass",
        type=str,
        default="",
        help="""Default=None. A highpass filtering processor (see e2help.py --verbose=10) applied to each volume prior to reprojection generation.""",
    )

    parser.add_argument(
        "--threshold",
        type=str,
        default="",
        help="""Default=None. A threshold  processor (see e2help.py --verbose=10) applied to each volume prior to reprojection generation.""",
    )

    parser.add_argument(
        "--saveali",
        action="store_true",
        default=False,
        help="""Default=False. If set, will save the recentered subtiltseries after each iteration.""",
    )

    (options, args) = parser.parse_args()

    logger = E2init(sys.argv, options.ppid)

    if not options.input and not options.inputdir and not options.inputstem:
        print "ERROR: Either of the following required: --input, --inputstemp, --inputdir"
        sys.exit()

    if options.input and options.inputstem:
        print "ERROR: Cannot provide --input and --inputstem simultaneously"
        sys.exit()

    if options.inputstem and options.inputdir:
        print "ERROR: Cannot provide --inputstem and --inputdir simultaneously"
        sys.exit()

    if options.input and options.inputdir:
        print "ERROR: Cannot provide --input and --inputdir simultaneously"
        sys.exit()

    from e2spt_classaverage import sptOptionsParser

    options = sptOptionsParser(options)
    # print "Options have been parsed, for example, mask is", options.mask, type(options.mask), len(options.mask)

    from e2spt_classaverage import sptmakepath

    options = sptmakepath(options, "sptisr")

    originalpath = options.path

    if options.verbose > 9:
        print "\n(e2spt_isr.py) I've read the options"

    inputfiles = {}  # C:Figure out whether there's a single HDF stack to process,
    # C:or a directory with many HDF stacks
    c = os.getcwd()

    if options.inputdir:
        c = os.getcwd() + "/" + options.inputdir

    findir = os.listdir(c)

    if options.inputstem:
        for f in findir:
            if ".hdf" in f and options.inputstem in f:
                if options.verbose > 8:
                    print "\nFound tiltseries!", f
                inputfiles.update(
                    {f: [f, None]}
                )  # C:The input files are put into a dictionary in the format {originalseriesfile:[originalseriesfile,volumefile]}

    elif options.inputdir:
        for f in findir:
            if ".hdf" in f:
                if options.verbose > 8:
                    print "\nFound tiltseries!", f
                inputfiles.update(
                    {f: [f, None]}
                )  # C:The input files are put into a dictionary in the format {originalseriesfile:[originalseriesfile,volumefile]}

    elif options.input:
        inputfiles.update({options.input: [options.input, None]})

    tiltstep = 0
    newvol = vol = None
    newfiles = {}
    firstiterdir = originalpath

    print "\n\nThere are these many iterations", options.iter
    fstats = {}
    convergedfs = []

    fmeanscores2d = {}
    itermeanscores2d = {}

    fmeanerrors = {}
    itermeanerrors = {}

    fmeanfscs = {-1: {}}  # Compute initial FSC before any iterations of correction or alignment have occurred
    itermeanfscs = {}

    fmeanscores3d = {-1: {}}
    itermeanscores3d = {}

    errorswitch = 0

    for i in range(options.iter):  # Iterate over options.iter
        itermeanscores2d.update({i: 0})
        itermeanerrors.update({i: 0})
        itermeanfscs.update({i: 0})
        itermeanscores3d.update({i: 0})

        print "***************\nStarting iteration number", i
        print "****************"
        previouspath = ""
        if options.iter > 1:
            iterdir = "iter_" + str(i + 1).zfill(len(str(options.iter)))
            os.system(
                "mkdir " + originalpath + "/" + iterdir
            )  # C:Make a new subdirectory within options.path only if options.iter > 0
            options.path = originalpath + "/" + iterdir  # C:Update path to include the newly created subdirectory
            previouspath = originalpath + "/iter_" + str(i).zfill(len(str(options.iter)))
            if i == 0:
                firstiterdir = options.path
        kk = 0

        statsfile = options.path + "/stats.txt"

        statslines = []

        if len(convergedfs) == len(inputfiles):
            print "\nAll files have converged. Terminating. Line 193"
            break

        fmeanscores2d.update({i: {}})
        fmeanerrors.update({i: {}})
        fmeanfscs.update({i: {}})
        fmeanscores3d.update({i: {}})

        for f in inputfiles:

            fmeanscores2d[i].update({f: [0]})
            fmeanerrors[i].update({f: [0]})
            fmeanfscs[i].update({f: [0]})
            fmeanscores3d[i].update({f: [0]})  # C:Iterate over files

            # originalseries = f

            if i == 0:
                fstats.update({f: list([])})
                print "fmeanfscs is", fmeanfscs
                fmeanfscs[-1].update(
                    {f: [0]}
                )  # Compute initial FSC before any iterations of correction or alignment have occurred
                print "fmeanscores3d is", fmeanscores3d
                fmeanscores3d[-1].update({f: [0]})
                print "set initial -1 fmeanscores3d!!"

            if "converged" not in fstats[f]:

                if i == 0:
                    if options.tltfile:
                        originalangles = getangles(options)  # C:Read angles from tlt file if available
                    else:
                        originalangles = calcangles(
                            f
                        )  # C:Get the angles of the actual data tilts from the header or calculate from input parameters

                stackfile = options.path + "/" + os.path.basename(f).replace(".hdf", "_ISR.hdf")

                print "\nWill refine center for file", f
                if i == 0:
                    hdr = EMData(
                        f, 0, True
                    )  # See if angles are in the header of the data, for each file; if not, write them
                    # print "\nRead header and its type", hdr, type(hdr)
                    # print "\nAnd the dictionary", hdr.get_attr_dict()
                    size = hdr["nx"]

                    aux = 0
                    if "spt_tiltangle" not in hdr.get_attr_dict():
                        print "\nspt_tiltangle not in header, therefore will write it by calling writeparamtoheader"
                        aux = writeparamtoheader(f, originalangles, "spt_tiltangle")
                        print "\naux returned is", aux
                    else:
                        aux = 1

                    if (
                        "sptisrtx" not in hdr.get_attr_dict()
                        or "sptisrty" not in hdr.get_attr_dict()
                        or "sptisrdr" not in hdr.get_attr_dict()
                    ):
                        tvals = [0.0 for tt in range(len(originalangles))]

                        auxx = auxy = auxr = 0
                        if "sptisrtx" not in hdr.get_attr_dict():
                            print "\nsptisrtx not in header, therefore will write it by calling writeparamtoheader"
                            auxx = writeparamtoheader(f, tvals, "sptisrtx")
                        else:
                            auxx = 1

                        if "sptisrty" not in hdr.get_attr_dict():
                            print "\nsptisrty not in header, therefore will write it by calling writeparamtoheader"
                            auxy = writeparamtoheader(f, tvals, "sptisrty")
                        else:
                            auxy = 1

                        if "sptisrdr" not in hdr.get_attr_dict():
                            print "\nsptisrdr not in header, therefore will write it by calling writeparamtoheader"
                            auxr = writeparamtoheader(f, tvals, "sptisrdr")
                        else:
                            auxr = 1

                        if auxx and auxy and auxr:
                            aux = 1
                    else:
                        aux = 1

                    if aux:
                        series = {}
                        nimgs = EMUtil.get_image_count(f)
                        for ii in range(nimgs):
                            img = EMData(f, ii)
                            try:
                                angle = img["spt_tiltangle"]
                                series.update({angle: img})
                            except:
                                print "ERROR: spt_tiltangle not found in image", ii
                                print "\nHeader is", img.get_attr_dict()
                                sys.exit()

                        retm = makevol(
                            options, f, series, i, originalangles, size, writevols=1, initialfsc=1
                        )  # C:In the first iteration, first reconstruct the tilt series into a 3D volume

                        vol = retm[0]
                        # newvolfile = retm[1]

                        fscarea = retm[2]
                        score3d = retm[3]

                        # fsc = retm[3]
                        # initialfscfilename = options.path + '/' + os.path.basename( f ).replace('.hdf', '_initial_evenOddFSC.txt')

                        fmeanfscs[-1][f].append(fscarea)
                        fmeanscores3d[-1][f].append(score3d)

                        print "\nVol and its type are", vol, type(vol)
                    else:
                        print "ERROR: Something went wrong. spt_tiltangle found in image headers, but somehow is unusuable"
                        sys.exit()

                elif i > 0:
                    # vol = EMData( inputfiles[f][1] )	#C:For iterations > 0 (after the first iteration), the updated volumes
                    # C:for each tilt series should exist from the previous iteration

                    # previousstackfile = previouspath + '/' + os.path.basename(f).replace('.hdf','_IPET.hdf')

                    # print "\n\n\previousstackfile is", previousstackfile
                    # vol = EMData( previousstackfile, 0 )

                    vol = newvol

                    # C:Make reprojections from all known angles
                reprojections = reprojectvolume(options, vol, f, originalangles)

                originalsize = vol["nx"]
                retrct = recentertilts(options, reprojections, f, originalangles, i)
                newseries = retrct[0]
                statsline = retrct[1]
                fscores2d = retrct[2]
                ferrors = retrct[3]

                if ferrors:
                    errorswitch = 1

                    # print "fscores2d received", fscores2d
                    # print "ferrors received", ferrors
                if ferrors == fscores2d:
                    print "ERROR: errors and scores2d are the same"
                    sys.exit()

                fmeanscore2d = sum(fscores2d) / len(fscores2d)
                fmeanscores2d[i][f].append(fmeanscore2d)

                if ferrors and errorswitch:
                    fmeanerror = sum(ferrors) / len(ferrors)
                    fmeanerrors[i][f].append(fmeanerror)

                    # fmeanscores2d.update( i:{ f:fmeanscore2d } )

                statslines.append(statsline)

                line2append = statsline

                # print "fstats[f] and type are", fstats[f], type(fstats[f])
                # sys.exit()
                if statsline in fstats[f]:
                    line2append = "converged"
                    convergedfs.append(f)

                fstats[f].append(line2append)

                fstats.update({f: fstats[f]})

                retmkvol = makevol(options, f, newseries, i, originalangles, originalsize, writevols=1)

                newvol = retmkvol[0]
                newvolfile = retmkvol[1]

                fscarea = retmkvol[2]
                fmeanfscs[i][f].append(fscarea)

                fmeanscore3d = retmkvol[3]
                fmeanscores3d[i][f].append(fmeanscore3d)

                if i == 0:
                    pass
                    # print "\nEEEEEEEEEEEEEEE\n\n\n\n\nNewvolfile returned is", newvolfile

                newfiles.update({f: [newseries, newvolfile]})
                # newvol.write_image( stackfile, 0 )

                kk += 1

                # firstrawvolfile = firstiterdir + '/' + os.path.basename(f).replace('.hdf','_3D.hdf')
                # fscfile = options.path + '/' + os.path.basename(f).replace('.hdf','FSC.txt')
                # cmdfsc = 'e2proc3d.py ' + firstrawvolfile + ' ' + fscfile + ' --calcfsc=' + newvolfile
                # os.popen( cmdfsc )
            else:
                statsline = fstats[f][-2]
                statslines.append(statsline)

                # Write mean tx, ty and dr of all files to a text file, for each iteration
        f = open(statsfile, "w")
        f.writelines(statslines)
        f.close()

        inputfiles = newfiles

        iterscores2d = []
        # print "in iteration", i
        # print "fmeanscores2d are",fmeanscores2d
        for ff in fmeanscores2d[i]:
            # print "therefore ff in fmeanscores2d[i] is", ff
            iterscores2d.append(fmeanscores2d[i][ff][-1])

        itermeanscore2d = sum(iterscores2d) / len(iterscores2d)
        itermeanscores2d[i] = itermeanscore2d

        ys = []
        lines = []
        for s in itermeanscores2d:
            y = itermeanscores2d[s]
            ys.append(y)
            # print "appending this y", itermeanscores2d[s]
            line = str(s) + "\t" + str(y) + "\n"
            lines.append(line)

            # if plots:
        fs = open(options.path + "/scores2d_" + str(i + 1) + ".txt", "w")
        fs.writelines(lines)
        fs.close()

        try:
            if errorswitch:
                itererrors = []
                # print "in iteration", i
                # print "fmeanerrors are",fmeanerrors
                for fscores2df in fmeanerrors[i]:
                    # print "therefore ff in fmeanerrors[i] is", ff
                    itererrors.append(fmeanerrors[i][ff][-1])

                itermeanerror = sum(itererrors) / len(itererrors)
                itermeanerrors[i] = itermeanerror

                yse = []
                linese = []
                for s in itermeanerrors:
                    ye = itermeanerrors[s]
                    yse.append(ye)
                    # print "appending this error", itermeanerrors[s]
                    linee = str(s) + "\t" + str(ye) + "\n"
                    linese.append(linee)

                    # if plots:
                fse = open(options.path + "/error_" + str(i + 1) + ".txt", "w")
                fse.writelines(linese)
                fse.close()
        except:
            pass

        if i == 0:
            iterfscs = []
            # print "in iteration", i
            # print "APPENDING INITIAL fmeanfscs are", fmeanfscs
            for ff in fmeanfscs[-1]:
                # print "therefore INITIAL ff in fmeanfscs[-1] are", ff
                iterfscs.append(fmeanfscs[-1][ff][-1])

            itermeanfsc = sum(iterfscs) / len(iterfscs)
            itermeanfscs[-1] = itermeanfsc

            ysf = []
            linesf = []
            for s in [-1, 0]:
                yf = itermeanfscs[s]
                ysf.append(yf)
                # print "for s", s
                # print "appending this fscarea", itermeanfscs[s]
                linef = str(s + 1) + "\t" + str(yf) + "\n"
                linesf.append(linef)

                # if plots:
            fsf = open(options.path + "/fscsareas_" + str(i + 1) + ".txt", "w")
            fsf.writelines(linesf)
            fsf.close()

            iterscores3d = []
            # print "in iteration", i
            # print "fmeanscores2d are",fmeanscores2d
            for ff in fmeanscores3d[-1]:
                # print "therefore ff in fmeanscores2d[i] is", ff
                iterscores3d.append(fmeanscores3d[-1][ff][-1])

            itermeanscore3d = sum(iterscores3d) / len(iterscores3d)
            itermeanscores3d[-1] = itermeanscore3d

            ys3 = []
            lines3 = []
            for s in [-1, 0]:
                y3 = itermeanscores3d[s]
                ys3.append(y)
                # print "appending this y", itermeanscores2d[s]
                line3 = str(s + 1) + "\t" + str(y3) + "\n"
                lines3.append(line3)

                # if plots:
            fs = open(options.path + "/scores3d_" + str(i + 1) + ".txt", "w")
            fs.writelines(lines3)
            fs.close()

        iterfscs = []
        # print "in iteration", i
        # print "fmeanfscs are",fmeanfscs
        for ff in fmeanfscs[i]:
            # print "therefore ff in fmeanfscs[i] are", ff
            iterfscs.append(fmeanfscs[i][ff][-1])

        itermeanfsc = sum(iterfscs) / len(iterfscs)
        itermeanfscs[i] = itermeanfsc

        ysf = []
        linesf = []
        fscsindxs = [s for s in itermeanfscs]
        fscsindxs.sort()
        for s in fscsindxs:
            yf = itermeanfscs[s]
            ysf.append(yf)
            # print "for s", s
            # print "appending this fscarea", itermeanfscs[s]
            linef = str(s + 1) + "\t" + str(yf) + "\n"
            linesf.append(linef)

            # if plots:
        fsf = open(options.path + "/fscsareas_" + str(i + 1) + ".txt", "w")
        fsf.writelines(linesf)
        fsf.close()

        iterscores3d = []
        # print "in iteration", i
        # print "fmeanscores2d are",fmeanscores2d
        for ff in fmeanscores3d[i]:
            # print "therefore ff in fmeanscores2d[i] is", ff
            iterscores3d.append(fmeanscores3d[i][ff][-1])

        itermeanscore3d = sum(iterscores3d) / len(iterscores3d)
        itermeanscores3d[i] = itermeanscore3d

        ys3 = []
        lines3 = []
        score3dindxs = [s for s in itermeanscores3d]
        score3dindxs.sort()

        for s in score3dindxs:
            y3 = itermeanscores3d[s]
            ys3.append(y)
            # print "appending this y", itermeanscores2d[s]
            line3 = str(s + 1) + "\t" + str(y3) + "\n"
            lines3.append(line3)

            # if plots:
        fs = open(options.path + "/scores3d_" + str(i + 1) + ".txt", "w")
        fs.writelines(lines3)
        fs.close()

        if i > 0:
            if itermeanscores2d[i] == itermeanscores2d[i - 1]:
                print "The meanscore2d for two consecutive iterations is the same, suggesting the algorithm has converged."
                sys.exit()

            try:
                if itermeanerrors[i] == itermeanerrors[i - 1]:
                    print "The meanerror for two consecutive iterations is the same, suggesting the algorithm has converged."
                    sys.exit()
            except:
                pass

            if itermeanfscs[i] == itermeanfscs[i - 1]:
                print "The fscsarea for two consecutive iterations is the same, suggesting the algorithm has converged."
                sys.exit()

            if itermeanscores3d[i] == itermeanscores3d[i - 1]:
                print "The meanscore3d for two consecutive iterations is the same, suggesting the algorithm has converged."
                sys.exit()

            difscore = math.fabs(float(itermeanscores2d[i]) - float(itermeanscores2d[i - 1]))
            if float(difscore) < 0.000001:
                print "In iter %d/%d global score difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                    i + 1,
                    options.iter,
                    difscore,
                )
                sys.exit()

            try:
                diferror = math.fabs(float(itermeanerrors[i]) - float(itermeanerrors[i - 1]))
                if float(difscore) < 0.000001:
                    print "In iter %d/%d global error difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                        i + 1,
                        options.iter,
                        diferror,
                    )
                    sys.exit()
            except:
                pass

            diffscarea = math.fabs(float(itermeanfscs[i]) - float(itermeanfscs[i - 1]))
            if float(difscore) < 0.000001:
                print "In iter %d/%d global fscarea difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                    i + 1,
                    options.iter,
                    diffscarea,
                )
                sys.exit()

            difscore3d = math.fabs(float(itermeanscores3d[i]) - float(itermeanscores3d[i - 1]))
            if float(difscore3d) < 0.000001:
                print "In iter %d/%d global score3dipetResult difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                    i + 1,
                    options.iter,
                    difscore,
                )
                sys.exit()

    E2end(logger)

    return ()
Beispiel #27
0
def main():
	
	progname = os.path.basename(sys.argv[0])
	usage = """Calculates, plots and optionally averages the FSC between multiple images and a reference."""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--input", type=str, help="""Volume or stack of volumes to be compared to --ref""", default=None)
	parser.add_argument("--path", type=str, help="Results directory. If not specified, defaults to e2sptfscs/", default='e2sptfscs')

	parser.add_argument("--ref", type=str, help="Volume that will be 'static' (the 'reference' to which volumes in --input will be aligned to). The format MUST be '.hdf' or '.mrc' ", default=None)
	#parser.add_argument("--output", type=str, help="""Name for the .txt file that will contain the FSC data. If not specified, a default name will be used.""", default=None)


	#parser.add_argument("--symali", type=str, default='c1', help = """Will pass the value to --sym for alignment with e2spt_classaverage.py""")

	parser.add_argument("--nocolor",action='store_true',default=False,help="""Turns the ouput png(s) into grey scale figures. Instead of using different colors to distinguish between various curves on the same plot, this option will have the program automatically use different markers in black and white for each curve.""")
	
	parser.add_argument("--sym", type=str, default='c1', help = """Will symmetrize --ref and --input prior to FSC computation.""")
	
	#parser.add_argument("--maskali",type=str,help="""Mask processor applied to particles 
	#	before alignment. Default is mask.sharp:outer_radius=-2""", default="mask.sharp:outer_radius=-2")
	
	parser.add_argument("--mask",type=str,help="""Mask processor applied to particles 
		before fsc computation. Default is mask.sharp:outer_radius=-2""", default=None)
	
	
	#parser.add_argument("--search", type=int,default=8,help=""""During COARSE alignment
	#	translational search in X, Y and Z, in pixels. Only works when --radius is provided.
	#	Otherwise, search parameters are provided with the aligner, through --align.""")
	
	#parser.add_argument("--searchfine", type=int,default=2,help=""""During FINE alignment
	#	translational search in X, Y and Z, in pixels. Only works when --radius is provided.
	#	Otherwise, search parameters are provided with the aligner, through --falign.""")
			
	#parser.add_argument("--normproc",type=str,help="""Normalization processor applied to particles before alignment. 
	#												Default is to use normalize.mask. If normalize.mask is used, results of the mask option will be passed in automatically. 
	#												If you want to turn this option off specify \'None\'""", default="normalize.mask")

	#parser.add_argument("--saveallalign",action="store_true", help="If set, will save the alignment parameters after each iteration",default=True)

	parser.add_argument("--mirror",action="store_true", help="""If set, it will generate a mirrored version of --ref and recompute FSCs against it.
															This will be IN ADDITION to FSC computation of --input against the original, unmirrored --ref.""",default=False)


	parser.add_argument("--preproc",type=str,default='',help="Any processor (as in e2proc3d.py) to be applied to each volumes prior to FSC computation. Typically this would be an automask.")
	
	parser.add_argument("--savepreproc",action='store_true',default=False,help="""Default=False. Otherwise, save preprocessed/masked volumes for inspection.""")

	parser.add_argument("--averagefscs",action='store_true',default=False,help="""Default=False. Averages FSC curves if --input contains multiple images.""")

	#parser.add_argument("--preprocessfine",type=str,default='',help="Any processor (as in e2proc3d.py) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging.")
	
	#parser.add_argument("--lowpass",type=str,default='',help="A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.")
	#parser.add_argument("--lowpassfine",type=str,default='',help="A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging.")

	#parser.add_argument("--highpass",type=str,default='',help="A highpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.")
	#parser.add_argument("--highpassfine",type=str,default='',help="A highpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to FINE alignment. Not applied to aligned particles before averaging.")

	#parser.add_argument("--shrink", type=int,default=1,help="Optionally shrink the input volumes by an integer amount for coarse alignment.")
	#parser.add_argument("--shrinkfine", type=int,default=1,help="Optionally shrink the input volumes by an integer amount for refine alignment.")

	#parser.add_argument("--threshold",type=str,default='',help="""A threshold applied to 
	#	the subvolumes after normalization. 
	#	For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels 
	#	equal 0, so that they do not contribute to the correlation score.""")

	#parser.add_argument("--nocenterofmass", default=False, action="store_true", help="""Disable Centering 
	#	of mass of the subtomogram every iteration.""")

	#parser.add_argument("--npeakstorefine", type=int, help="The number of best 'coarse peaks' from 'coarse alignment' to refine in search for the best final alignment. Default=4.", default=4)
	
	#parser.add_argument("--align",type=str,help="This is the aligner used to align particles to the previous class average.", default="rotate_translate_3d:search=6:delta=12:dphi=12")
	#parser.add_argument("--aligncmp",type=str,help="The comparator used for the --align aligner. Default is the internal tomographic ccc. Do not specify unless you need to use another specific aligner.",default="ccc.tomo")
	
	#parser.add_argument("--radius", type=float, help="""Hydrodynamic radius of the particle in Angstroms. 
	#												This will be used to automatically calculate the angular steps to use in search of the best alignment.
	#												Make sure the apix is correct on the particles' headers, sine the radius will be converted from Angstroms to pixels.
	#												Then, the fine angular step is equal to 360/(2*pi*radius), and the coarse angular step 4 times that""", default=0)
	
	#parser.add_argument("--falign",type=str,help="This is the second stage aligner used to refine the first alignment. Default is refine_3d:search=2:delta=3:range=12", default="refine_3d:search=2:delta=3:range=9")
	#parser.add_argument("--faligncmp",type=str,help="The comparator used by the second stage aligner. Default is the internal tomographic ccc",default="ccc.tomo")
	
	#parser.add_argument("--postprocess",type=str,help="A processor to be applied to the volume after averaging the raw volumes, before subsequent iterations begin.",default=None)
		
	parser.add_argument("--parallel",  help="Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel", default="thread:2")
	
	parser.add_argument("--apix", type=float, help="Provide --apix for automatic FSC calculation if you supply --plotonly and no volumes for --input and --ref, or if the apix of these is wrong.", default=1.0)
	#parser.add_argument("--boxsize", type=float, help="(Probably not needed for anything)", default=0)

	parser.add_argument("--maxres", type=float, help="How far in resolution to extend the FSC curve on the x axis; for example, to see up to 20anstroms, provide --maxres=1.0. Default=15", default=1.0)
	parser.add_argument("--cutoff", type=str, help="Comma separated values of cutoff thresholds to plot as horizontal lines. Default=0.5, to turn of supply 'None'. ", default='0.5')
	
	parser.add_argument("--smooth",action="store_true", help="""Smooth out FSC curves 
		by taking the average of a low value with a subsequent maxima.""", default=False)
	
	parser.add_argument("--smooththresh",type=float, help="""If --smooth is provided
		the curve will be smoothed only up to this resolution. Default is 100.""", default=100)

	#parser.add_argument("--fit",action="store_true", help="Smooth out FSC curves.", default=False)
	
	parser.add_argument("--polydegree",type=int, help="Degree of the polynomial to fit.", default=None)


	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID.",default=-1)
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness")
	#parser.add_argument("--plotonly",action="store_true", help="Assumes vol1 and vol2 are already aligned and fsc files will be provided through --curves; thus skips alignment and fsc curve generation", default=False)
	
	#parser.add_argument("--fsconly",action="store_true", help="""Assumes --input and --ref 
	#	are already aligned with respect to each other and thus skips alignment""", default=False)
		
	parser.add_argument("--plotonly",type=str, help="""FSC curves to plot in separate plots. 
		Skips fsc curve generation. Provide .txt. files separated by commas 
		--plotonly=file1.txt,file2.txt,file3.txt etc...""", default=None)
	parser.add_argument("--singleplot",action="store_true",help="It --plotonly provided, all FSC curves will be on the same plot/figure", default=False)
		
	(options, args) = parser.parse_args()
	
	logger = E2init(sys.argv, options.ppid)

	if options.mask: 
		options.mask=parsemodopt(options.mask)

	if options.preproc:
		options.preproc=parsemodopt(options.preproc)


	if options.cutoff and options.cutoff != 'None' and options.cutoff != 'none':
		options.cutoff = options.cutoff.split(',')
		print "Options.cutoff is", options.cutoff
	else:
		options.cutoff = None

	#if not options.output and not options.plotonly:
	#	print "ERROR: Unless you provide .txt files through --plotonly, you must specify an --output in .txt format."
	#elif options.output and not options.plotonly:
	#	if '.txt' not in options.output:
	#		print "ERROR: Output must be in .txt format"
	#		sys.exit()
		
	findir=os.listdir(os.getcwd())

	#if options.path not in findir:
	#	os.system('mkdir ' + options.path)
	
	#print "Befere options are of type", type(options)
	#print "\n\n\nand are", options
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'sptres')

	print '\n\nafter making path, options.path is', options.path
	
	if options.input:
		hdr = EMData(options.input,0,True)
		apix = hdr['apix_x']
	
	if options.apix:
		apix = float (options.apix)
		
	#print "Returned options are of type", type(options)
	#print "\n\n\nand are", options
	
	if options.plotonly:
		curves = options.plotonly
		curves = curves.split(',')
		
		if not options.singleplot:
			for curve in curves:
				print "Found this curve to plot", curve
				fscplotter([curve],options,apix)
				
		elif options.singleplot:
			fscplotter(curves,options,apix)
		
		print "Done plotting"
		sys.exit()
		
	else:
		getfscs(options,apix)
	
		print "Done calculating FSCs and plotting them."
		#sys.exit()
	
	'''
	elif options.align:
		print '\n\nI will align'
		if options.symmap and options.symmap is not 'c1' and options.symmap is not 'C1':		
			ref = EMData(options.ref,0)
			ref = symmetrize(ref,options)
			options.ref = options.path + '/' + os.path.basename(options.ref).replace('.','_' + options.sym + '.')
			ref.write_image(options.ref,0)
		
		ptclali = alignment(options)
		
		print '\n\nthe returned path for ali ptcl is', ptclali
		inputbackup = options.input
		options.input = ptclali
		
		print '\n\nwill get fsc'
		getfscs(options,apix)

		if options.mirror:
			options.input = inputbackup
			ref = EMData(options.ref,0)
			t=Transform({'type':'eman','mirror':True})
			
			options.ref = os.path.basename(options.ref).replace('.','_mirror.')
			if options.path not in options.ref:
				options.ref = options.path + '/' + options.ref
		
			ref.transform(t)
			ref.write_image(options.ref,0)
			
			ptclalimirror = alignment(options)
		
			options.input = ptclalimirror
			getfscs(options,apix)
	'''

	E2end(logger)
	return
def main():

    progname = os.path.basename(sys.argv[0])
    usage = """Plots the variation of correlation of a volume with itself as it is rotated in azimuth or altitude"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument("--path",
                        type=str,
                        default='',
                        help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'rotplot'; 
		for example, rotplot_02 will be the directory by default if 'rotplot_01' already exists."""
                        )

    parser.add_argument(
        "--vols1",
        type=str,
        help=
        "Comma-separated filenames of the .hdf volumes whose self-rotational correlation plot you want to compute.",
        default=None)
    parser.add_argument(
        "--vols2",
        type=str,
        help=
        "Comma-separated filenames of the .hdf volumes whose rotational correlation plot you want to compute against the volumes provided through --vols1.",
        default=None)

    parser.add_argument(
        "--output",
        type=str,
        help=
        "Name for the .txt file with the results and the corresponding .png plot"
    )
    parser.add_argument("--sym",
                        type=str,
                        help="Symmetry to apply after all preprocessing.",
                        default='c1')

    parser.add_argument(
        "--mask",
        type=str,
        help=
        "Mask processor applied to particles before alignment. Default is mask.sharp:outer_radius=-2",
        default="mask.sharp:outer_radius=-2")
    parser.add_argument(
        "--preprocess",
        type=str,
        help=
        "Any processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.",
        default=None)

    parser.add_argument(
        "--lowpass",
        type=str,
        help=
        "A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.",
        default=None)
    parser.add_argument(
        "--highpass",
        type=str,
        help=
        "A highpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.",
        default=None)

    parser.add_argument("--normproc",
                        type=str,
                        help="""Normalization processor applied to 
		particles before alignment. Default is 'normalize.edgemean'. 
		If normalize.mask is used, results of the mask option will be passed in automatically. 
		If you want to turn this option off specify \'None\'""",
                        default='normalize.edgemean')

    parser.add_argument(
        "--shrink",
        type=int,
        default=1,
        help=
        "Optionally shrink the input volumes by an integer amount for coarse alignment."
    )
    parser.add_argument(
        "--shrinkefine",
        type=int,
        default=1,
        help=
        "Optionally shrink the input volumes by an integer amount for refine alignment."
    )

    parser.add_argument("--daz",
                        type=int,
                        default=3,
                        help="Step size to vary azimuth.")
    parser.add_argument(
        "--icosvertices",
        action="store_true",
        help="Will produce an azimutal plot at each vertex of an icosahedron.",
        default=False)
    parser.add_argument("--dalt",
                        type=int,
                        default=181,
                        help="Step size to vary altitude.")
    parser.add_argument(
        "--alti",
        type=int,
        default=0,
        help=
        """Initial position to check in altitude. For example, for a D symmetric chaperonin, 
															if you want to check alt=0 ONLY, provide --alti=0 and --dalt=181 as options.
															if you want to check alt=180 ONLY, provide --alti=180, --dalt=1 or greater.
															if you want to check BOTH alt=0 and alt=180 in the same plot, provide --alti=0, --dalt=180"""
    )

    parser.add_argument(
        "--parallel",
        help="Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel",
        default="thread:1")

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)
    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )
    #parser.add_argument("--plotonly",type=str, help="Provide .txt files for a given alt, with 2 columns (az ccc) with the values to plot. For example, --plotonly=alt000.txt,alt180.txt", default=None)
    parser.add_argument(
        "--normalizeplot",
        action="store_true",
        help=
        "Make maximum correlation value on plot equal to 1 and scale all other values accordingly.",
        default=False)
    parser.add_argument("--plot2d",
                        action="store_true",
                        help="Produces 2D plot if both az and alt are varied.",
                        default=False)
    parser.add_argument("--only2dplot",
                        action="store_true",
                        help="Skips all plots, except 2dplot.",
                        default=False)
    parser.add_argument(
        "--savetxt",
        action="store_true",
        help="Will save the values for each plot into .txt files.",
        default=False)

    parser.add_argument(
        "--plotonly",
        type=str,
        help=
        """If you already have the correlation variation with azimuth (for a particular altitude) in a text file in rows of 'az,ccc', 
												provide the txt file(s) separated by commas --plotonly=file1.txt,file2.txt,file3.txt etc...""",
        default=None)

    parser.add_argument("--singleplot",
                        action="store_true",
                        help="""Plot all alts, 
		or each vertex of --icosvertices is on, in a single .png file.""",
                        default=False)

    parser.add_argument("--offset",
                        type=float,
                        default=0.0,
                        help="""Default=0. Rotation in azimuth
		to apply to one of the models before computing the entire rotational correlation plot."""
                        )

    parser.add_argument(
        "--ownvalues",
        action='store_true',
        default=False,
        help=
        """Default=False. If provided and --normalizeplot is also provided, this parameter will cause all curves to go from 0 to 1 when ploted on the same plot by specifying --singleplot. Otherwise, the maximum value will drawn from the highest value amongst all the curves and the minimum value from the lowest value amongst all the curves being plotted simultaneously, preserving the relative intensity between different curves, but still effectively making the range 0 to 1."""
    )

    (options, args) = parser.parse_args()

    #print "Loaded mask is", options.mask
    '''
	Parse options
	'''
    if options.mask:
        if 'None' in options.mask:
            options.mask = 'None'
        if options.mask != 'None' and options.mask != 'none':
            print "\noptions.mask before parsing is", options.mask
            options.mask = parsemodopt(options.mask)
        else:
            options.mask = None
        print "\nmask after parsing is", options.mask

    if options.preprocess:
        if options.preprocess != 'None' and options.preprocess != 'none':
            options.preprocess = parsemodopt(options.preprocess)
        else:
            options.preprocess = None
        print "\nPreprocessor is", options.preprocess

    if options.lowpass:
        if options.lowpass != 'None' and options.lowpass != 'none':
            options.lowpass = parsemodopt(options.lowpass)
        else:
            options.lowpass = None
        print "\nlowpass is", options.lowpass

    if options.highpass:
        if options.highpass != 'None' and options.highpass != 'none':
            options.highpass = parsemodopt(options.highpass)
        else:
            options.highpass = None
        print "\nHighpass is", options.highpass

    if options.normproc:
        if options.normproc != 'None' and options.normproc != 'none':
            options.normproc = parsemodopt(options.normproc)
        else:
            options.normproc = None
        print "\nNormproc is", options.normproc

    #print "plotonly is", options.plotonly

    if options.only2dplot:
        options.plot2d = True

    if options.icosvertices and options.vols2:
        print "ERROR: You can only use --icosvertices for volumes in --vols1. You must NOT supply --vols2."
        sys.exit()

    #print "args are", args
    logger = E2init(sys.argv, options.ppid)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'rotplot')

    if not options.plotonly:
        vols1 = []
        if options.vols1:
            vols1 = options.vols1.split(',')

        vols = vols1

        vols2 = []
        if options.vols2:
            vols2 = options.vols2.split(',')
            vols = vols1 + vols2

            for v in vols:
                if '.hdf' not in v and '.mrc' not in v:
                    print "ERROR: The input volumes must all be either .hdf, .mrc or .rec (which is also just a .mrc file)."
                    sys.exit()

                rotcccplot(v, v, options)

            for v1 in vols1:
                for v2 in vols2:
                    rotcccplot(v1, v2, options)

        else:
            for v in vols:
                if '.hdf' not in v and '.mrc' not in v:
                    print "ERROR: The input volumes must all be either .hdf, .mrc or .rec (which is also just a .mrc file)."
                    sys.exit()

                rotcccplot(v, v, options)
    else:

        files = options.plotonly.split(',')
        print "Will plot these files", files

        values = {}

        #absMIN=1000000
        #absMAX=-1
        absMIN = 0.0
        absMAX = 0.0
        ownvalues = 1
        try:
            if options.ownvalues:
                ownvalues = options.ownvalues
        except:
            pass

        k = 0
        for F in files:
            print "Working with this file now", F
            azs = []
            valuesforthisfile = []

            f = open(F, 'r')
            lines = f.readlines()
            f.close()

            for line in lines:
                print "Line is\n", line
                az = line.split()[0]
                azs.append(int(az))
                value = line.split()[-1].replace('\n', '')
                valuesforthisfile.append(float(value))
                print "Thus az, value are", az, value

            #title=F.replace('.txt','')

            if not ownvalues:

                minv = float(min(valuesforthisfile))
                if float(minv) < float(absMIN):
                    absMIN = float(minv)

                maxv = float(max(valuesforthisfile))
                if float(maxv) > float(absMAX):
                    absMAX = float(maxv)
                print "Min and max to send are", absMIN, absMAX

            values.update({k: valuesforthisfile})
            k += 1

        title = 'plot'
        if options.output:
            tilte = options.output.replace('.txt', '')

        plotter(options, azs, values, title, None, k, absMIN, absMAX)
        print "I have returned from the plotter"

        if options.singleplot:
            print "And single plot is on"

            plotname = 'plot'
            if options.output:
                plotname = options.output.replace('.txt', '')

            if not options.only2dplot:
                print "While only 2D plot is off"
                #pylab.savefig(plotname)
                #pylab.title(title)
                pylab.ylabel('Correlation')
                pylab.xlabel('Azimuth')
                pylab.savefig(options.path + '/' + plotname)
                #clf()

            if not options.icosvertices and options.plot2d:
                print "I will call 2dplot"
                twoD_plot(plotname, values, options)
        if not options.singleplot:
            clf()

    E2end(logger)

    return ()
Beispiel #29
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options]

	This program runs different spt programs quickly, in testing mode, such that crashes
	can be identified more easily.
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higher number means higher level of verboseness")

    parser.add_argument(
        "--testn",
        type=int,
        default=6,
        help=
        """default=6. size of dataset to run tests with; cannot be < 6, since initial model generation with HAC for gold-standard refinement requires at least 3 particles for the even set and 3 for the odd set."""
    )

    parser.add_argument(
        "--path",
        type=str,
        default='spttests',
        help=
        """Default=spttests. Directory to store results in. The default is a numbered series of directories containing the prefix 'spttests'; for example, spttests_02 will be the directory by default if 'spttests_01' already exists."""
    )

    parser.add_argument(
        "--parallel",
        type=str,
        default='',
        help=
        """the program will detect the number of cores available and use threaded parallelism by default. To use only one core, supply --parallel=thread:1. For MPI on clusters, see parallelism at http://blake.bcm.edu/emanwiki/EMAN2/Parallel"""
    )

    #parser.add_argument("--testsim",action='store_true',default=False,help="""default=False. If supplied, this option will test e2spt_simulation.py as well and use the generated simulated particles for subsequent tests, opposed to random volumes that do not have a missing wedge, noise or CTF.""")

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    (options, args) = parser.parse_args()

    logger = E2init(sys.argv, options.ppid)

    if not options.parallel:
        import multiprocessing
        nparallel = multiprocessing.cpu_count()
        options.parallel = 'thread:' + str(nparallel)
        print("\nfound %d cores" % (nparallel))
        print("setting --parallel to", options.parallel)

    if options.testn < 6:
        print("\nERROR: --testn must be > 5.")
        sys.exit()
    '''
	Make the directory where to create the database where the results will be stored
	'''
    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'spt_bt')

    from e2spt_classaverage import writeParameters
    writeParameters(options, 'e2spt_test.py', 'spttests')

    for i in range(options.testn):
        a = test_image_3d()
        t = Transform()
        if i > 0:
            az = random.randint(0, 360)
            alt = random.randint(0, 180)
            phi = random.randint(0, 360)
            tx = random.randint(-5, 5)
            ty = random.randint(-5, 5)
            tz = random.randint(-5, 5)
            t = Transform({
                'type': 'eman',
                'tx': tx,
                'ty': ty,
                'tz': tz,
                'alt': alt,
                'az': az,
                'phi': phi
            })
            a.transform(t)

        a.process_inplace('math.meanshrink', {'n': 4})
        a['spt_randT'] = t
        a.write_image(options.path + '/testimgs.hdf', -1)

        if i == 0:
            a.write_image(options.path + '/testimg_ref.hdf', 0)

    cmds = []

    rootpath = os.getcwd()

    os.system('touch ' + options.path + '/output.txt')

    #input = rootpath + '/' + options.path + '/testimgs.hdf'
    #if options.testsim:

    simcmd = 'e2spt_simulation.py --input=' + options.path + '/testimg_ref.hdf --nptcls ' + str(
        options.testn
    ) + ' --tiltrange 60 --nslices 25 --saveprjs --applyctf --snr 2' + ' --parallel=' + options.parallel + ' --path testsim'
    if options.verbose:
        simcmd += ' --verbose ' + str(options.verbose)

    cmds.append(simcmd)
    simcmd2 = 'mv testsim ' + options.path
    cmds.append(simcmd2)

    input = rootpath + '/' + options.path + '/testsim/simptcls.hdf'

    btcmd = 'e2spt_binarytree.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --parallel=' + options.parallel + ' --path testbt'
    cmds.append(btcmd)
    btcmd2 = 'mv testbt ' + rootpath + '/' + options.path + '/'
    cmds.append(btcmd2)

    haccmd = 'e2spt_hac.py  --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --parallel=' + options.parallel + ' --path testhac'
    cmds.append(haccmd)
    haccmd2 = 'mv testhac ' + rootpath + '/' + options.path + '/'
    cmds.append(haccmd2)

    ssacmd = 'e2symsearch3d.py  --input ' + input + ' --sym icos --steps 2 --parallel=' + options.parallel + ' --path testssa'
    cmds.append(ssacmd)
    ssacmd2 = 'mv testssa ' + rootpath + '/' + options.path + '/'
    cmds.append(ssacmd2)

    sptdefaultcmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --parallel=' + options.parallel + ' --path testsptdefaultgoldoff'
    cmds.append(sptdefaultcmdgoldoff)
    sptdefaultcmdgoldoff2 = 'mv testsptdefaultgoldoff ' + rootpath + '/' + options.path + '/'
    cmds.append(sptdefaultcmdgoldoff2)

    sptrefbtcmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --btref 2 --parallel=' + options.parallel + ' --path testsptrefbtgoldoff'
    cmds.append(sptrefbtcmdgoldoff)
    sptrefbtcmdgoldoff2 = 'mv testsptrefbtgoldoff ' + rootpath + '/' + options.path + '/'
    cmds.append(sptrefbtcmdgoldoff2)

    sptrefssacmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --ssaref 2 --parallel=' + options.parallel + ' --path testsptrefssagoldoff'
    cmds.append(sptrefssacmdgoldoff)
    sptrefssacmdgoldoff2 = 'mv testsptrefssagoldoff ' + rootpath + '/' + options.path + '/'
    cmds.append(sptrefssacmdgoldoff2)

    sptrefhaccmdgoldoff = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --goldstandardoff --hacref 3 --parallel=' + options.parallel + ' --path testsptrefhacgoldoff'
    cmds.append(sptrefhaccmdgoldoff)
    sptrefhaccmdgoldoff2 = 'mv testsptrefhacgoldoff ' + rootpath + '/' + options.path + '/'
    cmds.append(sptrefhaccmdgoldoff2)

    sptdefaultcmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --parallel=' + options.parallel + ' --path testsptdefaultgoldon'
    cmds.append(sptdefaultcmdgoldon)
    sptdefaultcmdgoldon2 = 'mv testsptdefaultgoldon ' + rootpath + '/' + options.path + '/'
    cmds.append(sptdefaultcmdgoldon2)

    sptrefbtcmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --btref 4 --parallel=' + options.parallel + ' --path testsptrefbtgoldon'
    cmds.append(sptrefbtcmdgoldon)
    sptrefbtcmdgoldon2 = 'mv testsptrefbtgoldon ' + rootpath + '/' + options.path + '/'
    cmds.append(sptrefbtcmdgoldon2)

    sptrefssacmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --ssaref 4 --parallel=' + options.parallel + ' --path testsptrefssagoldon'
    cmds.append(sptrefssacmdgoldon)
    sptrefssacmdgoldon2 = 'mv testsptrefssagoldon ' + rootpath + '/' + options.path + '/'
    cmds.append(sptrefssacmdgoldon2)

    sptrefhaccmdgoldon = 'e2spt_classaverage.py --input ' + input + ' --align rotate_symmetry_3d:sym=c1 --falign refine_3d_grid:range=3:delta=3 --hacref 6 --parallel=' + options.parallel + ' --path testsptrefhacgoldon'
    cmds.append(sptrefhaccmdgoldon)
    sptrefhaccmdgoldon2 = 'mv testsptrefhacgoldon ' + rootpath + '/' + options.path + '/'
    cmds.append(sptrefhaccmdgoldon2)

    for cmd in cmds:
        runcmd(options, cmd)

    E2end(logger)
    sys.stdout.flush()

    return
Beispiel #30
0
def main():

	usage = """e2spt_tiltstacker.py <options> . 
	The options should be supplied in "--option=value" format, 
	replacing "option" for a valid option name, and "value" for an acceptable value for that option. 
	
	This program operates in 3 different modes:
	1) It can STACK individual .dm3, .tiff or .hdf images into an .mrc (or .st) stack,
	by supplying a common string to all the images to stack via --stem2stack.
	It must be run in a directory containing the numbered images only.
	It also generates a .rawtlt file with tilt angle values if --lowerend, --upperend and --tiltstep are provided.
	
	2) It can UNSTACK a tilt series into individual files (either all the images, or selected
	images, controlled through the --exclude or --include parameters).
	
	3) It can RESTACK a tilt series; that is, put together a new tilt series that excludes/includes
	specific images
	"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)	
	
	parser.add_argument("--path",type=str,default='',help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'sptstacker';
		for example, sptstacker_02 will be the directory by default if 'sptstacker_01' 
		already exists.""")

	parser.add_argument("--stem2stack", type=str, default='', help="""String common to all 
		the files to put into an .st stack, which is in .MRC format; for example, --stem2stack=.hdf 
		will process all .hdf files in the current directory.
		If not specified, all valid EM imagefiles in the current directory will be put into 
		an .st stack.""")
	
	parser.add_argument("--tltfile",type=str,default='',help="""".tlt file IF unstacking an
		aligned tilt series with --unstack=<stackfile> or restacking a tiltseries with
		--restack=<stackfile>""")
		
	parser.add_argument("--invert",action="store_true",default=False,help=""""This 
		will multiply the pixel values by -1.""")
	
	parser.add_argument("--stackregardless",action="store_true",default=False,help=""""Stack
		images found with the common string provided through --stem2stack, even if the
		number of images does not match the predicted number of tilt angles.""")
	
	parser.add_argument("--outmode", type=str, default="float", help="""All EMAN2 programs 
		write images with 4-byte floating point values when possible by default. This allows 
		specifying an alternate format when supported: float, int8, int16, int32, uint8, 
		uint16, uint32. Values are rescaled to fill MIN-MAX range.""")
	
	parser.add_argument("--bidirectional",action='store_true',default=False,help="""This will
		assume the first image is at 0 degrees and will stack images from --lowerend through 0, 
		and then will stack the rest from 0+tiltstep throgh --upperend. 
		If --negativetiltseries is supplied, images will be stacked from --upperend through 0, then 
		from 0-tiltstep through --lowerend.""")
	
	parser.add_argument("--lowesttilt",type=float,default=0.0,help="""Lowest tilt angle.
		If not supplied, it will be assumed to be -1* --tiltrange.""")
	
	parser.add_argument("--highesttilt",type=float,default=0.0,help="""Highest tilt angle.
		If not supplied, it will be assumed to be 1* --tiltrange.""")
	
	parser.add_argument("--tiltrange",type=float,default=0.0,help="""If provided, this
		will make --lowesttilt=-1*tiltrange and --highesttilt=tiltrage.
		If the range is asymmetric, supply --lowesttilt and --highesttilt directly.""")
	
	parser.add_argument("--tiltstep",type=float,default=0.0,help="""Step between tilts.
		Required if using --stem2stack.""")
	
	parser.add_argument("--clip",type=str,default='',help="""Resize the 2-D images in the
		tilt series. If one number is provided, then x and y dimensions will be made the same.
		To specify both dimensions, supply two numbers, --clip=x,y. Clipping will be about
		the center of the image.""")
			
	parser.add_argument("--apix",type=float,default=0.0,help="""True apix of images to be 
		written on final stack.""")
	
	parser.add_argument("--unstack",type=str,default='',help=""".hdf, or 3D .st, .mrc, 
		.ali, or .mrcs stack file to unstack.
		This option can be used with --include or --exclude to unstack only specific images.
		Recall that the FIRST image INDEX is 0 (but unstacked image will be numbered from 1). 
		--exclude=1,5-7,10,12,15-19 will exclude images 1,5,6,7,10,12,15,16,17,18,19""""")
	
	parser.add_argument("--restack",type=str,default='',help=""".hdf, or 3D .st, .mrc, 
		.ali, or .mrcs stack file to restack.
		This option can be used with --include or --exclude to unstack only specific images.
		Recall that the FIRST image INDEX is 0 (but unstacked image will be numbered from 1). 
		--exclude=1,5-7,10,12,15-19 will exclude images 1,5,6,7,10,12,15,16,17,18,19""""")
	
	parser.add_argument("--mirroraxis",type=str,default='',help="""Options are x or y, and the
		mirrored copy of the 2-D images will be generated before being put into the tilt series.""")
	
	parser.add_argument("--exclude",type=str,default='',help="""Comma separated list of numbers
		corresponding to images to exclude. --unstack or --restack must be supplied. 
		You can also exclude by ranges. For example:
		Recall that the FIRST image INDEX is 0. 
		--exclude=1,5-7,10,12,15-19 will exclude images 1,5,6,7,10,12,15,16,17,18,19""")
		
	parser.add_argument("--include",type=str,default='',help="""Comma separated list of numbers
		corresponding to images to include (all others will be excluded). 
		--unstack or --restack must be supplied. 
		Recall that the FIRST image INDEX is 0. 
		--include=1,5-7,10,12,15-19 will include images 1,5,6,7,10,12,15,16,17,18,19""")


	#parser.add_argument("--negativetiltseries",action='store_true',default=False,help="""This indicates that the tilt series goes from -tiltrange to +tiltrange, or 0 to -tiltrange, then +tiltstep to +tiltrange if --bidirectional is specified.""")
	
	#parser.add_argument("--negative",action='store_true',default=False,help="""This indicates that the tilt series goes from -tiltrange to +tiltrange, or 0 to -tiltrange, then +tiltstep to +tiltrange if --bidirectional is specified.""")
	
	parser.add_argument("--negativetiltseries",action='store_true',default=False,help="""This indicates that the tilt series goes from -tiltrange to +tiltrange, or 0 to -tiltrange, then +tiltstep to +tiltrange if --bidirectional is specified.""")

	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")

	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	(options, args) = parser.parse_args()	
	
	
	print "--negativetiltseries", options.negativetiltseries
	
	if options.exclude and options.include:
		print "\nERROR: Supplied either exclude or include. Cannot supply both at the same time."
		sys.exit()
	
	print "\nLogging"
	logger = E2init(sys.argv, options.ppid)
	
	
	from e2spt_classaverage import sptmakepath
	options = sptmakepath( options, 'sptstacker')

	options.path = os.getcwd() + '/' + options.path
	
	if options.stem2stack and options.tiltstep == 0.0:
		print "ERROR: --tiltstep required when using --stem2stack"
		sys.exit()
	
	if options.lowesttilt == 0.0 and options.tiltrange:
		options.lowesttilt = -1 * options.tiltrange
		
	if options.highesttilt == 0.0 and options.tiltrange:
		options.highesttilt = options.tiltrange

	if options.unstack:
		if options.tltfile:
			usntacker( options )
		else:
			print "ERROR: --tltfile required when using --unstack"
			sys.exit()

	elif options.restack:
		if options.tltfile:
			restacker( options )
		else:
			print "ERROR: --tltfile required when using --restack"
			sys.exit()

	else:
		kk=0
		intilts = findtiltimgfiles( options )
		
		print "\nWill organize tilt imgs found"
		intiltsdict = organizetilts( intilts, options )		#Get a dictionary in the form { indexintiltseries:[ tiltfile, tiltangle, damageRank ]},
		print "\nDone organizing tilt imgs"					#where damageRank tells you the order in which the images where acquired
															#regardless of wether the tilt series goes from -tiltrange to +tiltrange, 
															#or 0 to -tiltrange then +tiltstep to +tiltrange, or the opposite of these 
		outstackhdf = options.path + '/stack.hdf' 
		
		minindx = min(intiltsdict)
		print "minindx is", minindx
		print "getting size from any first image, intiltsdict[ minindx ][0]", intiltsdict[ minindx ][0]
		
		hdr = EMData( intiltsdict[minindx][0], 0, True )
		nx = hdr['nx']
		ny = hdr['ny']
		print nx,ny
		
		
		print "\nOutstack is", outstackhdf
		
		tiltstoexclude = options.exclude.split(',')				
		
		#orderedindexes = []
		#for index in intiltsdict:
		#	orderedindexes.append( index )
		
		#orderedindexes.sort()
		
		for index in intiltsdict:
			
			if str(index) not in tiltstoexclude:
				intiltimgfile =	intiltsdict[index][0]
				
				print "\nat index %d we have image %s, collected in this turn %d" %( index, intiltsdict[index][0], intiltsdict[index][-1] )
				intiltimg = EMData( intiltimgfile, 0 )
			
				tiltangle = intiltsdict[index][1]
				intiltimg['spt_tiltangle'] = tiltangle
			
				damageRank = intiltsdict[index][2]
				intiltimg['damageRank'] = damageRank
			
				if options.invert:
					intiltimg.mult(-1)
				intiltimg.write_image( outstackhdf, -1 )
				print "\nWrote image index", index
		
		if options.clip:
			clip = options.clip.split(',')
			
			shiftx = 0
			shifty = 0
			if len( clip ) == 1:
				clipx = clipy = clip[0]
			
			if len( clip ) == 2:
				clipx = clip[0]
				clipy = clip[1]
			
			if len( clip ) == 4:
				clipx = clip[0]
				clipy = clip[1]
				shiftx = clip[2]
				shifty = clip[3]
			
			tmp = options.path + '/tmp.hdf'
			cmdClip = 'e2proc2d.py ' + outstackhdf + ' ' + tmp + ' --clip=' + clipx + ',' + clipy
			
			if shiftx:
				xcenter = int( round( nx/2.0 + float(shiftx)))
				cmdClip += ',' + str(xcenter)
			if shifty:
				ycenter = int( round( ny/2.0 + float(shifty)))
				cmdClip += ',' + str(ycenter)
			
			cmdClip += ' && rm ' + outstackhdf + ' && mv ' + tmp + ' ' + outstackhdf

			print "\n(e2spt_tiltstacker.py)(main) cmdClip is", cmdClip
			p = subprocess.Popen( cmdClip , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			text = p.communicate()	
			p.stdout.close()
			
			if options.verbose > 9:
				print "\nFeedback from cmdClip:"
				print text
			
			
		outtilthdr = EMData(outstackhdf,0,True)
		currentapix = outtilthdr['apix_x']
		if float(options.apix) and float(options.apix) != float(currentapix):
			print "\nFixing apix"
			cmdapix = 'e2fixheaderparam.py --input=' + outstackhdf + ' --stem=apix --valtype=float --stemval=' + str( options.apix )
			
			print "\n(e2spt_tiltstacker.py)(main) cmdapix is", cmdapix
			p = subprocess.Popen( cmdapix , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			text = p.communicate()	
			p.stdout.close()
			
			if options.verbose > 9:
				print "\nFeedback from cmdapix:"
				print text
			
			
		outstackst = outstackhdf.replace('.hdf','.st')
		stcmd = 'e2proc2d.py	' + outstackhdf + ' ' + outstackst + ' --twod2threed'
		if options.outmode != 'float':
			stcmd += ' --outmode=' + options.outmode + ' --fixintscaling=sane'
			
		if options.apix:
			stcmd += ' --apix=' + str(options.apix)
			stcmd += ' && e2fixheaderparam.py --input=' + outstackst + ' --stem=apix --valtype=float --stemval=' + str( options.apix ) + ' --output=' + outstackst.replace('.st','.mrc') + " && mv " +  outstackst.replace('.st','.mrc') + ' ' + outstackst
			
		
		print "\n(e2spt_tiltstacker.py)(main) stcmd is", stcmd	
		p = subprocess.Popen( stcmd , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
		text = p.communicate()	
		p.stdout.close()
		
		if options.verbose > 9:
			print "\nFeedback from stcmd:"
			print text
		
		if options.mirroraxis:
			print "\nMirroring across axis", options.mirroraxis
			mirrorlabel = options.mirroraxis.upper()
			outstackstmirror = outstackst.replace('.st','_mirror'+ mirrorlabel+ '.st')

			cmdMirror = 'e2proc2d.py ' + outstackst + ' ' + outstackstmirror + ' --process=xform.mirror:axis=' + options.mirroraxis
			
			if options.outmode != 'float':
				cmdMirror += ' --outmode=' + options.outmode + ' --fixintscaling=sane'
			
			print "options.apix is", options.apix
			if options.apix:
				cmdMirror += ' --apix=' + str(options.apix)
				cmdMirror += ' && e2fixheaderparam.py --input=' + outstackstmirror + ' --stem=apix --valtype=float --stemval=' + str( options.apix ) + ' --output=' + outstackstmirror.replace('.st','.mrc') + " && mv " +  outstackstmirror.replace('.st','.mrc') + ' ' + outstackstmirror
				
				print "added fixheaderparam to cmdMirror!"
			
			print "cmdMirror is", cmdMirror
			p = subprocess.Popen( cmdMirror , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			text = p.communicate()	
			
			if options.verbose > 9:
				print "\nFeedback from cmdMirror:"
				print text
				p.stdout.close()
	
	E2end( logger )
	return
Beispiel #31
0
def main():

    progname = os.path.basename(sys.argv[0])
    usage = """Program for individual subtomogram refinement (ISR) based on subtiltseries
	for each subtomogram extracted with e2spt_subtilt.py."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        '--input',
        type=str,
        default='',
        help=
        """Comma separated files in .ali, .st .hdf format of the aligned subtiltseries."""
    )

    parser.add_argument(
        '--inputstem',
        type=str,
        default='',
        help=
        """Alternative to supplying --input. This is a string common to multiple files to be processed in the CURERENT directory. The common string doesn't need to be at a particular location in the filenames. For example, a series of files "tiltA.hdf, tiltB.hdf, tiltC.hdf" could have either 'hdf', '.hdf', 't,','ti', 'til', 'tilt', etc., as a common string. The key is to choose a string shared ONLY by the files of interest. The files should be multiple subtiltseries in .hdf format; each file should correspond to an individual subtiltseries for a different particle: That is, each file should be a subtiltseries corresponding to an individual subtomogram, as extracted by e2spt_subtilt.py, or as simulated by e2spt_simulation.py"""
    )

    parser.add_argument(
        '--inputdir',
        type=str,
        default='',
        help=
        """Alternative to --input and --inputstem. Path to a directory containing individual subtiltseries stacks."""
    )

    parser.add_argument(
        "--path",
        type=str,
        default='',
        help=
        "Directory to store results in. The default is a numbered series of directories containing the prefix 'sptisr'; for example, sptisr02 will be the directory by default if 'sptisr_01' already exists."
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help=
        "Default=1. Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        type=int,
        default=0,
        help=
        "Default 0. Verbose level [0-9], higner number means higher level of verboseness",
        dest="verbose",
        action="store",
        metavar="n")

    parser.add_argument(
        "--reconstructor",
        type=str,
        default="fourier:mode=gauss_2",
        help=
        """Default=fourier:mode=gauss_2. The reconstructor to use to reconstruct the tilt series into a tomogram. Type 'e2help.py reconstructors' at the command line to see all options and parameters available. To specify the interpolation scheme for the fourier reconstructor, specify 'mode'. Options are 'nearest_neighbor', 'gauss_2', 'gauss_3', 'gauss_5'. For example --reconstructor=fourier:mode=gauss_5 """
    )

    parser.add_argument("--iter",
                        type=int,
                        default=1,
                        help="""Number of iterations to run algorithm for.""")

    parser.add_argument(
        "--tltfile",
        type=str,
        default='',
        help=
        """IMOD-like .tlt file with tilt angles for the aligned tiltseries (or set of subtiltseries)."""
    )

    parser.add_argument(
        "--tiltaxis",
        type=str,
        default='y',
        help=
        """Axis to produce projections about. Default is 'y'; the only other valid option is 'x'."""
    )

    parser.add_argument(
        "--pad2d",
        type=float,
        default=0.0,
        help=
        """Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the 2d images in the tilt series for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though)."""
    )

    parser.add_argument(
        "--pad3d",
        type=float,
        default=0.0,
        help=
        """Default=0.0. Padding factor (e.g., 2.0, to make the box twice as big) to zero-pad the volumes for reconstruction purposes (the final reconstructed subvolumes will be cropped back to the original size though)."""
    )

    parser.add_argument(
        "--savevols",
        action='store_true',
        default=False,
        help=
        """This option will save the reconstructed volumes at each iteration."""
    )

    parser.add_argument(
        "--outxsize",
        type=int,
        default=0,
        help=
        '''Clip the output volume in x to this size. The default size is the nx size of the input images.'''
    )

    parser.add_argument(
        "--outysize",
        type=int,
        default=0,
        help=
        '''Clip the output volume in y to this size. The default size is the ny size of the input images.'''
    )

    parser.add_argument(
        "--outzsize",
        type=int,
        default=0,
        help=
        '''Clip the output volume in z to this size. The default size is the nx size of the input images.'''
    )

    parser.add_argument(
        "--mask",
        type=str,
        help=
        """Default=None. Masking processor (see e2help.py --verbose=10) applied to the images to aid alignment. Default=None."""
    )

    parser.add_argument(
        "--preprocess",
        type=str,
        help=
        """Default=None. Any processor (see e2help.py --verbose=10) applied to the images to aid alignment."""
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        default='',
        help=
        """Default=None. A lowpass filtering processor (see e2help.py --verbose=10) applied to each volume prior to reprojection generation.."""
    )

    parser.add_argument(
        "--highpass",
        type=str,
        default='',
        help=
        """Default=None. A highpass filtering processor (see e2help.py --verbose=10) applied to each volume prior to reprojection generation."""
    )

    parser.add_argument(
        "--threshold",
        type=str,
        default='',
        help=
        """Default=None. A threshold  processor (see e2help.py --verbose=10) applied to each volume prior to reprojection generation."""
    )

    parser.add_argument(
        "--saveali",
        action="store_true",
        default=False,
        help=
        """Default=False. If set, will save the recentered subtiltseries after each iteration."""
    )

    (options, args) = parser.parse_args()

    logger = E2init(sys.argv, options.ppid)

    if not options.input and not options.inputdir and not options.inputstem:
        print "ERROR: Either of the following required: --input, --inputstemp, --inputdir"
        sys.exit()

    if options.input and options.inputstem:
        print "ERROR: Cannot provide --input and --inputstem simultaneously"
        sys.exit()

    if options.inputstem and options.inputdir:
        print "ERROR: Cannot provide --inputstem and --inputdir simultaneously"
        sys.exit()

    if options.input and options.inputdir:
        print "ERROR: Cannot provide --input and --inputdir simultaneously"
        sys.exit()

    from e2spt_classaverage import sptOptionsParser
    options = sptOptionsParser(options)
    #print "Options have been parsed, for example, mask is", options.mask, type(options.mask), len(options.mask)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'sptisr')

    originalpath = options.path

    if options.verbose > 9:
        print "\n(e2spt_isr.py) I've read the options"

    inputfiles = {
    }  #C:Figure out whether there's a single HDF stack to process,
    #C:or a directory with many HDF stacks
    c = os.getcwd()

    if options.inputdir:
        c = os.getcwd() + '/' + options.inputdir

    findir = os.listdir(c)

    if options.inputstem:
        for f in findir:
            if '.hdf' in f and options.inputstem in f:
                if options.verbose > 8:
                    print "\nFound tiltseries!", f
                inputfiles.update(
                    {f: [f, None]}
                )  #C:The input files are put into a dictionary in the format {originalseriesfile:[originalseriesfile,volumefile]}

    elif options.inputdir:
        for f in findir:
            if '.hdf' in f:
                if options.verbose > 8:
                    print "\nFound tiltseries!", f
                inputfiles.update(
                    {f: [f, None]}
                )  #C:The input files are put into a dictionary in the format {originalseriesfile:[originalseriesfile,volumefile]}

    elif options.input:
        inputfiles.update({options.input: [options.input, None]})

    tiltstep = 0
    newvol = vol = None
    newfiles = {}
    firstiterdir = originalpath

    print "\n\nThere are these many iterations", options.iter
    fstats = {}
    convergedfs = []

    fmeanscores2d = {}
    itermeanscores2d = {}

    fmeanerrors = {}
    itermeanerrors = {}

    fmeanfscs = {
        -1: {}
    }  #Compute initial FSC before any iterations of correction or alignment have occurred
    itermeanfscs = {}

    fmeanscores3d = {-1: {}}
    itermeanscores3d = {}

    errorswitch = 0

    for i in range(options.iter):  #Iterate over options.iter
        itermeanscores2d.update({i: 0})
        itermeanerrors.update({i: 0})
        itermeanfscs.update({i: 0})
        itermeanscores3d.update({i: 0})

        print "***************\nStarting iteration number", i
        print "****************"
        previouspath = ''
        if options.iter > 1:
            iterdir = 'iter_' + str(i + 1).zfill(len(str(options.iter)))
            os.system(
                'mkdir ' + originalpath + '/' + iterdir
            )  #C:Make a new subdirectory within options.path only if options.iter > 0
            options.path = originalpath + '/' + iterdir  #C:Update path to include the newly created subdirectory
            previouspath = originalpath + '/iter_' + str(i).zfill(
                len(str(options.iter)))
            if i == 0:
                firstiterdir = options.path
        kk = 0

        statsfile = options.path + '/stats.txt'

        statslines = []

        if len(convergedfs) == len(inputfiles):
            print "\nAll files have converged. Terminating. Line 193"
            break

        fmeanscores2d.update({i: {}})
        fmeanerrors.update({i: {}})
        fmeanfscs.update({i: {}})
        fmeanscores3d.update({i: {}})

        for f in inputfiles:

            fmeanscores2d[i].update({f: [0]})
            fmeanerrors[i].update({f: [0]})
            fmeanfscs[i].update({f: [0]})
            fmeanscores3d[i].update({f: [0]})  #C:Iterate over files

            #originalseries = f

            if i == 0:
                fstats.update({f: list([])})
                print "fmeanfscs is", fmeanfscs
                fmeanfscs[-1].update(
                    {f: [0]}
                )  #Compute initial FSC before any iterations of correction or alignment have occurred
                print "fmeanscores3d is", fmeanscores3d
                fmeanscores3d[-1].update({f: [0]})
                print "set initial -1 fmeanscores3d!!"

            if 'converged' not in fstats[f]:

                if i == 0:
                    if options.tltfile:
                        originalangles = getangles(
                            options)  #C:Read angles from tlt file if available
                    else:
                        originalangles = calcangles(
                            f
                        )  #C:Get the angles of the actual data tilts from the header or calculate from input parameters

                stackfile = options.path + '/' + os.path.basename(f).replace(
                    '.hdf', '_ISR.hdf')

                print "\nWill refine center for file", f
                if i == 0:
                    hdr = EMData(
                        f, 0, True
                    )  #See if angles are in the header of the data, for each file; if not, write them
                    #print "\nRead header and its type", hdr, type(hdr)
                    #print "\nAnd the dictionary", hdr.get_attr_dict()
                    size = hdr['nx']

                    aux = 0
                    if 'spt_tiltangle' not in hdr.get_attr_dict():
                        print "\nspt_tiltangle not in header, therefore will write it by calling writeparamtoheader"
                        aux = writeparamtoheader(f, originalangles,
                                                 'spt_tiltangle')
                        print "\naux returned is", aux
                    else:
                        aux = 1

                    if 'sptisrtx' not in hdr.get_attr_dict(
                    ) or 'sptisrty' not in hdr.get_attr_dict(
                    ) or 'sptisrdr' not in hdr.get_attr_dict():
                        tvals = [0.0 for tt in range(len(originalangles))]

                        auxx = auxy = auxr = 0
                        if 'sptisrtx' not in hdr.get_attr_dict():
                            print "\nsptisrtx not in header, therefore will write it by calling writeparamtoheader"
                            auxx = writeparamtoheader(f, tvals, 'sptisrtx')
                        else:
                            auxx = 1

                        if 'sptisrty' not in hdr.get_attr_dict():
                            print "\nsptisrty not in header, therefore will write it by calling writeparamtoheader"
                            auxy = writeparamtoheader(f, tvals, 'sptisrty')
                        else:
                            auxy = 1

                        if 'sptisrdr' not in hdr.get_attr_dict():
                            print "\nsptisrdr not in header, therefore will write it by calling writeparamtoheader"
                            auxr = writeparamtoheader(f, tvals, 'sptisrdr')
                        else:
                            auxr = 1

                        if auxx and auxy and auxr:
                            aux = 1
                    else:
                        aux = 1

                    if aux:
                        series = {}
                        nimgs = EMUtil.get_image_count(f)
                        for ii in range(nimgs):
                            img = EMData(f, ii)
                            try:
                                angle = img['spt_tiltangle']
                                series.update({angle: img})
                            except:
                                print "ERROR: spt_tiltangle not found in image", ii
                                print "\nHeader is", img.get_attr_dict()
                                sys.exit()

                        retm = makevol(
                            options,
                            f,
                            series,
                            i,
                            originalangles,
                            size,
                            writevols=1,
                            initialfsc=1
                        )  #C:In the first iteration, first reconstruct the tilt series into a 3D volume

                        vol = retm[0]
                        #newvolfile = retm[1]

                        fscarea = retm[2]
                        score3d = retm[3]

                        #fsc = retm[3]
                        #initialfscfilename = options.path + '/' + os.path.basename( f ).replace('.hdf', '_initial_evenOddFSC.txt')

                        fmeanfscs[-1][f].append(fscarea)
                        fmeanscores3d[-1][f].append(score3d)

                        print "\nVol and its type are", vol, type(vol)
                    else:
                        print "ERROR: Something went wrong. spt_tiltangle found in image headers, but somehow is unusuable"
                        sys.exit()

                elif i > 0:
                    #vol = EMData( inputfiles[f][1] )	#C:For iterations > 0 (after the first iteration), the updated volumes
                    #C:for each tilt series should exist from the previous iteration

                    #previousstackfile = previouspath + '/' + os.path.basename(f).replace('.hdf','_IPET.hdf')

                    #print "\n\n\previousstackfile is", previousstackfile
                    #vol = EMData( previousstackfile, 0 )

                    vol = newvol

                #C:Make reprojections from all known angles
                reprojections = reprojectvolume(options, vol, f,
                                                originalangles)

                originalsize = vol['nx']
                retrct = recentertilts(options, reprojections, f,
                                       originalangles, i)
                newseries = retrct[0]
                statsline = retrct[1]
                fscores2d = retrct[2]
                ferrors = retrct[3]

                if ferrors:
                    errorswitch = 1

                #print "fscores2d received", fscores2d
                #print "ferrors received", ferrors
                if ferrors == fscores2d:
                    print "ERROR: errors and scores2d are the same"
                    sys.exit()

                fmeanscore2d = sum(fscores2d) / len(fscores2d)
                fmeanscores2d[i][f].append(fmeanscore2d)

                if ferrors and errorswitch:
                    fmeanerror = sum(ferrors) / len(ferrors)
                    fmeanerrors[i][f].append(fmeanerror)

                #fmeanscores2d.update( i:{ f:fmeanscore2d } )

                statslines.append(statsline)

                line2append = statsline

                #print "fstats[f] and type are", fstats[f], type(fstats[f])
                #sys.exit()
                if statsline in fstats[f]:
                    line2append = 'converged'
                    convergedfs.append(f)

                fstats[f].append(line2append)

                fstats.update({f: fstats[f]})

                retmkvol = makevol(options,
                                   f,
                                   newseries,
                                   i,
                                   originalangles,
                                   originalsize,
                                   writevols=1)

                newvol = retmkvol[0]
                newvolfile = retmkvol[1]

                fscarea = retmkvol[2]
                fmeanfscs[i][f].append(fscarea)

                fmeanscore3d = retmkvol[3]
                fmeanscores3d[i][f].append(fmeanscore3d)

                if i == 0:
                    pass
                    #print "\nEEEEEEEEEEEEEEE\n\n\n\n\nNewvolfile returned is", newvolfile

                newfiles.update({f: [newseries, newvolfile]})
                #newvol.write_image( stackfile, 0 )

                kk += 1

                #firstrawvolfile = firstiterdir + '/' + os.path.basename(f).replace('.hdf','_3D.hdf')
                #fscfile = options.path + '/' + os.path.basename(f).replace('.hdf','FSC.txt')
                #cmdfsc = 'e2proc3d.py ' + firstrawvolfile + ' ' + fscfile + ' --calcfsc=' + newvolfile
                #os.popen( cmdfsc )
            else:
                statsline = fstats[f][-2]
                statslines.append(statsline)

        #Write mean tx, ty and dr of all files to a text file, for each iteration
        f = open(statsfile, 'w')
        f.writelines(statslines)
        f.close()

        inputfiles = newfiles

        iterscores2d = []
        #print "in iteration", i
        #print "fmeanscores2d are",fmeanscores2d
        for ff in fmeanscores2d[i]:
            #print "therefore ff in fmeanscores2d[i] is", ff
            iterscores2d.append(fmeanscores2d[i][ff][-1])

        itermeanscore2d = sum(iterscores2d) / len(iterscores2d)
        itermeanscores2d[i] = itermeanscore2d

        ys = []
        lines = []
        for s in itermeanscores2d:
            y = itermeanscores2d[s]
            ys.append(y)
            #print "appending this y", itermeanscores2d[s]
            line = str(s) + '\t' + str(y) + '\n'
            lines.append(line)

        #if plots:
        fs = open(options.path + '/scores2d_' + str(i + 1) + '.txt', 'w')
        fs.writelines(lines)
        fs.close()

        try:
            if errorswitch:
                itererrors = []
                #print "in iteration", i
                #print "fmeanerrors are",fmeanerrors
                for fscores2df in fmeanerrors[i]:
                    #print "therefore ff in fmeanerrors[i] is", ff
                    itererrors.append(fmeanerrors[i][ff][-1])

                itermeanerror = sum(itererrors) / len(itererrors)
                itermeanerrors[i] = itermeanerror

                yse = []
                linese = []
                for s in itermeanerrors:
                    ye = itermeanerrors[s]
                    yse.append(ye)
                    #print "appending this error", itermeanerrors[s]
                    linee = str(s) + '\t' + str(ye) + '\n'
                    linese.append(linee)

                #if plots:
                fse = open(options.path + '/error_' + str(i + 1) + '.txt', 'w')
                fse.writelines(linese)
                fse.close()
        except:
            pass

        if i == 0:
            iterfscs = []
            #print "in iteration", i
            #print "APPENDING INITIAL fmeanfscs are", fmeanfscs
            for ff in fmeanfscs[-1]:
                #print "therefore INITIAL ff in fmeanfscs[-1] are", ff
                iterfscs.append(fmeanfscs[-1][ff][-1])

            itermeanfsc = sum(iterfscs) / len(iterfscs)
            itermeanfscs[-1] = itermeanfsc

            ysf = []
            linesf = []
            for s in [-1, 0]:
                yf = itermeanfscs[s]
                ysf.append(yf)
                #print "for s", s
                #print "appending this fscarea", itermeanfscs[s]
                linef = str(s + 1) + '\t' + str(yf) + '\n'
                linesf.append(linef)

            #if plots:
            fsf = open(options.path + '/fscsareas_' + str(i + 1) + '.txt', 'w')
            fsf.writelines(linesf)
            fsf.close()

            iterscores3d = []
            #print "in iteration", i
            #print "fmeanscores2d are",fmeanscores2d
            for ff in fmeanscores3d[-1]:
                #print "therefore ff in fmeanscores2d[i] is", ff
                iterscores3d.append(fmeanscores3d[-1][ff][-1])

            itermeanscore3d = sum(iterscores3d) / len(iterscores3d)
            itermeanscores3d[-1] = itermeanscore3d

            ys3 = []
            lines3 = []
            for s in [-1, 0]:
                y3 = itermeanscores3d[s]
                ys3.append(y)
                #print "appending this y", itermeanscores2d[s]
                line3 = str(s + 1) + '\t' + str(y3) + '\n'
                lines3.append(line3)

            #if plots:
            fs = open(options.path + '/scores3d_' + str(i + 1) + '.txt', 'w')
            fs.writelines(lines3)
            fs.close()

        iterfscs = []
        #print "in iteration", i
        #print "fmeanfscs are",fmeanfscs
        for ff in fmeanfscs[i]:
            #print "therefore ff in fmeanfscs[i] are", ff
            iterfscs.append(fmeanfscs[i][ff][-1])

        itermeanfsc = sum(iterfscs) / len(iterfscs)
        itermeanfscs[i] = itermeanfsc

        ysf = []
        linesf = []
        fscsindxs = [s for s in itermeanfscs]
        fscsindxs.sort()
        for s in fscsindxs:
            yf = itermeanfscs[s]
            ysf.append(yf)
            #print "for s", s
            #print "appending this fscarea", itermeanfscs[s]
            linef = str(s + 1) + '\t' + str(yf) + '\n'
            linesf.append(linef)

        #if plots:
        fsf = open(options.path + '/fscsareas_' + str(i + 1) + '.txt', 'w')
        fsf.writelines(linesf)
        fsf.close()

        iterscores3d = []
        #print "in iteration", i
        #print "fmeanscores2d are",fmeanscores2d
        for ff in fmeanscores3d[i]:
            #print "therefore ff in fmeanscores2d[i] is", ff
            iterscores3d.append(fmeanscores3d[i][ff][-1])

        itermeanscore3d = sum(iterscores3d) / len(iterscores3d)
        itermeanscores3d[i] = itermeanscore3d

        ys3 = []
        lines3 = []
        score3dindxs = [s for s in itermeanscores3d]
        score3dindxs.sort()

        for s in score3dindxs:
            y3 = itermeanscores3d[s]
            ys3.append(y)
            #print "appending this y", itermeanscores2d[s]
            line3 = str(s + 1) + '\t' + str(y3) + '\n'
            lines3.append(line3)

        #if plots:
        fs = open(options.path + '/scores3d_' + str(i + 1) + '.txt', 'w')
        fs.writelines(lines3)
        fs.close()

        if i > 0:
            if itermeanscores2d[i] == itermeanscores2d[i - 1]:
                print "The meanscore2d for two consecutive iterations is the same, suggesting the algorithm has converged."
                sys.exit()

            try:
                if itermeanerrors[i] == itermeanerrors[i - 1]:
                    print "The meanerror for two consecutive iterations is the same, suggesting the algorithm has converged."
                    sys.exit()
            except:
                pass

            if itermeanfscs[i] == itermeanfscs[i - 1]:
                print "The fscsarea for two consecutive iterations is the same, suggesting the algorithm has converged."
                sys.exit()

            if itermeanscores3d[i] == itermeanscores3d[i - 1]:
                print "The meanscore3d for two consecutive iterations is the same, suggesting the algorithm has converged."
                sys.exit()

            difscore = math.fabs(
                float(itermeanscores2d[i]) - float(itermeanscores2d[i - 1]))
            if float(difscore) < 0.000001:
                print "In iter %d/%d global score difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                    i + 1, options.iter, difscore)
                sys.exit()

            try:
                diferror = math.fabs(
                    float(itermeanerrors[i]) - float(itermeanerrors[i - 1]))
                if float(difscore) < 0.000001:
                    print "In iter %d/%d global error difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                        i + 1, options.iter, diferror)
                    sys.exit()
            except:
                pass

            diffscarea = math.fabs(
                float(itermeanfscs[i]) - float(itermeanfscs[i - 1]))
            if float(difscore) < 0.000001:
                print "In iter %d/%d global fscarea difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                    i + 1, options.iter, diffscarea)
                sys.exit()

            difscore3d = math.fabs(
                float(itermeanscores3d[i]) - float(itermeanscores3d[i - 1]))
            if float(difscore3d) < 0.000001:
                print "In iter %d/%d global score3dipetResult difference with previous iteration is smaller than 0.000001, see: %f \nExiting program." % (
                    i + 1, options.iter, difscore)
                sys.exit()

    E2end(logger)

    return ()
Beispiel #32
0
def main():

	usage = """e2tomopreproc.py <imgs> <options> . 
	This program takes a tiltseries ('.st' or '.ali' file from IMOD) and applies preprocessing operations to them, such as lowpass, highpass, masking, etc.
	The options should be supplied in "--option=value" format, replacing "option" for a valid option name, and "value" for an acceptable value for that option. 
	"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)	
	
	parser.add_argument("--path",type=str,default='',help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'tomopreproc';
		for example, tomopreproc_02 will be the directory by default if 'tomopreproc_01' 
		already exists.""")
	
	parser.add_pos_argument(name="stack_files",default="",help="Stacks or images to process.")
	
	parser.add_argument("--input",type=str,default='',help=""""tiltseries to process. redundant with --tiltseries, or with providing images as arguments (separated by a space: e2tomopreproc.py stack1.hdf stack2.hdf), but --input takes precedence.""")
	
	parser.add_argument("--tiltseries",type=str,default='',help=""""tiltseries to process. redundant with --input""")

	parser.add_argument("--tltfile",type=str,default='',help="""".tlt file containing the tilt angles for --tiltseries""")
	
	parser.add_argument("--outmode", type=str, default='', help="""All EMAN2 programs write images with 4-byte floating point values when possible by default. This allows specifying an alternate format when supported: float, int8, int16, int32, uint8, uint16, uint32. Values are rescaled to fill MIN-MAX range.""")
	
	parser.add_argument("--dontcleanup", action='store_true', default=False, help="""If specified, intermediate files will be kept.""")
	
	parser.add_argument("--clip",type=str,default='',help="""Default=None. This resizes the 2-D images in the tilt series. If one number is provided, then x and y dimensions will be made the same. To specify both dimensions, supply two numbers, --clip=x,y. Clipping will be about the center of the image.""")
			
	#parser.add_argument("--apix",type=float,default=0.0,help="""True apix of images to be written on final stack.""")
	
	parser.add_argument("--shrink", type=float,default=0.0,help="""Default=0.0 (no shrinking). Can use decimal numbers, larger than 1.0. Optionally shrink the images by this factor. Uses processor math.fft.resample.""")
		
	parser.add_argument("--threshold",type=str,default='',help="""Default=None. A threshold processor applied to each image.""")
	
	parser.add_argument("--mask",type=str,default='', help="""Default=None. Masking processor applied to each image.""")
	
	parser.add_argument("--maskbyangle",action='store_true',default=False,help="""Default=False. Requires --tltfile. This will mask out from tilted images the info that isn't present at the 0 tilt angle. It uses the tomo.tiltedgemask processor (type 'e2help.py processors' at the commandline to read a description of the processor and its parameters). Provide --maskbyanglefalloff and --maskbyanglesigma to modify the default parameters.""")
	
	parser.add_argument("--maskbyanglefalloff", type=int, default=4,help="""Default=4. Number of pixels over which --maskbyangle will fall off to zero.""")
	
	parser.add_argument("--maskbyanglesigma", type=float, default=2.0,help="""Default=2.0. Number of sigmas for the width of the gaussian fall off in --maskbyangle and --maskbyanglefalloff""")
	
	parser.add_argument("--normproc",type=str, default='',help="""Default=None (see 'e2help.py processors -v 10' at the command line). Normalization processor applied to each image.""")
	
	parser.add_argument("--normalizeimod",action='store_true',default=False,help="""Default=False. This will apply 'newstack -float 2' to the input stack. requires IMOD.""")
	
	parser.add_argument("--preprocess",type=str,default='',help="""Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each image.""")
	
	parser.add_argument("--lowpassfrac",type=float,default=0.0,help="""Default=0.0 (not used). Fraction of Nyquist to lowpass at. The processor used is filter.lowpass.tanh""")
	
	parser.add_argument("--highpasspix",type=int,default=0,help="""Default=0 (not used). Number of Fourier pixels to apply highpass filter at. The processor used is filter.highpass.gauss.""")
	
	parser.add_argument("--parallel",type=str, default="thread:1", help="""default=thread:1. Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel""")
	
	parser.add_argument("--prenadminite",type=int, default=0, help="""Default=0. Requires IMOD to be installed. Used to apply prenad filtering to a tiltseries. This is the --minite parameter in IMOD's preNAD program (minimum number of iterations).""")
	
	parser.add_argument("--prenadmaxite",type=int, default=0, help="""Default=0. Requires IMOD to be installed. Used to apply prenad filtering to a tiltseries. This is the --maxite parameter in IMOD's preNAD program (maximum number of iterations).""")
	
	parser.add_argument("--prenadsigma",type=int, default=0, help="""Default=0. Requires IMOD to be installed. Used to apply prenad filtering to a tiltseries. This is the --sigma parameter in IMOD's preNAD program (initial sigma for 'smoothing structure tensor').""")
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")
	
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)

	(options, args) = parser.parse_args()	
	

	logger = E2init(sys.argv, options.ppid)
	print "\n(e2tomopreproc)(main) started log"	
	
	from e2spt_classaverage import sptmakepath
	
	options = sptmakepath(options,'tomopreproc')
	
	#print "args are",args

	infiles = []
	if not options.input:
		#try:
		#	infiles.append( sys.argv[1] )
		#except:
		if options.tiltseries:
			infiles.append( options.tiltseries )
		else:
			if args:
				print "copying args to infiles"
				infiles = list(args)
				print "infiles are", infiles
			else:
				print "\n(e2tomopreproc)(main) ERROR: must provide input files as arguments or via the --input or --tiltseries parameters."


	if infiles:
		print "\n(e2tomopreproc)(main) identified --input", options.input
		#print " .ali in options.input[:-4]", '.ali' in options.input[-4:]
		#print "options.input[-4] is", options.input[-4:]
		
		for infile in infiles:
			if '.ali' in infile[-4:] or '.st' in infile[-3:] or '.mrc' in infile[-4:] or '.mrcs' in infile[-5:] or '.hdf' in infile[-4:]:
				pass
			else:
				print "\n(e2tomopreproc)(main) ERROR: invalid image extension %s for image %s. Extension must be .st, .ali, .hdf, .mrc or .mrcs" %(options.input.split('.')[-1], infile)
				sys.exit(1)
	else:
		print "\n(e2tomopreproc)(main) ERROR: no images found/provided"
		sys.exit(1)
		
	originalextension = infiles[0].split('.')[-1]
	
	angles = {}
	if options.maskbyangle or (options.prenadminite and options.prenadmaxite and options.prenadsigma):
	
		if not options.tltfile:
			print "\n(e2tomopreproc)(main) ERROR: --maskbyangle and --prenad parameters require --tltfile"
			sys.exit(1)
		
		else:
			f = open( options.tltfile, 'r' )
			lines = f.readlines()
			print "\nnumber of lines read from --tltfile", len(lines)
			f.close()
			#print "lines in tlt file are", lines
			k=0
			for line in lines:
				line = line.replace('\t','').replace('\n','')
	
				if line:
					angle = float(line)
					angles.update( { k:angle } )
					if options.verbose:
						print "appending angle", angle
					k+=1
			if len(angles) < 2:
				print "\nERROR: something went terribly wrong with parsing the --tltlfile. This program does not work on single images"
				sys.exit()

		if len(angles) < 2:
			print "\nERROR: (second angle check) something went terribly wrong with parsing the --tltlfile. This program does not work on single images"
			sys.exit()
				
	
	
	
	
	print "\n(e2spt_preproc)(main) - INITIALIZING PARALLELISM!\n"

	from EMAN2PAR import EMTaskCustomer
	etc=EMTaskCustomer(options.parallel)
	pclist=[options.input]

	etc.precache(pclist)
	print "\n(e2spt_preproc)(main) - precaching --input"

	tasks=[]
	results=[]
	
	mrcstacks = []
	print "there are these many infiles to loop over", len(infiles)



	if options.lowpassfrac:
		hdr = EMData( infiles[0], 0, True )
		apix = hdr['apix_x']
		print "\n(e2spt_preproc)(main) apix is",apix
		nyquist = 2.0 * apix
		print "\n(e2spt_preproc)(main) therefore nyquist resolution is", nyquist
		print
		lowpassres = nyquist/options.lowpassfrac
		
		options.lowpassfrac = 1.0/(lowpassres)
		if float(options.shrink) > 1.0:
			options.lowpassfrac /= float(options.shrink)
			
			print "there's shrinking", options.shrink
			lowpassres = nyquist/options.lowpassfrac

		print "\n(e2spt_preproc)(main) and final lowpass frequency is", options.lowpassfrac

		print "corresponding to lowpassres of",lowpassres

	for infile in infiles:
	
		mrcstack = options.path + '/' + infile
		print "infile is", infile
		print "infile[-5:] is ", infile[-5:]
		if '.hdf' in infile[-5:]:
			print "replacing .hdf extension"
			mrcstack = options.path + '/' + infile.replace('.hdf','.mrc')
	
		if '.mrcs' in infile[-5:]:
			print "replacing .mrcs extension"
			mrcstack = options.path + '/' + infile.replace('.mrcs','.mrc')
	
		if '.st' in infile[-5:]:
			print "replacing .st extension"
			mrcstack = options.path + '/' + infile.replace('.st','.mrc')	

		if '.ali' in infile[-5:]:
			print "replacing .ali extension"
			mrcstack = options.path + '/' + infile.replace('.ali','.mrc')
			
		if '.tif' in infile[-5:]:
			print "replacing .ali extension"
			mrcstack = options.path + '/' + infile.replace('.tif','.mrc')
	
		#go = 0
		#if go:
		print "mrcstack is",mrcstack
		
		#outname = outname.replace('.mrc','.mrcs')
	
		mrcstacks.append( mrcstack )
		
		go = 0
		if options.maskbyangle:
			outname = mrcstack.replace('.mrc','_UNSTACKED.mrc')
			print "therefore, outname is", outname
	
			cmd = 'e2proc2d.py ' + infile + ' ' + outname + ' --unstacking --threed2twod'

			#from shutil import copyfile
			#copyfile(options.input, outname)
			#print "copied input to", outname

			if options.outmode:
				cmd += ' --outmode=' + options.outmode

			if options.verbose:
				cmd += ' --verbose=' + str(options.verbose)
				print "\ncommand to unstack original input tiltseries is", cmd	

			print "\n(e2tomopreproc)(main) unstacking command is", cmd

			p = subprocess.Popen( cmd , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			#p = subprocess.Popen( cmd , shell=True, stdout=subprocess.PIPE)

			text = p.communicate()	
			#p.stdout.close()

			p.wait()
		
			if p.returncode == 0:
				go = 1
		else:
			go = 1
	
		
		if go:

			imgs = []
			if options.maskbyangle:
				c = os.getcwd() + '/' + options.path 
				findir = os.listdir( os.getcwd() + '/' + options.path )

				print "\n(e2tomopreproc)(main) directory to look for images is", c	
				for f in findir:
					#if '.mrcs' in f:
					if "_UNSTACKED" in f:
						imgs.append( options.path + '/' +f )

				kk=0
				imgs.sort()
				print "\n(e2spt_preproc)(main) found these many images", len( imgs )		

				for img in imgs:
					#task=None

					#if options.maskbyangle:
					outimage = img.replace('.mrc','_preproc.mrc')
					task = TomoPreproc2DTask( img, options, angles[kk], outimage )
					tasks.append(task)
					kk+=1
			else:
				outimage = options.path + '/' + infile.replace('.mrc','_preproc.mrcs')
				task = TomoPreproc2DTask( infile, options, 0, outimage )
				tasks.append(task)
				
					
			#else:
			#	newmrcs = mrcstack.replace('.mrc','.mrcs')
			#	print "copying file %s to %s" %(infile,newmrcs)
			#	copyfile( infile, newmrcs  )
			#	imgs.append( newmrcs )
			
			

			

				
				#print "and the final lowpass frequency will be", options.lowpassfrac

			

			
	tids = etc.send_tasks(tasks)
	if options.verbose: 
		print "\n(e2spt_preproc)(main) preprocessing %d tasks queued" % (len(tids)) 

	results = get_results( etc, tids, options )

	print "\n(e2tomopreproc)(main) these many images have been processsed",len(results)

	
	imgspreproc = []
	findir = os.listdir( os.getcwd() + '/' + options.path )
	
	#for mrcstack in mrcstacks:


	for f in findir:
		if "_preproc.mrc" in f:
			print "found preprocessed image", f
			imgspreproc.append( options.path + '/' + f )
		else:
			print "this file is NOT a preprocessed image", f

	imgspreproc.sort()

	print "\n(e2tomopreproc)(main) these many preprocessed images loaded", len(imgspreproc)
	
	finalfiles=[]
	
	if options.maskbyangle:
		
		outfile = mrcstack.replace('.mrc','.mrcs')
		print "for RESTACKING"
		print "\n\n\noutfile is", outfile

		for f in imgspreproc:
			print "appending image %s to outfile %s" %(f,outfile)			
			cmd = 'e2proc2d.py ' + f + ' ' + outfile
			if options.outmode:
				cmd += ' --outmode=' + options.outmode

			if options.verbose:
				cmd += ' --verbose ' + str(options.verbose)

			print "\ncmd is with .mrcs outputformat is", cmd
			print "becauase outfile is",outfile	
			p = subprocess.Popen( cmd , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
			text = p.communicate()	
			p.stdout.close()		
	
		finaloutput = outfile.replace('.mrcs', '.' + originalextension)
		os.rename( outfile, finaloutput )
		
		finalfiles.append( finaloutput )
	else:
		finalfiles = list( imgspreproc )
	
	
	for finalf in finalfiles:
		if not options.tltfile:
			break
	
		if options.normalizeimod:
			try:
				cmd = 'newstack ' + finalf + ' ' + finalf + ' --float 2'
				print "normalizeimod cmd is", cmd
				p = subprocess.Popen( cmd , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
				text = p.communicate()	
				p.wait()
			except:
				print "\nERROR: --normalizeimod skipped. Doesn't seem like IMOD is installed on this machine"		

		if not options.dontcleanup and options.maskbyangle:
			purge( options.path, '_preproc.mrc')
			purge( options.path, '_UNSTACKED')	
			purge( options.path, '~')
		
		if options.tltfile:
			if options.prenadminite or options.prenadmaxite or options.prenadsigma:

				if options.prenadminite and options.prenadmaxite and options.prenadsigma:
					cmd = 'preNAD -input ' + finalf + ' -output ' + finalf.replace('.'+originalextension, '_prenad.' + originalextension) + ' -minite ' + str(options.prenadminite) + ' -maxite ' + str(options.prenadmaxite) + ' -sigma ' + str(options.prenadsigma) + ' -angles ' + options.tltfile 
					if options.verbose:
						print "\n(e2tomopreproc)(main) prenad cmd to run is", cmd
					try:
						p = subprocess.Popen( cmd , shell=True,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
						text = p.communicate()	
						p.wait()
					except:
						print "\nERROR: check that a version of IMOD containing the preNAD program is correctly installed on this machine"

				else:
					if options.prenadminite:
						if not options.prenadmaxite:
							print "\nERROR: --prenadmaxite required with --prenadminite"
						if not options.prenadsigma:
							print "\nERROR: --prenadsigma required with --prenadminite"

					if options.prenadmaxite:
						if not options.prenadminite:
							print "\nERROR: --prenadminite required with --prenadmaxite"
						if not options.prenadsigma:
							print "\nERROR: --prenadsigma required with --prenadmaxite"

					if options.prenadsigma:
						if not options.prenadminite:
							print "\nERROR: --prenadminite required with --prenadsigma"
						if not options.prenadmaxite:
							print "\nERROR: --prenadmaxite required with --prenadsigma"
					
		
	E2end(logger)	
	return()
Beispiel #33
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog [options] 
	This program takes a .json file produced by e2spt_classaverage.py and a stack of raw,
	unaligned 3-D images (or "subtomograms") and applies the transforms indicated in the .json file
	to average the particles in the stack.
	Alternatively, if the aligned stack is supplied and there's alignment information in
	the headers of the particles, a .json file with the alignment parameters can be produced.
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--input",
        default='',
        type=str,
        help="The name of the hdf stack of volumes to process.")
    #parser.add_argument("--output", default="avg.hdf",type=str, help="The name of the output average volume.")
    parser.add_argument(
        "--rotationtype",
        default="eman",
        type=str,
        help=
        "Valid options are: eman,imagic,mrc,spider,quaternion,sgirot,spi,xyz")

    parser.add_argument(
        "--averager",
        type=str,
        help=
        "The type of averager used to produce the class average. Default=mean",
        default="mean")

    parser.add_argument(
        "--sym",
        type=str,
        default='',
        help=
        "Symmetry to impose - choices are: c<n>, d<n>, h<n>, tet, oct, icos")

    parser.add_argument(
        "--path",
        default='',
        type=str,
        help="Name of directory where to save the output file.")
    parser.add_argument(
        "--alifile",
        default='',
        type=str,
        help=
        ".json file with alingment parameters, if raw stack supplied via --input."
    )
    parser.add_argument("--extractcoords",
                        default=False,
                        action='store_true',
                        help="""If you
		provide this option, a coordinates file can be written with the original coordinates
		stored on the header of a subtomogram stack""")

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)
    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )

    parser.add_argument("--saveali",
                        action="store_true",
                        default=False,
                        help="""If set, will save the 
		aligned particle volumes.""")

    parser.add_argument(
        "--extractsymsearch",
        action="store_true",
        default=False,
        help=
        """If set, this will look for the symxform among the particles' header parameters to produce a .json file with alignment info from e2symsearch3d.py. Works only if --alifile is NOT provided."""
    )

    (options, args) = parser.parse_args()

    if options.averager:
        options.averager = parsemodopt(options.averager)

    if not options.input:
        parser.print_help()
        sys.exit(0)

    #if ".hdf" not in options.output and ".mrc" not in options.output:
    #	print "ERROR. The output must contain a valid format ending, for example '.hdf.' TERMINATING!"
    #	sys.exit()

    if ".hdf" not in options.input:
        print "ERROR. HDF is the only supported input format."
        sys.exit()

    logid = E2init(sys.argv, options.ppid)

    n = EMUtil.get_image_count(options.input)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'sptextractali')

    if options.extractcoords:
        lines = []
        tomograms = {}
        for i in range(n):
            #You only need to load the ptcl header
            a = EMData(options.input, i, True)

            coords = a['ptcl_source_coord']
            tomogram = a['ptcl_source_image']
            try:
                tomogram = a['spt_tomogram']
            except:
                pass

            if tomogram not in tomograms:
                print "Indentified a new tomogram", tomogram
                tomograms.update({tomogram: []})

            line = str(coords[0]) + ' ' + str(coords[1]) + ' ' + str(
                coords[2]) + '\n'
            #lines.append(line)
            print "Line of coordinates to add", line
            tomograms[tomogram].append(line)

        for tomogram in tomograms.keys():
            #coordsfile = options.path + '/' + options.input.replace('.hdf','_coords.txt')
            coordsfile = options.path + '/' + tomogram.split(
                '.')[0] + '_coords.txt'

            f = open(coordsfile, 'w')
            f.writelines(tomograms[tomogram])
            f.close()

    if not options.alifile:
        a = Transform({"type": "eman", "alt": 1.0})
        #k=list(a.get_rotation(sys.argv[2]).keys())

        #k=list(a.get_rotation( options.rotationtype ).keys())

        #k.remove("type")
        #if len(k)==3:
        #	print "#{},{},{}".format(*k)
        #else:
        #	print "#{},{},{},{}".format(k)

        jsAliParamsPath = options.path + '/xform_align3d.json'
        jsA = js_open_dict(jsAliParamsPath)
        if options.extractsymsearch:
            symjsAliParamsPath = options.path + '/symxform.json'
            symjsA = js_open_dict(symjsAliParamsPath)

        for i in range(n):
            #You only need to load the header
            im = EMData(options.input, i, True)
            #xf=im["spt_ali_param"]

            xf = im['xform.align3d']
            #score=1.0

            score = im['spt_score']
            if options.extractsymsearch:
                symxformslabel = 'subtomo_' + str(i).zfill(len(str(n)))
                symxf = Transform()

                try:
                    symxf = im['symxform']
                    #symscore=im['spt_symsearch_score']

                except:
                    print "\nERROR: particle %d does not have 'symxform' parameter in its header. Defaulting to identity transform."
                symjsA.setval(symxformslabel, [symxf, score])

            xformslabel = 'subtomo_' + str(0).zfill(len(str(n)))
            jsA.setval(xformslabel, [xf, score])

            #r=xf.get_rotation( options.rotationtype )
            #print "{}".format(i),
            #for j in k:
            #	print ", {}".format(r[j]),
            #print ""

        jsA.close()
        if options.extractsymsearch:
            symjsA.close()

    elif options.alifile:
        preOrientationsDict = js_open_dict(options.alifile)

        avgr = Averagers.get(options.averager[0], options.averager[1])

        for i in range(n):
            print "reading particle"
            a = EMData(options.input, i)

            ptcl = a.copy()
            '''
			#The first case works with .json files from e2spt_hac.py
			#The second works for .json files from e2spt_classaverage.py
			try:
				ID=unicode(i)
				#print "ID is", ID
				t = preOrientationsDict[0][ID]
				#print "t 1 is",t
			except:
				ID='subtomo_' + str(i).zfill(len(str(n)))
				#print "ID is", ID
				t = preOrientationsDict[ID][0]
				#print "t 2 is", t
			'''
            ID = 'subtomo_' + str(i).zfill(len(str(n)))
            t = preOrientationsDict[ID][0]
            print "\nfor particle", i
            print "transform is", t

            ptcl['origin_x'] = 0
            ptcl['origin_y'] = 0
            ptcl['origin_z'] = 0
            ptcl['xform.align3d'] = Transform()

            if t:
                ptcl.transform(t)
                ptcl['xform.align3d'] = t
                alistack = os.path.basename(options.input).replace(
                    '.hdf', '_ali.hdf')
                if options.saveali:
                    print "\nsaving aligned particle", i
                    ptcl.write_image(options.path + '/' + alistack, i)

            avgr.add_image(ptcl)

            #if options.saveali:

            #pass

        avg = avgr.finish()

        if options.sym and options.sym is not 'c1' and options.sym is not 'C1':
            avg.process_inplace('xform.applysym', {'sym': options.sym})
        avg.process_inplace('normalize.edgemean')

        output = os.path.basename(options.input).replace('.hdf', '_recomp.hdf')
        avg.write_image(options.path + '/' + output, 0)

        preOrientationsDict.close()

    E2end(logid)

    return
Beispiel #34
0
def main():

    progname = os.path.basename(sys.argv[0])
    usage = """WARNING:  **PRELIMINARY** program, still heavily under development. 
				Autoboxes globular particles from tomograms.
				Note that self-generated spherical templates generated by this program
				are 'white'; which means you have to provide the tomogram with inverted (or 'white') contrast, and the same goes for any stacks
				provided (specimen particles, gold, carbon and/or background)."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--parallel",
        type=str,
        default='',
        help=
        """Default=Auto. This program will detect the number of CPU cores on your machine and parallelize some of the tasks using all of them. To disable, provide --parallel=None"""
    )

    parser.add_argument(
        "--input",
        type=str,
        default='',
        help="""Default=None. HDF stack of volumes to translate""")

    parser.add_argument(
        "--alistack",
        type=str,
        default='',
        help=
        """Default=None. HDF stack of volumes with alignment parameters on the header from which translations will be read and applied to --input."""
    )

    parser.add_argument(
        "--alifile",
        type=str,
        default='',
        help=
        """.json file from where to read alignment parameters. Alternative to --alistack."""
    )

    parser.add_argument(
        "--path",
        default='',
        type=str,
        help=
        "Default=spttranslate. Name of directory where to save the output file."
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness")

    parser.add_argument(
        "--subset",
        type=int,
        default=0,
        help="""default=0 (not used). Subset of particles to process.""")
    (options, args
     ) = parser.parse_args()  #c:this parses the options or "arguments" listed
    #c:above so that they're accesible in the form of option.argument;
    #c:for example, the input for --template would be accesible as options.template

    logger = E2init(
        sys.argv, options.ppid
    )  #c:this initiates the EMAN2 logger such that the execution
    #of the program with the specified parameters will be logged
    #(written) in the invisible file .eman2log.txt
    '''
	c:make a directory to store output generated by this program
	'''
    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'spttranslate')

    n = EMUtil.get_image_count(options.input)
    orign = n
    print "\nnumber of particles in stack %s is %d" % (options.input, n)

    if options.subset:
        n = options.subset

    if options.alistack:
        n2 = EMUtil.get_image_count(options.alistack)
        if n > n2:
            print """\nERROR: there are fewer particles in --alistack, %d, than in --input, %d. 
				Use --subset and set it to a number equal to or smaller than the number or particles in --alistack""" % (
                n2, n)
            sys.exit(1)

    if options.alifile:
        preOrientationsDict = js_open_dict(options.alifile)

    txs = []
    tys = []
    tzs = []
    trs = []

    outstack = options.path + '/' + os.path.basename(options.input).replace(
        '.hdf', '_trans.hdf')

    for i in range(n):
        print "\nreading particle %d" % (i)
        a = EMData(options.input, i)

        ptcl = a.copy()

        t = None
        if options.alifile:
            ID = 'subtomo_' + str(i).zfill(len(str(orign)))
            t = preOrientationsDict[ID][0]
        elif options.alistack:
            b = EMData(options.alistack, i, True)
            t = b['xform.align3d']

        ptcl['origin_x'] = 0
        ptcl['origin_y'] = 0
        ptcl['origin_z'] = 0
        ptcl['xform.align3d'] = Transform()

        if t:
            print "transform is t", t
            trans = t.get_trans()
            rot = t.get_rotation()

            az = rot['az']
            alt = rot['alt']
            phi = rot['phi']

            trot = Transform({
                'type': 'eman',
                'az': az,
                'alt': alt,
                'phi': phi
            })
            troti = trot.inverse()

            transi = troti * trans  #translations are in the frame of the rotated particle.
            #to apply translations only, you need to convert them to the unrotated frame

            tx = transi[0]
            txs.append(math.fabs(tx))

            ty = transi[1]
            tys.append(math.fabs(ty))

            tz = transi[2]
            tzs.append(math.fabs(tz))

            tr = math.sqrt(tx * tx + ty * ty + tz * tz)
            trs.append(tr)

            newt = Transform({'type': 'eman', 'tx': tx, 'ty': ty, 'tz': tz})
            print "new transform is", newt

            ptcl.transform(newt)
            ptcl['xform.align3d'] = newt
            #if options.saveali:
            print "\nsaving translated particle", i
            ptcl.write_image(outstack, i)

    outavg = options.path + '/' + os.path.basename(options.input).replace(
        '.hdf', '_trans_avg.hdf')
    cmd = 'e2proc3d.py ' + outstack + ' ' + outavg + ' --average'
    cmd += ' && e2proc3d.py ' + outavg + ' ' + outavg + ' --process normalize.edgemean'
    os.system(cmd)

    if options.alifile:
        preOrientationsDict.close()

    from e2spt_classaverage import textwriter

    if txs:
        txs.sort()
        textwriter(txs, options, 'x_trans.txt')

    if tys:
        tys.sort()
        textwriter(tys, options, 'y_trans.txt')

    if tzs:
        tzs.sort()
        textwriter(tzs, options, 'z_trans.txt')

    if trs:
        trs.sort()
        textwriter(trs, options, 'r_trans.txt')

    E2end(logger)

    return
Beispiel #35
0
def main():

    usage = """e2spt_tiltstacker.py <options> . 
	The options should be supplied in "--option=value" format, 
	replacing "option" for a valid option name, and "value" for an acceptable value for that option. 
	
	This program operates in 3 different modes:
	1) It can STACK individual .dm3, .tiff or .hdf images into an .mrc (or .st) stack,
	by supplying a common string to all the images to stack via --stem2stack.
	It must be run in a directory containing the numbered images only.
	It also generates a .rawtlt file with tilt angle values if --lowerend, --upperend and --tiltstep are provided.
	
	2) It can UNSTACK a tilt series into individual files (either all the images, or selected
	images, controlled through the --exclude or --include parameters).
	
	3) It can RESTACK a tilt series; that is, put together a new tilt series that excludes/includes
	specific images
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument("--path",
                        type=str,
                        default='',
                        help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'sptstacker';
		for example, sptstacker_02 will be the directory by default if 'sptstacker_01' 
		already exists.""")

    parser.add_argument("--stem2stack",
                        type=str,
                        default='',
                        help="""String common to all 
		the files to put into an .st stack, which is in .MRC format; for example, --stem2stack=.hdf 
		will process all .hdf files in the current directory.
		If not specified, all valid EM imagefiles in the current directory will be put into 
		an .st stack.""")

    parser.add_argument(
        "--anglesindxinfilename",
        type=int,
        default=None,
        help=
        """Default=None. The filename of the images will be split at any occurence of 
		the following delimiters: '_','-',',',' ' (the last one is a blank space). Provide the index (position) of the angle in the split filename.
		For example, if the filename of an image is "my_specimen-oct-10-2015_-50_deg-from_k2 camera.mrc", it will be split
		into ['my','specimen','oct','10','2015','','50','deg','from','k2','camera','mrc']. The angle '-50', is at position 6 (starting from 0). Therefore,
		you would provide --anglesindxinfilename=6, assuming all images to be stacked/processed are similarly named. No worries about the minus sign 
		disappearing. The program will look at whether there's a minus sign immediately preceeding the position where the angle info is."""
    )

    parser.add_argument("--tltfile",
                        type=str,
                        default='',
                        help="""".tlt file IF unstacking an
		aligned tilt series with --unstack=<stackfile> or restacking a tiltseries with
		--restack=<stackfile>""")

    parser.add_argument("--invert",
                        action="store_true",
                        default=False,
                        help=""""This 
		will multiply the pixel values by -1.""")

    parser.add_argument("--stackregardless",
                        action="store_true",
                        default=False,
                        help=""""Stack
		images found with the common string provided through --stem2stack, even if the
		number of images does not match the predicted number of tilt angles.""")

    parser.add_argument("--outmode",
                        type=str,
                        default="float",
                        help="""All EMAN2 programs 
		write images with 4-byte floating point values when possible by default. This allows 
		specifying an alternate format when supported: float, int8, int16, int32, uint8, 
		uint16, uint32. Values are rescaled to fill MIN-MAX range.""")

    parser.add_argument(
        "--normalizeimod",
        action='store_true',
        default=False,
        help=
        """Default=False. This will apply 'newstack -float 2' to the input stack. Requires IMOD. Does not apply to --unstack or --restack."""
    )

    parser.add_argument("--bidirectional",
                        action='store_true',
                        default=False,
                        help="""This will
		assume the first image is at 0 degrees and will stack images from --lowerend through 0, 
		and then will stack the rest from 0+tiltstep throgh --upperend. 
		If --negativetiltseries is supplied, images will be stacked from --upperend through 0, then 
		from 0-tiltstep through --lowerend.""")

    parser.add_argument("--lowesttilt",
                        type=float,
                        default=0.0,
                        help="""Lowest tilt angle.
		If not supplied, it will be assumed to be -1* --tiltrange.""")

    parser.add_argument("--highesttilt",
                        type=float,
                        default=0.0,
                        help="""Highest tilt angle.
		If not supplied, it will be assumed to be 1* --tiltrange.""")

    parser.add_argument("--tiltrange",
                        type=float,
                        default=0.0,
                        help="""If provided, this
		will make --lowesttilt=-1*tiltrange and --highesttilt=tiltrage.
		If the range is asymmetric, supply --lowesttilt and --highesttilt directly."""
                        )

    parser.add_argument("--tiltstep",
                        type=float,
                        default=0.0,
                        help="""Step between tilts.
		Required if using --stem2stack.""")

    parser.add_argument("--clip",
                        type=str,
                        default='',
                        help="""Resize the 2-D images in the
		tilt series. If one number is provided, then x and y dimensions will be made the same.
		To specify both dimensions, supply two numbers, --clip=x,y. Clipping will be about
		the center of the image.""")

    parser.add_argument("--apix",
                        type=float,
                        default=0.0,
                        help="""True apix of images to be 
		written on final stack.""")

    parser.add_argument("--unstack",
                        type=str,
                        default='',
                        help=""".hdf, or 3D .st, .mrc, 
		.ali, or .mrcs stack file to unstack.
		This option can be used with --include or --exclude to unstack only specific images.
		Recall that the FIRST image INDEX is 0 (but unstacked image will be numbered from 1). 
		--exclude=1,5-7,10,12,15-19 will exclude images 1,5,6,7,10,12,15,16,17,18,19"""
                        "")

    parser.add_argument("--restack",
                        type=str,
                        default='',
                        help=""".hdf, or 3D .st, .mrc, 
		.ali, or .mrcs stack file to restack.
		This option can be used with --include or --exclude to unstack only specific images.
		Recall that the FIRST image INDEX is 0 (but unstacked image will be numbered from 1). 
		--exclude=1,5-7,10,12,15-19 will exclude images 1,5,6,7,10,12,15,16,17,18,19"""
                        "")

    parser.add_argument("--mirroraxis",
                        type=str,
                        default='',
                        help="""Options are x or y, and the
		mirrored copy of the 2-D images will be generated before being put into the tilt series."""
                        )

    parser.add_argument("--exclude",
                        type=str,
                        default='',
                        help="""Comma separated list of numbers
		corresponding to images to exclude. --unstack or --restack must be supplied. 
		You can also exclude by ranges. For example:
		Recall that the FIRST image INDEX is 0. 
		--exclude=1,5-7,10,12,15-19 will exclude images 1,5,6,7,10,12,15,16,17,18,19"""
                        )

    parser.add_argument("--include",
                        type=str,
                        default='',
                        help="""Comma separated list of numbers
		corresponding to images to include (all others will be excluded). 
		--unstack or --restack must be supplied. 
		Recall that the FIRST image INDEX is 0. 
		--include=1,5-7,10,12,15-19 will include images 1,5,6,7,10,12,15,16,17,18,19"""
                        )

    #parser.add_argument("--negativetiltseries",action='store_true',default=False,help="""This indicates that the tilt series goes from -tiltrange to +tiltrange, or 0 to -tiltrange, then +tiltstep to +tiltrange if --bidirectional is specified.""")

    #parser.add_argument("--negative",action='store_true',default=False,help="""This indicates that the tilt series goes from -tiltrange to +tiltrange, or 0 to -tiltrange, then +tiltstep to +tiltrange if --bidirectional is specified.""")

    parser.add_argument(
        "--negativetiltseries",
        action='store_true',
        default=False,
        help=
        """This indicates that the tilt series goes from -tiltrange to +tiltrange, or 0 to -tiltrange, then +tiltstep to +tiltrange if --bidirectional is specified."""
    )

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    (options, args) = parser.parse_args()

    print "--negativetiltseries", options.negativetiltseries

    if options.exclude and options.include:
        print "\nERROR: Supplied either exclude or include. Cannot supply both at the same time."
        sys.exit()

    print "\nLogging"
    logger = E2init(sys.argv, options.ppid)

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'sptstacker')

    options.path = os.getcwd() + '/' + options.path

    tiltstoexclude = options.exclude.split(',')

    if options.stem2stack:
        if not options.anglesindxinfilename:
            if not options.tiltstep:
                print "ERROR: --tiltstep required when using --stem2stack, unless --anglesindxinfilename is provided"
                sys.exit()

    if options.lowesttilt == 0.0 and options.tiltrange:
        options.lowesttilt = -1 * options.tiltrange

    if options.highesttilt == 0.0 and options.tiltrange:
        options.highesttilt = options.tiltrange

    if options.unstack:
        if options.tltfile:
            usntacker(options)
        else:
            print "ERROR: --tltfile required when using --unstack"
            sys.exit()

    elif options.restack:
        if options.tltfile:
            restacker(options)
            angles = getangles(
                options, True
            )  #Second parameter enforces to keep the 'raw order' of the input file. Otherwise, this function returns angles from -tiltrange to +tiltrange if --negativetiltseries is supplied; from +tiltrange to -tiltrange otherwise

            #finalangles = list(angles)
            #anglestoexclude = []

            print "\n\nthere are these many angles", len(angles)
            #if tiltstoexclude:
            #	for tilt in tiltstoexclude:
            #		anglestoexclude.append( angles[ int(tilt) ] )
            #		finalangles.remove( angles[ int(tilt) ] )
            #	#for ax in anglestoexclude:
            #	#	finalangles.remove( ax )
            #
            #	print "\n\nthere are these many angles to exclude",len(anglestoexclude)
            #	print "\nexcluded angles",anglestoexclude
            #
            #	#finalangles = list( set(angles) - set(anglestoexclude) )

            #print "\nthere are these many final angles",len(finalangles)
            #print "\nfinal angles are", finalangles

            writetlt(angles, options, True)
        else:
            print "ERROR: --tltfile required when using --restack"
            sys.exit()

    else:
        kk = 0
        intilts = findtiltimgfiles(options)

        print "\nWill organize tilt imgs found"
        intiltsdict = organizetilts(
            intilts, options
        )  #Get a dictionary in the form { indexintiltseries:[ tiltfile, tiltangle, damageRank ]},
        print "\nDone organizing tilt imgs"  #where damageRank tells you the order in which the images where acquired
        #regardless of wether the tilt series goes from -tiltrange to +tiltrange,
        #or 0 to -tiltrange then +tiltstep to +tiltrange, or the opposite of these
        outstackhdf = options.path + '/stack.hdf'

        minindx = min(intiltsdict)
        print "minindx is", minindx
        print "getting size from any first image, intiltsdict[ minindx ][0]", intiltsdict[
            minindx][0]

        hdr = EMData(intiltsdict[minindx][0], 0, True)
        nx = hdr['nx']
        ny = hdr['ny']
        print nx, ny

        print "\nOutstack is", outstackhdf

        #orderedindexes = []
        #for index in intiltsdict:
        #	orderedindexes.append( index )

        #orderedindexes.sort()

        for index in intiltsdict:

            if str(index) not in tiltstoexclude:
                intiltimgfile = intiltsdict[index][0]

                print "\nat index %d we have image %s, collected in this turn %d" % (
                    index, intiltsdict[index][0], intiltsdict[index][-1])
                intiltimg = EMData(intiltimgfile, 0)

                tiltangle = intiltsdict[index][1]
                intiltimg['spt_tiltangle'] = tiltangle

                damageRank = intiltsdict[index][2]
                intiltimg['damageRank'] = damageRank

                if options.invert:
                    intiltimg.mult(-1)
                intiltimg.write_image(outstackhdf, -1)
                print "\nWrote image index", index

        if options.clip:
            clip = options.clip.split(',')

            shiftx = 0
            shifty = 0
            if len(clip) == 1:
                clipx = clipy = clip[0]

            if len(clip) == 2:
                clipx = clip[0]
                clipy = clip[1]

            if len(clip) == 4:
                clipx = clip[0]
                clipy = clip[1]
                shiftx = clip[2]
                shifty = clip[3]

            tmp = options.path + '/tmp.hdf'
            cmdClip = 'e2proc2d.py ' + outstackhdf + ' ' + tmp + ' --clip=' + clipx + ',' + clipy

            if shiftx:
                xcenter = int(round(nx / 2.0 + float(shiftx)))
                cmdClip += ',' + str(xcenter)
            if shifty:
                ycenter = int(round(ny / 2.0 + float(shifty)))
                cmdClip += ',' + str(ycenter)

            cmdClip += ' && rm ' + outstackhdf + ' && mv ' + tmp + ' ' + outstackhdf

            print "\n(e2spt_tiltstacker.py)(main) cmdClip is", cmdClip
            p = subprocess.Popen(cmdClip,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            text = p.communicate()
            p.stdout.close()

            if options.verbose > 9:
                print "\nFeedback from cmdClip:"
                print text

        outtilthdr = EMData(outstackhdf, 0, True)
        currentapix = outtilthdr['apix_x']
        if float(options.apix) and float(options.apix) != float(currentapix):
            print "\nFixing apix"
            cmdapix = 'e2fixheaderparam.py --input=' + outstackhdf + ' --stem=apix --valtype=float --stemval=' + str(
                options.apix)

            print "\n(e2spt_tiltstacker.py)(main) cmdapix is", cmdapix
            p = subprocess.Popen(cmdapix,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            text = p.communicate()
            p.stdout.close()

            if options.verbose > 9:
                print "\nFeedback from cmdapix:"
                print text

        outstackst = outstackhdf.replace('.hdf', '.st')
        stcmd = 'e2proc2d.py	' + outstackhdf + ' ' + outstackst + ' --twod2threed'
        if options.outmode != 'float':
            stcmd += ' --outmode=' + options.outmode + ' --fixintscaling=sane'

        if options.apix:
            stcmd += ' --apix=' + str(options.apix)
            stcmd += ' && e2fixheaderparam.py --input=' + outstackst + ' --stem=apix --valtype=float --stemval=' + str(
                options.apix) + ' --output=' + outstackst.replace(
                    '.st', '.mrc') + " && mv " + outstackst.replace(
                        '.st', '.mrc') + ' ' + outstackst

        stcmd += ' && rm ' + outstackhdf

        print "\n(e2spt_tiltstacker.py)(main) stcmd is", stcmd
        p = subprocess.Popen(stcmd,
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        text = p.communicate()
        p.stdout.close()

        if options.normalizeimod:
            try:
                cmd = 'newstack ' + outstackst + ' ' + outstackst + ' --float 2'
                print "normalizeimod cmd is", cmd
                p = subprocess.Popen(cmd,
                                     shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
                text = p.communicate()
                p.wait()
            except:
                print "\nERROR: --normalizeimod skipped. Doesn't seem like IMOD is installed on this machine"

        if options.verbose > 9:
            print "\nFeedback from stcmd:"
            print text

        if options.mirroraxis:
            print "\nMirroring across axis", options.mirroraxis
            mirrorlabel = options.mirroraxis.upper()
            outstackstmirror = outstackst.replace(
                '.st', '_mirror' + mirrorlabel + '.st')

            cmdMirror = 'e2proc2d.py ' + outstackst + ' ' + outstackstmirror + ' --process=xform.mirror:axis=' + options.mirroraxis

            if options.outmode != 'float':
                cmdMirror += ' --outmode=' + options.outmode + ' --fixintscaling=sane'

            print "options.apix is", options.apix
            if options.apix:
                cmdMirror += ' --apix=' + str(options.apix)
                cmdMirror += ' && e2fixheaderparam.py --input=' + outstackstmirror + ' --stem=apix --valtype=float --stemval=' + str(
                    options.apix) + ' --output=' + outstackstmirror.replace(
                        '.st', '.mrc') + " && mv " + outstackstmirror.replace(
                            '.st', '.mrc') + ' ' + outstackstmirror

                print "added fixheaderparam to cmdMirror!"

            print "cmdMirror is", cmdMirror
            p = subprocess.Popen(cmdMirror,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            text = p.communicate()

            if options.verbose > 9:
                print "\nFeedback from cmdMirror:"
                print text
                p.stdout.close()

    E2end(logger)
    return
Beispiel #36
0
def main():

    usage = """e2orthoproject.py <options> . 
			The options should be supplied in "--option=value", replacing "option" for a valid option name, and "value" for an acceptable value for that option. 
			This program produces orthogonal projections of an EM volume.
			"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument(
        "--path",
        type=str,
        default=None,
        help=
        """Directory to store results in. The default is a numbered series of directories containing the prefix 'orthoproject';
														for example, orthoproject_02 will be the directory by default if 'orthoproject_01' already exists."""
    )

    parser.add_argument(
        "--onlyx",
        action='store_true',
        default=False,
        help=
        "Only projection of the YZ plane will be generated [a 'side view'].")
    parser.add_argument(
        "--onlyy",
        action='store_true',
        default=False,
        help=
        "Only projection of the XZ plane will be generated [another 'side view']."
    )
    parser.add_argument(
        "--onlyz",
        action='store_true',
        default=False,
        help="Only projection of the XY plane will be generated a 'top view']")

    parser.add_argument(
        "--shrink",
        type=int,
        default=False,
        help=
        "Integer value to shrink the models by before generating projections.")

    parser.add_argument(
        "--saverotvol",
        action='store_true',
        default=False,
        help=
        "Will save the volume in each rotated position used to generate a projection."
    )

    parser.add_argument(
        "--input",
        type=str,
        help=
        """The name of the input volume from which you want to generate orthogonal projections.
													You can supply more than one model either by providing an .hdf stack of models, or by providing multiple files
													separated by commas.""",
        default=None)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    parser.add_argument(
        "--mask",
        type=str,
        help=
        "Mask processor applied to particles before alignment. Default is None",
        default=None)
    parser.add_argument(
        "--lowpass",
        type=str,
        help=
        "A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.",
        default=None)

    parser.add_argument(
        "--transformsfile",
        type=str,
        help=
        "A text files containing lines with one triplet of az,alt,phi values each, representing the transforms to use to project a single volume supplied. ",
        default='')
    parser.add_argument(
        "--angles",
        type=str,
        help=
        "A single comma or space separated triplet of az,alt,phi values representing the particle rotation to apply before projecting it.",
        default='')
    parser.add_argument(
        "--tag",
        type=str,
        help=
        "When supplying --angles, tag the output projection with a string provided through --tag",
        default='')

    parser.add_argument(
        "--normproc",
        type=str,
        help="""Normalization processor applied to particles before alignment. 
													Default is to use normalize.mask. If normalize.mask is used, results of the mask option will be passed in automatically. 
													If you want to turn this option off specify \'None\'""",
        default="normalize.edgemean")

    (options, args) = parser.parse_args()

    if not options.input:
        print "ERROR: Supply volume(s) through --input=."
        sys.exit()

    if options.transformsfile:
        n = EMUtil.get_image_count(options.input)
        if n > 1:
            print "ERROR: You cannot supply --transformsfile for particle stacks; it only works for individual volumes."
            sys.exit()

    logger = E2init(sys.argv, options.ppid)

    if options.mask:
        options.mask = parsemodopt(options.mask)

    if options.lowpass:
        options.lowpass = parsemodopt(options.lowpass)

    if options.normproc:
        options.normproc = parsemodopt(options.normproc)
    '''
	Check for sanity of some supplied parameters
	'''

    if options.onlyz:
        if options.onlyx or options.onlyy:
            print "ERROR: You can only supply one of --onlyx, --onlyy or --onlyz at a time."
            sys.exit()

    if options.onlyx:
        if options.onlyy or options.onlyz:
            print "ERROR: You can only supply one of --onlyx, --onlyy or --onlyz at a time."
            sys.exit()

    if options.onlyy:
        if options.onlyx or options.onlyz:
            print "ERROR: You can only supply one of --onlyx, --onlyy or --onlyz at a time."
            sys.exit()
    '''
	Make a directory where to store the results
	'''

    from e2spt_classaverage import sptmakepath
    options = sptmakepath(options, 'orthoprjs')

    if options.onlyz and options.onlyx:
        print "ERROR: Cannot supply --onlyz and --onlyx at the same time"
        sys.exit()
    if options.onlyz and options.onlyy:
        print "ERROR: Cannot supply --onlyz and --onlyy at the same time"
        sys.exit()
    if options.onlyy and options.onlyx:
        print "ERROR: Cannot supply --onlyy and --onlyx at the same time"
        sys.exit()
    '''
	Generate projection transforms
	'''

    projectiondirections = []

    if options.onlyz:
        pz = Transform({'type': 'eman', 'az': 0, 'alt': 0, 'phi': 0})
        projectiondirections = {'pz': pz}
    elif options.onlyx:
        px = Transform({'type': 'eman', 'az': 90, 'alt': -90, 'phi': 0})
        projectiondirections = {'px': px}
    elif options.onlyy:
        py = Transform({'type': 'eman', 'az': 0, 'alt': 90, 'phi': 0})

        projectiondirections = {'py': py}
    else:
        pz = Transform({'type': 'eman', 'az': 0, 'alt': 0, 'phi': 0})
        px = Transform({'type': 'eman', 'az': 90, 'alt': -90, 'phi': 0})
        py = Transform({'type': 'eman', 'az': 0, 'alt': 90, 'phi': 0})
        projectiondirections = {'pz': pz, 'px': px, 'py': py}

    if options.transformsfile:
        f = open(options.transformsfile, 'r')
        lines = f.readlines()
        f.close()

        np = len(lines)
        k = 0
        for line in lines:
            line = line.replace(',', ' ')
            line = line.replace('\n', '')
            line = line.replace('\t', ' ')
            line = line.split()
            t = Transform({
                'type': 'eman',
                'az': float(line[0]),
                'alt': float(line[1]),
                'phi': float(line[2])
            })
            tag = 'p' + str(k).zfill(len(str(np)))
            projectiondirections.update({tag: t})
            k += 1

    #elif options.angles:
    #	angles=options.angles
    #	angles=angles.replace(',',' ')
    #	angles=angles.split()
    #	t=Transform({'type':'eman','az':float(angles[0]),'alt':float(angles[1]),'phi':float(angles[2])})

    #	tag = 'p' + 'az' + str(int(round(float( angles[0] )))) + 'alt' + str(int(round(float( angles[1] ))))  + 'phi' + str(int(round(float( angles[2] ))))
    #	if options.tag:
    #		tag = options.tag

    #projectiondirections.update({ tag:t })
    '''
	Read input
	'''
    models = options.input.split(',')

    rootpath = os.getcwd()
    path = rootpath + '/' + options.path

    for model in models:
        n = EMUtil.get_image_count(model)

        newpath = path
        if len(models) > 1:
            newpath = path + '/' + model.split('.hdf')[0]
            os.system('mkdir ' + newpath)

        kstack = 0
        for i in range(n):
            subpath = newpath
            submodelname = subpath + '/' + model.split('.')[0] + '_prjs.hdf'
            if n > 1:
                if not options.onlyx and not options.onlyy and not options.onlyz:
                    subpath = newpath + '/ptcl' + str(i).zfill(len(str(n)))
                    os.system('mkdir ' + subpath)
                    submodelname = subpath + '/' + model.split(
                        '.')[0] + '_ptcl' + str(i).zfill(len(
                            str(n))) + '_prjs.hdf'
                else:
                    if options.onlyx:
                        submodelname = subpath + '/' + model.split(
                            '.hdf')[0] + '_Xprjs.hdf'
                    if options.onlyy:
                        submodelname = subpath + '/' + model.split(
                            '.hdf')[0] + '_Yprjs.hdf'
                    if options.onlyz:
                        submodelname = subpath + '/' + model.split(
                            '.hdf')[0] + '_Zprjs.hdf'

            submodel = EMData(model, i)
            if options.angles:
                angles = options.angles
                angles = angles.replace(',', ' ')
                angles = angles.split()
                t = Transform({
                    'type': 'eman',
                    'az': float(angles[0]),
                    'alt': float(angles[1]),
                    'phi': float(angles[2])
                })

                submodel.transform(t)

            apix = submodel['apix_x']
            '''
			Pre-process/enhance subvolume if specified
			'''

            # Make the mask first, use it to normalize (optionally), then apply it
            mask = EMData(submodel["nx"], submodel["ny"], submodel["nz"])
            mask.to_one()

            if options.mask:
                #print "This is the mask I will apply: mask.process_inplace(%s,%s)" %(options.mask[0],options.mask[1])
                mask.process_inplace(options.mask[0], options.mask[1])

            # normalize
            if options.normproc:
                if options.normproc[0] == "normalize.mask":
                    options.normproc[1]["mask"] = mask

                submodel.process_inplace(options.normproc[0],
                                         options.normproc[1])
            '''
			#Mask after normalizing with the mask you just made, which is just a box full of 1s if no mask is specified
			'''
            submodel.mult(mask)
            '''
			#If normalizing, it's best to do mask-normalize-mask
			'''
            if options.normproc:
                #if options["normproc"][0]=="normalize.mask":
                #	options["normproc"][1]["mask"]=mask

                submodel.process_inplace(options.normproc[0],
                                         options.normproc[1])

                submodel.mult(mask)

            if options.lowpass:
                submodel.process_inplace(options.lowpass[0],
                                         options.lowpass[1])

            if options.shrink:
                submodel.process_inplace('math.meanshrink',
                                         {'n': options.shrink})

            kindividual = 0
            for d in projectiondirections:
                print "\nThis is the projection direction", d
                print "And this the corresponding transform", projectiondirections[
                    d]
                print "\n"
                prj = submodel.project("standard", projectiondirections[d])
                prj.set_attr('xform.projection', projectiondirections[d])
                prj['apix_x'] = apix
                prj['apix_y'] = apix

                #print "The size of the prj is", prj['nx']

                #prj.process_inplace('normalize')

                tag = ''

                if options.angles:
                    if options.tag:
                        tag = options.tag

                if options.onlyx or options.onlyy or options.onlyz:
                    if options.onlyx:
                        tag = 'onlyx'
                    elif options.onlyy:
                        tag = 'onlyy'
                    elif options.onlyz:
                        tag = 'onlyz'

                    k = kstack

                else:
                    k = kindividual

                prj.write_image(
                    submodelname.replace('.hdf', '_' + tag + '.hdf'), k)

                #print "Options.saverotvol is", options.saverotvol
                if options.saverotvol:
                    submodel_rot = submodel.copy()
                    submodel_rot.transform(projectiondirections[d])

                    volname = submodelname.replace('_prjs.', '_vol' + d + '.')
                    #print "I will save the rotated volume to this file", volname
                    submodel_rot.write_image(volname, 0)

                kindividual += 1
                kstack += 1

    return ()
Beispiel #37
0
def main():

    usage = """e2tomopreproc.py <imgs> <options> . 
	This program takes a tiltseries ('.st' or '.ali' file from IMOD) and applies preprocessing operations to them, such as lowpass, highpass, masking, etc.
	The options should be supplied in "--option=value" format, replacing "option" for a valid option name, and "value" for an acceptable value for that option. 
	"""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument("--path",
                        type=str,
                        default='',
                        help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'tomopreproc';
		for example, tomopreproc_02 will be the directory by default if 'tomopreproc_01' 
		already exists.""")

    parser.add_pos_argument(name="stack_files",
                            default="",
                            help="Stacks or images to process.")

    parser.add_argument(
        "--input",
        type=str,
        default='',
        help=
        """"tiltseries to process. redundant with --tiltseries, or with providing images as arguments (separated by a space: e2tomopreproc.py stack1.hdf stack2.hdf), but --input takes precedence."""
    )

    parser.add_argument(
        "--tiltseries",
        type=str,
        default='',
        help=""""tiltseries to process. redundant with --input""")

    parser.add_argument(
        "--tltfile",
        type=str,
        default='',
        help="""".tlt file containing the tilt angles for --tiltseries""")

    parser.add_argument(
        "--outmode",
        type=str,
        default='',
        help=
        """All EMAN2 programs write images with 4-byte floating point values when possible by default. This allows specifying an alternate format when supported: float, int8, int16, int32, uint8, uint16, uint32. Values are rescaled to fill MIN-MAX range."""
    )

    parser.add_argument(
        "--dontcleanup",
        action='store_true',
        default=False,
        help="""If specified, intermediate files will be kept.""")

    parser.add_argument(
        "--clip",
        type=str,
        default='',
        help=
        """Default=None. This resizes the 2-D images in the tilt series. If one number is provided, then x and y dimensions will be made the same. To specify both dimensions, supply two numbers, --clip=x,y. Clipping will be about the center of the image."""
    )

    #parser.add_argument("--apix",type=float,default=0.0,help="""True apix of images to be written on final stack.""")

    parser.add_argument(
        "--shrink",
        type=float,
        default=0.0,
        help=
        """Default=0.0 (no shrinking). Can use decimal numbers, larger than 1.0. Optionally shrink the images by this factor. Uses processor math.fft.resample."""
    )

    parser.add_argument(
        "--threshold",
        type=str,
        default='',
        help="""Default=None. A threshold processor applied to each image.""")

    parser.add_argument(
        "--erasegold",
        action='store_true',
        default='',
        help="""Default=False. Runs erase_gold.py on the stack.""")

    parser.add_argument(
        "--mask",
        type=str,
        default='',
        help="""Default=None. Masking processor applied to each image.""")

    parser.add_argument(
        "--maskbyangle",
        action='store_true',
        default=False,
        help=
        """Default=False. Requires --tltfile. This will mask out from tilted images the info that isn't present at the 0 tilt angle. It uses the tomo.tiltedgemask processor (type 'e2help.py processors' at the commandline to read a description of the processor and its parameters). Provide --maskbyanglefalloff and --maskbyanglesigma to modify the default parameters."""
    )

    parser.add_argument(
        "--maskbyanglefalloff",
        type=int,
        default=4,
        help=
        """Default=4. Number of pixels over which --maskbyangle will fall off to zero."""
    )

    parser.add_argument(
        "--maskbyanglesigma",
        type=float,
        default=2.0,
        help=
        """Default=2.0. Number of sigmas for the width of the gaussian fall off in --maskbyangle and --maskbyanglefalloff"""
    )

    parser.add_argument(
        "--normproc",
        type=str,
        default='',
        help=
        """Default=None (see 'e2help.py processors -v 10' at the command line). Normalization processor applied to each image."""
    )

    parser.add_argument(
        "--normalizeimod",
        action='store_true',
        default=False,
        help=
        """Default=False. This will apply 'newstack -float 2' to the input stack. Requires IMOD."""
    )

    parser.add_argument(
        "--preprocess",
        type=str,
        default='',
        help=
        """Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each image."""
    )

    parser.add_argument(
        "--lowpassfrac",
        type=float,
        default=0.0,
        help=
        """Default=0.0 (not used). Fraction of Nyquist to lowpass at. The processor used is filter.lowpass.tanh"""
    )

    parser.add_argument(
        "--highpasspix",
        type=int,
        default=0,
        help=
        """Default=0 (not used). Number of Fourier pixels to apply highpass filter at. The processor used is filter.highpass.gauss."""
    )

    parser.add_argument(
        "--parallel",
        type=str,
        default="thread:1",
        help=
        """default=thread:1. Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel"""
    )

    parser.add_argument(
        "--prenadminite",
        type=int,
        default=0,
        help=
        """Default=0. Requires IMOD to be installed. Used to apply prenad filtering to a tiltseries. This is the --minite parameter in IMOD's preNAD program (minimum number of iterations)."""
    )

    parser.add_argument(
        "--prenadmaxite",
        type=int,
        default=0,
        help=
        """Default=0. Requires IMOD to be installed. Used to apply prenad filtering to a tiltseries. This is the --maxite parameter in IMOD's preNAD program (maximum number of iterations)."""
    )

    parser.add_argument(
        "--prenadsigma",
        type=int,
        default=0,
        help=
        """Default=0. Requires IMOD to be installed. Used to apply prenad filtering to a tiltseries. This is the --sigma parameter in IMOD's preNAD program (initial sigma for 'smoothing structure tensor')."""
    )

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help=
        "verbose level [0-9], higner number means higher level of verboseness."
    )

    parser.add_argument(
        "--ppid",
        type=int,
        help="Set the PID of the parent process, used for cross platform PPID",
        default=-1)

    (options, args) = parser.parse_args()

    logger = E2init(sys.argv, options.ppid)
    print "\n(e2tomopreproc)(main) started log"

    from e2spt_classaverage import sptmakepath

    options = sptmakepath(options, 'tomopreproc')

    #print "args are",args

    infiles = []
    if not options.input:
        #try:
        #	infiles.append( sys.argv[1] )
        #except:
        if options.tiltseries:
            infiles.append(options.tiltseries)
        else:
            if args:
                print "copying args to infiles"
                infiles = list(args)
                print "infiles are", infiles
            else:
                print "\n(e2tomopreproc)(main) ERROR: must provide input files as arguments or via the --input or --tiltseries parameters."

    elif options.input:
        infiles.append(options.input)

    if infiles:
        print "\n(e2tomopreproc)(main) identified --input", options.input
        #print " .ali in options.input[:-4]", '.ali' in options.input[-4:]
        #print "options.input[-4] is", options.input[-4:]

        for infile in infiles:
            if '.ali' in infile[-4:] or '.st' in infile[
                    -3:] or '.mrc' in infile[-4:] or '.mrcs' in infile[
                        -5:] or '.hdf' in infile[-4:]:
                pass
            else:
                print "\n(e2tomopreproc)(main) ERROR: invalid image extension %s for image %s. Extension must be .st, .ali, .hdf, .mrc or .mrcs" % (
                    options.input.split('.')[-1], infile)
                sys.exit(1)
    else:
        print "\n(e2tomopreproc)(main) ERROR: no images found/provided"
        sys.exit(1)

    originalextension = infiles[0].split('.')[-1]

    angles = {}
    if options.maskbyangle or (options.prenadminite and options.prenadmaxite
                               and options.prenadsigma):

        if not options.tltfile:
            print "\n(e2tomopreproc)(main) ERROR: --maskbyangle and --prenad parameters require --tltfile"
            sys.exit(1)

        else:
            f = open(options.tltfile, 'r')
            lines = f.readlines()
            print "\nnumber of lines read from --tltfile", len(lines)
            f.close()
            #print "lines in tlt file are", lines
            k = 0
            for line in lines:
                line = line.replace('\t', '').replace('\n', '')

                if line:
                    angle = float(line)
                    angles.update({k: angle})
                    if options.verbose:
                        print "appending angle", angle
                    k += 1
            if len(angles) < 2:
                print "\nERROR: something went terribly wrong with parsing the --tltlfile. This program does not work on single images"
                sys.exit()

        if len(angles) < 2:
            print "\nERROR: (second angle check) something went terribly wrong with parsing the --tltlfile. This program does not work on single images"
            sys.exit()

    print "\n(e2spt_preproc)(main) - INITIALIZING PARALLELISM!\n"

    from EMAN2PAR import EMTaskCustomer
    etc = EMTaskCustomer(options.parallel)
    pclist = [options.input]

    etc.precache(pclist)
    print "\n(e2spt_preproc)(main) - precaching --input"

    tasks = []
    results = []

    mrcstacks = []
    print "there are these many infiles to loop over", len(infiles)

    if options.lowpassfrac:
        hdr = EMData(infiles[0], 0, True)
        apix = hdr['apix_x']
        print "\n(e2spt_preproc)(main) apix is", apix
        nyquist = 2.0 * apix
        print "\n(e2spt_preproc)(main) therefore nyquist resolution is", nyquist
        print
        lowpassres = nyquist / options.lowpassfrac

        options.lowpassfrac = 1.0 / (lowpassres)
        if float(options.shrink) > 1.0:
            options.lowpassfrac /= float(options.shrink)

            print "there's shrinking", options.shrink
            lowpassres = nyquist / options.lowpassfrac

        print "\n(e2spt_preproc)(main) and final lowpass frequency is", options.lowpassfrac

        print "corresponding to lowpassres of", lowpassres

    for infile in infiles:

        mrcstack = options.path + '/' + infile
        print "infile is", infile
        print "infile[-5:] is ", infile[-5:]
        if '.hdf' in infile[-5:]:
            print "replacing .hdf extension"
            mrcstack = options.path + '/' + infile.replace('.hdf', '.mrc')

        if '.mrcs' in infile[-5:]:
            print "replacing .mrcs extension"
            mrcstack = options.path + '/' + infile.replace('.mrcs', '.mrc')

        if '.st' in infile[-5:]:
            print "replacing .st extension"
            mrcstack = options.path + '/' + infile.replace('.st', '.mrc')

        if '.ali' in infile[-5:]:
            print "replacing .ali extension"
            mrcstack = options.path + '/' + infile.replace('.ali', '.mrc')

        if '.tif' in infile[-5:]:
            print "replacing .ali extension"
            mrcstack = options.path + '/' + infile.replace('.tif', '.mrc')

        #go = 0
        #if go:
        print "mrcstack is", mrcstack

        #outname = outname.replace('.mrc','.mrcs')

        mrcstacks.append(mrcstack)

        go = 0
        if options.maskbyangle:
            outname = mrcstack.replace('.mrc', '_UNSTACKED.mrc')
            print "therefore, outname is", outname

            cmd = 'e2proc2d.py ' + infile + ' ' + outname + ' --unstacking --threed2twod'

            #from shutil import copyfile
            #copyfile(options.input, outname)
            #print "copied input to", outname

            if options.outmode:
                cmd += ' --outmode=' + options.outmode

            if options.verbose:
                cmd += ' --verbose=' + str(options.verbose)
                print "\ncommand to unstack original input tiltseries is", cmd

            print "\n(e2tomopreproc)(main) unstacking command is", cmd

            p = subprocess.Popen(cmd,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            #p = subprocess.Popen( cmd , shell=True, stdout=subprocess.PIPE)

            text = p.communicate()
            #p.stdout.close()

            p.wait()

            if p.returncode == 0:
                go = 1
        else:
            go = 1

        if go:

            imgs = []
            if options.maskbyangle:
                c = os.getcwd() + '/' + options.path
                findir = os.listdir(os.getcwd() + '/' + options.path)

                print "\n(e2tomopreproc)(main) directory to look for images is", c
                for f in findir:
                    #if '.mrcs' in f:
                    if "_UNSTACKED" in f:
                        imgs.append(options.path + '/' + f)

                kk = 0
                imgs.sort()
                print "\n(e2spt_preproc)(main) found these many images", len(
                    imgs)

                for img in imgs:
                    #task=None

                    #if options.maskbyangle:
                    outimage = img.replace('.mrc', '_preproc.mrc')
                    task = TomoPreproc2DTask(img, options, angles[kk],
                                             outimage)
                    tasks.append(task)
                    kk += 1
            else:
                outimage = options.path + '/' + infile.replace(
                    '.mrc', '_preproc.mrcs')
                task = TomoPreproc2DTask(infile, options, 0, outimage)
                tasks.append(task)

            #else:
            #	newmrcs = mrcstack.replace('.mrc','.mrcs')
            #	print "copying file %s to %s" %(infile,newmrcs)
            #	copyfile( infile, newmrcs  )
            #	imgs.append( newmrcs )

            #print "and the final lowpass frequency will be", options.lowpassfrac

    tids = etc.send_tasks(tasks)
    if options.verbose:
        print "\n(e2spt_preproc)(main) preprocessing %d tasks queued" % (
            len(tids))

    results = get_results(etc, tids, options)

    print "\n(e2tomopreproc)(main) these many images have been processsed", len(
        results)

    imgspreproc = []
    findir = os.listdir(os.getcwd() + '/' + options.path)

    #for mrcstack in mrcstacks:

    for f in findir:
        if "_preproc.mrc" in f:
            print "found preprocessed image", f
            imgspreproc.append(options.path + '/' + f)
        else:
            print "this file is NOT a preprocessed image", f

    imgspreproc.sort()

    print "\n(e2tomopreproc)(main) these many preprocessed images loaded", len(
        imgspreproc)

    finalfiles = []

    if options.maskbyangle:

        outfile = mrcstack.replace('.mrc', '.mrcs')
        print "for RESTACKING"
        print "\n\n\noutfile is", outfile

        for f in imgspreproc:
            print "appending image %s to outfile %s" % (f, outfile)
            cmd = 'e2proc2d.py ' + f + ' ' + outfile
            if options.outmode:
                cmd += ' --outmode=' + options.outmode

            if options.verbose:
                cmd += ' --verbose ' + str(options.verbose)

            print "\ncmd is with .mrcs outputformat is", cmd
            print "becauase outfile is", outfile
            p = subprocess.Popen(cmd,
                                 shell=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            text = p.communicate()
            p.stdout.close()

        finaloutput = outfile.replace('.mrcs', '.' + originalextension)
        os.rename(outfile, finaloutput)

        finalfiles.append(finaloutput)
    else:
        finalfiles = list(imgspreproc)

    for finalf in finalfiles:
        if not options.tltfile:
            break

        if options.normalizeimod:
            try:
                cmd = 'newstack ' + finalf + ' ' + finalf + ' --float 2'
                print "normalizeimod cmd is", cmd
                p = subprocess.Popen(cmd,
                                     shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.PIPE)
                text = p.communicate()
                p.wait()
            except:
                print "\nERROR: --normalizeimod skipped. Doesn't seem like IMOD is installed on this machine"

        if not options.dontcleanup and options.maskbyangle:
            purge(options.path, '_preproc.mrc')
            purge(options.path, '_UNSTACKED')
            purge(options.path, '~')

        if options.tltfile:
            if options.prenadminite or options.prenadmaxite or options.prenadsigma:

                if options.prenadminite and options.prenadmaxite and options.prenadsigma:
                    cmd = 'preNAD -input ' + finalf + ' -output ' + finalf.replace(
                        '.' + originalextension,
                        '_prenad.' + originalextension) + ' -minite ' + str(
                            options.prenadminite) + ' -maxite ' + str(
                                options.prenadmaxite) + ' -sigma ' + str(
                                    options.prenadsigma
                                ) + ' -angles ' + options.tltfile
                    if options.verbose:
                        print "\n(e2tomopreproc)(main) prenad cmd to run is", cmd
                    try:
                        p = subprocess.Popen(cmd,
                                             shell=True,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
                        text = p.communicate()
                        p.wait()
                    except:
                        print "\nERROR: check that a version of IMOD containing the preNAD program is correctly installed on this machine"

                else:
                    if options.prenadminite:
                        if not options.prenadmaxite:
                            print "\nERROR: --prenadmaxite required with --prenadminite"
                        if not options.prenadsigma:
                            print "\nERROR: --prenadsigma required with --prenadminite"

                    if options.prenadmaxite:
                        if not options.prenadminite:
                            print "\nERROR: --prenadminite required with --prenadmaxite"
                        if not options.prenadsigma:
                            print "\nERROR: --prenadsigma required with --prenadmaxite"

                    if options.prenadsigma:
                        if not options.prenadminite:
                            print "\nERROR: --prenadminite required with --prenadsigma"
                        if not options.prenadmaxite:
                            print "\nERROR: --prenadmaxite required with --prenadsigma"

    E2end(logger)
    return ()
Beispiel #38
0
def main():
	
	progname = os.path.basename(sys.argv[0])
	usage = """Plots the variation of correlation of a volume with itself as it is rotated in azimuth or altitude"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	
	parser.add_argument("--path",type=str,default='',help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'rotplot'; 
		for example, rotplot_02 will be the directory by default if 'rotplot_01' already exists.""")
	
	parser.add_argument("--vols1", type=str, help="Comma-separated filenames of the .hdf volumes whose self-rotational correlation plot you want to compute.", default=None)
	parser.add_argument("--vols2", type=str, help="Comma-separated filenames of the .hdf volumes whose rotational correlation plot you want to compute against the volumes provided through --vols1.", default=None)

	parser.add_argument("--output", type=str, help="Name for the .txt file with the results and the corresponding .png plot")
	parser.add_argument("--sym", type=str, help="Symmetry to apply after all preprocessing.",default='c1')

	
	parser.add_argument("--mask",type=str,help="Mask processor applied to particles before alignment. Default is mask.sharp:outer_radius=-2", default="mask.sharp:outer_radius=-2")
	parser.add_argument("--preprocess",type=str,help="Any processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.", default=None)

	parser.add_argument("--lowpass",type=str,help="A lowpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.", default=None)
	parser.add_argument("--highpass",type=str,help="A highpass filtering processor (as in e2proc3d.py) to be applied to each volume prior to alignment. Not applied to aligned particles before averaging.", default=None)
		
	parser.add_argument("--normproc",type=str,help="""Normalization processor applied to 
		particles before alignment. Default is 'normalize.edgemean'. 
		If normalize.mask is used, results of the mask option will be passed in automatically. 
		If you want to turn this option off specify \'None\'""", default='normalize.edgemean')	
		
	parser.add_argument("--shrink", type=int,default=1,help="Optionally shrink the input volumes by an integer amount for coarse alignment.")
	parser.add_argument("--shrinkefine", type=int,default=1,help="Optionally shrink the input volumes by an integer amount for refine alignment.")
	
	parser.add_argument("--daz", type=int,default=3,help="Step size to vary azimuth.")
	parser.add_argument("--icosvertices", action="store_true",help="Will produce an azimutal plot at each vertex of an icosahedron.", default=False)
	parser.add_argument("--dalt", type=int,default=181,help="Step size to vary altitude.")
	parser.add_argument("--alti", type=int,default=0,help="""Initial position to check in altitude. For example, for a D symmetric chaperonin, 
															if you want to check alt=0 ONLY, provide --alti=0 and --dalt=181 as options.
															if you want to check alt=180 ONLY, provide --alti=180, --dalt=1 or greater.
															if you want to check BOTH alt=0 and alt=180 in the same plot, provide --alti=0, --dalt=180""")
	
	parser.add_argument("--parallel",  help="Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel", default="thread:1")
	
	parser.add_argument("--ppid", type=int, help="Set the PID of the parent process, used for cross platform PPID",default=-1)
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n",type=int, default=0, help="verbose level [0-9], higner number means higher level of verboseness.")
	#parser.add_argument("--plotonly",type=str, help="Provide .txt files for a given alt, with 2 columns (az ccc) with the values to plot. For example, --plotonly=alt000.txt,alt180.txt", default=None)
	parser.add_argument("--normalizeplot",action="store_true", help="Make maximum correlation value on plot equal to 1 and scale all other values accordingly.", default=False)
	parser.add_argument("--plot2d",action="store_true", help="Produces 2D plot if both az and alt are varied.", default=False)
	parser.add_argument("--only2dplot",action="store_true", help="Skips all plots, except 2dplot.", default=False)
	parser.add_argument("--savetxt",action="store_true", help="Will save the values for each plot into .txt files.", default=False)

	parser.add_argument("--plotonly",type=str, help="""If you already have the correlation variation with azimuth (for a particular altitude) in a text file in rows of 'az,ccc', 
												provide the txt file(s) separated by commas --plotonly=file1.txt,file2.txt,file3.txt etc...""", default=None)
	
	parser.add_argument("--singleplot",action="store_true", help="""Plot all alts, 
		or each vertex of --icosvertices is on, in a single .png file.""", default=False)
		
	parser.add_argument("--offset",type=float,default=0.0, help="""Default=0. Rotation in azimuth
		to apply to one of the models before computing the entire rotational correlation plot.""")
		
	parser.add_argument("--ownvalues",action='store_true',default=False,help="""Default=False. If provided and --normalizeplot is also provided, this parameter will cause all curves to go from 0 to 1 when ploted on the same plot by specifying --singleplot. Otherwise, the maximum value will drawn from the highest value amongst all the curves and the minimum value from the lowest value amongst all the curves being plotted simultaneously, preserving the relative intensity between different curves, but still effectively making the range 0 to 1.""")

	
	(options, args) = parser.parse_args()

	
	#print "Loaded mask is", options.mask
	
	
	
	'''
	Parse options
	'''
	if options.mask:
		if 'None' in options.mask:
			options.mask = 'None'
		if options.mask != 'None' and options.mask != 'none':
			print "\noptions.mask before parsing is",  options.mask
			options.mask = parsemodopt(options.mask)
		else:
			options.mask = None
		print "\nmask after parsing is", options.mask
	
	if options.preprocess:
		if options.preprocess != 'None' and options.preprocess != 'none': 
			options.preprocess = parsemodopt(options.preprocess)
		else:
			options.preprocess = None
		print "\nPreprocessor is", options.preprocess
	
	if options.lowpass: 
		if options.lowpass != 'None' and options.lowpass != 'none': 
			options.lowpass = parsemodopt(options.lowpass)
		else:
			options.lowpass = None
		print "\nlowpass is", options.lowpass
		
	if options.highpass: 
		if options.highpass != 'None' and options.highpass != 'none': 
			options.highpass = parsemodopt(options.highpass)
		else:
			options.highpass = None
		print "\nHighpass is", options.highpass
	
	if options.normproc: 
		if options.normproc != 'None' and options.normproc != 'none':
			options.normproc=parsemodopt(options.normproc)
		else:
			options.normproc = None
		print "\nNormproc is", options.normproc

	#print "plotonly is", options.plotonly
	
	if options.only2dplot:
		options.plot2d = True	
	
	
	if options.icosvertices and options.vols2:
			print "ERROR: You can only use --icosvertices for volumes in --vols1. You must NOT supply --vols2."
			sys.exit()
	
	#print "args are", args	
	logger = E2init(sys.argv, options.ppid)
	
		
	from e2spt_classaverage import sptmakepath
	options = sptmakepath(options,'rotplot')
	
	
	if not options.plotonly:
		vols1=[]
		if options.vols1:
			vols1 = options.vols1.split(',')
	
		vols = vols1

		vols2=[]
		if options.vols2:
			vols2 = options.vols2.split(',')
			vols = vols1 + vols2
		
			for v in vols:
				if '.hdf' not in v and '.mrc' not in v:
					print "ERROR: The input volumes must all be either .hdf, .mrc or .rec (which is also just a .mrc file)."
					sys.exit()
					
				rotcccplot(v,v,options)
	
			for v1 in vols1:
				for v2 in vols2:
					rotcccplot(v1,v2,options)
				
		else:
			for v in vols:
				if '.hdf' not in v and '.mrc' not in v:
					print "ERROR: The input volumes must all be either .hdf, .mrc or .rec (which is also just a .mrc file)."
					sys.exit()
	
				rotcccplot(v,v,options)
	else:

		files=options.plotonly.split(',')
		print "Will plot these files", files
		
		values={}
		
		
		#absMIN=1000000
		#absMAX=-1
		absMIN = 0.0
		absMAX = 0.0
		ownvalues = 1
		try:
			if options.ownvalues:
				ownvalues = options.ownvalues
		except:
			pass
		
		
		k=0
		for F in files:
			print "Working with this file now", F
			azs=[]
			valuesforthisfile=[]
			
			f=open(F,'r')
			lines = f.readlines()
			f.close()
			
			for line in lines:
				print "Line is\n", line
				az=line.split()[0]
				azs.append(int(az))
				value=line.split()[-1].replace('\n','')
				valuesforthisfile.append(float(value))
				print "Thus az, value are", az, value
	
			#title=F.replace('.txt','')
			
			if not ownvalues:
			
				minv = float(min(valuesforthisfile))
				if float(minv) < float(absMIN):
					absMIN = float(minv)

				maxv = float(max(valuesforthisfile))
				if float(maxv) > float(absMAX):
					absMAX = float(maxv)
				print "Min and max to send are", absMIN, absMAX
		
			
			values.update({k:valuesforthisfile})
			k+=1
		
		title = 'plot'
		if options.output:
			tilte = options.output.replace('.txt','')
		
		
		plotter(options,azs,values,title,None,k,absMIN,absMAX)
		print "I have returned from the plotter"
			
		if options.singleplot:	
			print "And single plot is on"
			
			plotname = 'plot'
			if options.output:
				plotname = options.output.replace('.txt','')
			
			if not options.only2dplot:
				print "While only 2D plot is off"
				#pylab.savefig(plotname)	
				#pylab.title(title)
				pylab.ylabel('Correlation')
				pylab.xlabel('Azimuth')	
				pylab.savefig( options.path + '/' + plotname )
				#clf()
		
			if not options.icosvertices and options.plot2d:
				print "I will call 2dplot"
				twoD_plot(plotname,values,options)
		if not options.singleplot:
			clf()
			
	E2end(logger)
			
	return()
Beispiel #39
0
def main():
	progname = os.path.basename(sys.argv[0])
	usage = """prog <output> [options]

	This program is used to preprocess subtomograms before aligning them. The same can be accomplished with 
	e2proc3d, except that this program is parallelized and thus should be substantially faster for large subtomograms.
	"""
			
	parser = EMArgumentParser(usage=usage,version=EMANVERSION)
	

	parser.add_argument("--input", type=str, default='',help="""Default=None. The name of the input volume stack. MUST be HDF since volume stack support is required.""")
	
	parser.add_argument("--output", type=str, default='',help="""Default=None. Specific name of HDF file to write processed particles to.""")
		
	parser.add_argument("--parallel",type=str, default='', help="""default=None. Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel""")
	
	parser.add_argument("--ppid", type=int, help="""Default=-1. Set the PID of the parent process, used for cross platform PPID""",default=-1)
	
	parser.add_argument("--verbose", "-v", dest="verbose", action="store", metavar="n", type=int, default=0, help="""Default=0. Verbose level [0-9], higner number means higher level of verboseness""")
		
	parser.add_argument("--subset",type=int,default=0,help="""Default=0 (not used). Refine only this substet of particles from the stack provided through --input""")

	parser.add_argument("--apix",type=float,default=0.0,help="""Default=0.0 (not used). Use this apix value where relevant instead of whatever is in the header of the reference and the particles. Will overwrite particle header as well.""")

	parser.add_argument("--shrink", type=int,default=0,help="""Default=0 (no shrinking). Optionally shrink the input volumes by an integer amount for coarse alignment.""")
		
	parser.add_argument("--threshold",type=str,default='',help="""Default=None. A threshold applied to the subvolumes after normalization. For example, --threshold=threshold.belowtozero:minval=0 makes all negative pixels equal 0, so that they do not contribute to the correlation score.""")
	
	parser.add_argument("--mask",type=str,default='', help="""Default=None. Masking processor applied to particles before alignment. IF using --clip, make sure to express outer mask radii as negative pixels from the edge.""")
	
	parser.add_argument("--maskfile",type=str,default='',help="""Default=None. Mask file (3D IMAGE) applied to particles before alignment. Must be in HDF format. Default is None.""")
	
	parser.add_argument("--normproc",type=str, default='',help="""Default=None (see 'e2help.py processors -v 10' at the command line). Normalization processor applied to particles before alignment. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify \'None\'""")
	
	parser.add_argument("--preprocess",type=str,default='',help="""Any processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""")
	
	parser.add_argument("--lowpass",type=str,default='',help="""Default=None. A lowpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""")
	
	parser.add_argument("--highpass",type=str,default='',help="""Default=None. A highpass filtering processor (see 'e2help.py processors -v 10' at the command line) to be applied to each volume prior to COARSE alignment. Not applied to aligned particles before averaging.""")
	
	parser.add_argument("--clip",type=int,default=0,help="""Default=0 (which means it's not used). Boxsize to clip particles. For example, the boxsize of the particles might be 100 pixels, but the particles are only 50 pixels in diameter. Aliasing effects are not always as deleterious for all specimens, and sometimes 2x padding isn't necessary.""")
	
	parser.add_argument("--nopath",action='store_true',default=False,help="""If supplied, this option will save results in the directory where the command is run. A directory to store the results will not be made.""")

	parser.add_argument("--path",type=str,default='sptpreproc',help="""Default=spt. Directory to store results in. The default is a numbered series of directories containing the prefix 'sptpreproc'; for example, sptpreproc_02 will be the directory by default if 'sptpreproc_01' already exists.""")

	
	(options, args) = parser.parse_args()
	
	logger = E2init(sys.argv, options.ppid)
	print "\n(e2spt_preproc)(main) started log"
	
	
	
	from e2spt_classaverage import sptmakepath
	
	if options.path and not options.nopath:
	
		options = sptmakepath(options,'sptpreproc')

	if options.parallel=='None' or options.parallel=='none':
		options.parallel=None
	
	
	
	if not options.input:
		try:
			options.input = sys.argv[1]
		except:
			print "\n(e2spt_preproc)(main) ERROR: invalid input file"
			
	if options.mask or options.maskfile or options.threshold or options.clip or options.threshold or options.normproc or options.preprocess or options.lowpass or options.highpass or int(options.shrink) > 1:
		
		preprocstack =  str(os.path.basename(options.input).replace('.hdf','_preproc.hdf'))
		
		if options.path and not options.nopath:
			preprocstack = options.path + '/' + preprocstack
		
		if options.output:
			if '.hdf' in options.output[-4:]:
				preprocstack = options.output
			else:
				print "\n(e2spt_preproc)(main) ERROR: '.hdf' must be the last four characters of the output filename."
			
		print "\n(e2spt_preproc)(main) output stack will be %s" %( preprocstack)

		n = 0
		try:
			n = EMUtil.get_image_count( options.input )
		except:
			print "\n(e2spt_preproc)(main) ERROR: --input stack seems to be invalid"
			sys.exit()
		
		print "\n(e2spt_preproc)(main) number of particles is %d" %( n) 
		
		
		c = os.getcwd()
		
		findir = os.listdir( c )
		
		if preprocstack not in findir:
		
			dimg = EMData(8,8,8)
			dimg.to_one()

			for i in range(n):
				dimg.write_image( preprocstack, i )
		
		else:
			print "\n(e2spt_preproc)(main) WARNING: a file with the name of the output stack %s is already in the current directory and will be DELETED" %( preprocstack )
			os.remove( preprocstack )
			
			dimg = EMData(8,8,8)
			dimg.to_one()

			for i in range(n):
				dimg.write_image( preprocstack, i )
		

		finalbox = EMData(options.input,0,True)['nx']
		if options.clip:
			finalbox=options.clip

		
		#dimglarge=EMData(finalbox,finalbox,finalbox)
		#dimglarge.to_one()
		#dimglarge.write_image(preprocstack,0)
		#n=EMUtil.get_image_count(options.input)
		#if options.subset:
		#	n=options.subset
		#dimglarge.write_image(preprocstack,n-1)

		if options.verbose:
			print "\n(e2spt_preproc)(main) wrote dummy ptcls to %s" %( preprocstack)
	
		
		print "\n(e2spt_preproc)(main) - INITIALIZING PARALLELISM!\n"
		
		if options.parallel:
			from EMAN2PAR import EMTaskCustomer
			etc=EMTaskCustomer(options.parallel)
			pclist=[options.input]

			etc.precache(pclist)
			print "\n(e2spt_preproc)(main) - precaching --input"

			tasks=[]
			results=[]
		
		
		from e2spt_classaverage import sptOptionsParser
		options = sptOptionsParser( options )
		
		
		for j in range(n):
			#print "processing  particle", j
			
			img = EMData( options.input, j )
			
			if options.parallel:
				#task = Preproc3DTask( ["cache",options.input,j], options, j, preprocstack )
				task = Preproc3DTask( img, options, j, preprocstack )
				tasks.append(task)
		
			else:
				img = EMData( options.input, j )
				pimg = preprocfunc( img, options, j, preprocstack)
								
		
		
		if options.parallel and tasks:
			tids = etc.send_tasks(tasks)
			if options.verbose: 
				print "\n(e2spt_preproc)(main) preprocessing %d tasks queued" % (len(tids)) 

	
			results = get_results( etc, tids, options )
		#print "\n(e2spt_preproc)(main) preprocessing results are", results	
		
		
		#print "\n(e2spt_preproc)(main) input changing to preprocstack"
		#options.input = preprocstack

		#cache needs to be reloaded with the new options.input		
		
	else:
		print "\n(e2spt_preproc)(main) Nothing to do. No preprocessing parameters specified."
		
	E2end(logger)
	
	return
Beispiel #40
0
def main():
    progname = os.path.basename(sys.argv[0])
    usage = """prog <stack of particles> [options] . This programs autocenters particles
		using autocorrelation or spherical averages."""

    parser = EMArgumentParser(usage=usage, version=EMANVERSION)

    parser.add_argument("--input", type=str, default="", help="""Input stack in HDF format.""")

    parser.add_argument(
        "--path",
        type=str,
        default="spt_autoc",
        help="""Directory to store results in. 
		The default is a numbered series of directories containing the prefix 'sptautobox'; 
		for example, sptautobox_01 will be the directory by default if 'sptautobox' already exists.""",
    )

    parser.add_argument(
        "--boxclip",
        type=int,
        default=0,
        help="""The boxsize to clip the FINAL boxes 
		down to after auto-centering, so that they contain no empty pixels. Default=0 or 'off'""",
    )

    parser.add_argument("--iter", type=int, help="The number of iterations to perform. Default is 1.", default=1)

    parser.add_argument(
        "--verbose",
        "-v",
        dest="verbose",
        action="store",
        metavar="n",
        type=int,
        default=0,
        help="verbose level [0-9], higner number means higher level of verboseness",
    )

    # parser.add_argument("--averager",type=str,help="The type of averager used to produce the class average. Default=mean",default="mean")

    parser.add_argument(
        "--parallel", help="Parallelism. See http://blake.bcm.edu/emanwiki/EMAN2/Parallel", default="thread:1"
    )

    parser.add_argument(
        "--mask", type=str, default="", help="Mask to apply to the dataset average before spherically averaging it."
    )

    parser.add_argument(
        "--shrink", type=int, default=0, help="Optionally shrink the volume(s) to have the FFTs go faster"
    )

    parser.add_argument(
        "--lowpass",
        type=str,
        help="A filter applied to the average of the dataset before spherically averaging it",
        default="",
    )

    parser.add_argument(
        "--highpass",
        type=str,
        help="A filter applied to the average of the dataset before spherically averaging it",
        default="",
    )

    parser.add_argument(
        "--preprocess",
        type=str,
        help="A filter applied to the average of the dataset before spherically averaging it",
        default="",
    )

    parser.add_argument(
        "--threshold",
        type=str,
        help="A filter applied to the average of the dataset before spherically averaging it",
        default="",
    )

    parser.add_argument(
        "--processptcls",
        type=int,
        default=0,
        help="Apply all pre-processing (mask, shrink, filter, etc...) on the particles before aligning them to the previous spherical average.",
    )

    parser.add_argument(
        "--averager",
        type=str,
        help="The type of averager used to produce the class average. Default=mean",
        default="mean.tomo",
    )

    parser.add_argument(
        "--normproc",
        type=str,
        help="Normalization processor applied to particles before alignment. Default is to use normalize.mask. If normalize.mask is used, results of the mask option will be passed in automatically. If you want to turn this option off specify 'None'",
        default="normalize.mask",
    )

    parser.add_argument(
        "--savesteps",
        action="store_true",
        help="If set, will save the average after each iteration to class_#.hdf. Each class in a separate file. Appends to existing files.",
        default=False,
    )

    parser.add_argument(
        "--saveali",
        action="store_true",
        help="If set, will save the aligned particle volumes in class_ptcl.hdf. Overwrites existing file.",
        default=False,
    )
    # parser.add_argument("--align", help="Set by default",default="translational:intonly=1")

    parser.add_argument(
        "--aligncmp",
        type=str,
        help="The comparator used for the --align aligner. Default is the internal tomographic ccc. Do not specify unless you need to use another specific aligner.",
        default="ccc.tomo",
    )

    parser.add_argument(
        "--mode",
        type=str,
        default="autocorr",
        help="""Provide --mode=sphere or --mode=autocorr.
		The first one iteratively aligns the sperical averages of individual particles to 
		the speherical average of the entire set-average. 
		The second generates mirror images of each particle in 3-D and 2-D and uses
		autocorrelation to center the particles.
		You can actually provide both modes and they will be applied sequentially in the
		order you provided them. For example, --mode=autocorr,spherical""",
    )

    parser.add_argument(
        "--align",
        help="Set by default",
        default="rotate_translate_3d_grid:alt0=0:alt1=1:az0=0:az1=1:dalt=2:daz=2:dotrans=1:dphi=2:phi0=0:phi1=1:search=10:verbose=1",
    )

    (options, args) = parser.parse_args()

    hdr = EMData(options.input, 0, True)
    nx = hdr["nx"]
    ny = hdr["ny"]
    nz = hdr["nz"]
    if nx != ny or ny != nz:
        print "ERROR, input volumes are not cubes"
        sys.exit(1)
    oldbox = nx

    from e2spt_classaverage import sptmakepath

    options = sptmakepath(options)

    if options.averager:
        options.averager = parsemodopt(options.averager)

    if options.mask:
        options.mask = parsemodopt(options.mask)

    if options.lowpass:
        options.lowpass = parsemodopt(options.lowpass)

    if options.highpass:
        options.highpass = parsemodopt(options.highpass)

    if options.preprocess:
        options.preprocess = parsemodopt(options.preprocess)

    if options.normproc:
        options.normproc = parsemodopt(options.normproc)

    if options.align:
        options.align = parsemodopt(options.align)

    if options.aligncmp:
        options.aligncmp = parsemodopt(options.aligncmp)

    n = EMUtil.get_image_count(options.input)

    modes = options.mode.split(",")

    for m in modes:
        if "autocorr" in m:
            print "Mode is", m
            print "Number of ptcls to autocenter is", n
            print "In file", options.input
            for i in range(n):
                print "Autocentering ptcl number", i
                e = EMData(options.input, i)

                ret = autocorrcenter(e, options)
                outname = options.input.replace(".hdf", "_centered.hdf")

                ret[0].write_image(options.path + "/" + outname, i)
                ret[1].write_image(options.path + "/" + "prjsTopRaw.hdf", i)
                ret[2].write_image(options.path + "/" + "prjsSideRaw.hdf", i)
                ret[3].write_image(options.path + "/" + "prjsTopCent.hdf", i)
                ret[4].write_image(options.path + "/" + "prjsSideCent.hdf", i)

        elif "sphere" in m:
            print "Mode is", m
            spherical(options)

    return