Exemplo n.º 1
0
/* \fcnfh
   Set geometry variables

   @returns 0 on success
*/
int
setgeom(struct geometry *sg,	/* geometry structure */
	double time,		/* time for which to set planet
				   position, use HUGE_VAL for use the
				   default value stored in the geometry
				   structure */
	long *flags)		/* Progress indicator flag */
{
  transitcheckcalled(*flags,"setgeom",1,
		     "setgeomhint",TRPI_GEOMETRYHINT
		     );

  /* TD: include argument of pericenter and longitud of the node in the
     computations, right now both values are used as zero. */
  //Auxiliary variables in cgs
  double smaxis=sg->smaxis*sg->smaxisfct;
  double ecc=sg->ecc*sg->eccfct;
  double incl=sg->incl*sg->inclfct;
  //  double aper=sg->aper*sg->aperfct;
  //  double lnode=sg->lnode*sg->lnodefct;
  double t=(time<HUGE_VAL?time:sg->time)*sg->timefct;
  double mass=sg->starmass*sg->starmassfct;

  //set mean angular velocity, mean true anomaly, and others variables
  double prec2=1e-12;
  double n=sqrt(GGRAV*mass/smaxis/smaxis/smaxis);
  double Ea=HUGE_VAL,E=n*time;
  while((E-Ea)*(E-Ea)>prec2){
    Ea=E;
    E=n*t+ecc*sin(E);
  }
  double M=smaxis*(1-ecc*ecc);
  double Delta=smaxis*(1-ecc*cos(E));
  double cosv=(M-Delta)/ecc/Delta;
  double sini=sin(incl);
  double cosi=cos(incl);

  //set X and Y.
  sg->x=Delta*sqrt(cosi*cosi-cosv*cosv);
  sg->y=Delta*sini;
  
  //set progress indicator and return.
  *flags|=TRPI_GEOMETRY;
  return 0;
}
Exemplo n.º 2
0
/* \fcnfh
   Set X and Y geometry variables

   Return: 0 on success     */
int
setgeom(struct geometry *sg, /* geometry structure                           */
        double time,         /* Time for which to set planet position. If
                                HUGE_VAL, use the default geometry value     */
        long *flags){        /* Progress indicator flag                      */

  transitcheckcalled(*flags, "setgeom", 1, "setgeomhint", TRPI_GEOMETRYHINT);

  /* TBD: include argument of pericenter and longitud of the node in the
     computations, right now both values are used as zero.                */
  /* Auxiliary variables in cgs */
  double smaxis = sg->smaxis*sg->smaxisfct; /* semi-major axis */
  double ecc    = sg->ecc*sg->eccfct;       /* eccentricity    */
  double incl   = sg->incl*sg->inclfct;     /* inclination     */
  // double aper  = sg->aper*sg->aperfct;
  // double lnode = sg->lnode*sg->lnodefct;
  double t = (time<HUGE_VAL ? time:sg->time)*sg->timefct; /* observation time */
  double mass = sg->starmass*sg->starmassfct; /* Stellar mass */

  double prec2 = 1e-12;  /* Square eccentric anomaly precision limit */
  double n = sqrt(GGRAV*mass/(smaxis*smaxis*smaxis)); /* Mean motion */
  double Ea = HUGE_VAL,  /* Approximation to eccentric anomaly       */
         E  = n*time;    /* Eccentric anomaly                        */
  /* Solve Kepler equation to get the eccentric anomaly at time t:   */
  while((E-Ea)*(E-Ea) > prec2){
    Ea = E;
    E  = n*t + ecc*sin(E);
  }

  double M     = smaxis*(1-ecc*ecc);
  double Delta = smaxis*(1-ecc*cos(E));
  double cosv = (M-Delta)/(ecc*Delta);  /* a * cosine of true anomaly */
  double sini = sin(incl);
  double cosi = cos(incl);

  /* Set X and Y: */
  sg->x = Delta*sqrt(cosi*cosi-cosv*cosv);
  sg->y = Delta*sini;
  
  /* Set progress indicator and return: */
  *flags |= TRPI_GEOMETRY;
  return 0;
}
Exemplo n.º 3
0
/* FUNCTION:  Calculate the opacity due to molecular transitions.
   Return: 0 on success                                                     */
