def getBestVolumes(log,WorkingDir,NRansac,NumVolumes,UseAll):
    volumes = []
    inliers = []
    
    for n in range(NRansac):
        fnAngles = os.path.join(WorkingDir,"tmp/angles_ransac%05d"%n+".xmd")
        md=MetaData("inliers@"+fnAngles)
        numInliers=md.getValue(MDL_WEIGHT,md.firstObject())
        volumes.append(fnAngles)
        inliers.append(numInliers)
    
    index = sorted(range(inliers.__len__()), key=lambda k: inliers[k])
    fnBestAngles = ''
    threshold=getCCThreshold(WorkingDir)
 
    i=NRansac-1
    indx = 0
    while i>=0 and indx<NumVolumes:
        fnBestAngles = volumes[index[i]]
        fnBestAnglesOut=os.path.join(WorkingDir,"volumeProposed%05d"%indx+".xmd")
        copyFile(log,fnBestAngles,fnBestAnglesOut)
        print("Best volume "+str(indx)+" = "+fnBestAngles)
        if not UseAll:
            runJob(log,"xmipp_metadata_utilities","-i %s -o %s --query select \"maxCC>%f \" --mode append" %(fnBestAnglesOut,fnBestAnglesOut,threshold))
            if getMdSize(fnBestAnglesOut) > 0:
                indx += 1
        else:
            indx += 1
        i -= 1
        
    # Remove unnecessary files
    for n in range(NRansac):
        fnAngles = os.path.join(WorkingDir,"tmp/angles_ransac%05d"%n+".xmd")
        deleteFile(log, fnAngles)
示例#2
0
def exportReliontoMetadataFile(inputRelion,outputXmipp):
    """ This function will receive a relion file and will
    convert to the one xmipp metadata file.    
    """
    if str2Label('rlnImageName')== -1:
       addRelionLabels()
    #add xmipp header
    line1="""# XMIPP_STAR_1 * 
# 
"""
    tmpFile = inputRelion + '.tmp'
    fOut = open(tmpFile,'w')
    fOut.write(line1)
    #copy and paste relion file
    fIn = open(inputRelion,'r')
    fOut.write(fIn.read())
    fOut.flush()
    fOut.close()
    #addRelionLabels MUST BE CALLED FROM CODE 
    blocklist = getBlocksInMetaDataFile(tmpFile)
    if exists (outputXmipp):
        os.remove(outputXmipp)
    for block in blocklist:
        md = MetaData(block + '@'+tmpFile)
        if len(md.getActiveLabels())!=0:
            md.write(block +'@'+ outputXmipp,MD_APPEND)
        
    from protlib_filesystem import deleteFile
    deleteFile(None, tmpFile,False)
示例#3
0
 def _visualizeDisplayReconstruction(self):
     """ Visualize selected volumes per iterations.
     If show in slices, create a temporal single metadata
     for avoid opening multiple windows. 
     """
     prefixes = self._getPrefixes()
     
     if self._visualizeVolumesMode == 'slices':
         fn = self.getFilename('selected_volumes')
         if xmippExists(fn):
             deleteFile(None, fn)
             
         for it in self._visualizeIterations:
             volMd = MetaData()
             for prefix in prefixes:
                 for ref3d in self._visualizeRef3Ds:
                     volFn = self.getFilename('%svolume' % prefix, iter=it, ref3d=ref3d)
                     volMd.setValue(MDL_IMAGE, volFn, volMd.addObject())
             block = 'volumes_iter%06d@' % it
             volMd.write(block + fn, MD_APPEND)
         self.display2D(fn)         
     else:
         for it in self._visualizeIterations:
           for prefix in prefixes:
               for ref3d in self._visualizeRef3Ds:
                 self.display3D(self.getFilename('%svolume' % prefix, iter=it, ref3d=ref3d))
