<commit_before>(function() {
'use strict';

// TODO:
//     1. Develop epitope information window.
//     2. Support different sorting functions.
//     3. (?) Display of immungenicity (like binding score bar chart).
//     4. (?) Hover over score bars for more info.
//     5. (?) Dynamic SVG height to it's not too tall sometimes.

var WIDTH = 1000,
    HEIGHT = 12000,
    PEPTIDE_HEIGHT = 20,
    ACID_DIM = 12,
    GENE_WIDTH = 100,
    EPITOPE_INFO_HEIGHT = 125,
    acidX = d3.scale.ordinal().rangeBands([0, WIDTH - GENE_WIDTH]);


function main(data) {
  acidX.domain(d3.range(0, d3.max(data, function(d) {
    return d.sequence.length;
  })));

  d3.select('#peptides')
      .append('svg')
        .attr('width', WIDTH)
        .attr('height', HEIGHT)
      .append('g')
         .attr('transform', 'translate(0,' + PEPTIDE_HEIGHT + ')')
         .attr('id', 'svg');

  renderPeptides(data);
  initializeThresholdSliderHandler(data);
}

function renderPeptides(data) {
  var peptides = d3.select('#svg')
    .selectAll('.peptide')
      .data(data, function(d) { return d.sequence; });

  peptides
    .enter().append('g')
      .attr('class', 'peptide')
      .attr('transform', function(d, i) {
        return 'translate(' + GENE_WIDTH + ',' +
          (i * (PEPTIDE_HEIGHT + 5)) + ')';
      });

  peptides
    .transition().duration(600)
      .attr('transform', function(d, i) {
        return 'translate(' + GENE_WIDTH + ',' +
          (i * (PEPTIDE_HEIGHT + 5)) + ')';
      });

  peptides
      .call(renderGenes)
      .call(renderHighlightEpitopes)
      .call(renderPeptideSequences)
      .call(initializePeptideHandlers);
}

function renderGenes(peptides) {
  peptides.selectAll('.gene')
      .data(function(d,i) { return [d.gene]; })
    .enter().append('text')
      .attr('class', 'gene')
      .attr('dx', -GENE_WIDTH)
      .text(function(d) { return d; });
}

function renderHighlightEpitopes(peptides) {
  var epitopes = peptides.selectAll('.epitope')
      .data(function(d, i) {
        // TODO(ihodes): Is this a good way to handle this? This shows fewer
        //               than you'd normally see, so you just see the strongest
        //               in the overview/peptide list; once the list is
        //               exploded, all the epitopes with one MHC allelse above
        //               the score are shown.
        return epitopesAbove(3, d.epitopes, getThreshold());
      }, _epitope_key_fn);

  epitopes
    .enter().append('g')
      .attr('transform', function(d, i) {
        return 'translate(' + acidX(d.start) + ',0)';
      })
      .attr('class', 'epitope')
    .call(renderPassingEpitopeHighlights);

  epitopes
    .exit()
      .remove();

  // Ensure epitopes are below the letters of the sequence and the click box.
  peptides.selectAll('.sequence').each(function() {
    this.parentNode.appendChild(this);
  });
  peptides.selectAll('.clickbox').each(function() {
    this.parentNode.appendChild(this);
  });
}

function renderPeptideSequences(peptides) {
  var sequence = peptides.selectAll('.sequence')
      .data(function(d) { return d.sequence.split(''); });

  sequence
    .enter().append('text')
      .text(function(d, i) { return d;})
      .attr('class', function(d, i) {
        if (i == this.parentNode.__data__.mutStart
            && i < this.parentNode.__data__.mutEnd) {
          return 'sequence mutation';
        } else {
          return 'sequence';
        }
      })
      .attr('width', ACID_DIM)
      .attr('height', ACID_DIM)
      .attr('y', 0)
      .attr('x', function(d, i) {
        return acidX(i);
      });
}

function initializePeptideHandlers(peptides) {
  peptides.append('rect')
      .attr('class', 'clickbox')
      .attr('width', WIDTH)
      .attr('height', PEPTIDE_HEIGHT)
      .attr('y', -PEPTIDE_HEIGHT)
      .attr('opacity', 0)
      .on('click', function(d, i) {
        explodeEpitopes(peptides, this.parentNode, this, d);
      });<commit_msg>Mutations longer than length=1 now will be correctly highlighted.<commit_after>(function() {
'use strict';

// TODO:
//     1. Develop epitope information window.
//     2. Support different sorting functions.
//     3. (?) Display of immungenicity (like binding score bar chart).
//     4. (?) Hover over score bars for more info.
//     5. (?) Dynamic SVG height to it's not too tall sometimes.

var WIDTH = 1000,
    HEIGHT = 12000,
    PEPTIDE_HEIGHT = 20,
    ACID_DIM = 12,
    GENE_WIDTH = 100,
    EPITOPE_INFO_HEIGHT = 125,
    acidX = d3.scale.ordinal().rangeBands([0, WIDTH - GENE_WIDTH]);


function main(data) {
  acidX.domain(d3.range(0, d3.max(data, function(d) {
    return d.sequence.length;
  })));

  d3.select('#peptides')
      .append('svg')
        .attr('width', WIDTH)
        .attr('height', HEIGHT)
      .append('g')
         .attr('transform', 'translate(0,' + PEPTIDE_HEIGHT + ')')
         .attr('id', 'svg');

  renderPeptides(data);
  initializeThresholdSliderHandler(data);
}

function renderPeptides(data) {
  var peptides = d3.select('#svg')
    .selectAll('.peptide')
      .data(data, function(d) { return d.sequence; });

  peptides
    .enter().append('g')
      .attr('class', 'peptide')
      .attr('transform', function(d, i) {
        return 'translate(' + GENE_WIDTH + ',' +
          (i * (PEPTIDE_HEIGHT + 5)) + ')';
      });

  peptides
    .transition().duration(600)
      .attr('transform', function(d, i) {
        return 'translate(' + GENE_WIDTH + ',' +
          (i * (PEPTIDE_HEIGHT + 5)) + ')';
      });

  peptides
      .call(renderGenes)
      .call(renderHighlightEpitopes)
      .call(renderPeptideSequences)
      .call(initializePeptideHandlers);
}

function renderGenes(peptides) {
  peptides.selectAll('.gene')
      .data(function(d,i) { return [d.gene]; })
    .enter().append('text')
      .attr('class', 'gene')
      .attr('dx', -GENE_WIDTH)
      .text(function(d) { return d; });
}

function renderHighlightEpitopes(peptides) {
  var epitopes = peptides.selectAll('.epitope')
      .data(function(d, i) {
        // TODO(ihodes): Is this a good way to handle this? This shows fewer
        //               than you'd normally see, so you just see the strongest
        //               in the overview/peptide list; once the list is
        //               exploded, all the epitopes with one MHC allelse above
        //               the score are shown.
        return epitopesAbove(3, d.epitopes, getThreshold());
      }, _epitope_key_fn);

  epitopes
    .enter().append('g')
      .attr('transform', function(d, i) {
        return 'translate(' + acidX(d.start) + ',0)';
      })
      .attr('class', 'epitope')
    .call(renderPassingEpitopeHighlights);

  epitopes
    .exit()
      .remove();

  // Ensure epitopes are below the letters of the sequence and the click box.
  peptides.selectAll('.sequence').each(function() {
    this.parentNode.appendChild(this);
  });
  peptides.selectAll('.clickbox').each(function() {
    this.parentNode.appendChild(this);
  });
}

function renderPeptideSequences(peptides) {
  var sequence = peptides.selectAll('.sequence')
      .data(function(d) { return d.sequence.split(''); });

  sequence
    .enter().append('text')
      .text(function(d, i) { return d;})
      .attr('class', function(d, i) {
        if (i >= this.parentNode.__data__.mutStart
            && i < this.parentNode.__data__.mutEnd) {
          return 'sequence mutation';
        } else {
          return 'sequence';
        }
      })
      .attr('width', ACID_DIM)
      .attr('height', ACID_DIM)
      .attr('y', 0)
      .attr('x', function(d, i) {
        return acidX(i);
      });
}

function initializePeptideHandlers(peptides) {
  peptides.append('rect')
      .attr('class', 'clickbox')
      .attr('width', WIDTH)
      .attr('height', PEPTIDE_HEIGHT)
      .attr('y', -PEPTIDE_HEIGHT)
      .attr('opacity', 0)
      .on('click', function(d, i) {
        explodeEpitopes(peptides, this.parentNode, this, d);
      });
{'fraction_non_alphanumeric': 0.16091954022988506, 'fraction_numerical': 0.010369815092453773, 'mean_word_length': 2.5233274647887325, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '732999', 'n_tokens_mistral': 2740, 'n_tokens_neox': 2559, 'n_words': 564}