docs: def importProteinDatabase(filePath, proteindb=None, decoyTag='[decoy]',
          contaminationTag='[cont]', headerParser=None, forceId=False,
          cleavageRule='[KR]', minLength=5, maxLength=40, missedCleavage=2,
          ignoreIsoleucine=False, removeNtermM=True):
      """Generates a :class:`ProteinDatabase` by in silico digestion of proteins
      from a fasta file.
  
      :param filePath: File path
      :param proteindb: optional an existing :class:`ProteinDatabase` can be
          specified, otherwise a new instance is generated and returned
      :param decoyTag: If a fasta file contains decoy protein entries, they should
          be specified with a sequence tag
      :param contaminationTag: If a fasta file contains contamination protein
          entries, they should be specified with a sequence tag
      :param headerParser: optional a headerParser can be specified
          #TODO: describe how a parser looks like
      :param forceId: bool, if True and no id can be extracted from the fasta
          header the whole header sequence is used as a protein id instead of
          raising an exception.
      :param cleavageRule: cleavage rule expressed in a regular expression, see
          :attr:`maspy.constants.expasy_rules`
      :param missedCleavage: number of allowed missed cleavage sites
      :param removeNtermM: bool, True to consider also peptides with the
          N-terminal Methionine of the protein removed
      :param minLength: int, only yield peptides with length >= minLength
      :param maxLength: int, only yield peptides with length <= maxLength
      :param ignoreIsoleucine: bool, if True treat Isoleucine and Leucine in
          peptide sequences as indistinguishable
  
      See also :func:`maspy.peptidemethods.digestInSilico`
      """
      proteindb = ProteinDatabase() if proteindb is None else proteindb
      fastaRead = _readFastaFile(filePath)
  
      for header, sequence in fastaRead:
          proteinTags = list()
          if header.startswith(decoyTag):
              isDecoy = True
              header = header.replace(decoyTag, '')
              proteinTags.append(decoyTag)
          else:
              isDecoy = False
  
          if header.startswith(contaminationTag):
              isCont = True
              header = header.replace(contaminationTag, '')
              proteinTags.append(contaminationTag)
          else:
              isCont = False
  
          headerInfo = _extractFastaHeader(header, headerParser, forceId)
          proteinId = ''.join(itertools.chain(proteinTags, [headerInfo['id']]))
          if 'name' in headerInfo:
              proteinName = ''.join(itertools.chain(proteinTags,
                                                    [headerInfo['name']]
                                                    )
                                    )
          else:
              proteinName = proteinId
  
          if proteinId not in proteindb.proteins:
              protein = ProteinSequence(proteinId, sequence)
              protein.name = proteinName
              protein.fastaHeader = header
              protein.fastaInfo = headerInfo
              proteindb.proteins[protein.id] = protein
  
          #Perform the insilico digestion
          _digestion = maspy.peptidemethods.digestInSilico(sequence, cleavageRule,
                                                           missedCleavage,
                                                           removeNtermM,
                                                           minLength, maxLength
                                                           )
  
          #Add peptides to the protein database
          for unmodPeptide, info in _digestion:
              if ignoreIsoleucine:
                  unmodPeptideNoIsoleucine = unmodPeptide.replace('I', 'L')
                  if unmodPeptideNoIsoleucine in proteindb.peptides:
                      currPeptide = proteindb.peptides[unmodPeptideNoIsoleucine]
                  else:
                      currPeptide = PeptideSequence(unmodPeptideNoIsoleucine,
                                                    mc=info['missedCleavage']
                                                    )
                      proteindb.peptides[unmodPeptideNoIsoleucine] = currPeptide
  
                  if unmodPeptide not in proteindb.peptides:
                      proteindb.peptides[unmodPeptide] = currPeptide
              else:
                  if unmodPeptide in proteindb.peptides:
                      currPeptide = proteindb.peptides[unmodPeptide]
                  else:
                      currPeptide = PeptideSequence(unmodPeptide,
                                                    mc=info['missedCleavage']
                                                    )
                      proteindb.peptides[unmodPeptide] = currPeptide
  
              if proteinId not in currPeptide.proteins:
                  currPeptide.proteins.add(proteinId)
                  #TODO: change that a peptide can appear multiple times in a
                  #  protein sequence.
                  currPeptide.proteinPositions[proteinId] = (info['startPos'],
                                                             info['endPos']
                                                             )
  
      #Add peptide entries to the protein entries, define wheter a peptide can be
      #uniquely assigend to a single protein (.isUnique = True).
      for peptide, peptideEntry in viewitems(proteindb.peptides):
          numProteinMatches = len(peptideEntry.proteins)
          if numProteinMatches == 1:
              peptideEntry.isUnique = True
          elif numProteinMatches > 1:
              peptideEntry.isUnique = False
          else:
              raise Exception('No protein matches in proteindb for peptide' +
                              'sequence: ' + peptide)
  
          for proteinId in peptideEntry.proteins:
              if peptideEntry.isUnique:
                  proteindb.proteins[proteinId].uniquePeptides.add(peptide)
              else:
                  proteindb.proteins[proteinId].sharedPeptides.add(peptide)
  
      #Check protein entries if the digestions generated at least one peptide that
      #is uniquely assigned to the protein (.isUnique = True)
      for proteinEntry in viewvalues(proteindb.proteins):
          if len(proteinEntry.uniquePeptides) > 0:
              proteinEntry.isUnique = True
          else:
              proteinEntry.isUnique = False
      #Note: TODO, altough isoleucin is ignored, the protein entry should only
      #show the actually present ILE / LEU occurence, not any possibilities
      return proteindb