/************************************************
* Copyright (C) 2000-2003, CompHEP Collaboration
* Author: Alexandre Sherstnev 
*------------------------------------------------
* $Id: fill_tags.c,v 1.7 2003/11/15 20:54:23 kryukov Exp $
*
* $Log: fill_tags.c,v $
* Revision 1.7  2003/11/15 20:54:23  kryukov
* Some small bugs
*
* Revision 1.6  2003/07/20 14:34:37  kryukov
* Change width menu. Remove rwidth global vars.
* gwidth=0(fix), 1(overall), 2(running).
*
*************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "out_ext.h"

#include "cut.h"
#include "kfcodes.h"
#include "kinaux.h"
#include "runVegas.h"
#include "strfun.h"
#include "subproc.h"
#include "tag_reader.h"
#include "tag_parser.h"
#include "pdf.h"
#include "fill_tags.h"


tags *
init_cap_info (void)
{
  int i, j;
  int prtn = 0;
  int cutn = 0;
  int sum;
  int PDFid, PDFgr, nl;
  double lambda;
  double sqrtS;
  Str_fun_Info strfun[2];
  tags *t;

  for (i = 1; i <= nin_ + nout_; i++)
    {
      char buf[10];
      pinf_ (proces_1.nsub, i, buf, NULL);
      if (buf != NULL)
	prtn++;
    }

  cutn = get_cutn ();
  t = init_cap (prtn + cutn + 10);

/*  beams and structure function info */
  for (i = 0; i < 2; i++)
    wrt_sf_NF_ (i, &strfun[i]);
  vinf_ (0, NULL, &sqrtS);
  for (i = 0; i < 2; i++)
    {
      double p, e;

      e = (sqrtS * sqrtS + strfun[i].prt_mass * strfun[i].prt_mass - strfun[1 - i].prt_mass * strfun[1 - i].prt_mass) / (2 * sqrtS);
      p = sqrt (e * e - strfun[i].prt_mass * strfun[i].prt_mass);
      p = p * cosh (rapidity) + e * sinh (rapidity) * (1 - 2 * i);
      if (p * p < (10.E-10) * sqrtS)
	p = 0.0;

      t->tag[i] = init_tag (5);
      sprintf (t->tag[i]->tagname, "beam");
      sprintf (t->tag[i]->commands[0], "ID=%i", i + 1);
      sprintf (t->tag[i]->commands[1], "energy=%.5E", p);
      sprintf (t->tag[i]->commands[2], "KF=%i", kfbeam (strfun[i].prt_name));
      sprintf (t->tag[i]->commands[3], "name=\'%s\'", strfun[i].prt_name);
      sprintf (t->tag[i]->commands[4], "mass=%.5E", strfun[i].prt_mass);

      t->tag[i + 2] = init_tag (3 + strfun[i].N_extra_commands);
      sprintf (t->tag[i + 2]->tagname, "strfun");
      sprintf (t->tag[i + 2]->commands[0], "IDbeam=%i", i + 1);
      sprintf (t->tag[i + 2]->commands[1], "name=\'%s\'", strfun[i].pdf_name);
      sprintf (t->tag[i + 2]->commands[2], "version=\'%s\'", strfun[i].version);
      for (j = 0; j < strfun[i].N_extra_commands; j++)
	sprintf (t->tag[i + 2]->commands[j + 3], "%s", strfun[i].extra_commands[j]);
    }

  t->tag[4] = init_tag (6);
  sprintf (t->tag[4]->tagname, "process");
  sprintf (t->tag[4]->commands[0], "ID=1");
  {
    int k, kk;
    int len = strlen (proces_1.proces);
    char *name = malloc (len * sizeof (char));
    kk = 0;
    for (k = 0; k < len; k++)
      if (',' != proces_1.proces[k])
	{
	  name[kk] = proces_1.proces[k];
	  kk++;
	}
    name[kk] = '\0';
    sprintf (t->tag[4]->commands[1], "name=\'%s\'", name);
    free (name);
  }
  sprintf (t->tag[4]->commands[2], "CrosSec=%.5E", 0.0);
  sprintf (t->tag[4]->commands[3], "CrosSecErr=%.5E", 0.0);
  sprintf (t->tag[4]->commands[4], "Nparton=%i", prtn);
  sprintf (t->tag[4]->commands[5], "master=3");

  t->tag[5] = init_tag (3);
  sprintf (t->tag[5]->tagname, "generator");
  sprintf (t->tag[5]->commands[0], "IDprocess=1");
  sprintf (t->tag[5]->commands[1], "name=\'CompHEP\'");
  sprintf (t->tag[5]->commands[2], "name=\'4.4.00\'");

  t->tag[6] = init_tag (5);
  sprintf (t->tag[6]->tagname, "n_event");
  sprintf (t->tag[6]->commands[0], "IDprocess=1");
  sprintf (t->tag[6]->commands[1], "N=       0");
  sprintf (t->tag[6]->commands[2], "mult=%.5E", 0.0);
  sprintf (t->tag[6]->commands[3], "maxW=%.5E", 0.0);
  sprintf (t->tag[6]->commands[4], "CutN=%i", cutn);

