All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fudaa.dodico.reflux.io.RefluxSolutionSequentielReader Maven / Gradle / Ivy

There is a newer version: 2.7
Show newest version
/**
 * @creation 16 d?c. 2004 @modification $Date: 2007-06-20 12:21:44 $ @license GNU General Public License 2 @copyright (c)1998-2001 CETMEF 2 bd
 *     Gambetta F-60231 Compiegne @mail [email protected]
 */
package org.fudaa.dodico.reflux.io;

import gnu.trove.TDoubleArrayList;
import org.fudaa.dodico.fichiers.ByteBufferInputStream;
import org.fudaa.dodico.fortran.FortranReader;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Arrays;

/**
 * @author Fred Deniger
 * @version $Id: RefluxSolutionSequentielReader.java,v 1.10 2007-06-20 12:21:44 deniger Exp $
 */
public class RefluxSolutionSequentielReader {
  //  FileChannel ch_;
  final int nbVar_;
  final int nbPoint_;
  final int[] fmt_;
  /**
   * Taille d'une ligne de valeur.
   */
  final long lineLength_;
  /**
   * Taille du delimiteur -999.
   */
  final long delimLength_;
  /**
   * Taille d'un ligne d'entete t=.
   */
  final long enteteLength_;
  final long firstPos_;
  final File f_;

  // boolean fmtIsUpdated_;

  /**
   * @param _r les resultats
   * @param _f le fichier
   * @throws IOException lancer si le fichier n'existe pas et si impossible de locker le fichier
   */
  public RefluxSolutionSequentielReader(final RefluxRefondeSolutionSequentielResult _r, final File _f) {
    super();
    // positions_ = _r.position_;
    nbVar_ = _r.nbVar_;
    nbPoint_ = _r.nbPoint_;
    f_ = _f;
    fmt_ = new int[nbVar_ + 1];

    final int temp = _r.ft_.getDataColLength();
    lineLength_ = _r.lineLength_;
    firstPos_ = _r.firstPost_;
    enteteLength_ = _r.enteteLength_;
    delimLength_ = _r.delimLength_;
    Arrays.fill(fmt_, 0, fmt_.length, temp);
    fmt_[0] = _r.sizeFirstCol_;
  }

  private FileChannel buildChannel() throws IOException {
    return new FileInputStream(f_).getChannel();
  }

  protected long getPosition(final int _timeStep) {
    // on saute l'entete du fichier sov.
    // puis pour chaque pas de temps, on saute -999 +entete + la place prise
    // pour chaque point.
    return firstPos_ + _timeStep * getOffset();
  }

  private long getOffset() {
    return delimLength_ + enteteLength_ + nbPoint_ * lineLength_;
  }

  /**
   * @return nombre de pas de temps devin? ? partir de la taille du fichier
   */
  public int getNbTimeStepGuessed() throws IOException {
    final long size = f_.length();
    final long taille = size - firstPos_;
    final long tailleData = nbPoint_ * lineLength_;
    final long tailleBloc = tailleData + delimLength_;
    if (taille < tailleData) {
      return 0;
    }
    return (int) (2L + (taille - tailleBloc - tailleData - enteteLength_) / (tailleBloc + enteteLength_));
  }

  public double[] readTimeStep(final int _beginTimeStepIdx, final int _nb) throws IOException {
    final ByteBuffer buf = ByteBuffer.allocate((int) enteteLength_);
    final int[] fmtEtape = RefluxRefondeSolutionFileFormat.getInstance().getEtapeFormat();
    int debTimeStep = 0;
    // on recherche l'indice de debut du pas de temps
    for (int i = 0; i < fmtEtape.length - 1; i++) {
      debTimeStep += fmtEtape[i];
    }
    long pos = getPosition(_beginTimeStepIdx);
    pos -= enteteLength_;
    final TDoubleArrayList timeStep = new TDoubleArrayList(_nb);
    FileChannel ch = buildChannel();
    try {
      final long offset = getOffset();
      for (int i = 0; i < _nb; i++) {
        ch.position(pos);
        buf.rewind();
        ch.read(buf);
        // positions.add(ch.position());
        buf.rewind();
        final String str = new String(buf.array()).substring(debTimeStep);
        timeStep.add(Double.parseDouble(str));
        pos += offset;
      }
    } finally {
      ch.close();
    }
    return timeStep.toNativeArray();
  }

//  ByteBuffer simple_;
//  ByteBuffer complexe_;

  /**
   * @param _varIdx l'indice de la variable demandee
   * @param _timeStep l'indice du pas de temps
   * @param _idxPt l'indice du point
   * @return la valeur demande
   * @throws IOException si impossible de lire le fichier
   */
  public double read(final int _varIdx, final int _timeStep, final int _idxPt) throws IOException {
    FortranReader r = null;
    FileChannel ch = buildChannel();
    try {
      ByteBuffer simple = ByteBuffer.allocateDirect((int) lineLength_);
      ch.read(simple, getPosition(_timeStep) + _idxPt * lineLength_);
      simple.rewind();
      try (final ByteBufferInputStream in = new ByteBufferInputStream(simple)) {
        r = new FortranReader(new LineNumberReader(new InputStreamReader(in)));
        r.readFields(fmt_);
        return r.doubleField(_varIdx + 1);
      }
    } catch (final IOException e) {
      throw e;
    } finally {
      ch.close();
      if (r != null) {
        r.close();
      }
    }
  }

  /**
   * @param _varIdx le tableau des valeurs. Attention commence a 0 a partir de la colonne 1. La premiere colonne etant l'index du point
   * @param _timeStep le pas de temps demande
   * @param _d d[col.length][nbPoint]
   */
  public void read(final int[] _varIdx, final int _timeStep, final double[][] _d) throws IOException {
    FortranReader r = null;
    FileChannel ch = buildChannel();
    try {
      // a voir si cela prend de la place en memoire
      ByteBuffer complexe = ByteBuffer.allocateDirect((int) (nbPoint_ * lineLength_));
      ch.read(complexe, getPosition(_timeStep));
      complexe.rewind();
      try (final ByteBufferInputStream in = new ByteBufferInputStream(complexe)) {
        int idx = 0;
        r = new FortranReader(new LineNumberReader(new InputStreamReader(in)));
        while (idx < nbPoint_) {
          r.readFields(fmt_);
          for (int i = _varIdx.length - 1; i >= 0; i--) {
            _d[i][idx] = r.doubleField(_varIdx[i] + 1);
          }
          idx++;
        }
      }
    } catch (final NumberFormatException _e) {
      _e.printStackTrace();
    } catch (final IOException e) {
      throw e;
    } finally {
      ch.close();
      if (r != null) {
        r.close();
      }
    }
  }

  /**
   * Ferme le channel.
   */
  public void close() throws IOException {
  }

  /**
   * @return the nbPoint
   */
  public int getNbPoint() {
    return nbPoint_;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy