Remove Centroiding Visualizer Tool

Code cleanup - centroiding visualizer tool has not been used for a long time

BUG=b:206572894
TEST=Tested on chromeos devices & make sure webplot behavior is unaffected

Change-Id: Ib24b34879c3958cfeea8884b4ba729eb55412368
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/touch_firmware_test/+/3770318
Commit-Queue: Jingyuan Liang <jingyliang@google.com>
Reviewed-by: Kenneth Albanowski <kenalba@google.com>
Tested-by: Jingyuan Liang <jingyliang@google.com>
Reviewed-by: Sean O'Brien <seobrien@chromium.org>
Auto-Submit: Jingyuan Liang <jingyliang@google.com>
diff --git a/webplot/centroiding.html b/webplot/centroiding.html
deleted file mode 100644
index 73084b3..0000000
--- a/webplot/centroiding.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!--
-Copyright 2015 The Chromium OS Authors. All rights reserved.
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
--->
-
-<html>
-<head>
-  <script src="centroiding.js"></script>
-</head>
-
-<body style="margin:0; padding:0; background-color:black"
-  onbeforeunload="quit()"
-  onload="createWS()"
-  onkeyup="keyupHandler()"
-  onresize="resizeCanvas()">
-
-  <div id="websocketUrl" hidden>%(websocketUrl)s</div>
-  <div id="dataScale" hidden>%(dataScale)s</div>
-  <div id="dataOffset" hidden>%(dataOffset)s</div>
-  <div id="dataWidth" hidden>%(dataWidth)s</div>
-  <div id="dataHeight" hidden>%(dataHeight)s</div>
-  <canvas id="canvasWebplot"></canvas>
-
-</body>
-</html>
diff --git a/webplot/centroiding.js b/webplot/centroiding.js
deleted file mode 100644
index e7e260f..0000000
--- a/webplot/centroiding.js
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright 2015 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-/**
- * Object of a reported finger contact model.
- * @constructor
- * @param {array of float} paramArray the array of all contact parameters.
- *                         [0]: contact amplitude
- *                         [1]: x-positon of contact
- *                         [2]: y-position of contact
- *                         [3]: x-sigma of contact gaussian model
- *                         [4]: y-sigma of contact gaussian model
- *                         [5]: theta of contact gaussian model
- *                         [6]: tracking ID of contact
- *                         [7]: thumb likelihood
- *                         [8]: palm indicator (0: finger, 1: palm)
- */
-function Contact(paramArray) {
-  this.amp = paramArray[0];
-  this.xPos = paramArray[1];
-  this.yPos = paramArray[2];
-  this.xSigma = paramArray[3];
-  this.ySigma = paramArray[4];
-  this.theta = paramArray[5];
-  this.trackId = paramArray[6];
-  this.thumbLikelihood = 0;
-  this.isPalm = 0;
-  if (paramArray.length > 7)
-    this.thumbLikelihood = paramArray[7];
-  if (paramArray.length > 8)
-    this.isPalm = paramArray[8];
-}
-
-
-/**
- * Object of webplot.
- * @constructor
- * @param {Element} canvas the canvas to draw circles and clicks.
- * @param {string} dataScale the max scale of heatmap raw data.
- * @param {string} dataOffset the offset of heatmap raw data for presenting.
- * @param {string} dataWidth the size of width of heatmap raw data.
- * @param {string} dataHeight the size of height of heatmap raw data.
- */
-function Webplot(canvas, dataScale, dataOffset, dataWidth, dataHeight) {
-  this.canvas = canvas;
-  this.ctx = canvas.getContext('2d');
-  this.scale = 1 / parseInt(dataScale);
-  this.offset = parseInt(dataOffset);
-  this.width = parseInt(dataWidth);
-  this.height = parseInt(dataHeight);
-  this.gridSize = null;
-  this.pointRadius = 6.0;
-  this.contactLineWidth = 3.5;
-}
-
-
-/**
- * Update the width and height of the canvas, the max radius of circles,
- * and the edge of click rectangles.
- */
-Webplot.prototype.updateCanvasDimension = function() {
-  var newWidth = document.body.clientWidth;
-  var newHeight = document.body.clientHeight;
-
-  if (this.canvas.width != newWidth || this.canvas.height != newHeight) {
-    var dataRatio = this.height / this.width;
-    var canvasRatio = (newHeight / newWidth);
-
-    // The actual dimension of the viewport.
-    this.canvas.width = newWidth;
-    this.canvas.height = newHeight;
-
-    // Calculate the inner area of the viewport on which to draw finger traces.
-    // This inner area has the same height/width ratio as the touch device.
-    if (dataRatio >= canvasRatio) {
-      this.canvas.innerWidth = Math.round(newHeight / dataRatio);
-      this.canvas.innerHeight = newHeight;
-      this.canvas.innerOffsetLeft = Math.round(
-          (newWidth - this.canvas.innerWidth) / 2);
-      this.canvas.innerOffsetTop = 0;
-      this.gridSize = newHeight / this.height;
-    } else {
-      this.canvas.innerWidth = newWidth;
-      this.canvas.innerHeight = Math.round(newWidth * dataRatio);
-      this.canvas.innerOffsetLeft = 0;
-      this.canvas.innerOffsetTop = Math.round(
-          (newHeight - this.canvas.innerHeight) / 2);
-      this.gridSize = newWidth / this.width;
-    }
-  }
-  this.drawFrame(this.canvas.innerOffsetLeft, this.canvas.innerOffsetTop,
-                 this.canvas.innerWidth, this.canvas.innerHeight, 'gray');
-}
-
-
-/**
- * Draw a rectangle of heatmap frame border.
- * @param {int} x the x coordinate of upper left corner of the rectangle.
- * @param {int} y the y coordinate of upper left corner of the rectangle.
- * @param {int} width the width of the rectangle.
- * @param {int} height the height of the rectangle.
- * @param {string} colorName
- */
-Webplot.prototype.drawFrame = function(x, y, width, height, colorName) {
-  this.ctx.beginPath();
-  this.ctx.lineWidth = "4";
-  this.ctx.strokeStyle = colorName;
-  this.ctx.rect(x, y, width, height);
-  this.ctx.stroke();
-}
-
-
-/**
- * Draw a circle of presenting contact gaussian model.
- * @param {Element} contact the contact object of gaussian finger model.
- */
-Webplot.prototype.drawContactArea = function(contact) {
-  var ctxLeft = this.canvas.innerOffsetLeft;
-  var ctxTop = this.canvas.innerOffsetTop;
-  var grid = this.gridSize;
-  var offset = grid / 2;
-  var x = contact.xPos;
-  var y = (this.height - 1) - contact.yPos;  // Reflect over x-axis.
-  var cx = x * grid + offset + ctxLeft;
-  var cy = y * grid + offset + ctxTop;
-
-  this.ctx.beginPath();
-  this.ctx.save();  // save state
-  this.ctx.translate(cx, cy);
-  this.ctx.rotate(contact.theta);
-  this.ctx.scale(contact.xSigma * grid, contact.ySigma * grid);
-  this.ctx.arc(0, 0, 1, 0, 2 * Math.PI, false);
-  this.ctx.restore();  // restore to original state
-  this.ctx.lineWidth = this.contactLineWidth;
-  if (contact.isPalm)
-    this.ctx.strokeStyle = 'gold';
-  else
-    this.ctx.strokeStyle = 'deeppink';
-  this.ctx.stroke();
-}
-
-
-/**
- * Draw a point of presenting contact center.
- * @param {Element} contact the contact object of gaussian finger model.
- */
-Webplot.prototype.drawContactCenter = function(contact) {
-  var ctxLeft = this.canvas.innerOffsetLeft;
-  var ctxTop = this.canvas.innerOffsetTop;
-  var grid = this.gridSize;
-  var colors = ['blue', 'yellow', 'purple', 'red', 'orange', 'green',
-                'gold', 'cyan', 'brown', 'limegreen'];
-  var offset = grid / 2;
-  var x = contact.xPos;
-  var y = (this.height - 1) - contact.yPos;  // Reflect over x-axis.
-  var cx = x * grid + offset + ctxLeft;
-  var cy = y * grid + offset + ctxTop;
-
-  this.ctx.beginPath();
-  this.ctx.arc(cx, cy, this.pointRadius, 0, 2 * Math.PI, false);
-  this.ctx.fillStyle = colors[contact.trackId % colors.length];
-  this.ctx.fill();
-
-  if (contact.isPalm) {
-    var text = 'PALM';
-    var text_color = 'blue';
-  } else {
-    var text = contact.thumbLikelihood.toFixed(4);
-    var green = parseInt(255 * (1 - contact.thumbLikelihood)).toString(16);
-    green = (green.length < 2) ? '0' + green : green;
-    var red = parseInt(255 * contact.thumbLikelihood).toString(16);
-    red = (red.length < 2) ? '0' + red : red;
-    var text_color = '#' + red + green + '00';
-  }
-  this.fillText(text, cx + 4, cy + 20, '18px Arial', text_color);
-}
-
-
-/**
- * Fill text.
- * @param {string} text the text to display
- * @param {int} x the x coordinate of upper left corner of the text.
- * @param {int} y the y coordinate of upper left corner of the text.
- * @param {string} font the size and the font.
- * @param {string} color the color of the text.
- */
-Webplot.prototype.fillText = function(text, x, y, font, color) {
-  this.ctx.font = font;
-  this.ctx.fillStyle = color;
-  this.ctx.fillText(text, x, y);
-}
-
-
-/**
- * Capture the canvas image.
- * @return {string} the image represented in base64 text
- */
-Webplot.prototype.captureCanvasImage = function() {
-  var imageData = this.canvas.toDataURL('image/png');
-  // Strip off the header.
-  return imageData.replace(/^data:image\/png;base64,/, '');
-}
-
-
-/**
- * Process an incoming snapshot.
- * @param {object} snapshot
- *
- * A snapshot received from python server looks like:
- * Snapshot(
- *   data=[125,123,90,0,0, ... 230,231],
- *   contact=[[337.311, 1.55013, 6.43009, 0.747915, 0.97476, -0.026596, 1,
- *             0.13422, 0]],
- *   fps=[128.234, 49.992]
- * )
- *
- * data: a total length of width * height integers array of heatmap raw data.
- * contact: an array of contact arrays, each contact array has the following
- *          elements [amplitude, x-position, y-position, x-sigma, y-sigma,
- *          theta, track-ID, thumb likelihood, palm indicator], and they are
- *          all floating numbers.
- * fps: an 2-element array of float for receiver FPS and plot FPS.
- */
-Webplot.prototype.processSnapshot = function(snapshot) {
-  var ctxLeft = this.canvas.innerOffsetLeft;
-  var ctxTop = this.canvas.innerOffsetTop;
-  var grid = this.gridSize;
-  var gridFullPixel = Math.ceil(grid);
-  var data = snapshot.data;
-
-  // Clean up canvas.
-  this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
-
-  // Draw the frame border.
-  this.drawFrame(this.canvas.innerOffsetLeft, this.canvas.innerOffsetTop,
-                 this.canvas.innerWidth, this.canvas.innerHeight, 'gray');
-
-  // Draw heatmap raw data (data grid).
-  for (var i = 0; i < this.width; i++) {
-    for (var j = 0; j < this.height; j++) {
-      var value = this.scale * (data[j + i * this.height] + this.offset);
-      var x = Math.floor(ctxLeft + i * grid);
-      // Reflect over x-axis.
-      var y = Math.floor(ctxTop + (this.height - 1 - j) * grid);
-      var color = parseInt(255 * value).toString(16);
-      color = (color.length < 2) ? "0" + color : color;
-      this.ctx.fillStyle = "#" + color + color + color;
-      this.ctx.fillRect(x, y, gridFullPixel, gridFullPixel);
-    }
-  }
-
-  // Draw finger contact models.
-  for (var i = 0; i < snapshot.contact.length; i++) {
-    var contact = new Contact(snapshot.contact[i]);
-    this.drawContactArea(contact);
-    this.drawContactCenter(contact);
-  }
-
-  // Show FPS rates.
-  this.fillText("Algorithm FPS: " + snapshot.fps[0],
-                20 + ctxLeft, 25 + ctxTop, '14px Verdana', 'bisque');
-  this.fillText("Plot FPS: " + snapshot.fps[1],
-                240 + ctxLeft, 25 + ctxTop, '14px Verdana', 'cyan');
-}
-
-
-Webplot.quitFlag = false;
-
-
-/**
- * An handler for onresize event to update the canvas dimensions.
- */
-function resizeCanvas() {
-  webplot.updateCanvasDimension();
-}
-
-
-/**
- * Send a 'quit' message to the server and display the event file name
- * on the canvas.
- * @param {boolean} closed_by_server True if this is requested by the server.
- */
-function quit(closed_by_server) {
-  var canvas = document.getElementById('canvasWebplot');
-  var webplot = window.webplot;
-  var startX = 100;
-  var startY = 100;
-  var font = '30px Verdana';
-
-  // Capture the image before clearing the canvas and send it to the server,
-  // and notify the server that this client quits.
-  if (!Webplot.quitFlag) {
-    Webplot.quitFlag = true;
-    window.ws.send('quit');
-
-    clear(false);
-    if (closed_by_server) {
-      webplot.fillText('The python server has quit.',
-                       startX, startY, font, 'red');
-    }
-    webplot.fillText('Centroiding data are saved inside "/tmp/"',
-                     startX, startY + 100, font, 'red');
-  }
-}
-
-function save() {
-  window.ws.send('save:' + webplot.captureCanvasImage());
-}
-
-/**
- * A handler for keyup events to handle user hot keys.
- */
-function keyupHandler() {
-  var webplot = window.webplot;
-  var key = String.fromCharCode(event.which).toLowerCase();
-  var ESC = String.fromCharCode(27);
-
-  switch(String.fromCharCode(event.which).toLowerCase()) {
-    // ESC: clearing the canvas
-    case ESC:
-      clear(true);
-      break;
-
-    // 'b': toggle the background color between black and white
-    //      default: black
-    case 'b':
-      document.bgColor = (document.bgColor == 'Black' ? 'White' : 'Black');
-      break;
-
-    // 'f': toggle full screen
-    //      default: non-full screen
-    //      Note: entering or leaving full screen will trigger onresize events.
-    case 'f':
-      if (document.documentElement.webkitRequestFullscreen) {
-        if (document.webkitFullscreenElement)
-          document.webkitCancelFullScreen();
-        else
-          document.documentElement.webkitRequestFullscreen(
-              Element.ALLOW_KEYBOARD_INPUT);
-      }
-      webplot.updateCanvasDimension();
-      break;
-
-    // 'q': Quit the server (and save the plot and logs first)
-    case 'q':
-      save();
-      quit(false);
-      break;
-
-    // 's': Tell the server to save the touch events and a png of the plot
-    case 's':
-      save();
-      break;
-  }
-}
-
-
-function clear(should_redraw_border) {
-  var canvas = document.getElementById('canvasWebplot');
-  canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
-  if (should_redraw_border) {
-    window.webplot.updateCanvasDimension();
-  }
-}
-
-
-/**
- * Create a web socket and a new webplot object.
- */
-function createWS() {
-  var websocket = document.getElementById('websocketUrl').innerText;
-  var dataScale = document.getElementById('dataScale').innerText;
-  var dataOffset = document.getElementById('dataOffset').innerText;
-  var dataWidth = document.getElementById('dataWidth').innerText;
-  var dataHeight = document.getElementById('dataHeight').innerText;
-  if (window.WebSocket) {
-    ws = new WebSocket(websocket);
-    ws.addEventListener("message", function(event) {
-      if (event.data == 'quit') {
-        save();
-        quit(true);
-      } else if (event.data == 'clear') {
-        clear(true);
-      } else if (event.data == 'save') {
-        save();
-      } else {
-        var snapshot = JSON.parse(event.data);
-        webplot.processSnapshot(snapshot);
-      }
-    });
-  } else {
-    alert('WebSocket is not supported on this browser!')
-  }
-
-  webplot = new Webplot(document.getElementById('canvasWebplot'),
-                        dataScale, dataOffset, dataWidth, dataHeight);
-  webplot.updateCanvasDimension();
-}
diff --git a/webplot/centroiding/__init__.py b/webplot/centroiding/__init__.py
deleted file mode 100644
index 4bc803c..0000000
--- a/webplot/centroiding/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2015 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from centroiding_device import CentroidingDevice
-from centroiding_parser import CentroidingDataParser
-from centroiding_receiver import CentroidingDataReceiver
diff --git a/webplot/centroiding/centroiding_device.py b/webplot/centroiding/centroiding_device.py
deleted file mode 100644
index 2fb8f4c..0000000
--- a/webplot/centroiding/centroiding_device.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2015 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Device object for centroiding visualizer tool."""
-
-import os
-import yaml
-
-
-class CentroidingDevice(object):
-  def __init__(self, config):
-    with open(os.path.join(os.path.dirname(__file__), config), 'r') as f:
-      self.config = yaml.load(f)
-
-  @property
-  def device(self):
-    return self.config.get('device')
-
-  @property
-  def data_scale(self):
-    return self.config.get('data_scale')
-
-  @property
-  def data_offset(self):
-    return self.config.get('data_offset')
-
-  @property
-  def width(self):
-    return self.config.get('width')
-
-  @property
-  def height(self):
-    return self.config.get('height')
diff --git a/webplot/centroiding/centroiding_parser.py b/webplot/centroiding/centroiding_parser.py
deleted file mode 100644
index 7f54548..0000000
--- a/webplot/centroiding/centroiding_parser.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# Copyright 2015 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Parser for recorded centroiding data stream. It will generate data files in
-analytical format for our centroiding algorithm library.
-
-It will generate 3 files:
-
-  Trace file: will be generated in path <input_file>/<input_file>
-      To view it by centroiding source tree's tool, put the trace file into
-      traces/ in source tree.
-
-  Finger contact file: will be generated in path <input_file>/<input_file>.json
-      To view it by centroiding source tree's tool, put the contact file into
-      outputs/centroiding/ in source tree.
-
-  Track ID file: will be generated in path <input_file>/<input_file>.id.json
-"""
-
-import argparse
-import json
-import os
-
-from centroiding_device import CentroidingDevice
-
-_JSON_HEADER = '{\n  "events": [\n'
-_JSON_TAIL = '  ]\n}'
-
-
-class CentroidingDataParserError(Exception):
-  pass
-
-class CentroidingDataParser(object):
-  """Parser for recorded centroiding raw data stream."""
-  def __init__(self, input_file, device):
-    self.input_file = input_file
-    self.device = device
-
-    self.head_trim_thres = self.device.data_scale >> 2
-    self.is_head = True
-
-    # Use the root name of input_file as generated output folder name.
-    self.output_dir = os.path.splitext(input_file)[0]
-    if not os.path.exists(self.output_dir):
-      os.makedirs(self.output_dir)
-    filename = os.path.basename(self.output_dir)
-    self.output_trace = os.path.join(self.output_dir, filename)
-    self.output_finger = os.path.join(self.output_dir, '%s.json' % filename)
-    self.output_id = os.path.join(self.output_dir, '%s.id.json' % filename)
-
-    self.file_trace = open(self.output_trace, 'w')
-    self.file_finger = open(self.output_finger, 'w')
-    self.file_id = open(self.output_id, 'w')
-
-  def _PrintHeader(self):
-    """Prints header lines of json files."""
-    self.file_finger.write(_JSON_HEADER)
-    self.file_id.write(_JSON_HEADER)
-
-  def _PrintTail(self):
-    """Prints tail lines of json files."""
-    self.file_finger.write(_JSON_TAIL)
-    self.file_id.write(_JSON_TAIL)
-
-  def _AssertBadData(self, json_data):
-    """Asserts exception if received data is not as expected."""
-    if len(json_data['data']) != self.device.width * self.device.height:
-      raise CentroidingDataParserError('Mismatched data length')
-    if any(len(contact) != 7 for contact in json_data['contact']):
-      raise CentroidingDataParserError('Mismatched contact length')
-
-  def _IsEmptyHead(self, json_data, line_number):
-    """Checks if current frame is empty for head frame trimming.
-
-    Head frame trimming is used to trim empty frames from the beginning since
-    user may not drop fingers immediately after opening data receiver.
-
-    Frames will be regard empty-headed if there is no finger contact reported
-    and all trace data is below device.data_scale / 4. Once a frame is not
-    empty, all frames afterward will be parsed.
-
-    Args:
-      json_data: Frame data in json format.
-      line_number: Current line number.
-
-    Returns:
-      True if this frame is empty-headed; otherwise False.
-    """
-    if not self.is_head:
-      return False
-    if len(json_data['contact']) > 0:
-      self.is_head = False
-      print '[Parse] Trimmed empty content in the beginning.'
-      print '[Parse] Parse from line %d...' % line_number
-      return False
-    if any(d >= self.head_trim_thres for d in json_data['data']):
-      self.is_head = False
-      print '[Parse] Trimmed empty content in the beginning.'
-      print '[Parse] Parse from line %d...' % line_number
-      return False
-    return True
-
-  def _PrintTrace(self, data):
-    """Prints trace data into trace file.
-
-    For example, device width = 2, height = 3, data = [1, 2, 3, 4, 5, 6]
-    will be printed as 1 2 3
-                       4 5 6
-    """
-    for j in xrange(self.device.width):
-      data_line = data[j * self.device.height: (j + 1) * self.device.height]
-      self.file_trace.write(' '.join(str(d) for d in data_line))
-      self.file_trace.write('\n')
-    self.file_trace.write('\n')
-
-  def _PrintFingerAndId(self, contact):
-    """Prints contact fingers and tracking IDs into files."""
-    track_id = [c.pop() for c in contact]
-    self.file_finger.write('    %s,\n' % str(contact))
-    self.file_id.write('    %s,\n' % str(track_id))
-
-  def _PrintDummyEndFrame(self):
-    """Prints one last dummy frame into files.
-
-    Since json does not accept trailing comma in an array and it is difficult
-    to know the last frame data in file readline loop, printing a dummy frame
-    in the end can solve this issue easily.
-    """
-    for j in xrange(self.device.width):
-      self.file_trace.write(' '.join(['0' for i in xrange(self.device.height)]))
-      if j < self.device.width - 1:
-        self.file_trace.write('\n')
-    self.file_finger.write('    []\n')
-    self.file_id.write('    []\n')
-
-  def _CloseFiles(self):
-    """Closes all file objects."""
-    self.file_trace.close()
-    self.file_finger.close()
-    self.file_id.close()
-
-  def Parse(self):
-    """Starts parsing trace data and finger data into output files."""
-    self._PrintHeader()
-    with open(self.input_file) as f:
-      line_number = 0
-      for line in f:
-        line_number += 1
-        strip_line = line.strip()
-        if len(strip_line) == 0:
-          continue
-        try:
-          json_data = json.loads(strip_line)
-          self._AssertBadData(json_data)
-          if not self._IsEmptyHead(json_data, line_number):
-            self._PrintTrace(json_data['data'])
-            self._PrintFingerAndId(json_data['contact'])
-        except Exception as e:
-          print '[Parse] Invalid data line %d: %s' % (line_number, strip_line)
-          print e
-    self._PrintDummyEndFrame()
-    self._PrintTail()
-    self._CloseFiles()
-    print '[Parse] created trace data:', self.output_trace
-    print '[Parse] created finger json:', self.output_finger
-    print '[Parse] created track id json:', self.output_id
-
-
-def _ParseArguments():
-  """Parses the command line options."""
-  parser = argparse.ArgumentParser(description='Centroiding Main')
-
-  parser.add_argument('-i', '--input_file',
-                      help='the input file path of raw data')
-  parser.add_argument('-c', '--config', help='the config file of device')
-
-  args = parser.parse_args()
-  return args
-
-
-def Main():
-  args = _ParseArguments()
-
-  print 'parsing raw data %s to analytical format...' % args.input_file
-  device = CentroidingDevice(config=args.config)
-  data_parser = CentroidingDataParser(args.input_file, device)
-  data_parser.Parse()
-
-
-if __name__ == '__main__':
-  Main()
diff --git a/webplot/centroiding/centroiding_receiver.py b/webplot/centroiding/centroiding_receiver.py
deleted file mode 100644
index b5311ab..0000000
--- a/webplot/centroiding/centroiding_receiver.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# Copyright 2015 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Centroiding receiver handles centroiding data stream from dut and forwards
-to webplot module for data visualizing.
-"""
-
-import ctypes
-import ctypes.util
-import json
-import os
-import socket
-import time
-from builtins import range
-
-# Pre-load librt.so for MonotonicTime()
-librt_name = ctypes.util.find_library('rt')
-librt = ctypes.cdll.LoadLibrary(librt_name)
-
-
-class TimeSpec(ctypes.Structure):
-  """A representation of struct timespec in C."""
-  _fields_ = [
-      ('tv_sec', ctypes.c_long),
-      ('tv_nsec', ctypes.c_long),
-  ]
-
-
-clock_gettime = librt.clock_gettime
-clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(TimeSpec)]
-
-
-def MonotonicTime():
-  """Gets the raw monotonic time.
-
-  This function opens librt.so with ctypes and call:
-    int clock_gettime(clockid_t clk_id, struct timespec *tp);
-  to get raw monotonic time.
-
-  Returns:
-    The system monotonic time in seconds.
-  """
-  CLOCK_MONOTONIC_RAW = 4
-  t = TimeSpec()
-  if clock_gettime(CLOCK_MONOTONIC_RAW, ctypes.pointer(t)) != 0:
-    errno = ctypes.get_errno()
-    raise OSError(errno, os.strerror(errno))
-  return t.tv_sec + 1e-9 * t.tv_nsec
-
-
-class FPSCounter(object):
-  """The frame counter and frame rate calculator."""
-  def __init__(self, frame_interval=200):
-    """The init method of FPS counter.
-
-    Args:
-      frame_interval: FPS will be calculated and updated every # frames.
-    """
-    self.frame_interval = frame_interval
-    self.fps = 0
-    self.frame_counter = 0
-    self.timestamp = MonotonicTime()
-
-  def GetFPS(self):
-    """Gets current FPS in string."""
-    return '%.4f' % self.fps
-
-  def Count(self):
-    """Counts a new frame."""
-    self.frame_counter += 1
-    if self.frame_counter >= self.frame_interval:
-      self._UpdateFPS()
-      self.frame_counter = 0
-
-  def _UpdateFPS(self):
-    """Updates current FPS."""
-    new_timestamp = MonotonicTime()
-    time_interval = new_timestamp - self.timestamp
-    instant_fps = float(self.frame_counter) / time_interval
-    if self.fps == 0:
-      self.fps = instant_fps
-    else:
-      self.fps = self.fps * 0.9 + instant_fps * 0.1
-    self.timestamp = new_timestamp
-
-
-class CentroidingDataReceiver(object):
-  """The socket receiver of centroiding data."""
-  _CHUNK_BYTE_SIZE = 1024
-  _NULL_CHAR = '\x00'
-
-  def __init__(self, server_address, server_port, webplot,
-               save_data=None, plot_fps=0):
-    """The init method of centroiding TCP client.
-
-    Args:
-      server_address: Address of TCP socket server from testing device.
-      server_port: TCP socket server port.
-      webplot: Webplot object for plotting snapshots.
-      save_data: File name for saving received centroiding data. Set to None to
-                 disable saving data.
-      plot_fps: Target FPS for plotting snapshot. Flow control is managed by
-                server and overflow raw data sockets will be skipped. Set 0 to
-                disable flow control.
-    """
-    self.webplot = webplot
-    self.is_saving = save_data is not None
-    self.save_path = save_data if self.is_saving else '/dev/null'
-
-    self.plot_time_interval = 1.0 / plot_fps if plot_fps else 0
-    self.plot_time_target = 0
-    self.fps_receiver = FPSCounter()
-    self.fps_plot = FPSCounter()
-
-    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    self.sock.connect((server_address, server_port))
-
-  def StartReceive(self):
-    """Starts routine of receiving data and plotting."""
-    try:
-      with open(self.save_path, 'w') as f:
-        chunk_buffer = ''
-        while True:
-          try:
-            chunk = self.sock.recv(self._CHUNK_BYTE_SIZE)
-            chunk_buffer += chunk
-            if self._NULL_CHAR in chunk_buffer:
-              chunk_buffer = self._ExtractSnapshots(chunk_buffer, f)
-          except KeyboardInterrupt:
-            print('Keyboard interrupt accepted!')
-            print('Centroiding receiver is terminated...')
-            print('Webplot server is terminated...')
-            self.sock.close()
-            self.webplot.Quit()
-            break
-    except IOError as e:
-      print('Oops!! something wrong while saving data to %s: %s' % (
-          self.save_path, str(e)))
-      self.sock.close()
-      self.webplot.Quit()
-
-  def _ExtractSnapshots(self, chunk_buffer, save_file):
-    """Extracts snapshot data from received chunk buffer.
-
-    Args:
-      chunk_buffer: Current received chunk string buffer.
-      save_file: File object for saving received data.
-
-    Returns:
-      The residue on chunk buffer after snapshot extraction.
-    """
-    snapshots = chunk_buffer.split(self._NULL_CHAR)
-    for i in range(len(snapshots)):
-      if i == len(snapshots) - 1:
-        return snapshots[i]
-      if len(snapshots[i]) == 0:
-        continue
-      if self.is_saving:
-        save_file.write(snapshots[i] + '\n')
-        save_file.flush()
-      self.fps_receiver.Count()
-      if self._PlotWithFlowControl():
-        self.fps_plot.Count()
-        self._PlotSnapshot(snapshots[i])
-
-  def _PlotWithFlowControl(self):
-    """Determines whether to plot this snapshot with flow control.
-
-    Returns:
-      True to plot this snapshot; False otherwise.
-    """
-    if not self.plot_time_interval:
-      return True
-    current_time = MonotonicTime()
-    if current_time > self.plot_time_target:
-      self.plot_time_target = current_time + self.plot_time_interval
-      return True
-    return False
-
-  def _PlotSnapshot(self, snapshot):
-    """Plots snapshot data to webplot server.
-
-    Args:
-      snapshot: Snapshot data for centroiding in string.
-    """
-    try:
-      snapshot_json = json.loads(snapshot.strip())
-      snapshot_json.update(
-          {"fps": [self.fps_receiver.GetFPS(), self.fps_plot.GetFPS()]})
-      self.webplot.AddSnapshot(snapshot_json)
-    except Exception as e:
-      print('Exception while plotting snapshot = %r:' % snapshot, e)
diff --git a/webplot/centroiding/nexus9.conf b/webplot/centroiding/nexus9.conf
deleted file mode 100644
index 42853a9..0000000
--- a/webplot/centroiding/nexus9.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-### ========================================================= ###
-### Config file for centroiding visualizer device parameters  ###
-### ========================================================= ###
-### device: device name                                       ###
-### data_scale: upper-bound scale of raw heatmap data         ###
-### data_offset: data offset while presenting raw heatmap     ###
-### width: the size of width of raw heatmap                   ###
-### height: the size of height of raw heatmap                 ###
-### ========================================================= ###
-
-device: nexus9
-data_scale: 4000
-data_offset: 500
-width: 28
-height: 38
diff --git a/webplot/centroiding/tango.conf b/webplot/centroiding/tango.conf
deleted file mode 100644
index 307b682..0000000
--- a/webplot/centroiding/tango.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-### ========================================================= ###
-### Config file for centroiding visualizer device parameters  ###
-### ========================================================= ###
-### device: device name                                       ###
-### data_scale: upper-bound scale of raw heatmap data         ###
-### data_offset: data offset while presenting raw heatmap     ###
-### width: the size of width of raw heatmap                   ###
-### height: the size of height of raw heatmap                 ###
-### ========================================================= ###
-
-device: tango
-data_scale: 300
-data_offset: 35
-width: 27
-height: 44
diff --git a/webplot/centroiding_main.py b/webplot/centroiding_main.py
deleted file mode 100644
index b01f4a4..0000000
--- a/webplot/centroiding_main.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright 2015 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Main function for showing centroiding visualizer tool.
-
-It will automatically find the dut connection (via USB cable), build up tunnel,
-and open a webplot server daemon and a socket client. After then You can go and
-check the visualizing demo on the browser.
-
-For different kind of dut, you may setup a config file for parameters of
-visualizer tool.
-
-Example:
-  python centroiding_main.py -s 127.0.0.1 -p 8080 -c device.conf
-
-Server will load centroiding/device.conf as config, and build tunnel with port
-12345. The webplot will be in http://127.0.0.1:8080 on the browser.
-
-Add argument -l to record centroiding data into file.
-
-Note: this program needs to run adb (Android Debug Bridge) inside the chroot,
-please run this command in advance if you do not have adb in your chroot yet.
-  sudo emerge android-tools
-
-"""
-import argparse
-from datetime import datetime
-import os
-import subprocess
-import time
-
-from centroiding import (CentroidingDataParser,
-                         CentroidingDataReceiver,
-                         CentroidingDevice)
-from webplot import Webplot
-
-ADB_GETSTATE_RETRIES = 50
-ADB_FORWARD_RETRIES = 10
-SEPARATION_LINEWIDTH = 70
-
-
-def EstablishADBConnectionTunnel(port):
-  """Builds up tunnel to dut by ADB via connection cable.
-
-  1. Poll device presence by 'adb get-state'. This command will return 'device'
-     once it detects a dut connected.
-
-  2. Make socket connection tunnel by 'adb forward tcp:<port> tcp:<port>'.
-
-  3. Poll until tunnel established by checking 'adb forward --list' result.
-
-  Args:
-    port: port number of tunneling between device and server.
-
-  Returns:
-    Return False if errors happen; otherwise return True.
-  """
-  print('\n' + '-' * SEPARATION_LINEWIDTH)
-
-  # To prevent adb no permissions issue, it needs sudo to start adb server.
-  os.system('sudo adb kill-server')
-  os.system('sudo adb start-server')
-
-  def _GetDeviceOnline():
-    return subprocess.check_output(['adb', 'get-state']).strip() == 'device'
-
-  if not _GetDeviceOnline():
-    print('Currently no device attached!\nPlease attach your testing device...')
-    retry_times = 0
-    while True:
-      time.sleep(0.2)
-      if _GetDeviceOnline():
-        break
-      retry_times += 1
-      if retry_times > ADB_GETSTATE_RETRIES:
-        print('Timeout polling for testing device (%.1f seconds)...' % (
-            0.2 * ADB_GETSTATE_RETRIES))
-        return False
-
-  print('\nDevice is attached.\n')
-  print('Try to build tunnel port %d between device and server...' % port)
-
-  retry_times = 0
-  while True:
-    subprocess.check_call(
-        ['adb', 'forward', 'tcp:%d' % port, 'tcp:%d' % port])
-    time.sleep(0.2)
-    get_port = subprocess.check_output(
-        ['adb', 'forward', '--list']).strip()
-    if 'tcp:%d' % port in get_port:
-      break
-    retry_times += 1
-    if retry_times > ADB_FORWARD_RETRIES:
-      return False
-
-  print('\nTunnel is established successfully.\n')
-  return True
-
-
-def _ParseArguments():
-  """Parses the command line options."""
-  parser = argparse.ArgumentParser(description='Centroiding Main')
-
-  parser.add_argument('-s', '--server_addr', default='127.0.0.1',
-                      help='the address the webplot http server listens to')
-  parser.add_argument('-p', '--server_port', default=8080, type=int,
-                      help='the port the web server listens to (default: 8080)')
-  parser.add_argument('-f', '--dut_forward_port', default=12345, type=int,
-                      help='the forwarding port for centroiding socket server '
-                           '(default: 12345)')
-  parser.add_argument('-c', '--config', default='tango.conf', type=str,
-                      help='config file name of device for centroiding '
-                           'visualizing tool parameters.')
-  parser.add_argument('-l', '--log_data', action='store_true',
-                      help='log centroiding data and save to file in /tmp/.')
-  parser.add_argument('--fps', default=0, type=int,
-                      help='the target frame rate of visualizer plotting, set '
-                           '0 for keeping same as centroiding processing frame '
-                           'rate.')
-
-  args = parser.parse_args()
-  return args
-
-
-def Main():
-  args = _ParseArguments()
-
-  print('\n' + '-' * SEPARATION_LINEWIDTH + '\n')
-  print('**** Centroiding Data Visualizing Tool ****')
-  print('webplot server address:', args.server_addr)
-  print('webplot server port:', args.server_port)
-
-  print('\n' + '-' * SEPARATION_LINEWIDTH + '\n')
-  print('dut socket forwarding port:', args.dut_forward_port)
-  print('  (this port will be tunneled between dut and server)\n')
-  print('dut config file:', args.config)
-
-  device = CentroidingDevice(config=args.config)
-
-  print('  - device name:', device.device)
-  print('  - data_scale:', device.data_scale)
-  print('  - data_offset:', device.data_offset)
-  print('  - width:', device.width)
-  print('  - height:', device.height)
-
-  if not EstablishADBConnectionTunnel(args.dut_forward_port):
-    print('Connection to device failed. Task is aborted...')
-    return
-
-  print('\n' + '-' * SEPARATION_LINEWIDTH + '\n')
-  print('webplot server has started...')
-  print('port %d is listening on sockets from dut...' % args.dut_forward_port)
-  print(('check http://%s:%d on browser of your device to view the plot...\n' %
-      (args.server_addr, args.server_port)))
-
-  if args.log_data:
-    time_now = datetime.now().strftime('%Y%m%d%H%M%S')
-    save_data = os.path.join('/tmp', '%s_%s.dat' % (device.device, time_now))
-  else:
-    save_data = None
-
-  # Instantiate a webplot server daemon and start it.
-  plot_server = Webplot(args.server_addr, args.server_port, device,
-                        logging=True, is_behind_iptables_firewall=False,
-                        is_centroiding=True)
-  plot_server.start()
-
-  receiver = CentroidingDataReceiver(
-      '127.0.0.1', args.dut_forward_port, plot_server,
-      save_data=save_data, plot_fps=args.fps)
-  receiver.StartReceive()
-
-  if args.log_data:
-    print('\ncentroiding raw data are saved into file %s\n' % save_data)
-    print('parsing saved raw data to analytical format...')
-    data_parser = CentroidingDataParser(save_data, device)
-    data_parser.Parse()
-    print('parse finished...')
-
-
-if __name__ == '__main__':
-  Main()
-
diff --git a/webplot/webplot.py b/webplot/webplot.py
index 3fc8de2..57eeeac 100755
--- a/webplot/webplot.py
+++ b/webplot/webplot.py
@@ -297,45 +297,6 @@
     state.IncCount()
 
 
