Example #1
0
/* \fcnfh
   Print (to file or stdout) the emergent intensities as function of wavelength
   for each angle)                                                          */
void
printintens(struct transit *tr){
  long int i, w;                  /* Auxilliary for-loop indices            */
  FILE *outf = stdout;            /* Output file pointer                    */

  PREC_RES *angles = tr->angles;  /* Array of incident angles               */
  int an = tr->ann;               /* Number of incident angles              */

  prop_samp *wn = &tr->wns;       /* Wavenumber sample                      */
  long int wnn = wn->n;           /* Number of wavenumber samples           */

  /* Intensity for all angles and all wn:                                   */
  PREC_RES **intens_grid = tr->ds.intens->a;   

  /* Adds string to the output files to differentiate between outputs        */
  char our_fileName[512];

  /* Open file:                                                             */
  if (tr->f_outintens && tr->f_outintens[0] != '-'){
    strncpy(our_fileName, tr->f_outintens, 512);
    outf = fopen(our_fileName, "w");
  }
  else{
    transitprint(1, verblevel, "No intensity file.\n");
    return;
  }
  transitprint(1, verblevel, "\nPrinting intensity in '%s'\n",
                             tr->f_outintens ? our_fileName:"standard output");

  /* Print the header:                                                      */
  //fprintf(outf, "#wvl [um]%*s", 6, " ");
  //for(i=0; i < an; i++)
  //    fprintf(outf, "I[%4.1lf deg]%*s", angles[i], 7, " ");
  //fprintf(outf, "[erg/s/cm/sr]\n");

  /* Print the header:                                                      */
  fprintf(outf, "#wvl %*s", 10, " ");
  for(i=0; i < an; i++)
      fprintf(outf, "I[%4.1lf deg]%*s", angles[i], 7, " ");
  fprintf(outf, "\n#[um]%*s", 10, " ");
  for(i=0; i < an; i++)
      fprintf(outf, "[erg/s/cm/sr]%*s", 5, " ");
  fprintf(outf, "\n");


  /* Fills out each column with the correct output intensity                 */
  for(w=0; w<wnn; w++){
    fprintf(outf, "%-15.10g", 1e4/(tr->wns.v[w]/tr->wns.fct));
    for(i=0; i < an; i++)
      fprintf(outf, "%-18.9g", intens_grid[i][w]);
    fprintf(outf,"\n");
  }

  /* Closes the file:                                                        */
  fclose(outf);
  return;
}
Example #2
0
/* \fcnfh
   Print (to file or stdout) the emergent intensity as function of wavenumber 
   (and wavelength)                                                         */
void
printflux(struct transit *tr){
  FILE *outf=stdout;
  /* The flux per wavenumber array:                                         */
  PREC_RES *Flux = tr->ds.out->o; 
  int rn;

  /* Adds string to the output files to differentiate between outputs:      */
  char our_fileName[512];
  strncpy(our_fileName, tr->f_outflux, 512);
  //strcat(our_fileName, ".-Flux");

  /* Open file:                                                             */
  if(tr->f_outflux && tr->f_outflux[0] != '-')
    outf = fopen(our_fileName, "w");

  transitprint(1, verblevel, "\nPrinting flux in '%s'\n",
               tr->f_outflux ? our_fileName:"standard output");

  /* Print the header:                                                      */
  fprintf(outf, "#wvl [um]%*sFlux [erg/s/cm]\n", 6, " ");

  /* Print wavelength and flux:                                             */
  for(rn=0; rn < tr->wns.n; rn++)
    fprintf(outf, "%-15.10g%-18.9g\n", 1e4/(tr->wns.v[rn]/tr->wns.fct),
            Flux[rn]);

  /* Closes the file:                                                       */
  fclose(outf);
  return;
}
Example #3
0
/* \fcnfh
   Print (to file or stdout) the modulation as function of wavelength */