示例#4
0
def reconstructClass(
    log,
    WorkingDir,
    ExtraDir,
    ClassNameIn,
    ClassNameOut,
    ClassImage,
    CenterMaxShift,
    ThinObject,
    SkipTiltedTranslations,
    ClassVolumeOut,
    ReconstructAdditionalParams,
    DoLowPassFilter,
    LowPassFilter,
):
    # If class image doesn't exists, generate it by averaging
    if len(ClassImage) == 0:
        classRootOut = ClassNameOut.replace(".xmd", "") + "_"
        params = "-i %(ClassNameIn)s --save_image_stats %(classRootOut)s -o %(ExtraDir)s/stats.xmd" % locals()
        runJob(log, "xmipp_image_statistics", params)
        ClassImage = classRootOut + "average.xmp"
        deleteFile(log, classRootOut + "stddev.xmp")
        deleteFile(log, "%(ExtraDir)s/stats.xmd" % locals())

    params = "-i %(ClassNameIn)s -o %(ClassNameOut)s --ref %(ClassImage)s --max_shift %(CenterMaxShift)d" % locals()

    if ThinObject:
        params += " --do_stretch"

    if SkipTiltedTranslations:
        params += " --do_not_align_tilted"

    runJob(log, "xmipp_image_align_tilt_pairs", params)

    params = "-i %(ClassNameOut)s -o %(ClassVolumeOut)s %(ReconstructAdditionalParams)s" % locals()
    runJob(log, "xmipp_reconstruct_art", params)

    if exists(ClassVolumeOut):
        mdFn = join(WorkingDir, "volumes.xmd")
        md = MetaData()

        if exists(mdFn):
            md.read(mdFn)
        objId = md.addObject()
        md.setValue(MDL_IMAGE, ClassVolumeOut, objId)

        if DoLowPassFilter:
            filteredVolume = ClassVolumeOut.replace(".vol", "_filtered.vol")
            params = "-i %(ClassVolumeOut)s -o %(filteredVolume)s --fourier low_pass %(LowPassFilter)f" % locals()
            runJob(log, "xmipp_transform_filter", params)
            objId = md.addObject()
            md.setValue(MDL_IMAGE, filteredVolume, objId)
        md.write(mdFn)
def automaticRejection(log,WorkingDir,condition,MDL_TYPE):
    fnMic=os.path.join(WorkingDir,"micrographs.xmd")
    fnRejected=os.path.join(WorkingDir,"tmp/rejectedMicrographs.xmd")
    runJob(log,"xmipp_metadata_utilities",'-i %s --query select "%s" -o %s'%(fnMic,condition,fnRejected))
    md = xmipp.MetaData(fnRejected)
    fnRejectedMicrographs=md.getColumnValues(MDL_TYPE)
    md.read(fnMic)
    for id in md:
        fnCurrentMicrograph=md.getValue(MDL_TYPE,id)
        if fnCurrentMicrograph in fnRejectedMicrographs:
            md.setValue(xmipp.MDL_ENABLED,-1,id)
    md.write(fnMic)
    deleteFile(log,fnRejected)
示例#6
0
def sortClasses(log,ExtraDir,Nproc,suffix):
    if Nproc==1:
        Nproc=2
    if Nproc>8:
        Nproc=8
    for filename in glob.glob(os.path.join(ExtraDir,"level_??/level_classes%s.xmd"%suffix)):
        level=int(re.search('level_(\d\d)',filename).group(1))
        fnRoot=os.path.join(ExtraDir,"level_%02d/level_classes%s_sorted"%(level,suffix))
        params= "-i classes@"+filename+" --oroot "+fnRoot
        runJob(log,"xmipp_image_sort",params,Nproc)
        mD=MetaData(fnRoot+".xmd")
        mD.write("classes_sorted@"+filename,MD_APPEND)
        deleteFile(log,fnRoot+".xmd")
