Skip to content
Snippets Groups Projects
LoadFile.ts 34.9 KiB
Newer Older
//dichiarazione interfacce e variabili globali
interface coordinates{
  xp: number;
  yp: number;
Laura Cappelli's avatar
Laura Cappelli committed
}
var a: number = 3.36275; //costante moltiplicativa per la calibrazione
var b: number = 58.2353; //costante additiva per la calibrazione
var pixelDim: number; //dimensione dei pixel responsive
var maxAbsolute: number; //massimo conteggio della matrice nOfCounts
var globalxMinRange: number = 0, globalxMaxRange: number = 55;
var xDim: number = 0, yDim: number = 0; //numero di pixel nelle due dimensioni
var DataMatrix: number[][][], nOfCounts: number[][]; //matrici con i dati
Laura Cappelli's avatar
Laura Cappelli committed
var rePrint: boolean = false; //variabile per ricolorare con il max relativo
var newOrigin: coordinates; //nuovo origine nel caso di zoom
var zPixel1: coordinates = {xp: 0, yp: 0}; //pixel1 dello zoom
var zPixel2: coordinates = {xp: 0, yp: 0}; //pixel2 dello zoom
var dataCompleteChart: string = "Channel,Counts\n";
var dataCompleteChartCalibrated: string = "Energy,Counts\n";
var calibrated: boolean = false; //variabile per il controllo sulla calibrazione

//INIZIO DELLO SCRIPT
$(document).ready( function() {

  //creazione dell'albero e gestione barre laterali
  setImportFile();
  compressingSidenavSettings();
  compressingSidenavFS();

  //abilitazione drag&drop
  var droppableArea: any = document.querySelector('.droppable');
  makeDroppable(droppableArea, callback);

  login();

}); 

