/********************************************/
/* splitx_au - TopSpin3 version             */
/* Based on NBL, splits and processes       */
/* NOAH expts according to AU processing    */
/* programs defined by userP1-P5 parameters */
/* EK, 21.11.2015, eriks.kupce@bruker.com   */
/********************************************/

  int size[3];
  int *row;
  int i, j, k, td, td1, tds, td1s, tdx;
  int oexpno, nexpno, byteorder, parmode;
  int nbl = 0, fntype = 0;
  char path[PATH_MAX + 64], proc_nm[8], str[32];
  FILE **fp;

/***** get dataset and parameters *****/

  FETCHPAR("PARMODE", &parmode)
  FETCHPAR("NBL", &nbl)

  if (parmode != 1) STOPMSG("Program is only suitable for 2D")
  if ((nbl<2) || (nbl>8)) STOPMSG("Program is only suitable for 8 > NBL > 1")
  
  FETCHPARS("BYTORDA", &byteorder)
  FETCHPARS("TD", &tds)
  FETCHPAR1("TD", &td1)
  FETCHPAR1S("TD", &td1s)

  td = ((tds + 255) / 256) * 256;
  if (td <= 0  ||  td > 64 * 1024 * 1024)
    STOPMSG("TD{F2} out of range")
  if (td1s <= 0  ||  td1s > 64 * 1024 * 1024)
    STOPMSG("TD{F1} out of range")
  tdx = nbl*td;
  if ((double) tdx >= 2. * 1024 * 1024 * 1024 / sizeof(int))
    STOPMSG("amount of memory requested too large")

/***** get input *****/

  oexpno = expno;
  nexpno = expno * 1000 + 1;
  if (nexpno <= 0)
    STOPMSG("invalid expno value")

/***** check files *****/

  for(i=0; i<nbl; i++)
  {
    WRAPARAM(nexpno+i)
    ERRORABORT
  }

  fp = (FILE **) calloc(nbl+1, sizeof(FILE *));
  
  (void)strcpy(path, ACQUPATH("ser"));
  if ((fp[nbl] = fopen(path, "rb")) == 0)
    STOPMSG(strcat(path, " - cannot open file for reading"))
    
  for(i=0; i<nbl; i++)
  {
    expno = nexpno+i;
    (void)strcpy(path, ACQUPATH("ser"));
    if ((fp[i] = fopen(path, "wb")) == 0)
      STOPMSG(strcat(path, " - cannot open file for writing"))
  }

  expno = oexpno;

/***** allocate memory *****/

  if((row = (int*)malloc(tdx * sizeof(int))) == 0)
    STOPMSG("cannot get enough memory")

/***** split *****/

  Show_status("splitting data"); 

  k = td1s / nbl;
  for (i = 0; i < k; i ++)
  {
    if (fread(row, sizeof(int), tdx, fp[nbl]) != (size_t)(tdx))
      STOPMSG("read failed")

    local_swap4(row, tdx * sizeof(int), byteorder);

    for (j = 0; j < nbl; j++)
    {
      if (fwrite(row+j*td, sizeof(int), td, fp[j]) != (size_t)(td))
        STOPMSG("write failed")
    }
  }

/***** free resources *****/

  for(i=0; i<nbl; i++) fclose(fp[i]);
  fclose(fp[i]);
  free(row);

/***** store parameters and generate audit entry ***/

  td1  /= nbl;
  td1s /= nbl;

  strcpy(path, ACQUPATH(0));
  byteorder = local_endian();
  size[0] = td;
  size[1] = td1s;
  i = 0;
  do
  {
    double ymin, ymax;
    char  autext[PATH_MAX + 256];
    char* hashbuf = autext + sprintf(autext, "created by splitx");

    hashbuf += sprintf(hashbuf, " %d", nbl);
    hashbuf += sprintf(hashbuf, " %d. dataset from\n       %s", i + 1, path);

    DATASET(name, nexpno + i, procno, disk, user)

    sprintf(proc_nm, "userP%d", i+1);
    FETCHPAR(proc_nm, str)
    STOREPAR("AUNMP", str)
    STOREPAR("NBL", 1)
    STOREPARS("NBL", 1)
    STOREPARS("BYTORDA", byteorder)
    STOREPAR1("TD", td1)
    STOREPAR1S("TD", td1s)

    if (CheckSumFileMax(ACQUPATH("ser"), 0, hashbuf, 0, 0, byteorder, 0, parmode + 1, tds, size, size, &ymin, &ymax) > 0)
    {
      (void)AuditCreate(ACQUPATH("audita.txt"), autext);
      STOREPARS("YMIN_a", ymin)
      STOREPARS("YMAX_a", ymax)
    }
    XAUPW;

    REFRESHDATA
  }
  while (++i < nbl);

  Show_status("splitx done."); 

QUIT

