def getACE2Path(self):
		exename = 'ace2correct.exe'
		ace2exe = subprocess.Popen("which "+exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
		if not os.path.isfile(ace2exe):
			ace2exe = os.path.join(apParam.getAppionDirectory(), 'bin', exename)
		if not os.path.isfile(ace2exe):
			apDisplay.printError(exename+" was not found at: "+apParam.getAppionDirectory())
		return ace2exe
	def getCtfProgPath(self):
		exename = "ctffind4"
		ctfprgmexe = subprocess.Popen("which "+exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
		if not os.path.isfile(ctfprgmexe):
			ctfprgmexe = os.path.join(apParam.getAppionDirectory(), 'bin', exename)
		if not os.path.isfile(ctfprgmexe):
			apDisplay.printError(exename+" was not found at: "+apParam.getAppionDirectory())
		apDisplay.printMsg("Running program %s"%(exename))
		return ctfprgmexe
def getSignaturePath():
	unames = os.uname()
	if unames[-1].find('64') >= 0:
		exename = 'signature64.exe'
	else:
		exename = 'signature32.exe'
	signaturepath = os.path.join(apParam.getAppionDirectory(), 'bin', exename)
	if not os.path.isfile(signaturepath):
		signaturepath = subprocess.Popen("which "+exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
	if not os.path.isfile(signaturepath):
		apDisplay.printError(exename+" was not found at: "+apParam.getAppionDirectory())
	return signaturepath
def getFindEMPath():
	unames = os.uname()
	if True:
	#if unames[-1].find('64') >= 0:
		exename = 'automatch'
	else:
		apDisplay.printError(exename+" not implemented for 32 bit computer")
	findempath = os.path.join(apParam.getAppionDirectory(), 'bin', exename)
	if not os.path.isfile(findempath):
		findempath = subprocess.Popen("which "+exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
	if not os.path.isfile(findempath):
		apDisplay.printError(exename+" was not found at: "+apParam.getAppionDirectory())
	return findempath
def getFindEMPath():
	unames = os.uname()
	if unames[-1].find('64') >= 0:
#		For FindEM2
#		exename = '/ami/sw/packages/FindEM2/FindEM2_V1.00.exe'
		exename = 'findem64.exe'
	else:
		exename = 'findem32.exe'
	findempath = os.path.join(apParam.getAppionDirectory(), 'bin', exename)
	if not os.path.isfile(findempath):
		findempath = subprocess.Popen("which "+exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
	if not os.path.isfile(findempath):
		apDisplay.printError(exename+" was not found at: "+apParam.getAppionDirectory())
	return findempath
 def _addDefaultParams(self):
         ### new system, global params
         self.params['functionname'] = self.functionname
         self.params['appiondir'] = apParam.getAppionDirectory()
         ### classic methods
         self.params['functionLog']=None
         self.defaultparams = {}
def getPrototypeParamFile(outparamfile):
        
        #TODO: expand on this later
        appiondir=apParam.getAppionDirectory()
        origparamfile=os.path.join(appiondir,'appionlib','data','protomo.param')
        newparamfile=os.path.join(os.getcwd(),outparamfile)
        shutil.copyfile(origparamfile,newparamfile)
	def getCtfProgPath(self):
		unames = os.uname()
		exename = "ctffind"
		if self.params['ctftilt'] is True:
			exename = "ctftilt"
		if unames[-1].find('64') >= 0:
			exename += '64.exe'
		else:
			exename += "3.exe"
		ctfprgmexe = subprocess.Popen("which "+exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
		if not os.path.isfile(ctfprgmexe):
			ctfprgmexe = os.path.join(apParam.getAppionDirectory(), 'bin', exename)
		if not os.path.isfile(ctfprgmexe):
			apDisplay.printError(exename+" was not found at: "+apParam.getAppionDirectory())
		apDisplay.printMsg("Running program %s"%(exename))
		return ctfprgmexe
        def runAffinityPropagation(self, alignedstack):
                ### Get initial correlation values
                ### this is really, really slow
                similarfile, simlist = self.fillSimilarityMatrix(alignedstack)

                ### Preference value stats
                preffile = self.setPreferences(simlist)

                ### run apcluster.exe program
                outfile = "clusters.out"
                apDisplay.printMsg("Run apcluster.exe program")
                apclusterexe = os.path.join(apParam.getAppionDirectory(), "bin/apcluster.exe")
                apFile.removeFile(outfile)
                clustercmd = apclusterexe+" "+similarfile+" "+preffile+" "+outfile
                clusttime = time.time()
                proc = subprocess.Popen(clustercmd, shell=True)
                proc.wait()
                apDisplay.printMsg("apCluster time: "+apDisplay.timeString(time.time()-clusttime))

                if not os.path.isfile(outfile):
                        apDisplay.printError("apCluster did not run")

                ### Parse apcluster output file: clusters.out
                apDisplay.printMsg("Parse apcluster output file: "+outfile)
                clustf = open(outfile, "r")
                ### each line is the particle and the number is the class
                partnum = 0
                classes = {}
                for line in clustf:
                        sline = line.strip()
                        if sline:
                                partnum += 1
                                classnum = int(sline)
                                if not classnum in classes:
                                        classes[classnum] = [partnum,]
                                else:
                                        classes[classnum].append(partnum)
                clustf.close()
                apDisplay.printMsg("Found %d classes"%(len(classes.keys())))

                ### Create class averages
                classavgdata = []
                classnames = classes.keys()
                classnames.sort()
                for classnum in classnames:
                        apDisplay.printMsg("Class %d, %d members"%(classnum, len(classes[classnum])))
                        #clsf = open('subcls%04d.lst'%(classnum), 'w')
                        #for partnum in classes[classnum]:
                        #       clsf.write("%d\n"%(partnum))
                        #clsf.close()
                        classdatalist = apImagicFile.readParticleListFromStack(alignedstack, classes[classnum], msg=False)
                        classdatarray = numpy.asarray(classdatalist)
                        classavgarray = classdatarray.mean(0)
                        #mrc.write(classavgarray, 'subcls%04d.mrc'%(classnum))
                        classavgdata.append(classavgarray)
                apFile.removeStack("classaverage-"+self.timestamp+".hed")
                apImagicFile.writeImagic(classavgdata, "classaverage-"+self.timestamp+".hed")

                return classes
def getSnapPath():
        chimsnappath = os.path.join(apParam.getAppionDirectory(), "appionlib", "apChimSnapshot.py")
        if not os.path.isfile(chimsnappath):
                libdir = os.path.dirname(__file__)
                chimsnappath = os.path.join(libdir, "apChimSnapshot.py")
        if not os.path.isfile(chimsnappath):
                apDisplay.printError("Could not find file: apChimSnapshot.py")
        return chimsnappath
	def __init__(self,optargs=sys.argv[1:],quiet=False,useglobalparams=True,maxnproc=None):
		"""
		Starts a new function and gets all the parameters
		"""
		### setup some expected values
		self.successful_run = False
		self.params = {}
		sys.stdout.write("\n\n")
		self.quiet = quiet
		self.maxnproc = maxnproc
		self.startmem = mem.active()
		self.t0 = time.time()
		self.createDefaultStats()
		self.timestamp = apParam.makeTimestamp()
		self.argdict = {}
		self.optdict = {}
		apDisplay.printMsg("Time stamp: "+self.timestamp)
		self.functionname = apParam.getFunctionName(sys.argv[0])
		apDisplay.printMsg("Function name: "+self.functionname)
		self.appiondir = apParam.getAppionDirectory()
		apDisplay.printMsg("Appion directory: "+self.appiondir)
		self.parsePythonPath()
# 		loadavg = os.getloadavg()[0]
# 		if loadavg > 2.0:
# 			apDisplay.printMsg("Load average is high "+str(round(loadavg,2)))
# 			loadsquared = loadavg*loadavg
# 			time.sleep(loadavg)
# 			apDisplay.printMsg("New load average "+str(round(os.getloadavg()[0],2)))
		self.setLockname('lock')

		### setup default parser: run directory, etc.
		self.setParams(optargs,useglobalparams)
		#if 'outdir' in self.params and self.params['outdir'] is not None:
		#	self.params['rundir'] = self.params['outdir']

		self.checkConflicts()
		if useglobalparams is True:
			self.checkGlobalConflicts()

		### setup run directory
		self.setProcessingDirName()
		self.setupRunDirectory()

		### Start pool of threads to run subprocesses.
		### Later you will use self.process_launcher.launch(...) to
		### put commands into the queue.
		### There is currently a timeout built into it that will cause
		### the threads to die if they have no tasks after 10 seconds.
		self.process_launcher = apThread.ProcessLauncher(2, self.params['rundir'])

		### write function log
		self.logfile = apParam.writeFunctionLog(sys.argv, msg=(not self.quiet))


		### any custom init functions go here
		self.onInit()
def getRMeasurePath():
    unames = os.uname()
    if unames[-1].find("64") >= 0:
        exename = "rmeasure64.exe"
    else:
        exename = "rmeasure32.exe"
    rmeasexe = subprocess.Popen("which " + exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
    if not os.path.isfile(rmeasexe):
        rmeasexe = os.path.join(apParam.getAppionDirectory(), "bin", exename)
    if not os.path.isfile(rmeasexe):
        exename = "rmeasure.exe"
        rmeasexe = subprocess.Popen("which " + exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
    if not os.path.isfile(rmeasexe):
        exename = "rmeasure"
        rmeasexe = subprocess.Popen("which " + exename, shell=True, stdout=subprocess.PIPE).stdout.read().strip()
    if not os.path.isfile(rmeasexe):
        apDisplay.printWarning(exename + " was not found at: " + apParam.getAppionDirectory())
        return None
    return rmeasexe
	def locateAmpFile(self):
		### may be ready to use as is
		ampabspath = os.path.abspath(self.params['ampfile'])
		if os.path.isfile(ampabspath):
			return ampabspath
		### try to find it in the appion directory
		appiondir = apParam.getAppionDirectory()
		ampabspath = os.path.join(appiondir, "appionlib/data", os.path.basename(self.params['ampfile']))
		if os.path.isfile(ampabspath):
			return ampabspath
		### can't find it
		apDisplay.printError("Could not locate amplitude file: %s" % (self.params['ampfile'],))
def createAmpcorBatchFile(infile,params):
        localinfile = spyder.fileFilter(infile)

        appiondir = apParam.getAppionDirectory()
        scriptfile = os.path.join(appiondir, "appionlib/data/enhance.bat")
        pwscfile = os.path.join(appiondir, "appionlib/data/pwsc.bat")
        if not os.path.isfile(scriptfile):
                apDisplay.printError("could not find spider script: "+scriptfile)
        if not os.path.isfile(pwscfile):
                apDisplay.printError("could not find spider script: "+pwscfile)
        inf = open(scriptfile, "r")

        tmpfile = "out_"+os.path.basename(infile)
        tmpfile = os.path.join(params['rundir'], tmpfile)
        localtmpfile = spyder.fileFilter(tmpfile)

        outfile = "enhance_edit.bat"
        if os.path.isfile(outfile):
                apDisplay.printWarning(outfile+" already exists; removing it")
                time.sleep(2)
                os.remove(outfile)
        if os.path.isfile('pwsc.bat'):
                apDisplay.printWarning(pwscfile+" already exists; replacing it")
                time.sleep(2)
        shutil.copyfile(pwscfile, 'pwsc.bat')
        outf = open(outfile, "w")

        notdone = True
        for line in inf:
                if notdone is False:
                        outf.write(line)
                else:
                        thr = line[:3]
                        if thr == "x99":
                                outf.write(spiderline(99,params['box'],"box size in pixels"))
                        elif thr == "x98":
                                outf.write(spiderline(98,params['maxfilt'],"filter limit in angstroms"))
                        elif thr == "x80":
                                outf.write(spiderline(80,params['apix'],"pixel size"))
                        elif re.search("^\[vol\]",line):
                                outf.write(spiderline("vol",localinfile,"input density file"))
                        elif re.search("^\[outvol\]",line):
                                outf.write(spiderline("outvol",localtmpfile,"enhanced output file"))
                        elif re.search("^\[scatter\]",line):
                                outf.write(spiderline("scatter",params['ampfile'],"amplitude curve file"))
                        elif re.search("^\[pwsc\]",line):
                                outf.write(spiderline("pwsc","pwsc","scaling script"))
                        elif re.search("^\[applyfen\]",line):
                                outf.write(spiderline("applyfen",os.path.join(appiondir,"appionlib/data/applyfen"),"apply curve to data script"))
                        else:
                                outf.write(line)
        return tmpfile
        def runSpiderBatch(self, localbatch, spiderstack):
                ### set SPPROC_DIR environment variable
                spiprocdir = os.path.join(apParam.getAppionDirectory(), "spiderbatch/")
                
                ### strip localbatch extension
                batchheadname = os.path.splitext(localbatch)[0] ###batchheadname = localbatch.split('.')[0]

                ### run Iterative Classification and Alignment
                mySpider = spyder.SpiderSession(logo=True, spiderprocdir=spiprocdir, projext=".spi", term=True, verbose=True)
                mySpider.toSpider("@%s" % batchheadname)
                mySpider.close()

                ###output is class averages, variances, particle lists, and alignment parameters
                ### write aligned stack
                if not os.path.isfile("apshdoc.spi"):
                        apDisplay.printError("Output alignment parameters file apshdoc.spi does not exist.")
                else:
                        mySpider = spyder.SpiderSession(logo=True, spiderprocdir=spiprocdir, projext=".spi", term=True, verbose=True)
                        mySpider.toSpider("@rtmr",                              #spider script for rotate,shift,mirror
                                "apshdoc",                                      #input transformation doc
                                "%s@******" % spyder.fileFilter(spiderstack),   #input particles
                                "alignstack@******")                            #output aligned particles
                        mySpider.close()
def getPrototypeParamPath():
        appiondir=apParam.getAppionDirectory()
        origparamfile=os.path.join(appiondir,'appionlib','data','protomo.param')
        return origparamfile
        def setupBatchFile(self, spiderstack, templatestack, orientref):
                """
                sets up Ed's batch script to run
                """

                ### write particle selection file
                partsel = os.path.join(self.params['rundir'], "partlist.spi")
                f = open(partsel, "w")
                for i in range(self.params['numpart']):
                        f.write("%06d 1 %06d \n"%(i+1, i+1))
                f.close()

                refsel = os.path.join(self.params['rundir'], "reflist.spi")
                f = open(refsel, "w")
                for i in range(self.params['numtemplate']):
                        f.write("%03d 1 %03d \n"%(i+1, i+1))
                f.close()

                ### read / write batch file
                globalbatch = os.path.join(apParam.getAppionDirectory(), "spiderbatch/IterativeClassifyAlign.spi")
                localbatch =  os.path.join(self.params['rundir'], "IterativeClassifyAlign.spi")
                gf = open(globalbatch, "r")
                lf = open(localbatch, "w")
                modify = True
                for line in gf:
                        if modify is True: #flag for line is in header
                                ### Input files ###
                                if re.match("\<pcltmpl\>", line):
                                        ### template for spider particle names
                                        lf.write("<pcltmpl>"+spyder.fileFilter(spiderstack)+"@****** \n")
                                elif re.match("\<pcllist\>", line):
                                        ### list of particle numbers
                                        lf.write("<pcllist>"+spyder.fileFilter(partsel)+"\n")
                                elif re.match("\<reftmpl\>", line):
                                        ### template for reference image names
                                        lf.write("<reftmpl>"+spyder.fileFilter(templatestack)+"@*** \n")
                                elif re.match("\<reflist\>", line):
                                        ### list of reference numbers
                                        lf.write("<reflist>"+spyder.fileFilter(refsel)+"\n")
                                elif re.match("\<ref\>", line):
                                        ### orientation reference
                                        lf.write("<ref>"+spyder.fileFilter(orientref)+"\n")
                                ### Parameters ###
                                elif re.match("23  ;pixels", line):
                                        ### particle radius in pixels
                                        pixrad = int(self.params['partrad']/self.stack['apix']/self.params['bin'])
                                        lf.write("%d  ;pixels\n"%(pixrad))
                                elif re.match("10  ;iterations", line):
                                        ### number of ref-based iterations
                                        lf.write("%d  ;iterations\n"%(self.params['numiter']))
                                #elif re.match("1   ;free-align rounds", line):
                                        ### number of ref-free alignments per class
                                        #lf.write("%d   ;free-align rounds\n"%(self.params['freealigns']))
                                elif re.match("0   ;processors", line):
                                        ### number of processors
                                        lf.write("%d   ;processors\n"%(self.params['nproc']))
                                elif re.match("\<dir\>", line):
                                        ### sub-directory, we use "."
                                        lf.write("<dir>.\n")
                                elif re.search("- END BATCH HEADER -", line):
                                        ### reached last line of batch header ###
                                        modify = False
                                else:
                                        lf.write(line)
                        else:
                                lf.write(line)

                return localbatch
from appionlib import apDog
from appionlib import apFile
from appionlib import apPeaks
from appionlib import apImage
from appionlib import apParam
from appionlib import apDisplay
from appionlib.apTilt import apTiltTransform

version = "2.0b13"
releasedate = "July 21, 2010"
this_file = inspect.currentframe().f_code.co_filename
logoimage = os.path.abspath(os.path.join(os.path.dirname(this_file), "../../data/tplogo.png"))
if not os.path.isfile(logoimage):
        logoimage = os.path.abspath(os.path.join(os.path.dirname(this_file), "../data/tplogo.png"))
if not os.path.isfile(logoimage):
        logoimage = os.path.join(apParam.getAppionDirectory(), "appionlib/data/tplogo.png")
citation = """
Voss NR, Yoshioka CK, Radermacher M, Potter CS, and Carragher B.
"DoG Picker and TiltPicker: software tools to facilitate particle selection 
    in single particle electron microscopy."
J Struct Biol. 2009 v166(2): pp. 205-13.
http://dx.doi.org/10.1016/j.jsb.2009.01.004
"""
citationlogo = """
####
  # ###    Voss NR, Yoshioka CK, Radermacher M, Potter CS, and Carragher B.
  # #  #   "DoG Picker and TiltPicker: software tools to facilitate particle selection 
  #####        in single particle electron microscopy."
    #      J Struct Biol. 2009 v166(2): pp. 205-13.
    #      http://dx.doi.org/10.1016/j.jsb.2009.01.004
"""
	def __init__(self,optargs=sys.argv[1:],quiet=False,useglobalparams=True,maxnproc=None):
		"""
		Starts a new function and gets all the parameters
		"""
		### setup some expected values
		self.successful_run = False
		self.clusterjobdata = None
		self.params = {}
		sys.stdout.write("\n\n")
		self.quiet = quiet
		self.maxnproc = maxnproc
		self.startmem = mem.active()
		self.t0 = time.time()
		self.createDefaultStats()
		self.timestamp = apParam.makeTimestamp()
		self.argdict = {}
		self.optdict = {}
		apDisplay.printMsg("Time stamp: "+self.timestamp)
		self.functionname = apParam.getFunctionName(sys.argv[0])
		apDisplay.printMsg("Function name: "+self.functionname)
		self.appiondir = apParam.getAppionDirectory()
		apDisplay.printMsg("Appion directory: "+self.appiondir)
		hostname = apParam.getHostname()
		apDisplay.printMsg("Processing hostname: "+hostname)
		self.parsePythonPath()
# 		loadavg = os.getloadavg()[0]
# 		if loadavg > 2.0:
# 			apDisplay.printMsg("Load average is high "+str(round(loadavg,2)))
# 			loadsquared = loadavg*loadavg
# 			time.sleep(loadavg)
# 			apDisplay.printMsg("New load average "+str(round(os.getloadavg()[0],2)))
		self.setLockname('lock')

		### setup default parser: run directory, etc.
		self.setParams(optargs,useglobalparams)
		#if 'outdir' in self.params and self.params['outdir'] is not None:
		#	self.params['rundir'] = self.params['outdir']

		### setup correct database after we have read the project id
		if 'projectid' in self.params and self.params['projectid'] is not None:
			apDisplay.printMsg("Using split database")
			# use a project database
			newdbname = apProject.getAppionDBFromProjectId(self.params['projectid'])
			sinedon.setConfig('appiondata', db=newdbname)
			apDisplay.printColor("Connected to database: '"+newdbname+"'", "green")

		### check if user wants to print help message
		if 'commit' in self.params and self.params['commit'] is True:
			apDisplay.printMsg("Committing data to database")
		else:
			apDisplay.printWarning("Not committing data to database")

		self.checkConflicts()
		if useglobalparams is True:
			self.checkGlobalConflicts()

		### setup run directory
		self.setProcessingDirName()
		self.setupRunDirectory()

		### Start pool of threads to run subprocesses.
		### Later you will use self.process_launcher.launch(...) to
		### put commands into the queue.
		### There is currently a timeout built into it that will cause
		### the threads to die if they have no tasks after 10 seconds.
		self.process_launcher = apThread.ProcessLauncher(2, self.params['rundir'])

		### write function log
		self.logfile = apParam.writeFunctionLog(sys.argv, msg=(not self.quiet))

		### upload command line parameters to database
		self.uploadScriptData()

		### any custom init functions go here
		self.onInit()
	def checkConflicts(self):

		self.appiondir = apParam.getAppionDirectory()

		### necessary input values
		if self.params['threedfile'] is None and self.params['modelid'] is None:
			apDisplay.printError('either threed .mrc file or modelid was not defined')
		if self.params['threedfile'] is not None and self.params['modelid'] is not None:
			apDisplay.printError('please specify a single .mrc file (i.e. threedfile or modelid)')
		if self.params['box'] is None and self.params['modelid'] is None:
			apDisplay.printError('boxsize of the output stack not specified')
		if self.params['apix'] is None and self.params['modelid'] is None:
			apDisplay.printError('angstroms per pixel of the input model not specified')
		
		### radius defaulted to 0.5
		if self.params['radius'] is None:
			self.params['radius'] = self.params['box'] / 2
		if self.params['radius'] > self.params['box']/2:
			apDisplay.printError('radius of particle (in pixels) must be smaller than 1/2*boxsize of model')
		if self.params['radius'] > 0 and self.params['radius'] < 1:
			apDisplay.printError('radius must be specified in pixels') 

		### get session info
		if self.params['sessionname'] is None:
			split = self.params['rundir'].split("/")
			self.params['sessionname'] = split[4]

		### make sure that the defoci are positive (underfocus) and in microns
		self.params['df1'] *= 10**-6
		self.params['df2'] *= 10**-6
		if self.params['df1'] < 0:
			apDisplay.printError('defocus value is negative! specify positive (underfocus) values')
		if self.params['df2'] < 0:
			apDisplay.printError('defocus value is negative! specify positive (underfocus) values')

		### check defocus group values
		if self.params['defocus_groups'] is not None:
			self.defmin = float(self.params['defocus_groups'].split(",")[0])
			self.defmax = float(self.params['defocus_groups'].split(",")[1])
			self.defint = float(self.params['defocus_groups'].split(",")[2])
			if self.defmin is None or self.defmax is None or self.defint is None:
				apDisplay.printError("all defocus group values must be specified, e.g. --defocus_groups=1,3,0.1")

		### make sure that only one type of ace2correction is specified
		if self.params['ace2correct'] is True and self.params['ace2correct_rand'] is True:
			apDisplay.printError('Please specify only 1 type of ace2 correction')
		if self.params['ace2correct_std'] >= 0.5 or self.params['ace2correct_std'] <= 0:
			apDisplay.printError("Ace2correct standard deviation specified too high, please use value between 0 < std < 0.5")
		if self.params['ace2estimate'] is True and self.params['ace2correct'] is False:
			apDisplay.printError("ACE2 estimation should only be used if you're doing correction as well, please use both ace2correct and ace2estimate")

		### make sure amplitude correction file exists
		if self.params['envelopefile'] is None:
			self.params['envelopefile'] = os.path.join(apParam.getAppionDirectory(), "appionlib/data/radial-envelope.spi")
		### set cs value & make sure that it's in millimeters
		if self.params['cs'] is None:
			self.params['cs'] = apInstrument.getCsValueFromSession(self.getSessionData())
			self.params['cs'] = self.params['cs'] 
		if self.params['cs'] > 0:
			apDisplay.printWarning("non-zero cs value is untested and may not be properly applied. Consider setting to 0")
		apDisplay.printColor("cs value: %.3f" % self.params['cs'], "cyan")
		return
	def uploadScriptData(self):
		"""
		Using tables to track program run parameters in a generic fashion
		inspired by Roberto Marabini and Carlos Oscar Sanchez Sorzano from the Xmipp team/Carazo lab
		"""
		apDisplay.printMsg("Uploading ScriptData....")
		prognameq = appiondata.ScriptProgramName()
		prognameq['name'] = self.functionname

		userq = appiondata.ScriptUserName()
		userdict = apParam.getUserDict()
		if userdict:
			userq['name'] = userdict['username']
			userq['uid'] = userdict['uid']
			userq['gid'] = userdict['gid']
			userq['fullname'] = userdict['fullname']
			unixshell = userdict['unixshell']
		else:
			userq['name'] = "unknown"
			unixshell = None

		hostq = appiondata.ScriptHostName()
		hostq['name'] = apParam.getHostname()
		hostq['ip'] = apParam.getHostIP()
		hostq['system'] = apParam.getSystemName()
		hostq['distro'] = apParam.getLinuxDistro()
		hostq['nproc'] = apParam.getNumProcessors()
		hostq['memory'] = apParam.getTotalMemory()
		hostq['cpu_vendor'] = apParam.getCPUVendor()
		hostq['gpu_vendor'] = apParam.getGPUVendor()
		hostq['arch'] = apParam.getMachineArch()

		progrunq = appiondata.ScriptProgramRun()
		progrunq['runname'] = self.params['runname']
		progrunq['progname'] = prognameq
		progrunq['username'] = userq
		progrunq['hostname'] = hostq
		progrunq['unixshell'] = unixshell
		progrunq['rundir'] = appiondata.ApPathData(path=os.path.abspath(self.params['rundir']))
		progrunq['job'] = self.getClusterJobData()
		appiondir = apParam.getAppionDirectory()
		### get appion version/subversion revision
		progrunq['revision'] = None
		versionfile = os.path.join(appiondir, "appionlib/version.txt")
		if os.path.isfile(versionfile):
			f = open(versionfile, 'r')
			line = f.readline()
			f.close()
			sline = line.strip()
			progrunq['revision'] = sline
		if os.path.isdir(os.path.join(appiondir, ".svn")):
			if progrunq['revision'] is None:
				progrunq['revision'] = version.getSubversionRevision(appiondir)
			else:
				progrunq['revision'] += "-"+version.getSubversionRevision(appiondir)
		if not progrunq['revision']:
			progrunq['revision'] = 'unknown'
		apDisplay.printMsg("Running Appion version '%s'"%(progrunq['revision']))
		progrunq['appion_path'] = appiondata.ApPathData(path=os.path.abspath(appiondir))

		for paramname in self.params.keys():
			paramnameq = appiondata.ScriptParamName()
			paramnameq['name'] = paramname
			paramnameq['progname'] = prognameq

			paramvalueq = appiondata.ScriptParamValue()
			paramvalueq['value'] = str(self.params[paramname])
			usage = self.usageFromParamDest(paramname, self.params[paramname])
			#print "usage: ", usage
			paramvalueq['usage'] = usage
			paramvalueq['paramname'] = paramnameq
			paramvalueq['progrun'] = progrunq
			if usage is not None:
				paramvalueq.insert()