Beispiel #1
0
    def fc__init__(self):
        """
    Create formatConversion object and set NMR constraint store
    """

        self.formatConversion = FormatConversion(ccpnProject=self.ccpnProject,
                                                 guiRoot=self.guiRoot)

        if not hasattr(self, 'nmrConstraintStore'):
            self.nmrConstraintStore = None
Beispiel #2
0
  def writePdbFile(self):
 
    self.tmpFileName = "tmp.%d.pdb" % random.randint(0,10000000)
    self.tmpFilePath = os.path.join(self.tempPath,self.tmpFileName)
    
    if not os.path.exists(self.tempPath):
      os.mkdir(self.tempPath)

    fc = FormatConversion(ccpnProject=self.ccpnProject)

    addKeywords = {'structures': [self.structureEnsemble.sortedModels()[0]], 'version': '3.2' }
    fc.exportFile('coordinates','pdb',self.tmpFilePath,addKeywords = addKeywords)
    def __init__(self, ccpnProjectName=None, ccpnProject=None, guiRoot=None):

        # TODO: this could start from existing project, for example when reading in second chain!
        self.formatConversion = FormatConversion(
            ccpnProjectName=ccpnProjectName,
            ccpnProject=ccpnProject,
            silentRead=True,
            guiRoot=guiRoot)

        self.formatNamesAtImport = {}

        self.importReturns = {}
        self.importConversion = {}
        self.importSuccess = {}

        self.newResonances = {}

        self.sequenceComparison = SequenceCompare()
Beispiel #4
0
    def startFormatConversion(self):

        #
        # Import formatConversion code
        #

        from ccpnmr.format.general.Conversion import FormatConversion

        self.formatConversion = FormatConversion()
    def writePdbFile(self):

        self.tmpFileName = "tmp.%d.pdb" % random.randint(0, 10000000)
        self.tmpFilePath = os.path.join(self.tempPath, self.tmpFileName)

        if not os.path.exists(self.tempPath):
            os.mkdir(self.tempPath)

        fc = FormatConversion(ccpnProject=self.ccpnProject)

        addKeywords = {
            'structures': [self.structureEnsemble.sortedModels()[0]],
            'version': '3.2'
        }
        fc.exportFile('coordinates',
                      'pdb',
                      self.tmpFilePath,
                      addKeywords=addKeywords)
    projectName = 'testImport'

    #
    # Remove project if it already exists - otherwise will interfere with creation of data
    # as it will be picked up automatically.
    #

    if os.path.exists(projectName):
        shutil.rmtree(projectName)

    #
    # Create the FormatConversion object (is a wrapper around the FormatConverter that takes care
    # of CCPN object creation and tracking.
    #

    fc = FormatConversion(identifier=projectName, useGui=True)

    #
    # Import the chemComp - returns a list of objects
    #

    chemComps = fc.importFile('chemComps', 'mol2', mol2File)

    #
    # If the import worked, list info on the chemComps that were created
    #

    for chemComp in chemComps:
        listChemCompInfo(chemComp)

    #
