/* 
   * Copyright (C) 1997, Alexander Pukhov 
   * with changes by V.Ilyin for #-mdl, 6 Sept 2000, 8 Oct 2000.
   * Copyright (C) 2001-2003, CompHEP Collaboration
   *------------------------------------------------------
   * $Id: strfun.c,v 1.16 2003/11/08 19:46:05 kryukov Exp $
   *
   * $Log: strfun.c,v $
   * Revision 1.16  2003/11/08 19:46:05  kryukov
   * To bring into according the usage of messanykey and warnanykey functions.
   *
   * Revision 1.15  2003/11/07 21:23:29  sherstnv
   * Bug has been fixed: if a process has a model particle with no strfun,
   * session.dat generated by s_comphep contains string
   * StrFun2: PDF:OFF
   * The string can not be interpeted by n_comphep (warning is output
   * before a X-session is opened.
   *
   * Revision 1.14  2003/07/11 20:34:24  kryukov
   * both #partons must or must not have PDF
   *
   * Revision 1.13  2003/06/25 18:46:41  kryukov
   * *** empty log message ***
   *
   * Revision 1.12  2003/04/22 09:01:19  kryukov
   * Apply indent to improve readability of files
   *
   * Revision 1.11  2003/04/19 18:33:17  kryukov
   * Change structure of PDF/spectrum menus.
   *
   * Revision 1.10  2003/04/03 21:26:52  sherstnv
   * Ispravlen bug: esli v nachalnom sostoyanii est' ne hash-particle,
   * to n_comphep ne mog sravnit' pdfName u dvuh nachal'nih puchkov
   * i padal

   Revision 1.9  2003/04/03 20:20:25  sherstnv
   Dlya ISR electrona izmeneni vozmozhnie imenya electronov:
   Bilo: e1,E1
   Stalo:e,E,e1,E1
   Takzhe ispravlen bug v strfun.c:
   teper' ne sravnimaetsya strFun iz sf_pdf.c ise 2-ya
   nachalnaya chastitsa nee hash chastitsa.

   Revision 1.8  2003/03/30 17:16:42  sherstnv
   Ispravlen bug v raspredelenii pamyati v tag_parser.c

   Revision 1.7  2003/03/17 11:06:09  sherstnv
   A bug in strfun_ has been fixed

   Revision 1.6  2003/03/09 10:46:56  sherstnv
   New method to call strfun: for given phase space point structure function
   is called just one time. (structure functions may be factorizable on not)

   Revision 1.5  2003/03/01 09:39:30  sherstnv
   Checks in strfun_ are simplified

   Revision 1.4  2003/02/23 22:38:16  sherstnv
   Function strfun has been developed with single
   checks of initial particle names for #-models

   Revision 1.2  2003/02/23 17:58:10  sherstnv
   Bug with D#,D# initial state has been fixed. Structure of
   strfun function has been changed (switch operator) 
 */

#include <stdio.h>
#include "chep_crt/include/crt_util.h"
#include "chep_crt/include/syst.h"
#include "service2/include/tptcmac.h"
#include "out_ext.h"
#include"f_c.h"

#include"num/include/subproc.h"
#include"num/include/sf_epa.h"
#include"num/include/sf_isr.h"
#include"num/include/sf_lsr.h"
#include"num/include/sf_pdf.h"
#include"num/include/sf_mrs.h"
#include"num/include/events.h"
#include"num/include/strfun.h"

#define MAXFUN 4
#define FUNLEN 40

int sf_num[2] =
{0, 0};				/* switched off */
double sf_mass[2] =
{0, 0};
double sf_be[2] =
{0, 0};

static int uprt[2], dprt[2], Uprt[21], Dprt[2];
static int beam[2];

static struct
  {
    int (*myParticle) (char *);
    void (*fullName) (int, char *);
    void (*realSTRFUN_info) (int, Str_fun_Info *);
    int (*readName) (int, char *);
    int (*menu) (int);
    int (*init) (int, double *, double *);
    double (*val) (int, double, double);
  }
strFun[MAXFUN] =
{
  {
    p_epa__, n_epa__, info_epa__, r_epa__, m_epa__, i_epa__, c_epa__
  }
  ,
  {
    p_lsr__, n_lsr__, info_lsr__, r_lsr__, m_lsr__, i_lsr__, c_lsr__
  }
  ,
  {
    p_isr__, n_isr__, info_isr__, r_isr__, m_isr__, i_isr__, c_isr__
  }
  ,
  {
    p_pdf, n_pdf, info_pdf, r_pdf, m_pdf, be_pdf, c_pdf
  }
  ,
/*                     {p_mrs__,n_mrs__,info_mrs__,r_mrs__,m_mrs__,i_mrs__,c_mrs__}, */
};

