Visualization and Animation of Solar Relative Positions and Velocities of Hipparcos Stars Within a 50 Light Year Radius


John Morgan
Physics 3301 - Scientific Computations
University of Sydney



Stage I
Virtual Model of Positions of 100 Closest Hipparcos Stars
The first step was to collect position data for the 100 closest Hipparcos stars. That being stars with a parallax greater than 131.12 miliarcseconds or a distance from our solar system of less than 24.875 light years. The data was collected from The Hipparcos Main Catalogue via the VizieR Catalog Search Website. The data was acquired in celestial spherical coordinates. The right ascension and declination were in degrees and the parallaxes were in miliarcseconds. In order to create a virtual 3 dimensional visualization of these stars, it was necessary to convert the celestial spherical coordinates into cartesian coordinates. This was achieved using basic spherical trigonometry and assuming our sun to be at the x, y, z origin (0,0,0).
These are the calculations that were used:



Trigonometric Half-Sphere image created with Mathematica and edited with Adobe
Photoshop The x, y, z origin of the trigonometric half-sphere to the left represents our solar system.

In this figure a star's Right Ascension (RA) is represented by , its Declination (Dec) is represented by , and the stellar distance (R) is represented by .



This is a sample of the data acquired from the Hipparcos Catalog:
3 Closest Stars to our Solar System
HIP#RA (deg)Dec (deg)Parallax (mas)
71681219.91412833-60.83947139742.12
71683219.92041034-60.83514707742.12
70890217.44894751-62.68135207772.33


To view the full table of data for all 100 stars, click here.



Stellar Distance (R) Calculation
Parallax = (In milliarcseconds)
1 / = R (In milliparsecs)
R * 1000 = R (In parsecs)
R * 3.2616 = R (In light years)




Spherical Coordinate to Cartesian Coordinate Transformation Calculations
X = R Sin Cos Y = R Sin Sin Z = R Cos




The calculations were performed by the same C++ program that was used in Stage II.

This is a sample of the cartesian coordinate data after the calculations:


3 Closest Stars to our Solar System
HIP#X (ly)Y (ly)Z (ly)
716812.9437330102.4625764532.141488287
716832.9433390262.4627954682.141777945
708903.7735435072.2845491971.938128126



The cartesian coordinate data was outputted to a file in particular format that would be read by the visualization software. The software used was MDMovie, by Jerry p. Greenberg. To view the full table of formatted cartesian coordinate data for all 100 stars, click here.
Once the data was read into MDMovie a virtual 3 dimensional on screen model of the 100 closest Hipparcos stars was constructed. The radius of the Sun was extremely exaggerated so it would stand out.


~ 3-D Virtual Model ~

Note: This will only work if your browser is equipped with the virtual world plugin.






Stage II
Animation of Velocities of Hipparcos Stars Within a 50 Light Year Radius

The first step here was to acquire the position data and the proper motions of right ascension and declination for the 100 closest Hipparcos stars. This was data was also collected from The Hipparcos Main Catalogue via the VizieR Catalog Search Website. The next step was to acquire radial velocities for the same stars. This turned out to be quite a difficult task. The stellar position data and proper motions are data that were collected by the Hipparcos Satellite. Radial velocities are calculated by a much different method and, therefore, most are not included in the final Hipparcos catalog. Data collection and organization became one of the most challenging parts of this project. It was necessary to find a catalog with a large number of Radial Velocities, which also gave star ID numbers that corresponded to ones available in the Hipparcos Catalog. The ID's worth mentioning that The Main Hipparcos Catalog supplied were the Hipparcos Number (HIP) and the Henry Draper Catalog Number (HD). Most catalogs provide a HD number, but many of the catalogs that supplied radial velocities only had a scattered amount of HD numbers. It was discovered that the Hipparcos Input Catalog Number (HIC) was the same as the HIP number. The WEB Catalog of Radial Velocities was found to provide a large number of stellar radial velocities and the corresponding HIC number. The total catalog of HIC numbers and radial velocities was acquired and it contained 20795 stars.

~ RADIAL VELOCITY DATA ~

These stars did not necessarily include the 100 closest Hipparcos stars. Radial velocities, therefore, became more important than stellar distance for an attractive model to be achieved. The next step was to combine the Radial velocities with the rest of the position and proper motion data of the Hipparcos stars. In order to assure that the largest number of stars with radial velocities was acquired, all stars with a HIP less than the largest HIC in the radial velocity catalog were downloaded. The HIP number, visual magnitude, right ascension, declination, proper motion of right ascension, proper motion of declination, parallax, error in parallax, and the B-V color was acquired for each star. This yielded 128173 lines of data.

