#include "dump2analysis.h"
/* DOCUMENT */
/* -m cube_radius */
/* lammpstrjから指定した原子を有限のサイズを考慮してグリッドデータ(cubeファイル)を作成する。 */
/* cubeファイルは、VESTAやVMDでisosurfaceやvolumes urfaceで可視化できる。 */
/* cubeファイル中での指定以外の原子座標は、全ステップの平均値とする */
/* 基本的に1種類の原子によるグリッドデータのみを想定している */

void ErrorCube_Radius(){
  printf("Required arguments atoms A\n");
  printf("(-a, -x, -s) atom A\n");
  printf("------------------------------------------------------------\n");
  printf("Optional arguments for cube analysis:\n");
  printf("--nx        numebr boxcel on X            [100]\n");
  printf("--ny        numebr boxcel on X            [100]\n");
  printf("--nz        numebr boxcel on X            [100]\n");
  printf("--radius    atomic radius                 [0.7]\n");
  printf("------------------------------------------------------------\n");  
  printf("Example:\n");
  printf("dump2analysis -m cube_radius -x Li --radius 0.7 -i hoge.lammpstrj -o hoge.cube\n");
  exit(0);
}

void EstimateCube_Radius(PARAM *param){
  int i, j, k;
  int ix, iy, iz;
  FILE *f;
  HEAD head;
  ATOMS a;
  double ***rho;
  double da, db, dc;
  double r, x, y, z, xp, yp, zp;
  double dx, dy, dz;

  /* メモリ確保 */
  rho = malloc(sizeof(double**) * NZ);
  for (i=0; i<NZ; i++) rho[i] = malloc(sizeof(double*) * NY);
  for (i=0; i<NZ; i++){
    for (j=0; j<NY; j++) rho[i][j] = malloc(sizeof(double*) * NX);
  }
  /* 初期化 */
  for (i=0; i<NZ; i++){
    for (j=0; j<NY; j++){
      for (k=0; k<NX; k++){
	rho[i][j][k] = 0.0;
      }
    }
  }
  
  /* エラーのチェック */
  if (ArgCheckInputOutput(param) != 0) ErrorCube_Radius();
  SetAtomsSteps(param);
  /* 1: A原子以外も指定している */
  if (CheckArgAtomSelect(param) != 1) ErrorCube_Radius();

  /* 原子数を与えての構造体のメモリ確保 */
  Allocate(&a, param->atoms);

  /* ファイルオープン */
  f = fopen(param->infile, "r");
  
  /* ステップ毎にデータを取得する */
  da = 1.0/(double)NX;
  db = 1.0/(double)NY;
  dc = 1.0/(double)NZ;
  for (i=0; i<param->steps; i++){
    GetData(f, param, &head, &a, NULL, NULL);
    for (j=0; j<a.atoms; j++){
      /* voxelの中心点と原子の距離を探すloop */
      for (ix=0; ix<NX; ix++){
	for (iy=0; iy<NY; iy++){
	  for (iz=0; iz<NZ; iz++){
	    xp = ix*da + 0.5*da;
	    yp = iy*db + 0.5*db;
	    zp = iz*dc + 0.5*dc;
	    dx = a.x[j] - xp;
	    dy = a.y[j] - yp;
	    dz = a.z[j] - zp;
	    dx = dx - rint(dx);
	    dy = dy - rint(dy);
	    dz = dz - rint(dz);
	    /* 絶対座標に変換 */
	    x = dx*head.A[0][0] + dy*head.A[1][0] + dz*head.A[2][0];
	    y = dx*head.A[0][1] + dy*head.A[1][1] + dz*head.A[2][1];
	    z = dx*head.A[0][2] + dy*head.A[1][2] + dz*head.A[2][2];
	    r = sqrt(x*x + y*y + z*z);
	    if (r < RADIUS) rho[iz][iy][ix] += 1.0;
	  }
	}
      }
    }
    printf("step: %d\r", i);
    fflush(stdout);
  }
  printf("\n");
  fclose(f);

  OutputCube(param, rho);
}