int
opacity(struct transit *tr){
  struct transithint *th = tr->ds.th; /* transithint struct                 */
  static struct opacity op;           /* The opacity struct                 */

  /* Set the opacity struct's mem to 0:                                     */
  memset(&op, 0, sizeof(struct opacity));
  tr->ds.op = &op;

  /* Check that the radius array has been sampled:                          */
  transitcheckcalled(tr->pi, "opacity", 1, "makeradsample", TRPI_MAKERAD);

  /* Check if the opacity file exists:                                      */
  int file_exists = fileexistopen(th->f_opa, NULL);
  tr_output(TOUT_INFO, "Opacity-file exist status = %d\n", file_exists);

  /* Set the file name in the transit struct:                               */
  tr->f_opa = th->f_opa;

  /* Opacity file has some error that makes it unusable, or not specified:  */
  if (file_exists < -1 || file_exists == 0) {

    /* Calculate Voigt profiles:                                            */
    tr_output(TOUT_INFO, "Calculating grid of Voigt profiles.\n");
    calcprofiles(tr);

    /* Set progress indicator and return success:                           */
    tr->pi |= TRPI_OPACITY;
    return 0;
  }

  /* Opacity file specified, but it just doesn't exist yet:                 */
  if (file_exists == -1) {

    /* Open file for writing:                                               */
    tr->fp_opa = fopen(tr->f_opa, "wb");

    /* Immediately return if the file could not be opened:                  */
    if (tr->fp_opa == NULL){
      tr_output(TOUT_WARN, "Opacity filename '%s' cannot be opened "
        "for writing.\n", tr->f_opa);
      return -1;
    }

    /* Calculate Voigt profiles:                                            */
    tr_output(TOUT_INFO, "Calculating grid of Voigt profiles.\n");
    calcprofiles(tr);

    /* Calculate the grid of opacities:                                     */
    tr_output(TOUT_INFO, "Calculating new grid of opacities: '%s'.\n",
                               tr->f_opa);
    calcopacity(tr, tr->fp_opa);

    /* Free the line-transition memory:                                     */
    freemem_linetransition(&tr->ds.li->lt, &tr->pi);
    tr->pi |= TRPI_READDATA;
    tr->pi |= TRPI_READINFO;

    /* Set progress indicator and return success:                           */
    tr->pi |= TRPI_OPACITY;
    return 0;
  }

  /* Implied: The opacity file exists:                                      */
  file_exists = fileexistopen(th->f_opa, &tr->fp_opa);
  tr->f_opa = th->f_opa;
  tr_output(TOUT_INFO, "Opacity-file exist status = %d\n", file_exists);

  if (file_exists != 1) {

    tr_output(TOUT_WARN, "Opening opacity file failed.\n");

    /* Calculate Voigt profiles:                                            */
    tr_output(TOUT_INFO, "Calculating grid of Voigt profiles.\n");
    calcprofiles(tr);

    /* Set progress indicator and return success:                           */
    tr->pi |= TRPI_OPACITY;
    return 0;
  }

  /* Should attempt to use shared memory:                                   */
  if (tr->opashare) {

    /* Get ID or create shared opacityhint struct:                          */
    key_t hintkey = ftok(tr->f_opa, 'a');
    op.hintID = shmget(hintkey, sizeof(struct opacityhint), 0644 | IPC_CREAT);

    /* If reserving the hint segment was unsuccessful, give up:             */
    if (op.hintID == -1) {

      tr_output(TOUT_WARN, "Could not get hint shared memory ID.\n");

      /* Read the grid of opacities from file:                              */
      tr_output(TOUT_INFO, "Reading opacity file: '%s'.\n", tr->f_opa);
      readopacity(tr, tr->fp_opa);

      /* Set progress indicator and return success:                         */
      tr->pi |= TRPI_OPACITY;
      return 0;
    }

    /* Attach to the hint shared memory segment:                            */
    op.hint = shmat(op.hintID, (void *) 0, 0);

    /* If attaching was unsuccessful, give up.                              */
    if (op.hint == (struct opacityhint *) -1) {

      tr_output(TOUT_WARN, "Could not attach to hint shared memory.\n");

      /* Read the grid of opacities from file:                              */
      tr_output(TOUT_INFO, "Reading opacity file: '%s'.\n", tr->f_opa);
      readopacity(tr, tr->fp_opa);

      /* Set progress indicator and return success:                         */
      tr->pi |= TRPI_OPACITY;
      return 0;
    }

    /* If no process has claimed to be the master, claim it:                */
    if (op.hint->master_PID == 0)
      op.hint->master_PID = getpid();

    /* Wait a few cycles in case multiple processes claimed it at once:     */
    int i;
    for (i = 0; i < 10; i++);

    /* Check again to see if this process claimed the memory:               */
    if (op.hint->master_PID == getpid()) {

      /* Share the grid of opacities from file:                             */
      tr_output(TOUT_INFO, "Sharing opacity file: '%s'.\n", tr->f_opa);

      if (shareopacity(tr, tr->fp_opa) || mountopacity(tr)) {

        tr_output(TOUT_WARN, "Shared memory sh/mt error. Aborting.\n");
        op.hint->status |= TSHM_ERROR;

        /* Read the grid of opacities from file:                            */
        tr_output(TOUT_INFO, "Reading opacity file: '%s'.\n",
                                    tr->f_opa);
        readopacity(tr, tr->fp_opa);
      }

      /* Assuming that all processes have attached to the two shared
         memory segments, mark them for destruction as soon as all of the
         processes have detached.                                           */
      struct shmid_ds buf1, buf2;
      shmctl(op.hintID, IPC_STAT, &buf1);

      do {
        shmctl(op.mainID, IPC_STAT, &buf2);
      }
      while (buf2.shm_nattch != buf1.shm_nattch);

      tr_output(TOUT_DEBUG, "Marking shared memory for removal.\n");
      shmctl(op.hintID, IPC_RMID, &buf1);
      shmctl(op.mainID, IPC_RMID, &buf2);

      /* Set progress indicator and return success:                         */
      tr->pi |= TRPI_OPACITY;
      return 0;
    }

    else {

      while ((op.hint->status & TSHM_WRITTEN) == 0) {

        /* If there's an error with the shared memory, abort.               */
        if (op.hint->status & TSHM_ERROR) {

          tr_output(TOUT_WARN, "Shared memory error. Aborting.\n");

          /* Read the grid of opacities from file:                          */
          tr_output(TOUT_INFO, "Reading opacity file: '%s'.\n", tr->f_opa);
          readopacity(tr, tr->fp_opa);

          /* Set progress indicator and return success:                     */
          tr->pi |= TRPI_OPACITY;
          return 0;
        }
      }
    }

    /* If there's an error attaching or mounting the memory, abort.     */
    if (attachopacity(tr) || mountopacity(tr)) {

      tr_output(TOUT_WARN, "Shared memory att/mt error. Aborting.\n");

      /* Read the grid of opacities from file:                          */
      tr_output(TOUT_INFO, "Reading opacity file: '%s'.\n", tr->f_opa);
      readopacity(tr, tr->fp_opa);
    }
  }

  /* Should not attempt to use shared memory:                               */
  else {

    /* Read the grid of opacities from file:                                */
    tr_output(TOUT_INFO, "Reading opacity file: '%s'.\n", tr->f_opa);
    readopacity(tr, tr->fp_opa);
  }

  /* Set progress indicator and return success:                           */
  tr->pi |= TRPI_OPACITY;
  return 0;
}
Exemplo n.º 4
0
/* \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;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/* FUNCTION:
   Fill up the extinction information in tr->ds.ex
   TD: Scattering parameters should be added at some point here.
  Return: 0 on success, else
          computeextradius()                                                */