~ SAMPLE OF HIPPARCOS DATA ~

Before cleaning up the Hipparcos data, the radial velocity data needed to be cleaned and organized. The first run through just cleaned up some of the data by adding zeros where there were empty spaces. The following PERL script was used...






#!/usr/local/bin/perl

$finName = "RVdata";                  #ARRAY
open( FILEINPUT, "<$finName" );       #OPEN FILE FOR INPUT
$foutName = "RVclean";                #ARRAY 
open( FILEOUTPUT, ">$foutName" );     #OPEN FILE FOR OUTPUT

for ($i=0; $i<118300; $i++)   
        
#while ( $line = <FILEINPUT> )     #LOOP
{

 $line = <FILEINPUT>;
 
 @myList = split( /\s+/, $line );
 
 if ( @myList[0] eq "" ) 
 {
   if ( @myList[2] ne "" ) 
   {
     print FILEOUTPUT "@myList[2]  000.0\n"; 
   }
 } elsif( @myList[1] ne "" ) 
   {
     print FILEOUTPUT "@myList[1] @myList[0]\n"; 
   }
  
}#end while loop




Next the data needed to be sorted to make the matching to the Hipparcos data more efficient. This was done using the "sort" command like this: sort RVclean.dat RVsorted.dat -d -n.
The next problem was there are many multi-star systems. Some double and triple systems are represented by one star identification number and some have their own identification numbers. The first error in this model, which will is discussed in the model accuracy section, was the individual stellar radial velocities of the multi-star systems was ignored. The radial velocity data contained a good number of duplicate or triplicate HIC numbers. These represented the multi-star systems that had only one HIC number but had separate radial velocities. In order to ignore the velocities of the stars relative to each other, an average radial velocity was found for each multi star system. Each multi star system was then replaced by one HIC entry with the averaged radial velocity. This was achieved with the following C++ program...




#include <iostream.h>  
#include <fstream.h>  

ofstream fout("RVfinal");  
ifstream fin("RVsorted");      

int main()
{
 double HIP, RV;
 double star[17071][2];
 
 for(int i=0; i<17071; i++)
 {
   fin>>HIP>>RV;
   star[i][0] = HIP;
   star[i][1] = RV;
   if(star[i][0] == star[i-1][0])
   {
     star[i][1]  = (star[i][1] + star[i-1][1]) / 2;
     star[i-1][1]= star[i][1];
     
   }//end if
   
  }//end while
   
fout.precision(7);   
 for(int j=0; j<17071; j++)
 {
   if(star[j][0] != star[j-1][0])

   {
     fout<<star[j][0]<<" "<<star[j][1]<<endl;
     
   }//end if
     
 }//end for   

 return 0;
 
}// end main





~ FINAL RADIAL VELOCITY DATA ~

The next step was to combine the radial velocity data with the Hipparcos data. The following PERL script was used to achieve this...




#!/usr/local/bin/perl

$finRV = "RVfinal";                  
$finHIP = "fullHIP";                 
$foutName = "finalData";               
open( RV_FILEINPUT, "<$finRV" );  
open( FILEOUTPUT, ">$foutName" );    
open( HIP_FILEINPUT, "<$finHIP" ); 

for ($i=1; $i<16770; $i++)
{
 $RV_line = <RV_FILEINPUT>;
 @RV_List = split( /\s+/, $RV_line );
 
 while( @HIP_List[0] < @RV_List[0] )
 {
 
   $HIP_line = <HIP_FILEINPUT>;
   @HIP_List = split( /\s+/, $HIP_line );
 
   chop ( $HIP_line );
 
   print FILEOUTPUT "$HIP_line ";
 
   if ( @HIP_List[0] eq @RV_List[0] )
   {
     print "$i out of 16769 found, HIP#@HIP_List[0] = @RV_List[0]\n";
     print FILEOUTPUT " @RV_List[1]\n";
 
   }else {print FILEOUTPUT "0\n";}
 
  
 }#end j for loop
  
}#end i for loop

print "DONE!\n";




Next the data was sorted using the command: sort finalData.dat sfinalData.dat -d -n. The Hipparcos data had stars with insufficient data and it had repeated occurrences of stars. The stars in the newly combined and sorted data file that had insufficient data were junked and the repeated occurrences were taken out. The following PERL script was used to do this...




#!/usr/local/bin/perl

$fin = "sfinalData1";                  
$fout = "finalData2";               
$jout = "junk";  
open( FILEINPUT, "<$fin" );  
open( GOODOUTPUT, ">$fout" );    
open( JUNKOUTPUT, ">$jout" ); 
$j=1;
$i=1;

