Пример #1
0
    def calculate_animation(self, dt):
        '''
		based on the assumption that dt goes from 0 to 1
		'''
        if dt > 1: raise
        if self.angle != 0:
            t1 = dt * self.angle
            t2 = self.angle - t1
            next = old_div(
                (sin(t2) * self.start_point + sin(t1) * self.end_point),
                self.sinangle)
        else:
            T = Transform()
            d = {"type": "spin"}
            d["omega"] = dt * 360
            d["n1"] = self.rot_vec[0]
            d["n2"] = self.rot_vec[1]
            d["n3"] = self.rot_vec[2]
            T.set_rotation(d)

            next = T * self.start_point

            #next = Vec3f(self.start_point[0],self.start_point[1],self.start_point[2])

        self.arc_points[self.stage].append(self.radius * next)
        self.target.arc_animation_update(self.arc_points)
Пример #2
0
    def calculate_animation(self, dt):
        """
		based on the assumption that dt goes from 0 to 1
		"""
        if dt > 1:
            raise
        if self.angle != 0:
            t1 = dt * self.angle
            t2 = self.angle - t1
            next = (sin(t2) * self.start_point + sin(t1) * self.end_point) / self.sinangle
        else:
            T = Transform()
            d = {"type": "spin"}
            d["omega"] = dt * 360
            d["n1"] = self.rot_vec[0]
            d["n2"] = self.rot_vec[1]
            d["n3"] = self.rot_vec[2]
            T.set_rotation(d)

            next = T * self.start_point

            # next = Vec3f(self.start_point[0],self.start_point[1],self.start_point[2])

        self.arc_points[self.stage].append(self.radius * next)
        self.target.arc_animation_update(self.arc_points)
Пример #3
0
    def __establish_sphere_points(self, stage):
        self.start_point = self.transforms[stage].transpose() * self.z_point
        self.end_point = self.transforms[stage + 1].transpose() * self.z_point
        if self.start_point != self.end_point:
            self.angle = acos(self.start_point.dot(self.end_point))
            self.omega = 1
        else:
            self.angle = 0
            normal = Vec3f(-self.start_point[2], 0, -self.start_point[0])
            normal.normalize()

            T = Transform()
            d = {"type": "spin"}
            d["omega"] = self.omega
            d["n1"] = normal[0]
            d["n2"] = normal[1]
            d["n3"] = normal[2]
            T.set_rotation(d)
            self.rot_vec = self.start_point
            p = self.start_point
            self.start_point = T * self.rot_vec
            self.end_point = T * self.rot_vec
            self.omega += 1

        self.sinangle = sin(self.angle)
        self.arc_points.append([])
Пример #4
0
def mult_transform(v1, v2):
    from EMAN2 import Transform
    T1 = Transform({
        "type": "spider",
        "phi": v1[0],
        "theta": v1[1],
        "psi": v1[2],
        "tx": 0.0,
        "ty": 0.0,
        "tz": 0.0,
        "mirror": 0,
        "scale": 1.0
    })
    T2 = Transform({
        "type": "spider",
        "phi": v2[0],
        "theta": v2[1],
        "psi": v2[2],
        "tx": 0.0,
        "ty": 0.0,
        "tz": 0.0,
        "mirror": 0,
        "scale": 1.0
    })
    T = T1 * T2
    return [
        T.get_params("spider")["phi"],
        T.get_params("spider")["theta"],
        T.get_params("spider")["psi"]
    ]
Пример #5
0
    def __establish_sphere_points(self, stage):
        self.start_point = self.transforms[stage].transpose() * self.z_point
        self.end_point = self.transforms[stage + 1].transpose() * self.z_point
        if self.start_point != self.end_point:
            self.angle = acos(self.start_point.dot(self.end_point))
            self.omega = 1
        else:
            self.angle = 0
            normal = Vec3f(-self.start_point[2], 0, -self.start_point[0])
            normal.normalize()

            T = Transform()
            d = {"type": "spin"}
            d["omega"] = self.omega
            d["n1"] = normal[0]
            d["n2"] = normal[1]
            d["n3"] = normal[2]
            T.set_rotation(d)
            self.rot_vec = self.start_point
            p = self.start_point
            self.start_point = T * self.rot_vec
            self.end_point = T * self.rot_vec
            self.omega += 1

        self.sinangle = sin(self.angle)
        self.arc_points.append([])
Пример #6
0
def apply_rotation_gaps(angleset1, qrot):
    from EMAN2 import Transform, Vec2f
    import types
    if (type(qrot) == list):
        rot = Transform({
            "type": "spider",
            "phi": qrot[0],
            "theta": qrot[1],
            "psi": qrot[2]
        })
    else:
        rot = qrot
    for i in range(len(angleset1)):
        if (len(angleset1[i]) > 1):
            T1 = Transform({
                "type": "spider",
                "phi": angleset1[i][0],
                "theta": angleset1[i][1],
                "psi": angleset1[i][2],
                "tx": 0.0,
                "ty": 0.0,
                "tz": 0.0,
                "mirror": 0,
                "scale": 1.0
            })
            T1.set_trans(Vec2f(-angleset1[i][3], -angleset1[i][4]))
            T = T1 * rot
            d = T.get_params("spider")
            angleset1[i] = [d["phi"], d["theta"], d["psi"], -d["tx"], -d["ty"]]
Пример #7
0
def apply_rotation_gaps(angleset1, qrot):
	from EMAN2 import Transform, Vec2f
	import types
	if(type(qrot) == types.ListType): rot = Transform({"type":"spider","phi":qrot[0],"theta":qrot[1],"psi":qrot[2]})
	else:                             rot = qrot
	for i in xrange(len(angleset1)):
		if(len(angleset1[i]) > 1):
			T1 = Transform({"type":"spider","phi":angleset1[i][0],"theta":angleset1[i][1],"psi":angleset1[i][2],"tx":0.0,"ty":0.0,"tz":0.0,"mirror":0,"scale":1.0})
			T1.set_trans(Vec2f(-angleset1[i][3], -angleset1[i][4]))
			T = T1*rot
			d = T.get_params("spider")
			angleset1[i] = [d["phi"], d["theta"], d["psi"], -d["tx"], -d["ty"]]
Пример #8
0
def subtract(particle,
             dens,
             sub_dens,
             recenter=None,
             no_frc=False,
             low_cutoff=0.0,
             high_cutoff=0.7071):
    """
    Perform projection subtraction on one particle image.
    :param particle: Tuple holding original (particle EMData, particle MetaData)
    :param dens: Whole density map
    :param sub_dens: Subtraction density map
    :param recenter: Vector between CoM before and after subtraction, or None to skip recenter operation (default None)
    :param no_frc: Skip FRC normalization (default False)
    :param low_cutoff: Low cutoff frequency in FRC normalization (default 0.0)
    :param high_cutoff: High cutoff frequency in FRC normalization (default 0.7071)
    :return: Result object
    """
    ptcl, meta = particle[0], particle[1]
    ctfproj = make_proj(dens, meta)
    ctfproj_sub = make_proj(sub_dens, meta)

    if no_frc:  # Direct subtraction only.
        ptcl_sub = ptcl - ctfproj_sub
    else:  # Per-particle FRC normalization.
        ptcl_sub = ptcl.process(
            "math.sub.optimal", {
                "ref": ctfproj,
                "actual": ctfproj_sub,
                "low_cutoff_frequency": low_cutoff,
                "high_cutoff_frequency": high_cutoff
            })

    ptcl_norm_sub = ptcl_sub.process("normalize")

    if recenter is not None:
        # Rotate the coordinate frame of the CoM difference vector by the Euler angles.
        t = Transform()
        t.set_rotation({
            'psi': meta.psi,
            'phi': meta.phi,
            'theta': meta.theta,
            'type': 'spider'
        })
        shift = t.transform(recenter)
        # The change in the origin is the projection of the transformed difference vector on the new xy plane.
        meta.x_origin += shift[0]
        meta.y_origin += shift[1]

    return Result(ptcl, meta, ctfproj, ctfproj_sub, ptcl_sub, ptcl_norm_sub)
Пример #9
0
def average2dtransform(data, return_avg_pixel_error=False):

	from math import pi, sin, cos, radians, degrees

	L = len(data)

	sum_cosa = 0.0
	sum_sina = 0.0
	sx = 0.0
	sy = 0.0
	for j in xrange(L):
		sum_cosa += cos(radians(data[j][0]))
		sum_sina += sin(radians(data[j][0]))
		sx +=  data[j][1]
		sy +=  data[j][2]
	sx /= L
	sy /= L
	sqrtP = sqrt(sum_cosa**2+sum_sina**2)

	# Get ave transform params
	H = Transform({"type":"2D"})
	H.set_matrix([sum_cosa/sqrtP, sum_sina/sqrtP, 0.0, sx, -sum_sina/sqrtP, sum_cosa/sqrtP, 0.0, sy, 0.0, 0.0, 1.0, 0.0])
	dd = H.get_params("2D")

	H = Transform({"type":"2D","alpha":dd[ "alpha" ],"tx":dd[ "tx" ],"ty": dd[ "ty" ],"mirror":0,"scale":1.0})
	dd = H.get_params("2D")
	if return_avg_pixel_error:
		return sum(sqr_pixel_error)/N
	else:
		return [dd[ "alpha" ], dd[ "tx" ], dd[ "ty" ]]
