⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 convi.c

📁 卷积程序
💻 C
字号:
/****************************************************************
 *	Functions for reading files.
 ****/

#include "conv.h"

/****************************************************************
 *	Get the filename and open it for reading, retry until the
 *	file can be opened, or a '.' is input.
 ****/
FILE       *
GetFile(char *Fname)
{
  FILE       *file = NULL;

  do {
    printf("Input filename of mcml output(or . to quit): ");
    scanf("%s", Fname);
    if (strlen(Fname) == 1 && Fname[0] == '.')
      break;

    file = fopen(Fname, "r");
  } while (file == NULL);

  return (file);
}

/****************************************************************
 *  Allocate the arrays for the original data from mcml
 *	computation in OutStruct for each run, and they are
 *	automatically initialized to zeros.
 *
 *  Returns 1 if successful, otherwise 0.
 ****/
Boolean 
AllocOrigData(InputStruct * In_Ptr,
	      OutStruct * Out_Ptr)
{
  short       nz = In_Ptr->nz;
  short       nr = In_Ptr->nr;
  short       na = In_Ptr->na;
  short       nl = In_Ptr->num_layers;	/* remember +2 for ambient. */

  if (nz <= 0 || nr <= 0 || na <= 0 || nl <= 0) {
    printf("Wrong grid parameters.\n");
    return (0);
  }
  /* Allocate the arrays and the matrices. */
  Out_Ptr->Rd_ra = AllocMatrix(0, nr - 1, 0, na - 1);
  Out_Ptr->Rd_r = AllocVector(0, nr - 1);
  Out_Ptr->Rd_a = AllocVector(0, na - 1);

  Out_Ptr->A_rz = AllocMatrix(0, nr - 1, 0, nz - 1);
  Out_Ptr->A_z = AllocVector(0, nz - 1);
  Out_Ptr->A_l = AllocVector(0, nl + 1);

  Out_Ptr->Tt_ra = AllocMatrix(0, nr - 1, 0, na - 1);
  Out_Ptr->Tt_r = AllocVector(0, nr - 1);
  Out_Ptr->Tt_a = AllocVector(0, na - 1);

  return (1);
}

/****************************************************************
 *  Allocate the arrays for convolution in OutStruct for each
 *	run, and they are automatically initialized to zeros.
 *
 *  Returns 1 if successful, otherwise 0.
 ****/
Boolean 
AllocConvData(InputStruct * In_Ptr,
	      OutStruct * Out_Ptr)
{
  short       nz = In_Ptr->nz;
  short       nr = In_Ptr->nrc;	/* use nrc instead of nr. */
  short       na = In_Ptr->na;

  if (nz <= 0 || nr <= 0 || na <= 0) {
    printf("Wrong grid parameters.\n");
    return (0);
  }
  Out_Ptr->Rd_rac = AllocMatrix(0, nr - 1, 0, na - 1);
  Out_Ptr->Rd_rc = AllocVector(0, nr - 1);
  Out_Ptr->A_rzc = AllocMatrix(0, nr - 1, 0, nz - 1);
  Out_Ptr->Tt_rac = AllocMatrix(0, nr - 1, 0, na - 1);
  Out_Ptr->Tt_rc = AllocVector(0, nr - 1);

  return (1);
}

/****************************************************************
 *  Free the arrays in OutStruct.
 ****/
void 
FreeOrigData(InputStruct * In_Ptr,
	     OutStruct * Out_Ptr)
{
  short       nz = In_Ptr->nz;
  short       nr = In_Ptr->nr;
  short       na = In_Ptr->na;
  short       nl = In_Ptr->num_layers;	/* remember +2 for ambient. */

  if (nz <= 0 || nr <= 0 || na <= 0 || nl <= 0) {
    printf("Wrong grid parameters.\n");
    return;
  }
  if (Out_Ptr->Rd_ra != NULL)
    FreeMatrix(Out_Ptr->Rd_ra, 0, nr - 1, 0, na - 1);
  if (Out_Ptr->Rd_r != NULL)
    FreeVector(Out_Ptr->Rd_r, 0, nr - 1);
  if (Out_Ptr->Rd_a != NULL)
    FreeVector(Out_Ptr->Rd_a, 0, na - 1);

  if (Out_Ptr->A_rz != NULL)
    FreeMatrix(Out_Ptr->A_rz, 0, nr - 1, 0, nz - 1);
  if (Out_Ptr->A_z != NULL)
    FreeVector(Out_Ptr->A_z, 0, nz - 1);
  if (Out_Ptr->A_l != NULL)
    FreeVector(Out_Ptr->A_l, 0, nl + 1);

  if (Out_Ptr->Tt_ra != NULL)
    FreeMatrix(Out_Ptr->Tt_ra, 0, nr - 1, 0, na - 1);
  if (Out_Ptr->Tt_r != NULL)
    FreeVector(Out_Ptr->Tt_r, 0, nr - 1);
  if (Out_Ptr->Tt_a != NULL)
    FreeVector(Out_Ptr->Tt_a, 0, na - 1);
}