void
printmod(struct transit *tr){
  FILE *outf = stdout;
  struct outputray *outray = tr->ds.out;
  int rn;

  /* Open file: */
  if(tr->f_out && tr->f_out[0] != '-')
    outf = fopen(tr->f_out, "w");

  transitprint(1, verblevel,
               "\nPrinting in-transit/out-transit modulation in '%s'.\n",
               tr->f_out?tr->f_out:"standard output");

  /* Print: */
  char wlu[20], /* Wavelength units name */
       wnu[20]; /* Wavenumber units name (the inverse, actually) */
  long nsd = (long)(1e6);

  /* Get wavenumber units name: */
  if((long)(nsd*tr->wns.fct)==nsd) strcpy(wnu, "cm");
  else if((long)(nsd*1e-1*tr->wns.fct)==nsd) strcpy(wnu, "mm");
  else if((long)(nsd*1e-4*tr->wns.fct)==nsd) strcpy(wnu, "um");
  else if((long)(nsd*1e-7*tr->wns.fct)==nsd) strcpy(wnu, "nm");
  else if((long)(nsd*1e-8*tr->wns.fct)==nsd) strcpy(wnu, "A ");
  else sprintf(wnu, "%6.1g cm", 1/tr->wns.fct);

  /* Get wavelength units name: */
  if((long)(nsd*tr->wavs.fct)==nsd) strcpy(wlu, "cm");
  else if((long)(nsd*1e1*tr->wavs.fct)==nsd) strcpy(wlu, "mm");
  else if((long)(nsd*1e4*tr->wavs.fct)==nsd) strcpy(wlu, "um");
  else if((long)(nsd*1e7*tr->wavs.fct)==nsd) strcpy(wlu, "nm");
  else if((long)(nsd*1e8*tr->wavs.fct)==nsd) strcpy(wlu, "A ");
  else sprintf(wlu, "%8.1g cm", tr->wavs.fct);

  /* Print header: */
  fprintf(outf, "#wvn %s-1%*s wvl %s%*s modulation\n",
          wnu, (int)(9-strlen(wnu)), "", wlu, (int)(12-strlen(wlu)),"");
  /* Print wavenumber, wavelength, and modulation at each wavenumber: */
  for(rn=0; rn<tr->wns.n; rn++)
    fprintf(outf, "%-17.9g%-17.9g%-18.9g\n",
            tr->wns.v[rn]/tr->wns.fct,
            1/tr->wavs.fct/tr->wns.v[rn]/tr->wns.fct,
            outray->o[rn]);

  fclose(outf);
  return;
}
/* \fcnfh
   Printout for modulation as function of wavelength
*/
void
printmod(struct transit *tr)
{
    FILE *outf=stdout;
    struct outputray *outray=tr->ds.out;
    int rn;

    //open file
    if(tr->f_out&&tr->f_out[0]!='-')
        outf=fopen(tr->f_out,"w");

    transitprint(1,verblevel,
                 "\nPrinting in-eclipse/out-eclipse ratio for requested\n"
                 " conditions in '%s'\n"
                 ,tr->f_out?tr->f_out:"standard output");

    //print!
    char wlu[20],wnu[20];
    long nsd=(long)(1e6);

    if((long)(nsd*tr->wns.fct)==nsd) strcpy(wnu,"cm");
    else if((long)(nsd*1e-1*tr->wns.fct)==nsd) strcpy(wnu,"mm");
    else if((long)(nsd*1e-4*tr->wns.fct)==nsd) strcpy(wnu,"um");
    else if((long)(nsd*1e-7*tr->wns.fct)==nsd) strcpy(wnu,"nm");
    else if((long)(nsd*1e-8*tr->wns.fct)==nsd) strcpy(wnu,"a");
    else sprintf(wnu,"%6.1g cm",1/tr->wns.fct);

    if((long)(nsd*tr->wavs.fct)==nsd) strcpy(wlu,"cm");
    else if((long)(nsd*1e1*tr->wavs.fct)==nsd) strcpy(wlu,"mm");
    else if((long)(nsd*1e4*tr->wavs.fct)==nsd) strcpy(wlu,"um");
    else if((long)(nsd*1e7*tr->wavs.fct)==nsd) strcpy(wlu,"nm");
    else if((long)(nsd*1e8*tr->wavs.fct)==nsd)  strcpy(wlu,"a");
    else sprintf(wlu,"%8.1g cm",tr->wavs.fct);

    fprintf(outf,
            "#wvn[%s-1]%*swvl[%s]%*smodulation\n"
            ,wnu,(int)(9-strlen(wnu)),"",wlu,(int)(12-strlen(wlu)),"");
    for(rn=0; rn<tr->wns.n; rn++)
        fprintf(outf,"%-17.9g%-17.9g%-18.9g\n"
                ,tr->wns.v[rn]/tr->wns.fct
                ,1/tr->wavs.fct/tr->wns.v[rn]/tr->wns.fct,
                outray->o[rn]);

    fclose(outf);

    return;
}
Example #5
0
/* \fcnfh
   Check whether isotope 'name' found in atmosphere file do
   correspond to an isotope in the lineinfofile for which
   extinction is going to be calculated
*/
static void
isisoline(char *name,		/* Isotope's name */
	  PREC_ATM mass,	/* Isotope's mass */
	  int *isoeq,		/* Isotope's lineinfo position to be stored */
	  enum isodo atisodo,	/* Action for current isotope */
	  prop_isof *isof,	/* Info from lineinfo file */
	  enum isodo *isodo,	/* Action to be taken storage */
	  PREC_NREC nliso)	/* Number of isotopes in the lineinfo */
{
  PREC_NREC i;

  //Note that here, even though the isotope might be ignored, it will
  //stilll have an equivalent lineiso associated if one is found.
  //\refline{isodbassoc}
  for(i=0;i<nliso;i++){
    if(strcasecmp(name,isof[i].n)==0){
      *isoeq=i;
      if(isolineinatm[i])
	transiterror(TERR_SERIOUS,
		     "Isotope %s has been defined more than once in the\n"
		     "atmosphere file.\n"
		     ,name);
      isolineinatm[i]=1;
      if(isodo[i]!=ignore)
	isodo[i]=atisodo;
      if(isodo[i]==ignore)
	transitprint(2,verblevel,
		     "Ignoring isotope %s (%g AMU)\n"
		     ,isof[i].n,isof[i].m);
      else if(isof[i].m!=mass&&mass!=0)
	transiterror(TERR_WARNING,
		     "Mass of isotope %s, is not the same\n"
		     "in the atmosphere file %s(%g) than in\n"
		     "the transition info file(%g)\n"
		     ,name,atmfilename,mass,
		     isof[i].m);
      break;
    }
  }
  if(*isoeq==-1&&atisodo==ignore)
    nfonly++;
}
/* \fcnfh
   Ask mass and name for new isotopes
*/
void
askonemn(struct onept *onept,	/* user given values are going to be
				   stored here */
         prop_isof *isof,	/* Also stored here for use by the
				   program */
         int n,			/* number of new isotopes, only partial
				   info for these is requested */
         int nf)		/* Number of isotopes with full info */
{
    int i;
    char rc;

    //Allocate room in 'onept'. Room in 'isof' should be already be
    //allocated
    onept->m=(PREC_ZREC *)calloc(n,sizeof(PREC_ZREC));
    onept->n=(char **)calloc(n,sizeof(char *));
    onept->n[0]=(char *)calloc(n*maxeisoname,sizeof(char));

    //For each isotope ask for mass and name
    for(i=0; i<n; i++) {
        onept->n[i]=onept->n[0]+i*maxeisoname;

        while(1) {
            fprintf(stderr,
                    " Mass and name of extra isotope #%i (Order mandatory, "
                    "e.g. 12.011Carbon):\n  "
                    ,i+1);
            onept->m[i]=isof[i+nf].m=readds(stdin,&rc,
                                            onept->n[i],maxeisoname-1);
            strcpy(isof[i+nf].n,onept->n[i]);
            if(rc=='q') {
                transitprint(0,verblevel,"User interrupt!\n");
                exit(EXIT_SUCCESS);
            }
            if(onept->m[i]<=0)
                fprintf(stderr," Invalid value %g, has to be positive\n",onept->m[i]);
            else if(!rc)
                break;
            fprintf(stderr,"Try again!\n");
        }
    }
}
Example #7
0
/* DEF */
int
emergent_intens(struct transit *tr){  /* Transit structure                  */
  static struct outputray st_out;     /* Output structure                   */
  tr->ds.out = &st_out;

  /* Initial variables:                                                     */
  long w;
  prop_samp *rad = &tr->rads;          /* Radius array pointer              */
  prop_samp *wn  = &tr->wns;           /* Wavenumber array pointer          */
  long int wnn   = wn->n;              /* Wavenumbers                       */
  ray_solution *sol = tr->sol;         /* Eclipse ray solution pointer      */

  /* Reads angle index from transit structure                               */
  long int angleIndex = tr->angleIndex;
  /* Intensity for all angles and all wn                                    */
  PREC_RES **intens_grid = tr->ds.intens->a;

  /* Intensity array for one angle all wn:                                  */
  PREC_RES *out = intens_grid[angleIndex];

  /* Reads the tau array from transit structure                             */
  struct optdepth *tau = tr->ds.tau;

  /* Integrate for each wavelength:                                         */
  transitprint(4, verblevel, "Integrating over wavelength.\n");

  /* Printing process variable:                                             */
  int nextw = wn->n/10;

  /* Calculates the intensity integral at each wavenumber:                  */
  for(w=0; w<wnn; w++){
    //transitprint(1, 2, "[%li]", w);
    //if (w == 1612 || w == 1607){
    //  transitprint(1, 2, "\nTau (%.3f) [%li,%li]= np.array([", wn->v[w],
    //                      rad->n, tau->last[w]);
    //  //for (int ii=rad->n-1; ii>tau->last[w]; ii--)
    //  for (int ii=0; ii<rad->n; ii++)
    //    transitprint(1, 2, "%.4e, ", tau->t[w][ii]);
    //  transitprint(1, 2, "])\n");
    //}
    //if (fabs(wn->v[w] - 1844.59) < 0.005)
    //  transitprint(1, verblevel, "\nWavenumber index is: %li\n", w);

    /* Calculate the intensity spectrum (call to eclipse_intens):           */
    out[w] = sol->spectrum(tr, tau->t[w], wn->v[w], tau->last[w],
                           tau->toomuch, rad);

    /* Prints to screen the progress status:                                */
    if(w == nextw){
      nextw += wn->n/10;
      transitprint(10, verblevel, "%i%% ", (10*(int)(10*w/wn->n+0.9999999999)));
    }
  }

  transitprint(4, verblevel, "\nDone.\n");

  /* Sets progress indicator, and prints output:                             */
  tr->pi |= TRPI_MODULATION; /* FINDME: this is not a modulation calculation */
  if (tr->angleIndex == tr->ann-1)
    printintens(tr);
  return 0;
}
Example #8
0
/* \fcnfh
   get number of isotopes from file and set index 

   @returns number of lines read
*/
int
getmnfromfile(FILE *fp,
	      struct atm_data *at,
	      struct transit *tr,
	      int nmb)
{
  char line[maxline],*lp;
  int ison=0,i;
  struct isotopes *iso=tr->ds.iso;
  enum isodo *isodo=iso->isodo;

  //Set variable to handle proportional to isotopes
  int ipi=0,ipa=at->ipa=4;
  isolineinatm=(_Bool *)calloc(iso->n_i,sizeof(_Bool));
  isoprop=(struct atm_isoprop *)calloc(ipa,sizeof(struct atm_isoprop));

  at->begline=0;
  enum isodo atisodo;
  at->isodo = (enum isodo *)calloc(nmb,sizeof(enum isodo));
  at->isoeq = (int *)       calloc(nmb,sizeof(int));
  at->m     = (PREC_ZREC *) calloc(nmb,sizeof(PREC_ZREC));
  at->n     = (char **)     calloc(nmb,sizeof(char *));
  at->n[0]  = (char *)      calloc(nmb*maxeisoname,sizeof(char));
  at->isoeq[0]=-1;
  for(i=1;i<nmb;i++){
    at->n[i]=at->n[0]+i*maxeisoname;
    at->isoeq[i]=-1;
  }

  //while t,p data doesn't start, check for the various modifiers
  while(1){
    switch(fgetupto_err(line,maxline,fp,&atmerr,atmfilename,
			at->begline++)){
    case '\n':			//Ignore comments and
    case '#':			//  blank lines
      continue;

    case 0:			//Error if EOF
      transiterror(TERR_SERIOUS|TERR_ALLOWCONT,
		   "readatminfo:: EOF unexpectedly found at line %i\n"
		   "of file %s while no t,p data points have been read\n"
		   ,at->begline,atmfilename);
      exit(EXIT_FAILURE);
      continue;

    case 'q':			//Whether is mass or number abundance
      lp=line+1;
      while(*lp++==' ');
      lp--;
      switch(*lp|0x20){
      case 'n':
	at->mass=0;
	break;
      case 'm':
	at->mass=1;
	break;
      default:
	transiterror(TERR_SERIOUS,
		     "'q' option in the atmosphere file can only be followed\n"
		     "by 'm' (for abundances by mass) or 'n' (for abundances by\n"
		     "number). '%s' is invalid.\n"
		     ,line);
	break;
      }
      continue;

    case 'z':			//Zero radius value
      zerorad=atof(line+1);
      continue;

    case 'f':			//An isotope is to be taken as
				//proportional to other.
      lp=line+1;
      while(*lp==' '||*lp=='\t') lp++;

      if(ipi==ipa)
	isoprop=(struct atm_isoprop *)realloc(isoprop,(ipa<<=1)*
					      sizeof(struct atm_isoprop));
      isoprop[ipi].m=getds(lp,0,isoprop[ipi].n,maxeisoname-1);
      //skip over recently read field, and go to next field.
      lp=nextfield(lp);
      //skip an optional equal '=' sign
      if(*lp=='=' && lp[1]==' ')
	lp=nextfield(lp);
      //get factor, which has to be between 0 and 1
      isoprop[ipi].f=strtod(lp,NULL);
      if(isoprop[ipi].f<0 )
	transiterror(TERR_CRITICAL,
		     "Abundance ratio has to be positive in atmosphere\n"
		     "file '%s' in line: %s"
		     ,atmfilename,line);
      lp=nextfield(lp);
      //get name of reference and increase index
      i=0;
      while(*lp)
	isoprop[ipi].t[i++]=*lp++;
      isoprop[ipi].t[i]='\0';

      //now check if that isotope is one of the given in the lineinfo
      //file 
      isoprop[ipi].eq=-1;
      isisoline(isoprop[ipi].n,isoprop[ipi].m,&isoprop[ipi].eq,factor,
		iso->isof,isodo,iso->n_i);

      //advance index and go for the next line
      ipi++;
      continue;

    case 'u':			//Change factorization of radius, temp,
				//or press
      switch(line[1]){
      case 'r':
	at->rads.fct=atof(line+2);
	break;
      case 'p':
	at->atm.pfct=atof(line+2);
	break;
      case 't':
	at->atm.tfct=atof(line+2);
	break;
      default:
	transiterror(TERR_SERIOUS,
		     "Invalid unit factor indication in atmosphere file\n");
	exit(EXIT_FAILURE);
      }
      continue;

    case 'n':			//Name or identifier for file data
      storename(at,line+1);
      continue;

    case 'i':			//Isotope information
      lp=line+1;
      while(*lp==' '||*lp=='\t') lp++;
      //'i' has to come before 'f'
      if(ipi)
	transiterror(TERR_CRITICAL,
		     "In line '%s'.\n"
		     " 'f' lines have to come after all the 'i' lines in\n"
		     " atmosphere file '%s'"
		     ,line,atmfilename);

      //for each field
      while(*lp){
	atisodo=atmfile;
	//Allocate if necessary
	if(ison==nmb){
	  nmb<<=1;
	  at->isodo = (enum isodo *)realloc(at->isodo,nmb*sizeof(enum isodo));
	  at->isoeq = (int *)       realloc(at->isoeq,nmb*sizeof(int));
	  at->m     = (PREC_ZREC *) realloc(at->m,    nmb*sizeof(PREC_ZREC));
	  at->n     = (char **)     realloc(at->n,    nmb*sizeof(char *));
	  at->n[0]  = (char *)      realloc(at->n[0], nmb*maxeisoname*sizeof(char));
	  for(i=1;i<nmb;i++)
	    at->n[i]=at->n[0]+i*maxeisoname;
	  for(i=nmb/2;i<nmb;i++)
	    at->isoeq[i]=-1;
	}

	//get mass and name, checking that is correct. First see if this
	//isotope wants to be ignored.
	if(*lp=='!'){
	  lp++;
	  atisodo=ignore;
	}
	at->m[ison]=getds(lp,0,at->n[ison],maxeisoname-1);
	if(at->m[ison]<0||at->n[ison]=='\0'){
	  transiterror(TERR_SERIOUS,
		       "Invalid field in file %s, line %i while reading isotope"
		       " info at:\n%s\n"
		       ,atmfilename,at->begline,lp);
	}

	//now check if that isotope is one of the given in the lineinfo
	//file
	isisoline(at->n[ison],at->m[ison],at->isoeq+ison,atisodo,
		  iso->isof,isodo,iso->n_i);
	at->isodo[ison++]=atisodo;

	//skip over recently read field, and go to next field.
	while(*lp!=' '&&*lp!='\0') lp++;
	while(*lp==' '||*lp=='\t') lp++;
      }
      continue;

    default:			//T,P seems to be starting
      break;
    }
    break;
  }

  transitprint(3,verblevel,
	       "Read all keywords in atmosphere file without problems\n");

  //Check if there was at least an isotope identification and allocate new
  //arrays
  if(!ison)
    transiterror(TERR_SERIOUS,
		 "No isotopes were found in atmosphere file, make sure to\n"
		 "specify them in a line starting with the letter 'i'.\n"
		 "First non-comment line read:\n%s\n"
		 ,line);
  at->begpos=ftell(fp)-strlen(line)-1;

  //shorten extra length of arrays
  fonly=(struct fonly *)calloc(nfonly,sizeof(struct fonly));
  at->ipa=ipa=ipi;
  isoprop=(struct atm_isoprop *)realloc(isoprop,ipa*
					sizeof(struct atm_isoprop));

  //Makes at arrays bigger, so that they can hold the factorized values.
  nmb       = at->n_aiso = ison + ipa;
  at->isodo = (enum isodo *)realloc(at->isodo,nmb*sizeof(enum isodo)      );
  at->isoeq = (int *)       realloc(at->isoeq,nmb*sizeof(int)             );
  at->m     = (PREC_ZREC *) realloc(at->m,    nmb*sizeof(PREC_ZREC)       );
  at->n     = (char **)     realloc(at->n,    nmb*sizeof(char *)          );
  at->n[0]  = (char *)      realloc(at->n[0], nmb*maxeisoname*sizeof(char));
  for(i=1;i<nmb;i++)
    at->n[i] = at->n[0] + i * maxeisoname;

  //initialize values for the factorized elements
  for(i=ison;i<nmb;i++){
    strncpy(at->n[i],isoprop[i-ison].n,maxeisoname-1);
    at->n[i][maxeisoname-1] = '\0';
    at->isoeq[i]            = i-ison;
    at->m[i]                = isoprop[i-ison].m;
    at->isodo[i]            = factor;
  }

  //Resolve what to do with those isotopes that appear in the transition
  //database, but not in the atmosphere file.
  at->n_niso = checknonmatch(tr,at,isodo);

  //Set full isotope info in the transit structure
  nmb = iso->n_i + at->n_niso;
  iso->isodo   = (enum isodo *)realloc(iso->isodo,
				       nmb*sizeof(enum isodo));
  iso->isof    = (prop_isof *)realloc(iso->isof,
				      nmb*sizeof(prop_isof));
  iso->isof[iso->n_i].n = (char *)realloc(iso->isof[iso->n_i].n,
					  (nmb-iso->n_i)*maxeisoname*
					  sizeof(char));
  for(i=1;i<nmb-iso->n_i;i++)
    iso->isof[iso->n_i+i].n = iso->isof[iso->n_i].n + i * maxeisoname;



  //Look for isotopes who have not been associated and see whether they
  //are supposed to be ignored. 
  nmb = iso->n_i;
  ipi = 0;
  int lineignore=0;
  for(i=0 ; i<ison+ipa ; i++)
    //If the isotope is not associated to the linedb isotopes, then
    //associate it. Note that isotopes in linedb that are ignored will
    //be associated (see comments for Line \label{isodbassoc}). Hence
    //they won't be detected in this IF. Factor isotopes will also be
    //associated, and will be handled below
    if(at->isoeq[i] == -1){
      //If they are not going to be ignored then associate them with the
      //following index available of post linedb isotopes.
      if(at->isodo[i] != ignore){
	at->isoeq[i]     = nmb;
	iso->isodo[nmb]  = at->isodo[i];
	iso->isof[nmb].m = at->m[i];
	strcpy(iso->isof[nmb++].n, at->n[i]);
      }
      //otherwise, they might only be used as a reference to factor.
      else{
	at->isoeq[i] = ipi;
      	strcpy(fonly[ipi++].n, at->n[i]);
      }
    }
  //Just count the number of ignored isotopes that belonged to the line
  //isotopes.
    else if(at->isodo[i] == ignore)
      lineignore++;
  //If there is factor isotopes
    else if(at->isodo[i] == factor && isoprop[at->isoeq[i]].eq == -1){
      if(at->isodo[i]==ignore)
	transiterror(TERR_CRITICAL,
		    "Trying to ignore an factor isotope, that is not\n"
		     "posible.\n");
      isoprop[at->isoeq[i]].eq = nmb;
      iso->isodo[nmb]          = at->isodo[i];
      iso->isof[nmb].m         = at->m[i];
      strcpy(iso->isof[nmb++].n, at->n[i]);
    }

  //Reduce the array to get rid of nonline-ignored isotopes. (isov has
  //not even been allocated yet)
  iso->n_e = nmb;
  iso->isodo   = (enum isodo *)realloc(iso->isodo,
				       nmb*sizeof(enum isodo));
  iso->isof    = (prop_isof *)realloc(iso->isof,
				      nmb*sizeof(prop_isof));
  iso->isof[iso->n_i].n = (char *)realloc(iso->isof[iso->n_i].n,
					  nmb*maxeisoname*sizeof(char));
  for(i=1;i<nmb-iso->n_i;i++)
    iso->isof[iso->n_i+i].n = iso->isof[iso->n_i].n + i * maxeisoname;


  //Check that everything makes sense
  double cumulother=0;
  for(i=0 ; i<at->n_aiso ; i++)
    if(at->isodo[i]==factor){
      int feq=at->isoeq[i];
      if(strcasecmp(isoprop[feq].n,"other")==0)
	cumulother+=isoprop[feq].f;
    }
  //It doesn't make sense for cumulother to be anything different from
  //unity (except round-off error): you want to associate the
  //remainder of the atmosphere to some isotopic properties. 
  if( cumulother!=0 && (int)(cumulother*ROUNDOFF+0.5)!=(int)(ROUNDOFF+0.5) )
    transiterror(TERR_SERIOUS,
		 "If you are specifying isotopes proportional to 'other'\n"
		 "you have to complete unity (%g). It doesn't make sense\n"
		 "otherwise\n"
		 ,cumulother);

  transitASSERT(nmb+nfonly!=ison+ipa,
		"Oooops, number of ignored-nonline elements (%i), plus the\n"
		"number of ignored-line elements(%i), plus the number of\n"
		"nonignored (%i), doesn't match the number of elements\n"
		"found in fields 'i'(%i) and 'f'(%i) of the atmosphere\n"
		"file '%s'\n"
		,nfonly,lineignore,nmb-lineignore,ison,ipa,atmfilename);

  transitASSERT(nmb!=iso->n_e,
		"Uyuyuyuyu! Problem in file %s, line %i,\n"
		"assertion failed: %i != %i!!\n"
		,__FILE__,__LINE__,nmb,iso->n_e);

  //free unused array, store factor info in at structure and return line
  //where T,P start
  free(isolineinatm);
  at->isoprop=isoprop;

  return at->begline;
}
/* \fcnfh
   Obtains the quantity that is observable, but before being convolved
   to telescope resolution

   @returns 0 on success
            -1 if impact parameter sampling is not equispaced
 */
int
modulation(struct transit *tr)	/* Main structure */
{
    static struct outputray st_out;
    tr->ds.out=&st_out;

    transitcheckcalled(tr->pi,"modulation",3,
                       "tau",TRPI_TAU,
                       "makeipsample",TRPI_MAKEIP,
                       "makewnsample",TRPI_MAKEWN
                      );

    //initial variables and check that impact parameters was a monospaced
    //array. Stop otherwise.
    long w;
    prop_samp *ip=&tr->ips;
    prop_samp *wn=&tr->wns;
    transit_ray_solution *sol=tr->sol;
    if(ip->d==0&&sol->monoip) {
        transiterror(TERR_SERIOUS|TERR_ALLOWCONT,
                     "To compute %s modulation, the impact parameter has to\n"
                     "be an equispaced array\n"
                     ,sol->name);
        return -1;
    }

    //output and geometry variables.
    PREC_RES *out=st_out.o=(PREC_RES *)calloc(wn->n,sizeof(PREC_RES));
    struct geometry *sg=tr->ds.sg;
    struct optdepth *tau=tr->ds.tau;

    //set time to the user hinted default, and other user hints
    setgeom(sg,HUGE_VAL,&tr->pi);
    const int modlevel=tr->modlevel=tr->ds.th->modlevel;

    //integrate for each wavelength
    transitprint(1,verblevel,
                 "\nIntegrating for each wavelength...\n");

    int nextw=wn->n/10;

    for(w=0; w<wn->n; w++) {
        out[w]=sol->obsperwn(tau->t[w],tau->last[w],tau->toomuch,
                             ip,sg,modlevel);
        if(out[w]<0) {
            switch(-(int)out[w]) {
            case 1:
                if(modlevel==-1)
                    transiterror(TERR_SERIOUS,
                                 "Optical depth didn't reach limiting %g at wavenumber %g[cm-1]\n"
                                 " (Only reached %g)."
                                 " Cannot use critical radius technique (-1)\n"
                                 ,tau->toomuch,tau->t[w][tau->last[w]],wn->v[w]*wn->fct);
            default:
                transiterror(TERR_SERIOUS,
                             "There was a problem while calculating modulation\n"
                             " at wavenumber %g[cm-1]. Error code %i\n"
                             ,wn->v[w]*wn->fct,(int)out[w]);
                break;
            }
            exit(EXIT_FAILURE);
        }

        if(w==nextw) {
            nextw+=wn->n/10;
            transitprint(2,verblevel,
                         "%i%%\r"
                         ,(10*(int)(10*w/wn->n+0.9999999999)));
        }
    }
    transitprint(1,verblevel," done\n");

    //frees no longer needed memory.
    freemem_idexrefrac(tr->ds.ir,&tr->pi);
    freemem_extinction(tr->ds.ex,&tr->pi);
    freemem_tau(tr->ds.tau,&tr->pi);

    //set progress indicator, and print output
    tr->pi&=TRPI_MODULATION;
    printmod(tr);
    return 0;
}
Example #10
0
void getmass(struct atm_data *at, struct molecules *mol){
  int nmol = at->n_aiso;
  /* FINDME: De-hardcode filename, put it in tr.ds.at: */
  char *filename = "../inputs/molecules.dat";
  FILE *elist;

  /* Atomic masses, names, alias names, alias molecules, and sizes: */
  double *amass,    /* Atomic masses form list          */
         *radius;   /* Molecular radii from list        */
  char **aname,     /* Atomic symbol names              */
       **rname,     /* Molecules names for listed radii */
       **alias,     /* Alias of names given in atmfile  */
       **amol,      /* Corresponding molecule for alias */
       **elements;  /* Elements in a molecule           */
  int natoms = 92,  /* Number of listed atoms           */
      nalias =  2,  /* Number of listed alias names     */
      nradii = 14,  /* Number of listed radii           */
      namelen = 3,  /* Atomic symbol name length        */
      maxlinelen = 501,
      molnamelen,   /* Length of a molecule name        */
      elen,         /* Element name length              */
      iatom,        /* Atom's index from list           */
      ielement,     /* Element counter in a molecule    */
      i, j;         /* Auxiliary for-loop index         */
  int *nelements;   /* Number of elements in a molecule */

  char line[maxlinelen], *lp,
       molecule[MAXNAMELEN]; /* Current molecule's name */

  /* Alias names, and corresponding molecules: */
  amass    = (double *)calloc(natoms,         sizeof(double));
  aname    = (char  **)calloc(natoms,         sizeof(char *));
  aname[0] = (char   *)calloc(natoms*namelen, sizeof(char));
  for (i=1; i<natoms; i++)
    aname[i] = aname[0] + i*namelen;

  /* Open Molecules file: */
  if((elist=verbfileopen(filename, "Molecular info ")) == NULL)
    exit(EXIT_FAILURE);

  do{  /* Read lines, skipping comments and blank lines: */
    lp = fgets(line, maxlinelen, elist);
  }while (lp[0] == '\0' || lp[0] == '\n' || lp[0] == '#');

  /* Fill atoms and mass array with info from element list: */
  for (i=0; i<natoms; i++){
    lp += 19; /* The element's symbol starts at the 19th character */
    getname(lp, aname[i]);
    lp = nextfield(lp);
    amass[i] = strtod(lp, NULL);
    lp = fgets(line, maxlinelen, elist);
  }

  /* Allocate alias names and corresponding molecules: */
  alias    = (char  **)calloc(nalias, sizeof(char *));
  amol     = (char  **)calloc(nalias, sizeof(char *));
  alias[0] = (char   *)calloc(nalias*MAXNAMELEN, sizeof(char));
  amol[0]  = (char   *)calloc(nalias*MAXNAMELEN, sizeof(char));
  for (i=1; i<nalias; i++){
    alias[i] = alias[0] + i*MAXNAMELEN;
    amol[i]  = amol[0]  + i*MAXNAMELEN;
  }

  /* Continue reading the file to get the alias names: */
  do{  /* Skip blank and comment lines: */
    lp = fgets(line, maxlinelen, elist);
  }while (lp[0] == '\0' || lp[0] == '\n' || lp[0] == '#');

  /* Get aliases from file:         */
  for (i=0; i<nalias; i++){
    /* Get alias and molecule name: */
    getname(lp, alias[i]);
    lp = nextfield(lp);
    getname(lp, amol[i]);
    lp = fgets(line, maxlinelen, elist);
  }

  /* Allocate names and radii:         */
  radius   = (double *)calloc(nradii,            sizeof(double));
  rname    = (char  **)calloc(nradii,            sizeof(char *));
  rname[0] = (char   *)calloc(nradii*MAXNAMELEN, sizeof(char));
  for (i=1; i<nradii; i++)
    rname[i] = rname[0] + i*MAXNAMELEN;

  /* Go to next block                  */
  do{
    lp = fgets(line, maxlinelen, elist);
  }while (lp[0] == '\0' || lp[0] == '\n' || lp[0] == '#');

  /* Get radii from file:              */
  for (i=0; i<nradii; i++){
    /* Get molecules' name and radius: */
    getname(lp, rname[i]);
    lp = nextfield(lp);
    radius[i] = strtod(lp, NULL)/2.0;
    lp = fgets(line, maxlinelen, elist);
  }

  /* Allocate max number of molecules and max len of molecule name: */
  nelements   = (int   *)calloc(MAXNAMELEN, sizeof(int));
  elements    = (char **)calloc(MAXNAMELEN, sizeof(char *));
  elements[0] = (char  *)calloc((MAXNAMELEN+1)*MAXNAMELEN, sizeof(char));
  for (j=0; j<MAXNAMELEN; j++)
    elements[j] = elements[0] + j*(MAXNAMELEN+1);

  /* For each molecule: */
  for (i=0; i<nmol; i++){
    /* Check if molecule name is an alias: */
    if ((j=findstring(mol->name[i], alias, nalias)) >= 0)
      strcpy(molecule, amol[j]);
    else
      strcpy(molecule, mol->name[i]);

    /* Allocate elements in a molecule: */
    molnamelen  = (int)strlen(molecule);

    /* Break down molecule into its elements: */
    elen     = 0;  /* Element name length            */
    ielement = 0;  /* Elements in a molecule counter */
    for (j=0; j<molnamelen; j++){
      if (isalpha(molecule[j])){
        if (isupper(molecule[j])){  /* Uppercase letter: */
          if (elen > 0){
            /* End last element, advance j, store new letter */
            if (elen <= 2){ /* If name is longer, it's an alias name */
              elen = 0;
              ielement++;  /* Count 1 more element */
              nelements[ielement] = 1;
            }
            elements[ielement][elen++] = molecule[j];
          }
          else{ /* New Atom (elen==0) */
            elements[ielement][elen++] = molecule[j];
            nelements[ielement] = 1;
          }
        }
        else{ /* Lowercase: */
          elements[ielement][elen++] = molecule[j];
        }
      }
      else{  /* A numeric value: */
        nelements[ielement] = (int)strtol(&molecule[j], NULL, 10);
        elements[ielement][elen] = '\0';
        j += (int)log10((double)nelements[ielement++]);
        elen = 0;
      }
    }
    if (elen != 0)
     ielement++;

    /* Calculate molecule's mass: */
    for (j=0; j<ielement; j++){
      /* Find index of atom in list: */
      iatom = findstring(elements[j], aname, natoms);
      transitprint(30, verblevel, "Found %d %2s[%2d] atom(s) with mass "
                 "%9.6f u.\n", nelements[j], aname[iatom], iatom, amass[iatom]);
      /* Get mass and multiply by the number of atoms in molecule: */
      mol->mass[i] += amass[iatom] * nelements[j];
    }

    /* Set the radius: */
    j = findstring(molecule, rname, nradii);
    mol->radius[i] = radius[j] * ANGSTROM;
    transitprint(30, verblevel, "Molecule '%s' has radius %4.2f A and mass "
                      "%4.2f u.\n", mol->name[i], mol->radius[i]/ANGSTROM,
                       mol->mass[i]);
  }
}
Example #11
0
/* \fcnfh
    Read radius, pressure, temperature, and abundances and store it into
    at_data of transit.  Calculate mean molecular mass and densities.

    Detailed:
    Read and store radius, pressure, and temperature from file.
    Read abundances for each (non other-factor) isotope.
    Sum fractional abundances. Calculate ramaining (other-factor) abundances.
    Calculate mean molecular mass per radius.
    Calculate densities per isotope at each radius.

    Returns: number of sample radius                                         */
