Пример #1
0
/**************************************************************************
 * atct_init:
 * calculates alpha1, alpha2, and alpha3, which are some sort of coordinate
 * rotation amounts, in degrees.  This creates a latitude/longitude-style
 * coordinate system centered under the satellite at the start of imaging.
 * You must pass it a state vector from the start of imaging.            */
void atct_init(meta_projection *proj,stateVector st)
{
  vector up={0.0,0.0,1.0};
  vector z_orbit, y_axis, a, nd;
  double alpha3_sign;
  double alpha1,alpha2,alpha3;

  vecCross(st.pos,st.vel,&z_orbit);vecNormalize(&z_orbit);

  vecCross(z_orbit,up,&y_axis);vecNormalize(&y_axis);

  vecCross(y_axis,z_orbit,&a);vecNormalize(&a);

  alpha1 = atan2_check(a.y,a.x)*R2D;
  alpha2 = -1.0 * asind(a.z);
  if (z_orbit.z < 0.0)
    {
      alpha1 +=  180.0;
      alpha2 = -1.0*(180.0-fabs(alpha2));
    }

  vecCross(a,st.pos,&nd);vecNormalize(&nd);
  alpha3_sign = vecDot(nd,z_orbit);
  alpha3 = acosd(vecDot(a,st.pos)/vecMagnitude(st.pos));
  if (alpha3_sign<0.0)
    alpha3 *= -1.0;

  proj->param.atct.alpha1=alpha1;
  proj->param.atct.alpha2=alpha2;
  proj->param.atct.alpha3=alpha3;
}
Пример #2
0
main()
    {
    double alt, b, asshole ;

    for( alt = 0.0 ; alt <= 90.1 ; alt += 1 )
	{
	asshole = sind( ( alt + 90.0 ) ) ;
	b = asind( 0.75 * sind( alt + 90.0 ) ) ;

	printf( "%13.6e %13.6e %13.6e\n", alt, asshole, b ) ;
	}
    }