class FormatConverterWrapper:
    """
  
  
  Restrictions:

  - Will not work with complex carbohydrates or multiple ligands connected to each other.
  
  
  """

    coordinateFormatNames = [
        'auremol', 'charmm', 'cns', 'cyana', 'dyana', 'molmol', 'nmrStar',
        'pdb', 'pseudoPdb'
    ]

    formatNameLists = {
        'shifts':

        # 'cosmos',
        [
            'auremol', 'autoAssign', 'cns', 'csi', 'mars', 'monte', 'nmrStar',
            'nmrView', 'pipp', 'pistachio', 'pronto', 'shiftx', 'sparky',
            'talos', 'xeasy'
        ],
        'coordinates':

        # 'cosmos'
        coordinateFormatNames,
        'chemComps': [
            'mol2', 'pdb'
        ],  # Only these, need atom names! Pdb overlap is OK - different parser.
        'sequence':

        # 'mol2',
        coordinateFormatNames[:] + [
            'ansig', 'aria', 'autoAssign', 'csi', 'fasta', 'mars', 'monte',
            'nmrView', 'pipp', 'pistachio', 'pronto', 'shiftx', 'sparky',
            'talos', 'xeasy'
        ],
        'distanceConstraints': ['cns', 'cyana'],
        'rdcConstraints': ['cns', 'cyana'],
        'dihedralConstraints': ['cns', 'cyana'],
    }

    def __init__(self, ccpnProjectName=None, ccpnProject=None, guiRoot=None):

        # TODO: this could start from existing project, for example when reading in second chain!
        self.formatConversion = FormatConversion(
            ccpnProjectName=ccpnProjectName,
            ccpnProject=ccpnProject,
            silentRead=True,
            guiRoot=guiRoot)

        self.formatNamesAtImport = {}

        self.importReturns = {}
        self.importConversion = {}
        self.importSuccess = {}

        self.newResonances = {}

        self.sequenceComparison = SequenceCompare()

    def readChemicalShiftFile(self, formatName, filePath):

        dataType = 'shifts'

        return self.readFile(dataType, formatName, filePath)

    def readSequenceFile(self, formatName, filePath):

        dataType = 'sequence'

        return self.readFile(dataType, formatName, filePath)

    def readLigandFile(self, formatName, filePath):

        # TODO doesn't work yet in Conversion.py!
        dataType = 'chemComps'

        return self.readFile(dataType, formatName, filePath)

    def readCoordinateFile(self, formatName, filePath):

        dataType = 'coordinates'

        return self.readFile(dataType, formatName, filePath)

    def readFile(self, dataType, formatName, filePath, addKeywords=None):

        # Track name of format name used for import of this file type
        self.formatNamesAtImport[dataType] = formatName

        if not addKeywords:
            addKeywords = {}

        # Hacks to handle coordinates - handling these files is a mess in the formatConversion class!
        preparseFilePath = filePath
        if dataType == 'coordinates':
            addKeywords['autoCreateChemComps'] = True
            preparseFilePath = [filePath]

        (fileRead, fileInformation) = self.formatConversion.preparseFile(
            dataType, formatName, preparseFilePath)

        self.importReturns[dataType] = self.formatConversion.importFile(
            dataType, formatName, filePath, addKeywords=addKeywords)

        self.ccpnObjectOrList = self.importReturns[dataType]
        self.conversionInfo = self.formatConversion.conversionInfo
        self.conversionSuccess = self.formatConversion.conversionSuccess

        # Set info for export to NMR-STAR
        self.setNmrStarExportInfo(formatName)

        # Track newly created resonances
        if dataType not in ('sequence', 'coordinates', 'chemComps'):
            self.addNewResonances(formatName)

        return (fileRead, fileInformation)

    def setNmrStarExportInfo(self, importFormatName):

        resonances = self.formatConversion.getFormatClass(
            importFormatName).newResonances

        #
        # Copy over original assignment info for NMR-STAR export!
        #

        for resonance in resonances:
            for appData in resonance.findAllApplicationData(
                    application=importFormatName):
                newAppData = None
                if appData.keyword == 'assign':
                    newAppData = Implementation.AppDataString(
                        application='nmrStar',
                        keyword='origAssign',
                        value=appData.value)
                elif appData.keyword == 'origResLabel':
                    newAppData = appData

                if newAppData:
                    resonance.addApplicationData(newAppData)

    def addNewResonances(self, importFormatName):

        newResonances = self.formatConversion.getFormatClass(
            importFormatName).newResonances

        if newResonances:

            resonanceParent = newResonances[0].parent

            if resonanceParent not in self.newResonances.keys():
                self.newResonances[resonanceParent] = {}
            if importFormatName not in self.newResonances[
                    resonanceParent].keys():
                self.newResonances[resonanceParent][importFormatName] = []

            for newResonance in newResonances:
                if newResonance not in self.newResonances[resonanceParent][
                        importFormatName]:
                    self.newResonances[resonanceParent][
                        importFormatName].append(newResonance)

    def determineFileInfo(self, filePath):
        """ Analyse file and file name for readable file and return info dictionary
    
    NB currently only for restrains and coordinates as in the dataTypes parameter
    Problem is that sequence reading will interpret almost any text as a sequence and try to
    download ChemComps name '<DocType' etc.
    Rasmus Fogh 26/6/2013
    """

        constraintTypes = (
            'distanceConstraints',
            'dihedralConstraints',
            'rdcConstraints',
        )
        coordinateFormats = ('pdb', 'pseudoPdb')
        ignoreExtensions = ('.xml', )

        result = {}

        # Set up
        fileName = os.path.basename(filePath)
        head, ext = os.path.splitext(fileName)

        result['name'] = head

        # lower case to simplify tests below
        head = head.lower()
        ext = ext.lower()

        # set dataTypes and formatNames from extension
        dataTypes = None
        formatNames = None

        if ext in ('.coord', '.pdb'):
            dataTypes = ('coordinates', )
            formatNames = coordinateFormats

        elif ext in ('.upl', '.lol'):
            dataTypes = ('distanceConstraints', )
            formatNames = ('cyana', )

        elif ext == '.aco':
            dataTypes = ('dihedralConstraints', )
            formatNames = ('cyana', )

        elif ext == '.tbl':
            formatNames = ('cns', )

            if 'dihe' in head:
                dataTypes = ('dihedralConstraints', )

            elif 'rdc' in head:
                dataTypes = ('rdcConstraints', )

            else:
                for tag in ('ambig', 'unambig', 'noe', 'dist'):
                    if tag in head:
                        dataTypes = ('distanceConstraints', )
                        break
                else:
                    dataTypes = constraintTypes

        else:
            # extension not recognised
            # do nothing for now
            # Later add shifts, sequences, peaks ... here
            pass

        # Check if any of the proposed dataType,formtName combos work
        fileRead = None
        if dataTypes and formatNames:
            # extension shows which format(s) to check
            for dataType in dataTypes:
                for formatName in formatNames:
                    fileRead, fileInformation = self.formatConversion.preparseFile(
                        dataType, formatName, filePath)
                    if fileRead:
                        break
                else:
                    continue
                break

        if fileRead:
            # success above. Set result
            result['dataType'] = dataType
            result['formatName'] = formatName

        #
        return result

    def determineFormatNamesForFile(self, dataType, filePath):

        formatNameSuggestions = self.formatConversion.determineFormatNamesForFile(
            dataType, filePath, formatNameList=self.formatNameLists[dataType])

        return formatNameSuggestions

    def linkAllResonancesToAtoms(self):

        linkingInfo = {}

        # Links everything, will only work for monomers at this stage
        resonanceParents = self.newResonances.keys()
        resonanceParents.sort()

        for resonanceParent in resonanceParents:

            importFormatNames = self.newResonances[resonanceParent].keys()
            importFormatNames.sort()

            for importFormatName in importFormatNames:

                origUnlinked = -999
                """
        TODO: Deal with problem of files with different chain codes; could run first on distance stuff (residue
        info), then force same mapping for other chaincodes... best to make sure original format is fixed though?
        """
                forceChainMappings = self.linkResonancesToSequence(
                    resonanceParent=resonanceParent,
                    importFormatName=importFormatName,
                    allowMultipleFormatChains=True)

                # This tries to apply a chain mapping from another format to this one; bit dangerous
                if not forceChainMappings:
                    if existingForceChainMappings:
                        forceChainMappings = self.setForceChainMappingsFromPreviousMapping(
                            existingForceChainMappings,
                            resonanceParent=resonanceParent,
                            importFormatName=importFormatName)
                else:
                    existingForceChainMappings = forceChainMappings

                if forceChainMappings:

                    chainMappingResetAttempted = False

                    while True:

                        self.formatConversion.linkResonances(
                            forceChainMappings=forceChainMappings,
                            setSingleProchiral=False,
                            setSinglePossEquiv=False)
                        numResonancesLinked = self.formatConversion.numResonancesLinked
                        linkingInfo[(resonanceParent,
                                     importFormatName)] = numResonancesLinked

                        if numResonancesLinked['unlinked'] == 0:
                            break
                        elif self.formatConversion.numResonancesLinked[
                                'origUnlinked'] == origUnlinked:
                            # Here trying to apply a working chain mapping to one where there is not enough information, within the same format.
                            if existingForceChainMappings:
                                forceChainMappings = self.setForceChainMappingsFromPreviousMapping(
                                    existingForceChainMappings,
                                    resonanceParent=resonanceParent,
                                    importFormatName=importFormatName)

                            if chainMappingResetAttempted or not forceChainMappings:
                                break
                            else:
                                print("  WARNING: trying new chain mapping {}".
                                      format(str(forceChainMappings)))
                                chainMappingResetAttempted = True

                        origUnlinked = self.formatConversion.numResonancesLinked[
                            'origUnlinked']

        return linkingInfo

    def setForceChainMappingsFromPreviousMapping(self,
                                                 existingForceChainMappings,
                                                 resonanceParent=None,
                                                 importFormatName=None):

        self.setSequenceComparisonFormatFileInfo(resonanceParent,
                                                 importFormatName)

        # Make sure to exclude format chain codes in the existing mapping; are picked up again in above method
        existingMappedFormatChainCodes = []
        for (ccpnChainCode, existingFormatChainCode, ccpnSeqId,
             offset) in existingForceChainMappings:
            if existingFormatChainCode not in existingMappedFormatChainCodes:
                existingMappedFormatChainCodes.append(existingFormatChainCode)

        # Now try to find out whether a new chain mapping can be created based on the existing one.
        forceChainMappings = []

        formatChainCodes = self.sequenceComparison.formatFileResidueDict.keys()
        for formatChainCode in formatChainCodes[:]:
            if formatChainCode in existingMappedFormatChainCodes:
                formatChainCodes.pop(formatChainCodes.index(formatChainCode))

        if len(formatChainCodes) == 1:
            for (ccpnChainCode, existingFormatChainCode, ccpnSeqId,
                 offset) in existingForceChainMappings:
                forceChainMappings.append(
                    (ccpnChainCode, formatChainCodes[0], ccpnSeqId, offset))
        else:
            print(
                "   Warning: cannot use previous mapping, multiple chain codes in format."
            )

        return forceChainMappings

    def setSequenceComparisonFormatFileInfo(self, resonanceParent,
                                            importFormatName):

        #
        # New resonances for shift list are tracked by FC
        #

        if not resonanceParent:
            if self.newResonances.keys():
                resonanceParent = self.newResonances.keys()[0]

        assert resonanceParent in self.newResonances.keys(
        ), "No resonance parent class defined!"

        if not importFormatName:
            if self.newResonances[resonanceParent].keys():
                importFormatName = self.newResonances[resonanceParent].keys(
                )[0]

        resonances = self.newResonances[resonanceParent][importFormatName]
        self.numNewResonances = len(resonances)

        #print importFormatName, resonances

        #
        # Get info from the resonances
        #

        self.sequenceComparison.getFormatFileInformation(
            resonances, importFormatName)

    def linkResonancesToSequence(self,
                                 chain=None,
                                 resonanceParent=None,
                                 importFormatName=None,
                                 allowMultipleFormatChains=False):
        """
    Note: taken from ccpnmr.format.process.matchResonToMolSys
    """

        forceChainMappings = {}

        self.setSequenceComparisonFormatFileInfo(resonanceParent,
                                                 importFormatName)

        #
        # Now generate the sequence information (one-letter codes for polymer, three letter otherwise) for the chain(s) in CCPN
        #

        if not chain:

            # 2013JUn26 Rasmus Fogh
            # Changed to allow use of pre-exiating MolSystem, e.g. if reading into existing project

            #if 'sequence' not in self.importReturns.keys() and 'coordinates' not in self.importReturns.keys():
            #  raise DepositionImportError('Sequence information missing, cannot continue!')

            if 'sequence' in self.importReturns.keys():
                chains = self.importReturns['sequence']
            else:
                chains = self.formatConversion.ccpnProject.currentMolSystem.sortedChains(
                )

            # Rasmus Fogh addition
            if not chains:
                raise DepositionImportError(
                    'Sequence information missing, cannot continue!')

            # TODO REMOVE THIS WHEN BECOMES POSSIBLE!
            if len(chains) > 1:
                raise DepositionImportError(
                    'Multiple chains created during import, cannot continue!')

        else:

            chains = [chain]

        self.sequenceComparison.createCcpnChainInformation(chains)

        #
        # Now generate the sequence (one-letter codes) for the information from the chemical shift file
        #

        if not allowMultipleFormatChains and len(
                self.sequenceComparison.formatFileChainDict) > 1:
            raise DepositionImportError(
                'Multiple format chain codes in imported chemical shift file, cannot continue!'
            )

        self.sequenceComparison.createFormatFileChainInformation()

        #
        # Now run the comparison...
        #

        forceChainMappings = self.sequenceComparison.compareFormatFileToCcpnInfo(
        )

        print "\n*** Chain mappings set by alignment information ***\n"
        print forceChainMappings

        #
        # Reset list of resonances for FormatClass!
        #

        self.formatConversion.getFormatClass(
            importFormatName).newResonances = []

        return forceChainMappings
Beispiel #8
0
def runD2D(chain, shiftList):

    fileName = tempfile.mkstemp()[1]
    predictionDict = {}

    try:

        # FIRST: run Format Converter to export shifts to ShiftY file
        chains = [chain]
        fc = FormatConversion(ccpnProject=chain.root)
        fc.exportFile('shifts',
                      'shifty',
                      fileName,
                      addKeywords={
                          'measurementList': shiftList,
                          'chains': chains
                      })

        # SECOND: run D2D on remote server
        fields = {'MAX_FILE_SIZE': 7000000, 'ph': 'No'}
        fileKey = 'userfile'
        response = uploadFile(URL, fileKey, fileName, fields)
        response = response.split('\n')

        # THIRD: parse results and return
        ss = 'File failed to upload correctly'
        tt = '#num'
        vv = '#DONE!'
        fields = None
        for line in response:
            if ss in line:
                raise Exception('D2D: %s' % ss)
            if line.startswith(tt):
                fields = line[1:].split()
            elif line.startswith(vv):
                break
            elif fields:
                values = line.split()
                if len(values) == len(fields):
                    residue = secStrucCode = None
                    probabilityDict = {}
                    for n, value in enumerate(values):
                        field = fields[n]
                        if field in SEC_STRUC_KEYS:
                            probabilityDict[field] = float(value)
                        elif field == RES_NUM_KEY:
                            seqCode = int(value)
                            residue = chain.findFirstResidue(seqCode=seqCode)
                        elif field == SS_KEY:
                            isReliable = not value.endswith(UNRELIABLE)
                            if not isReliable:
                                value = value[:-1]
                            secStrucCode = value
                    predictionDict[residue] = (secStrucCode, isReliable,
                                               probabilityDict)

    finally:
        try:
            # sometimes, at least on Windows, get following error:
            # The process cannot access the file because it is being used by another process
            os.remove(fileName)
        except:
            pass

    return predictionDict