//funzione che definisce tutti gli elementi responsabili dell'apertura di un file.
//Sono definiti quindi l'albero e il bottone per l'importazione da locale
function setImportFile(){

  //Leggo il contenuto del file json e ne eseguo il parse
  var contentfilesystem: any = document.getElementById('contentfilesystem').innerHTML;
  var jsonObject: any = JSON.parse(contentfilesystem);

  alert(jsonObject[0].name);

  //ora genero l'albero e definisco l'evento in caso di selezione di un nodo
  // $('#FileTreeview').treeview({data: generateTree(xmlDoc)});
  // $('#FileTreeview').on('nodeSelected', function(e, node){
  //   if(node['url'] != undefined){
  //     openFileFromServer(node['url']);
  //   }
  // });

  //bottone per l'importazione locale
  var fileInputButton: any = document.getElementById('myImport'); 
  fileInputButton.onchange = function(){
    var fileName: string = fileInputButton.files[0];
    var readerObject: any = new FileReader();
    readerObject.readAsBinaryString(fileName);  
    readerObject.onload = function() {
      var fileString: string = readerObject.result; 
      readData(fileString);
    }
  }


//funzione che genera automaticamente l'albero
function generateTree(xmlDoc){
  var first: boolean = true;
  var oldFolderParent: string = "";
  var oldFolder: string = "";

  //inizio leggendo tutti gli elementi da inserire nell'albero (caratterizzati
  //dall'avere un url di riferimento)
  var entry: string[] = xmlDoc.getElementsByTagName("d:href");
  
  //per ogni elemento controllo se si tratta di una cartella o di un documento
  for (var i:number = 0; i < entry.length; i++) {
    var path: string[] = entry[i].childNodes[0].nodeValue.split("");
    
    //cartella, creo l'oggetto corrsipondente
    if (path[path.length-1] == "/") { 
      var folderName: string[] = entry[i].childNodes[0].nodeValue.split("/");
      var Folder = {
        text: folderName[folderName.length-2],
        nodes: []
      }

      //posiziono la radice del file system, ne memorizzo il path e il padre
      if (first) {
        tree.push(Folder);
        first=false;
        oldFolder = entry[i].childNodes[0].nodeValue;
        oldFolderParent =
          oldFolder.slice(0, oldFolder.lastIndexOf(folderName[folderName.length-2]));
        
      //per ogni cartella determino la relazione con la cartella precedente  
      } else {
        var newFolder: string = entry[i].childNodes[0].nodeValue;
        var newFolderParent: string =
          newFolder.slice(0, newFolder.lastIndexOf(folderName[folderName.length-2]));
        //cartella sorella con quella memorizzata
        if(newFolderParent == oldFolderParent){ 
          oldFolder = newFolder;
          insertOBJinFS(Folder, tree, folderName, 0);
        //cartella figlia di quella memorizzata 
        } else if(newFolderParent == oldFolder){ 
          oldFolder = newFolder;
          oldFolderParent = newFolderParent;
          insertOBJinFS(Folder, tree, folderName, 0);
        //nessuno dei casi precedenti
        } else { 
          //arretro nell'albero fino a trovare lo stesso padre. Per fare questo
          //tolgo al padre memorizzato in precedenza prima "/" poi il nome dell'
          //ultima cartella
          while(newFolderParent != oldFolderParent){
            oldFolderParent = oldFolderParent.slice(0, oldFolderParent.length-1);
            oldFolderParent = oldFolderParent.slice(0, (oldFolderParent.lastIndexOf("/")+1));
          }
          oldFolder = newFolder;
          insertOBJinFS(Folder, tree, folderName, 0);
        }
      }

    //documento, creo l'oggetto corrispondente e lo inserisco nell'albero
    } else {
      var fileName: string[] = entry[i].childNodes[0].nodeValue.split("/");
      var filePath: string =
        "https://oc-chnet.cr.cnaf.infn.it:8443"
        + entry[i].childNodes[0].nodeValue;
      var File = {
        text: fileName[fileName.length-1],
        icon: "glyphicon glyphicon-file",
        selectedIcon: "glyphicon glyphicon-file",
        url: filePath
      }
      insertOBJinFS(File, tree, fileName, 1);
    }
  }
  return tree;
//funzione che posiziona l'oggetto passato in input nell'albero
function insertOBJinFS(objfs, tree, objfsName, type){

  //determino la profondità dell'oggetto (se è un file devo aggiungere 1 a causa si "/")
  var depth: number = objfsName.length;
  if(type) depth++;

  //in base alla profondità determino a quale oggetto agganciare quello in input
  var treePosition: any;
  switch(depth){
    case 8: treePosition = tree; break;
    case 9: treePosition = tree[tree.length-1].nodes; break;
    case 10: treePosition =
      tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes; break;
    case 11: treePosition = 
      tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes.length-1].nodes;
    case 12: treePosition = 
      tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes[tree[tree.length-1].nodes[tree[tree.length-1].nodes.length-1].nodes.length-1].nodes.length-1].nodes;
    break;
    default: break;
  }
  treePosition[treePosition.length-1].nodes.push(objfs);
Laura Cappelli's avatar
Laura Cappelli committed

//funzione che dato l'url di un file, lo apre e lo legge passandone il contenuto
//alla funzione readData(). Questa funzione è invocata quando viene selezionato
//un file dall'albero
function openFileFromServer(url){
  var fileName: string[] = url.split("/");
  console.log("Try to open " + fileName[fileName.length-1] + " ...");
  var txtFile: any = new XMLHttpRequest();
  txtFile.open("GET", url, true);
  txtFile.onreadystatechange = function(){
    if(txtFile.readyState === 4){
      if(txtFile.status === 200){
        if(url != "oc-chnet.cr.cnaf.infn.it:8443/owncloud/remote.php/webdav/Documents/log.txt" ){
          readData((txtFile.responseText));
        }
      }
  txtFile.send(null);    

}

//funzione per la compressione della sidenav dx
function compressingSidenavSettings(){

  var setLabel: any = $('.btn-settings');
  var isClosedSettings: boolean = false;
  setLabel.click(function () { setLabel_cross(); });

  function setLabel_cross() {
    if (isClosedSettings == true) {
      isClosedSettings = false;
      $('#mySidenavSet').css('width', "0");
      $('#wrapper').css('marginRight', "0");
      $('#setbtn').css('marginRight', "-2px");
    } else {
      isClosedSettings = true;
      $('#mySidenavSet').css('width', "250px");
      $('#wrapper').css('marginRight', "250px");
      $('#setbtn').css('marginRight', "248px");
}

//funzione per la compressione della sidenav sx
function compressingSidenavFS(){

  var fsLabel: any = $('.fs-label');
  var isClosedfs: boolean = false;
  fsLabel.click(function () { fsLabel_cross(); });

  function fsLabel_cross() {
    if (isClosedfs == true) {
      isClosedfs = false;
      fsLabel.removeClass('is-open');
      fsLabel.addClass('is-closed');
      $('#mySidenavfs').css('width', "0");
      $('#wrapper').css('marginLeft', "0");
      $('#fsbtn').css('marginLeft', "-2px");
    } else {
      isClosedfs = true;
      fsLabel.removeClass('is-closed');
      fsLabel.addClass('is-open');
      $('#mySidenavfs').css('width', "250px");
      $('#wrapper').css('marginLeft', "250px");
      $('#fsbtn').css('marginLeft', "248px");
//funzione che definisce l'area su cui si può eseguire il drag&drop
function makeDroppable(droppableArea, callback) {
Laura Cappelli's avatar
Laura Cappelli committed

  //creo l'elemento "input type file" non visibile e lo aggiungo a "droppableArea"
  var input: any = document.createElement('input');
Laura Cappelli's avatar
Laura Cappelli committed
  input.setAttribute('type', 'file');
  input.setAttribute('multiple', true);
  input.style.display = 'none';
  droppableArea.appendChild(input);
Laura Cappelli's avatar
Laura Cappelli committed

  //questo evento è chiamato quando i file sono trascinati ma non ancora lasciati
  droppableArea.addEventListener('dragover', function(e) {
Laura Cappelli's avatar
Laura Cappelli committed
    e.preventDefault(); //impediamo l'apertura del file
    e.stopPropagation();
    e.dataTransfer.dropEffect = 'copy';
    droppableArea.classList.add('dragover');
Laura Cappelli's avatar
Laura Cappelli committed
  });

  //l'evento è chiamato quando un file lascia la zona predefinita per il drag&drop
  droppableArea.addEventListener('dragleave', function(e) {
Laura Cappelli's avatar
Laura Cappelli committed
    e.preventDefault();
    e.stopPropagation();
    droppableArea.classList.remove('dragover');
Laura Cappelli's avatar
Laura Cappelli committed
  });

  //questo evento si innesca quando il drop è effettivamente avvenuto
  droppableArea.addEventListener('drop', function(e) {
Laura Cappelli's avatar
Laura Cappelli committed
    e.preventDefault();
    e.stopPropagation();
    droppableArea.classList.remove('dragover');
    callback.call(null, e.dataTransfer.files);
//funzione chiamata in caso di drag&drop responsabile dell'apertura del file droppato,
//della sua lettura e del passaggio del suo contenuto alla funzione readData()
function callback(files) {

  console.log("Try to open " + files[files.length-1].name + " ...");
  var readerObject: any = new FileReader();
  readerObject.readAsBinaryString(files[files.length-1]);  
  readerObject.onload = function() {
    var fileString: string = readerObject.result; 
    readData(fileString);
Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

//la funzione prepara i dati per il grafico completo
function setDataForCompleteChart(){
Laura Cappelli's avatar
Laura Cappelli committed

  //per ogni pixel sommo i conteggi di tutti i canali rilevati
  var dataForChart: number[] = new Array(16384);
  for(var i: number = 0; i < 16384; i++){
   dataForChart[i] = 0;
  }
  for(var i: number = 0; i < xDim; i++){
    for(var j: number = 0; j < yDim; j++){
      for(var k: number = 0; k < 16384; k++){
        dataForChart[k] += DataMatrix[i][j][k];
      }
Laura Cappelli's avatar
Laura Cappelli committed
    }
  }
  //riempio le stringhe con i dati per il grafico
  for(var i: number = 0; i < 16348; i++){
    dataCompleteChart += (i+1) + "," + dataForChart[i] + "\n";
    dataCompleteChartCalibrated+=round3(((i+1)*a-b)/1000)+","+dataForChart[i]+"\n";
  }
Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

//La funzione riceve in input un vettore di cui somma gli elementi compresi tra 
//gli indici from e to 
function sumVect(vect: number[], from: number, to: number){
Laura Cappelli's avatar
Laura Cappelli committed

  var sum: number = 0;
  for(var i: number = from; i < to; i++){ sum += vect[i]; }
  return sum;
Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

//La funzione riceve in input la matrice e gli estremi della sottomatrice di cui
//calcola il massimo
function findMax(matrix: number[][], pixel1: coordinates, pixel2:coordinates){
Laura Cappelli's avatar
Laura Cappelli committed

  var max: number = 0;
  for(var i: number = pixel1.xp; i <= pixel2.xp; i++){
    for(var j: number = pixel1.yp; j <= pixel2.yp; j++){
      if(matrix[i][j] > max){
          max = matrix[i][j];
      }
Laura Cappelli's avatar
Laura Cappelli committed
    }
Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

//Funzione per arrotondare il numero in input alla terza cifra decimale
function round3(val: number){
Laura Cappelli's avatar
Laura Cappelli committed

  return (Math.round(val*Math.pow(10,3))/Math.pow(10,3));
//la funzione findPosition definisce la posizione del cursore del mouse
//relativa al canvas nel momento in cui avviene l'evento passato in input 
function findPosition(event: any, pixel: coordinates){
Laura Cappelli's avatar
Laura Cappelli committed

  var scrollTOP: number = (document.documentElement.scrollTop) ? 
    document.documentElement.scrollTop : document.body.scrollTop;
  var scrollLEFT: number = (document.documentElement.scrollLeft) ? 
    document.documentElement.scrollLeft : document.body.scrollLeft;
  var allX: number = event.clientX+scrollLEFT;
  var allY: number = event.clientY+scrollTOP;
  var elParent: any = document.getElementById('myCanvas');
  var objX: number = 0, objY: number = 0;
  while (elParent){
    objX += elParent.offsetLeft;
    objY += elParent.offsetTop;
    elParent = elParent.offsetParent;
  }
Laura Cappelli's avatar
Laura Cappelli committed

  pixel.xp = Math.floor((allX-objX - 1) / pixelDim ) + newOrigin.xp;
  pixel.yp = Math.floor((allY-objY - 1) / pixelDim ) + newOrigin.yp;
}
//la funzione findPosDown memorizza la posizione del pixel cliccato
function findPosDown(event: any){
Laura Cappelli's avatar
Laura Cappelli committed

  findPosition(event, zPixel1);
Laura Cappelli's avatar
Laura Cappelli committed

}
 
//la funzione findPosUp memorizza la posizione del pixel quando il mouse viene
//rilasciato, ordina le coordinate, aggiorna l'origine e la pagina.
function findPosUp(event: any){
Laura Cappelli's avatar
Laura Cappelli committed

  findPosition(event, zPixel2);
  var tmp: number;
  if (zPixel1.xp > zPixel2.xp) {
    tmp = zPixel1.xp;
    zPixel1.xp = zPixel2.xp;
    zPixel2.xp = tmp;
  }
  if (zPixel1.yp > zPixel2.yp) {
      tmp = zPixel1.yp;
      zPixel1.yp = zPixel2.yp;
      zPixel2.yp = tmp;
  }
  //se è stato cliccato un punto disegno il grafico, altrimenti disegno anche il
  //canvas e aggiorno l'origine
  if (zPixel1.xp != zPixel2.xp || zPixel1.yp != zPixel2.yp){
    newOrigin = {xp: zPixel1.xp, yp:zPixel1.yp};
    drawImg(zPixel1, zPixel2, globalxMinRange, globalxMaxRange);
  }
  drawChart(zPixel1, zPixel2, globalxMinRange, globalxMaxRange);
// La funzione readData() prende in ingresso il file di input memorizzato nella 
// stringa "fileString". La funzione riempie la matrice "DataMatrix" con i dati
// in modo che essi siano memorizzati in un formato più leggibile. Sono ricavate
// anche altre variabili necessarie per il resto del codice.
function readData(fileString){
Laura Cappelli's avatar
Laura Cappelli committed

  newOrigin = {xp: 0, yp: 0};  //origine nel caso di zoom
  var passo: number = 0; //dimensione di un pixel in micorn
  var readMode: string; //direzione di lettura
  //coordinate minime e massime in entrambe le dimensioni
  var xMin: number = 0, yMin: number = 0, xMax: number = 0, yMax: number = 0;  
  //array con il contenuto del file di input suddiviso per righe
  var fileStringArray: any = fileString.split("\n");
Laura Cappelli's avatar
Laura Cappelli committed
    
  //scorro l'array soffermandomi solo sulle righe "intestazione delle x". Devo
  //determinare ascisse e cordinate minime e massime, il passo e la direzione di
  //scansione
  for(var i: number = 0; i < fileStringArray.length; i++){
    if(parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] =='5'){      
      if(xMin == 0){ //se sono alla prima intestazione salvo la x e la y
        xMin = parseInt(fileStringArray[i]);
        yMin = parseInt(fileStringArray[i+1]);
        i++;
      } else { //definisco passo e direzione di scansione dalla seconda intestazione
        if(parseInt(fileStringArray[i]) == xMin){
          readMode = 'c';
          passo = Math.abs(yMin - fileStringArray[i+1]);
          //se sto leggendo per colonne determino xMax leggendo dalla fine
          for(var j: number = fileStringArray.length; j > i; j--){
            //se la riga è "intestazione x" memorizzo xMax e lo confronto con xMin
            if(parseInt(fileStringArray[j]) > 17000 && fileStringArray[j][0] =='5'){
              xMax = parseInt(fileStringArray[j]);
              if(xMax < xMin){ var t: number = xMax; xMax = xMin; xMin = t; }
              break;
Laura Cappelli's avatar
Laura Cappelli committed
            }
Laura Cappelli's avatar
Laura Cappelli committed
        } else {
          readMode = 'r';
          passo = Math.abs(xMin - fileStringArray[i]);
          //se sto leggendo per righe determino yMax leggendo dalla fine
          for(var j: number = fileStringArray.length; j > i; j--){
            //se la riga è "intestazione y" memorizzo yMax e lo confronto con yMin
            if(parseInt(fileStringArray[j]) > 17000 && fileStringArray[j][0] =='6'){
              yMax = parseInt(fileStringArray[j]);
              if(yMax < yMin){ var t: number = yMax; yMax = yMin; yMin = t; }
              break;
Laura Cappelli's avatar
Laura Cappelli committed
            }
Laura Cappelli's avatar
Laura Cappelli committed
    }
  } //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
    
  //A seconda della direzione di lettura determino o yMin e yMax, o xMin e xMax    
  for(var i: number = 2; i < fileStringArray.length; i++){
    if(readMode == 'c'){ //se leggo per colonne devo deterinare yMin e yMax
      //mi soffermo sulle righe "intestazione y"
      if (parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] == '6') {
        if (yMin > parseInt(fileStringArray[i])){
          yMin = parseInt(fileStringArray[i]);
Laura Cappelli's avatar
Laura Cappelli committed
        }
        if(yMax < parseInt(fileStringArray[i])){
          yMax = parseInt(fileStringArray[i]);
      }
      //alla terza colonna posso uscire perché ho già tutte le informazioni
      if (parseInt(fileStringArray[i]) == xMin + (passo * 2)) { break; }
    } else { //se leggo per righe devo deterinare xMin e xMax 
      //mi soffermo sulle righe "intestazione x"
      if (parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] == '5') {
        if (xMin > parseInt(fileStringArray[i])){
          xMin = parseInt(fileStringArray[i]);
        if(xMax < parseInt(fileStringArray[i])){
          xMax = parseInt(fileStringArray[i]);
        }
      }
      //alla terza colonna posso uscire perché ho già tutte le informazioni
      if (parseInt(fileStringArray[i]) == yMin + 2000) { break; }
Laura Cappelli's avatar
Laura Cappelli committed
    }
  } //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
Laura Cappelli's avatar
Laura Cappelli committed

  //Risolvo gli shift
  for(var i: number = 0; i < fileStringArray.length; i++){
    //se leggo per colonne allora aggiungo 1 alle y di tutte le colonne dispari
    if(readMode == 'c' && parseInt(fileStringArray[i]) > 17000 &&
      fileStringArray[i][0]=='5' && (parseInt(fileStringArray[i])/1000)%2 != 0){
      
      fileStringArray[i+1] = (parseInt(fileStringArray[i+1]) + passo).toString();
Laura Cappelli's avatar
Laura Cappelli committed
    }
    //se leggo per righe allora aggiungo 1 alle x di tutte le righe dispari
    else if(readMode == 'r' && parseInt(fileStringArray[i]) > 17000 &&
      fileStringArray[i][0]=='5' && (parseInt(fileStringArray[i+1])/1000)%2 != 0){

      fileStringArray[i] = (parseInt(fileStringArray[i]) + passo).toString();
Laura Cappelli's avatar
Laura Cappelli committed
    }
  }

  //Definisco le dimensioni della matrice DataMatrix e la inizializzo
  if(readMode == 'c'){
    xDim = (xMax - xMin)/passo + 1;
    yDim = (yMax - yMin)/passo - 2;
  } else {
    xDim = (xMax - xMin)/passo - 2;
    yDim = (yMax - yMin)/passo + 1;
  }
  //alert(xDim + " " + yDim);
  DataMatrix = new Array(xDim);
  for(var i: number = 0; i < xDim; i++){
    DataMatrix[i] = new Array(yDim);
    for(var j: number = 0; j < yDim; j++){
      DataMatrix[i][j] = new Array(16384);
      for(var k: number = 0; k < 16384; k++){
        DataMatrix[i][j][k] = 0;
      }
Laura Cappelli's avatar
Laura Cappelli committed
    }
  }
    
  //riempio la matrice DataMatrix eliminando i bordi
  for(var i: number = 0; i < fileStringArray.length; i++){
    var x: number, y: number, write: boolean;
    //riga "intestazione x": memorizzo le x e le y del punto e avanzo al conteggio
    if(parseInt(fileStringArray[i]) > 17000 && fileStringArray[i][0] == '5'){
      x = (parseInt(fileStringArray[i]) - xMin);
      y = (parseInt(fileStringArray[i+1]) - yMin);
      if(x != 0){ x /= passo; }
      if(y != 0){ y /= passo; }
      i++;

      //non è un pixel del bordo e sto leggendo per colonne: i successivi valori
      //sono da considerare
      if(readMode == 'c' && y != 0 && y != 1 && y != (yMax - yMin)/passo &&
        y != (yMax - yMin)/passo + 1){
        write = true;
        y -= 2; //aggiorno la y con i bordi tagliati
      }
      //non è un pixel del bordo e sto leggendo per righe: i successivi valori
      //sono da considerare
      else if(readMode == 'r' && x != 0 && x != 1 && x != (xMax - xMin)/passo && 
        x != (xMax - xMin)/passo + 1){
        write = true;
        x -= 2; //aggiorno la x con i bordi tagliati
      }
      //pixel del bordo: i valori successivi sono da ignorare
      else{ write = false; }
Laura Cappelli's avatar
Laura Cappelli committed
    
    //conteggio da considerare (non del bordo) 
    } else if (parseInt(fileStringArray[i]) < 17000 && write == true){
      //inserisco il conteggio nella matrice (occhio all'orientamento)
      DataMatrix[xDim-x-1][yDim-y-1][parseInt(fileStringArray[i])] += 1;
Laura Cappelli's avatar
Laura Cappelli committed
    }
Laura Cappelli's avatar
Laura Cappelli committed

  //calcolo il numero di conteggi per pixel e li salvo nella matrice nOfCounts
  nOfCounts = new Array(xDim);
  for(var i: number = 0; i < xDim; i++){
    nOfCounts[i] = new Array(yDim);
    for(var j: number = 0; j < yDim; j++){
      nOfCounts[i][j] = sumVect(DataMatrix[i][j], 0, DataMatrix[i][j].length);
Laura Cappelli's avatar
Laura Cappelli committed
    }
Laura Cappelli's avatar
Laura Cappelli committed

  //calcolo il conteggio massimo della matrice
  maxAbsolute = findMax(nOfCounts, {xp: 0, yp: 0}, {xp: xDim-1, yp: yDim-1});
Laura Cappelli's avatar
Laura Cappelli committed

  //definisco i dati per il grafico completo
  setDataForCompleteChart();
Laura Cappelli's avatar
Laura Cappelli committed

  console.log("File open with succes");
  drawImg({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
  drawChart({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

//la funzione drawImg disegna il canvas con l'immagine desiderata ed è responsabile
//della gestione di tutti gli eventi ad essa associati
function drawImg(pixel1: coordinates, pixel2:coordinates, xMinRange: number, xMaxRange: number){

  //dimensioni pixel
  var nPixelX: number = pixel2.xp - pixel1.xp + 1;
  var nPixelY: number = pixel2.yp - pixel1.yp + 1;
  var mappaPannelDim: any = document.querySelector ('#mappa-pannel').getBoundingClientRect();
  var mappaWidth: number = mappaPannelDim.right - mappaPannelDim.left - 20;
  var mappaHeigth: number = mappaPannelDim.bottom - mappaPannelDim.top - 50; 
  var dimPixelx: number = Math.floor(mappaWidth/nPixelX);
  var dimPixely: number = Math.floor(mappaHeigth/nPixelY);
  pixelDim = (dimPixelx < dimPixely) ? dimPixelx : dimPixely;
  document.getElementById("myCanvas").height = nPixelY * pixelDim;
  document.getElementById("myCanvas").width = nPixelX * pixelDim;
  var ctx = document.getElementById('myCanvas').getContext('2d'); //contesto del canvas

  if(xMaxRange - xMinRange >= 55){ //range completo
    var max: number; //massimo relativo o assoluto
    if (rePrint) max = findMax(nOfCounts, pixel1, pixel2);
    else max = maxAbsolute;
    max = (max * document.getElementById("SaturationSlider").value)/100 ; //saturazione
    drawCanvas(nOfCounts, max); //disegno

  } else { //range parziale (solo alcuni canali)
    var xMinRangeCh: number = Math.floor((((xMinRange*1000)+b)/a)-1); //16
    var xMaxRangeCh: number = Math.floor((((xMaxRange*1000)+b)/a)-1); //16371
    //calcolo il numero di conteggi solo dei canali selezionati
    var nOfCountsRelative: number[][];
    nOfCountsRelative = new Array(xDim);
Laura Cappelli's avatar
Laura Cappelli committed
    for(var i: number = 0; i < xDim; i++){
      nOfCountsRelative[i] = new Array(yDim);
      for(var j: number = 0; j < yDim; j++){
        nOfCountsRelative[i][j] = sumVect(DataMatrix[i][j], xMinRangeCh, xMaxRangeCh);
      }
Laura Cappelli's avatar
Laura Cappelli committed
    }
    //calcolo il massimo
    var max: number;
    if (rePrint) { max = findMax(nOfCountsRelative, pixel1, pixel2); }
    else { max = findMax(nOfCountsRelative,{xp:0,yp:0},{xp:xDim-1,yp:yDim-1}); }
    max = (max * document.getElementById("SaturationSlider").value)/100 ; //saturazione
    drawCanvas(nOfCountsRelative, max); //disegno
  }
Laura Cappelli's avatar
Laura Cappelli committed

  //La funzione, ricevuti dati e massimo, disegna la mappa nel canvas
  function drawCanvas(noc, max){

    //controllo il valore della trasparenza
    var setTrsp: number = 1-document.getElementById("TrasparencySlider").value/100;

    //scorro tutti i pixel: ne determino il colore e li disegno      
    var color:string = "";
    for (var i: number = pixel1.xp; i <= pixel2.xp; i++) {
      for (var j: number = pixel1.yp; j <= pixel2.yp; j++) {
        var intensity: number = noc[i][j] / max;
        if(intensity < 1/5) //blu
          color = "rgba(0, 0, "+Math.floor(intensity*5*255)+","+setTrsp+")";
        else if (1/5 <= intensity && intensity < 2/5) //blu+verde
          color="rgba(0, "+Math.floor((intensity-1/5)*5*255)+",255, "+setTrsp+")"; 
        else if (2/5 <= intensity && intensity < 3/5) // verde-blu
          color="rgba(0, 255, "+(255-Math.floor((intensity-2/5)*5*255))+", "+setTrsp+")"; 
        else if (3/5 <= intensity && intensity < 4/5) //verde + rosso 
          color="rgba("+Math.floor((intensity-3/5)*5*255)+",255,0,"+setTrsp+")"; 
        else //rosso -verde
          color="rgba(255,"+(255-Math.floor((intensity-4/5)*5*255))+", 0, "+setTrsp+")";
        ctx.fillStyle = color;
        ctx.fillRect((i - pixel1.xp) * pixelDim, (j - pixel1.yp) * pixelDim, pixelDim, pixelDim);
      }
Laura Cappelli's avatar
Laura Cappelli committed
    }
    rePrint = false; //annullo rePrint
  }
  
  $("#SaturationSlider").mouseup(function(){ //Slider della saturazione
    drawImg(pixel1, pixel2, xMinRange, xMaxRange);
  });
Laura Cappelli's avatar
Laura Cappelli committed

  $("#rePlot").click(function(){ //bottone per colorare con il max relativo
    rePrint = true;
    document.getElementById("SaturationSlider").value = "100";
    drawImg(pixel1, pixel2, xMinRange, xMaxRange);
  });
Laura Cappelli's avatar
Laura Cappelli committed

  $("#TrasparencySlider").mouseup(function(){ //Slider della trasparenza
    drawImg(pixel1, pixel2, xMinRange, xMaxRange);
  });
Laura Cappelli's avatar
Laura Cappelli committed

  $("#reset").click(function(){ //bottone per il reset dell'applicazione
    newOrigin = {xp: 0, yp: 0};
    rePrint = false;
    calibrated = false;
    globalxMinRange = 0;
    globalxMaxRange = 55;
    document.getElementById("SaturationSlider").value = "100";
    document.getElementById("TrasparencySlider").value = "0";
    document.getElementById("spinBoxMin").setAttribute("value", "-");
    document.getElementById("spinBoxMax").setAttribute("value", "-");
    drawImg({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
    drawChart({xp: 0, yp: 0}, {xp: xDim - 1, yp: yDim - 1}, 0, 55);
  });

  $("#ExportImage").click(function(){ //esportazione immagine
    var img = document.getElementById("myCanvas").toDataURL("image/png");
    $("#ExportImage").attr("href", img);
    //document.write('<img src="'+img+'"/>');
  });

}

//la funzione drawChart (input: estremi dell'immagine, estremi dell'intervallo)
//disegna il grafico richiesto relativo alla mappa visualizzata
function drawChart(pixel1: coordinates, pixel2:coordinates, xMinRange: number, xMaxRange: number){
    
  //definisco la variabile "grafico", i bottoni relativi al grafico, il tag
  //select e le due spinbox con il relativo botton
  var g: any;
  var box1 = <HTMLElement>document.getElementById("spinBoxMin");
  var box2 = <HTMLElement>document.getElementById("spinBoxMax");

  //disegno il grafico completo
  if(pixel1.xp == 0 && pixel1.yp == 0 && pixel2.xp == xDim-1 && pixel2.yp == yDim-1){
    if(!calibrated){ //canali
      var chartTitle: string = "Chart from (0, 0) to ("+(xDim-1)+", "+(yDim-1)+")";
      g = setChart(dataCompleteChart, chartTitle);
    } else { //energie
      var chartTitle: string = "Calibrated chart from (0, 0) to ("+(xDim-1)+", "+(yDim-1)+")";
      g = setChart(dataCompleteChartCalibrated, chartTitle);
    }

  //disegno il grafico parzialmente 
  } else {
    //determino i conteggi dei pixel da disegnare
    var dataForChart: number[] = new Array(16384);
    for(var i: number = 0; i < 16384; i++){
      dataForChart[i] = 0;
    }
Laura Cappelli's avatar
Laura Cappelli committed
    for(var i: number = pixel1.xp; i <= pixel2.xp; i++){
      for(var j: number = pixel1.yp; j <= pixel2.yp; j++){
        for(var k: number = 0; k < 16384; k++){
          dataForChart[k] += DataMatrix[i][j][k];
Laura Cappelli's avatar
Laura Cappelli committed
        }
      }
    }
    
    if(!calibrated){ //disegno in canali
      var dataChart: string = "Channel,Counts\n";
      for(var i: number = 0; i < 16348; i++){
        dataChart += i + "," + dataForChart[i] + "\n";
      }
      if(pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp){
        var chartTitle: string = "Chart pixel (" + pixel1.xp + ", " + (yDim - pixel1.yp - 1) + ")";
      } else {
        var chartTitle: string = "Chart from (" + pixel1.xp + "," + pixel2.xp + ") to (" +
          (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")";
      }
      g = setChart(dataChart, chartTitle);
Laura Cappelli's avatar
Laura Cappelli committed

    } else { //disegno in energie
      var dataChartCalibrated: string = "Energy,Counts\n";
      for(var i: number = 0; i < 16348; i++){
        dataChartCalibrated += round3(((i+1)*a-b)/1000) + "," + dataForChart[i] + "\n";
      }
      if(pixel1.xp == pixel2.xp && pixel1.yp == pixel2.yp){
        var chartTitle: string = "Calibrated chart pixel ("+pixel1.xp+", "+(yDim-pixel1.yp-1)+")";
      } else {
        var chartTitle: string = "Calibrated chart from (" + pixel1.xp + ", " + pixel2.xp +
         ") to ("+ (yDim - pixel1.yp - 1) + ", " + (yDim - pixel2.yp - 1) + ")";
      }
      g = setChart(dataChartCalibrated, chartTitle);
    }     
  }
Laura Cappelli's avatar
Laura Cappelli committed

  $('#setlinearButton').on('click', function() { //selezione scala lineare
    g.updateOptions( {logscale: false} );
  });
  $('#setlogButton').on('click', function() { //selezione scala logaritmica
    g.updateOptions( {logscale: true} );
  });
  $('#setEnergyButton').on('click', function() { //selezione energie
    calibrated = true;
    drawChart(pixel1, pixel2, 0, 55);
    box1.setAttribute("value", "0");
    box2.setAttribute("value", "55");
  });
  $('#setChannelsButton').on('click', function() { //selezione canali
    calibrated = false;
    drawChart(pixel1, pixel2, 0, 55);
    box1.setAttribute("value", "-");
    box2.setAttribute("value", "-");
  });
  $('#ExportGraph').on('click', function() { //esportazione grafico
    var img = document.getElementById("chartToImg");
    Dygraph.Export.asPNG(g, img);
    document.getElementById("ExportGraph").href = img.src.replace('image/png','image/octet-stream');
  });
  $('#readSpinbox').on('click', function() { //esportazione grafico
    peackSelection(0, 0);
  });
  $('#chart').on('click', function() { //zoom manuale sul grafico
    var r: number[];
    r = g.xAxisRange();
    if(!calibrated){
        r[0] = Math.floor((((r[0] + 1) * a) - b) / 1000);
        r[1] = Math.floor((((r[1] + 1) * a) - b) / 1000);
    } else {
        r[0] = round3(r[0]);
        r[1] = round3(r[1]);
        box1.setAttribute("value", r[0].toString());
        box2.setAttribute("value", r[1].toString());
    }
    globalxMinRange = r[0];
    globalxMaxRange = r[1];
    drawImg(pixel1, pixel2, r[0], r[1]);
  });
  $('#elementSelect').on('change', function() { //selezione elemento
    var element: string = document.getElementById("elementSelect").value;
    switch(element){
      case "1": //Ca 
        peackSelection(3.6, 3.8);
        box1.setAttribute("value", "3.60");
        box2.setAttribute("value", "3.80");
        break;
      case "2": //Pb
        peackSelection(10.4, 10.7);
        box1.setAttribute("value", "10.40");
        box2.setAttribute("value", "10.70");
        break; 
      case "3":  //Hg
        peackSelection(9.8, 10.15);
        box1.setAttribute("value", "9.80");
        box2.setAttribute("value", "10.15");
        break;       
      case "4": //Fe
        peackSelection(6.3, 6.5);
        box1.setAttribute("value", "6.30");
        box2.setAttribute("value", "6.50");
        break;       
      case "5":  //Cu
        peackSelection(7.85, 8.2);
        box1.setAttribute("value", "7.85");
        box2.setAttribute("value", "8.20");
        break;       
      case "6": //Zn
        peackSelection(8.5, 8.72);
        box1.setAttribute("value", "8.50");
        box2.setAttribute("value", "8.72"); 
        break;
      case "7": //Ti
        peackSelection(4.35, 4.65);
        box1.setAttribute("value", "4.35");
        box2.setAttribute("value", "4.65");
        break;
      case "8": //K
        peackSelection(3.2, 3.42);
        box1.setAttribute("value", "3.20");
        box2.setAttribute("value", "3.42");
        break;       
      case "9": //Co
        peackSelection(6.8, 7.05);
        box1.setAttribute("value", "6.80");
        box2.setAttribute("value", "7.05");
        break;
      default:
        peackSelection(0, 55);
        box1.setAttribute("value", "0");
        box2.setAttribute("value", "55");
        break;
Laura Cappelli's avatar
Laura Cappelli committed
    }
Laura Cappelli's avatar
Laura Cappelli committed

  //la funzione setChart riceve in input i dati e il titolo del grafico da disegnare
  //il quale è restituito il output
  function setChart(dataString: string, charTitle: string){

    var xArrayRange: number[]; //estremi asse x da visualizzare
    var xLab: string;
    if(!calibrated){
      xArrayRange = [0, 16383];
      xLab = "ADC Channel";
    }else{
      xArrayRange = [xMinRange, xMaxRange];
      xLab = "Energy (keV)";
    }

    //dimensioni grafico
    var chartDim: any = document.querySelector('#chart-pannel').getBoundingClientRect();
    var chartWidth = chartDim.right - chartDim.left - 50;
    $('#chart').css('width', chartWidth);
    var chartHeight: number = chartDim.bottom - chartDim.top - 100; 
    $('#chart').css('height', chartHeight);

    //disegno il grafico
    var graphs: any = new Dygraph(document.getElementById("chart"), dataString, {
      title: charTitle,
      ylabel: 'Counts',
      xlabel: xLab,
      //legend: 'always',
      labelsDivStyles: { 'textAlign': 'right' },
      dateWindow: xArrayRange,
      showRangeSelector: true,
      logscale: false
    });

    //dimensioni responsive alle sideNav
    $('#fsbtn').on('click', function() { 
      setTimeout(function(){
        g = setChart(dataString, charTitle);
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      }, 400);
    });
    $('#setbtn').on('click', function() {
      setTimeout(function(){
        g = setChart(dataString, charTitle);
        drawImg(pixel1, pixel2, xMinRange, xMaxRange);
      }, 400);
    });
Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

Laura Cappelli's avatar
Laura Cappelli committed

  //la funzione, dati gli estremi dell'intervallo da rappresentare, aggiorna mappa e grafico
  function peackSelection(xMinRange: number, xMaxRange: number){
Laura Cappelli's avatar
Laura Cappelli committed

    //se l'intervallo è [0, 0] devo leggere dalle i valori dalle spinbox
    if(xMinRange == 0 && xMaxRange == 0){
      xMinRange = box1.value;
      xMaxRange = box2.value;
Laura Cappelli's avatar
Laura Cappelli committed
    }

    globalxMinRange = xMinRange;
    globalxMaxRange = xMaxRange;
    newOrigin = { xp: 0, yp: 0};
    rePrint = false;
    calibrated = true;
    drawImg({xp:0, yp:0}, {xp:xDim-1, yp:yDim-1}, globalxMinRange, globalxMaxRange);
    drawChart({xp:0, yp:0}, {xp:xDim-1, yp:yDim-1}, globalxMinRange, globalxMaxRange);

  }

Laura Cappelli's avatar
Laura Cappelli committed
}