/************************************************************************** * 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; }
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 ) ; } }
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))); } }
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); }
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]); } }
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; }
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; }
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; }
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; }
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; }
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; } }