while( $line = <FILEINPUT> )
 {
   $temp=@List[0];
   @List = split( /\s+/, $line );
   chop ( $line );
  
   if (@List[0] eq $temp )
   {
     print JUNKOUTPUT "$line\n";
     print "$i\n";
     $i++;
   }else{print GOODOUTPUT "$line\n";}
  
}#end while loop
  
print "DONE!\n";




This yielded a data file containing 116872 stars and only about 15% of those stars had a corresponding radial velocity.

~ SAMPLE OF CROSSREFERENCED DATA ~

It was found that most of the radial velocities were available for the closer stars. To achieve an attractive model, the number of stars needed to be limited. The data file was then stripped down to include only those stars with a parallax greater than 65.232 milliarcseconds (or a distance of less than 50 light years). The following PERL script used to achieve this...




#!/usr/local/bin/perl

$finName = "finalData2";                  #ARRAY
open( FILEINPUT, "<$finName" );       #OPEN FILE FOR INPUT
$foutName = "closeStars";                #ARRAY 
open( FILEOUTPUT, ">$foutName" );     #OPEN FILE FOR OUTPUT

for ($i=0; $i<116873; $i++)   
{

 $line = <FILEINPUT>;
 
 @myList = split( /\s+/, $line );
 
 if ( @myList[4] > 65.232 ) 
 {
    print FILEOUTPUT "$line"; 
 }
 
print "$i\n";   

}#end while loop





The resulting file contained 487 stars and around 60% - 70% of these stars had corresponding radial velocities. This list of stars still included possible multi-star systems, but only ones recognized by the Hipparcos catalog and therefore any multi-star system stars had their own HIP number. Now there was the case of having two or three stars from one multi-star system, but only one star would have a radial velocity.
The star velocities were imitated by incrementing the positions and creating a seperate frame for each of the new positions.


Position Incrementation Calculations
RA2 = RA1 + pmRA/N
Dec2 = Dec1 + pmDec/N
N = 3600, which is the conversion factor for milliarcseconds -> 1000 deg/yr
R2 = R1 + RV * C
C = 0.003335640952, which is the conversion factor for km/s -> 1000 ly/yr


The following is the main program. It was written in C++. It uses a class to represent a star and it's position. The class also contains the functions that transform the coordinates from spherical to cartesian. Double precision was used to insure accuracy with the small difference in angles. The program also outputted the data in the format required for input into MDMovie. The program also included the Visual Magnitude of the stars in the formatted data file, which would be used by MDMovie to determine each star's radius.

~ SAMPLE OF FORMATED DATA ~





//////////////////////////////////////////////////////////////////////////
///////////////////////////// John Morgan //////////////////////////////// 
/////////////////////// Scientific Computing Project /////////////////////
////////////////////////////// Stars.cpp /////////////////////////////////
//////////////////////////////////////////////////////////////////////////


#include <iostream.h>  // includes basic operations class
#include <fstream.h>  // includes file streaming class
#include <math.h>
#define M_PI 

//////////////////////////////////START OF  CLASS/////////////////////////////////

////////////////////////////////start class defintion/////////////////////////////////////

class starClass
{

public:
  starClass();    
  //default constructor

  starClass(double& cnstHIP, double& cnstVmag, double& cnstRA, 
                                                double& cnstDec, double& cnstDist);
  //Constructor, sets values to the private data members
  //Precondition: values are compatible with their cooresponding data types
  //Postcondition: private data members contain star data and spherical coord data

  void SphereToCart();
  //Converts star postion from spherical coordinates to cartesian coordinates
  //Precondition: first three varialbles contain spherical data
  //Postcondition: last three varialbles contain cartesian data

  void GetCartCoord(double& cnstX, double& cnstY, double& cnstZ);
  //Gets the cartesian coordinate values of the star
  //Precondition: cartesian coordinate contain data, ie 'SphereToCart' has run
  //Postcondition: cartesian coordinates are given in light years
 
  void GetSphereCoord(double& cnstDist, double& cnstRA, double& cnstDec);
  //Gets the spherical coordinate values of the star
  //Precondition: sperical coordinat data was inputed
  //Postcondition: spherical coordinates are given

  double ReturnHIP();
  //returns the star's Hiparcos number as an integer data type
  //Precondition: HIP was inputed by the constructor
  //Postcondition: HIP is returned