def findDihedrical(log,WorkingDir,InputVolume,CylinderRadius):
    fnRotated=os.path.join(WorkingDir,'tmp','volume_rotated.vol')
    runJob(log,"xmipp_transform_geometry","-i %s -o %s --rotate_volume axis 180 1 0 0"%(InputVolume,fnRotated))
    if CylinderRadius>0:
        [xdim,ydim,zdim,ndim]=getImageSize(InputVolume)
        maskArgs=" --mask cylinder %d %d"%(int(-CylinderRadius),int(-xdim))
    else:
        maskArgs=""
    runJob(log,"xmipp_volume_align","--i1 %s --i2 %s --rot 0 360 3 -z -2 2 0.5 --apply"%(InputVolume,fnRotated)+maskArgs)
    runJob(log,"xmipp_volume_align","--i1 %s --i2 %s --local --apply"%(InputVolume,fnRotated)+maskArgs)
    runJob(log,"xmipp_image_operate","-i %s --plus %s -o %s"%(InputVolume,fnRotated,InputVolume))
    runJob(log,"xmipp_image_operate","-i %s --divide 2"%(InputVolume))
    runJob(log,"xmipp_transform_mask","-i %s "%(InputVolume)+maskArgs)
    deleteFile(log,fnRotated)
示例#8
0
def qualifyModes(log,WorkingDir,NumberOfModes,StructureType,CollectivityThreshold):
    currentDir=os.getcwd()
    changeDir(log,WorkingDir)
    
    fnVec=glob.glob("modes/vec.*")
    if len(fnVec)<NumberOfModes:
        fhWarning=open("warnings.xmd",'w')
        fhWarning.write(redStr("There are only "+str(len(fnVec))+" modes instead of "+str(NumberOfModes)+". Check the number of modes you asked to compute and/or consider increasing cut-off distance. The maximum number of modes allowed by the method for atomic normal mode analysis is 6 times the number of RTB blocks and for pseudoatomic normal mode analysis 3 times the number of pseudoatoms. However, the protocol allows only up to 200 modes as 20-100 modes are usually enough. If the number of modes is below the minimum between these two numbers, consider increasing cut-off distance.")+"\n")
        fhWarning.close()

    fnDiag="diagrtb.eigenfacs"
    if StructureType=="EM":
        runJob(log,"nma_reformatForElNemo.sh","%d"%NumberOfModes)
        fnDiag="diag_arpack.eigenfacs"
        
    runJob(log,"echo","%s | nma_check_modes"%fnDiag)
    deleteFile(log,fnDiag)
    
    fh=open("Chkmod.res")
    MDout=MetaData()
    collectivityList=[]
    for n in range(NumberOfModes):
        line=fh.readline()
        collectivity=float(line.split()[1])
        collectivityList.append(collectivity)

        id=MDout.addObject()
        MDout.setValue(MDL_NMA_MODEFILE,os.path.join(WorkingDir,"modes/vec.%d"%(n+1)),id)
        MDout.setValue(MDL_ORDER,long(n+1),id)
        if n>=6:
            MDout.setValue(MDL_ENABLED,1,id)
        else:
            MDout.setValue(MDL_ENABLED,-1,id)
        MDout.setValue(MDL_NMA_COLLECTIVITY,collectivity,id)
        if collectivity<CollectivityThreshold:
            MDout.setValue(MDL_ENABLED,-1,id)
    fh.close()
    idxSorted=[i[0] for i in sorted(enumerate(collectivityList), key=lambda x:x[1])]
    score=[0]*NumberOfModes
    for i in range(NumberOfModes):
       score[i]+=i+1
       score[idxSorted[i]]+=NumberOfModes-i
    i=0
    for id in MDout:
        score_i=float(score[i])/(2.0*NumberOfModes)
        MDout.setValue(MDL_NMA_SCORE,score_i,id)
        i+=1
    MDout.write("modes.xmd")
    deleteFile(log,"Chkmod.res")
    changeDir(log,currentDir)
