Example #1
0
void
compute_tropospheric_delays(pulsar *psr,int npsr)
{
  double zenith_delay_hydrostatic, zenith_delay_wet;
  double mapping_hydrostatic, mapping_wet;
  int i, p;
  observatory *obs;
  double source_elevation;
  double pressure;
  const char *CVS_verNum = "$Revision: 1.9 $";

  if (displayCVSversion == 1) CVSdisplayVersion("tropo.C","computer_tropospheric_delays()",CVS_verNum);

  // test code
#if 0
  {
    int ilat, iel;
    double lat, el, h, w;
    for (ilat=0;ilat<=11;ilat++)
    {
      lat = (ilat * 8.0)* 3.14159265358979/180.0;
      for (iel=0; iel<=100; iel++)
      {
	el = (5.0+iel*0.84) * 3.14159265358979/180.0;
	h = NMF_hydrostatic(50000.0, lat, 10000.0, el);
	w = NMF_wet(lat, el);
	printf("%.15lg %.15lg %.15lg %.15lg NMF\n",
	       el, h, w, lat);
      }
    }
    exit(1);
  }
#endif

  for (p=0;p<npsr;p++)
  {
    bool warned = false;
    for (i=0;i<psr[p].nobs;i++)
    { 
      psr[p].obsn[i].troposphericDelay = 0.0;
      if (psr[p].obsn[i].delayCorr!=0 && psr[p].correctTroposphere!=0 && psr[p].obsn[i].zenith[2]==0.0 && !warned)
      {
	logdbg( "WARNING: Tropospheric delay correction not possible with T2CMETHOD TEMPO %d %lf", i, psr[p].obsn[i].zenith[2]);
	warned = true;
      }
      else if (strcmp(psr[p].obsn[i].telID,"STL_FBAT")==0)
	{
	  logdbg("Not correcting for tropospheric delay");
	  warned=true;
	}
      else if (psr[p].obsn[i].delayCorr!=0 && psr[p].correctTroposphere!=0)
      {
	obs = getObservatory(psr[p].obsn[i].telID);
	/* Check whether the observation represents the COE */
	if (strcasecmp(obs->name,"COE")!=0)
	  {
	    // get source elevation neglecting proper motion
	    source_elevation = asin(dotproduct(psr[p].obsn[i].zenith,
					       psr[p].posPulsar)
				    / obs->height_grs80);
	    // get surface atmospheric pressure
	    pressure = 
	      getSurfaceAtmosphericPressure(obs->code, psr[p].obsn[i].sat, 
					    psr[p].noWarnings);
	    
	    // ------------------- Hydrostatic delay
	    // Zenith delay from Davies et al (Radio Sci 20 1593)
	    zenith_delay_hydrostatic = 0.02268 * pressure 
	      / (SPEED_LIGHT * (1.0-0.00266*cos(obs->latitude_grs80)
				-2.8e-7*obs->height_grs80));
	    // mapping function
	    mapping_hydrostatic = 
	      NMF_hydrostatic(psr[p].obsn[i].sat
			      + getCorrection(psr[p].obsn+i, 
					      psr[p].clockFromOverride,
					      "UTC", psr[p].noWarnings)/SECDAY,
			      obs->latitude_grs80, obs->height_grs80,
			      source_elevation);
	    // ------------------ Wet delay
	    zenith_delay_wet = 
	      getZenithWetDelay(obs->code, psr[p].obsn[i].sat, 
				psr[p].noWarnings);
	    mapping_wet = NMF_wet(obs->latitude_grs80, source_elevation);
	    
	    psr[p].obsn[i].troposphericDelay = 
	      zenith_delay_hydrostatic * mapping_hydrostatic
	      + zenith_delay_wet * mapping_wet;
	  }
	else
	  psr[p].obsn[i].troposphericDelay = 0.0;
      }
    }
  }
}
Example #2
0
    double