  double ReturnVmag();
  //returns the star's visual magnitude as a float double data type
  //Precondition: Vmag was inputed by the constructor
  //Postcondition: Vmag is returned

private:
  
  double HIP;   // star's Hiparcos catalog number
  double Vmag;  // star's visual magnitude
  double Dist;  // stars distance in light years
  double RA;    // star's right ascencion in degrees
  double Dec;   // star's declination in degrees
  
  double X;     // star's x coordinate assuming a 3D cartesian coordinate system 
                // with our sun at the origin, our equator parallel to the (x,y) 
                // plane, and with a scale in light years
  double Y;     // star's y coordinate assuming a 3D cartesian coordinate system 
                // with our sun at the origin, our equator parallel to the (x,y) 
                // plane, and with a scale in light years
  double Z;     // star's z coordinate assuming a 3D cartesian coordinate system 
                // with our sun at the origin, our equator parallel to the (x,y) 
                // plane, and with a scale in light years

}; 

////////////////////////////////// end class definition /////////////////////////////////


////////////////////////////////// start class implementation//////////////////////////

starClass::starClass()
{
  HIP = 0;
  Vmag =  Dist = RA = Dec = X = Y = Z = 0;
  
}// end default constructor StarClass()


starClass::starClass(double& cnstHIP, double& cnstVmag, double& cnstRA, 
                                        double& cnstDec, double& cnstDist)
{
  
  HIP  = 0;
  Vmag =  Dist = RA = Dec = X = Y = Z = 0;
  HIP  = cnstHIP;
  Vmag = cnstVmag;
  Dist  = cnstDist;
  RA = cnstRA;
  Dec= cnstDec;
  
}//end constructor StarClass()


void starClass::SphereToCart()
{

  X = (Dist)*( sin( (M_PI/180.0) * (90-Dec) ) ) * ( cos( (M_PI/180.0)*RA ) );
 
  Y = (Dist)*( sin( (M_PI/180.0) * (90-Dec) ) ) * ( sin( (M_PI/180.0)*RA ) );
 
  Z = (Dist)*( cos( (M_PI/180.0) * (90-Dec) ) );


}//end SphereToCart


void starClass::GetCartCoord(double& cnstX, double& cnstY, double& cnstZ)
{
  cnstX=X;
  cnstY=Y;
  cnstZ=Z;

}// end GetCoord()


void starClass::GetSphereCoord(double& cnstDist, double& cnstRA, double& cnstDec)
{
  cnstDist=Dist;
  cnstRA=RA;
  cnstDec=Dec;

}//end GetSphereCoord()



double starClass::ReturnHIP()
{
  return HIP;

}//end 


double starClass::ReturnVmag()
{
  return Vmag;
}

////////////////////////////////////end class implementation////////////////////////////////

////////////////////////////////////////END CLASS///////////////////////////////////////////




///////////////////////////////////////START MAIN PROGRAM////////////////////////////////////





ofstream foutvis("visualData");  // creates or opens a file to write to
ifstream finhip;      // opens a file to read from