int
readatmfile(FILE *fp,                /* Atmospheric file               */
            struct transit *tr,      /* transit struct                 */
            struct atm_data *at,     /* Atmosphere struct              */
            prop_samp *rads,         /* Radius sampling                */
            int nrad,                /* Size of allocated radius array */
            PREC_ZREC *f_remainder){ /* Remainder molecules' factor    */

  transitprint(1, verblevel, "Start reading abundances.\n");
  /* Find abundance related quantities for each radius */
  int lines = at->begline;
  PREC_NREC r = 0; /* Radius index (number of radii being read) */
  char rc;         /* File reading output */
  float allowq = 1 - tr->allowrq;
  int nabundances;  /* Number of abundances in list */
  double sumq;      /* Sum of abundances per line   */
  char line[maxline], *lp, *lp2;
  prop_mol *molec = at->molec;
  struct molecules *mol = tr->ds.mol;
  int i, j;            /* Auxiliary for-loop indices */
  /* Variables to be used by factor (except ieq which is general): */

  /* Count the number of abundances in each line:                      */
  fseek(fp, at->begpos, SEEK_SET); /* Go to position where data begins */
  /* Skip comments:                    */
  while((rc=fgetupto_err(lp=line, maxline, fp, &atmerr, atmfilename, lines++))
        =='#' || rc=='\n');
  /* Count values per line:            */
  nabundances = countfields(lp, ' ') - 3; /* Subtract rad, p, and T columns */
 
  fseek(fp, at->begpos, SEEK_SET); /* Go to position where data begins */
  while(1){
    /* Reallocate if necessary: */
    if(r==nrad){
      nrad <<= 1;
      rads->v     = (PREC_ATM *)realloc(rads->v,   nrad*sizeof(PREC_ATM));
      at->atm.t   = (PREC_ATM *)realloc(at->atm.t, nrad*sizeof(PREC_ATM));
      at->atm.p   = (PREC_ATM *)realloc(at->atm.p, nrad*sizeof(PREC_ATM));
      at->mm      = (double   *)realloc(at->mm,    nrad*sizeof(double));
      for(i=0; i<at->n_aiso; i++){
        molec[i].d = (PREC_ATM *)realloc(molec[i].d, nrad*sizeof(PREC_ATM));
        molec[i].q = (PREC_ATM *)realloc(molec[i].q, nrad*sizeof(PREC_ATM));
        molec[i].n = nrad;
      }
    }

    /* Skip comments and read next line: */
    while((rc=fgetupto_err(lp=line, maxline, fp, &atmerr, atmfilename, lines++))
          =='#' || rc=='\n');
    /* If it is end of file, stop loop: */
    if(!rc)
      break;

    /* Read and store radius, pressure, and temperature from file: */
    rads->v[r] = strtod(lp, &lp2) + zerorad; /* Radius       */
    checkposvalue(rads->v[r], 1, lines);       /* Check value is positive */
    if(lp==lp2) 
      invalidfield(line, lines, 1, "radius");
    at->atm.p[r] = strtod(lp2, &lp);         /* Pressure     */
    checkposvalue(at->atm.p[r], 2, lines); 
    if(lp==lp2)
      invalidfield(line, lines, 2, "pressure");
    at->atm.t[r] = strtod(lp, &lp2);         /* Temperature  */
    checkposvalue(at->atm.t[r], 3, lines);
    if(lp==lp2)
      invalidfield(line, lines, 3, "temperature");

    /* Read abundances for each isotope.  Keep reading-in values
       while there are numbers in line:                            */
    for(i=0, sumq=0; i<nabundances; i++){
      lp = lp2;
      /* Read the abundance of the isotope:                        */
      molec[i].q[r] = strtod(lp, &lp2);
      if (r==0)
        transitprint(30, verblevel, "density[%d, %li]: %.9f.\n",
                                    i, r, molec[i].q[r]);
      sumq += molec[i].q[r]; /* Add the abundances */
      checkposvalue(molec[i].q[r], i+4, lines); /* Check that tmp is positive */
      if(lp==lp2)
        invalidfield(line, lines, 4+i, "isotope abundance");
    }

    /* Remainder of the sum of abundances:     */
    /* Set abundance of remainder molecules:   */
    for(j=0; i < at->n_aiso; i++, j++)
      molec[i].q[r] = f_remainder[j]*(1-sumq);

    transitASSERT(i!=at->n_aiso, "The line %s of file %s contains %d abundance "
                                 "values, when there were %d expected.\n",
                                 __LINE__, __FILE__, i, at->n_aiso);
    
    /* Calculate mean molecular mass and check whether abundances add up
       to one (within roundoff error): */
    sumq = checkaddmm(at->mm+r, r, molec, mol, at->n_aiso, at->mass);
    if((int)(sumq*ROUNDOFF+0.5)<(int)(allowq*ROUNDOFF+0.5))
      transiterror(TERR_WARNING,
                   "In radius %g (%i: %g in file), abundances "
                   "don't add up to 1: %.9g\n",
                   at->rads.v[r], r, at->rads.v[r]-zerorad, sumq);

    /* Calculate densities using ideal gas law: */
    if (r>=0){
      transitprint(30, verblevel, "Abund: %.9f, mmm: %.3f, mass: %.3f, "
                                "p: %.3f, T: %.3f.\n", molec[2].q[r], at->mm[r],
                                   mol->mass[2], at->atm.p[r]*at->atm.pfct,
                                   at->atm.t[r]*at->atm.tfct);
    }
    for(i=0; i<at->n_aiso; i++)
      molec[i].d[r] = stateeqnford(at->mass, molec[i].q[r], at->mm[r],
                                   mol->mass[i], at->atm.p[r]*at->atm.pfct,
                                   at->atm.t[r]*at->atm.tfct);
    transitprint(30, verblevel, "dens[%2li]: %.14f,   ", r, molec[2].d[r]);
    r++;
  }

  /* Re-allocate arrays to final size (nrad):  */
  rads->n = nrad = r;
  rads->v   = (PREC_ATM *)realloc(rads->v,   nrad*sizeof(PREC_ATM));
  at->atm.t = (PREC_ATM *)realloc(at->atm.t, nrad*sizeof(PREC_ATM));
  at->atm.p = (PREC_ATM *)realloc(at->atm.p, nrad*sizeof(PREC_ATM));
  at->mm    = (double   *)realloc(at->mm,    nrad*sizeof(double));
  for(i=0; i<at->n_aiso; i++){
    molec[i].d = (PREC_ATM *)realloc(molec[i].d, nrad*sizeof(PREC_ATM));
    molec[i].q = (PREC_ATM *)realloc(molec[i].q, nrad*sizeof(PREC_ATM));
    molec[i].n = nrad;
  }

  /* Free arrays that were used only to get the factorizing elements: */
  free(fonly);
  nfonly = 0;

  return nrad;
}
Example #12
0
/* \fcnfh
    Get keyword variables from atmosphere file (mass/number abundance bool;
    zero-radius offset; radius, temperature, and pressure units factor;
    atmfile name/info; list isotopes; list of proportional-abundance isotopes).
    Store molecules and proportional isotopes in atm_data struct. 
    Determine which linedb isotope corresponds to such atm_data isotope.
    Solve non-matched linedb isotope cases.
    Put all non-ignore isotopes in transit.ds.iso structure.

    Return: Number of lines read                                     */