Пример #10
0
	def updateMatrices(self, params, xformtype):
		"""
		The matrcies are updated in such a way that each is done in the standard cooridnate system and the std coord system is not perturbed by the others
		@type params: List
		@param params: A list defining how the transform in each active node is modified
		@type xfromtype: sting
		@param xformtype: The sort of transform we wish to do
		"""	
		if self.is_selected:
			if xformtype == "rotate":
				if self.parent:
					self.transform.rotate_origin_newbasis(self.getParentMatrixProduct(), params[0], params[1], params[2], params[3])
				else:
					self.transform.rotate_origin(Transform({"type":"spin","omega":params[0],"n1":params[1],"n2":params[2],"n3":params[3]}))
			elif xformtype == "translate":
				if self.parent: 
					self.transform.translate_newbasis(self.getParentMatrixProduct(), params[0], params[1], params[2])
				else:
					self.transform.translate(params[0], params[1], params[2])
					
			elif xformtype == "scale":
				self.transform.scale(params[0])
			else:
				raise Exception,"Invalid transformation type"
		
		# Now tell all children to update
		# TODO: we MIGHT want to get rid of the recursive part of this algorithm
		#        instead, the calling function would get a list of all selected nodes, and apply transformations to each
		for child in self.children:
			child.updateMatrices(params, xformtype) #Note: the transformation is only applied to SELECTED nodes
Пример #11
0
 def _on_EMAN_rotation(self, value):
     self._set_rotation_std_coords(
         Transform({
             "type": "eman",
             "az": self.emanazslider.getValue(),
             "alt": self.emanaltslider.getValue(),
             "phi": self.emanphislider.getValue()
         }))
     self.inspector().updateSceneGraph()
Пример #12
0
 def _on_Imagic_rotation(self, value):
     self._set_rotation_std_coords(
         Transform({
             "type": "imagic",
             "gamma": self.imagicgammaslider.getValue(),
             "beta": self.imagicbetaslider.getValue(),
             "alpha": self.imagicalphaslider.getValue()
         }))
     self.inspector().updateSceneGraph()
Пример #13
0
 def _on_Spider_rotation(self, value):
     self._set_rotation_std_coords(
         Transform({
             "type": "spider",
             "psi": self.spiderpsislider.getValue(),
             "theta": self.spiderthetaslider.getValue(),
             "phi": self.spiderphislider.getValue()
         }))
     self.inspector().updateSceneGraph()
Пример #14
0
 def _on_MRC_rotation(self, value):
     self._set_rotation_std_coords(
         Transform({
             "type": "mrc",
             "phi": self.mrcpsislider.getValue(),
             "theta": self.mrcthetaslider.getValue(),
             "omega": self.mrcomegaslider.getValue()
         }))
     self.inspector().updateSceneGraph()
Пример #15
0
 def _on_XYZ_rotation(self, value):
     self._set_rotation_std_coords(
         Transform({
             "type": "xyz",
             "ztilt": self.xyzzslider.getValue(),
             "ytilt": self.xyzyslider.getValue(),
             "xtilt": self.xyzxslider.getValue()
         }))
     self.inspector().updateSceneGraph()
Пример #16
0
	def _on_translation(self, value):
		"""
		Need to contain the right coords. And do translation in the correct corrd system
		"""
		tt = t = Transform({"tx":self.tx.getValue(),"ty":self.ty.getValue(),"tz":self.tz.getValue()})
		tp = self.item3d().getParentMatrixProduct()
		if tp: tt = tp.inverse()*t
		self.item3d().getTransform().set_trans(tt.get_trans())
		self.inspector().updateSceneGraph()
Пример #17
0
def transform_com(com, ptcl):
    t = Transform()
    if len(com) == 3:
        t.set_rotation({'psi': meta.psi, 'phi': meta.phi, 'theta': meta.theta, 'type': 'spider'})
    else:
        t.set_rotation({'psi': meta.psi})
    shift = t.transform(com)
    # The change in the origin is the projection of the transformed difference vector on the new xy plane.
    return shift[0], shift[1]
Пример #18
0
 def getTransformFromDict(attribdict):
     """ Return a transform using a dict created using the above function"""
     return Transform({
         "type": "eman",
         "az": float(attribdict["az"].text()),
         "alt": float(attribdict["alt"].text()),
         "phi": float(attribdict["phi"].text()),
         "tx": float(attribdict["tx"].text()),
         "ty": float(attribdict["ty"].text()),
         "tz": float(attribdict["tz"].text()),
         "scale": float(attribdict["zoom"].text())
     })
Пример #19
0
    def setUsingDictionary(self, dictionary):
        """
		Set item attributes using a dictionary, used in session restoration
		"""
        self.setTransform(Transform(dictionary["TRANSFORMATION"]))
        self.setVisibleItem(dictionary["VISIBLE"])
        self.setSelectedItem(dictionary["SELECTED"])
        try:
            self.setHiddenSelected(dictionary["HIDDENSEL"])
        except:
            pass
        self.setLabel(dictionary["NAME"])
Пример #20
0
 def _on_spin_rotation(self, value):
     v = Vec3f(self.spinn1slider.getValue(), self.spinn2slider.getValue(),
               self.spinn3slider.getValue())
     v.normalize()
     self._set_rotation_std_coords(
         Transform({
             "type": "spin",
             "omega": self.spinomegaslider.getValue(),
             "n1": v[0],
             "n2": v[1],
             "n3": v[2]
         }))
     self.inspector().updateSceneGraph()
Пример #21
0
def apply_rotation(angleset1, qrot):
	from EMAN2 import Transform, Vec2f

	"""
	if indexes != None:
		new_ang1 = []
		new_ang2 = []
		for i in indexes:
			new_ang1.append(angleset1[i])
			new_ang2.append(angleset2[i])
		angleset1 = new_ang1
		angleset2 = new_ang2
	"""
	import types
	if(type(qrot) == types.ListType): rot = Transform({"type":"spider","phi":qrot[0],"theta":qrot[1],"psi":qrot[2]})
	else:                             rot = qrot
	for i in xrange(len(angleset1)):
		T1 = Transform({"type":"spider","phi":angleset1[i][0],"theta":angleset1[i][1],"psi":angleset1[i][2],"tx":0.0,"ty":0.0,"tz":0.0,"mirror":0,"scale":1.0})
		T1.set_trans(Vec2f(-angleset1[i][3], -angleset1[i][4]))
		T = T1*rot
		d = T.get_params("spider")
		angleset1[i] = [d["phi"], d["theta"], d["psi"], -d["tx"], -d["ty"]]
Пример #22
0
 def _on_sgirot_rotation(self, value):
     v = Vec3f(self.sgirotn1slider.getValue(),
               self.sgirotn2slider.getValue(),
               self.sgirotn3slider.getValue())
     v.normalize()
     self._set_rotation_std_coords(
         Transform({
             "type": "sgirot",
             "q": self.sgirotqslider.getValue(),
             "n1": v[0],
             "n2": v[1],
             "n3": v[2]
         }))
     self.inspector().updateSceneGraph()
Пример #23
0
 def _on_quaternion_rotation(self, value):
     v = Vec4f(self.quaternione0slider.getValue(),
               self.quaternione1slider.getValue(),
               self.quaternione2slider.getValue(),
               self.quaternione3slider.getValue())
     v.normalize()
     self._set_rotation_std_coords(
         Transform({
             "type": "quaternion",
             "e0": v[0],
             "e1": v[1],
             "e2": v[2],
             "e3": v[3]
         }))
     self.inspector().updateSceneGraph()
Пример #24
0
def make_proj(dens, meta):
    """
    Project and CTF filter density according to particle metadata.
    :param dens: EMData density
    :param meta: Particle metadata (Euler angles and CTF parameters)
    :return: CTF-filtered projection
    """
    t = Transform()
    t.set_rotation({'psi': meta.psi, 'phi': meta.phi, 'theta': meta.theta, 'type': 'spider'})
    t.set_trans(-meta.x_origin, -meta.y_origin)
    proj = dens.project("standard", t)
    ctf = generate_ctf(meta.ctf_params)
    ctf_proj = filt_ctf(proj, ctf)
    return ctf_proj
