code: def from_bam(pysam_samfile, loci, normalized_contig_names=True):
          '''
          Create a PileupCollection for a set of loci from a BAM file.
          Parameters
          ----------
          pysam_samfile : `pysam.Samfile` instance, or filename string
              to a BAM file. The BAM file must be indexed.
          loci : list of Locus instances
              Loci to collect pileups for.
          normalized_contig_names : whether the contig names have been normalized
              (e.g. pyensembl removes the 'chr' prefix). Set to true to
              de-normalize the names when querying the BAM file.
          Returns
          ----------
          PileupCollection instance containing pileups for the specified loci.
          All alignments in the BAM file are included (e.g. duplicate reads,
          secondary alignments, etc.). See `PileupCollection.filter` if these
          need to be removed. 
          '''
          loci = [to_locus(obj) for obj in loci]
          close_on_completion = False
          if typechecks.is_string(pysam_samfile):
              pysam_samfile = Samfile(pysam_samfile)
              close_on_completion = True        
          try:
              if normalized_contig_names:
                  chromosome_name_map = {}
                  for name in pysam_samfile.references:
                      normalized = pyensembl.locus.normalize_chromosome(name)
                      chromosome_name_map[normalized] = name
                      chromosome_name_map[name] = name
              else:
                  chromosome_name_map = None
              result = PileupCollection({})
              locus_iterator = itertools.chain.from_iterable(
                  (Locus.from_interbase_coordinates(locus_interval.contig, pos)
                      for pos
                      in locus_interval.positions)
                  for locus_interval in sorted(loci))
              for locus in locus_iterator:
                  result.pileups[locus] = Pileup(locus, [])
                  if normalized_contig_names:
                      try:
                          chromosome = chromosome_name_map[locus.contig]
                      except KeyError:
                          logging.warn("No such contig in bam: %s" % locus.contig)
                          continue
                  else:
                      chromosome = locus.contig
                  columns = pysam_samfile.pileup(
                      chromosome,
                      locus.position,
                      locus.position + 1,
                      truncate=True,
                      stepper="nofilter")
                  try:
                      column = next(columns)
                  except StopIteration:
                      continue
                  pileups = column.pileups
                  assert list(columns) == []
                  for pileup_read in pileups:
                      if not pileup_read.is_refskip:
                          element = PileupElement.from_pysam_alignment(
                              locus, pileup_read)
                          result.pileups[locus].append(element)
              return result
          finally:
              if close_on_completion:
                  pysam_samfile.close()