-class CentroidingRoot(object):
-  """A class to handle requests about docroot."""
-
-  def __init__(self, ip, port, data_scale, data_offset,
-               data_width, data_height):
-    self.ip = ip
-    self.port = port
-    self.data_scale = data_scale
-    self.data_offset = data_offset
-    self.data_width = data_width
-    self.data_height = data_height
-    self.scheme = 'ws'
-    cherrypy.log('Root address: (%s, %s)' % (ip, str(port)))
-    cherrypy.log('scheme: %s' % self.scheme)
-
-  @cherrypy.expose
-  def index(self):
-    """This is the default index.html page."""
-    websocket_dict = {
-      'websocketUrl': '%s://%s:%s/ws' % (self.scheme, self.ip, self.port),
-      'dataScale': str(self.data_scale),
-      'dataOffset': str(self.data_offset),
-      'dataWidth': str(self.data_width),
-      'dataHeight': str(self.data_height),
-    }
-    print(websocket_dict)
-    root_page = os.path.join(os.path.abspath(os.path.dirname(__file__)),
-                             'centroiding.html')
-    with open(root_page) as f:
-      return f.read() % websocket_dict
-
-  @cherrypy.expose
-  def ws(self):
-    """This handles the request to create a new web socket per client."""
-    cherrypy.log('A new client requesting for WS')
-    cherrypy.log('WS handler created: %s' % repr(cherrypy.request.ws_handler))
-    state.IncCount()
-
-
 class Webplot(threading.Thread):
   """The server handling the Plotting of finger traces.
 
@@ -375,13 +336,11 @@
   """
 
   def __init__(self, server_addr, server_port, device, saved_file=SAVED_FILE,
-               logging=False, is_behind_iptables_firewall=False,
-               is_centroiding=False):
+               logging=False, is_behind_iptables_firewall=False):
     self._server_addr = server_addr
     self._server_port = server_port
     self._device = device
     self._saved_file = saved_file
-    self._is_centroiding = is_centroiding
     super(Webplot, self).__init__(name='webplot thread')
 
     self.daemon = True
@@ -414,37 +373,25 @@
     # If the cherrypy server exits for whatever reason, close the device
     # for required cleanup. Otherwise, there might exist local/remote
     # zombie processes.
-    if not self._is_centroiding:
-      cherrypy.engine.subscribe('exit',  self._device.__del__)
+    cherrypy.engine.subscribe('exit',  self._device.__del__)
 
     cherrypy.engine.signal_handler.handlers['SIGINT'] = InterruptHandler
     cherrypy.engine.signal_handler.handlers['SIGTERM'] = InterruptHandler
 
   def run(self):
     """Start the cherrypy engine."""
-    if not self._is_centroiding:
-      x_min, x_max = self._device.RangeX()
-      y_min, y_max = self._device.RangeY()
-      p_min, p_max = self._device.RangeP()
-      tilt_x_min, tilt_x_max = self._device.RangeTiltX()
-      tilt_y_min, tilt_y_max = self._device.RangeTiltY()
-      major_min, major_max = self._device.RangeMajor()
-      minor_min, minor_max = self._device.RangeMinor()
+    x_min, x_max = self._device.RangeX()
+    y_min, y_max = self._device.RangeY()
+    p_min, p_max = self._device.RangeP()
+    tilt_x_min, tilt_x_max = self._device.RangeTiltX()
+    tilt_y_min, tilt_y_max = self._device.RangeTiltY()
+    major_min, major_max = self._device.RangeMajor()
+    minor_min, minor_max = self._device.RangeMinor()
 