示例#9
0
def ransacIteration(log,WorkingDir,n,fnClasses,SymmetryGroup,Xdim,Xdim2,NumSamples,InitialVolume,AngularSampling):
    fnBase="ransac%05d"%n
    TmpDir=os.path.join(WorkingDir,"tmp")
    fnRoot=os.path.join(TmpDir,fnBase)

    runJob(log,"xmipp_metadata_utilities","-i %s -o %s.xmd  --operate random_subset %d --mode overwrite "%(fnClasses,fnRoot,NumSamples))        
          
    
    runJob(log,"xmipp_metadata_utilities","-i %s.xmd --fill angleRot  rand_uniform -180 180 "%(fnRoot))
    runJob(log,"xmipp_metadata_utilities","-i %s.xmd --fill angleTilt rand_uniform 0 180 "%(fnRoot))
    runJob(log,"xmipp_metadata_utilities","-i %s.xmd --fill anglePsi  rand_uniform 0 360 "%(fnRoot)) 
 
    # If there is an initial volume, assign angles        
    if (InitialVolume != ''):
        fnGallery=os.path.join(TmpDir,'gallery_InitialVolume.stk')
        runJob(log,"xmipp_angular_projection_matching", "-i %s.xmd -o %s.xmd --ref %s --Ri 0 --Ro %s --max_shift %s --append -v 0"\
               %(fnRoot,fnRoot,fnGallery,str(Xdim/2),str(Xdim/20)))

    # Reconstruct with the small sample
    reconstruct(log,fnRoot,SymmetryGroup,Xdim2/2)
    fnVol = fnRoot+'.vol'
    
    # Generate projections from this reconstruction
    fnGallery=os.path.join(TmpDir,'gallery_'+fnBase+'.stk')
    runJob(log,"xmipp_angular_project_library", "-i %s -o %s --sampling_rate %f --sym %s --method fourier 1 0.25 bspline --compute_neighbors --angular_distance -1 --experimental_images %s -v 0"\
                %(fnVol,fnGallery,float(AngularSampling),SymmetryGroup,fnClasses))
        
    # Assign angles to the rest of images
    fnAngles=os.path.join(TmpDir,'angles_'+fnBase+'.xmd')
    runJob(log,"xmipp_angular_projection_matching", "-i %s -o %s --ref %s --Ri 0 --Ro %s --max_shift %s --append -v 0"\
                          %(fnClasses,fnAngles,fnGallery,str(Xdim/2),str(Xdim/20)))
   
    # Delete intermediate files 
    deleteFile(log,fnGallery)
    deleteFile(log,os.path.join(TmpDir,'gallery_'+fnBase+'_sampling.xmd'))
    deleteFile(log,os.path.join(TmpDir,'gallery_'+fnBase+'.doc'))
    deleteFile(log,fnVol)
    deleteFile(log,os.path.join(TmpDir,fnBase+'.xmd'))
示例#10
0
def exportMdToRelion(md, outputRelion):
    """ This function will receive a Xmipp metadata and will
    convert to the one expected by Relion.    
    All labels not recognized by Relion will be dropped.
    Params:
     md: input xmipp metadata.
     outputRelion: output filename to store the Relion star file.
    """
    for label in md.getActiveLabels():
        if not label in XMIPP_RELION_LABELS:
            md.removeLabel(label)
    tmpFile = outputRelion + '.tmp'
    md.write(tmpFile)
    # Create a dict with the names
    d = {}
    for k, v in XMIPP_RELION_LABELS.iteritems():
        d[label2Str(k)] = v
        
    #print "dict: ", d
        
    renameMdLabels(tmpFile, outputRelion, d)
    from protlib_filesystem import deleteFile
    deleteFile(None, tmpFile)