int
extwn(struct transit *tr){
  struct transithint *th=tr->ds.th;
  static struct extinction st_ex;
  tr->ds.ex = &st_ex;
  struct extinction *ex = &st_ex;
  int i;

  /* Check these routines have been called:                                 */
  transitcheckcalled(tr->pi, "extwn", 4,
                             "readinfo_tli",  TRPI_READINFO,
                             "readdatarng",   TRPI_READDATA,
                             "makewnsample",  TRPI_MAKEWN,
                             "makeradsample", TRPI_MAKERAD);
  transitacceptflag(tr->fl, tr->ds.th->fl, TRU_EXTBITS);

  struct isotopes *iso = tr->ds.iso;
  int niso = iso->n_i;
  int nrad = tr->rads.n;
  int nwn  = tr->wns.n;

  /* Check there is at least one atmospheric layer:                         */
  /* FINDME: Move to readatm                                                */
  if(tr->rads.n < 1){
    tr_output(TOUT_ERROR,
      "There are no atmospheric parameters specified. I need at "
      "least one atmospheric point to calculate a spectra.\n");
    return -2;
  }
  /* Check there are at least two wavenumber sample points:                 */
  /* FINDME: Move to makewnsample                                           */
  if(tr->wns.n < 2){
    tr_output(TOUT_ERROR,
      "I need at least 2 wavenumber points to compute anything; "
      "I need resolution.\n");
    return -3;
  }
  /* Check there is at least one isotope linelist                           */
  /* FINDME: This should not be a condition, we may want
     to calculate an atmosphere with only CIA for example.                  */
  if(niso < 1){
    tr_output(TOUT_WARN, "You are requiring a spectra of zero isotopes.\n");
  }

  /* Get the extinction coefficient threshold:                              */
  ex->ethresh = th->ethresh;

  /* Declare extinction-coefficient array:                                  */
  ex->e        = (PREC_RES **)calloc(nrad,     sizeof(PREC_RES *));
  if((ex->e[0] = (PREC_RES  *)calloc(nrad*nwn, sizeof(PREC_RES)))==NULL) {
    tr_output(TOUT_ERROR, "Unable to allocate %li = %li*%li "
      "for the extinction coefficient.\n", nrad*nwn, nrad, nwn);
    exit(EXIT_FAILURE);
  }

  for(i=1; i<nrad; i++){
    ex->e[i] = ex->e[0] + i*nwn;
  }

  /* Has the extinction been computed at given radius boolean:              */
  ex->computed = (_Bool *)calloc(nrad, sizeof(_Bool));

  /* Set progress indicator, and print and output extinction if one P,T
     was desired, otherwise return success:                                 */
  tr->pi |= TRPI_EXTWN;
  return 0;
}