int
getmnfromfile(FILE *fp,                /* Pointer to atmospheric file    */
              struct atm_data *at,     /* atmosphere structure           */
              struct transit *tr,      /* transit structure              */
              PREC_ZREC *f_remainder){ /* Remainder molecules' factor    */
  struct molecules *mol=tr->ds.mol;
  char line[maxline], *lp;
  int nimol=0, /* Number of molecules with abundance profile */
      nmol=0,  /* Total number of molecules                  */
      i;       /* Auxiliary for-loop index                   */
  double cumulother = 0; /* Cumulative remainder-molecules' factor */
  int ipi = 0;    /* Number of remainder molecules   */

  /* Is the isotope defined in the atm file?: */
  //isoprop = (struct atm_isoprop *)calloc(ipa, sizeof(struct atm_isoprop));

  at->begline = 0; /* Line where the info begins      */

  /* Read and store the keyword atmospheric variables: */ 
  while(1){
    switch(fgetupto_err(line, maxline, fp, &atmerr, atmfilename,
                        at->begline++)){
    /* Ignore comments and blank lines: */
    case '\n':
    case '#':
      continue;
    case 0:     /* Throw error if EOF   */
      transiterror(TERR_SERIOUS|TERR_ALLOWCONT,
                   "readatm :: EOF unexpectedly found at line %i "
                   "of file %s while no t,p data points have been read.\n",
                   at->begline, atmfilename);
      exit(EXIT_FAILURE);
      continue;

    /* Determine whether abundance is by mass or number:     */
    case 'q':  
      lp = line + 1;
      while(*lp++ == ' '); /* Skip blank spaces              */
      lp--;
      switch(*lp|0x20){
      case 'n':
        at->mass = 0;  /* Number abundance (mixing ratio)    */
        break;
      case 'm':
        at->mass = 1;  /* Mass abundance (mass mixing ratio) */
        break;
      default:
        transiterror(TERR_SERIOUS,
                     "'q' option in the atmosphere file can only be followed "
                     "by 'm' (for abundances by mass) or 'n' (for abundances "
                     "by number). '%s' is invalid.\n", line);
        break;
      }
      continue;

    /* Zero radius value: */
    case 'z':  
      zerorad = atof(line+1);
      continue;

    /* Radius, temperature, or pressure units factor: */
    case 'u':
      switch(line[1]){
      case 'r':
        at->rads.fct = atof(line+2);
        break;
      case 'p':
        at->atm.pfct = atof(line+2);
        break;
      case 't':
        at->atm.tfct = atof(line+2);
        break;
      default:
        transiterror(TERR_SERIOUS, "Invalid unit factor indication in "
                                   "atmosphere file.\n");
        exit(EXIT_FAILURE);
      }
      continue;

    case 'n':  /* Name or identifier for file data */
      storename(at, line+1);
      continue;

    case 'i':  /* Molecule names with an abundance profile: */
      /* Count the number of wrds (molecules) in line:      */
      nimol = countfields(line+1, ' ');
      transitprint(15, verblevel, "The number of molecules is %d.\n", nimol);

      /* Allocate Molecules names:                          */
      mol->name    = (char **)calloc(nimol,             sizeof(char *));
      mol->name[0] = (char  *)calloc(nimol*maxeisoname, sizeof(char));
      for(i=1; i<nimol; i++)
        mol->name[i] = mol->name[0] + i*maxeisoname;

      transitprint(1, verblevel, "Molecules with abundance profile:\n  ");
      lp = line;
      lp = nextfield(lp); /* Skip keyword                   */
      /* Read and store names:                              */
      for (i=0; i<nimol; i++){
        getname(lp, mol->name[i]);
        lp = nextfield(lp);
        transitprint(1, verblevel, "%s, ", mol->name[i]);
      }
      transitprint(1, verblevel, "\b\b.\n");
      continue;

    /* Molecules with abundance proportional to the remainder: */
    case 'f':
      lp = line;
      lp = nextfield(lp); /* Skip keyword                      */

      /* Current total number of molecules:                    */
      nmol = ++ipi + nimol;
      /* Re-allocate to add the new molecule:                  */
      mol->name    = (char **)realloc(mol->name, nmol*sizeof(char *));
      mol->name[0] = (char  *)realloc(mol->name[0],
                                                 nmol*maxeisoname*sizeof(char));
      for (i=1; i<nmol; i++)
        mol->name[i] = mol->name[0] + i*maxeisoname;

      /* Re-allocate remainder factors:                        */
      f_remainder = (PREC_ZREC *)realloc(f_remainder, ipi*sizeof(PREC_ZREC));

      /* Read and store the molecule's name:                   */
      getname(lp, mol->name[nmol-1]);

      lp = nextfield(lp);   /* Move pointer to next field      */
      if(*lp == '=')        /* Skip an optional equal '=' sign */
        lp++;

      /* Read and store factor:                                */
      f_remainder[ipi-1] = strtod(lp, NULL);
      transitprint(30, verblevel, "%s remainder factor: %.3f\n",
                                  mol->name[nmol-1], f_remainder[ipi-1]);
      if(f_remainder[ipi-1] < 0)
        transiterror(TERR_CRITICAL,
                     "Abundance ratio has to be positive in atmosphere "
                     "file '%s' in line: '%s'.\n", atmfilename, line);
      continue;

    /* End of keyword variables: */
    default:   
      break;
    }
    break;
  }
  transitprint(1, verblevel, "Molecules with abundance proportional to "
                             "remainder:\n  ");
  for(i=nimol; i<nmol; i++)
    transitprint(1, verblevel, "%s, ", mol->name[i]);
  transitprint(1, verblevel, "\b\b.\n");

  transitprint(3, verblevel, "Read all keywords in atmosphere file without "
                             "problems.\n");

  /* Set total number of molecules in atmosphere: */
  mol->nmol = at->n_aiso = nmol;

  /* Check that there was at least one isotope defined and re-allocate 
     array sizes to their final size:                                */
  if(!nimol)
    transiterror(TERR_SERIOUS, "No isotopes were found in atmosphere file, "
                               "make sure to specify them in a line starting "
                               "with the letter 'i'. First non-comment line "
                               "read:\n%s\n", line);

  /* Set position of beginning of data: */
  at->begpos = ftell(fp) - strlen(line) - 1;

  /* Calculate cumulative fraction of remainder molecules: */
  for(i=0;  i < nmol-nimol;  i++)
    cumulother += f_remainder[i];

  transitprint(30, verblevel, "Cumulative remainder fraction: %.4f.\n",
                               cumulother);
  /* Check that cumulother sums to 1.0 (within allowed errors):  */
  if(nmol>nimol  &&  abs(1.0 - cumulother) > ROUNDTHRESH)
    transiterror(TERR_SERIOUS, "Sum of remainder-molecules fractional "
           "abundance (%g) must add to 1.0 +/- %g.\n", cumulother, ROUNDTHRESH);

  /* Resolve what to do with those isotopes that appear in the
     line transition database, but not in the atmosphere file. Get
     the number of non-ignored isotopes in atm_data without linelist: */
  //at->n_niso = checknonmatch(tr, at, isodo);
  /* FINDME: This will be a task in readline (if actually needed). */

  return at->begline;
}
Example #13
0
/* \fcnfh
   Calculate the transit modulation at each wavenumber
   Return: 0 on success, else
          -1 if impact parameter sampling is not equispaced                 */
int
modulation(struct transit *tr){
  struct optdepth *tau = tr->ds.tau;
  struct geometry *sg  = tr->ds.sg;
  static struct outputray st_out;
  tr->ds.out = &st_out;

  long w;
  prop_samp *ip = &tr->ips;
  prop_samp *wn = &tr->wns;
  ray_solution *sol = tr->sol;

  /* Check that impact parameter and wavenumber samples exist:              */
  transitcheckcalled(tr->pi, "modulation", 3, "tau",          TRPI_TAU,
                                              "makeipsample", TRPI_MAKEIP,
                                              "makewnsample", TRPI_MAKEWN);

  /* Allocate the modulation array:                                         */
  PREC_RES *out = st_out.o = (PREC_RES *)calloc(wn->n, sizeof(PREC_RES));

  /* Set time to the user hinted default, and other user hints:             */
  setgeom(sg, HUGE_VAL, &tr->pi);

  /* Integrate for each wavelength:                                         */
  transitprint(1, verblevel, "Integrating over wavelength.\n");

  int nextw = wn->n/10;

  /* Calculate the modulation spectrum at each wavenumber:                  */
  for(w=0; w < wn->n; w++){
    out[w] = sol->spectrum(tr, tau->t[w], wn->v[w], tau->last[w],
                           tau->toomuch, ip);
    if (out[w] < 0){
      switch(-(int)out[w]){
      case 1:
        if(tr->modlevel == -1)
          transiterror(TERR_SERIOUS, "Optical depth didn't reach limiting "
                       "%g at wavenumber %g cm-1 (only reached %g).  Cannot "
                       "use critical radius technique (-1).\n", tau->toomuch,
                       tau->t[w][tau->last[w]], wn->v[w]*wn->fct);
      default:
        transiterror(TERR_SERIOUS, "There was a problem while calculating "
                     "modulation at wavenumber %g cm-1. Error code %i.\n",
                     wn->v[w]*wn->fct, (int)out[w]);
        break;
      }
      exit(EXIT_FAILURE);
    }

    /* Print to screen the progress status:                                 */
    if(w==nextw){
      nextw += wn->n/10;
      transitprint(2, verblevel, "%i%% ", (10*(int)(10*w/wn->n+0.9999999999)));
    }
  }
  transitprint(1, verblevel, "\nDone.\n");

  /* Set progress indicator, and print output:                              */
  tr->pi |= TRPI_MODULATION;
  printmod(tr);  
  return 0;
}
Example #14
0
/* \fcnfh
   Read CIA info from tabulated files.
   Return: 0 on success                                                     */