/****************************************************************
 *  Free the arrays in OutStruct.
 ****/
void 
FreeConvData(InputStruct * In_Ptr,
	     OutStruct * Out_Ptr)
{
  short       nz = In_Ptr->nz;
  short       nr = In_Ptr->nrc;
  short       na = In_Ptr->na;

  if (nz <= 0 || nr <= 0 || na <= 0) {
    printf("Wrong grid parameters.\n");
    return;
  }
  if (Out_Ptr->Rd_rac != NULL)
    FreeMatrix(Out_Ptr->Rd_rac, 0, nr - 1, 0, na - 1);
  if (Out_Ptr->Rd_rc != NULL)
    FreeVector(Out_Ptr->Rd_rc, 0, nr - 1);
  if (Out_Ptr->A_rzc != NULL)
    FreeMatrix(Out_Ptr->A_rzc, 0, nr - 1, 0, nz - 1);
  if (Out_Ptr->Tt_rac != NULL)
    FreeMatrix(Out_Ptr->Tt_rac, 0, nr - 1, 0, na - 1);
  if (Out_Ptr->Tt_rc != NULL)
    FreeVector(Out_Ptr->Tt_rc, 0, nr - 1);
}

/****************************************************************
 * 	Kill the ith char (counting from 0), push the following chars
 *	forward by one.
 ****/
void 
KillChar(size_t i, char *Str)
{
  size_t      sl = strlen(Str);

  for (; i < sl; i++)
    Str[i] = Str[i + 1];
}

/****************************************************************
 *	Eliminate the chars in a string which are not printing chars
 *	or spaces.
 *
 *	Space include ' ', '\f', '\t' etc.
 *
 *	Return 1 if no nonprinting chars found, otherwise return 0.
 ****/
Boolean 
CheckChar(char *Str)
{
  Boolean     found = 0;
  size_t      sl = strlen(Str);
  size_t      i = 0;

  while (i < sl)
    if (isprint(Str[i]) || isspace(Str[i]))
      i++;
    else {
      found = 1;
      KillChar(i, Str);
      sl--;
    }

  return (found);

}

/****************************************************************
 *	Return 1 if this line is comment line in which the first
 *	non-space character is "#".
 *
 *	Also return 1 if this line is space line.
 ****/
Boolean 
CommentLine(char *Buf)
{
  size_t      spn, cspn;

  spn = strspn(Buf, " \t");
  /* length spanned by space or tab chars. */
  cspn = strcspn(Buf, "#\n");
  /* length before the 1st # or return. */
  if (spn == cspn)
    return (1);
  /* comment line or space line. */
  else
    return (0);			/* the line has data. */
}

/****************************************************************
 *	Skip space or comment lines and return data line only.
 ****/
char       *
FindDataLine(FILE * File_Ptr)
{
  static char        buf[STRLEN];

  do {				/* skip space or comment lines. */
    if (fgets(buf, STRLEN, File_Ptr) == NULL) {
      printf("Incomplete data.\n");
      exit(1);
    }
    CheckChar(buf);
  } while (CommentLine(buf));

  return (buf);
}

/****************************************************************
 *	Look for the key word, which is the 1st word in the line.
 ****/
Boolean 
FoundKeyWord(char *LineBuf, char *Key)
{
  char       *sub_str;
  Boolean     found = 0;

  if ((sub_str = strstr(LineBuf, Key)) != NULL)
    if (sub_str == LineBuf)
      found = 1;

  return (found);
}

/****************************************************************
 *
 ****/
void 
SeekKey(FILE * File_Ptr, char *Key)
{
  char        buf[STRLEN];

  do
    strcpy(buf, FindDataLine(File_Ptr));
  while (!FoundKeyWord(buf, Key));
}

/****************************************************************
 *
 ****/