int 
initStrFun (void)
{
  int l, i;
  char p_name[100];
  int returnCode = 0;

  alphaMode = 0;
  if (nin_ != 2)
    return returnCode;

  for (i = 0; i < 2; i++)
    {
      l = sf_num[i];
      sf_be[i] = 0.;
      if (l)
	{
	  l--;
	  pinf_ (proces_1.nsub, i + 1, p_name, NULL);
	  if (!strFun[l].myParticle (p_name) || !strFun[l].init (i + 1, sf_be + i, sf_mass + i))
	    {
	      sf_num[i] = 0;
	      fprintf (stderr, "\n%i-th Stucture function is switched OFF.\n",i+1);
	      returnCode = 2;
	    }
	  else
	    {
	      beam[i] = -1;
	      if (!strchr (p_name, 35))
		beam[i] = 0;
	      else if (!strcmp (p_name, "u#"))
		beam[i] = 1;
	      else if (!strcmp (p_name, "U#"))
		beam[i] = 2;
	      else if (!strcmp (p_name, "d#"))
		beam[i] = 3;
	      else if (!strcmp (p_name, "D#"))
		beam[i] = 4;
	      else if (!strcmp (p_name, "q#"))
		beam[i] = 5;
	      else if (!strcmp (p_name, "Q#"))
		beam[i] = 6;
	      else
		{
		  fprintf (stderr, "***Error! function: initStrFun, unknown initial particle = %s!\n", p_name);
		  exit (2);
		}

	      dprt[0] = 9;
	      uprt[0] = 8;
	      Uprt[0] = 6;
	      Dprt[0] = 5;
	      if (1 == i)
		{
		  dprt[1] = 9;
		  uprt[1] = 8;
		  Uprt[1] = 6;
		  Dprt[1] = 5;
		  if (beam[0] > 0 && beam[1] > 0)
		    {
		      if (!pdfnamecmp ())
			{
			  dprt[1] = 5;
			  uprt[1] = 6;
			  Uprt[1] = 8;
			  Dprt[1] = 9;
			}
		    }
		}
	    }
	}
    }
  return returnCode;
}


void 
strFunName (int i, char *mess)
{
  if (sf_num[i - 1])
    {
      strFun[sf_num[i - 1] - 1].fullName (i, mess);
    }
  else
    {
      strcpy (mess, "OFF");
    }
  if (!strncmp (mess, "PDF:OFF", 7))
    {
      strcpy (mess, "OFF");
      sf_num[i - 1] = 0;
    }
}

int 
sf_menu (int i)
{
  int k;
  char name[STRSIZ];
  int nfun[MAXFUN];
  char p_name__[10];
  char strmen[2 + MAXFUN * (FUNLEN + 1)];

  void *pscr = NULL;
  int mode, l;

  strmen[0] = FUNLEN + 1;

  pinf_ (proces_1.nsub, i, p_name__, NULL);

  sprintf (strmen + 1, " %-*.*s", FUNLEN, FUNLEN, "OFF");

  k = 0;
  for (l = 0; l < MAXFUN; l++)
    {
      int ju;
      ju = strFun[l].myParticle (p_name__);
      if (ju)
	{
	  nfun[k++] = l;
	  strFun[l].fullName (i, name);
	  sprintf (strmen + 1 + (FUNLEN + 1) * k, " %-*.*s", FUNLEN, FUNLEN, name);
	}
    }
  if (!k)
    {
      warnanykey (15, 15, "Structure functions for this particle\n"
		  "are not known\n");
      return 0;
    }

  if (strncmp (name, "PDF:", 4))	/* Not parton */
    {
      menu1 (77 - FUNLEN, 7, "", strmen, "n_strfun", &pscr, &mode);
      if (mode == 0)
	return 0;
      if (mode == 1)
	sf_num[i - 1] = 0;
      else
	{
	  strFun[nfun[mode - 2]].menu (i);
	  sf_num[i - 1] = nfun[mode - 2] + 1;
	}
      put_text (&pscr);
      return 1;
    }

  mode = strFun[nfun[0]].menu (i);
  switch (mode)
    {
    case 0:
      return 0;
    case 1:
      sf_num[i - 1] = 0;
      break;
    default:
      sf_num[i - 1] = nfun[0] + 1;
    }
  return 1;
}				/* sf_menu__ */


static double 
strfun_f (int i, double x, double q)
{
  switch (beam[i - 1])
    {
    case 0:
      return strFun[sf_num[i - 1] - 1].val (i, x, q);	/* standard parton */
      break;
    case 1:			/* f_u(x)+f_c(x) */
      return strFun[sf_num[i - 1] - 1].val (uprt[i - 1], x, q) + strFun[sf_num[i - 1] - 1].val (3, x, q);
      break;
    case 2:			/* f_U(x)+f_C(x) */
      return strFun[sf_num[i - 1] - 1].val (Uprt[i - 1], x, q) + strFun[sf_num[i - 1] - 1].val (3, x, q);
      break;
    case 3:			/* f_d(x)+f_s(x) */
      return strFun[sf_num[i - 1] - 1].val (dprt[i - 1], x, q) + strFun[sf_num[i - 1] - 1].val (4, x, q);
      break;
    case 4:			/* f_U(x)+f_S(x) */
      return strFun[sf_num[i - 1] - 1].val (Dprt[i - 1], x, q) + strFun[sf_num[i - 1] - 1].val (4, x, q);
      break;
    case 5:			/* f_u(x)+f_d(x)+f_s(x)+f_c(x) */
      return
	strFun[sf_num[i - 1] - 1].val (3, x, q)
	+ strFun[sf_num[i - 1] - 1].val (4, x, q)
	+ strFun[sf_num[i - 1] - 1].val (uprt[i - 1], x, q)
	+ strFun[sf_num[i - 1] - 1].val (dprt[i - 1], x, q);
      break;
    case 6:			/* f_U(x)+f_D(x)+f_S(x)+f_C(x) */
      return
	strFun[sf_num[i - 1] - 1].val (3, x, q)
	+ strFun[sf_num[i - 1] - 1].val (4, x, q)
	+ strFun[sf_num[i - 1] - 1].val (Uprt[i - 1], x, q)
	+ strFun[sf_num[i - 1] - 1].val (Dprt[i - 1], x, q);
      break;
    }
  fprintf (stderr, "***Error! function: strfun_f, unknown particle!\n");
  return 0.0;
}				/* strfun_f */


static double 
strfun_nonf (double x, double y, double q)
{
  double sinc2 = 0.221 * 0.221;	/* sin of Cabbibo angle squared */
  double cosc2 = 1. - sinc2;

  switch (beam[1] + 10 * beam[0])
    {
    case 0:
      return strFun[sf_num[0] - 1].val (1, x, q) * strFun[sf_num[0] - 1].val (2, y, q);		/* standard parton */
      break;
    case 12:			/* f_u(x)*f_U(y)+f_c(x)*f_C(y) */
      return
	strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q);
      break;
    case 21:			/* f_U(x)*f_u(y)+f_C(x)*f_c(y) */
      return
	strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q);
      break;
    case 34:			/* f_d(x)*f_D(y)+f_s(x)*f_S(y) */
      return
	strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q);
      break;
    case 43:			/* f_D(x)*f_d(y)+f_S(x)*f_s(y) */
      return
	strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q);
      break;
    case 13:			/* f_u(x)*f_d(y)*cosc2+f_u(x)*f_s(y)*sinc2+f_c(x)*f_d(y)*sinc2+f_c(x)*f_s(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (4, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (4, y, q) * cosc2;
      break;
    case 31:			/* f_d(x)*f_u(y)*cosc2+f_s(x)*f_u(y)*sinc2+f_d(x)*f_c(y)*sinc2+f_s(x)*f_c(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (3, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (3, y, q) * cosc2;
      break;
    case 14:			/* f_u(x)*f_D(y)*cosc2+f_u(x)*f_S(y)*sinc2+f_c(x)*f_D(y)*sinc2+f_c(x)*f_S(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (4, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (4, y, q) * cosc2;
      break;
    case 41:			/* f_D(x)*f_u(y)*cosc2+f_S(x)*f_u(y)*sinc2+f_D(x)*f_c(y)*sinc2+f_S(x)*f_c(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (3, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (3, y, q) * cosc2;
      break;
    case 23:			/* f_U(x)*f_d(y)*cosc2+f_C(x)*f_d(y)*sinc2+f_U(x)*f_s(y)*sinc2+f_C(x)*f_s(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (4, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (4, y, q) * cosc2;
      break;
    case 32:			/* f_d(x)*f_U(y)*cosc2+f_d(x)*f_C(y)*sinc2+f_s(x)*f_U(y)*sinc2+f_s(x)*f_C(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (3, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (3, y, q) * cosc2;
      break;
    case 24:			/* f_U(x)*f_D(y)*cosc2+f_C(x)*f_D(y)*sinc2+f_U(x)*f_S(y)*sinc2+f_C(x)*f_S(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (4, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (4, y, q) * cosc2;
      break;
    case 42:			/* f_D(x)*f_U(y)*cosc2+f_D(x)*f_C(y)*sinc2+f_S(x)*f_U(y)*sinc2+f_S(x)*f_C(y)*cosc2 */
      return
	strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q) * cosc2
	+ strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (3, y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q) * sinc2
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (3, y, q) * cosc2;
      break;
    case 11:			/* f_u(x)*f_u(y)+f_c(x)*f_c(y) */
      return
	strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q);
      break;
    case 22:			/* f_U(x)*f_U(y)+f_C(x)*f_c(y) */
      return
	strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q);
      break;
    case 33:			/* f_d(x)*f_d(y)+f_s(x)*f_s(y) */
      return
	strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q);
      break;
    case 44:			/* f_D(x)*f_D(y)+f_S(x)*f_S(y) */
      return
	strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q);
      break;
    case 56:			/*f_u(x)*f_U(y)+f_d(x)*f_D(y)+f_c(x)*f_C(y)+f_s(x)*f_S(y) */
      return
	strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q);
      break;
    case 65:			/*f_U(x)*f_u(y)+f_D(x)*f_d(y)+f_C(x)*f_c(y)+f_S(x)*f_s(y) */
      return
	strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q);
      break;
    case 55:			/* f_d(x)*f_d(y)+f_u(x)*f_u(y)+f_s(x)*f_s(y)+f_c(x)*f_c(y) */
      return
	strFun[sf_num[0] - 1].val (uprt[0], x, q) * strFun[sf_num[1] - 1].val (uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (dprt[0], x, q) * strFun[sf_num[1] - 1].val (dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q);
      break;
    case 66:			/* f_D(x)*f_D(y)+f_U(x)*f_U(y)+f_S(x)*f_S(y)+f_C(x)*f_C(y) */
      return
	strFun[sf_num[0] - 1].val (Uprt[0], x, q) * strFun[sf_num[1] - 1].val (Uprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (Dprt[0], x, q) * strFun[sf_num[1] - 1].val (Dprt[1], y, q)
	+ strFun[sf_num[0] - 1].val (3, x, q) * strFun[sf_num[1] - 1].val (3, y, q)
	+ strFun[sf_num[0] - 1].val (4, x, q) * strFun[sf_num[1] - 1].val (4, y, q);
      break;
    }
  fprintf (stderr, "***Error! function: strfun_nonf, unknown particle!\n");
  return 0.0;
}				/* strfun_nonf */


double 
strfun_ (int factr, double x, double y, double q)
{
  double xstr, xstr1, xstr2;

  if (factr)
    {
      if (sf_num[0])
	xstr1 = strfun_f (1, x, q);
      else
	xstr1 = 1.0;
      if (sf_num[1])
	  
	xstr2 = strfun_f (2, y, q);
      else
	xstr2 = 1.0;
      xstr = xstr1 * xstr2;
    }
  else
    {
      if (!sf_num[0] && !sf_num[1])
	xstr = 1.0;
      else if (sf_num[0] && sf_num[1])
	xstr = strfun_nonf (x, y, q);
      else
	{
	  fprintf (stderr, "***** strfun_: In non-factorize case both parton must have PDF\n");
	  xstr = 0.0;
	}
    }
  if (!finite (xstr))
    fprintf (stderr, "***Error! x= %18.15g, y=%18.15g, q=%18.15g, xstr=%18.15g\n", x, y, q, xstr);
  return xstr;
}				/* strfun_ */


int 
rd_sf__ (FILE * mode)
{
  char sf_txt[2][STRSIZ];
  char p_name[100];
  int l, i;

  for (i = 0; i < 2; i++)
    sf_num[i] = 0;

  if (2 != fscanf (mode, "  StrFun1: %[^\n]\n  StrFun2: %[^\n]\n", sf_txt[0], sf_txt[1]))
    return 1;
  for (i = 0; i < 2; i++)
    {
      pinf_ (proces_1.nsub, i + 1, p_name, NULL);
      for (l = 0; l < MAXFUN; l++)
	if (strFun[l].myParticle (p_name) && strFun[l].readName (i + 1, sf_txt[i]))
	  {
	    sf_num[i] = l + 1;
	    break;
	  }
    }
  initStrFun ();
  return 0;
}

int 
wrt_sf__ (FILE * mode)
{
  char sf_txt[2][STRSIZ];
  int i;

  for (i = 0; i < 2; i++)
    {
      fprintf (mode, "  StrFun%d: ", i + 1);
      if (sf_num[i])
	strFun[sf_num[i] - 1].fullName (i + 1, sf_txt[i]);
      else
	strcpy (sf_txt[i], "OFF");
      fprintf (mode, "%s\n", sf_txt[i]);
    }
  return 0;
}

void 
wrt_sf_NF_ (int i, Str_fun_Info * info)
{

  if (sf_num[i])
    strFun[sf_num[i] - 1].realSTRFUN_info (i, info);
  else
    {
      double part_mass;
      char part_name[10];

      strcpy (info->pdf_name, "OFF");
      pinf_ (proces_1.nsub, i + 1, part_name, &part_mass);
      strcpy (info->prt_name, part_name);
      info->prt_mass = part_mass;
      info->N_extra_commands = 0;
      snprintf (info->version, 1, " ");
    }
}
