private void generateTables() {
    /* Initialise the cbits array */
    ProteinProducer.cbits = new int[2][tfGenes.length+pGenes.length][tfProteins.length];
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < tfGenes.length + pGenes.length; j++)
        for (int k = 0; k < tfProteins.length; k++)
          ProteinProducer.cbits[i][j][k] = -1;

    /* Find the maximum level of matching */
    umax = -1;
    for (Gene g : tfGenes) {
      int temp;
      if ((temp = ProteinProducer.calculateUMax(g, tfProteins)) > umax)
        umax = temp;
    }
    for (Gene g : pGenes) {
      int temp;
      if ((temp = ProteinProducer.calculateUMax(g, tfProteins)) > umax)
        umax = temp;
    }

    /* Populate the table by expressing each gene once */
    for (int i = 0; i < tfGenes.length;  i++) {
      tfGenes[i].index = i;
      ProteinProducer.produce(tfGenes[i], tfProteins[i], tfProteins, umax);
    }
    for (int i = 0; i < pGenes.length;  i++) {
      pGenes[i].index = tfGenes.length+i;
      ProteinProducer.p_produce(pGenes[i], pProteins[i], tfProteins, umax);
    }
  }