void 
ReadLayerParm(FILE * File_Ptr,
	      short Num_Layers,
	      LayerStruct ** Layers_PP)
{
  char        buf[STRLEN];
  short       i = 0;
  double      d, n, mua, mus, g;
  double      z = 0.0;		/* z coordinate of the current layer. */

  /* layer 0 and layer Num_Layers + 1 are for ambient. */
  *Layers_PP = (LayerStruct *)
    malloc((unsigned) (Num_Layers + 2) * sizeof(LayerStruct));
  if (!(*Layers_PP))
    nrerror("allocation failure in ReadLayerParm()");

  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf", &n);
  (*Layers_PP)[i].n = n;
  for (i = 1; i <= Num_Layers; i++) {
    strcpy(buf, FindDataLine(File_Ptr));
    sscanf(buf, "%lf%lf%lf%lf%lf", &n, &mua, &mus, &g, &d);
    (*Layers_PP)[i].n = n;
    (*Layers_PP)[i].mua = mua;
    (*Layers_PP)[i].mus = mus;
    (*Layers_PP)[i].g = g;
    (*Layers_PP)[i].z0 = z;
    z += d;
    (*Layers_PP)[i].z1 = z;
  }
  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf", &n);
  (*Layers_PP)[i].n = n;
}

/****************************************************************
 *	Read in the input parameters which were used for Monte Carlo
 *	simulations.
 ****/
void 
ReadInParm(FILE * File_Ptr, InputStruct * In_Ptr)
{
  char        buf[STRLEN];

  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%c", &(In_Ptr->in_fformat));
  if (toupper(In_Ptr->in_fformat) != 'B')
    In_Ptr->in_fformat = 'A';

  /** Find the key word "InParm". */
  do
    strcpy(buf, FindDataLine(File_Ptr));
  while (!FoundKeyWord(buf, "InParm"));

  /** Escape filename & file format. */
  FindDataLine(File_Ptr);

  /** read in number of photons. **/
  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%ld", &In_Ptr->num_photons);

  /** assign in Wth (critical weight). **/
  In_Ptr->Wth = 1E-4;

  /** read in dz, dr. **/
  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf%lf", &In_Ptr->dz, &In_Ptr->dr);

  /** read in nz, nr, na and compute da. **/
  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%hd%hd%hd", &In_Ptr->nz,
	 &In_Ptr->nr, &In_Ptr->na);
  In_Ptr->da = 0.5 * PI / In_Ptr->na;

  /** read in number of layers. **/
  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%hd", &In_Ptr->num_layers);

  ReadLayerParm(File_Ptr, In_Ptr->num_layers,
		&In_Ptr->layerspecs);
}

/****************************************************************
 *	Read reflectance, absorbed fraction, transmittance.
 ****/
void 
ReadRAT(FILE * File_Ptr,
	OutStruct * Out_Ptr)
{
  char        buf[STRLEN];

  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf", &(Out_Ptr->Rsp));

  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf", &(Out_Ptr->Rd));

  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf", &(Out_Ptr->A));

  strcpy(buf, FindDataLine(File_Ptr));
  sscanf(buf, "%lf", &(Out_Ptr->Tt));
}

/****************************************************************
 ****/
void 
ReadA_layer(FILE * File_Ptr,
	    short Num_Layers,
	    OutStruct * Out_Ptr)
{
  char        buf[STRLEN];
  short       i;

  for (i = 1; i <= Num_Layers; i++) {
    strcpy(buf, FindDataLine(File_Ptr));
    sscanf(buf, "%lf", &(Out_Ptr->A_l[i]));
  }
}

/****************************************************************
 ****/
void 
ReadA_z(FILE * File_Ptr,
	short Nz,
	OutStruct * Out_Ptr)
{
  char        buf[STRLEN];
  short       i;

  for (i = 0; i < Nz; i++) {
    strcpy(buf, FindDataLine(File_Ptr));
    sscanf(buf, "%lf", &(Out_Ptr->A_z[i]));
  }
}

/****************************************************************
 ****/
void 
ReadRd_r(FILE * File_Ptr,
	 short Nr,
	 OutStruct * Out_Ptr)
{
  char        buf[STRLEN];
  short       i;

  for (i = 0; i < Nr; i++) {
    strcpy(buf, FindDataLine(File_Ptr));
    sscanf(buf, "%lf", &(Out_Ptr->Rd_r[i]));
  }
}

/****************************************************************
 ****/
void 
ReadRd_a(FILE * File_Ptr,
	 short Na,
	 OutStruct * Out_Ptr)
{
  char        buf[STRLEN];
  short       i;

  for (i = 0; i < Na; i++) {
    strcpy(buf, FindDataLine(File_Ptr));
    sscanf(buf, "%lf", &(Out_Ptr->Rd_a[i]));
  }
}

/****************************************************************
 ****/
void 
ReadTt_r(FILE * File_Ptr,
	 short Nr,
	 OutStruct * Out_Ptr)
{
  char        buf[STRLEN];
  short       i;

  for (i = 0; i < Nr; i++) {
    strcpy(buf, FindDataLine(File_Ptr));
    sscanf(buf, "%lf", &(Out_Ptr->Tt_r[i]));
  }
}

/****************************************************************
 ****/
