Skip to content
Snippets Groups Projects
loaddir.ts 14.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • Francesco Giacomini's avatar
    Francesco Giacomini committed
    // Copyright 2017 Istituto Nazionale di Fisica Nucleare
    //
    // Licensed under the EUPL
    
    
    import * as $ from "jquery";
    
    import assert from "assert";
    import "./globals";
    import * as img from "./draw";
    
    //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
    
    export function setImportFile() {
    
    
      //genero e leggo il contenuto della directory "filesystem"
    
      let xmlDoc: any;
      let xmlListingFile: any = new XMLHttpRequest();
    
      xmlListingFile.open("PROPFIND", "CHNET/", false);
      xmlListingFile.setRequestHeader("Depth", "infinity");
    
      xmlListingFile.onreadystatechange = function () {
        if (xmlListingFile.readyState === 4) {
          if (xmlListingFile.status === 207) {
            let parser: any = new DOMParser();
    
            xmlDoc = parser.parseFromString(xmlListingFile.responseText, "text/xml");
          }
        }
      }
      xmlListingFile.send(null);
    
    
      //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) {
    
          $("#load-spinner").css("display", "inline");
          openFileFromServer(node['url']);
        }
      });
    
      //bottone per l'importazione locale
    
      let fileInputButton: any = document.getElementById('myImport');
      fileInputButton.onchange = function () {
    
        $("#load-spinner").css("display", "inline");
    
        let fileName: string = fileInputButton.files[0];
        let readerObject: any = new FileReader();
        readerObject.readAsBinaryString(fileName);
        readerObject.onload = function () {
          let fileString: string = readerObject.result;
    
          readData(fileString);
        }
      }
    
    }
    
    //funzione che genera automaticamente l'albero
    
    function generateTree(xmlDoc) {
    
      let tree: any = [];
      let first: boolean = true;
      let oldFolderParent: string = "";
      let oldFolder: string = "";
    
    
      //inizio leggendo tutti gli elementi da inserire nell'albero (caratterizzati
      //dall'avere un url di riferimento)
    
      let entry: string[] = xmlDoc.getElementsByTagName("D:href");
    
    
      //per ogni elemento controllo se si tratta di una cartella o di un documento
    
      for (let i: number = 0; i < entry.length; i++) {
        let path: string[] = entry[i].childNodes[0].nodeValue.split("");
    
    
        //cartella, creo l'oggetto corrsipondente
    
        if (path[path.length - 1] == "/") {
          let folderName: string[] = entry[i].childNodes[0].nodeValue.split("/");
          let 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);
    
            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  
    
            let newFolder: string = entry[i].childNodes[0].nodeValue;
            let 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
    
          let fileName: string[] = entry[i].childNodes[0].nodeValue.split("/");
          let filePath: string = entry[i].childNodes[0].nodeValue;
          let 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 di "/")
    
      let depth: number = objfsName.length;
      if (type) depth++;
    
    
      //in base alla profondità determino a quale oggetto agganciare quello in input
    
      let treePosition: any;
      let l: number = tree.length - 1;
      switch (depth) {
    
        case 6: treePosition = tree; break;
        case 7: treePosition = tree[l].nodes; break;
        case 8: treePosition =
    
          tree[l].nodes[tree[l].nodes.length - 1].nodes; break;
        case 9: treePosition =
          tree[l].nodes[tree[l].nodes.length - 1].nodes[tree[l].nodes[tree[l].nodes.length - 1].nodes.length - 1].nodes;
          break;
        case 10: treePosition =
          tree[l].nodes[tree[l].nodes.length - 1].nodes[tree[l].nodes[tree[l].nodes.length - 1].nodes.length - 1].nodes[tree[l].nodes[tree[l].nodes.length - 1].nodes[tree[l].nodes[tree[l].nodes.length - 1].nodes.length - 1].nodes.length - 1].nodes;
          break;
    
      treePosition[treePosition.length - 1].nodes.push(objfs);
    
    
    }
    
    //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) {
    
      let fileName: string[] = url.split("/");
      console.log("Try to open " + fileName[fileName.length - 1] + " ...");
      let txtFile: any = new XMLHttpRequest();
    
      txtFile.open("GET", url, true);
    
      txtFile.onreadystatechange = function () {
        if (txtFile.readyState === 4) {
          if (txtFile.status === 200) {
    
            readData((txtFile.responseText));
          }
        }
      }
    
      txtFile.send(null);
    }
    
    // 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.
    export function readData(fileString: string)
    {
    
      let newOrigin = { xp: 0, yp: 0 };  //origine nel caso di zoom
      let passo: number = 0; //dimensione di un pixel in micorn
      let readMode: string = 'u'; //direzione di lettura
      //coordinate minime e massime in entrambe le dimensioni
      let xMin: number = 0, yMin: number = 0, xMax: number = 0, yMax: number = 0;
      //array con il contenuto del file di input suddiviso per righe
      let fileStringArray: any = fileString.split("\n");
    
      //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 (let 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 (let 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) { let t: number = xMax; xMax = xMin; xMin = t; }
                  break;
                }
              }
            } else {
              readMode = 'r';
              passo = Math.abs(xMin - fileStringArray[i]);
              //se sto leggendo per righe determino yMax leggendo dalla fine
              for (let 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) { let t: number = yMax; yMax = yMin; yMin = t; }
                  break;
                }
              }
            }
            break;
          }
        }
      } //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
    
      assert.notEqual(readMode, 'p');
    
      //A seconda della direzione di lettura determino o yMin e yMax, o xMin e xMax    
      for (let 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]);
            }
            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; }
        }
      } //alert(xMin + " " + xMax + " " + yMin + " " + yMax + " " + passo);
    
      //Risolvo gli shift
      for (let 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();
        }
        //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();
        }
      }
    
      //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);
      //determino la profondità del problema: mi soffermo solo sui conteggi e tengo
      //il massimo
      // for(let i: number = 0; i < fileStringArray.length; i++){
      //   if(parseInt(fileStringArray[i]) < 17000){
      //     if(parseInt(fileStringArray[i]) > depth){
      //       depth = parseInt(fileStringArray[i]);
      //     }
      //   }
      // }
      //alert(depth);
      DataMatrix = new Array(xDim);
      for (let i: number = 0; i < xDim; i++) {
        DataMatrix[i] = new Array(yDim);
        for (let j: number = 0; j < yDim; j++) {
          DataMatrix[i][j] = new Array(depth);
          for (let k: number = 0; k < depth; k++) {
            DataMatrix[i][j][k] = 0;
          }
        }
      }
    
      //riempio la matrice DataMatrix eliminando i bordi
      for (let i: number = 0; i < fileStringArray.length; i++) {
        let x: number, y: number;
        var 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; }
    
          //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;
        }
      }
    
      //calcolo il numero di conteggi per pixel e li salvo nella matrice nOfCounts
      nOfCounts = new Array(xDim);
      for (let i: number = 0; i < xDim; i++) {
        nOfCounts[i] = new Array(yDim);
        for (let j: number = 0; j < yDim; j++) {
          nOfCounts[i][j] = sumVect(DataMatrix[i][j], 0, DataMatrix[i][j].length);
        }
      }
    
      //calcolo il conteggio massimo della matrice
      maxAbsolute = findMax(nOfCounts, { xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 });
    
      //definisco i dati per il grafico completo
      setDataForCompleteChart();
    
      console.log("File open with succes");
      img.drawImg({ xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }, 0, channelDepth);
      img.drawChart({ xp: 0, yp: 0 }, { xp: xDim - 1, yp: yDim - 1 }, 0, channelDepth);
      $("#load-spinner").css("display", "none");