Пример #25
0
    def __init__(self, parent=None, children=[], transform=None):
        """
		@type parent: EMItem3D
		@param parent: the parent node to the current node or None for the root node
		@type children: list
		@param children: the child nodes
		@type transform: Transform or None
		@param transform: The transformation (rotation, scaling, translation) that should be applied before rendering this node and its children 
		"""
        self.label = None  # Customisabl label, used to label the inspector in the tree
        self.setParent(parent)
        self.setChildren(children)
        if not transform: transform = Transform()
        self.transform = transform
        self.is_visible = True
        self.is_selected = False
        self.hide_selection = False
        self.item_inspector = None  # This is an inspector widget
        self.EMQTreeWidgetItem = None  # This is an inspector tree item
        self.boundingboxsize = None
        self.getAndSetUniqueInteger()
Пример #26
0
    def execute(self):
        '''
		The main function - executes the job of performing all v all boot strapped probe generation
		'''
        if self.logger: E2progress(self.logger, 0.0)
        #		all_v_all_cmd = self.get_all_v_all_cmd()
        #		all_v_all_output = self.get_all_v_all_output()
        #
        #		# NOTE: calling the allvall program is probably not strictly necessary, seeing
        #		# as there is a generic framework for generating and executing alignment jobs
        #		# implemented below that would be easily adaptable to this - however I left it
        #		# because doing it this way is absolutely equivalent and has the same cost.
        #		all_v_all_cmd += " --output="+all_v_all_output
        #		print "executing",all_v_all_cmd
        #		if self.logger:	E2progress(self.logger,0.01)
        #		if ( launch_childprocess(all_v_all_cmd) != 0 ):
        #			print "Failed to execute %s" %all_v_all_cmd
        #			sys.exit(1)
        #		if self.logger:	E2progress(self.logger,0.02)
        #
        #		images = []
        #		images.append(EMData(all_v_all_output,0))
        #		images.append(EMData(all_v_all_output,1))
        #		images.append(EMData(all_v_all_output,2))
        #		images.append(EMData(all_v_all_output,3))
        #		images.append(EMData(all_v_all_output,4))
        #		images.append(EMData(all_v_all_output,5))
        #		images.append(EMData(all_v_all_output,6))
        #
        start_n = len(self.files)  # the number of averages produced
        images = []
        e = EMData(start_n, start_n)
        e.to_zero()
        images.append(e)
        for j in range(6):
            images.append(e.copy())

        # keep tracks of the names of the new files
        big_n = images[0].get_xsize() * (images[0].get_xsize() - 1) / 2.0

        iter = 1
        current_files = self.files

        alignment_jobs = []  # a list of comparisons to be performed
        for i in range(len(current_files)):
            for j in range(i + 1, len(current_files)):
                alignment_jobs.append([i, j])

        self.register_current_images(images)
        self.register_current_files(self.files)
        alignments_manager = EMTomoAlignments(self.options)
        alignments_manager.execute(alignment_jobs, self.files, self)
        self.write_current_images(self.files)
        # this loop
        while True:
            couples = self.get_couples(images[0])
            taken = list(range(images[0].get_xsize()))

            done = False
            if len(couples) == 1 and len(taken) == 2: done = True
            #print len(couples),len(taken)
            new_files = []

            # write the averages of the couples to disk, store the new names
            for i, j in couples:
                image_1 = EMData(current_files[j], 0)
                image_2 = EMData(current_files[i], 0)

                image_1_weight = 1
                if image_1.has_attr("total_inc"):
                    image_1_weight = image_1["total_inc"]
                image_2_weight = 1
                if image_2.has_attr("total_inc"):
                    image_2_weight = image_2["total_inc"]
                total_weight = image_1_weight + image_2_weight
                image_1.mult(old_div(float(image_1_weight), total_weight))
                image_2.mult(old_div(float(image_2_weight), total_weight))

                d = {}
                d["type"] = "eman"
                d["tx"] = images[1].get(i, j)
                d["ty"] = images[2].get(i, j)
                d["tz"] = images[3].get(i, j)
                d["az"] = images[4].get(i, j)
                d["alt"] = images[5].get(i, j)
                d["phi"] = images[6].get(i, j)
                t = Transform(d)
                image_1.process_inplace("xform", {"transform": t})

                image_2 += image_1
                image_2.set_attr(
                    "src_image",
                    current_files[j])  # so we can recollect how it was created
                image_2.set_attr(
                    "added_src_image",
                    current_files[i])  # so we can recollect how it was created
                image_2.set_attr("added_src_transform",
                                 t)  # so we can recollect how it was created
                image_2.set_attr("added_src_cmp", images[0](
                    i, j))  # so we can recollect how it was created
                image_2.set_attr(
                    "total_inc",
                    total_weight)  # so we can recollect how it was created

                output_name = numbered_bdb("bdb:" + self.options.path +
                                           "#tomo_ave_0" + str(iter - 1))
                image_2.write_image(output_name, 0)
                if self.options.dbls: self.save_to_workflow_db(output_name)
                new_files.append(output_name)
                taken.remove(i)
                taken.remove(j)

            if done: break

            num_new = len(new_files)  # the number of averages produced
            new_n = len(new_files) + len(taken)
            new_images = []
            e = EMData(new_n, new_n)
            e.to_zero()
            new_images.append(e)
            for j in range(6):
                new_images.append(e.copy())

            for i, idxi in enumerate(taken):
                new_files.append(current_files[idxi])
                for j, idxj in enumerate(taken):
                    if i == j: continue
                    else:
                        new_images[0].set(num_new + i, num_new + j,
                                          images[0].get(idxi, idxj))
                        new_images[1].set(num_new + i, num_new + j,
                                          images[1].get(idxi, idxj))
                        new_images[2].set(num_new + i, num_new + j,
                                          images[2].get(idxi, idxj))
                        new_images[3].set(num_new + i, num_new + j,
                                          images[3].get(idxi, idxj))
                        new_images[4].set(num_new + i, num_new + j,
                                          images[4].get(idxi, idxj))
                        new_images[5].set(num_new + i, num_new + j,
                                          images[5].get(idxi, idxj))
                        new_images[6].set(num_new + i, num_new + j,
                                          images[6].get(idxi, idxj))

            alignment_jobs = []  # a list of comparisons to be performed
            for i in range(num_new):
                for j in range(i + 1, len(new_files)):
                    alignment_jobs.append([i, j])

            if self.logger:
                E2progress(self.logger,
                           1.0 - old_div(len(alignment_jobs), big_n))

            self.register_current_images(new_images)
            self.register_current_files(new_files)
            alignments_manager = EMTomoAlignments(self.options)
            alignments_manager.execute(alignment_jobs, new_files, self)

            self.write_current_images(new_files)
            current_files = new_files
            images = new_images
            iter += 1
            print(couples, taken)

        if self.logger: E2progress(self.logger, 1.0)