-      root = TouchRoot(self._server_addr, self._server_port,
-                       x_min, x_max, y_min, y_max, p_min, p_max, tilt_x_min,
-                       tilt_x_max, tilt_y_min, tilt_y_max,
-                       major_min, major_max, minor_min, minor_max,)
-    else:
-      data_scale = self._device.data_scale
-      data_offset = self._device.data_offset
-      data_width = self._device.width
-      data_height = self._device.height
-      tilt_x_min, tilt_x_max = self._device.RangeTiltX()
-      tilt_y_min, tilt_y_max = self._device.RangeTiltY()
-      root = CentroidingRoot(self._server_addr, self._server_port,
-                             data_scale, data_offset, data_width, data_height,
-                             tilt_x_min, tilt_x_max, tilt_y_min, tilt_y_max)
+    root = TouchRoot(self._server_addr, self._server_port,
+                     x_min, x_max, y_min, y_max, p_min, p_max, tilt_x_min,
+                     tilt_x_max, tilt_y_min, tilt_y_max,
+                     major_min, major_max, minor_min, minor_max,)
 
     cherrypy.quickstart(
         root,
@@ -513,8 +460,7 @@
 
   def AddSnapshot(self, snapshot):
     """Convert the snapshot to a proper format and publish it to clients."""
-    if not self._is_centroiding:
-      snapshot = self._ConvertNamedtupleToDict(snapshot)
+    snapshot = self._ConvertNamedtupleToDict(snapshot)
     cherrypy.engine.publish('websocket-broadcast', json.dumps(snapshot))
     return snapshot
 
@@ -615,7 +561,7 @@
   parser.add_argument('-s', '--server_addr', default='0.0.0.0',
                       help='the address the webplot http server listens to')
   parser.add_argument('-t', '--dut_type', default='chromeos', type=str.lower,
-                      help='dut type: chromeos, android, centroiding')
+                      help='dut type: chromeos, android')
   parser.add_argument('--automatically_start_browser', action='store_true',
                       help=('When this flag is set the script will try to '
                             'start a web browser automatically once webplot '
@@ -625,19 +571,6 @@
                       help=('Which protocol does the device use? Choose from '
                             'auto, MTB, MTA, or stylus'))
 
-  # Arguments especial for centroiding visualizing tool.
-  # Please set "--dut_type centroiding" for centroiding utility.
-  parser.add_argument('-f', '--dut_forward_port', default=12345, type=int,
-                      help='the forwarding port for centroiding socket server '
-                           '(default: 12345) (only needed for centroiding)')
-  parser.add_argument('-c', '--config', default='tango.conf', type=str,
-                      help='Config file name of device for centroiding '
-                           'visualizing tool parameters.')
-  parser.add_argument('--fps', default=0, type=int,
-                      help='the target frame rate of visualizer plotting, set '
-                           '0 for keeping same as centroiding processing frame '
-                           'rate.')
-
   args = parser.parse_args()
 
   args.grab = not args.nograb
@@ -652,20 +585,11 @@
   configure_logger(level=logging.ERROR)
   args = _ParseArguments()
 
-  # Specify Webplot for centroiding purpose.
-  is_centroiding = args.dut_type == 'centroiding'
-
   print('\n' + '-' * 70)
-  if is_centroiding:
-    cherrypy.log('**** Centroiding Data Visualizing Tool ****')
-    cherrypy.log('dut config file: %s' % args.config)
-    cherrypy.log('dut address: %s' % args.dut_addr)
-    cherrypy.log('dut socket forwarding port: %d' % args.dut_forward_port)
-  else:
-    cherrypy.log('dut machine type: %s' % args.dut_type)
-    cherrypy.log('dut\'s touch device: %s' %
+  cherrypy.log('dut machine type: %s' % args.dut_type)
+  cherrypy.log('dut\'s touch device: %s' %
                  ('touchscreen' if args.is_touchscreen else 'touchpad'))
-    cherrypy.log('dut address: %s' % args.dut_addr)
+  cherrypy.log('dut address: %s' % args.dut_addr)
   cherrypy.log('web server address: %s' % args.server_addr)
   cherrypy.log('web server port: %s' % args.server_port)
   cherrypy.log('grab the touch device: %s' % args.grab)
@@ -698,18 +622,13 @@
                                  protocol=args.protocol)
   elif args.dut_type == 'android':
     device = AndroidTouchDevice(args.dut_addr, True, protocol=args.protocol)
-  elif is_centroiding:  # args.dut_type == 'centroiding'
-    # Import centroiding library conditionally to avoid missing dependency.
-    from centroiding import CentroidingDataReceiver, CentroidingDevice
-    device = CentroidingDevice(args.config)
   else:
     print('Unrecognized dut_type: %s. Webplot is aborted...' % args.dut_type)
     exit(1)
 
   # Instantiate a webplot server daemon and start it.
   webplot = Webplot(args.server_addr, args.server_port, device, logging=True,
-                    is_behind_iptables_firewall=args.behind_firewall,
-                    is_centroiding=is_centroiding)
+                    is_behind_iptables_firewall=args.behind_firewall)
   webplot.start()
 
   if args.automatically_start_browser:
@@ -722,13 +641,8 @@
       print('Please navigate to "%s" in a browser manually, instead' % url)
       print('!' * 80)
 
-  if not is_centroiding:
-    # Get touch snapshots from the touch device and have clients plot them.
-    webplot.GetAndPlotSnapshots()
-  else:
-    receiver = CentroidingDataReceiver(
-        '127.0.0.1', args.dut_forward_port, webplot, plot_fps=args.fps)
-    receiver.StartReceive()
+  # Get touch snapshots from the touch device and have clients plot them.
+  webplot.GetAndPlotSnapshots()
 
 
 if __name__ == '__main__':