void 
ReadTt_a(FILE * File_Ptr,
	 short Na,
	 OutStruct * Out_Ptr)
{
  char        buf[STRLEN];
  short       i;

  for (i = 0; i < Na; i++) {
    /*
     * strcpy(buf, FindDataLine(File_Ptr)); sscanf(buf, "%lf",
     * &(Out_Ptr->Tt_a[i]));
     */
    fscanf(File_Ptr, "%lf", &(Out_Ptr->Tt_a[i]));
  }
}

/****************************************************************
 ****/
void 
ReadA_rz(FILE * File_Ptr,
	 short Nr,
	 short Nz,
	 OutStruct * Out_Ptr)
{
  short       iz, ir;

  for (ir = 0; ir < Nr; ir++)
    for (iz = 0; iz < Nz; iz++)
      fscanf(File_Ptr, "%lf ", &(Out_Ptr->A_rz[ir][iz]));
}

/****************************************************************
 ****/
void 
ReadRd_ra(FILE * File_Ptr,
	  short Nr,
	  short Na,
	  OutStruct * Out_Ptr)
{
  short       ir, ia;

  for (ir = 0; ir < Nr; ir++)
    for (ia = 0; ia < Na; ia++)
      fscanf(File_Ptr, "%lf ", &(Out_Ptr->Rd_ra[ir][ia]));
}

/****************************************************************
 ****/
void 
ReadTt_ra(FILE * File_Ptr,
	  short Nr,
	  short Na,
	  OutStruct * Out_Ptr)
{
  short       ir, ia;

  for (ir = 0; ir < Nr; ir++)
    for (ia = 0; ia < Na; ia++)
      fscanf(File_Ptr, "%lf ", &(Out_Ptr->Tt_ra[ir][ia]));
}

/****************************************************************
 *	Read in the Monte Carlo output parameters.
 ****/
void 
ReadOutMC(FILE * File_Ptr,
	  InputStruct * In_Ptr,
	  OutStruct * Out_Ptr)
{
  ConvStruct  null_conved = NULLCONVSTRUCT;

  SeekKey(File_Ptr, "RAT");
  ReadRAT(File_Ptr, Out_Ptr);	/* refl.,absorption,transmission. */

  /* 1D arrays. */
  SeekKey(File_Ptr, "A_l");
  ReadA_layer(File_Ptr, In_Ptr->num_layers, Out_Ptr);

  SeekKey(File_Ptr, "A_z");
  ReadA_z(File_Ptr, In_Ptr->nz, Out_Ptr);

  SeekKey(File_Ptr, "Rd_r");
  ReadRd_r(File_Ptr, In_Ptr->nr, Out_Ptr);

  SeekKey(File_Ptr, "Rd_a");
  ReadRd_a(File_Ptr, In_Ptr->na, Out_Ptr);

  SeekKey(File_Ptr, "Tt_r");
  ReadTt_r(File_Ptr, In_Ptr->nr, Out_Ptr);

  SeekKey(File_Ptr, "Tt_a");
  ReadTt_a(File_Ptr, In_Ptr->na, Out_Ptr);

  /* 2D arrays. */
  SeekKey(File_Ptr, "A_rz");
  ReadA_rz(File_Ptr, In_Ptr->nr, In_Ptr->nz, Out_Ptr);

  SeekKey(File_Ptr, "Rd_ra");
  ReadRd_ra(File_Ptr, In_Ptr->nr, In_Ptr->na, Out_Ptr);

  SeekKey(File_Ptr, "Tt_ra");
  ReadTt_ra(File_Ptr, In_Ptr->nr, In_Ptr->na, Out_Ptr);

  Out_Ptr->conved = null_conved;
}

/****************************************************************
 *	After the Input parameters are read in, the parameters drc
 *	and nrc are initialized to dr and nr respectively.
 ****/
void 
ReadMcoFile(InputStruct * In_Ptr,
	    OutStruct * Out_Ptr)
{
  FILE       *infile;

  infile = GetFile(In_Ptr->in_fname);
  if (infile == NULL)
    return;

  if (Out_Ptr->allocated) {
    OutStruct   null_out = NULLOUTSTRUCT;
    FreeOrigData(In_Ptr, Out_Ptr);
    *Out_Ptr = null_out;
  }
  ReadInParm(infile, In_Ptr);
  In_Ptr->beam.type = pencil;
  In_Ptr->drc = In_Ptr->dr;
  In_Ptr->nrc = In_Ptr->nr;

  AllocOrigData(In_Ptr, Out_Ptr);
  AllocConvData(In_Ptr, Out_Ptr);
  Out_Ptr->allocated = 1;

  ReadOutMC(infile, In_Ptr, Out_Ptr);
  fclose(infile);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -