Source code for pwem.utils

# **************************************************************************
# *
# * Authors: Yunior C. Fonseca Reyna    (cfonseca@cnb.csic.es)
# *
# *
# * Unidad de  Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************
from glob import glob
from os.path import join, dirname, basename
import logging
logger = logging.getLogger(__name__)
import pyworkflow.utils as pwutils
import pwem


[docs]def loadSetFromDb(dbName, dbPrefix=''): from pwem import Domain from pyworkflow.mapper.sqlite import SqliteFlatDb db = SqliteFlatDb(dbName=dbName, tablePrefix=dbPrefix) setClassName = db.getProperty('self') # get the set class name setObj = Domain.getObjects()[setClassName](filename=dbName, prefix=dbPrefix) return setObj
[docs]def runProgram(program, params): """ Runs an em program setting its environment matching a prefix""" env = None # Allow passing absolute paths programName = basename(program) from pwem import Domain # Avoid detecting xmipp installation script to be run as xmipp, since # it will run devel installation with production xmippEnv.json environment: # Example: want to compile devel with java 8, but production was compiled with java 11. # So java 11 makes it into the PATH taking priority if programName.startswith('xmipp_'): print("Xmipp command detected") xmipp3 = Domain.getPlugin('xmipp3').Plugin env = xmipp3.getEnviron() if programName.startswith('relion'): print("relion command detected") relion = Domain.getPlugin("relion").Plugin env = relion.getEnviron() elif (programName.startswith('e2') or programName.startswith('sx')): print("eman/sparx command detected") eman2 = Domain.importFromPlugin('eman2', 'Plugin') env = eman2.getEnviron() program = eman2.getProgram(programName) elif programName.startswith('b'): print("Bsoft command detected") bsoft = Domain.importFromPlugin('bsoft', 'Plugin') env = bsoft.getEnviron() pwutils.runJob(None, program, params, env=env)
[docs]def getPWEMPath(*paths): return join(dirname(pwem.__file__), *paths)
[docs]def getTemplatePath(*paths): return join(getPWEMPath('templates'), *paths)
[docs]def getCmdPath(*paths): return join(getPWEMPath('cmd'), *paths)
[docs]def convertPixToLength(samplingRate, length): return samplingRate * length
[docs]def splitRange(minValue, maxValue, splitNum=10, roundTo=2): """ returns a list of "splitNum" items with values ranging from minValue to maxValue, equally divided :param minValue: value to start from :param maxValue: value to stop :param splitNum: number of splits, limits included :param roundTo: default to 2, rounding decimal value :return: list with the split """ inter = (maxValue - minValue) / (splitNum - 1) rangeList = [] for step in range(0, splitNum): rangeList.append(round(minValue + step * inter, roundTo)) return rangeList
PROBLEMATIC_SHELL_CHARS = ";<>?\"()|*\\'&"
[docs]def cleanFileName(fn, warn=True): """ Cleans any character that later on might cause shell parsing errors like "(", ")", " " and warns about it if warn is true. :param fn: file to be cleaned :param warn: Optional (True). Logs """ cleaned = False for bannedChar in PROBLEMATIC_SHELL_CHARS: if bannedChar in fn: if warn: logger.info("Warning!. Problematic character (%s) found in file %s. " "Any of these characters will be removed: %s" % (bannedChar, fn, PROBLEMATIC_SHELL_CHARS)) fn = fn.replace(bannedChar, '') cleaned = True return fn, cleaned
[docs]def round_to_nearest(number, base): """ Rounds number to the nearest integer: E.g: pass base=5 to round to the nearest number multiple of 5 :param number: number to be rounded :param base: integer to limit the rounding to """ return base * round(number/base)
[docs]def getMatchingFiles(path, sort=False): filePaths = glob(path) if sort: filePaths.sort() return filePaths
[docs]def fnMatching(itemId, filesDict, objType='Micrograph'): """ Check if in an object (micrograph, ctf, etc...) its files are matched :param itemId: Is micName, baseName, tsId,...(is not objId) :param filesDict: The keys are the base name of the file to import without the extension, and the values can be a path (e.g. path of the ctf files when importing ctf) or an object (e.g. micrographs when importing coordinates). :param objType: This parameter is informative to complete the log messages to know what is being imported. :return: A tuple with the key and the value of filesDict that matches itemId """ longestItem = None longestItemId = None finalMessage = None if itemId in filesDict: longestItem = filesDict[itemId] longestItemId = itemId finalMessage = "%s %s exact match" % (objType, itemId) else: longestMatch = 0 matchLen = 0 # ItemId is not objId. Is micName or tsId for fileBaseName, item in filesDict.items(): if itemId.startswith(fileBaseName): # BVP_1234_aligned(objFile) startswith BVP_1234(micName, baseName, tsId,...) message = "%s %s starts with %s" % (objType, itemId, fileBaseName) matchLen = len(fileBaseName) elif fileBaseName in itemId: # BVP_1234(micName or baseName) in BVP_1234_info(objFile) message = "%s %s contains %s" % (objType, itemId, fileBaseName) matchLen = len(fileBaseName) if len(itemId) > matchLen: if fileBaseName.startswith(itemId): # BVP_1234_aligned(fileBaseName) startswith BVP_1234(itemId) # MicBase start with coordBase message = "%s %s is the beginning of %s" % (objType, itemId, fileBaseName) matchLen = len(itemId) elif itemId in fileBaseName: # BVP_1234(itemId) in BVP_1234_aligned(fileBaseName) # micBase contains coordBase message = "%s %s contained in %s" % (objType, itemId, fileBaseName) matchLen = len(itemId) if matchLen > longestMatch: finalMessage = message longestMatch = matchLen longestItem = item longestItemId = fileBaseName matchLen = 0 if finalMessage is not None: logger.debug(finalMessage + ': ' + str(longestItem)) else: finalMessage = '%s %s does not match ' % (objType, itemId) logger.debug(finalMessage) return longestItemId, longestItem