<commit_before>var React  = require('react'),
  Router   = require('react-router'),
  config   = require('../common/config'),
  core     = require('../common/core'),
  datatype = null,
  infotype = config.settings.infotype,
  TileCoordinates = require('./TileCoordinates.react'),
  SparseVolViewer = require('./SparseVolViewer.react'),
  slice1    = 'xy',
  slice2    = 'xz',
  slice3    = 'yz',
  viewer   = null;
  img_helper = null;

var TileMapArea = React.createClass({
  mixins: [ Router.Navigation ],

  getInitialState: function() {
    return {
      x: 0,
      y: 0,
      z: 0,
      layer: 0,
      volumeViewer: false,
      plane: undefined,
      segmentation: false,
      // this is initially set to true, so that we will update the location
      // of the tile viewer window on page load, but then not again after that.
      // The aim is to prevent a feedback loop where the url updates the
      // image location which in turn updates the url, which updates the image location....
      url_update: true,
      //for use by the sprsevolume viewer child.
      click_x: null,
      click_y: null,
      click_z: null,
      click_axis: null,
      click_label: null,
    };
  },

  componentDidMount: function() {
  },

  componentWillReceiveProps: function (props) {
    var self = this;
    var dataIsTiled = false;

    if (viewer && viewer.xy) {
      if (props.coordinateString && self.state.url_update) {
        var coordinates = props.coordinateString.split('_');
        var dataPoint = new OpenSeadragon.Point(parseInt(coordinates[0]),parseInt(coordinates[1]));
        var logicalPoint = img_helper.dataToLogicalPoint(dataPoint);
        img_helper.centerAboutLogicalPoint(logicalPoint, true);
        self.setState({layer: coordinates[2]});
        self.handleLayerChange(coordinates[2]);
      }
      return;
    }

    datatype = this.props.tileSource;

    if (props.instances && props.instances.hasOwnProperty(datatype)) {
      var node = this.getDOMNode();
      var uuid = this.props.uuid;
      config.uuid = uuid;
      // set the variables for the tile viewer based on data fetched from the server
      var url = config.baseUrl();
      var startingTileSource = 0;


      //check if we are using tiles or grayscale
      if (props.instances[datatype].Base.TypeName === "multiscale2d") {
        dataIsTiled = true;
      }

      // check if we have a plane in the url and modify the display accordingly.
      if (props.plane) {
        var tileSourceMapping = {
          'xy': 0,
          'xz': 1,
          'yz': 2
        };
        startingTileSource = tileSourceMapping[props.plane];
        self.setState({plane: startingTileSource});
      }

      $.when($.ajax(config.datatypeInfoUrl(uuid, datatype)), $.ajax(config.datatypeInfoUrl(uuid, infotype)))
        .done(function(tileRequest, grayscaleRequest) {
          var tileData = tileRequest[0],
            gScaleData = grayscaleRequest[0],
            maxPoint   = gScaleData.Extended.MaxPoint,
            minPoint   = gScaleData.Extended.MinPoint,
            dx        = maxPoint[0] - minPoint[0],
            dy        = maxPoint[1] - minPoint[1],
            dz        = maxPoint[2] - minPoint[2];

          // set a default level of one unless we actually have tiling information
          var maxLevel = config.settings.maxTileLevel;
          if (tileData.Extended && tileData.Extended.Levels) {
            maxLevel = Object.keys(tileData.Extended.Levels).length - 1;
          }

          var minLevel = config.settings.minTileLevel;

          if (!dataIsTiled) {
            minLevel = 4;
            maxLevel = 4;
          }

          // this works out the size of the image based on the number of tiles required
          // to cover the complete image at the largest level.
          //
          //Notes from Bill.
          //
          //Say we have 500x500 tiles but our real volume size is 6133 x 7000 x 8000.
          //In order to cover the real volume size, we have 5 scales.
          //
          //Scale 0 = no downres, so we have 6133/500 = 13 tiles along X to cover real X extent.
          //Scale 1 = 2x, so we have 3067/500 = 7 tiles along X to cover the downres X extent
          //Scale 2 = 4x, it’s now 1534/500 = 4 tiles
          //Scale 3 = 8x, it’s now 717/500 = 2 tiles
          //Scale 4 = 16x, one tile
          //
          //But this means to OpenSeadragon, the “tiled” X extent is really 500 x 16 = 8000 voxels.
          //This will lead to a lot of empty padding at end of x, y, and z, but shouldn’t affect
          //your offsets I believe.
          //

          var maxDimensions = 512 * Math.pow(2, maxLevel);

          var volumeWidth = {
            'xy': dx,
            'xz': dx,
            'yz': dy,
          };

          var volumeHeight = {
            'xy':  dy,
            'xz':  dz,
            'yz':  dz
          };

          var volumeDepth = {
            'xy':  dz,
            'xz':  dy,
            'yz':  dx
          };

          $('#stack-slider').attr('max', dz).change(function() {
            $('#depth').val($(this).val());
          });

          $('#depth').attr('max', dz);

          var tileSize = 512;
          if (tileData.Extended && tileData.Extended.Levels) {
            tileSize = tileData.Extended.Levels[0].TileSize[0];
          }

          viewer = {
            nmPerPixel: 10,
            tileSources: [
            {
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  minLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice1]-1,
              getTileUrl: function xyTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + datatype + "/raw/" + slice1 + "/512_512/" + (x * 512) + "_" + (y * 512) + "_" + z + "/jpg:80";
                if (dataIsTiled) {
                   api_url = config.tileFetchUrl(uuid, maxLevel - level, slice1, x, y, z);
                }
                return api_url;
              }
            },
            {
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  minLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice2]-1,
              getTileUrl: function xzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + datatype + "/raw/" + slice2 + "/512_512/" + (x * 512) + "_" + z + "_" + (y * 512) + "/jpg:80";
                if (dataIsTiled) {
                  api_url = config.tileFetchUrl(uuid, maxLevel - level, slice2, x, z, y);
                }
                return api_url;
              }
            },
            {
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  minLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice3]-1,
              getTileUrl: function yzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + datatype + "/raw/" + slice3 + "/512_512/" + z + "_" + (x * 512) + "_" + (y * 512) + "/jpg:80";
                if (dataIsTiled) {
                  api_url = config.tileFetchUrl(uuid, maxLevel - level, slice3, z, x, y);
                }
                return api_url;
              }
            },
            // composite for xy plane
            {
              virtualMode: 'segmentation',
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  maxLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice1]-1,
              getTileUrl: function xyTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + config.settings.bodyType + "/raw/0_1_2/512_512_1/" + (x * 512) + "_" + (y * 512) + "_" + z;
                return api_url;
              }
            },
            {
              virtualMode: 'segmentation',
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  maxLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice2]-1,
              getTileUrl: function xzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + config.settings.bodyType + "/raw/0_1_2/512_1_512/" + (x * 512) + "_" + z + "_" + (y * 512);
                return api_url;
              }
            },
            {
              virtualMode: 'segmentation',
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  maxLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice3]-1,
              getTileUrl: function yzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + config.settings.bodyType + "/raw/0_1_2/1_512_512/" + z + "_" + (x * 512) + "_" + (y * 512);
                return api_url;
              }
            },
            ]
          };

          var minZoomLevel = config.settings.minZoomLevel;
          var defaultZoomLevel = config.settings.defaultZoomLevel;

          if (!dataIsTiled) {
            minZoomLevel = 6;
            defaultZoomLevel = 6;
          }

          viewer.xy = OpenSeadragon({
            // need to be able to pass in the react state, so that we can modify it
            // when using the other buttons to change z layer.
            id:                 "viewer",
            prefixUrl:          "js/vendor/openseadragon/images/",
            navigatorSizeRatio: 0.25,
            wrapHorizontal:     false,
            maxZoomPixelRatio:  1.8,
            showNavigator:      config.settings.showNavigator,
            tileSources:        viewer.tileSources,
            //zoomPerClick:       1.0,
            toolbar:            "toolbar",<commit_msg>Adds dynamic choice of segmentation source<commit_after>var React  = require('react'),
  Router   = require('react-router'),
  config   = require('../common/config'),
  core     = require('../common/core'),
  datatype = null,
  infotype = config.settings.infotype,
  labeltype = null,
  TileCoordinates = require('./TileCoordinates.react'),
  SparseVolViewer = require('./SparseVolViewer.react'),
  slice1    = 'xy',
  slice2    = 'xz',
  slice3    = 'yz',
  viewer   = null;
  img_helper = null;

var TileMapArea = React.createClass({
  mixins: [ Router.Navigation ],

  getInitialState: function() {
    return {
      x: 0,
      y: 0,
      z: 0,
      layer: 0,
      volumeViewer: false,
      plane: undefined,
      segmentation: false,
      // this is initially set to true, so that we will update the location
      // of the tile viewer window on page load, but then not again after that.
      // The aim is to prevent a feedback loop where the url updates the
      // image location which in turn updates the url, which updates the image location....
      url_update: true,
      //for use by the sprsevolume viewer child.
      click_x: null,
      click_y: null,
      click_z: null,
      click_axis: null,
      click_label: null,
    };
  },

  componentDidMount: function() {
  },

  componentWillReceiveProps: function (props) {
    var self = this;
    var dataIsTiled = false;

    if (viewer && viewer.xy) {
      if (props.coordinateString && self.state.url_update) {
        var coordinates = props.coordinateString.split('_');
        var dataPoint = new OpenSeadragon.Point(parseInt(coordinates[0]),parseInt(coordinates[1]));
        var logicalPoint = img_helper.dataToLogicalPoint(dataPoint);
        img_helper.centerAboutLogicalPoint(logicalPoint, true);
        self.setState({layer: coordinates[2]});
        self.handleLayerChange(coordinates[2]);
      }
      return;
    }

    datatype = this.props.tileSource;
    labeltype = this.props.labelSource;

    if (props.instances && props.instances.hasOwnProperty(datatype)) {
      var node = this.getDOMNode();
      var uuid = this.props.uuid;
      config.uuid = uuid;
      // set the variables for the tile viewer based on data fetched from the server
      var url = config.baseUrl();
      var startingTileSource = 0;


      //check if we are using tiles or grayscale
      if (props.instances[datatype].Base.TypeName === "multiscale2d") {
        dataIsTiled = true;
      }

      // check if we have a plane in the url and modify the display accordingly.
      if (props.plane) {
        var tileSourceMapping = {
          'xy': 0,
          'xz': 1,
          'yz': 2
        };
        startingTileSource = tileSourceMapping[props.plane];
        self.setState({plane: startingTileSource});
      }

      $.when($.ajax(config.datatypeInfoUrl(uuid, datatype)), $.ajax(config.datatypeInfoUrl(uuid, infotype)))
        .done(function(tileRequest, grayscaleRequest) {
          var tileData = tileRequest[0],
            gScaleData = grayscaleRequest[0],
            maxPoint   = gScaleData.Extended.MaxPoint,
            minPoint   = gScaleData.Extended.MinPoint,
            dx        = maxPoint[0] - minPoint[0],
            dy        = maxPoint[1] - minPoint[1],
            dz        = maxPoint[2] - minPoint[2];

          // set a default level of one unless we actually have tiling information
          var maxLevel = config.settings.maxTileLevel;
          if (tileData.Extended && tileData.Extended.Levels) {
            maxLevel = Object.keys(tileData.Extended.Levels).length - 1;
          }

          var minLevel = config.settings.minTileLevel;

          if (!dataIsTiled) {
            minLevel = 4;
            maxLevel = 4;
          }

          // this works out the size of the image based on the number of tiles required
          // to cover the complete image at the largest level.
          //
          //Notes from Bill.
          //
          //Say we have 500x500 tiles but our real volume size is 6133 x 7000 x 8000.
          //In order to cover the real volume size, we have 5 scales.
          //
          //Scale 0 = no downres, so we have 6133/500 = 13 tiles along X to cover real X extent.
          //Scale 1 = 2x, so we have 3067/500 = 7 tiles along X to cover the downres X extent
          //Scale 2 = 4x, it’s now 1534/500 = 4 tiles
          //Scale 3 = 8x, it’s now 717/500 = 2 tiles
          //Scale 4 = 16x, one tile
          //
          //But this means to OpenSeadragon, the “tiled” X extent is really 500 x 16 = 8000 voxels.
          //This will lead to a lot of empty padding at end of x, y, and z, but shouldn’t affect
          //your offsets I believe.
          //

          var maxDimensions = 512 * Math.pow(2, maxLevel);

          var volumeWidth = {
            'xy': dx,
            'xz': dx,
            'yz': dy,
          };

          var volumeHeight = {
            'xy':  dy,
            'xz':  dz,
            'yz':  dz
          };

          var volumeDepth = {
            'xy':  dz,
            'xz':  dy,
            'yz':  dx
          };

          $('#stack-slider').attr('max', dz).change(function() {
            $('#depth').val($(this).val());
          });

          $('#depth').attr('max', dz);

          var tileSize = 512;
          if (tileData.Extended && tileData.Extended.Levels) {
            tileSize = tileData.Extended.Levels[0].TileSize[0];
          }

          viewer = {
            nmPerPixel: 10,
            tileSources: [
            {
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  minLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice1]-1,
              getTileUrl: function xyTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + datatype + "/raw/" + slice1 + "/512_512/" + (x * 512) + "_" + (y * 512) + "_" + z + "/jpg:80";
                if (dataIsTiled) {
                   api_url = config.tileFetchUrl(uuid, maxLevel - level, slice1, x, y, z);
                }
                return api_url;
              }
            },
            {
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  minLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice2]-1,
              getTileUrl: function xzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + datatype + "/raw/" + slice2 + "/512_512/" + (x * 512) + "_" + z + "_" + (y * 512) + "/jpg:80";
                if (dataIsTiled) {
                  api_url = config.tileFetchUrl(uuid, maxLevel - level, slice2, x, z, y);
                }
                return api_url;
              }
            },
            {
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  minLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice3]-1,
              getTileUrl: function yzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + datatype + "/raw/" + slice3 + "/512_512/" + z + "_" + (x * 512) + "_" + (y * 512) + "/jpg:80";
                if (dataIsTiled) {
                  api_url = config.tileFetchUrl(uuid, maxLevel - level, slice3, z, x, y);
                }
                return api_url;
              }
            },
            // composite for xy plane
            {
              virtualMode: 'segmentation',
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  maxLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice1]-1,
              getTileUrl: function xyTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + labeltype + "/raw/0_1_2/512_512_1/" + (x * 512) + "_" + (y * 512) + "_" + z;
                return api_url;
              }
            },
            {
              virtualMode: 'segmentation',
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  maxLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice2]-1,
              getTileUrl: function xzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + labeltype + "/raw/0_1_2/512_1_512/" + (x * 512) + "_" + z + "_" + (y * 512);
                return api_url;
              }
            },
            {
              virtualMode: 'segmentation',
              height:    maxDimensions,
              width:     maxDimensions,
              tileSize:  tileSize,
              minLevel:  maxLevel,
              maxLevel:  maxLevel,
              minZ:      0,
              maxZ:      volumeDepth[slice3]-1,
              getTileUrl: function yzTileURL(level, x, y, z) {
                var api_url = url + "/api/node/" + uuid + "/" + labeltype + "/raw/0_1_2/1_512_512/" + z + "_" + (x * 512) + "_" + (y * 512);
                return api_url;
              }
            },
            ]
          };

          var minZoomLevel = config.settings.minZoomLevel;
          var defaultZoomLevel = config.settings.defaultZoomLevel;

          if (!dataIsTiled) {
            minZoomLevel = 6;
            defaultZoomLevel = 6;
          }

          viewer.xy = OpenSeadragon({
            // need to be able to pass in the react state, so that we can modify it
            // when using the other buttons to change z layer.
            id:                 "viewer",
            prefixUrl:          "js/vendor/openseadragon/images/",
            navigatorSizeRatio: 0.25,
            wrapHorizontal:     false,
            maxZoomPixelRatio:  1.8,
            showNavigator:      config.settings.showNavigator,
            tileSources:        viewer.tileSources,
            //zoomPerClick:       1.0,
            toolbar:            "toolbar",
{'fraction_non_alphanumeric': 0.1123868833317116, 'fraction_numerical': 0.02247737666634232, 'mean_word_length': 1.4723358191003126, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '960308', 'n_tokens_mistral': 6323, 'n_tokens_neox': 5879, 'n_words': 1582}