/* 
   * Copyright (C) 1997, Slava Ilyin 
   * Copyright (C) 2001-2003, CompHEP Collaboration
   *------------------------------------------------------
   * $Id: rw_sess.c,v 1.8 2003/08/25 09:15:35 sherstnv Exp $
   *
   * $Log: rw_sess.c,v $
   * Revision 1.8  2003/08/25 09:15:35  sherstnv
   * Some changes in r/w of the session.dat file.
   * Bug fixed in the Width_scheme position
   *
   * Revision 1.7  2003/07/20 14:34:37  kryukov
   * Change width menu. Remove rwidth global vars.
   * gwidth=0(fix), 1(overall), 2(running).
   *
   * Revision 1.6  2003/06/25 18:46:41  kryukov
   * *** empty log message ***
   *
   * Revision 1.5  2003/04/22 09:01:19  kryukov
   * Apply indent to improve readability of files
   *
   * Revision 1.4  2003/04/20 17:55:02  kryukov
   * Clean up warnings during make
   *
 */
#include "chep_crt/include/crt_util.h"
#include "service2/include/tptcmac.h"
#include "service2/include/files.h"
#include "service2/include/drandXX.h"
#include "service2/include/paragraphs.h"
#include "symb/include/physics.h"
#include "out_ext.h"

#include "cut.h"
#include "kinaux.h"
#include "kininpt.h"
#include "regul.h"
#include "alphas2.h"
#include "histogram.h"
#include "runVegas.h"
#include "strfun.h"
#include "subproc.h"
#include "evnt_menu.h"
#include "rw_sess.h"

/*********************************************************/
/* R/W of Statistic string (cross section and its error) */
static int WriteIntegral (FILE * f) {
  fprintf (f, " %.17E %.17E %.17E %d %d %d",  
           integral.s0, integral.s1, integral.s2,
           integral.n_it, integral.old, (int) integral.nCallTot);
  return 0;
}

static int ReadIntegral (FILE * f) {
  fscanf (f, " %lf %lf %lf %d %d %ld", 
          &(integral.s0), &(integral.s1), &(integral.s2), 
          &(integral.n_it), &(integral.old), &(integral.nCallTot));
  return 0;
}


/**********************************************/
/* R/W subprocess number and name */
static int WriteSubprocessInfo (FILE * mode) {
  return fprintf (mode, "%d (%s)", proces_1.nsub, proces_1.proces);
}

static int ReadSubprocessInfo (FILE * mode) {
  int status = 0;
  shortstr proc_name;

  fscanf (mode, "%d (%[^)]", &proces_1.nsub, proc_name);
  if (proces_1.nsub > nprc_) {
    fprintf (stderr, "Error! The different number of subprocesses... num_{in file} = %i, nprc_ = %i.\n", proces_1.nsub, nprc_);
    return 2;
  }
  ComposeSubprocessString ();
  if (strcmp (proc_name, proces_1.proces)) {
    fprintf (stderr, "Error! Strange parameter names... name_{in file} = %s, name_{from particle names} = %s.\n", proc_name, proces_1.proces);
    status = 2;
  }
  return status;
}

int ComposeSubprocessString (void) {
  vshortstr buff;
  int pos = 0;
  int i;
  for (i = 1; i <= nin_ + nout_; i++) {
    pinf_ (proces_1.nsub, i, buff, NULL);
    strcpy (proces_1.proces + pos, buff);
    pos += strlen (buff);
    if (i < nin_ + nout_) {
      if (i == nin_)
      {
        strcpy (proces_1.proces + pos, " -> ");
        pos += 4;
      } else {
        strcpy (proces_1.proces + pos, ",");
        pos += 1;
      }
    }
  }
  return 0;
}

static int InitSubprocessString (void) {
  proces_1.nsub = 1;
  ComposeSubprocessString ();
  return 0;
}


/*********************************************************/
/* R/W the Session Number */
static int WriteSessionNumber (FILE * mode) {
  fprintf (mode, "%d", nSess);
  return 0;
}

static int ReadSessionNumber (FILE * mode) {
  fscanf (mode, "%d", &nSess);
  return 0;
}

static int InitSessionNumber (void) {
  nSess = 1;
  return 0;
}


/**********************************************/
/* R/W Monte-Carlo parameters */
static int WriteMC (FILE * mode) {
  fprintf (mode, "%dx%d", (int) mcintr_1.ncall0, mcintr_1.itmx0);
  return 0;
}

static int ReadMC (FILE * mode) {
  fscanf (mode, "%ldx%d", &mcintr_1.ncall0, &mcintr_1.itmx0);
  return 0;
}


/**********************************************/
/* R/W  */
static int WritePhysParameters (FILE * mode) {
  long i;
  double val;
  vshortstr name;
  fprintf (mode, "\n");
  for (i = 1; i <= nvar_; ++i) {
    vinf_ (i, name, &val);
    fprintf (mode, "%10s = %.15E\n", name, val);
  }
  return 0;
}

static int ReadPhysParameters (FILE * mode) {
  static double val;
  long i;
  vshortstr name1;
  vshortstr name2;

  for (i = 1; i <= nvar_; ++i) {
    if (2 != fscanf (mode, "%s = %lf", name1, &val)) {
      fprintf (stderr, "Error! Can not read parameter string...\n");
      return 2;
    }
    vinf_ (i, name2, NULL);
    if (strcmp (name1, name2)) {
      fprintf (stderr, "Error! Strange parameter names... name1 = %s, name2 = %s.\n", name1, name2);
      return 2;
    }
    asgn_ (i, val);
  }
  return 0;
}