getCorrection(observation *obs, const char *clockFrom_c, const char *clockTo, int warnings)
{
    observatory *site;
    DynamicArray *sequence;
    size_t ifunc;
    ClockCorrectionFunction *func;
    double correction = 0.0;
    const char *CVS_verNum = "$Id: 2ecd61c300367fd1dc527ff60a21468091473d85 $";
    char clockFrom[128];
    char currClock[128];
    strcpy(clockFrom,clockFrom_c);

    if (clockFrom[0]=='\0')
        site = getObservatory(obs->telID);

    if (displayCVSversion == 1) CVSdisplayVersion("clkcorr.C","getCorrection()",CVS_verNum);

    if (clockFrom[0]=='\0')
        strcpy(clockFrom,site->clock_name);
    strcpy(currClock,clockFrom);

    if (!strcasecmp(clockTo, clockFrom))
        return 0.0;

    /*   printf("Getting %s<->%s\n", site->clock_name, clockTo); */
    sequence = getClockCorrectionSequence(clockFrom, clockTo, obs->sat,
            warnings);

    if (sequence == NULL)
    {
        char msg[1000],msg2[1000];
        sprintf(msg,"Proceeding assuming UTC = ");
        sprintf(msg2,"%s",currClock);
        displayMsg(1,"CLK6",msg,msg2,warnings);

        if (!strcasecmp(clockTo, "UTC"))
            return 0.0;
        sequence = getClockCorrectionSequence("UTC", clockTo, obs->sat,
                warnings); 
        strcpy(currClock,"UTC");
        if (sequence == NULL)
        {
            if (warnings==0) 
                printf( "!Warning [CLK:9], no clock correction available for TOA @ MJD %.4lf!\n",
                        (double)obs->sat);
            return 0.0;
        }
    }

    for (ifunc=0; ifunc < sequence->nelem
            && strcasecmp(currClock, clockTo); ifunc++)
    {
        func = ((ClockCorrectionFunction **)sequence->data)[ifunc];
        bool backwards = strcasecmp(currClock, func->clockFrom);
        /* add correction using sign based on direction of correction */
        correction += 
            ClockCorrectionFunction_getCorrection(func, obs->sat+correction/SECDAY)
            * (backwards ? -1.0 : 1.0);
        strcpy(currClock,(backwards ? func->clockFrom : func->clockTo));
        /*     printf("--> %s\n", currClock); */
    }


    return correction;
}
Example #3
0
void get_obsCoord(pulsar *psr,int npsr)
{
  double ph,eeq[3];
  int i,j,k; 
  double prn[3][3];
  double pc,oblq,toblq;
  double siteCoord[3];
  double erad,hlt,alng,hrd,tsid,sdd,speed,sitera;
  int p;
  observatory *obs;
  const char *CVS_verNum = "$Revision: 1.8 $";

  if (displayCVSversion == 1) CVSdisplayVersion("get_obsCoord.C","get_obsCoord()",CVS_verNum);

  for (p=0;p<npsr;p++)
    {
       for (i=0;i<psr[p].nobs;i++)
	{ 
	  if (psr[p].obsn[i].delayCorr!=0)
	    {	     
	      if (strcmp(psr[p].obsn[i].telID,"STL")==0 ||
		  strcmp(psr[p].obsn[i].telID,"STL_FBAT")==0) // Satellite
		{
		  psr[p].obsn[i].siteVel[0] = 0.0;
		  psr[p].obsn[i].siteVel[1] = 0.0;
		  psr[p].obsn[i].siteVel[2] = 0.0;		  

		  // Set from the TELX, TELY, TELZ parameters
		  if (psr[p].param[param_telx].paramSet[0] == 1)
		    {
		      longdouble arg,deltaT,t0,pos;

		      if (psr[p].param[param_telEpoch].paramSet[0]==1)
			t0 = psr[p].param[param_telEpoch].val[0];
		      else
			t0 = 0.0L;

		      deltaT = (psr[p].obsn[i].sat - t0)*SECDAY;		
		      arg = deltaT;
		      pos = psr[p].param[param_telx].val[0];
		      if (psr[p].param[param_telx].paramSet[1] == 1) {
			pos += psr[p].param[param_telx].val[1]*arg;
			if (psr[p].param[param_telEpoch].paramSet[0]==0)
			  {
			    printf("ERROR: Using telescope velocity without setting telEpoch\n");
			    exit(1);
			  }
		      }
		      arg *= deltaT; if (psr[p].param[param_telx].paramSet[2] == 1) pos += (0.5*psr[p].param[param_telx].val[2]*arg);
		      arg *= deltaT; if (psr[p].param[param_telx].paramSet[3] == 1) pos += (1.0L/6.0L*psr[p].param[param_telx].val[3]*arg);
		      psr[p].obsn[i].observatory_earth[0] = (double)pos;
		      printf("Setting x to %g\n",(double)psr[p].obsn[i].observatory_earth[0]);
		    }
		  if (psr[p].param[param_tely].paramSet[0] == 1)
		    {
		      longdouble arg,deltaT,t0,pos;

		      if (psr[p].param[param_telEpoch].paramSet[0]==1)
			t0 = psr[p].param[param_telEpoch].val[0];
		      else
			t0 = 0.0L;

		      deltaT = (psr[p].obsn[i].sat - t0)*SECDAY;		
		      arg = deltaT;
		      pos = psr[p].param[param_tely].val[0];
		      if (psr[p].param[param_tely].paramSet[1] == 1) pos += psr[p].param[param_tely].val[1]*arg;
		      arg *= deltaT; if (psr[p].param[param_tely].paramSet[2] == 1) pos += (0.5*psr[p].param[param_tely].val[2]*arg);
		      arg *= deltaT; if (psr[p].param[param_tely].paramSet[3] == 1) pos += (1.0L/6.0L*psr[p].param[param_tely].val[3]*arg);
		      psr[p].obsn[i].observatory_earth[1] = (double)pos;
		      printf("Setting y to %g\n",(double)psr[p].obsn[i].observatory_earth[1]);
		    }
		  if (psr[p].param[param_telz].paramSet[0] == 1)
		    {
		      longdouble arg,deltaT,t0,pos;

		      if (psr[p].param[param_telEpoch].paramSet[0]==1)
			t0 = psr[p].param[param_telEpoch].val[0];
		      else
			t0 = 0.0L;

		      deltaT = (psr[p].obsn[i].sat - t0)*SECDAY;		
		      arg = deltaT;
		      pos = psr[p].param[param_telz].val[0];
		      if (psr[p].param[param_telz].paramSet[1] == 1) pos += psr[p].param[param_telz].val[1]*arg;
		      arg *= deltaT; if (psr[p].param[param_telz].paramSet[2] == 1) pos += (0.5*psr[p].param[param_telz].val[2]*arg);
		      arg *= deltaT; if (psr[p].param[param_telz].paramSet[3] == 1) pos += (1.0L/6.0L*psr[p].param[param_telz].val[3]*arg);
		      psr[p].obsn[i].observatory_earth[2] = (double)pos;
		      printf("Setting z to %g\n",(double)psr[p].obsn[i].observatory_earth[2]);
		    }



		  //		  printf("Setting observatory coordinates for TOA %d\n",i);
		  // Now check flags to obtain the telescope coordinates for this time
		  for (k=0;k<psr[p].obsn[i].nFlags;k++)
		    {
		      //
		      // NOTE: For a STL_FBAT setting OBSERVATORY->BAT not OBSERVATORY->EARTH
		      // The terminology is misleading
		      //
		      if (strcmp(psr[p].obsn[i].flagID[k],"-telx")==0){
			sscanf(psr[p].obsn[i].flagVal[k],"%lf",&psr[p].obsn[i].observatory_earth[0]);
			if (strcmp(psr[p].obsn[i].telID,"STL")==0) psr[p].obsn[i].observatory_earth[0]/=SPEED_LIGHT;
		      }
		      if (strcmp(psr[p].obsn[i].flagID[k],"-tely")==0){
			sscanf(psr[p].obsn[i].flagVal[k],"%lf",&psr[p].obsn[i].observatory_earth[1]);
			if (strcmp(psr[p].obsn[i].telID,"STL")==0) psr[p].obsn[i].observatory_earth[1]/=SPEED_LIGHT;
		      }
		      if (strcmp(psr[p].obsn[i].flagID[k],"-telz")==0){
			sscanf(psr[p].obsn[i].flagVal[k],"%lf",&psr[p].obsn[i].observatory_earth[2]);		      
			if (strcmp(psr[p].obsn[i].telID,"STL")==0) psr[p].obsn[i].observatory_earth[2]/=SPEED_LIGHT;
		      }
			
		    }
		}
	      else if (strcmp(psr[p].obsn[i].telID,"STL_BAT")==0) // Satellite in barycentric coordinates
		{
		  psr[p].obsn[i].siteVel[0] = 0.0;
		  psr[p].obsn[i].siteVel[1] = 0.0;
		  psr[p].obsn[i].siteVel[2] = 0.0;
		  psr[p].obsn[i].observatory_earth[0] = 0.0;
		  psr[p].obsn[i].observatory_earth[1] = 0.0;
		  psr[p].obsn[i].observatory_earth[2] = 0.0;
		  psr[p].correctTroposphere = 0;
		}
	      else
		{
		  obs = getObservatory(psr[p].obsn[i].telID);
		  // Check for override:
		  if (strcmp(psr[p].obsn[i].telID,"IMAG")==0)
		    {
		      //
		      // Must check what is happening to other parameters - such as velocities
		      //
		      for (k=0;k<psr[p].obsn[i].nFlags;k++)
			{
			  if (strcmp(psr[p].obsn[i].flagID[k],"-telx")==0){
			    sscanf(psr[p].obsn[i].flagVal[k],"%lf",&obs->x);
			  }
			  if (strcmp(psr[p].obsn[i].flagID[k],"-tely")==0){
			    sscanf(psr[p].obsn[i].flagVal[k],"%lf",&obs->y);
			  }
			  if (strcmp(psr[p].obsn[i].flagID[k],"-telz")==0){
			    sscanf(psr[p].obsn[i].flagVal[k],"%lf",&obs->z);		      
			  }
			}		
		    }
		  // New way
		  if (psr[p].t2cMethod == T2C_IAU2000B)
		    {
		      double trs[3], zenith_trs[3];
		      trs[0]=obs->x;
		      trs[1]=obs->y;
		      trs[2]=obs->z;
		      zenith_trs[0]= obs->height_grs80 
			* cos(obs->longitude_grs80) * cos(obs->latitude_grs80);
		      zenith_trs[1]= obs->height_grs80 
			* sin(obs->longitude_grs80) * cos(obs->latitude_grs80);
		      zenith_trs[2] = obs->height_grs80*sin(obs->latitude_grs80);
		      long double utc = psr[p].obsn[i].sat;
		      if (psr[p].obsn[i].clockCorr!=0 && psr[p].obsn[i].clockCorr!=2)
			utc += getCorrection(psr[p].obsn+i, 
					     psr[p].clockFromOverride,
					     "UTC", psr[p].noWarnings)/SECDAY;
		      get_obsCoord_IAU2000B(trs, zenith_trs,
					    psr[p].obsn[i].sat
					    +getCorrectionTT(psr[p].obsn+i)/SECDAY,
					    utc,
					    psr[p].obsn[i].observatory_earth,
					    psr[p].obsn[i].zenith,
					    psr[p].obsn[i].siteVel);
		    }
		  else {
		    psr[p].obsn[i].zenith[0]=psr[p].obsn[i].zenith[1]=psr[p].obsn[i].zenith[2]=0.0; // Only calc'd by IAU code
		    //	      if (	psr[p].obsn[i].zenith[2]==0.0)
		    erad = sqrt(obs->x*obs->x+obs->y*obs->y+obs->z*obs->z);//height(m)
		    hlt  = asin(obs->z/erad); // latitude
		    alng = atan2(-obs->y,obs->x); // longitude
		    hrd  = erad/(2.99792458e8*499.004786); // height (AU)
		    siteCoord[0] = hrd * cos(hlt) * 499.004786; // dist from axis (lt-sec)
		    siteCoord[1] = siteCoord[0]*tan(hlt); // z (lt-sec)
		    siteCoord[2] = alng; // longitude
		    
		    /* PC,PS equatorial and meridional components of nutations of longitude */      
		    toblq = (psr[p].obsn[i].sat+2400000.5-2451545.0)/36525.0;
		    oblq = (((1.813e-3*toblq-5.9e-4)*toblq-4.6815e1)*toblq +84381.448)/3600.0;
		    
		    pc = cos(oblq*M_PI/180.0+psr[p].obsn[i].nutations[1])*psr[p].obsn[i].nutations[0];
		    
		    /* TSID = sidereal time (lmst, timcalc -> obsite) */
		    
		    lmst(psr[p].obsn[i].sat+psr[p].obsn[i].correctionUT1/SECDAY
			 ,0.0,&tsid,&sdd);
		    tsid*=2.0*M_PI;
		    
		    /* Compute the local, true sidereal time */
		    ph = tsid+pc-siteCoord[2];  
		    /* Get X-Y-Z coordinates taking out earth rotation */
		    eeq[0] = siteCoord[0]*cos(ph); 
		    eeq[1] = siteCoord[0]*sin(ph);
		    eeq[2] = siteCoord[1];
		    
		    /* Now obtain PRN -- the precession matrix */
		    get_precessionMatrix(prn,(double)psr[p].obsn[i].sat
					 +psr[p].obsn[i].correctionUT1/SECDAY
					 ,psr[p].obsn[i].nutations[0],
					 psr[p].obsn[i].nutations[1]);
		    /* Calculate the position after precession/nutation*/
		    for (j=0;j<3;j++)
		      psr[p].obsn[i].observatory_earth[j]=prn[j][0]*eeq[0]+prn[j][1]*eeq[1]+prn[j][2]*eeq[2]; 
		    /* Rotate vector if we are working in ecliptic coordinates */
		    if (psr[p].eclCoord==1) equ2ecl(psr[p].obsn[i].observatory_earth);
		    
		    /* Calculate observatory velocity w.r.t. geocentre (1950.0)!!!! <<<<<<< */
		    speed = 2.0*M_PI*siteCoord[0]/(86400.0/1.00273);
		    sitera = 0.0;
		    if (speed>1.0e-10) sitera = atan2(psr[p].obsn[i].observatory_earth[1],
						      psr[p].obsn[i].observatory_earth[0]);
		    psr[p].obsn[i].siteVel[0] = -sin(sitera)*speed;
		    psr[p].obsn[i].siteVel[1] =  cos(sitera)*speed;
		    psr[p].obsn[i].siteVel[2] =  0.0;
		    if (psr[p].eclCoord==1) equ2ecl(psr[p].obsn[i].siteVel);
		    
		    /* Technically if using TDB these coordinates should be 
		       transformed to that frame. In practise it doesn't matter,
		       we're only talking about 0.3 ns, or 2.5e-14 in v/c */
		    
		    /* hack to transform for faked values of "K" */
		    //  	      vectorscale(psr[p].obsn[i].observatory_earth, 1.15505);
		    //  	      vectorscale(psr[p].obsn[i].siteVel, 1.15505);
		  }
		}
	    }
	  else if (i==0)
	    printf("Delay correction turned off for psr %d\n", p);
	}
    }
}
Example #4
0
    void 