Пример #3
0
static inline void CorrectHKLsLatC(double LatC[6],double Lsd,double Wavelength,double hkls[5000][4],double Thetas[5000],double hklsIn[5000][4],int nhkls)
{
	double a=LatC[0],b=LatC[1],c=LatC[2],alpha=LatC[3],beta=LatC[4],gamma=LatC[5];
	int hklnr;
	for (hklnr=0;hklnr<nhkls;hklnr++){
		double ginit[3]; ginit[0] = hklsIn[hklnr][0]; ginit[1] = hklsIn[hklnr][1]; ginit[2] = hklsIn[hklnr][2];
		double SinA = sind(alpha), SinB = sind(beta), SinG = sind(gamma), CosA = cosd(alpha), CosB = cosd(beta), CosG = cosd(gamma);
		double GammaPr = acosd((CosA*CosB - CosG)/(SinA*SinB)), BetaPr  = acosd((CosG*CosA - CosB)/(SinG*SinA)), SinBetaPr = sind(BetaPr);
		double Vol = (a*(b*(c*(SinA*(SinBetaPr*(SinG)))))), APr = b*c*SinA/Vol, BPr = c*a*SinB/Vol, CPr = a*b*SinG/Vol;
		double B[3][3]; B[0][0] = APr; B[0][1] = (BPr*cosd(GammaPr)), B[0][2] = (CPr*cosd(BetaPr)), B[1][0] = 0,
			B[1][1] = (BPr*sind(GammaPr)), B[1][2] = (-CPr*SinBetaPr*CosA), B[2][0] = 0, B[2][1] = 0, B[2][2] = (CPr*SinBetaPr*SinA);
		double GCart[3];
		MatrixMultF(B,ginit,GCart);
		double Ds = 1/(sqrt((GCart[0]*GCart[0])+(GCart[1]*GCart[1])+(GCart[2]*GCart[2])));
		hkls[hklnr][0] = GCart[0];hkls[hklnr][1] = GCart[1];hkls[hklnr][2] = GCart[2];
        hkls[hklnr][3] = hklsIn[hklnr][3];
        Thetas[hklnr] = (asind((Wavelength)/(2*Ds)));
	}
}
Пример #4
0
void fldpnth_gs(double gdlat,double gdlon,double psi,double bore,
			 double fh,double r,double *frho,double *flat,
	                 double *flon) {

  double rrad,rlat,rlon,del;
  double tan_azi,azi,rel,xel,fhx,xal,rrho,ral,xh;
  double dum,dum1,dum2,dum3;
  double frad;  
 
  if (fh<=150) xh=fh;
  else {
    if (r<=300) xh=115;
    else if ((r>300) && (r<500)) xh=(r-300)/200*(fh-115)+115;
    else xh=fh;
  }

  if (r<150) xh=(r/150.0)*115.0;
  geodtgc(1,&gdlat,&gdlon,&rrad,&rlat,&rlon,&del);
  rrho=rrad;
  frad=rrad;
 

  do {
    *frho=frad+xh;
  
    rel=asind( ((*frho**frho) - (rrad*rrad) - (r*r)) / (2*rrad*r));
    xel=rel;
    if (((cosd(psi)*cosd(psi))-(sind(xel)*sind(xel)))<0) tan_azi=1e32;
      else tan_azi=sqrt( (sind(psi)*sind(psi))/
                ((cosd(psi)*cosd(psi))-(sind(xel)*sind(xel))));
    if (psi>0) azi=atand(tan_azi)*1.0;
      else azi=atand(tan_azi)*-1.0;
    xal=azi+bore;
    geocnvrt(gdlat,gdlon,xal,xel,&ral,&dum);

    fldpnt(rrho,rlat,rlon,ral,rel,r,frho,flat,flon);
    geodtgc(-1,&dum1,&dum2,&frad,flat,flon,&dum3);
    fhx=*frho-frad; 
  } while(fabs(fhx-xh) > 0.5);
} 
Пример #5
0
int main (int argc, char *argv[]){
	if (argc != 2){
		printf("Give a parameter file.\n");
		exit(1);
	}
	int SpaceGrp;
	double LatC[6], wl, Lsd, MaxRingRad;
	char *ParamFN;
    FILE *fileParam;
    ParamFN = argv[1];
    char aline[1000];
    fileParam = fopen(ParamFN,"r");
    char *str, dummy[1000];
    int LowNr;
    while (fgets(aline,1000,fileParam)!=NULL){
        str = "SpaceGroup ";
        LowNr = strncmp(aline,str,strlen(str));
        if (LowNr==0){
            sscanf(aline,"%s %d", dummy, &SpaceGrp);
            continue;
        }
        str = "LatticeConstant ";
        LowNr = strncmp(aline,str,strlen(str));
        if (LowNr==0){
            sscanf(aline,"%s %lf %lf %lf %lf %lf %lf", dummy, &LatC[0],
					&LatC[1], &LatC[2], &LatC[3], &LatC[4], &LatC[5]);
            continue;
        }
        str = "LatticeParameter ";
        LowNr = strncmp(aline,str,strlen(str));
        if (LowNr==0){
            sscanf(aline,"%s %lf %lf %lf %lf %lf %lf", dummy, &LatC[0],
					&LatC[1], &LatC[2], &LatC[3], &LatC[4], &LatC[5]);
            continue;
        }
        str = "Wavelength ";
        LowNr = strncmp(aline,str,strlen(str));
        if (LowNr==0){
            sscanf(aline,"%s %lf", dummy, &wl);
            continue;
        }
        str = "Lsd ";
        LowNr = strncmp(aline,str,strlen(str));
        if (LowNr==0){
            sscanf(aline,"%s %lf", dummy, &Lsd);
            continue;
        }
        str = "MaxRingRad ";
        LowNr = strncmp(aline,str,strlen(str));
        if (LowNr==0){
            sscanf(aline,"%s %lf", dummy, &MaxRingRad);
            continue;
        }
	}
	printf("%f %f %f %d %f %f %f %f %f %f\n",wl,Lsd,MaxRingRad,SpaceGrp,LatC[0],LatC[1],LatC[2],LatC[3],LatC[4],LatC[5]);
	int h, k, l, iList, restriction, M, i, j;
	int Minh, Mink, Minl;
	int CCMx_PL[9], deterCCMx_LP = 0;
	double Epsilon = 0.0001;
	int Families[50000][3];
	T_SgInfo *SgInfo;
	char SgName[200]; 
	int F_Convention='A';
	const T_TabSgName *tsgn; 
	
	printf("Generating hkl's\n");
	if((SgInfo = (T_SgInfo *)malloc(sizeof(T_SgInfo)))==NULL){
		printf("Unable to allocate SgInfo\n");
		printf("Aborting\n");
		exit(1);
	}
	SgInfo->GenOption = 0;
	SgInfo->MaxList   = 192;
	if((SgInfo->ListSeitzMx = (T_RTMx*)malloc(SgInfo->MaxList * sizeof(T_RTMx)))==NULL){
		printf("Unable to allocate (SgInfo.ListSeitzMx\n");
		printf("Aborting\n");
		exit(1);
	}
	SgInfo->ListRotMxInfo = NULL;
	InitSgInfo(SgInfo);
	sprintf(SgName,"%d",SpaceGrp);
	tsgn = FindTabSgNameEntry(SgName, F_Convention);
	if (tsgn == NULL){
		printf("Error: Unknown Space Group Symbol\n");
		printf("Aborting\n");
		exit(1);
	}
	sprintf(SgName,"%s",tsgn->HallSymbol);
	SgInfo->TabSgName = tsgn;
	if (tsgn) SgInfo->GenOption = 1;
	{
		int pos_hsym;
		pos_hsym = ParseHallSymbol(SgName, SgInfo);
		
		if (SgError != NULL) {
			printf("Error: Unknown Space Group Symbol\n");
			printf("Aborting\n");
			exit(1);
		}
	}
	if(CompleteSgInfo(SgInfo)!=0) {
		printf("Error in Complete\n");
		printf("Aborting\n");
		exit(1);
	}
	if (SgInfo->LatticeInfo->Code != 'P')
	{
		deterCCMx_LP = deterRotMx(SgInfo->CCMx_LP);
		InverseRotMx(SgInfo->CCMx_LP, CCMx_PL);
		if (deterCCMx_LP < 1) {
			printf("deterCMM failed.\n");
			return 0;
		}
	}
	int Maxh, Maxk, Maxl;
	int nrFilled=0;
	Maxh = 10;
	Maxk = 10;
	Maxl = 10;
	SetListMin_hkl(SgInfo, Maxk, Maxl, &Minh, &Mink, &Minl);
	printf("Will go from %d to %d in h; %d to %d in k; %d to %d in l.\n",Minh, Maxh, Mink, Maxk, Minl, Maxl);
	for (h = Minh; h <= Maxh; h++){
		for (k = Mink; k <= Maxk; k++){
			for (l = Minl; l <= Maxl; l++){
				if (h==0 && k==0 && l==0){
					continue;
				}
				iList = IsSysAbsent_hkl(SgInfo, h, k, l, &restriction);
				if (SgError != NULL) {
					printf("IsSysAbsent_hkl failed.\n");
					return 0;
				}
				if (iList == 0){
					if ((iList = IsSuppressed_hkl(SgInfo, Minh, Mink, Minl,
						Maxk, Maxl, h, k, l)) != 0) {/* Suppressed reflections */
					} else {
						//printf("New plane.\n");
						T_Eq_hkl Eq_hkl;
						M = BuildEq_hkl(SgInfo, &Eq_hkl, h, k, l);
						if (SgError != NULL){
							return 0;
						}
						for (i=0;i<Eq_hkl.N;i++){
							for (j=-1;j<=1;j+=2){
								//printf("%d %d %d\n",Eq_hkl.h[i]*j,Eq_hkl.k[i]*j,Eq_hkl.l[i]*j);
								Families[nrFilled][0] = Eq_hkl.h[i]*j;
								Families[nrFilled][1] = Eq_hkl.k[i]*j;
								Families[nrFilled][2] = Eq_hkl.l[i]*j;
								nrFilled++;
							}
						}
					}
				}
			}
		}
	}
	int AreDuplicates[50000];
	double **UniquePlanes;
	UniquePlanes = allocMatrix(50000,3);
	for (i=0;i<50000;i++) AreDuplicates[i] = 0;
	int nrPlanes=0;
	for (i=0;i<nrFilled-1;i++){
		if (AreDuplicates[i] == 1){
			continue;
		}
		for (j=i+1;j<nrFilled;j++){
			if (Families[i][0] == Families[j][0] && 
				Families[i][1] == Families[j][1] && 
				Families[i][2] == Families[j][2] &&
				AreDuplicates[j] == 0){
					AreDuplicates[j] = 1;
			}
		}
		UniquePlanes[nrPlanes][0] = (double)Families[i][0];
		UniquePlanes[nrPlanes][1] = (double)Families[i][1];
		UniquePlanes[nrPlanes][2] = (double)Families[i][2];
		nrPlanes++;
	}
	double **hkls;
	hkls = allocMatrix(nrPlanes,12);
	CorrectHKLsLatC(LatC,UniquePlanes,nrPlanes,hkls);
	SortFunc(nrPlanes,11,hkls,3,-1);
	double DsMin = wl/(2*sind((atand(MaxRingRad/Lsd))/2));
	for (i=0;i<nrPlanes;i++){
		if (hkls[i][3] < DsMin){
			nrPlanes = i;
			break;
		}
	}
	int RingNr = 1;
	double DsTemp = hkls[0][3];
	hkls[0][4] = 1;
	hkls[0][8] = asind(wl/(2*(hkls[0][3])));
	hkls[0][9] = hkls[0][8]*2;
	hkls[0][10] = Lsd*tand(hkls[0][9]);
	for (i=1;i<nrPlanes;i++){
		if (fabs(hkls[i][3] - DsTemp) < Epsilon){
			hkls[i][4] = RingNr;
		}else{
			DsTemp = hkls[i][3];
			RingNr++;
			hkls[i][4] = RingNr;
		}
		hkls[i][8] = asind(wl/(2*(hkls[i][3])));
		hkls[i][9] = hkls[i][8]*2;
		hkls[i][10] = Lsd*tand(hkls[i][9]);
	}
	char *fn = "hkls.csv";
	FILE *fp;
	fp = fopen(fn,"w");
	fprintf(fp,"h k l D-spacing RingNr\n");
	for (i=0;i<nrPlanes;i++){
		fprintf(fp,"%.0f %.0f %.0f %f %.0f %f %f %f %f %f %f\n",hkls[i][0],
			hkls[i][1],hkls[i][2],hkls[i][3],hkls[i][4],
			hkls[i][5],hkls[i][6],hkls[i][7],hkls[i][8],
			hkls[i][9],hkls[i][10]);
	}
}
Пример #6
0
int spcs2x(
  struct spcprm *spc,
  int nspec,
  int sspec,
  int sx,
  const double spec[],
  double x[],
  int stat[])