/**********************************************/
/* R/W IN-state parameters */
static int WriteInitialState (FILE * mode) {
  double sqrt_S;
  vinf_ (0, NULL, &sqrt_S);
  fprintf (mode, "\n  SQRT(S) %E\n  Rapidity(c.m.s) %E\n", sqrt_S, rapidity);
  wrt_sf__ (mode);
  return 0;
}

static int ReadInitialState (FILE * mode) {
  double sqrt_S;
  midstr tmp;
  fgets (tmp, STRSIZ, mode);
  fgets (tmp, STRSIZ, mode);
  sscanf (tmp, "  SQRT(S) %lf", &sqrt_S);
  fgets (tmp, STRSIZ, mode);
  sscanf (tmp, "  Rapidity(c.m.s) %lf", &rapidity);
  asgn_ (0, sqrt_S);
  rd_sf__ (mode);
  return 0;
}


/**********************************************/
/* R/W model number */
static int nModel = 0;

static int WriteModelNumber(FILE * mode) {
  fprintf (mode, "%d", nModel);
  return 0;
}

static int ReadModelNumber(FILE * mode) {
  midstr tmp;
  fgets (tmp, STRSIZ, mode);
  sscanf (tmp, "%d", &nModel);
  return 0;
}

int getModelNumber (void) {
  int num = getModelNumberSymb ();
  return num;
}


/**********************************************/
/* R/W initial Random seed */
static int WriteRandom (FILE * f) {
  fprintf (f, "%s\n", seedXX (NULL));
  return 0;
}

static int ReadRandom (FILE * f) {
  static char s[128];
  fscanf (f, "%s", s);
  seedXX (s);
  return 0;
}


/**********************************************/
/* R/W width scheme choice */
static int WriteWidthScheme (FILE * f) {
  fprintf (f, " %i\n", gwidth);
  return 0;
}

static int ReadWidthScheme (FILE * f) {
  fscanf (f, " %i", &gwidth);
  return 0;
}


/**********************************************/
/* Session reader and writer */
int w_sess__ (FILE * mode_) {
  int NumberOfStrings_in_session = 17;
  int NumberOfStrings_in_prt = 11;
  FILE * mode;

  rw_paragraph wrt_array[17] =
  {
    {"Subprocess",          WriteSubprocessInfo},
    {"Session_number",      WriteSessionNumber},
    {"Model_number",        WriteModelNumber},
    {"Initial_state",       WriteInitialState},
    {"Physical_Parameters", WritePhysParameters},
    {"Width_scheme",        WriteWidthScheme},
    {"Kinematical_scheme",  WriteKinScheme},
    {"Cuts",                WriteCuts},
    {"Regularization",      WriteRegularisations},
    {"QCD",                 WriteQCDInfo},
    {"Vegas_calls",         WriteMC},
    {"Vegas_integral",      WriteIntegral},
    {"Distributions",       WriteHistograms},
    {"Events",              WriteEventSettings},
    {"Random",              WriteRandom},
    {"VEGAS_Grid",          WriteVegasGrid},
    {"MAX",                 WriteEventMax}
  };

  if (nin_ == 1) {
    wrt_array[2].rw_command = NULL;
  }

  if (mode_ == NULL) {
    char fname[100];
    sprintf (fname, "%ssession.dat", outputDir);
    mode = fopen (fname, "w");
    if (mode == NULL) {
      return 0;
    }
  } else {
    mode = mode_;
  }

  if (mode_ == NULL) {
    writeParagraphs (mode, NumberOfStrings_in_session, wrt_array);
    fclose (mode);
  } else {
    writeParagraphs (mode, NumberOfStrings_in_prt, wrt_array);
  }

  return 0;
}


int r_sess__ (FILE * mode_) {
  int NumberOfStrings = 17;
  FILE * mode;

  rw_paragraph rd_array[17] =
  {
    {"Subprocess",          ReadSubprocessInfo},
    {"Session_number",      ReadSessionNumber},
    {"Model_number",        ReadModelNumber},
    {"Initial_state",       ReadInitialState},
    {"Physical_Parameters", ReadPhysParameters},
    {"Width_scheme",        ReadWidthScheme},
    {"Kinematical_scheme",  ReadKinScheme},
    {"Cuts",                ReadCuts},
    {"Regularization",      ReadRegularisations},
    {"QCD",                 ReadQCDInfo},
    {"Distributions",       ReadHistograms},
    {"Vegas_integral",      ReadIntegral},
    {"Vegas_calls",         ReadMC},
    {"Events",              ReadEventSettings},
    {"Random",              ReadRandom},
    {"VEGAS_Grid",          ReadVegasGrid},
    {"MAX",                 ReadEventMax}
  };

  mode = fopen ("session.dat", "r");
  if (mode == NULL) {
    fprintf (stderr, "Warning! Can not open session.dat! Dummy session.dat will be created.\n");
    return 0;
  }
  readParagraphs (mode, NumberOfStrings, rd_array);
  fclose (mode);
  return 0;
}


void inipar_ (void) {
  InitSubprocessString ();     /* structure process from the comphep output file */
  InitSessionNumber (); /* session number = 1 */
  InitKinScheme ();
  InitQCDInfo ();
  rapidity = 0;
  gwidth = 0;
}


void clearSession (void) {
  cleartab (&cutTab);
  cleartab (&regTab);
  cleartab (&histTab);
  clearHists ();
}
