/*------------------------------perturb.c-----------------------------
  This program loads a molecule in .abc format, perturbs each atomic
  coordinate by a random amount within some range, and saves the
  result to another .abc file. This software was written by Stephen
  Jordan.
  --------------------------------------------------------------------*/

#include "abcio.h"               //for loadabc and saveabc
#include "cell.h"                //for the cell structure
#include <stdio.h>               //for sprintf, fopen, FILE
#include <stdlib.h>              //for EXIT_SUCCESS and EXIT_FAILURE
#include <ctype.h>               //for isdigit

//strips the path off of a filename
void strip_path(char *name) {
  char *temp;
  temp = strrchr(name, '/');
  if(temp != NULL) strcpy(name, temp + 1);
}


//add random perturbations to the atomic coordinates
//the maximum perturbation is "distance" in Angstroms
void perturb(cell *C, double distance) {
  int i;
  double uniform;
  for(i = 0; i < 3*C->atoms; i++) {
    //uniformly distributed random variable from -1 to 1
    uniform = (2.0*(double)rand() - (double)RAND_MAX)/(double)RAND_MAX;
    C->x[i] += distance*uniform;
  }
}


int main(int argc, char *argv[]) {
  FILE *infile;
  FILE *outfile;
  char filename[256];
  char comment[256];
  double distance;
  int i, tally;
  char response;
  cell C;
  distance = 0.1; //default value 
  if(argc < 2) {
    printf("Usage: perturb [-d maxdistance] filename.abc\n");
    printf("(Default maximum distance is 0.1 angstroms.)\n");
    return EXIT_FAILURE;
  }
  for(i = 1; i < argc; i++) {
    if(argv[i][0] == '-' && argv[i][1]=='d') {
      if(strlen(argv[i]) >= 3) sscanf(argv[i]+2, "%lf", &distance);
      else {
        if(i < argc - 1) sscanf(argv[i+1], "%lf", &distance);
        else { 
          printf("Invalid switches.\n"); 
          return EXIT_FAILURE;
        }
      }
    }
  }
  tally = 0;
  for(i = 1; i < argc; i++) {
    if(argv[i][0] != '-' && !isdigit(argv[i][0])) {
      tally++;
      infile = fopen(argv[i], "r");
      if(infile == NULL) {
        printf("Unable to open %s\n", argv[i]);
        return EXIT_FAILURE;
      }
      strip_path(argv[i]);
      sprintf(filename, "P_%s", argv[i]);
      outfile = fopen(filename, "w");
      if(outfile == NULL) {
        printf("Unable to create %s\n", filename);
        return EXIT_FAILURE;
      }
      loadabc(infile, &C, 0);
      printf("atoms = %i\tbonds = %i\n", C.atoms, C.bonds);
      perturb(&C, distance);
      sprintf(comment, "Perturbed by %f Angstroms\n", distance);
      saveabc(outfile, &C, comment, 3, 0);
      fclose(infile);
      fclose(outfile);
      destroy_cell(&C);
    }
  }
  printf("%i files perturbed.\n", tally);
  return EXIT_SUCCESS;
}