{
  static const char *function = "spcs2x";

  int statP2X, status = 0, statS2P;
  double beta, s;
  register int ispec;
  register int *statp;
  register const double *specp;
  register double *xp;
  struct wcserr **err;

  /* Initialize. */
  if (spc == 0x0) return SPCERR_NULL_POINTER;
  err = &(spc->err);

  if (spc->flag == 0) {
    if ((status = spcset(spc))) return status;
  }

  /* Apply the linear step of the algorithm chain to convert the S-type */
  /* spectral variable to P-type intermediate spectral variable.        */
  if (spc->spxS2P) {
    if ((statS2P = spc->spxS2P(spc->w[0], nspec, sspec, sx, spec, x, stat))) {
      if (statS2P == SPXERR_BAD_INSPEC_COORD) {
        status = SPCERR_BAD_SPEC;
      } else if (statS2P == SPXERR_BAD_SPEC_PARAMS) {
        return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS),
          "Invalid spectral parameters: Frequency or wavelength is 0");
      } else {
        return wcserr_set(SPC_ERRMSG(spc_spxerr[statS2P]));
      }
    }

  } else {
    /* Just a copy. */
    xp = x;
    specp = spec;
    statp = stat;
    for (ispec = 0; ispec < nspec; ispec++, specp += sspec, xp += sx) {
      *xp = *specp;
      *(statp++) = 0;
    }
  }


  /* Apply the non-linear step of the algorithm chain to convert P-type */
  /* intermediate spectral variable to X-type spectral variable. */
  if (spc->spxP2X) {
    if ((statP2X = spc->spxP2X(spc->w[0], nspec, sx, sx, x, x, stat))) {
      if (statP2X == SPCERR_BAD_SPEC) {
        status = SPCERR_BAD_SPEC;
      } else if (statP2X == SPXERR_BAD_SPEC_PARAMS) {
        return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS),
          "Invalid spectral parameters: Frequency or wavelength is 0");
      } else {
        return wcserr_set(SPC_ERRMSG(spc_spxerr[statP2X]));
      }
    }
  }

  if (spc->isGrism) {
    /* Convert X-type spectral variable (wavelength) to grism parameter. */
    xp = x;
    statp = stat;
    for (ispec = 0; ispec < nspec; ispec++, xp += sx, statp++) {
      if (*statp) continue;

      s = *xp/spc->w[5] - spc->w[4];
      if (fabs(s) <= 1.0) {
        beta = asind(s);
        *xp = tand(beta - spc->w[3]);
      } else {
        *statp = 1;
      }
    }
  }


  /* Convert X-type spectral variable to intermediate world coordinate x. */
  xp = x;
  statp = stat;
  for (ispec = 0; ispec < nspec; ispec++, xp += sx) {
    if (*(statp++)) continue;

    *xp -= spc->w[1];
    *xp /= spc->w[2];
  }

  if (status) {
    wcserr_set(SPC_ERRMSG(status));
  }
  return status;
}
Пример #7
0
int spcset(struct spcprm *spc)