getClockCorrections(observation *obs, const char *clockFrom_const, 
        const char *clockTo,int warnings)
{
    DynamicArray *sequence;
    size_t ifunc;
    char *currClock;
    ClockCorrectionFunction *func;
    double correction = 0.0;
    obs->nclock_correction = 0;
    char clockFrom[128];
    strcpy(clockFrom,clockFrom_const);

    char clockFromOrig[128]; 
    //  logdbg("In getClockCorrections");

    //logdbg("Getting clockFrom >%s<",obs->telID);
    if (clockFrom[0]=='\0') // get from observatory instead
        strcpy(clockFrom,getObservatory(obs->telID)->clock_name);
    //  logdbg("Got clockFrom");
    strcpy(clockFromOrig,clockFrom);

    if (!strcasecmp(clockTo, clockFrom))
    {
        obs->nclock_correction = 0;
        return;
    }
    //  logdbg("In getClockCorrections calling sequence 1");
    // Memory leak here
    sequence = getClockCorrectionSequence(clockFrom, clockTo, obs->sat,warnings);

    if (sequence == NULL)
    {
        char msg[1000],msg2[1000];
        sprintf(msg,"Trying assuming UTC =");
        sprintf(msg2,"%s",clockFrom);
        displayMsg(1,"CLK4",msg,msg2,warnings);
        strcpy(clockFrom,"UTC");
        if (!strcasecmp(clockTo, clockFrom))
        {
            obs->nclock_correction = 0;
            return;
        }
        logdbg("In getClockCorrections calling sequence 2");
        sequence = getClockCorrectionSequence(clockFrom, clockTo, obs->sat,
                warnings); 
        if (sequence == NULL)
        {
            char msg[1000],msg2[1000];
            sprintf(msg,"Trying TT(TAI) instead of ");
            sprintf(msg2,"%s",clockTo);
            displayMsg(1,"CLK5",msg,msg2,warnings);
            strcpy(clockFrom,clockFromOrig);
            clockTo="TT(TAI)";
            if (!strcasecmp(clockTo, clockFrom))
            {
                obs->nclock_correction = 0;
                return;
            }
            logdbg("In getClockCorrections calling sequence 3");
            sequence = getClockCorrectionSequence(clockFrom, clockTo, obs->sat,
                    warnings); 
            if (sequence == NULL)
            {
                displayMsg(1,"CLK8","Trying both","",warnings);       
                strcpy(clockFrom,"UTC");
                if (!strcasecmp(clockTo, clockFrom))
                {
                    obs->nclock_correction = 0;
                    return;
                }
                logdbg("In getClockCorrections calling sequence 4");
                sequence = getClockCorrectionSequence(clockFrom, clockTo, obs->sat,
                        warnings); 

                if (sequence==NULL)
                {
                    obs->nclock_correction = 0;
                    if (warnings==0)
                        printf( "Warning [CLK:7], no clock correction available for TOA @ MJD %.4lf!\n",
                                (double)obs->sat);
                    return;
                }
            }
        }
        displayMsg(1,"CLK9","... ok, using stated approximation","",warnings);       
    }
    currClock = clockFrom;
    // Already bad
    for (ifunc=0; ifunc < sequence->nelem 
            && strcasecmp(currClock, clockTo); ifunc++)
    {
        func = ((ClockCorrectionFunction **)sequence->data)[ifunc];
        bool backwards = strcasecmp(currClock, func->clockFrom);
        if (backwards && strcasecmp(currClock, func->clockTo))
        {
            printf("Programming error! Broken clock correction chain!!\n");
            exit(1);
        }
        /* add correction using sign based on direction of correction */
        obs->correctionsTT[obs->nclock_correction].correction = 
            ClockCorrectionFunction_getCorrection(func, obs->sat+correction/SECDAY)
            * (backwards ? -1.0 : 1.0);
        correction += obs->correctionsTT[obs->nclock_correction].correction;
        strcpy(obs->correctionsTT[obs->nclock_correction].corrects_to, 
                (backwards ? func->clockFrom : func->clockTo)); 
        obs->nclock_correction++;
        currClock = (backwards ? func->clockFrom : func->clockTo);
    }
    //  logdbg("leaving getClockCorrections");
    /*   printf("Correction: %lg\n", correction); */
}
Example #5
0
/* Based on atimfake.f from original TEMPO */
void atimfake(pulsar *psr,int npsr,int tspan,int ncoeff,longdouble maxha,char *sitename,longdouble freq,
	      longdouble afmjd,longdouble *tmin,longdouble *tmidMJD,int *retTspan,int *nsets,longdouble *val)
{
  int i,k;
  longdouble rax,rajVal,mjd2;
  longdouble hlst,wait;
  longdouble x[33];
  longdouble solsid = 1.002737909; /* 1 solar day = 1.002737909 sidereal days */
                                   /* Note: slightly different in almanac p50 */
  int    ntoas=31;  
  int    nmjd;
  int    j;
  double alng;
  longdouble mjd1,val0=0.0L,bma,bpa;

  *retTspan = tspan;

  /* Get observatory coordinates - if barycenter do nothing */
  if (strcmp(sitename,"@")==0 || strcasecmp(sitename,"bat")==0) {
    alng = 0;
  }
  else {
    observatory *obs = getObservatory(sitename);
    /* See tzinit.f for if icoord = 0 : NOT IMPLEMENTED */
    alng = atan2(-obs->y, obs->x);
  }

  /* Conversion of UT into local sidereal time (WHERE DOES 0.154374 come from????) */
  /* Note: 0.154374 is the GST at MJD 0 = 3.716667309 h = 0.15486*24               */

  /* Local sidereal time */
  hlst = 24.0*fortran_mod((longdouble)(solsid*afmjd + 0.154374 - alng/(2*M_PI)),1.0);
  rajVal = psr->param[param_raj].val[0]/M_PI*12.0; /* RAJ in hours */

  /* Why +2 in the next expression ? */
  /* Convert to RAJ at CURRENT epoch */
  rax = (int)rajVal + ((int)((rajVal - ((int)rajVal))*60.0)+2)/60.0;

  /* local hour angle */
  wait = (rax - hlst)/solsid; /* solar to sidereal */

  /* Add a day if not in range */
  if (wait < -maxha) wait+= (24.0/solsid);

  mjd1 = afmjd + (wait-maxha)/24.0+tspan/(2.0*1440.0); /* Compute start time */
  nmjd = (int)mjd1;
  mjd1 = fortran_nint(48.0*(mjd1-(int)mjd1))/48.0; /* Round to nearest 1/2 hour, accurate precision not required here */
  *nsets = (int)((long double)(120.0L*maxha+tspan-1)/(long double)tspan);

  mjd2 = mjd1;
  /* MJD2 is rounded to 1.e-10 -- WHY DO THIS? */  
  /* IN TEMPO NOT BEING ROUNDED CORRECTLY (being cutoff instead) */
  {
    int ntmp1,ntmp2;
    
    ntmp1 = (int)(mjd2*1.0e8L);
    ntmp2 = (int)((mjd2*1.0e8L-ntmp1)*100.0L);
    mjd2 = ntmp2*1e-10L+ntmp1*1.0e-8L;
  }
  mjd1 = mjd2;
  /* This is the first part of the chebft numerical recipes routine 
   * for carrying out a Chebyshev fit 
   */
  {
    longdouble a,b;
    b = tspan/2.0+5.0;
    a = -b;
    bma = 0.5*(b-a);
    bpa = 0.5*(b+a);
  }

  psr->nobs = (ntoas*(*nsets))+1;
  /* First store the reference TOA */
  if (psr->param[param_tzrmjd].paramSet[0]!=1)
    {
      printf("ERROR: must set tzrmjd in the parameter file\n");
      exit(1);
    }
  psr->obsn[0].sat = psr->param[param_tzrmjd].val[0];
  psr->obsn[0].freq = psr->param[param_tzrfrq].val[0]; 
  psr->obsn[0].deleted = 0;
  psr->obsn[0].toaErr = 0;
  psr->obsn[0].efac=1.0;
  strcpy(psr->obsn[0].fname,"POLYCO_REF");
  strcpy(psr->obsn[0].telID,psr->tzrsite); 
  psr->obsn[0].nFlags = 0;

  for (k=1;k<=ntoas;k++)
    x[k-1]=cosl(M_PI*(k-0.5L)/ntoas)*bma+bpa;

  i = -1;
  for (j=0;j<*nsets;j++)
    {
      /* Part of the Chebyshev fit routine */
      mjd2 = mjd1 + (j)*tspan/1440.0L;

      for (k=0;k<ntoas;k++)
	{
	  i++;
	  if (i>800)
	    {
	      printf("ERROR: Tspan too small\n");
	      exit(1);
	    }
	  /* ************************************* */
	  val[i] = mjd2 + x[k]/1440.0L;
	  /* Do some more rounding */
	  {
	    int ntmp1,ntmp2;
	    
	    ntmp1 = (int)(val[i]*1.0e8L);
	    ntmp2 = (int)((val[i]*1.0e8L-ntmp1)*100.0L);
	    val[i] = ntmp2*1e-10L+ntmp1*1.0e-8L;
	  }	  	  
	  if (i==0) val0=val[i];
	  		  
	  psr->obsn[i+1].sat     = val[i]+nmjd; 
	  tmin[i+1]              = 1440.0*(val[i]-val0); 
	  psr->obsn[i+1].freq    = freq; 
	  psr->obsn[i+1].toaErr = 0.0;
	  psr->obsn[i+1].deleted = 0;
	  psr->obsn[i+1].efac=1.0;
	  strcpy(psr->obsn[i+1].fname,"POLYCO");
	  
	  /* HARDCODED TO PARKES ... */
	  strcpy(psr->obsn[i+1].telID,sitename);
	  psr->obsn[i+1].nFlags = 0;
	}


    }
  *tmidMJD = mjd2;
}