//      partons info    //
  for (i = 1; i <= prtn; i++)
    {
      double part_mass;
      char part_name[10];

      t->tag[i + 6] = init_tag (6);
      sprintf (t->tag[i + 6]->tagname, "parton");
      sprintf (t->tag[i + 6]->commands[0], "IDprocess=1");
      if (i <= 2)
	{
	  sprintf (t->tag[i + 6]->commands[1], "in=%i", i);
	  sprintf (t->tag[i + 6]->commands[2], "out=0");
	}
      else
	{
	  sprintf (t->tag[i + 6]->commands[1], "in=0");
	  sprintf (t->tag[i + 6]->commands[2], "out=%i", i);
	}
      pinf_ (proces_1.nsub, i, part_name, &part_mass);
      sprintf (t->tag[i + 6]->commands[3], "KF=%i", kfbeam (part_name));
      sprintf (t->tag[i + 6]->commands[4], "name=\'%s\'", part_name);
      sprintf (t->tag[i + 6]->commands[5], "mass=%.5E", part_mass);
    }

  for (i = 0; i < cutn; i++)
    {
      char parts[PLISTLEN];
      int k = 0;

      t->tag[i + prtn + 7] = init_tag (5);
      sprintf (t->tag[i + prtn + 7]->tagname, "cut");
      sprintf (t->tag[i + prtn + 7]->commands[0], "IDprocess=1");
      j = 0;
      while (invcut_1[i].lvinvc[j])
	{
	  parts[j] = invcut_1[i].lvinvc[j] + '0';
	  j++;
	}
      parts[j] = '\0';
      sprintf (t->tag[i + prtn + 7]->commands[1], "var=\'%c%s\'", invcut_1[i].key, parts);
      if (invcut_1[i].minon)
	{
	  k++;
	  sprintf (t->tag[i + prtn + 7]->commands[1 + k], "min=%.5E", invcut_1[i].cvmin);
	}
      if (invcut_1[i].maxon)
	{
	  k++;
	  sprintf (t->tag[i + prtn + 7]->commands[1 + k], "max=%.5E", invcut_1[i].cvmax);
	}
      if (invcut_1[i].key != 'U')
	sprintf (t->tag[i + prtn + 7]->commands[2 + k], "reg=1");
      else
	{
	  sprintf (t->tag[i + prtn + 7]->commands[2 + k], "reg=0");
	  sprintf (t->tag[i + prtn + 7]->commands[3 + k], "filename='userFun.c'");
	}
    }
  sum = prtn + cutn - 1;

  t->tag[sum + 8] = init_tag (4);
  sprintf (t->tag[sum + 8]->tagname, "QCDinfo");
  sprintf (t->tag[sum + 8]->commands[0], "IDprocess=1");
  CERNpdf_number (strfun[0].pdf_name, strfun[0].version, &PDFid, &PDFgr);
  nl=2;
  if(4==PDFgr && (32==PDFid || 46==PDFid || 58==PDFid)) nl=1;
  sprintf (t->tag[sum + 8]->commands[1], "NL=%i",nl);
  sprintf (t->tag[sum + 8]->commands[2], "Nflavour=%i", 5);
  lambda = QCDLambda();
  sprintf (t->tag[sum + 8]->commands[3], "QCDLambda=%.5E", lambda);

  t->tag[sum + 9] = init_tag (3 * prtn);
  sprintf (t->tag[sum + 9]->tagname, "format");
  sprintf (t->tag[sum + 9]->commands[0], "IDprocess=1");
  sprintf (t->tag[sum + 9]->commands[1], "ProcNumber='%i'");
  sprintf (t->tag[sum + 9]->commands[2], "p1.3='17.10E'");
  sprintf (t->tag[sum + 9]->commands[3], "p2.3='17.10E'");
  for (i = 2; i < prtn; i++)
    {
      sprintf (t->tag[sum + 9]->commands[3 * i - 2], "p%i.1='17.10E'", i + 1);
      sprintf (t->tag[sum + 9]->commands[3 * i - 1], "p%i.2='17.10E'", i + 1);
      sprintf (t->tag[sum + 9]->commands[3 * i], "p%i.3='17.10E'", i + 1);
    }
  sprintf (t->tag[sum + 9]->commands[3 * prtn - 2], "Qsquared='10.3E'");
  sprintf (t->tag[sum + 9]->commands[3 * prtn - 1], "color_chain='string'");

  t->tag[sum + 10] = init_tag (4);
  sprintf (t->tag[sum + 10]->tagname, "total");
  sprintf (t->tag[sum + 10]->commands[0], "Nproc=1");
  sprintf (t->tag[sum + 10]->commands[1], "Nevent=       0");
  sprintf (t->tag[sum + 10]->commands[2], "CrosSec=%.5E", 0.0);
  sprintf (t->tag[sum + 10]->commands[3], "CrosSecErr=%.5E", 0.0);
  return t;
}


void
full_free (tags * t)
{
  int i, j;
  for (i = 0; i < t->number_of_tags; i++)
    {
      for (j = 0; j < t->tag[i]->tagsize; j++)
	free (t->tag[i]->commands[j]);
      free (t->tag[i]);
    }
  free (t);
}