int
readcia(struct transit *tr){
  FILE *fp;       /* Pointer to CIA file                                    */
  char *file,     /* CIA file name                                          */
       *colname;  /* CIA isotope names                                      */
  PREC_CIA **a,   /* CIA cross sections sample                              */
           *wn;   /* CIA sampled wavenumber array                           */

  static struct cia st_cia;  /* CIA structure                               */
  tr->ds.cia = &st_cia;
  int npairs = tr->ds.cia->nfiles = tr->ds.th->ncia; /* Number of CIA files */
  int p;                /* Auxiliary wavenumber index                       */
  long nt, wa;          /* Number of temperature, wn samples in CIA file    */
  char rc;
  char *lp, *lpa;       /* Pointers in file                                 */
  int maxline=300, n;   /* Max length of line. Counter                      */
  long lines;           /* Lines read counter                               */
  long i;               /* Auxiliary for indices                            */
  char line[maxline+1]; /* Array to hold line being read                    */
  struct molecules *mol=tr->ds.mol;

  /* Make sure that radius and wavenumber samples exist:                    */
  transitcheckcalled(tr->pi, "interpolatecia", 2, "makewnsample", TRPI_MAKEWN,
                                               "makeradsample", TRPI_MAKERAD);

  /* Allocate (output) transit extinction array (in cm-1):                  */
  st_cia.e    = (PREC_CIA **)calloc(tr->wns.n,            sizeof(PREC_CIA *));
  st_cia.e[0] = (PREC_CIA  *)calloc(tr->wns.n*tr->rads.n, sizeof(PREC_CIA));
  for(p=1; p < tr->wns.n; p++)
    st_cia.e[p] = st_cia.e[0] + p*tr->rads.n;
  memset(st_cia.e[0], 0, tr->wns.n*tr->rads.n*sizeof(double));

  /* If there are no files, allocate tr.ds.cia.e (extinction) and return:   */
  if(!npairs){
    return 0;
  }
  transitprint(1, verblevel, "Computing CIA opacities for %i database%s:\n",
               npairs, npairs>1 ? "s":"");

  /* Allocate string for molecule names:                                    */
  colname = (char *)calloc(maxline, sizeof(char));

  /* Allocate molecules' ID:                                                */
  st_cia.mol1 = (int   *)calloc(npairs, sizeof(int));
  st_cia.mol2 = (int   *)calloc(npairs, sizeof(int));
  /* Number of temperature and wavenumber samples per file:                 */
  st_cia.ntemp = (int  *)calloc(npairs, sizeof(int));
  st_cia.nwave = (int  *)calloc(npairs, sizeof(int));
  /* CIA, temperature and wavenumber samples:                               */
  st_cia.cia  = (PREC_CIA ***)calloc(npairs, sizeof(PREC_CIA **));
  st_cia.temp = (PREC_CIA  **)calloc(npairs, sizeof(PREC_CIA  *));
  st_cia.wn   = (PREC_CIA  **)calloc(npairs, sizeof(PREC_CIA  *));

  for(p=0; p < npairs; p++){
    /* Copy file names from hint:                                           */
    file = xstrdup(tr->ds.th->ciafile[p]);

    /* Attempt to open the files:                                           */
    if((fp=fopen(file, "r")) == NULL)
      transiterror(TERR_SERIOUS, "Cannot read CIA file '%s'.\n", file);
    transitprint(10, verblevel, "  CIA file (%d/%d): '%s'\n",
                                p+1, npairs, file);
    lines = 0; /* lines read counter                                        */
    lpa   = 0;
    /* Read the file headers:                                               */
    while(1){
      /* Skip comments, blanks and read next line:                          */
      while((rc=fgetupto_err(lp=line, maxline, fp, &ciaerr, file, lines++))
             =='#' || rc=='\n');
      /* If it is end of file, stop loop:                                   */
      if(!rc)
        transiterror(TERR_SERIOUS, "File '%s' finished before opacity info.\n",
                     file);

      switch(rc){
      case 'i': /* Read the name of the isotopes:                           */
        while(isblank(*++lp));
        /* Check that there are exactly two isotopes:                       */
        if(countfields(lp, ' ') != 2)
          transiterror(TERR_SERIOUS,
                       "Wrong line %i in CIA file '%s', if it begins with a "
                       "'i', it should have the species separated by blank "
                       "spaces.  Rest of line:\n'%s'\n", lines, file, lp);

        st_cia.mol1[p] = st_cia.mol2[p] = -1;
        /* Allocate and copy the name of the first moleculee:               */
        getname(lp, colname);
        /* Find the ID of the first molecule:                               */
        for(i=0; i<mol->nmol; i++)
          if(strcmp(mol->name[i], colname)==0)
            st_cia.mol1[p] = i;
        /* If the molecule is not in the atmosphere file:                   */
        if(st_cia.mol1[p] == -1)
          transiterror(TERR_SERIOUS, "CIA molecule '%s' from file '%s' does "
                    "not match any in the atmsopheric file.\n", colname, file);

        /* Allocate and store the name of the second isotope:               */
        lp = nextfield(lp);
        getname(lp, colname);
        for(i=0; i < mol->nmol; i++)
          if(strcmp(mol->name[i], colname)==0)
            st_cia.mol2[p] = i;
        if(st_cia.mol2[p] == -1)
          transiterror(TERR_SERIOUS, "CIA molecule '%s' from file '%s' does "
                    "not match any in the atmsopheric file.\n", colname, file);
        transitprint(10, verblevel, "  CIA molecules: [%s, %s]\n",
                         mol->name[st_cia.mol1[p]], mol->name[st_cia.mol2[p]]);
        continue;

      case 't': /* Read the sampling temperatures array:                    */
        while(isblank(*++lp));
        nt = st_cia.ntemp[p] = countfields(lp, ' '); /* Number of temps.    */
        transitprint(10, verblevel, "  Number of temperature samples: %ld\n",
                                    nt);
        if(!nt)
          transiterror(TERR_SERIOUS, "Wrong line %i in CIA file '%s', if it "
                       "begins with a 't' then it should have the "
                       "blank-separated fields with the temperatures. Rest "
                       "of line: %s.\n", lines, file, lp);
        /* Allocate and store the temperatures array:                       */
        st_cia.temp[p] = (PREC_CIA *)calloc(nt, sizeof(PREC_CIA));
        n = 0;    /* Count temperatures per line                            */
        lpa = lp; /* Pointer in line                                        */
        transitprint(20, verblevel, "  Temperatures (K) = [");
        while(n < nt){
          while(isblank(*lpa++));
          st_cia.temp[p][n] = strtod(--lpa, &lp); /* Get value */
          transitprint(20, verblevel, "%d, ", (int)st_cia.temp[p][n]);
          if(lp==lpa)
            transiterror(TERR_CRITICAL, "Less fields (%i) than expected (%i) "
                         "were read for temperature in the CIA file '%s'.\n",
                         n, nt, file);
          if((lp[0]|0x20) == 'k') lp++; /* Remove trailing K if exists      */
          lpa = lp;
          n++;
        }
        transitprint(20, verblevel, "\b\b]\n");
        continue;
      default:
        break;
      }
      break;
    }

    /* Set an initial value for allocated wavenumber fields:                */
    wa = 32;

    /* Allocate wavenumber array:                                           */
    wn   = (PREC_CIA  *)calloc(wa,    sizeof(PREC_CIA));
    /* Allocate input extinction array (in cm-1 amagat-2):                  */
    a    = (PREC_CIA **)calloc(wa,    sizeof(PREC_CIA *));
    a[0] = (PREC_CIA  *)calloc(wa*nt, sizeof(PREC_CIA));
    for(i=1; i<wa; i++)
      a[i] = a[0] + i*nt;

    n=0;
    /* Read information for each wavenumber sample:                         */
    while(1){
      /* Skip comments and blanks; read next line:                          */
      if (n)
        while((rc=fgetupto_err(lp=line, maxline, fp, &ciaerr, file, lines++))
              =='#'||rc=='\n');
      /* Stop, if it is end of file:                                        */
      if(!rc)
        break;

      /* Re-allocate (double the size) if necessary:                        */
      if(n==wa){
        wn   = (PREC_CIA  *)realloc(wn,  (wa<<=1) * sizeof(PREC_CIA));
        a    = (PREC_CIA **)realloc(a,    wa *      sizeof(PREC_CIA *));
        a[0] = (PREC_CIA  *)realloc(a[0], wa * nt * sizeof(PREC_CIA));
        for(i=1; i<wa; i++)
          a[i] = a[0] + i*nt;
      }

      /* Store new line: wavenumber first, then loop over cross sections:   */
      while(isblank(*lp++));
      wn[n] = strtod(lp-1, &lpa);  /* Store wavenumber                      */
      if(lp==lpa+1)
        transiterror(TERR_CRITICAL, "Invalid fields for the %ith wavenumber "
                                    "in the CIA file '%s'.\n", n+1, file);
      i = 0;
      while(i<nt){
        a[n][i] = strtod(lpa, &lp); /* Store cross section                  */
        if(lp==lpa)
          transiterror(TERR_CRITICAL, "Less fields (%i) than expected (%i) "
                       "were read for the %ith wavenumber in the CIA "
                       "file '%s'.\n", i, nt, n+1, file);
        lpa = lp;
        i++;
      }
      n++;
    }

    /* Re-allocate arrays to their final sizes:                             */
    if(n<wa){
      st_cia.wn[p] = (PREC_CIA  *)realloc(wn,   n*   sizeof(PREC_CIA));
      a            = (PREC_CIA **)realloc(a,    n*   sizeof(PREC_CIA *));
      a[0]         = (PREC_CIA  *)realloc(a[0], n*nt*sizeof(PREC_CIA));
      for(i=1; i<n; i++)
        a[i] = a[0] + i*nt;
    }
    transitprint(10, verblevel, "  Number of wavenumber samples: %d\n", n);
    transitprint(20, verblevel, "  Wavenumber array (cm-1) = [%.1f, %.1f, "
         "%.1f, ..., %.1f, %.1f, %.1f]\n", st_cia.wn[p][0],   st_cia.wn[p][1],
      st_cia.wn[p][2], st_cia.wn[p][n-3], st_cia.wn[p][n-2], st_cia.wn[p][n-1]);
    st_cia.cia[p] = a;
    st_cia.nwave[p] = n;
    fclose(fp);
  }
  /* FINDME: The program breaks when I free colname, it makes no sense      */
  free(colname);
  transitprint(1, verblevel, "Done.\n");
  tr->pi |= TRPI_CIA;
  return 0;
}