Example #1
0
def getBestTiltTransform(imgdata):
    """
	For a given image get the best tilt transform 
	parameters in the database
	"""
    transdatas = []
    ## case 1: check if imgdata is image1
    transq = appiondata.ApImageTiltTransformData()
    transq['image1'] = imgdata
    transdatas1 = transq.query()
    if transdatas1:
        transdatas.extend(transdatas1)
    ## case 2: check if imgdata is image2
    transq = appiondata.ApImageTiltTransformData()
    transq['image2'] = imgdata
    transdatas2 = transq.query()
    if transdatas2:
        transdatas.extend(transdatas2)

    ### case 1: no transformation
    if len(transdatas) == 0:
        apDisplay.printWarning("no transformation found for image %s" %
                               (apDisplay.short(imgdata['filename'])))
        return None
    ### case 2: single transformation, no sorting required
    if len(transdatas) == 1:
        apDisplay.printMsg(
            "single transformation found with rmsd %.2f for image %s" %
            (transdatas[0]['rmsd'], apDisplay.short(imgdata['filename'])))
        return transdatas[0]
    ### case 3: more than one transformation, get one with lowest rmsd
    besttransdata = transdatas[0]
    bestrmsd = transdatas[0]['rmsd']
    for transdata in transdatas:
        if transdata['rmsd'] > 0 and transdata['rmsd'] < bestrmsd:
            besttransdata = transdata
            bestrmsd = transdata['rmsd']
    apDisplay.printMsg(
        "returning best transformation with rmsd %.2f for image %s" %
        (bestrmsd, apDisplay.short(imgdata['filename'])))
    return besttransdata
Example #2
0
def insertTiltTransform(imgdata1, imgdata2, tiltparams, params):
        #First we need to sort imgdata
        #'07aug30b_a_00013gr_00010sq_v01_00002sq_v01_00016en_00'
        #'07aug30b_a_00013gr_00010sq_v01_00002sq_01_00016en_01'
        #last two digits confer order, but then the transform changes...
        bin = params['bin']

        ### first find the runid
        runq = appiondata.ApSelectionRunData()
        runq['name'] = params['runname']
        runq['session'] = imgdata1['session']
        rundatas = runq.query(results=1, readimages=False)
        if not rundatas:
                apDisplay.printError("could not find runid in database")

        ### the order is specified by 1,2; so don't change it let makestack figure it out
        for imgdata in (imgdata1, imgdata2):
                for index in ("1","2"):
                        transq = appiondata.ApImageTiltTransformData()
                        transq["image"+index] = imgdata
                        transq['tiltrun'] = rundatas[0]
                        transdata = transq.query(readimages=False)
                        if transdata:
                                apDisplay.printWarning("Transform values already in database for "+imgdata['filename'])
                                return transdata[0]

        ### prepare the insertion
        transq = appiondata.ApImageTiltTransformData()
        transq['image1'] = imgdata1
        transq['image2'] = imgdata2
        transq['tiltrun'] = rundatas[0]
        dbdict = tiltPickerToDbNames(tiltparams)
        if dbdict is None:
                return None
        #Can I do for key in appiondata.ApImageTiltTransformData() ro transq???
        for key in ('image1_x','image1_y','image1_rotation','image2_x','image2_y','image2_rotation','scale_factor','tilt_angle', 'overlap'):
                if key not in dbdict:
                        apDisplay.printError("Key: "+key+" was not found in transformation data")

        for key,val in dbdict.items():
                #print key
                if re.match("image[12]_[xy]", key):
                        transq[key] = round(val*bin,2)
                else:
                        transq[key] = val
                #print i,v


        ### this overlap is wrong because the images are binned by 'bin' and now we give it the full image
        """
        imgShape1 = numpy.asarray(imgdata1['image'].shape, dtype=numpy.int8)/params['bin']
        image1 = numpy.ones(imgShape1)
        imgShape2 = numpy.asarray(imgdata2['image'].shape, dtype=numpy.int8)/params['bin']
        image2 = numpy.ones(imgShape2)
        bestOverlap, tiltOverlap = apTiltTransform.getOverlapPercent(image1, image2, tiltparams)
        print "image overlaps", bestOverlap, tiltOverlap
        transq['overlap'] = round(bestOverlap,5)
        """

        apDisplay.printMsg("Inserting transform between "+apDisplay.short(imgdata1['filename'])+\
                " and "+apDisplay.short(imgdata2['filename'])+" into database")
        transq.insert()
        apDisplay.printMsg("done")
        return transq
def insertParticlePeakPairs(peaktree1, peaktree2, peakerrors, imgdata1,
                            imgdata2, transdata, runname):
    """
	takes both image data (imgdata) and inserts particle pairs into DB from peaktrees
	"""
    #INFO
    sessiondata = imgdata1['session']
    legimgid1 = int(imgdata1.dbid)
    legimgid2 = int(imgdata2.dbid)
    imgname1 = imgdata1['filename']
    imgname2 = imgdata2['filename']

    #CHECK ARRAY LENGTHS
    len1 = len(peaktree1)
    len2 = len(peaktree2)
    len3 = len(peakerrors)
    if len1 != len2 or len2 != len3:
        apDisplay.printError("insertParticlePeakPairs particle arrays must have the same length "+\
         str(len1)+" "+str(len2)+" "+str(len3))

    #GET RUN DATA
    runq = appiondata.ApSelectionRunData()
    runq['name'] = runname
    runq['session'] = sessiondata
    selectionruns = runq.query(results=1)
    if not selectionruns:
        apDisplay.printError("could not find selection run in database")

    #GET TRANSFORM DATA
    transq = appiondata.ApImageTiltTransformData()
    transq['image1'] = imgdata1
    transq['image2'] = imgdata2
    transq['tiltrun'] = selectionruns[0]
    transids = transq.query(results=1)
    if not transids:
        apDisplay.printError("could not find transform id in database")

    ### WRITE PARTICLES TO DATABASE
    count = 0
    t0 = time.time()
    last50 = time.time()
    apDisplay.printMsg("looping over " + str(len(peaktree1)) + " particles")
    for i in range(len(peaktree1)):
        remaining_peaks = len(peaktree1) - count
        if count and remaining_peaks and remaining_peaks % 50 == 0:
            #sys.stderr.write("<"+str(len(peaktree1)-count))
            print(
                "%d particles remain, %s time remains, %s per particle, %s last 50 particles"
                % (
                    len(peaktree1) - count,
                    apDisplay.timeString(
                        (time.time() - t0) / count * (remaining_peaks)),
                    apDisplay.timeString((time.time() - t0) / count),
                    apDisplay.timeString(time.time() - last50),
                ))
            last50 = time.time()
        peakdict1 = peaktree1[i]
        peakdict2 = peaktree2[i]
        error = peakerrors[i]

        partq1 = appiondata.ApParticleData()
        partq1['selectionrun'] = selectionruns[0]
        partq1['image'] = imgdata1
        partq1['xcoord'] = peakdict1['xcoord']
        partq1['ycoord'] = peakdict1['ycoord']
        partq1['peakarea'] = 1

        partq2 = appiondata.ApParticleData()
        partq2['selectionrun'] = selectionruns[0]
        partq2['image'] = imgdata2
        partq2['xcoord'] = peakdict2['xcoord']
        partq2['ycoord'] = peakdict2['ycoord']
        partq2['peakarea'] = 1

        # I do NOT have to check if particles already exist, because this is a NEW selectionrun

        partpairq = appiondata.ApTiltParticlePairData()
        partpairq['particle1'] = partq1
        partpairq['particle2'] = partq2
        #NEED TO LOOK UP TRANSFORM DATA
        partpairq['transform'] = transdata
        #NEED TO CALCULATE ERROR, ALWAYS POSITIVE
        partpairq['error'] = error

        #presult = partpairq.query()
        #if not presult:
        count += 1
        partq1.insert(force=True)
        partq2.insert(force=True)
        partpairq.insert(force=True)

    apDisplay.printMsg("inserted " + str(count) + " of " +
                       str(len(peaktree1)) + " peaks into database" + " in " +
                       apDisplay.timeString(time.time() - t0))
    return