示例#11
0
def extendCore(log,WorkingDirStructureCore,WorkingDirStructureExtended,NumVolumes,RemainingClasses,ComplementaryClasses,AngularSampling,\
               SymmetryGroup,CorrThresh,NumberOfMpi):
    from protlib_projmatch import projMatch
    
    fnCore=os.path.join(WorkingDirStructureCore,"imagesCore.xmd")
    fnComplementary=os.path.join(WorkingDirStructureExtended,"imagesComplementary.xmd")
    runJob(log,"xmipp_metadata_utilities","-i %s --set subtraction %s image image -o %s"%(RemainingClasses,fnCore,fnComplementary))
    runJob(log,"xmipp_metadata_utilities","-i %s --operate keep_column image"%fnComplementary)
    if ComplementaryClasses!="":
        fnAux=os.path.join(WorkingDirStructureExtended,"aux.xmd")
        runJob(log,"xmipp_metadata_utilities","-i %s -o %s --operate keep_column image"%(ComplementaryClasses,fnAux))
        runJob(log,"xmipp_metadata_utilities", "-i %s  --set union %s image image"%(fnComplementary,fnAux))
        deleteFile(log,fnAux)
        runJob(log,"xmipp_metadata_utilities", "-i %s  --set subtraction %s image image"%(fnComplementary,fnCore))
        
    for i in range(NumVolumes):
        # Projection matching with the complementary images
        fnVolume=os.path.join(WorkingDirStructureCore,"proposedVolume%05d.vol"%i)
        fnAngles=os.path.join(WorkingDirStructureExtended,"anglesComplementary%05d.xmd"%i)
        projMatch(log,fnVolume,AngularSampling,SymmetryGroup,fnComplementary,WorkingDirStructureExtended,fnAngles,NumberOfMpi)
        
        # Calculate minimum correlation
        fnInliers=fnVolume=os.path.join(WorkingDirStructureCore,"proposedVolume%05d.xmd"%i)
        md=MetaData(fnInliers)
        cc=md.getColumnValues(MDL_MAXCC)
        cc.sort()
        minCC=min(cc[0],CorrThresh)
        
        # Choose those complementary images whose correlation is larger than the minimum
        fnAnglesChosen=os.path.join(WorkingDirStructureExtended,"anglesComplementaryChosen%05d.xmd"%i)
        runJob(log,"xmipp_metadata_utilities",'-i %s --query select "maxCC>%f" -o %s'%(fnAngles,minCC,fnAnglesChosen))
        fnExtended=os.path.join(WorkingDirStructureExtended,"proposedVolume%05d.xmd"%i)
        runJob(log,"xmipp_metadata_utilities",'-i %s --set union %s -o %s'%(fnInliers,fnAnglesChosen,fnExtended))
        deleteFile(log,fnAngles)
        deleteFile(log,fnAnglesChosen)
        fnOutOfCore=os.path.join(WorkingDirStructureExtended,"imagesOutOfCore%05d.xmd"%i)
        runJob(log,"xmipp_metadata_utilities",'-i %s --set subtraction %s -o %s'%(RemainingClasses,fnExtended,fnOutOfCore))
        runJob(log,"xmipp_metadata_utilities",'-i %s --operate sort'%fnOutOfCore)
        runJob(log,"xmipp_metadata_utilities",'-i %s --operate drop_column scale'%fnOutOfCore)
        runJob(log,"xmipp_metadata_utilities",'-i %s --operate sort'%fnExtended)
    
    deleteFile(log,os.path.join(WorkingDirStructureExtended,"gallery.stk"))
示例#12
0
def projMatch(log, WorkingDir,WorkingDirStructure, fnClasses, fnBase, AngularSampling, SymmetryGroup, Xdim):
    fnRoot=os.path.join(WorkingDirStructure,fnBase)
    fnGallery=os.path.join(WorkingDir,'tmp/gallery_'+fnBase+'.stk')
    
    AngularSampling=int(max(floor(AngularSampling/2.0),2));
    runJob(log,"xmipp_angular_project_library", "-i %s.vol -o %s --sampling_rate %f --sym %s --method fourier 1 0.25 bspline --compute_neighbors --angular_distance -1 --experimental_images %s -v 0"\
                          %(fnRoot,fnGallery,float(AngularSampling),SymmetryGroup,fnClasses))

    runJob(log,"xmipp_angular_projection_matching", "-i %s.xmd -o %s.xmd --ref %s --Ri 0 --Ro %s --max_shift %s --append -v 0"\
           %(fnRoot,fnRoot,fnGallery,str(Xdim/2),str(Xdim/20)))
            
    deleteFile(log,os.path.join(WorkingDir,'tmp/gallery_'+fnBase+'_sampling.xmd'))
    deleteFile(log,os.path.join(WorkingDir,'tmp/gallery_'+fnBase+'.doc'))
    deleteFile(log,os.path.join(WorkingDir,'tmp/gallery_'+fnBase+'.stk'))