Beispiel #9
0
class FcWorkFlow(WorkFlow):

    FcWorkFlowError = StandardError

    #
    # componentList contains the data elements that this particular workflow bit can handle as input.
    # If empty, means it can handle anything.
    #
    # TODO: should I split this up into import/export?
    #

    componentList = []

    #
    # These are class-specific linkResonances variables that can be set for a specific
    # import.
    #

    specificResNameMappings = {}
    forceChainMappings = {}
    useCommonNames = False
    useIupacMatching = False

    def fc__init__(self):
        """
    Create formatConversion object and set NMR constraint store
    """

        self.formatConversion = FormatConversion(ccpnProject=self.ccpnProject,
                                                 guiRoot=self.guiRoot)

        if not hasattr(self, 'nmrConstraintStore'):
            self.nmrConstraintStore = None

    def fcImportValidateAllData(self):
        """
    Import the data for a particular project - this is customised in subclass,
    and validate the information
    """

        self.fcImportAllData()

        #
        # Make sure nmrConstraintStore is set - TODO Where does this belong logically?
        #
        # TODO use formatConversion objects? In a way has code parallel to this...
        #

        if not self.nmrConstraintStore and self.ccpnProject.currentNmrConstraintStore:
            self.nmrConstraintStore = self.ccpnProject.currentNmrConstraintStore

        #
        # Validate if data OK.
        #

        self.fcValidateProjectData()

    def fcImportAllData(self):

        print "Please define an importProjectData function in a subclass component of FcWorkFlow!"

    def fcImportFile(self, *args, **keywds):
        """
    Short method name wrapper for file import
    """

        self.formatConversion.importFile(*args, **keywds)

    def fcGetFormatNameSuggestion(self, informationType, filePath):
        """
    Code to get suggestions for the file format. Will exit when done as default behaviour
    so the correct format can be manually set for this file.
    """

        formatNameSuggestions = self.formatConversion.determineFormatNamesForFile(
            informationType, filePath)

        print "Format suggestions for file %s containing %s information:" % (
            filePath, informationType)
        print formatNameSuggestions
        # TODO this behaviour should probably be settable
        exit(-1)

    def fcExportFile(self, *args, **keywds):
        """
    Short method name wrapper for file export
    """

        self.formatConversion.exportFile(*args, **keywds)

    def fcValidateProjectData(self):
        """
    Check for unlinked resonances, and report
    """

        self.reportUnlinkedResonances(self.nmrProject.sortedResonances())

        if self.nmrConstraintStore:
            self.reportUnlinkedResonances(
                self.nmrConstraintStore.sortedFixedResonances())

    def fcConnectResonancesToAtoms(self, importFormatName, chains):
        """
    Run linkResonances for an import format name and a defined set of chains
    """

        sequenceComparison = SequenceCompare()

        #
        # Set CCPN info
        #

        sequenceComparison.createCcpnChainInformation(chains)

        #
        # Get info from the resonances - NOTE this should be run after every individual import!!
        #

        resonances = self.formatConversion.getFormatClass(
            importFormatName).newResonances

        if not resonances:
            print "\n  Warning: No new resonances created during this import, skipping resonance connecting.\n"
            return None

        sequenceComparison.getFormatFileInformation(resonances,
                                                    importFormatName)

        if not sequenceComparison.formatFileResidueDict.keys():
            print "\n  Warning: No format chain information available, skipping resonance connecting.\n"
            return None

        sequenceComparison.createFormatFileChainInformation()

        #
        # Now run the comparison...
        #

        if not self.forceChainMappings:
            self.forceChainMappings = sequenceComparison.compareFormatFileToCcpnInfo(
            )

            print "\n*** Chain mappings set by alignment information ***\n"
        else:
            print "\n*** Chain mappings defined by user ***\n"

        print self.forceChainMappings

        #
        # Reset list of resonances for FormatClass!
        #

        self.formatConversion.getFormatClass(
            importFormatName).newResonances = []

        #
        # Now run linkResonances with automatic mapping
        #

        self.formatConversion.linkResonances(
            forceChainMappings=self.forceChainMappings,
            useLinkResonancePopup=True,
            setSingleProchiral=
            True,  # Assume that, e.g. HB2 is not same as HB3 if only info for HB3.
            setSinglePossEquiv=
            False,  # Assume that, e.g. HD2 is same as HD1 for Phe, Tyr if only info for HD1.
            specificResNameMappings=self.specificResNameMappings,
            useCommonNames=self.useCommonNames,
            useIupacMatching=self.useIupacMatching)

        return self.forceChainMappings

    def fcSetPeaksInformation(self, formatName, filePath, addKeywords):
        """
    Handling of peak lists - can use specific addKeywords that make it easier to select
    reference experiments and set the peak list to reference experiment dimension mappings.
    """

        from ccpnmr.format.general.Util import getRefExpFromOldExpType

        #
        # Step 1, preparse the file and get info out
        #

        (fileRead, fileInformation) = self.formatConversion.preparseFile(
            'peaks', formatName, filePath, addKeywords=addKeywords)

        if not fileRead:
            raise self.FcWorkFlowError(
                "Could not read peak list file %s in format %s:\n%s" %
                (filePath, formatName, fileRead))
        else:
            peakListNames = fileInformation.keys()

            if len(peakListNames) > 1:
                if not addKeywords.has_key("peakListName"):
                    raise self.FcWorkFlowError(
                        "Multiple peak lists in file %s, and no specific 'peakListName' defined in addKeywords."
                        % (filePath))

                else:
                    peakListName = addKeywords['peakListName']

                    if peakListName not in peakListNames:
                        raise self.FcWorkFlowError(
                            "Multiple peak lists in file %s, and 'peakListName' %s not in list of peak list names from file."
                            % (filePath, peakListName))

            else:
                peakListName = peakListNames[0]

            peakPpmRanges = fileInformation[peakListName]['peakPpmRanges']
            dimCodes = fileInformation[peakListName]['dimensionCodes']

        #
        # Step 2, set the reference experiment.
        #

        if addKeywords.has_key('oldExpType'):
            refExperiment = getRefExpFromOldExpType(
                self.formatConversion.ccpnProject, addKeywords['oldExpType'])

            if not refExperiment:
                raise self.FcWorkFlowError(
                    "Could not find reference experiment 'old' name %s." %
                    (addKeywords['oldExpType']))

            del (addKeywords['oldExpType'])

        elif addKeywords.has_key('expTypeInfo'):
            (expPrototypeName, refExpName) = addKeywords['expTypeInfo']

            refExperiment = None

            expPrototype = project.findFirstNmrExpPrototype(
                name=expPrototypeName)
            if expPrototype:
                refExperiment = expPrototype.findFirstRefExperiment(
                    name=refExpName)

            if not refExperiment:
                raise self.FcWorkFlowError(
                    "Could not find reference experiment with (prototype,experiment) names %s."
                    % (addKeywords['expTypeInfo']))

            del (addKeywords['expTypeInfo'])

        else:
            raise self.FcWorkFlowError(
                "No reference experiment defined for %s:\nNeed to set an 'oldExpType' or 'expTypeInfo' variable in addKeywords in self.dataFiles."
                % (filePath))

        addKeywords['refExperiment'] = refExperiment

        refExperimentInfo = self.formatConversion.getRefExperimentInfo(
            addKeywords['refExperiment'])

        #
        # Step 3 set the peak list to reference experiment dimension mapping, if necessary
        #
        # uniqueMatches gives the unique (shift matches) connection between the CCPN dimension (as number) and the peak dimension (as list index)
        # matches       gives all possible shift matches
        #
        # Basically, web side has to allow all possibilities in 'matches', but should set the 'uniqueMatches' match as default.
        #

        # Only run this if not manually set!

        if not addKeywords.has_key(
                'expDimToPeakDim') or not addKeywords['expDimToPeakDim']:

            (matches,
             uniqueMatches) = self.formatConversion.matchFormatAndCcpnPeakDims(
                 peakPpmRanges, dimCodes, refExperimentInfo['ppmRange'])

            if uniqueMatches:
                addKeywords['expDimToPeakDim'] = uniqueMatches
            else:
                raise self.FcWorkFlowError(
                    "No reference experiment dimension to peak list dimension mapping set or a unique match found. Possibilities are:\n%s\n\nReference experiment info is:\n%s\n\nPeak ppm ranges:\n%s\n"
                    % (str(matches), refExperimentInfo, str(peakPpmRanges)))