int main()
{
 int numstars=0;
 int frames=0;
 double LY = 3.2616;               //convesion factor for parsecs to Light Years
 double convert = 0.003335640952;  //convertion factor for km/sec into 1000LY/year

 double HIP[490], Vmag[490], fixedVmag[490], Plx[490][1000], RA[490][1000], 
        Dec[490][1000],  pmRA[490], pmDec[490], e_Plx[490], Dist[490][1000], B_V[490], RV[490];

 double X, Y, Z;

 cout<<"# of stars(<=490)? ";
 cin>>numstars;

 foutvis<<"\n"<<320<<" "<<320<<"\n";


 finhip.open("localStars");

 for(int starIndex=0; starIndex < numstars; starIndex++)
  { 
           
    finhip>>HIP[starIndex]>>Vmag[starIndex]>>RA[starIndex][0]
          >>Dec[starIndex][0]>>Plx[starIndex][0]>>pmRA[starIndex]
          >>pmDec[starIndex]>>e_Plx[starIndex]>>B_V[starIndex]>>RV[starIndex];
  }


 finhip.close();

 for(int i=0; i< numstars; i++)
  {
    if(RV[i]!=0)

     { 
      fixedVmag[i] = (Vmag[i] + 10)/100;
      foutvis<<HIP[i]<<" 1 "<<fixedVmag[i]<<"\n";
     }

  }//end while
  
 foutvis<<"Sun 1 1\n";

 for(int j=0; j< numstars; j++)
  {
    if(RV[j]!=0)

     {
      foutvis<<HIP[j]<<"\n";
     }
  }//end while

 foutvis<<"Sun\n";
 
 cout<<"# of frames(<=1000)?";

 cin>>frames;

 for(int frameIndex=0; frameIndex < frames; frameIndex++)  
  {

    foutvis<<frameIndex+1<<"\n";
  

     for(int starIndex=0; starIndex < numstars; starIndex++)
      { 
           
          Dist[starIndex][frameIndex] = (LY/Plx[starIndex][frameIndex])*1000;

          
          if(RV[starIndex]==0)

                {
                  Dist[starIndex][frameIndex] = 0;

                } 
              
          if(frameIndex!=0)//initial case break
            {
              RA[starIndex][frameIndex] = RA[starIndex][frameIndex-1] + 
                                                        (pmRA[starIndex]/3600.0);

              if(RA[starIndex][frameIndex] < 0.0)
                 RA[starIndex][frameIndex] = RA[starIndex][frameIndex] + 360.0;
              if(RA[starIndex][frameIndex] > 360.0)
                 RA[starIndex][frameIndex] = RA[starIndex][frameIndex] - 360.0;
             
              Dec[starIndex][frameIndex] = Dec[starIndex][frameIndex-1] + 
                                                        (pmDec[starIndex]/3600.0);

              if(Dec[starIndex][frameIndex] < -90.0) 
                 Dec[starIndex][frameIndex] = Dec[starIndex][frameIndex] + 180.0;
              if(Dec[starIndex][frameIndex] >  90.0) 
                 Dec[starIndex][frameIndex] = Dec[starIndex][frameIndex] - 180.0;
                 
              Dist[starIndex][frameIndex] = Dist[starIndex][frameIndex-1] + 
                                                        (RV[starIndex] * convert);
                      
            }//end else
  
          starClass MyStarClass(HIP[starIndex], Vmag[starIndex], RA[starIndex][frameIndex], 
                                Dec[starIndex][frameIndex], Dist[starIndex][frameIndex]);
          MyStarClass.SphereToCart();
          MyStarClass.GetCartCoord(X, Y, Z);
          foutvis.precision(11);
          if((X!=0)&&(Y!=0)&&(Z!=0))

            foutvis<<X<<"   "<<Y<<"   "<<Z<<"\n";

       }//end for starIndex...
     
       finhip.close();
       starIndex=0;

       foutvis<<"0  0  0\n";
       cout<<"Frame "<<frameIndex+1<<" complete...\n";
 
  }//end for frameIndex...

         
  //cout<<"\nVisual X, Y, Z  Data File Created Succesfully!!!\n"<<endl;
  return 0;

}// end main






In the final animation model, any stars that had incomplete data, including radial velocity, were omitted. Any star lacking a radial velocity in a multi-star system, in which the stars had independant HIP numbers, was omitted. Some multi-star systems are therefore represented by only one star.
The animation model is a 100x100x100 Light Year scale model with our sun at the center. The velocities are 1000 times the actual velocity, each frame represents 1 year, and it plays at 25 frames per second. Hence, each second of the animation model represents 25,000 years. The model is oriented so that the positive z axes is perpendicular to and projecting from the screen. In other words, you are facing the the earth's Northern pole, so the plane of the solar sytem is at about a 23 degree tilt from parallel with the screen.

Click here to download the Quicktime movie!



Accuracy Of Model

1. The error in the Hipparcos parrallax data increases as the the parallax gets smaller. A graphical representation of these errors was created. At the outer edge of the still model, because of the scale used, the error is too small to be detected. In the animated model the outer edge of the model (50ly) has a somewhat significant error of about 1-5 ly.

2. The motions of the stars in the animated model are relative to our solar system. Our solar system is moving, so it should not be assumed that these are the true velocities of the stars.

3. In the animation model all and any acceleration of a star was ignored. This includes any accelerating affects a multi-star system may have on the velocities of the individual stars. Ignoring any acceleration also allows for the likely false assumption that the stars are moving in a straight line relative to the solar system. Lastly, it allows for the likely false assumption that the star's current velocity will not change in time, thus moving at a constant rate in a constant direction.


Conclusion
The model is not a perfect representation of the paths the stars will actually take, but it does demonstrate the apparent motions relative to our solar system. The most constructive aspect of this project was the acquiring, processing, and calculating of the astronomical data. That process has made this author aware of the difficulties and technicalities of using a computer to model a natural system.


Hipparcos Space Astrometry Mission
John Morgan
Physics 3301 - Scientific Computations
University of Sydney
jmor0359@vislab.usyd.edu.au
~ or ~
jmor0359@postoffice.uri.edu
~ HOME ~