def estimateSingleCTF(log, WorkingDir, inputFile, DownsampleFactor, AutomaticDownsampling,
                      Voltage, SphericalAberration, AngPix, AmplitudeContrast, LowResolCutoff, 
                      HighResolCutoff,WinSize,MaxFocus,MinFocus,FastDefocus,MDL_TYPE):
    extraDir=os.path.join(WorkingDir,'extra')
    tmpDir=os.path.join(WorkingDir,'tmp')
    micrographName = os.path.basename(inputFile)
    shortname = os.path.splitext(micrographName)[0]
    micrographDir = os.path.join(extraDir,shortname)
    oroot="%s/xmipp_ctf"%micrographDir           

    if not os.path.exists(micrographDir):
        createDir(log,micrographDir)

    downsampleList=[DownsampleFactor]
    if AutomaticDownsampling:
        downsampleList.append(DownsampleFactor+1)
        if DownsampleFactor>=2:
            downsampleList.append(DownsampleFactor-1)
        else:
            downsampleList.append(max(DownsampleFactor/2.,1.))
    
    for DownsampleFactor in downsampleList:
        # Downsample if necessary
        deleteTmp=False
        if DownsampleFactor != 1:
            finalname = os.path.join(tmpDir,shortname + "_tmp.mrc")
            runJob(log,"xmipp_transform_downsample","-i %s -o %s --step %f --method fourier" % (inputFile,finalname,DownsampleFactor))
            deleteTmp=True
        else:
            finalname = inputFile
            
        # CTF estimation with Xmipp
        args="--micrograph "+finalname+\
             " --oroot "+oroot+\
             " --kV "+str(Voltage)+\
             " --Cs "+str(SphericalAberration)+\
             " --sampling_rate "+str(AngPix*DownsampleFactor)+\
             " --downSamplingPerformed "+str(DownsampleFactor)+\
             " --ctfmodelSize 256"+\
             " --Q0 "+str(AmplitudeContrast)+\
             " --min_freq "+str(LowResolCutoff)+\
             " --max_freq "+str(HighResolCutoff)+\
             " --pieceDim "+str(WinSize)+\
             " --defocus_range "+str((MaxFocus-MinFocus)*10000/2)+\
             " --defocusU "+str((MaxFocus+MinFocus)*10000/2)
        if (FastDefocus):
            args+=" --fastDefocus"
        


        runJob(log,'xmipp_ctf_estimate_from_micrograph', args)
        
        if deleteTmp:
            deleteFile(log, finalname)
        
        md = xmipp.MetaData()
        id = md.addObject()
        
        if MDL_TYPE == xmipp.MDL_MICROGRAPH_MOVIE:
            md.setValue(xmipp.MDL_MICROGRAPH_MOVIE,inputFile,id)
            md.setValue(xmipp.MDL_MICROGRAPH,('%05d@%s'%(1,inputFile)),id)
        else:
            md.setValue(xmipp.MDL_MICROGRAPH,inputFile,id)
            
        md.setValue(xmipp.MDL_PSD,oroot+".psd",id)
        md.setValue(xmipp.MDL_PSD_ENHANCED,oroot+"_enhanced_psd.xmp",id)
        md.setValue(xmipp.MDL_CTF_MODEL,oroot+".ctfparam",id)
        md.setValue(xmipp.MDL_IMAGE1,oroot+"_ctfmodel_quadrant.xmp",id)
        md.setValue(xmipp.MDL_IMAGE2,oroot+"_ctfmodel_halfplane.xmp",id)
        md.setValue(xmipp.MDL_CTF_DOWNSAMPLE_PERFORMED,float(DownsampleFactor),id)
        fnEval=os.path.join(micrographDir,"xmipp_ctf.xmd")
        md.write(fnEval)
        criterion="ctfCritFirstZero<5 OR ctfCritMaxFreq>20 OR ctfCritfirstZeroRatio<0.9 OR ctfCritfirstZeroRatio>1.1 OR "\
                  "ctfCritFirstMinFirstZeroRatio>10 OR ctfCritCorr13<0 OR ctfCritCtfMargin<0 OR ctfCritNonAstigmaticValidty<0.3 OR " \
                  "ctfCritNonAstigmaticValidty>25"
        runJob(log,"xmipp_ctf_sort_psds","-i %s"%(fnEval))
        fnRejected=os.path.join(tmpDir,shortname+"_rejected.xmd")
        runJob(log,"xmipp_metadata_utilities",'-i %s --query select "%s" -o %s'%(fnEval,criterion,fnRejected))
        md.read(fnRejected)
        if md.size()==0:
            break