{
  static const char *function = "spcset";

  char   ctype[9], ptype, xtype;
  int    restreq, status;
  double alpha, beta_r, crvalX, dn_r, dXdS, epsilon, G, m, lambda_r, n_r,
         t, restfrq, restwav, theta;
  struct wcserr **err;

  if (spc == 0x0) return SPCERR_NULL_POINTER;
  err = &(spc->err);

  if (undefined(spc->crval)) {
    return wcserr_set(WCSERR_SET(SPCERR_BAD_SPEC_PARAMS),
      "Spectral crval is undefined");
  }

  memset((spc->type)+4, 0, 4);
  spc->code[3] = '\0';
  wcsutil_blank_fill(4, spc->type);
  wcsutil_blank_fill(3, spc->code);
  spc->w[0] = 0.0;


  /* Analyse the spectral axis type. */
  memset(ctype, 0, 9);
  strncpy(ctype, spc->type, 4);
  if (*(spc->code) != ' ') {
    sprintf(ctype+4, "-%s", spc->code);
  }
  restfrq = spc->restfrq;
  restwav = spc->restwav;
  if ((status = spcspxe(ctype, spc->crval, restfrq, restwav, &ptype, &xtype,
                        &restreq, &crvalX, &dXdS, &(spc->err)))) {
    return status;
  }

  /* Satisfy rest frequency/wavelength requirements. */
  if (restreq) {
    if (restreq == 3 && restfrq == 0.0 && restwav == 0.0) {
      /* VRAD-V2F, VOPT-V2W, and ZOPT-V2W require the rest frequency or */
      /* wavelength for the S-P and P-X transformations but not for S-X */
      /* so supply a phoney value. */
      restwav = 1.0;
    }

    if (restfrq == 0.0) {
      restfrq = C/restwav;
    } else {
      restwav = C/restfrq;
    }

    if (ptype == 'F') {
      spc->w[0] = restfrq;
    } else if (ptype != 'V') {
      spc->w[0] = restwav;
    } else {
      if (xtype == 'F') {
        spc->w[0] = restfrq;
      } else {
        spc->w[0] = restwav;
      }
    }
  }

  spc->w[1] = crvalX;
  spc->w[2] = dXdS;


  /* Set pointers-to-functions for the linear part of the transformation. */
  if (ptype == 'F') {
    if (strcmp(spc->type, "FREQ") == 0) {
      /* Frequency. */
      spc->flag = FREQ;
      spc->spxP2S = 0x0;
      spc->spxS2P = 0x0;

    } else if (strcmp(spc->type, "AFRQ") == 0) {
      /* Angular frequency. */
      spc->flag = AFRQ;
      spc->spxP2S = freqafrq;
      spc->spxS2P = afrqfreq;

    } else if (strcmp(spc->type, "ENER") == 0) {
      /* Photon energy. */
      spc->flag = ENER;
      spc->spxP2S = freqener;
      spc->spxS2P = enerfreq;

    } else if (strcmp(spc->type, "WAVN") == 0) {
      /* Wave number. */
      spc->flag = WAVN;
      spc->spxP2S = freqwavn;
      spc->spxS2P = wavnfreq;

    } else if (strcmp(spc->type, "VRAD") == 0) {
      /* Radio velocity. */
      spc->flag = VRAD;
      spc->spxP2S = freqvrad;
      spc->spxS2P = vradfreq;
    }

  } else if (ptype == 'W') {
    if (strcmp(spc->type, "WAVE") == 0) {
      /* Vacuum wavelengths. */
      spc->flag = WAVE;
      spc->spxP2S = 0x0;
      spc->spxS2P = 0x0;

    } else if (strcmp(spc->type, "VOPT") == 0) {
      /* Optical velocity. */
      spc->flag = VOPT;
      spc->spxP2S = wavevopt;
      spc->spxS2P = voptwave;

    } else if (strcmp(spc->type, "ZOPT") == 0) {
      /* Redshift. */
      spc->flag = ZOPT;
      spc->spxP2S = wavezopt;
      spc->spxS2P = zoptwave;
    }

  } else if (ptype == 'A') {
    if (strcmp(spc->type, "AWAV") == 0) {
      /* Air wavelengths. */
      spc->flag = AWAV;
      spc->spxP2S = 0x0;
      spc->spxS2P = 0x0;
    }

  } else if (ptype == 'V') {
    if (strcmp(spc->type, "VELO") == 0) {
      /* Relativistic velocity. */
      spc->flag = VELO;
      spc->spxP2S = 0x0;
      spc->spxS2P = 0x0;

    } else if (strcmp(spc->type, "BETA") == 0) {
      /* Velocity ratio (v/c). */
      spc->flag = BETA;
      spc->spxP2S = velobeta;
      spc->spxS2P = betavelo;
    }
  }


  /* Set pointers-to-functions for the non-linear part of the spectral */
  /* transformation.                                                   */
  spc->isGrism = 0;
  if (xtype == 'F') {
    /* Axis is linear in frequency. */
    if (ptype == 'F') {
      spc->spxX2P = 0x0;
      spc->spxP2X = 0x0;

    } else if (ptype == 'W') {
      spc->spxX2P = freqwave;
      spc->spxP2X = wavefreq;

    } else if (ptype == 'A') {
      spc->spxX2P = freqawav;
      spc->spxP2X = awavfreq;

    } else if (ptype == 'V') {
      spc->spxX2P = freqvelo;
      spc->spxP2X = velofreq;
    }

    spc->flag += F2S;

  } else if (xtype == 'W' || xtype == 'w') {
    /* Axis is linear in vacuum wavelengths. */
    if (ptype == 'F') {
      spc->spxX2P = wavefreq;
      spc->spxP2X = freqwave;

    } else if (ptype == 'W') {
      spc->spxX2P = 0x0;
      spc->spxP2X = 0x0;

    } else if (ptype == 'A') {
      spc->spxX2P = waveawav;
      spc->spxP2X = awavwave;

    } else if (ptype == 'V') {
      spc->spxX2P = wavevelo;
      spc->spxP2X = velowave;
    }

    if (xtype == 'W') {
      spc->flag += W2S;
    } else {
      /* Grism in vacuum. */
      spc->isGrism = 1;
      spc->flag += GRI;
    }

  } else if (xtype == 'A' || xtype == 'a') {
    /* Axis is linear in air wavelengths. */
    if (ptype == 'F') {
      spc->spxX2P = awavfreq;
      spc->spxP2X = freqawav;

    } else if (ptype == 'W') {
      spc->spxX2P = awavwave;
      spc->spxP2X = waveawav;

    } else if (ptype == 'A') {
      spc->spxX2P = 0x0;
      spc->spxP2X = 0x0;

    } else if (ptype == 'V') {
      spc->spxX2P = awavvelo;
      spc->spxP2X = veloawav;
    }

    if (xtype == 'A') {
      spc->flag += A2S;
    } else {
      /* Grism in air. */
      spc->isGrism = 2;
      spc->flag += GRA;
    }

  } else if (xtype == 'V') {
    /* Axis is linear in relativistic velocity. */
    if (ptype == 'F') {
      spc->spxX2P = velofreq;
      spc->spxP2X = freqvelo;

    } else if (ptype == 'W') {
      spc->spxX2P = velowave;
      spc->spxP2X = wavevelo;

    } else if (ptype == 'A') {
      spc->spxX2P = veloawav;
      spc->spxP2X = awavvelo;

    } else if (ptype == 'V') {
      spc->spxX2P = 0x0;
      spc->spxP2X = 0x0;
    }

    spc->flag += V2S;
  }


  /* Check for grism axes. */
  if (spc->isGrism) {
    /* Axis is linear in "grism parameter"; work in wavelength. */
    lambda_r = crvalX;

    /* Set defaults. */
    if (undefined(spc->pv[0])) spc->pv[0] = 0.0;
    if (undefined(spc->pv[1])) spc->pv[1] = 0.0;
    if (undefined(spc->pv[2])) spc->pv[2] = 0.0;
    if (undefined(spc->pv[3])) spc->pv[3] = 1.0;
    if (undefined(spc->pv[4])) spc->pv[4] = 0.0;
    if (undefined(spc->pv[5])) spc->pv[5] = 0.0;
    if (undefined(spc->pv[6])) spc->pv[6] = 0.0;

    /* Compute intermediaries. */
    G       = spc->pv[0];
    m       = spc->pv[1];
    alpha   = spc->pv[2];
    n_r     = spc->pv[3];
    dn_r    = spc->pv[4];
    epsilon = spc->pv[5];
    theta   = spc->pv[6];

    t = G*m/cosd(epsilon);
    beta_r = asind(t*lambda_r - n_r*sind(alpha));

    t -= dn_r*sind(alpha);

    spc->w[1] = -tand(theta);
    spc->w[2] *= t / (cosd(beta_r)*cosd(theta)*cosd(theta));
    spc->w[3] = beta_r + theta;
    spc->w[4] = (n_r - dn_r*lambda_r)*sind(alpha);
    spc->w[5] = 1.0 / t;
  }

  return 0;
}
Пример #8
0
int sphx2s(
  const double eul[5],
  int nphi,
  int ntheta,
  int spt,
  int sll,
  const double phi[],
  const double theta[],
  double lng[],
  double lat[])