Пример #27
0
def main():

	def params_3D_2D_NEW(phi, theta, psi, s2x, s2y, mirror):
		# the final ali2d parameters already combine shifts operation first and rotation operation second for parameters converted from 3D
		if mirror:
			m = 1
			alpha, sx, sy, scalen = compose_transform2(0, s2x, s2y, 1.0, 540.0-psi, 0, 0, 1.0)
		else:
			m = 0
			alpha, sx, sy, scalen = compose_transform2(0, s2x, s2y, 1.0, 360.0-psi, 0, 0, 1.0)
		return  alpha, sx, sy, m
	
	progname = os.path.basename(sys.argv[0])
	usage = progname + " prj_stack  --ave2D= --var2D=  --ave3D= --var3D= --img_per_grp= --fl=  --aa=   --sym=symmetry --CTF"
	parser = OptionParser(usage, version=SPARXVERSION)
	
	parser.add_option("--output_dir",   type="string"	   ,	default="./",				    help="Output directory")
	parser.add_option("--ave2D",		type="string"	   ,	default=False,				help="Write to the disk a stack of 2D averages")
	parser.add_option("--var2D",		type="string"	   ,	default=False,				help="Write to the disk a stack of 2D variances")
	parser.add_option("--ave3D",		type="string"	   ,	default=False,				help="Write to the disk reconstructed 3D average")
	parser.add_option("--var3D",		type="string"	   ,	default=False,				help="Compute 3D variability (time consuming!)")
	parser.add_option("--img_per_grp",	type="int"         ,	default=100,	     	    help="Number of neighbouring projections.(Default is 100)")
	parser.add_option("--no_norm",		action="store_true",	default=False,				help="Do not use normalization.(Default is to apply normalization)")
	#parser.add_option("--radius", 	    type="int"         ,	default=-1   ,				help="radius for 3D variability" )
	parser.add_option("--npad",			type="int"         ,	default=2    ,				help="Number of time to pad the original images.(Default is 2 times padding)")
	parser.add_option("--sym" , 		type="string"      ,	default="c1",				help="Symmetry. (Default is no symmetry)")
	parser.add_option("--fl",			type="float"       ,	default=0.0,				help="Low pass filter cutoff in absolute frequency (0.0 - 0.5) and is applied to decimated images. (Default - no filtration)")
	parser.add_option("--aa",			type="float"       ,	default=0.02 ,				help="Fall off of the filter. Use default value if user has no clue about falloff (Default value is 0.02)")
	parser.add_option("--CTF",			action="store_true",	default=False,				help="Use CFT correction.(Default is no CTF correction)")
	#parser.add_option("--MPI" , 		action="store_true",	default=False,				help="use MPI version")
	#parser.add_option("--radiuspca", 	type="int"         ,	default=-1   ,				help="radius for PCA" )
	#parser.add_option("--iter", 		type="int"         ,	default=40   ,				help="maximum number of iterations (stop criterion of reconstruction process)" )
	#parser.add_option("--abs", 		type="float"   ,        default=0.0  ,				help="minimum average absolute change of voxels' values (stop criterion of reconstruction process)" )
	#parser.add_option("--squ", 		type="float"   ,	    default=0.0  ,				help="minimum average squared change of voxels' values (stop criterion of reconstruction process)" )
	parser.add_option("--VAR" , 		action="store_true",	default=False,				help="Stack of input consists of 2D variances (Default False)")
	parser.add_option("--decimate",     type  ="float",         default=0.25,               help="Image decimate rate, a number less than 1. (Default is 0.25)")
	parser.add_option("--window",       type  ="int",           default=0,                  help="Target image size relative to original image size. (Default value is zero.)")
	#parser.add_option("--SND",			action="store_true",	default=False,				help="compute squared normalized differences (Default False)")
	#parser.add_option("--nvec",			type="int"         ,	default=0    ,				help="Number of eigenvectors, (Default = 0 meaning no PCA calculated)")
	parser.add_option("--symmetrize",	action="store_true",	default=False,				help="Prepare input stack for handling symmetry (Default False)")
	parser.add_option("--overhead",     type  ="float",         default=0.5,                help="python overhead per CPU.")

	(options,args) = parser.parse_args()
	#####
	from mpi import mpi_init, mpi_comm_rank, mpi_comm_size, mpi_recv, MPI_COMM_WORLD
	from mpi import mpi_barrier, mpi_reduce, mpi_bcast, mpi_send, MPI_FLOAT, MPI_SUM, MPI_INT, MPI_MAX
	#from mpi import *
	from applications   import MPI_start_end
	from reconstruction import recons3d_em, recons3d_em_MPI
	from reconstruction	import recons3d_4nn_MPI, recons3d_4nn_ctf_MPI
	from utilities      import print_begin_msg, print_end_msg, print_msg
	from utilities      import read_text_row, get_image, get_im, wrap_mpi_send, wrap_mpi_recv
	from utilities      import bcast_EMData_to_all, bcast_number_to_all
	from utilities      import get_symt

	#  This is code for handling symmetries by the above program.  To be incorporated. PAP 01/27/2015

	from EMAN2db import db_open_dict

	# Set up global variables related to bdb cache 
	if global_def.CACHE_DISABLE:
		from utilities import disable_bdb_cache
		disable_bdb_cache()
	
	# Set up global variables related to ERROR function
	global_def.BATCH = True
	
	# detect if program is running under MPI
	RUNNING_UNDER_MPI = "OMPI_COMM_WORLD_SIZE" in os.environ
	if RUNNING_UNDER_MPI: global_def.MPI = True
	if options.output_dir =="./": current_output_dir = os.path.abspath(options.output_dir)
	else: current_output_dir = options.output_dir
	if options.symmetrize :
		if RUNNING_UNDER_MPI:
			try:
				sys.argv = mpi_init(len(sys.argv), sys.argv)
				try:	
					number_of_proc = mpi_comm_size(MPI_COMM_WORLD)
					if( number_of_proc > 1 ):
						ERROR("Cannot use more than one CPU for symmetry preparation","sx3dvariability",1)
				except:
					pass
			except:
				pass
		if not os.path.exists(current_output_dir): os.mkdir(current_output_dir)
		
		#  Input
		#instack = "Clean_NORM_CTF_start_wparams.hdf"
		#instack = "bdb:data"
		
		
		from logger import Logger,BaseLogger_Files
		if os.path.exists(os.path.join(current_output_dir, "log.txt")): os.remove(os.path.join(current_output_dir, "log.txt"))
		log_main=Logger(BaseLogger_Files())
		log_main.prefix = os.path.join(current_output_dir, "./")
		
		instack = args[0]
		sym = options.sym.lower()
		if( sym == "c1" ):
			ERROR("There is no need to symmetrize stack for C1 symmetry","sx3dvariability",1)
		
		line =""
		for a in sys.argv:
			line +=" "+a
		log_main.add(line)
	
		if(instack[:4] !="bdb:"):
			#if output_dir =="./": stack = "bdb:data"
			stack = "bdb:"+current_output_dir+"/data"
			delete_bdb(stack)
			junk = cmdexecute("sxcpy.py  "+instack+"  "+stack)
		else: stack = instack
		
		qt = EMUtil.get_all_attributes(stack,'xform.projection')

		na = len(qt)
		ts = get_symt(sym)
		ks = len(ts)
		angsa = [None]*na
		
		for k in range(ks):
			#Qfile = "Q%1d"%k
			#if options.output_dir!="./": Qfile = os.path.join(options.output_dir,"Q%1d"%k)
			Qfile = os.path.join(current_output_dir, "Q%1d"%k)
			#delete_bdb("bdb:Q%1d"%k)
			delete_bdb("bdb:"+Qfile)
			#junk = cmdexecute("e2bdb.py  "+stack+"  --makevstack=bdb:Q%1d"%k)
			junk = cmdexecute("e2bdb.py  "+stack+"  --makevstack=bdb:"+Qfile)
			#DB = db_open_dict("bdb:Q%1d"%k)
			DB = db_open_dict("bdb:"+Qfile)
			for i in range(na):
				ut = qt[i]*ts[k]
				DB.set_attr(i, "xform.projection", ut)
				#bt = ut.get_params("spider")
				#angsa[i] = [round(bt["phi"],3)%360.0, round(bt["theta"],3)%360.0, bt["psi"], -bt["tx"], -bt["ty"]]
			#write_text_row(angsa, 'ptsma%1d.txt'%k)
			#junk = cmdexecute("e2bdb.py  "+stack+"  --makevstack=bdb:Q%1d"%k)
			#junk = cmdexecute("sxheader.py  bdb:Q%1d  --params=xform.projection  --import=ptsma%1d.txt"%(k,k))
			DB.close()
		#if options.output_dir =="./": delete_bdb("bdb:sdata")
		delete_bdb("bdb:" + current_output_dir + "/"+"sdata")
		#junk = cmdexecute("e2bdb.py . --makevstack=bdb:sdata --filt=Q")
		sdata = "bdb:"+current_output_dir+"/"+"sdata"
		print(sdata)
		junk = cmdexecute("e2bdb.py   " + current_output_dir +"  --makevstack="+sdata +" --filt=Q")
		#junk = cmdexecute("ls  EMAN2DB/sdata*")
		#a = get_im("bdb:sdata")
		a = get_im(sdata)
		a.set_attr("variabilitysymmetry",sym)
		#a.write_image("bdb:sdata")
		a.write_image(sdata)

	else:

		from fundamentals import window2d
		sys.argv       = mpi_init(len(sys.argv), sys.argv)
		myid           = mpi_comm_rank(MPI_COMM_WORLD)
		number_of_proc = mpi_comm_size(MPI_COMM_WORLD)
		main_node      = 0
		shared_comm  = mpi_comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED,  0, MPI_INFO_NULL)
		myid_on_node = mpi_comm_rank(shared_comm)
		no_of_processes_per_group = mpi_comm_size(shared_comm)
		masters_from_groups_vs_everything_else_comm = mpi_comm_split(MPI_COMM_WORLD, main_node == myid_on_node, myid_on_node)
		color, no_of_groups, balanced_processor_load_on_nodes = get_colors_and_subsets(main_node, MPI_COMM_WORLD, myid, \
		    shared_comm, myid_on_node, masters_from_groups_vs_everything_else_comm)
		overhead_loading = options.overhead*number_of_proc
		#memory_per_node  = options.memory_per_node
		#if memory_per_node == -1.: memory_per_node = 2.*no_of_processes_per_group
		keepgoing = 1
		
		current_window   = options.window
		current_decimate = options.decimate
		
		if len(args) == 1: stack = args[0]
		else:
			print(( "usage: " + usage))
			print(( "Please run '" + progname + " -h' for detailed options"))
			return 1

		t0 = time()	
		# obsolete flags
		options.MPI  = True
		#options.nvec = 0
		options.radiuspca = -1
		options.iter = 40
		options.abs  = 0.0
		options.squ  = 0.0

		if options.fl > 0.0 and options.aa == 0.0:
			ERROR("Fall off has to be given for the low-pass filter", "sx3dvariability", 1, myid)
			
		#if options.VAR and options.SND:
		#	ERROR("Only one of var and SND can be set!", "sx3dvariability", myid)
			
		if options.VAR and (options.ave2D or options.ave3D or options.var2D): 
			ERROR("When VAR is set, the program cannot output ave2D, ave3D or var2D", "sx3dvariability", 1, myid)
			
		#if options.SND and (options.ave2D or options.ave3D):
		#	ERROR("When SND is set, the program cannot output ave2D or ave3D", "sx3dvariability", 1, myid)
		
		#if options.nvec > 0 :
		#	ERROR("PCA option not implemented", "sx3dvariability", 1, myid)
			
		#if options.nvec > 0 and options.ave3D == None:
		#	ERROR("When doing PCA analysis, one must set ave3D", "sx3dvariability", 1, myid)
		
		if current_decimate>1.0 or current_decimate<0.0:
			ERROR("Decimate rate should be a value between 0.0 and 1.0", "sx3dvariability", 1, myid)
		
		if current_window < 0.0:
			ERROR("Target window size should be always larger than zero", "sx3dvariability", 1, myid)
			
		if myid == main_node:
			img  = get_image(stack, 0)
			nx   = img.get_xsize()
			ny   = img.get_ysize()
			if(min(nx, ny) < current_window):   keepgoing = 0
		keepgoing = bcast_number_to_all(keepgoing, main_node, MPI_COMM_WORLD)
		if keepgoing == 0: ERROR("The target window size cannot be larger than the size of decimated image", "sx3dvariability", 1, myid)

		import string
		options.sym = options.sym.lower()
		# if global_def.CACHE_DISABLE:
		# 	from utilities import disable_bdb_cache
		# 	disable_bdb_cache()
		# global_def.BATCH = True
		
		if myid == main_node:
			if not os.path.exists(current_output_dir): os.mkdir(current_output_dir)# Never delete output_dir in the program!
	
		img_per_grp = options.img_per_grp
		#nvec        = options.nvec
		radiuspca   = options.radiuspca
		from logger import Logger,BaseLogger_Files
		#if os.path.exists(os.path.join(options.output_dir, "log.txt")): os.remove(os.path.join(options.output_dir, "log.txt"))
		log_main=Logger(BaseLogger_Files())
		log_main.prefix = os.path.join(current_output_dir, "./")

		if myid == main_node:
			line = ""
			for a in sys.argv: line +=" "+a
			log_main.add(line)
			log_main.add("-------->>>Settings given by all options<<<-------")
			log_main.add("Symmetry             : %s"%options.sym)
			log_main.add("Input stack          : %s"%stack)
			log_main.add("Output_dir           : %s"%current_output_dir)
			
			if options.ave3D: log_main.add("Ave3d                : %s"%options.ave3D)
			if options.var3D: log_main.add("Var3d                : %s"%options.var3D)
			if options.ave2D: log_main.add("Ave2D                : %s"%options.ave2D)
			if options.var2D: log_main.add("Var2D                : %s"%options.var2D)
			if options.VAR:   log_main.add("VAR                  : True")
			else:             log_main.add("VAR                  : False")
			if options.CTF:   log_main.add("CTF correction       : True  ")
			else:             log_main.add("CTF correction       : False ")
			
			log_main.add("Image per group      : %5d"%options.img_per_grp)
			log_main.add("Image decimate rate  : %4.3f"%current_decimate)
			log_main.add("Low pass filter      : %4.3f"%options.fl)
			current_fl = options.fl
			if current_fl == 0.0: current_fl = 0.5
			log_main.add("Current low pass filter is equivalent to cutoff frequency %4.3f for original image size"%round((current_fl*current_decimate),3))
			log_main.add("Window size          : %5d "%current_window)
			log_main.add("sx3dvariability begins")
	
		symbaselen = 0
		if myid == main_node:
			nima = EMUtil.get_image_count(stack)
			img  = get_image(stack)
			nx   = img.get_xsize()
			ny   = img.get_ysize()
			nnxo = nx
			nnyo = ny
			if options.sym != "c1" :
				imgdata = get_im(stack)
				try:
					i = imgdata.get_attr("variabilitysymmetry").lower()
					if(i != options.sym):
						ERROR("The symmetry provided does not agree with the symmetry of the input stack", "sx3dvariability", 1, myid)
				except:
					ERROR("Input stack is not prepared for symmetry, please follow instructions", "sx3dvariability", 1, myid)
				from utilities import get_symt
				i = len(get_symt(options.sym))
				if((nima/i)*i != nima):
					ERROR("The length of the input stack is incorrect for symmetry processing", "sx3dvariability", 1, myid)
				symbaselen = nima/i
			else:  symbaselen = nima
		else:
			nima = 0
			nx = 0
			ny = 0
			nnxo = 0
			nnyo = 0
		nima    = bcast_number_to_all(nima)
		nx      = bcast_number_to_all(nx)
		ny      = bcast_number_to_all(ny)
		nnxo    = bcast_number_to_all(nnxo)
		nnyo    = bcast_number_to_all(nnyo)
		if current_window > max(nx, ny):
			ERROR("Window size is larger than the original image size", "sx3dvariability", 1)
		
		if current_decimate == 1.:
			if current_window !=0:
				nx = current_window
				ny = current_window
		else:
			if current_window == 0:
				nx = int(nx*current_decimate+0.5)
				ny = int(ny*current_decimate+0.5)
			else:
				nx = int(current_window*current_decimate+0.5)
				ny = nx
		symbaselen = bcast_number_to_all(symbaselen)
		
		# check FFT prime number
		from fundamentals import smallprime
		is_fft_friendly = (nx == smallprime(nx))
		
		if not is_fft_friendly:
			if myid == main_node:
				log_main.add("The target image size is not a product of small prime numbers")
				log_main.add("Program adjusts the input settings!")
			### two cases
			if current_decimate == 1.:
				nx = smallprime(nx)
				ny = nx
				current_window = nx # update
				if myid == main_node:
					log_main.add("The window size is updated to %d."%current_window)
			else:
				if current_window == 0:
					nx = smallprime(int(nx*current_decimate+0.5))
					current_decimate = float(nx)/nnxo
					ny = nx
					if (myid == main_node):
						log_main.add("The decimate rate is updated to %f."%current_decimate)
				else:
					nx = smallprime(int(current_window*current_decimate+0.5))
					ny = nx
					current_window = int(nx/current_decimate+0.5)
					if (myid == main_node):
						log_main.add("The window size is updated to %d."%current_window)
						
		if myid == main_node:
			log_main.add("The target image size is %d"%nx)
						
		if radiuspca == -1: radiuspca = nx/2-2
		if myid == main_node: log_main.add("%-70s:  %d\n"%("Number of projection", nima))
		img_begin, img_end = MPI_start_end(nima, number_of_proc, myid)
		
		"""
		if options.SND:
			from projection		import prep_vol, prgs
			from statistics		import im_diff
			from utilities		import get_im, model_circle, get_params_proj, set_params_proj
			from utilities		import get_ctf, generate_ctf
			from filter			import filt_ctf
		
			imgdata = EMData.read_images(stack, range(img_begin, img_end))

			if options.CTF:
				vol = recons3d_4nn_ctf_MPI(myid, imgdata, 1.0, symmetry=options.sym, npad=options.npad, xysize=-1, zsize=-1)
			else:
				vol = recons3d_4nn_MPI(myid, imgdata, symmetry=options.sym, npad=options.npad, xysize=-1, zsize=-1)

			bcast_EMData_to_all(vol, myid)
			volft, kb = prep_vol(vol)

			mask = model_circle(nx/2-2, nx, ny)
			varList = []
			for i in xrange(img_begin, img_end):
				phi, theta, psi, s2x, s2y = get_params_proj(imgdata[i-img_begin])
				ref_prj = prgs(volft, kb, [phi, theta, psi, -s2x, -s2y])
				if options.CTF:
					ctf_params = get_ctf(imgdata[i-img_begin])
					ref_prj = filt_ctf(ref_prj, generate_ctf(ctf_params))
				diff, A, B = im_diff(ref_prj, imgdata[i-img_begin], mask)
				diff2 = diff*diff
				set_params_proj(diff2, [phi, theta, psi, s2x, s2y])
				varList.append(diff2)
			mpi_barrier(MPI_COMM_WORLD)
		"""
		
		if options.VAR: # 2D variance images have no shifts
			#varList   = EMData.read_images(stack, range(img_begin, img_end))
			from EMAN2 import Region
			for index_of_particle in range(img_begin,img_end):
				image = get_im(stack, index_of_proj)
				if current_window > 0: varList.append(fdecimate(window2d(image,current_window,current_window), nx,ny))
				else:   varList.append(fdecimate(image, nx,ny))
				
		else:
			from utilities		import bcast_number_to_all, bcast_list_to_all, send_EMData, recv_EMData
			from utilities		import set_params_proj, get_params_proj, params_3D_2D, get_params2D, set_params2D, compose_transform2
			from utilities		import model_blank, nearest_proj, model_circle, write_text_row, wrap_mpi_gatherv
			from applications	import pca
			from statistics		import avgvar, avgvar_ctf, ccc
			from filter		    import filt_tanl
			from morphology		import threshold, square_root
			from projection 	import project, prep_vol, prgs
			from sets		    import Set
			from utilities      import wrap_mpi_recv, wrap_mpi_bcast, wrap_mpi_send
			import numpy as np
			if myid == main_node:
				t1          = time()
				proj_angles = []
				aveList     = []
				tab = EMUtil.get_all_attributes(stack, 'xform.projection')	
				for i in range(nima):
					t     = tab[i].get_params('spider')
					phi   = t['phi']
					theta = t['theta']
					psi   = t['psi']
					x     = theta
					if x > 90.0: x = 180.0 - x
					x = x*10000+psi
					proj_angles.append([x, t['phi'], t['theta'], t['psi'], i])
				t2 = time()
				log_main.add( "%-70s:  %d\n"%("Number of neighboring projections", img_per_grp))
				log_main.add("...... Finding neighboring projections\n")
				log_main.add( "Number of images per group: %d"%img_per_grp)
				log_main.add( "Now grouping projections")
				proj_angles.sort()
				proj_angles_list = np.full((nima, 4), 0.0, dtype=np.float32)	
				for i in range(nima):
					proj_angles_list[i][0] = proj_angles[i][1]
					proj_angles_list[i][1] = proj_angles[i][2]
					proj_angles_list[i][2] = proj_angles[i][3]
					proj_angles_list[i][3] = proj_angles[i][4]
			else: proj_angles_list = 0
			proj_angles_list = wrap_mpi_bcast(proj_angles_list, main_node, MPI_COMM_WORLD)
			proj_angles      = []
			for i in range(nima):
				proj_angles.append([proj_angles_list[i][0], proj_angles_list[i][1], proj_angles_list[i][2], int(proj_angles_list[i][3])])
			del proj_angles_list
			proj_list, mirror_list = nearest_proj(proj_angles, img_per_grp, range(img_begin, img_end))
			all_proj = Set()
			for im in proj_list:
				for jm in im:
					all_proj.add(proj_angles[jm][3])
			all_proj = list(all_proj)
			index = {}
			for i in range(len(all_proj)): index[all_proj[i]] = i
			mpi_barrier(MPI_COMM_WORLD)
			if myid == main_node:
				log_main.add("%-70s:  %.2f\n"%("Finding neighboring projections lasted [s]", time()-t2))
				log_main.add("%-70s:  %d\n"%("Number of groups processed on the main node", len(proj_list)))
				log_main.add("Grouping projections took:  %12.1f [m]"%((time()-t2)/60.))
				log_main.add("Number of groups on main node: ", len(proj_list))
			mpi_barrier(MPI_COMM_WORLD)

			if myid == main_node:
				log_main.add("...... Calculating the stack of 2D variances \n")
			# Memory estimation. There are two memory consumption peaks
			# peak 1. Compute ave, var; 
			# peak 2. Var volume reconstruction;
			# proj_params = [0.0]*(nima*5)
			aveList = []
			varList = []				
			#if nvec > 0: eigList = [[] for i in range(nvec)]
			dnumber   = len(all_proj)# all neighborhood set for assigned to myid
			pnumber   = len(proj_list)*2. + img_per_grp # aveList and varList 
			tnumber   = dnumber+pnumber
			vol_size2 = nx**3*4.*8/1.e9
			vol_size1 = 2.*nnxo**3*4.*8/1.e9
			proj_size         = nnxo*nnyo*len(proj_list)*4.*2./1.e9 # both aveList and varList
			orig_data_size    = nnxo*nnyo*4.*tnumber/1.e9
			reduced_data_size = nx*nx*4.*tnumber/1.e9
			full_data         = np.full((number_of_proc, 2), -1., dtype=np.float16)
			full_data[myid]   = orig_data_size, reduced_data_size
			if myid != main_node: wrap_mpi_send(full_data, main_node, MPI_COMM_WORLD)
			if myid == main_node:
				for iproc in range(number_of_proc):
					if iproc != main_node:
						dummy = wrap_mpi_recv(iproc, MPI_COMM_WORLD)
						full_data[np.where(dummy>-1)] = dummy[np.where(dummy>-1)]
				del dummy
			mpi_barrier(MPI_COMM_WORLD)
			full_data = wrap_mpi_bcast(full_data, main_node, MPI_COMM_WORLD)
			# find the CPU with heaviest load
			minindx         = np.argsort(full_data, 0)
			heavy_load_myid = minindx[-1][1]
			total_mem       = sum(full_data)
			if myid == main_node:
				if current_window == 0:
					log_main.add("Nx:   current image size = %d. Decimated by %f from %d"%(nx, current_decimate, nnxo))
				else:
					log_main.add("Nx:   current image size = %d. Windowed to %d, and decimated by %f from %d"%(nx, current_window, current_decimate, nnxo))
				log_main.add("Nproj:       number of particle images.")
				log_main.add("Navg:        number of 2D average images.")
				log_main.add("Nvar:        number of 2D variance images.")
				log_main.add("Img_per_grp: user defined image per group for averaging = %d"%img_per_grp)
				log_main.add("Overhead:    total python overhead memory consumption   = %f"%overhead_loading)
				log_main.add("Total memory) = 4.0*nx^2*(nproj + navg +nvar+ img_per_grp)/1.0e9 + overhead: %12.3f [GB]"%\
				   (total_mem[1] + overhead_loading))
			del full_data
			mpi_barrier(MPI_COMM_WORLD)
			if myid == heavy_load_myid:
				log_main.add("Begin reading and preprocessing images on processor. Wait... ")
				ttt = time()
			#imgdata = EMData.read_images(stack, all_proj)			
			imgdata = [ None for im in range(len(all_proj))]
			for index_of_proj in range(len(all_proj)):
				#image = get_im(stack, all_proj[index_of_proj])
				if( current_window > 0): imgdata[index_of_proj] = fdecimate(window2d(get_im(stack, all_proj[index_of_proj]),current_window,current_window), nx, ny)
				else:                    imgdata[index_of_proj] = fdecimate(get_im(stack, all_proj[index_of_proj]), nx, ny)
				
				if (current_decimate> 0.0 and options.CTF):
					ctf = imgdata[index_of_proj].get_attr("ctf")
					ctf.apix = ctf.apix/current_decimate
					imgdata[index_of_proj].set_attr("ctf", ctf)
					
				if myid == heavy_load_myid and index_of_proj%100 == 0:
					log_main.add(" ...... %6.2f%% "%(index_of_proj/float(len(all_proj))*100.))
			mpi_barrier(MPI_COMM_WORLD)
			if myid == heavy_load_myid:
				log_main.add("All_proj preprocessing cost %7.2f m"%((time()-ttt)/60.))
				log_main.add("Wait untill reading on all CPUs done...")
			'''	
			imgdata2 = EMData.read_images(stack, range(img_begin, img_end))
			if options.fl > 0.0:
				for k in xrange(len(imgdata2)):
					imgdata2[k] = filt_tanl(imgdata2[k], options.fl, options.aa)
			if options.CTF:
				vol = recons3d_4nn_ctf_MPI(myid, imgdata2, 1.0, symmetry=options.sym, npad=options.npad, xysize=-1, zsize=-1)
			else:
				vol = recons3d_4nn_MPI(myid, imgdata2, symmetry=options.sym, npad=options.npad, xysize=-1, zsize=-1)
			if myid == main_node:
				vol.write_image("vol_ctf.hdf")
				print_msg("Writing to the disk volume reconstructed from averages as		:  %s\n"%("vol_ctf.hdf"))
			del vol, imgdata2
			mpi_barrier(MPI_COMM_WORLD)
			'''
			from applications import prepare_2d_forPCA
			from utilities    import model_blank
			from EMAN2        import Transform
			if not options.no_norm: 
				mask = model_circle(nx/2-2, nx, nx)
			if options.CTF: 
				from utilities import pad
				from filter import filt_ctf
			from filter import filt_tanl
			if myid == heavy_load_myid:
				log_main.add("Start computing 2D aveList and varList. Wait...")
				ttt = time()
			inner=nx//2-4
			outer=inner+2
			xform_proj_for_2D = [ None for i in range(len(proj_list))]
			for i in range(len(proj_list)):
				ki = proj_angles[proj_list[i][0]][3]
				if ki >= symbaselen:  continue
				mi = index[ki]
				dpar = Util.get_transform_params(imgdata[mi], "xform.projection", "spider")
				phiM, thetaM, psiM, s2xM, s2yM  = dpar["phi"],dpar["theta"],dpar["psi"],-dpar["tx"]*current_decimate,-dpar["ty"]*current_decimate
				grp_imgdata = []
				for j in range(img_per_grp):
					mj = index[proj_angles[proj_list[i][j]][3]]
					cpar = Util.get_transform_params(imgdata[mj], "xform.projection", "spider")
					alpha, sx, sy, mirror = params_3D_2D_NEW(cpar["phi"], cpar["theta"],cpar["psi"], -cpar["tx"]*current_decimate, -cpar["ty"]*current_decimate, mirror_list[i][j])
					if thetaM <= 90:
						if mirror == 0:  alpha, sx, sy, scale = compose_transform2(alpha, sx, sy, 1.0, phiM - cpar["phi"], 0.0, 0.0, 1.0)
						else:            alpha, sx, sy, scale = compose_transform2(alpha, sx, sy, 1.0, 180-(phiM - cpar["phi"]), 0.0, 0.0, 1.0)
					else:
						if mirror == 0:  alpha, sx, sy, scale = compose_transform2(alpha, sx, sy, 1.0, -(phiM- cpar["phi"]), 0.0, 0.0, 1.0)
						else:            alpha, sx, sy, scale = compose_transform2(alpha, sx, sy, 1.0, -(180-(phiM - cpar["phi"])), 0.0, 0.0, 1.0)
					imgdata[mj].set_attr("xform.align2d", Transform({"type":"2D","alpha":alpha,"tx":sx,"ty":sy,"mirror":mirror,"scale":1.0}))
					grp_imgdata.append(imgdata[mj])
				if not options.no_norm:
					for k in range(img_per_grp):
						ave, std, minn, maxx = Util.infomask(grp_imgdata[k], mask, False)
						grp_imgdata[k] -= ave
						grp_imgdata[k] /= std
				if options.fl > 0.0:
					for k in range(img_per_grp):
						grp_imgdata[k] = filt_tanl(grp_imgdata[k], options.fl, options.aa)

				#  Because of background issues, only linear option works.
				if options.CTF:  ave, var = aves_wiener(grp_imgdata, SNR = 1.0e5, interpolation_method = "linear")
				else:  ave, var = ave_var(grp_imgdata)
				# Switch to std dev
				# threshold is not really needed,it is just in case due to numerical accuracy something turns out negative.
				var = square_root(threshold(var))

				set_params_proj(ave, [phiM, thetaM, 0.0, 0.0, 0.0])
				set_params_proj(var, [phiM, thetaM, 0.0, 0.0, 0.0])

				aveList.append(ave)
				varList.append(var)
				xform_proj_for_2D[i] = [phiM, thetaM, 0.0, 0.0, 0.0]

				'''
				if nvec > 0:
					eig = pca(input_stacks=grp_imgdata, subavg="", mask_radius=radiuspca, nvec=nvec, incore=True, shuffle=False, genbuf=True)
					for k in range(nvec):
						set_params_proj(eig[k], [phiM, thetaM, 0.0, 0.0, 0.0])
						eigList[k].append(eig[k])
					"""
					if myid == 0 and i == 0:
						for k in xrange(nvec):
							eig[k].write_image("eig.hdf", k)
					"""
				'''
				if (myid == heavy_load_myid) and (i%100 == 0):
					log_main.add(" ......%6.2f%%  "%(i/float(len(proj_list))*100.))		
			del imgdata, grp_imgdata, cpar, dpar, all_proj, proj_angles, index
			if not options.no_norm: del mask
			if myid == main_node: del tab
			#  At this point, all averages and variances are computed
			mpi_barrier(MPI_COMM_WORLD)
			
			if (myid == heavy_load_myid):
				log_main.add("Computing aveList and varList took %12.1f [m]"%((time()-ttt)/60.))
			
			xform_proj_for_2D = wrap_mpi_gatherv(xform_proj_for_2D, main_node, MPI_COMM_WORLD)
			if (myid == main_node):
				write_text_row(xform_proj_for_2D, os.path.join(current_output_dir, "params.txt"))
			del xform_proj_for_2D
			mpi_barrier(MPI_COMM_WORLD)
			if options.ave2D:
				from fundamentals import fpol
				from applications import header
				if myid == main_node:
					log_main.add("Compute ave2D ... ")
					km = 0
					for i in range(number_of_proc):
						if i == main_node :
							for im in range(len(aveList)):
								aveList[im].write_image(os.path.join(current_output_dir, options.ave2D), km)
								km += 1
						else:
							nl = mpi_recv(1, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
							nl = int(nl[0])
							for im in range(nl):
								ave = recv_EMData(i, im+i+70000)
								"""
								nm = mpi_recv(1, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
								nm = int(nm[0])
								members = mpi_recv(nm, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
								ave.set_attr('members', map(int, members))
								members = mpi_recv(nm, MPI_FLOAT, i, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
								ave.set_attr('pix_err', map(float, members))
								members = mpi_recv(3, MPI_FLOAT, i, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
								ave.set_attr('refprojdir', map(float, members))
								"""
								tmpvol=fpol(ave, nx, nx,1)								
								tmpvol.write_image(os.path.join(current_output_dir, options.ave2D), km)
								km += 1
				else:
					mpi_send(len(aveList), 1, MPI_INT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
					for im in range(len(aveList)):
						send_EMData(aveList[im], main_node,im+myid+70000)
						"""
						members = aveList[im].get_attr('members')
						mpi_send(len(members), 1, MPI_INT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
						mpi_send(members, len(members), MPI_INT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
						members = aveList[im].get_attr('pix_err')
						mpi_send(members, len(members), MPI_FLOAT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
						try:
							members = aveList[im].get_attr('refprojdir')
							mpi_send(members, 3, MPI_FLOAT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
						except:
							mpi_send([-999.0,-999.0,-999.0], 3, MPI_FLOAT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
						"""
				if myid == main_node:
					header(os.path.join(current_output_dir, options.ave2D), params='xform.projection', fimport = os.path.join(current_output_dir, "params.txt"))
				mpi_barrier(MPI_COMM_WORLD)	
			if options.ave3D:
				from fundamentals import fpol
				t5 = time()
				if myid == main_node: log_main.add("Reconstruct ave3D ... ")
				ave3D = recons3d_4nn_MPI(myid, aveList, symmetry=options.sym, npad=options.npad)
				bcast_EMData_to_all(ave3D, myid)
				if myid == main_node:
					if current_decimate != 1.0: ave3D = resample(ave3D, 1./current_decimate)
					ave3D = fpol(ave3D, nnxo, nnxo, nnxo) # always to the orignal image size
					set_pixel_size(ave3D, 1.0)
					ave3D.write_image(os.path.join(current_output_dir, options.ave3D))
					log_main.add("Ave3D reconstruction took %12.1f [m]"%((time()-t5)/60.0))
					log_main.add("%-70s:  %s\n"%("The reconstructed ave3D is saved as ", options.ave3D))
					
			mpi_barrier(MPI_COMM_WORLD)		
			del ave, var, proj_list, stack, alpha, sx, sy, mirror, aveList
			'''
			if nvec > 0:
				for k in range(nvec):
					if myid == main_node:log_main.add("Reconstruction eigenvolumes", k)
					cont = True
					ITER = 0
					mask2d = model_circle(radiuspca, nx, nx)
					while cont:
						#print "On node %d, iteration %d"%(myid, ITER)
						eig3D = recons3d_4nn_MPI(myid, eigList[k], symmetry=options.sym, npad=options.npad)
						bcast_EMData_to_all(eig3D, myid, main_node)
						if options.fl > 0.0:
							eig3D = filt_tanl(eig3D, options.fl, options.aa)
						if myid == main_node:
							eig3D.write_image(os.path.join(options.outpout_dir, "eig3d_%03d.hdf"%(k, ITER)))
						Util.mul_img( eig3D, model_circle(radiuspca, nx, nx, nx) )
						eig3Df, kb = prep_vol(eig3D)
						del eig3D
						cont = False
						icont = 0
						for l in range(len(eigList[k])):
							phi, theta, psi, s2x, s2y = get_params_proj(eigList[k][l])
							proj = prgs(eig3Df, kb, [phi, theta, psi, s2x, s2y])
							cl = ccc(proj, eigList[k][l], mask2d)
							if cl < 0.0:
								icont += 1
								cont = True
								eigList[k][l] *= -1.0
						u = int(cont)
						u = mpi_reduce([u], 1, MPI_INT, MPI_MAX, main_node, MPI_COMM_WORLD)
						icont = mpi_reduce([icont], 1, MPI_INT, MPI_SUM, main_node, MPI_COMM_WORLD)

						if myid == main_node:
							u = int(u[0])
							log_main.add(" Eigenvector: ",k," number changed ",int(icont[0]))
						else: u = 0
						u = bcast_number_to_all(u, main_node)
						cont = bool(u)
						ITER += 1

					del eig3Df, kb
					mpi_barrier(MPI_COMM_WORLD)
				del eigList, mask2d
			'''
			if options.ave3D: del ave3D
			if options.var2D:
				from fundamentals import fpol 
				from applications import header
				if myid == main_node:
					log_main.add("Compute var2D...")
					km = 0
					for i in range(number_of_proc):
						if i == main_node :
							for im in range(len(varList)):
								tmpvol=fpol(varList[im], nx, nx,1)
								tmpvol.write_image(os.path.join(current_output_dir, options.var2D), km)
								km += 1
						else:
							nl = mpi_recv(1, MPI_INT, i, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
							nl = int(nl[0])
							for im in range(nl):
								ave = recv_EMData(i, im+i+70000)
								tmpvol=fpol(ave, nx, nx,1)
								tmpvol.write_image(os.path.join(current_output_dir, options.var2D), km)
								km += 1
				else:
					mpi_send(len(varList), 1, MPI_INT, main_node, SPARX_MPI_TAG_UNIVERSAL, MPI_COMM_WORLD)
					for im in range(len(varList)):
						send_EMData(varList[im], main_node, im+myid+70000)#  What with the attributes??
				mpi_barrier(MPI_COMM_WORLD)
				if myid == main_node:
					from applications import header
					header(os.path.join(current_output_dir, options.var2D), params = 'xform.projection',fimport = os.path.join(current_output_dir, "params.txt"))
				mpi_barrier(MPI_COMM_WORLD)
		if options.var3D:
			if myid == main_node: log_main.add("Reconstruct var3D ...")
			t6 = time()
			# radiusvar = options.radius
			# if( radiusvar < 0 ):  radiusvar = nx//2 -3
			res = recons3d_4nn_MPI(myid, varList, symmetry = options.sym, npad=options.npad)
			#res = recons3d_em_MPI(varList, vol_stack, options.iter, radiusvar, options.abs, True, options.sym, options.squ)
			if myid == main_node:
				from fundamentals import fpol
				if current_decimate != 1.0: res	= resample(res, 1./current_decimate)
				res = fpol(res, nnxo, nnxo, nnxo)
				set_pixel_size(res, 1.0)
				res.write_image(os.path.join(current_output_dir, options.var3D))
				log_main.add("%-70s:  %s\n"%("The reconstructed var3D is saved as ", options.var3D))
				log_main.add("Var3D reconstruction took %f12.1 [m]"%((time()-t6)/60.0))
				log_main.add("Total computation time %f12.1 [m]"%((time()-t0)/60.0))
				log_main.add("sx3dvariability finishes")
		from mpi import mpi_finalize
		mpi_finalize()
		
		if RUNNING_UNDER_MPI: global_def.MPI = False

		global_def.BATCH = False
Пример #28
0
	def __new__(cls,filename,application,force_plot=False,force_2d=False,old=None):
		
		file_type = Util.get_filename_ext(filename)
		em_file_type = EMUtil.get_image_ext_type(file_type)
		if not file_exists(filename): return None
		
		if force_plot and force_2d:
			# ok this sucks but it suffices for the time being
			print("Error, the force_plot and force_2d options are mutually exclusive")
			return None
		
		if force_plot:
			from .emplot2d import EMPlot2DWidget
			if isinstance(old,EMPlot2DWidget): widget = old
			else: widget = EMPlot2DWidget(application=application)
			widget.set_data_from_file(filename)
			return widget
		
		if em_file_type != IMAGE_UNKNOWN or filename[:4] == "bdb:":
			n = EMUtil.get_image_count(filename)
			nx,ny,nz = gimme_image_dimensions3D(filename)
			if n > 1 and nz == 1: 
				if force_2d:
					a = EMData()
					data=a.read_images(filename)
				else:
					data = None # This is like a flag - the ImageMXWidget only needs the file name
			elif nz == 1:
				data = [EMData(filename,0)]
			else:
				data = EMData()
				data.read_image(filename,0,not force_2d)		# This should be 3-D. We read the header-only here
				data = [data]
				
			if data != None and len(data) == 1: data = data[0]
			
			if force_2d or isinstance(data,EMData) and data.get_zsize()==1:
				if isinstance(data,list) or data.get_ysize() != 1:
					from .emimage2d import EMImage2DWidget
					if isinstance(old,EMImage2DWidget): widget = old
					else: widget= EMImage2DWidget(application=application)
				else:
					from .emplot2d import EMPlot2DWidget
					if isinstance(old,EMPlot2DWidget): widget = old
					else: widget = EMPlot2DWidget(application=application)
					widget.set_data_from_file(filename)
					return widget
			elif isinstance(data,EMData):
				if isinstance(old,EMScene3D): widget = old
				else: widget = EMScene3D()
#				print n,data
				for ii in range(n):
					data=EMData(filename,ii)
					datai = EMDataItem3D(data, transform=Transform())
					widget.insertNewNode(os.path.basename(filename), datai, parentnode=widget)
					isosurface = EMIsosurface(datai, transform=Transform())
					widget.insertNewNode("Iso", isosurface, parentnode=datai)
				return widget
				
			elif data == None or isinstance(data,list):
				from .emimagemx import EMImageMXWidget
				if isinstance(old,EMImageMXWidget): widget = old
				else: widget = EMImageMXWidget(application=application)
				data = filename
			else: 
				print(filename)
				raise # weirdness, this should never happen
			widget.set_data(data,filename)
			return widget
		else:
			from .emplot2d import EMPlot2DWidget
			if isinstance(old,EMPlot2DWidget): widget = old
			else: widget = EMPlot2DWidget(application=application)
			widget.set_data_from_file(filename)
			return widget
Пример #29
0
	def __new__(cls,data=None,old=None,app=None,force_2d=False,force_plot=False,filename="",replace=True):
		"""This will create a new EMImage* object depending on the type of 'data'. If
		old= is provided, and of the appropriate type, it will be used rather than creating
		a new instance.
		"""
		
		if isinstance(data,EMData) and data.get_size()==0: raise RuntimeError("Can not display an EMData object that has no pixels")
		
		from EMAN2 import remove_directories_from_name
		if force_plot and force_2d:
			# ok this sucks but it suffices for the time being
			print("Error, the force_plot and force_2d options are mutually exclusive")
			return None
		
		if force_plot or (isinstance(data,EMData) and data.get_zsize()==1 and data.get_ysize()==1):
			from .emplot2d import EMPlot2DWidget
			if old:
				if isinstance(old,EMPlot2DWidget) :
					old.set_data(data,remove_directories_from_name(filename),replace)
					return old
			widget = EMPlot2DWidget(application=app)
			widget.set_data(data,remove_directories_from_name(filename),replace)
			return widget	
		elif force_2d or (isinstance(data,EMData) and data.get_zsize()==1):
			from .emimage2d import EMImage2DWidget
			if old:
				if isinstance(old,EMImage2DWidget) :
					old.set_data(data,filename)
					return old
			widget = EMImage2DWidget(application=app)
			widget.set_data(data,filename)
			return widget
		elif isinstance(data,EMData):
			if isinstance(old,EMScene3D): widget = old
			else: widget = EMScene3D()
			data = EMDataItem3D(data, transform=Transform())
			#data.setSelectedItem(True)
			isosurface = EMIsosurface(data, transform=Transform())
			widget.insertNewNode(os.path.basename(filename), data, parentnode=widget)
			widget.insertNewNode("Iso", isosurface, parentnode=data)
			return widget

		elif isinstance(data,list) and isinstance(data[0],EMData):
			from .emimagemx import EMImageMXWidget
			if old:
				if isinstance(old,EMImageMXWidget) :
					old.set_data(data,filename)
					return old
			widget = EMImageMXWidget(application=app)
			widget.set_data(data,filename)
			return widget
		elif isinstance(data,list):
			from .emplot3d import EMPlot3DWidgetNew
			if (isinstance(data[0],list) or isinstance(data[0],tuple)) and len(data) > 2:
				if old:
					if isinstance(old,EMPlot3DWidgetNew) :
						old.set_data(data,remove_directories_from_name(filename),replace)
						return old
						
				widget = EMPlot3DWidgetNew()
				widget.set_data(data,remove_directories_from_name(filename),replace)
				return widget	
			else:
				from .emplot2d import EMPlot2DWidget
				if old:
					if isinstance(old,EMPlot2DWidget) :
						old.set_data(data,remove_directories_from_name(filename),replace)
						return old
				widget = EMPlot2DWidget(application=app)
				widget.set_data(data,remove_directories_from_name(filename),replace)
				return widget	
		else:
			raise Exception("data must be a single EMData object or a list of EMData objects")