def ransacIteration(log,WorkingDir,n,SymmetryGroup,Xdim,Xdim2,NumGrids,NumSamples,DimRed,InitialVolume,AngularSampling,UseSA,
                    NIterRandom,Rejection):
    fnBase="ransac%05d"%n
    TmpDir=os.path.join(WorkingDir,"tmp")
    fnRoot=os.path.join(TmpDir,fnBase)
    fnOutputReducedClass = os.path.join(WorkingDir,"extra/reducedClasses.xmd")

    if (DimRed=='Yes'):
        # Get a random sample of images
        runJob(log,"xmipp_transform_dimred","-i %s --randomSample %s.xmd  %d -m LTSA "%(fnOutputReducedClass,fnRoot,NumGrids))
    else:        
        runJob(log,"xmipp_metadata_utilities","-i %s -o %s.xmd  --operate random_subset %d --mode overwrite "%(fnOutputReducedClass,fnRoot,NumSamples))
        runJob(log,"xmipp_metadata_utilities","-i %s.xmd --fill angleRot rand_uniform -180 180 "%(fnRoot))
        runJob(log,"xmipp_metadata_utilities","-i %s.xmd --fill angleTilt rand_uniform 0 180 "%(fnRoot))
        runJob(log,"xmipp_metadata_utilities","-i %s.xmd --fill anglePsi  rand_uniform 0 360 "%(fnRoot)) 

    # If there is an initial volume, assign angles        
    if (InitialVolume != ''):
        fnGallery=os.path.join(TmpDir,'gallery_InitialVolume.stk')
        runJob(log,"xmipp_angular_projection_matching", "-i %s.xmd -o %s.xmd --ref %s --Ri 0 --Ro %s --max_shift %s --append"\
               %(fnRoot,fnRoot,fnGallery,str(Xdim/2),str(Xdim/20)))

    # Reconstruct with the small sample
    reconstruct(log,fnRoot,SymmetryGroup,Xdim2/2)
    fnVol = fnRoot+'.vol'
    
    # Simulated annealing
    if UseSA:
        smallIter=int(min(floor(NIterRandom/5.0),0));
        runJob(log,"xmipp_volume_initial_simulated_annealing","-i %s --initial %s --oroot %s_sa --sym %s --randomIter %d --rejection %f --dontApplyPositive"
                  %(fnRoot+".xmd",fnVol,fnRoot,SymmetryGroup,smallIter,Rejection))
        moveFile(log, fnRoot+"_sa.vol", fnVol)
        deleteFile(log, fnRoot+"_sa.xmd")

    # Generate projections from this reconstruction
    fnGallery=os.path.join(TmpDir,'gallery_'+fnBase+'.stk')
    runJob(log,"xmipp_angular_project_library", "-i %s -o %s --sampling_rate %f --sym %s --method fourier 1 0.25 bspline --compute_neighbors --angular_distance -1 --experimental_images %s"\
                %(fnVol,fnGallery,float(AngularSampling),SymmetryGroup,fnOutputReducedClass))
        
    # Assign angles to the rest of images
    fnAngles=os.path.join(TmpDir,'angles_'+fnBase+'.xmd')
    runJob(log,"xmipp_angular_projection_matching", "-i %s -o %s --ref %s --Ri 0 --Ro %s --max_shift %s --append"\
                          %(fnOutputReducedClass,fnAngles,fnGallery,str(Xdim/2),str(Xdim/20)))
   
    # Delete intermediate files 
    deleteFile(log,fnGallery)
    deleteFile(log,os.path.join(TmpDir,'gallery_'+fnBase+'_sampling.xmd'))
    deleteFile(log,os.path.join(TmpDir,'gallery_'+fnBase+'.doc'))
    deleteFile(log,fnVol)
    deleteFile(log,os.path.join(TmpDir,fnBase+'.xmd'))