{
  int mphi, mtheta, rowlen, rowoff;
  double cosphi, costhe, costhe3, costhe4, dlng, dphi, sinphi, sinthe,
         sinthe3, sinthe4, x, y, z;
  register int iphi, itheta;
  register const double *phip, *thetap;
  register double *latp, *lngp;

  if (ntheta > 0) {
    mphi   = nphi;
    mtheta = ntheta;
  } else {
    mphi   = 1;
    mtheta = 1;
    ntheta = nphi;
  }


  /* Check for a simple change in origin of longitude. */
  if (eul[4] == 0.0) {
    if (eul[1] == 0.0) {
      dlng = fmod(eul[0] + 180.0 - eul[2], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (itheta = 0; itheta < ntheta; itheta++) {
        for (iphi = 0; iphi < mphi; iphi++) {
          *lngp = *phip + dlng;
          *latp = *thetap;

          /* Normalize the celestial longitude. */
          if (eul[0] >= 0.0) {
            if (*lngp < 0.0) *lngp += 360.0;
          } else {
            if (*lngp > 0.0) *lngp -= 360.0;
          }

          if (*lngp > 360.0) {
            *lngp -= 360.0;
          } else if (*lngp < -360.0) {
            *lngp += 360.0;
          }

          lngp   += sll;
          latp   += sll;
          phip   += spt;
          thetap += spt;
        }
      }

    } else {
      dlng = fmod(eul[0] + eul[2], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (itheta = 0; itheta < ntheta; itheta++) {
        for (iphi = 0; iphi < mphi; iphi++) {
          *lngp = dlng - *phip;
          *latp = -(*thetap);

          /* Normalize the celestial longitude. */
          if (eul[0] >= 0.0) {
            if (*lngp < 0.0) *lngp += 360.0;
          } else {
            if (*lngp > 0.0) *lngp -= 360.0;
          }

          if (*lngp > 360.0) {
            *lngp -= 360.0;
          } else if (*lngp < -360.0) {
            *lngp += 360.0;
          }

          lngp   += sll;
          latp   += sll;
          phip   += spt;
          thetap += spt;
        }
      }
    }

    return 0;
  }


  /* Do phi dependency. */
  phip = phi;
  rowoff = 0;
  rowlen = nphi*sll;
  for (iphi = 0; iphi < nphi; iphi++, rowoff += sll, phip += spt) {
    dphi = *phip - eul[2];

    lngp = lng + rowoff;
    for (itheta = 0; itheta < mtheta; itheta++) {
      *lngp = dphi;
      lngp += rowlen;
    }
  }


  /* Do theta dependency. */
  thetap = theta;
  lngp = lng;
  latp = lat;
  for (itheta = 0; itheta < ntheta; itheta++, thetap += spt) {
    sincosd(*thetap, &sinthe, &costhe);
    costhe3 = costhe*eul[3];
    costhe4 = costhe*eul[4];
    sinthe3 = sinthe*eul[3];
    sinthe4 = sinthe*eul[4];

    for (iphi = 0; iphi < mphi; iphi++, lngp += sll, latp += sll) {
      dphi = *lngp;
      sincosd(dphi, &sinphi, &cosphi);

      /* Compute the celestial longitude. */
      x = sinthe4 - costhe3*cosphi;
      if (fabs(x) < tol) {
        /* Rearrange formula to reduce roundoff errors. */
        x = -cosd(*thetap + eul[1]) + costhe3*(1.0 - cosphi);
      }

      y = -costhe*sinphi;
      if (x != 0.0 || y != 0.0) {
        dlng = atan2d(y, x);
      } else {
        /* Change of origin of longitude. */
        if (eul[1] < 90.0) {
          dlng =  dphi + 180.0;
        } else {
          dlng = -dphi;
        }
      }
      *lngp = eul[0] + dlng;

      /* Normalize the celestial longitude. */
      if (eul[0] >= 0.0) {
        if (*lngp < 0.0) *lngp += 360.0;
      } else {
        if (*lngp > 0.0) *lngp -= 360.0;
      }

      if (*lngp > 360.0) {
        *lngp -= 360.0;
      } else if (*lngp < -360.0) {
        *lngp += 360.0;
      }

      /* Compute the celestial latitude. */
      if (fmod(dphi,180.0) == 0.0) {
        *latp = *thetap + cosphi*eul[1];
        if (*latp >  90.0) *latp =  180.0 - *latp;
        if (*latp < -90.0) *latp = -180.0 - *latp;
      } else {
        z = sinthe3 + costhe4*cosphi;
        if (fabs(z) > 0.99) {
          /* Use an alternative formula for greater accuracy. */
          *latp = copysign(acosd(sqrt(x*x+y*y)), z);
        } else {
          *latp = asind(z);
        }
      }
    }
  }

  return 0;
}
Пример #9
0
int sphs2x(
  const double eul[5],
  int nlng,
  int nlat,
  int sll,
  int spt,
  const double lng[],
  const double lat[],
  double phi[],
  double theta[])

{
  int mlat, mlng, rowlen, rowoff;
  double coslat, coslat3, coslat4, coslng, dlng, dphi, sinlat, sinlat3,
         sinlat4, sinlng, x, y, z;
  register int ilat, ilng;
  register const double *latp, *lngp;
  register double *phip, *thetap;

  if (nlat > 0) {
    mlng = nlng;
    mlat = nlat;
  } else {
    mlng = 1;
    mlat = 1;
    nlat = nlng;
  }


  /* Check for a simple change in origin of longitude. */
  if (eul[4] == 0.0) {
    if (eul[1] == 0.0) {
      dphi = fmod(eul[2] - 180.0 - eul[0], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (ilat = 0; ilat < nlat; ilat++) {
        for (ilng = 0; ilng < mlng; ilng++) {
          *phip = fmod(*lngp + dphi, 360.0);
          *thetap = *latp;

          /* Normalize the native longitude. */
          if (*phip > 180.0) {
            *phip -= 360.0;
          } else if (*phip < -180.0) {
            *phip += 360.0;
          }

          phip   += spt;
          thetap += spt;
          lngp   += sll;
          latp   += sll;
        }
      }

    } else {
      dphi = fmod(eul[2] + eul[0], 360.0);

      lngp = lng;
      latp = lat;
      phip   = phi;
      thetap = theta;
      for (ilat = 0; ilat < nlat; ilat++) {
        for (ilng = 0; ilng < mlng; ilng++) {
          *phip = fmod(dphi - *lngp, 360.0);
          *thetap = -(*latp);

          /* Normalize the native longitude. */
          if (*phip > 180.0) {
            *phip -= 360.0;
          } else if (*phip < -180.0) {
            *phip += 360.0;
          }

          phip   += spt;
          thetap += spt;
          lngp   += sll;
          latp   += sll;
        }
      }
    }

    return 0;
  }


  /* Do lng dependency. */
  lngp = lng;
  rowoff = 0;
  rowlen = nlng*spt;
  for (ilng = 0; ilng < nlng; ilng++, rowoff += spt, lngp += sll) {
    dlng = *lngp - eul[0];

    phip = phi + rowoff;
    thetap = theta;
    for (ilat = 0; ilat < mlat; ilat++) {
      *phip = dlng;
      phip += rowlen;
    }
  }


  /* Do lat dependency. */
  latp = lat;
  phip   = phi;
  thetap = theta;
  for (ilat = 0; ilat < nlat; ilat++, latp += sll) {
    sincosd(*latp, &sinlat, &coslat);
    coslat3 = coslat*eul[3];
    coslat4 = coslat*eul[4];
    sinlat3 = sinlat*eul[3];
    sinlat4 = sinlat*eul[4];

    for (ilng = 0; ilng < mlng; ilng++, phip += spt, thetap += spt) {
      dlng = *phip;
      sincosd(dlng, &sinlng, &coslng);

      /* Compute the native longitude. */
      x = sinlat4 - coslat3*coslng;
      if (fabs(x) < tol) {
        /* Rearrange formula to reduce roundoff errors. */
        x = -cosd(*latp+eul[1]) + coslat3*(1.0 - coslng);
      }

      y = -coslat*sinlng;
      if (x != 0.0 || y != 0.0) {
        dphi = atan2d(y, x);
      } else {
        /* Change of origin of longitude. */
        if (eul[1] < 90.0) {
          dphi =  dlng - 180.0;
        } else {
          dphi = -dlng;
        }
      }
      *phip = fmod(eul[2] + dphi, 360.0);

      /* Normalize the native longitude. */
      if (*phip > 180.0) {
        *phip -= 360.0;
      } else if (*phip < -180.0) {
        *phip += 360.0;
      }

      /* Compute the native latitude. */
      if (fmod(dlng,180.0) == 0.0) {
        *thetap = *latp + coslng*eul[1];
        if (*thetap >  90.0) *thetap =  180.0 - *thetap;
        if (*thetap < -90.0) *thetap = -180.0 - *thetap;
      } else {
        z = sinlat3 + coslat4*coslng;
        if (fabs(z) > 0.99) {
          /* Use an alternative formula for greater accuracy. */
          *thetap = copysign(acosd(sqrt(x*x+y*y)), z);
        } else {
          *thetap = asind(z);
        }
      }
    }
  }

  return 0;
}
Пример #10
0
int spcs2x(
   struct spcprm *spc,
   int nspec,
   int sspec,
   int sx,
   const double spec[],
   double x[],
   int stat[])

{
   int statP2X, status = 0, statS2P;
   double beta, s;
   register int ispec;
   register int *statp;
   register const double *specp;
   register double *xp;


   /* Initialize. */
   if (spc == 0) return 1;
   if (spc->flag == 0) {
      if (spcset(spc)) return 2;
   }

   /* Apply the linear step of the algorithm chain to convert the S-type */
   /* spectral variable to P-type intermediate spectral variable.        */
   if (spc->spxS2P != 0) {
      if (statS2P = spc->spxS2P(spc->w[0], nspec, sspec, sx, spec, x, stat)) {
         if (statS2P == 4) {
            status = 4;
         } else {
            return statS2P;
         }
      }

   } else {
      /* Just a copy. */
      xp = x;
      specp = spec;
      statp = stat;
      for (ispec = 0; ispec < nspec; ispec++, specp += sspec, xp += sx) {
         *xp = *specp;
         *(statp++) = 0;
      }
   }


   /* Apply the non-linear step of the algorithm chain to convert P-type */
   /* intermediate spectral variable to X-type spectral variable. */
   if (spc->spxP2X != 0) {
      if (statP2X = spc->spxP2X(spc->w[0], nspec, sx, sx, x, x, stat)) {
         if (statP2X == 4) {
            status = 4;
         } else {
            return statP2X;
         }
      }
   }

   if (spc->isGrism) {
      /* Convert X-type spectral variable (wavelength) to grism parameter. */
      xp = x;
      statp = stat;
      for (ispec = 0; ispec < nspec; ispec++, xp += sx, statp++) {
         if (*statp) continue;

         s = *xp/spc->w[5] - spc->w[4];
         if (fabs(s) <= 1.0) {
            beta = asind(s);
            *xp = tand(beta - spc->w[3]);
         } else {
            *statp = 1;
         }
      }
   }


   /* Convert X-type spectral variable to intermediate world coordinate x. */
   xp = x;
   statp = stat;
   for (ispec = 0; ispec < nspec; ispec++, xp += sx) {
      if (*(statp++)) continue;

      *xp -= spc->w[1];
      *xp /= spc->w[2];
   }

   return status;
}
Пример #11
0
void astro_calculate(astro_t *ast) {
	if	(!ast->tm) {
		time_t t = time(0);
		ast->tm	= localtime(&t);
	}
/*
	if	(!ast->Lat && !ast->Lon) {
		ast->Lat	= 45.7500000000;
		ast->Lon	= 4.8333333333;
	}
*/

/*
	ast->j = ast->tm->tm_yday;
*/
	ast->JD = JD (ast->tm->tm_year+1900, ast->tm->tm_mon+1, ast->tm->tm_mday + 0.5);	// 0.5 is 12:00
	ast->j = ast->JD - 2451545.0;	// 2000.0

#if (VERSION==1)
	ast->M = 357 + 0.9856 * ast->j;
	ast->C = 1.914 * sind(ast->M) + 0.02 * sind(2*ast->M);
	ast->L = 280 + ast->C + 0.9856 * ast->j;
	ast->R = -2.465 * sind(2*ast->L) + 0.053 * sind(4*ast->L);
#endif
#if (VERSION==2)
	ast->M = 357.5291 + 0.98560028 * ast->j;
	ast->C = 1.9146 * sind(ast->M) + 0.02 * sind(2*ast->M) + 0.0003 * sind(3*ast->M);
	ast->L = 280.4665 + ast->C + 0.98564736 * ast->j;
	ast->R = -2.4680 * sind(2*ast->L) + 0.053 * sind(4*ast->L) - 0.0014 * sind(6*ast->L);
#endif

	ast->EoT = -(ast->C + ast->R) * 4;

	//	0.397777 représente le sinus de l'obliquité de l'écliptique (23.43929)
	ast->Dec = asind(0.397777 * sind(ast->L));

	//double RA = atan2d(0.9175*sind(ast->L), cosd(ast->L));

	/*
	Le Soleil se lève ou se couche quand le bord supérieur de son disque apparaît ou disparait à l'horizon.
	Du fait de la réfraction atmosphérique le centre du Soleil est alors à 50' sous l'horizon : 34' pour
	l'effet de la réfraction et 16' pour le demi-diamètre du Soleil. L'angle horaire Ho du Soleil, en degrés,
	au moment où son bord supérieur est sur l'horizon est donné par :
	*/
#define UPPER_LIMB -0.01454		// sind(50/60);
#define BUREAU_DES_LONGITUDES -0.01065	// sind(36.6/60);
#define CREPUSCULE_CIVIL -0.105
#define CREPUSCULE_NAUTIQUE -0.208
#define CREPUSCULE_ASTRONOMIQUE -0.309

	/*
	Si vous comparez aux valeurs données par le Bureau des Longitudes (IMCCE) vous constaterez qu'elles sont franchement différentes. En effet le BdL calcule les heures des lever/coucher du centre du Soleil avec une réfraction à l'horizon de 36,6'. Pour vous assurer de la justesse de vos calculs remplacez 0,01454 par 0,01065 dans l'expression de Ho.
	*/

#define Occultation UPPER_LIMB
//#define Occultation BUREAU_DES_LONGITUDES

	ast->cosHo = (Occultation - sind(ast->Dec)*sind(ast->Lat)) / (cosd(ast->Dec)*cosd(ast->Lat));

	/* Si la valeur du cosinus est supérieure à 1 il n'y a pas de lever (et pas de coucher), le Soleil est
	toujours sous l'horizon; si elle est inférieure à -1 il n'y a pas de coucher (et pas de lever), le
	Soleil est toujours au dessus de l'horizon.
	*/

	if	(ast->cosHo < -1) {
		ast->DayTime	= 1;
		return;
	}
	if	(ast->cosHo > 1) {
		ast->DayTime	= 0;
		return;
	}

	ast->Ho = acosd(ast->cosHo);

	//	Azimut
	//ast->cosAz = ( X * sind(ast->Lat) - sind(ast->Dec)) / cosd(ast->Lat);
	//ast->Az = acos(ast->cosAz);

	//	Lever
	ast->VL = 12 - ast->Ho/15;		// Heure vraie
	ast->TL = ast->VL - ast->EoT/60 - ast->Lon/15; // Heure UTC
	ast->HL = ast->TL + ast->tm->tm_gmtoff/3600; // Heure légale

	//	Coucher
	ast->VC = 12 + ast->Ho/15;	// Heure vraie;
	ast->TC = ast->VC - ast->EoT/60 - ast->Lon/15; // Heure UTC
	ast->HC = ast->TC + ast->tm->tm_gmtoff/3600; // Heure légale

	//	Epoch calculation
	struct tm tm	= *ast->tm;
	tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
	time_t hour0	= mktime(&tm);
	hour0	+= tm.tm_gmtoff;
	ast->TL_epoch	= hour0 + ast->TL*3600;
	ast->TC_epoch	= hour0 + ast->TC*3600;

	ast->h = (double)ast->tm->tm_hour + (double)ast->tm->tm_min/60.0 + (double)ast->tm->tm_sec/3600.0;

	if	((ast->h > ast->HL) && (ast->h < ast->HC)) {
		ast->DayTime	= 1;
		return;
	}
	else {
		ast->DayTime	= 0;
		return;
	}
}