deepsky.pl
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:37k
源码类别:

OpenGL

开发平台:

Visual C++

  1. #!/usr/bin/perl -w
  2. #
  3. # Author: Fridger.Schrempp@desy.de
  4. #
  5. #use Math::Libm ':all';
  6. use Math::Trig;
  7. use Math::Quaternion qw(slerp);
  8. #
  9. open(DSC, ">deepsky.dsc") || die "Can not create deepsky.dscn";
  10. #
  11. # Boiler plate
  12. #-------------
  13. #
  14. ($ver = "Revision: 1.50 ") =~ s/$//g;
  15. ($me = $0) =~ s/.*///;
  16. ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
  17. $year += 1900;
  18. $mon += 1;
  19. print DSC "# Revised NGC and IC Catalog, Wolfgang Steinicke, January 6, 2006n";
  20. print DSC "# http://www.ngcic.org/steinicke/default.htmn";
  21. print DSC "#n";
  22. print DSC "# Augmented by galaxies from Local Group volume (V <~ (10 Mpc)^3)n";
  23. print DSC "# Catalog of Neighboring Galaxies (Karachentsev+, 2004)n";
  24. print DSC "# http://cdsweb.u-strasbg.fr/viz-bin/Cat?J/AJ/127/2031n";
  25. print DSC "#n";
  26. print DSC "# Augmented by averages of distance entries fromn";
  27. print DSC "# NED-1D: NASA/IPAC Extragalactic Database of Distancesn";
  28. print DSC "# http://nedwww.ipac.caltech.edu/level5/NED1D/n";
  29. print DSC "#n";
  30. print DSC "# Augmented byn";
  31. print DSC "# NASA/IPAC Extragalactic Database (NED, batch)n";
  32. print DSC "# http://nedwww.ipac.caltech.edu/n";
  33. print DSC "#n";
  34. print DSC "# Augmented byn";
  35. print DSC "# Revised 3rd Reference Catalog of Bright Galaxies (RC3,VII/155)n";
  36. print DSC "# http://cdsweb.u-strasbg.fr/viz-bin/Cat?VII/155n";
  37. print DSC "#n";
  38. print DSC "# Augmented byn";
  39. print DSC "# Mark III Catalog of Galaxy Peculiar Velocities (Willick+ 1997,VII/198)n";
  40. print DSC "# http://cdsweb.u-strasbg.fr/viz-bin/Cat?VII/198#sRM2.18n";
  41. print DSC "#n";
  42. print DSC "# Augmented by distances fromn";
  43. print DSC "# The SBF Survey of Galaxy Distances. IV.n";
  44. print DSC "# SBF Magnitudes, Colors, and Distances, n";
  45. print DSC "# J.L. Tonry et al., Astrophys J 546, 681 (2001)n";
  46. print DSC "#n";
  47. print DSC "# Augmented by distances fromn";
  48. print DSC "# Compilation of "200 Brightest Galaxies"n";
  49. print DSC "# http://www.anzwers.org/free/universe/galax200.htmln";
  50. print DSC "#n";
  51. print DSC "# Augmented by redshifts-> distances fromn";
  52. print DSC "# VII/193 The CfA Redshift Catalogue, Version June 1995  (Huchra+ 1995)n";
  53. print DSC "# http://cdsweb.u-strasbg.fr/viz-bin/Cat?VII/193n";
  54. print DSC "#n";
  55. print DSC "# Using today's Hubble constant = 73.2 [km/sec/Mpc]n";  
  56. print DSC "# (WMAP 2007, 3 years running, legacy archive)n";
  57. print DSC "#n";
  58. print DSC "# Abreviations for various distance methods used:n";
  59. print DSC "# SBF= SBF (Surface Brightness Fluctuations), T-F= Tully-Fischern";
  60. print DSC "# V_cmb = rad. velocity in CMB frame & Hubble law n";
  61. print DSC "# cep=Cepheids, P=photometric, N(G)=planetary nebula (globular cluster) luminosity functionn";
  62. print DSC "#n";
  63. print DSC "# Adapted for Celestia with Perl script: $me $vern";
  64. print DSC "# Processed $year-$mon-$mday $wday $yday $isdst $hour:$min:$sec UTCn";
  65. print DSC "#n";
  66. print DSC "# by Dr. Fridger Schrempp, fridger.schrempp@desy.den";
  67. print DSC "# ------------------------------------------------------ n";
  68. print DSC "nn";
  69. #
  70. # Constants
  71. #----------
  72. #
  73. $H0 = 73.2;       # today's Hubble constant [km/sec/Mpc], WMAP 2007, 3 years
  74. $c = 299792.458;  # Celestia's speed of light [km/sec]
  75. $Omega_matter = 0.27;    # flat Universe
  76. $Omega_lambda = 0.73;
  77. $pc2ly = 3.26167; # parsec-to-lightyear conversion
  78. $epsilon = 23.4392911; # ecliptic angle
  79. # from peak of SBF-survey distribution <=== Maple
  80. $M_abs_ell = -20.133; # absolute (Blue) magnitude for elliptical galaxies
  81. $M_abs_spir = -19.07; # absolute (Blue) magnitude for spiral galaxies
  82. # output of LG member galaxy parameters, set $lgout = 0; to suppress.
  83. $lgout = 0;
  84. $count = 0;
  85. #
  86. # Constant hashes and arrays
  87. # --------------------------
  88. #
  89. # hash with distance methods used, key = $dist_flag
  90. %method =  ("0" => "  # distance uncertain!n",
  91.             "1" => "  # method: SBFn",
  92.             "2" => "  # method: T-Fn",
  93.             "3" => "  # method: V_cmbn",
  94.             "4" => "  # method: B200n",
  95.             "5" => "  # method: ZCATn",
  96.             "6" => "  # method: NED-1D averagen",
  97.             "7" => "  # method: othern",
  98.             "8" => "  # method: NED (batch)n"
  99.             );
  100. # Hubble types of nearby galaxies
  101. %HType =("-6" => "E0",
  102.  "-5" => "E0",
  103.  "-4" => "E0",
  104.  "-3" => "S0",
  105.  "-2" => "S0",
  106.  "-1" => "S0",
  107.   "0" => "S0",
  108.   "1" => "Sa",
  109.   "2" => "Sb",
  110.   "3" => "Sb",
  111.   "4" => "Sc",
  112.   "5" => "Sc",
  113.   "6" => "Sc",
  114.   "7" => "Sc",
  115.   "8" => "Sc",
  116.   "9" => "Irr",
  117.  "90" => "Irr",
  118.  "10" => "Irr",
  119.  "11" => "Irr");
  120.  
  121. #
  122. # add Milky Way (J2000)
  123. # --------------
  124. #
  125. $name = "Milky Way";
  126. $altname = " ";
  127.    
  128. # galactic center direction
  129. $ra  = "17 45 37.224";   #IAU 1959
  130. $dec = "-28 56 10.23";   #IAU 1959
  131. # galactic north pole at (J2000)
  132. $ra_pole  = "12 51 26.282";  #IAU 1959
  133. $dec_pole = "+27 07 42.01";  #IAU 1959
  134. # convert to hours, degrees, respectively
  135. $alpha = &ra2h ($ra);
  136. $delta = &dec2deg ($dec);
  137. $delta_pole = &dec2deg($dec_pole);
  138. $alpha_pole = &ra2h ($ra_pole);
  139. # position angle 
  140. $PA = 122.932 - 90;# - 90;  #IAU 1959
  141. $Mabs = -20.6;
  142. $tp = "SBc";
  143. $dist = 2.772e4;
  144. # Orientation (Axis, Angle)
  145. #
  146. &orientation($alpha_pole,$delta_pole,"MilkyWay",0,$PA);
  147.    
  148. print  DSC "# Local Group volume (< (10 Mpc)^3):n";
  149. print  DSC "# Milky Wayn";
  150. print  DSC "Galaxy "Milky Way"n";
  151. print  DSC "{n";
  152. print  DSC "        Type  "$tp"n";
  153. print  DSC "        CustomTemplate "MilkyWay.png"n";  
  154. printf DSC "        RA        %10.6fn",$alpha;
  155. printf DSC "        Dec       %10.6fn",$delta;
  156. printf DSC "        Distance  %10.4gn",$dist;
  157. printf DSC "        Radius    %10.4gn",50000;
  158. printf DSC "        AbsMag    %10.4gn",$Mabs;
  159. printf DSC "        Axis    [%8.4f %8.4f %8.4f]n",@v;
  160. printf DSC "        Angle    %8.4fn",$angle;
  161. print  DSC "        InfoURL  "http://www.seds.org/messier/more/mw.html"n";  
  162. print  DSC "}nn";
  163. if ($lgout){
  164. $dkpc = $dist/($pc2ly * 1e3);
  165. $rar  = "17 45 37.2";
  166. $decr = "-28 56 10"; 
  167. printf "%17s %15s; %10s; %9s; %5s; %8.3f;  %6.2fn",$name,$altname,$rar,$decr,$tp,$dkpc,$Mabs;
  168. }
  169. $count++;
  170. #
  171. # read in the averaged distances from the NED1D distance data base
  172. # http://nedwww.ipac.caltech.edu/level5/NED1D/
  173. #
  174. open(NED1D," < catalogs/ned1d.txt")|| die "Can not read ned1d.txtn";
  175. $name_old = "";
  176. $ct = 1;
  177. $n_ned1d = 0;
  178. while (<NED1D>){
  179. next if (/^Contents/);
  180. next if (/^s+/);
  181. next if(/^Galaxy/);
  182. next if(/^s*(kpc)/);
  183. next if(/^s*(1)/);
  184. ($name,$dist) = split (/ss+/);
  185. ($name1,$namealt) = split(/,/,$name);
  186. if ($namealt){
  187.      $name = $name1;    
  188. }
  189. $dist = &clean($dist);
  190. $name = &clean($name);
  191.     # adapt syntax of galaxy names to RC3/NGC/IC conventions
  192. $name = &standardize($name);
  193. # only consider Messier, NGC and IC galaxies in NED1D data base for now
  194. next unless ($name =~ /^Msd+|^NGC|^IC/);    
  195.     # calculate the distance averages for all entries with the same $name
  196. if ($name eq $name_old){
  197. $ct++;
  198. $d = (($ct-1) * $d + $dist)/$ct;
  199. } else {
  200.     $n_ned1d++;
  201.     $d = $dist;
  202. $ct = 1;
  203. }
  204. # convert kpc to ly
  205.     $distance_ned1d{$name} = $d * $pc2ly * 1e3;
  206.     #print "$name  $distance_ned1d{$name}n" if ($name ne $name_old);
  207. #print "$name       $distance_ned1d{$name}n" if ($name =~/^Msd+/ && $name ne $name_old);
  208. $name_old = $name;
  209. }
  210. close(NED1D);
  211. # +++++++++++++++++++++++++++++++++++++++++++++++++++
  212. # read in revised SBF-survey data IV for fast lookup
  213. # +++++++++++++++++++++++++++++++++++++++++++++++++++
  214. open(SBF," < catalogs/sbf.txt")|| die "Can not read sbf.txtn";
  215. $n_sbf=0;
  216. while (<SBF>) {
  217.     next if (/^Pref_name/);
  218.     $name = &ss(1,8);
  219.     $name =~ s/s+//g;
  220.     $name = &standardize($name);
  221. # only consider NGC and IC galaxies in NED1D data base for now
  222. next unless ($name =~ /^NGC|^IC/);    
  223.     
  224.     #
  225.     # SBF-distances [ly]
  226.     # ------------------
  227.     #
  228.     $deltam   = &ss(77,81);
  229.     $dm{$name} = $deltam;
  230.     $dm{$name} =~ s/ //g;
  231.     $sbf_distance{$name} = 10**(($deltam+5)/5)*$pc2ly;
  232.     #print "$name  $sbf_distance{$name}n";
  233.     $n_sbf++;
  234. }
  235. close (SBF);
  236. # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  237. # read in Tully-Fisher (T-F) & Dn-sigma distance data for fast lookup
  238. # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  239. # read in first GINnumber ($gin), name and BT and B-V
  240. open(TFE," < catalogs/TF/egalf1.dat") || die "Can not read egalf1.datn";
  241. while (<TFE>) {
  242.     $gin = &ss(1,5);
  243.     $gin =~ s/ //g;
  244.     $name = &standardize (&ss(7,16));
  245. # only consider NGC and IC galaxies in NED1D data base for now
  246. next unless ($name =~ /^NGC|^IC/);    
  247.     
  248.     $name_f1{$gin} = $name;
  249.     #print "$namen";
  250. }
  251. close (TFE);
  252. # next enter the corresponding T-F distances for elliptical galaxies, 
  253. # match via $gin with egalf1.dat
  254. open(TF," < catalogs/TF/egalf2.dat") || die "Can not read egalf2.datn";
  255. $n_tf_e=0;
  256. while (<TF>) {
  257.     $gin = &ss(1,4);
  258.     $gin =~ s/ //g;;
  259.     $name = $name_f1{$gin} if ($name_f1{$gin});
  260.     $distance_TFE = &ss(35,41);
  261.     $distance_TFE = &clean($distance_TFE);
  262.     $distance_TFE{$name} = $distance_TFE/$H0 * 1.0e6 * $pc2ly; # [ly]
  263.     # $v_CMB_TFE{$name} = &ss(32,38) + &ss(40,46);
  264.     #printf "%5d %15s   %10.4gn",$gin,$name, $distance_TFE{$name};
  265.     $n_tf_e++;
  266. }
  267. close(TF);
  268. # next enter the corresponding T-F distances for spiral  galaxies
  269. open(TF," < catalogs/TF/tf-spiral.dat") || die "Can not read tf-spiral.datn";
  270. $n_tf_s=0;
  271. while (<TF>) {
  272.     $pgc = &ss(6,10);
  273.     $pgc =~ s/ //g;
  274.     $name = &standardize(&ss(12,20));
  275. # only consider NGC and IC galaxies in NED1D data base for now
  276. next unless ($name =~ /^NGC|^IC/);    
  277.     
  278.     #$name_TFS{$pgc} = $name;
  279.     $distance_TF = &ss(82,86);
  280.     $distance_TF =~ s/ //g;
  281.     $distance_TFS{$name} = $distance_TF/$H0 * 1.0e6*$pc2ly; # [ly]
  282.     $logr = &ss(66,70);
  283.     $logr =~ s/ //g;
  284.     #printf "PGC %6d %15s   %10.4gn",$pgc, $name, $distance_TFS{$name};
  285.     $n_tf_s++;
  286. }
  287. close(TF);
  288. # ++++++++++++++++++++++++++++++++++++++
  289. # read in data on 200 brightest galaxies
  290. # ++++++++++++++++++++++++++++++++++++++
  291. $n_b200 = 0;
  292. open( B200," < catalogs/200.txt") || die "Can not read 200.txtn";
  293. while (<B200>) {
  294.     next if (/^s+/);
  295.     $name = &ss(1,8);
  296.     $name = &cmpname ($name) if ($name =~ /^N|^I/);;
  297.     $name =~ s/s*$//g;
  298.     $messier = &ss(10,13);
  299.     $messier =~ s/ //g;
  300.     if ($messier){
  301.      $messier =~ s/M(d+)/M $1/;
  302.      $name = $messier;
  303.     }
  304. # only consider Messier, NGC and IC galaxies in NED1D data base for now
  305.     next unless ($name =~ /^Msd+|^NGC|^IC/);    
  306.     
  307.     $distance_B200{$name} = &ss(74,79);
  308.     $distance_B200{$name} =~ s/ //g;
  309.     $distance_B200{$name} = 1e6 * $distance_B200{$name};
  310.     $method_B200{$name} = &ss(83,90);
  311.     $method_B200{$name} =~ s/s+$//g;
  312.     #print "$name   $distance_B200{$name} $method_B200{$name}n";
  313.     $n_b200++;
  314. }
  315. close(B200);
  316. # +++++++++++++++++++++++++++++++
  317. # read in redshift data from zcat
  318. # +++++++++++++++++++++++++++++++
  319. $n_zcat = 0;
  320. open( ZCAT," < catalogs/zcat.txt") || die "Can not read zcat.txtn";
  321. while (<ZCAT>) {
  322.     next if (/^s+/);
  323.     $name = &clean(&ss(1,11));
  324.     $name = &standardize ($name); 
  325. # only consider NGC and IC galaxies in NED1D data base for now
  326.     next unless ($name =~ /^NGC|^IC/);    
  327.     
  328.     $cz = &ss(32,36);
  329.     $cz =~ s/ //g;
  330. # skip if redshift z is missing    
  331.     next if (! $cz);
  332.     $z = $cz/$c;
  333. # distance inclusive relativistic cosmological  corrections    
  334.     #printf "%10s  %10.3f  %10.3fn", $name, $z,  $distance_zcat{$name};
  335.     $distance_zcat{$name} = &dcmr($Omega_matter,$Omega_lambda,$z);
  336.     $n_zcat++;
  337. }
  338. close(ZCAT);
  339. # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  340. # Read in missing redshift data from NED batch-job for fast lookup
  341. # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  342. open(NED," < catalogs/nedz8.txt")|| die "Can not read nedz.txtn";
  343. $n_ned = 0;
  344. while (<NED>){
  345.     if (/(s+d)sG/){
  346.      $name = &standardize(&ss(19,28));
  347.      next if ($name =~ /NE*$/); # drop the NGC|IC xxx NED 1/2 objects
  348. $z = &ss(75,80);
  349. $z =~ s/ //g;   
  350.      if ($name =~ /^NGC 4518/){$z = 0.021868;}
  351.      if ($name =~ /^IC 1947/){$z = 0.03851;}
  352.      if ($name =~ /^IC 3658/){$z = 0.00015;}
  353. #printf "%10s %10.4fn",$name,$z if ($z);    
  354.      if ($z && $z > 0){
  355.      $distance_ned{$name} = &dcmr($Omega_matter,$Omega_lambda,$z);
  356.         #printf "%10d   %15s %10.4fn",$n_ned, $name,$z; 
  357.         $n_ned++;
  358.     }    
  359.     } 
  360. }
  361. # +++++++++++++++++++++++++++++++++++++++++++++++++
  362. # Read in revised RC3 data rc3.txt for fast lookup
  363. # +++++++++++++++++++++++++++++++++++++++++++++++++
  364. open(RC3," < catalogs/rc3.txt")|| die "Can not read rc3.txtn";
  365. $n_rc3 = 0;
  366. while (<RC3>) {
  367.     $pgc = &ss(106,116);
  368.     $pgc =~ s/^PGCs*0*(d+)s*$/$1/g;
  369.     #
  370.     # Galaxy name in RC3 as tag
  371.     #--------------------------
  372.     #
  373.     $n1 = &standardize(&ss(63,74));
  374.     
  375.     # These data are used BOTH for 
  376.     #  -- $PA and $Type values for 'catalog of neighboring galaxies' 
  377.     #  -- distances via Hubble law for NGC/IC catalog
  378.     # Hence evaluate all alternative names for now
  379.         
  380.     # Hierarchy: UGC , ESO , MCG , UGCA, CGCG (Zwicky et al.)
  381.     # Read out 2 alternative names:
  382.     
  383.     $altname =  &standardize(&ss(75,89));
  384.     $altname2 = &standardize(&ss(91,104));
  385.     
  386.     # RC3 does not list Messier names! Hence, must translate NGC to Messier names for the 5 M-galaxies used in "catalog of neighboring galaxies"     
  387.     
  388.     $n1 =~ s/NGC 224/M 31/;
  389.     $n1 =~ s/NGC 598/M 33/;
  390.     $n1 =~ s/NGC 3031/M 81/;
  391.     $n1 =~ s/NGC 3034/M 82/;
  392.     $n1 =~ s/NGC 5457/M 101/;
  393.     
  394.     # Read out position angle for the "catalog of neighboring galaxies" below
  395.     
  396.     $PA{$n1} = &ss(186,188); 
  397. $PA{$n1} =~ s/ //g;
  398. # assign to 0 if undefined
  399. $PA{$n1} = 0 if (! $PA{$n1});
  400.     $PA{$altname} = $PA{$n1};
  401.     $PA{$altname2} = $PA{$n1};
  402.     
  403.     # Read out morphological types for the "catalog of neighboring galaxies" below
  404.     
  405.     $type = &ss(118,124);
  406.     $type =~ s/ //g;
  407.     $Type{$n1} = $type;
  408.     $Type{$altname} = $type;
  409.     $Type{$altname2} = $type;
  410.     
  411.     if(0){
  412.      if ($type){
  413.      $tp = &RC3type($type);
  414.      printf "%15s %15s %15s %10s %10s %10sn",$pgc, $n1, $altname, $altname2, $type, $tp;
  415.      }
  416.     }    
  417.     #
  418.     # RC3 distances, [ly]
  419.     #--------------------
  420.     # from Hubble's law, d ~ v_recession/H0,
  421.     # if velocity >~ +80 km/sec (positive!)
  422.     # use weighted mean recession velocity corrected to the reference frame
  423.     # defined by the 3K microwave background radiation (CMB), units [km/sec]
  424.     
  425.     $vrad = &ss(359,363);
  426.     $vrad =~ s/ //g;
  427.     if ($vrad) {
  428.         $n_rc3++ if ($vrad > 80.0);
  429.      $rc3_distance{$n1} = $vrad/$H0 * 1e6 * $pc2ly;
  430.      $v_CMB_RC3{$n1} = $vrad;
  431.     }
  432. }
  433. close (RC3);
  434. # +++++++++++++++++++++++++++++++++++++++++++++++++++
  435. # Read in data from "Catalog of Neighboring Galaxies"
  436. # +++++++++++++++++++++++++++++++++++++++++++++++++++
  437. # names, major diameters, inclinations, absolute B-band magnitudes
  438. open(LOCALV4," < catalogs/neighborgals4.txt")|| die "Can not read neighborgals4.txtn";
  439. $n_local = 0;
  440. $j = 0;
  441. while (<LOCALV4>){
  442. $names = &ss(1,15);
  443. $names = &clean($names);
  444. if ($names =~/,/){
  445. ($name,$name2) = split(/,/,$names);
  446. } else {
  447. $name = $names;
  448. }
  449. $name = &standardize($name);
  450.     
  451.     # it was forgotten to list main IC name first for DDO 226    
  452.     $name =~ s/^DDO 226/IC 1574/;
  453. # skip all NGC/IC and Messier objects in 'catalog of neighboring galaxies'
  454. # this drops 114 objects from the catalog
  455. #if ($name =~ /^Msd+|^NGC|^IC/){print "$j  $namen";$j++;}
  456. next if ($name =~ /^Msd+|^NGC|^IC/); 
  457.     next if ($name =~ /^Milky Way/);
  458. #
  459. # Major diameters  [ly]
  460. # (corrected for galaxy inclination and the galactic extinction)
  461. #
  462. $D = &ss(17,21);
  463. $D =~ s/ //g;
  464. next if (!$D);
  465. $radius{$name} = 0.5 * $D * $pc2ly * 1e3;
  466. #print "$name $radius{$name}n";
  467. #
  468. # Inclinations from face-on [deg]
  469. #
  470. $i{$name} = &ss(23,24);
  471.        
  472. #
  473. # Absolute B-band magnitudes
  474. #
  475. $BMag{$name} = &ss(35,40);
  476. $BMag{$name} =~ s/ //g;
  477. }
  478. close (LOCALV4);
  479. # names, altnames, J2000 coordinates, distances, position angles and types from RC3
  480. open(LOCALV," < catalogs/neighborgals.txt")|| die "Can not read neighborgals.txtn";
  481. $n_local = 0;
  482. $j=0;
  483. $name2="";
  484. while (<LOCALV>){
  485. $names = &ss(1,15);
  486. $names = &clean($names);
  487. if ($names =~/,/){
  488. ($name1,$name2) = split(/,/,$names);
  489. $name2 = &standardize($name2);
  490. } else {
  491. $name1 = $names;
  492.      $name2 = "";
  493. }
  494. $name1 = &standardize($name1);
  495. #print "$name1n" if ($name1 =~/^[A-Z]+[a-z]+s*[a-zA-Z]*s*$/);
  496.     
  497.     # it was forgotten to list main IC name first for DDO 226    
  498.     $name1 =~ s/^DDO 226/IC 1574/;
  499. # skip all NGC/IC and Messier objects in 'catalog of neighboring galaxies'
  500. next if ($name1 =~ /^Msd+|^NGC|^IC/); 
  501.     next if ($name1 =~ /^Milky Way/);
  502. #$DD = &ss(38,42);
  503. #$DD =~ s/ //g;
  504. next if (!$radius{$name1});
  505. #
  506. # Read out J2000 coordinates
  507. #
  508. # RA, DEC fields:
  509. $ra = &clean(&ss(17,26));
  510. $dec= &clean(&ss(28,36));
  511. # convert to hours, degrees, respectively
  512.   
  513.    $alpha = &ra2h ($ra);
  514.    $delta = &dec2deg ($dec);
  515. #
  516. # Implement morphological Type (RC2/RC3)
  517. #
  518. $T = &ss(61,62);
  519. $T =~ s/ //g;
  520. if ($Type{$name1}){
  521. $tp = &RC3type($Type{$name1});
  522. #print "$j $name1 $Type{$name1} $tpn";
  523. #$j++;
  524. } elsif ($Type{$name2} && $name2){
  525. $tp = &RC3type($Type{$name2});
  526. #print "$j $name2 $Type{$name2} $tpn";
  527. #$j++;
  528. } else {
  529. $tp = $HType{$T};
  530. }
  531. if ($name1 =~ /^Ands+IIb/) {$tp = "E3";}
  532. if ($name1 =~ /^Ands+Ib/)  {$tp = "E0";}
  533. if ($name1 =~ /^Antliab/)   {$tp = "E3";}
  534. if ($name1 =~ /^Ands+IIIb/){$tp = "E6";}
  535.     if ($name1 =~ /^Antliab/)   {$tp = "E3";}
  536. if ($name1 =~ /^Cetusb/)    {$tp = "E4";}
  537. if ($name1 =~ /^Sex dSphb/) {$tp = "E4";}
  538. if ($name1 =~ /^Tucanab/)   {$tp = "E5";}
  539. if ($name1 =~ /^Ands+Vb/)  {$tp = "E0";}
  540. if ($name1 =~ /^UMinb/)     {$tp = "E5";}
  541. if ($name1 =~ /^Dracob/)    {$tp = "E3";}
  542. if ($name1 =~ /^Sag dSphb/) {$tp = "E6";}
  543. if ($name1 =~ /^Cass+dSphb/){$tp = "E3";}
  544. if ($name1 =~ /^Pegs+dSphb/){$tp = "E3";}
  545. #
  546. # distance [ly]
  547. #
  548. $dist_local = &ss(88,92)* $pc2ly * 1e6;
  549.     #$distance_local{$name1} = $dist_local;
  550.     #printf "%15s  %15.3fn", $name1,$dist_local;
  551. # method used
  552. $meth = &clean(&ss(95,98));
  553. #
  554. # Implement PA, degrees E of N, from RC3, else PA = 0
  555. # check both names 
  556. if ($PA{$name1}){
  557. $pa = &clean($PA{$name1});
  558. #print "$j $name1 $pan";
  559. #$j++;
  560. } elsif ($PA{$name2} && $name2){
  561.   $pa = &clean($PA{$name2});
  562. #print "$j $name2 $pan";
  563. #$j++;
  564. } elsif ($name1 =~ /^Sag dSphb/){
  565.     $pa = 90.0;
  566. } else {
  567. $pa = 0.0;
  568. }  
  569. #
  570. # Orientation (Axis, Angle)
  571. #
  572. &orientation($alpha,$delta,$tp,$i{$name1},$pa);
  573. #
  574. # recall radius and BMag from other file
  575. #
  576. $Radius = $radius{$name1};
  577. $Mabs = $BMag{$name1};
  578. # NED conform nomenclature:
  579. # ellipticities from http://www.ast.cam.ac.uk/~mike/local_members.html
  580. $name1 =~ s/(^Tucana|^Draco|^Antlia|^Carina|^Orion|^Phoenix|^Cetus)/$1 Dwarf/;
  581. $name1 =~ s/^SagDIG/Sagittarius DIG/;
  582. $name1 =~ s/UMin/UrsaMinor Dwarf/;
  583. $name1 =~ s/ESO 349-31/Sculptor DIG/;
  584. $name2 =~ s/SDIG/ESO 349-31/;
  585. $name1 =~ s/^Sculptors*$/Sculptor dSph/;
  586. $name2 =  "ESO 351-30" if ($name1 =~/Sculptor dSph/);
  587. $name1 =~ s/^Sexb/Sextans/;
  588. $name1 =~ s/^Sagb/Sagittarius/;
  589. $name1 =~ s/^Cass+dSphb/And VII/;
  590. $name2 = "Cassiopeia dSph" if ($name1 =~/And VII/);
  591. $name1 =~ s/^DDO 210/Aquarius Dwarf/;
  592. $name2 =  "DDO 210" if ($name1 =~/Aquarius Dwarf/);
  593. $name1 =~ s/^Pegs+dSph/And VI/;
  594. $name2 = "Pegasus dSph" if ($name1 =~/And VIb/);
  595. $name1 =~ s/^Fornax/Fornax dSph/;
  596. $name1 =~ s/^Pegasus/Pegasus DIG/;
  597.  
  598. $na = "";
  599. if ($name2){$na = ":".$name2;}
  600.   $name1 =~ s/ $//g;
  601. if($lgout){   
  602.      $dkpc = $dist_local /($pc2ly * 1e3);
  603. if ($dkpc < 1400){
  604. printf "%17s %15s; %10s; %9s; %5s; %8.3f;  %6.2fn",$name1,$name2,$ra,$dec,$tp,$dkpc,$Mabs;
  605. }
  606. }
  607. #
  608. # add 333 galaxies of the local group volume, V < (10 Mpc)^3,
  609. # (without Messier, NGC and IC galaxies)
  610. print  DSC "# Local Group volume (< (10 Mpc)^3):n";
  611. print  DSC "Galaxy "$name1$na"n";
  612. print  DSC "{n";
  613. print  DSC "        Type  "$tp"n";
  614. printf DSC "        RA        %10.4fn",$alpha;
  615. printf DSC "        Dec       %10.4fn",$delta;
  616. printf DSC "        Distance  %10.4g",$dist_local;
  617. print  DSC " # method: $methn";
  618. printf DSC "        Radius    %10.4gn",$Radius;
  619. printf DSC "        AbsMag    %10.4gn",$Mabs;
  620. printf DSC "        Axis    [%8.4f %8.4f %8.4f]n",@v;
  621. printf DSC "        Angle    %8.4fn",$angle;
  622. print  DSC "        InfoURL  "http://simbad.u-strasbg.fr/sim-id.pl?Ident=$name1"n";  
  623. print  DSC "}nn";
  624. $count++;
  625. $n_local++;
  626. }
  627. close (LOCALV);
  628. if(!$lgout){
  629. print "n Catalog Input:n---------------n";
  630. printf "%5d Galaxies in Local Group Volume (d < 10 Mpc)n",$n_local;
  631. printf "%5d Averaged distances from NED-1D Distance Data Basen",$n_ned1d;
  632. printf "%5d Surface Brightness Fluctuation (SBF) distance datan",$n_sbf;
  633. printf "%5d Tully-Fisher elliptical galaxy distance datan",$n_tf_e;
  634. printf "%5d Tully-Fisher spiral galaxy distance datan",$n_tf_s;
  635. printf "%5d ZCAT redshift datan",$n_zcat;
  636. printf "%5d RC3 galaxy distance datan",$n_rc3;
  637. printf "%5d NED redshift data (batch)n",$n_ned;
  638. }
  639. $ngcic_flag = 0;        # =1 for NGC, =2 for IC
  640. $c_sbf = 0;
  641. $c_hubble = 0;
  642. $c_tf = 0;
  643. $c_B200 = 0;
  644. $c_zcat = 0;
  645. $c_ned1d = 0;
  646. $c_ned = 0;
  647. # ++++++++++++++++++++++++++++++++++++++++++++++++++++++
  648. # Read out data from revised NGC/IC catalog (Steinecke), 
  649. # merge with above distance data
  650. # +++++++++++++++++++++++++++++++++++++++++++++++++++++
  651. $name = "";
  652. open(NGCIC,"<catalogs/revngcic.txt")|| die "Can not read revngcic.txtn";
  653. while (<NGCIC>) {
  654. # skip header and identify NGC or IC catalogs
  655. if (/^NGC/) {
  656.    $ngcic_flag = 1;
  657.      next;
  658.    } elsif (/^ IC/) {
  659.      $ngcic_flag = 2;
  660.      next;
  661.    } elsif (/^-/) {
  662.      next;
  663.    }
  664. # status ( reading out the S-column)
  665.    $status = &clean(&ss(11,12));
  666. # drop all but galaxies S=1 (drop also  parts of galaxies S=6)
  667.    next if (!$status);
  668.    next if ($status != 1);
  669. # skip extension lines
  670.    next if (&ss(9,10) =~ /2|10/);
  671.     $pgc = &ss(89,94);
  672.     $pgc =~ s/ //g;
  673.     $pgc =~ s/0*(d+)/$1/g;
  674. #
  675. # J2000 coordinates
  676. #
  677.    $ra =  &clean(&ss(21,30));
  678.    $dec = &clean(&ss(32,40));
  679. # Convert coordinates into hours (ra) and degrees (dec):
  680.    $alpha = &ra2h ($ra);
  681.    $delta = &dec2deg ($dec);
  682. #
  683. # Galaxy type, translation to simplified Hubble classes
  684. #
  685.    $Type = &clean(&ss(79,87));
  686.     $HType = &type($Type);
  687. # uncomment as a check on "punch-through" NON-simple Hubble types    
  688. #   next if ($HType =~ /^S[0a-c]$/);
  689. # next if ($HType =~ /^SB[a-c]$/);
  690. # next if ($HType =~ /^E[0-7]$/);
  691. # next if ($HType =~ /^Irr$/);
  692. #   print STDOUT "$name     $Type    $HTypen";
  693. #
  694. # Galaxy names
  695. #
  696. # NGC number
  697.   
  698.    $basename = &clean(&ss(1,5));
  699. #   $basename =~ s/ //g;
  700. #
  701. # Read alternative galaxy names, too
  702. #
  703.    $ID1 = &ss(97,111);
  704. #    $ID1 =~ s/ //g;  
  705.    $ID2 = &ss(113,127);
  706.   $ID2 =~ s/ //g;
  707.   $ID3 = &ss(129,143);
  708.    $ID3 =~ s/ //g;
  709.   
  710.    if    ($ngcic_flag == 1) {$basename = "NGC ".$basename;} 
  711.    elsif ($ngcic_flag == 2) {$basename =  "IC ".$basename;} 
  712.    else                     {next;}
  713.    
  714.     $partflag = &ss(6,6);
  715.    $partflag =~ s/ //g;
  716. # connect the different components (C-column) of an object with a dash  
  717.   
  718.    if ($partflag){
  719.    $name = $basename."-".$partflag;
  720.    #$basename = &standardize($ID1); # so NED (batch) will find it!
  721.     } else {
  722.     $name = $basename;
  723.     }
  724. # NGC 292 = SMC will be taken care of separately
  725.    next if($name =~ /NGC 292/);
  726.   
  727.    $altname1 = "";
  728.    if ($ID1) {
  729. #
  730. # Exchange NGC number by Messier designation from Steinicke's catalog
  731. # find all 40 galaxies from Messier catalog! (checked)
  732. #
  733.    if ( $ID1 =~ /(^Msd{1,3})/) {
  734.      $an1 =  $name;
  735.        $name = $1;
  736.        $basename = $name;
  737.    } else {
  738.      $an1 = &standardize($ID1);
  739.    }
  740.      if ($an1) {
  741.      $altname1 = ":".$an1 ;
  742.      }
  743.    }
  744.    $altname2 = "";
  745.    $an2 = "";
  746.    if ($ID2) {
  747.      $an2      = &standardize($ID2);
  748.        $altname2 = ":".$an2;
  749.    }
  750.    $altname3 = "";
  751.    if ($ID3) {
  752.      $an3      = &standardize($ID3);
  753.      $an3 = "DDO 226" if ($an3 eq "UGCA 9"); 
  754.      $altname3 = ":".$an3;
  755.    }
  756.   
  757.    @nm = ();
  758.    if ($basename) {
  759. #$name =~ s/^(NGC|IC) (d+)[ABCD-]1*$/$1 $2/; 
  760. #$name =~ s/^(?:NGC|IC) d+[ABCD-][234]$//;
  761. #$basename =~ s/-[12]$//;
  762.    #print "$name     $basename" if ($basename);
  763.    #print "          $an1n" if ($an1);
  764.    #print "n" if (!$an1);
  765.        push(@nm,$basename);# if ($basename);
  766.    }
  767.    if ($an1)  {push(@nm,$an1) };
  768.    if ($an2)  {push(@nm,$an2) };
  769.    if ($an3)  {push(@nm,$an3) };
  770. #
  771. # Max/min extensions $D/$d [arcmin] and  inclination $i [degrees]
  772. # ---------------------------------------------------------------
  773. #
  774. # use $D [arcmin] from Steinicke's data
  775. # for all lines, $D entry well-defined
  776. $D = &ss(62,67);
  777.    $D =~ s/ //g;
  778.    $d = &ss(69,73);
  779.    if ($d =~ /[0-9]/) {
  780.      $i = &inclination($d/$D);
  781.     # if $d lacking, equate min size $d to to max size $D.
  782.    } else {
  783.      $d = $D;
  784.      $i = 3.0;
  785.    }
  786. #
  787. # Apparent blue magnitude $Bmag
  788. # ------------------------------------------------
  789. #
  790.    $Bmag = "";                   # $Bmag undefined
  791.    if (&ss(42,47) =~ /[0-9]/) {
  792.      $Bmag = &ss(42,47);
  793.      $Bmag =~ s/ //g;
  794.    }
  795.   
  796. # Distance [ly] from various methods
  797. #-----------------------------------
  798. #
  799.    $distance = "";
  800.    $dist_flag = "";
  801.    # loop over alternate names
  802.    foreach $n (@nm) {
  803.     #
  804.     # first, use the distance-averages from the accurate NED-1D 
  805.     # Extragalactic Distance Database
  806.     # 
  807.     #
  808.      if ($distance_ned1d{$n}) {
  809.          #print "$nn";
  810.        $distance = $distance_ned1d{$n};
  811.        $dist_flag = 6;
  812.        last;    
  813.     #
  814.     # next, exploit SBF-distance data (IV)
  815.     # they are very accurate
  816.     #
  817.      } elsif ($sbf_distance{$n}) {
  818.        $distance = $sbf_distance{$n};
  819.        $dist_flag = 1;
  820.        #print "$nn";
  821.        last;
  822.     #
  823.     # next add in available Tully-Fischer distances
  824.     # for elliptical galaxies
  825.     #
  826.      } elsif ($distance_TFE{$n}) {
  827.        $distance = $distance_TFE{$n};
  828.        $dist_flag = 2;
  829.        #printf "%10s %10.2g %5s %10.2fn",$n,$distance,$HType,$Bmag;
  830.        last;
  831.     #
  832.     # next add in available Tully-Fischer distances
  833.     # for spiral galaxies
  834.     #
  835.     
  836.     # match via PGC numbers
  837.      } elsif ($distance_TFS{$n}) {
  838.        $distance = $distance_TFS{$n};
  839.        #printf "%10s %10.2g %5s %10.2fn",$n,$distance,$HType,$Bmag;
  840.             $dist_flag = 2;
  841.     
  842.     #
  843.     # Next, use distances from "200 brightest galaxies" compilation
  844.     #
  845.     #
  846.     } elsif ($distance_B200{$n}) {
  847.      $distance = $distance_B200{$n};
  848.      $dist_flag = 4;
  849.      $method{4} = "  # method: $method_B200{$n}n";
  850.      #printf "%10s %10s %10.2gn", $name,$method_B200{$name},$distance_B200{$name};
  851.     #
  852.     # next exploit Hubble's law, distance ~ v_recession/H0,
  853.     # if radial velocity >~ 80 [km/sec] (positive!),
  854.     # use weighted mean recession velocity corrected to
  855.     # the reference frame defined by the 3K microwave background
  856.     # radiation (CMB)
  857.     #
  858.     # recession velocities from RC3_rev catalog
  859.     } elsif ($rc3_distance{$n}) {
  860. if ($v_CMB_RC3{$n} > 80.0) {
  861.      $distance = $rc3_distance{$n};
  862.      #print "$pgc $n   $distance  $v_CMB_RC3{$n}n";
  863.      $dist_flag = 3;  
  864.    }  
  865.   
  866.    #
  867.    # Next, use distances from zcat redshift catalog
  868.    #  
  869.         } elsif ($distance_zcat{$n}) {
  870.    if ($distance_zcat{$n} > 0){  
  871.      $distance = $distance_zcat{$n} ;
  872.      #print "$n  $distancen";
  873.      $dist_flag = 5;
  874.    }  
  875.    } elsif ($distance_ned{$n}) {
  876.      $distance = $distance_ned{$n} ;
  877.      #print "$n  $distancen";        
  878.      $dist_flag = 8;
  879.        }
  880.    }
  881.   #
  882.   # Individual corrections from various recent sources
  883.   #
  884.    if($name =~ /M 51/) {
  885.      $distance = $sbf_distance{"NGC 5195"} - 0.5e6;
  886.      $dist_flag = 4;
  887.      $method{4} = "  # method: $method_B200{$name}n";
  888.    }
  889.    if($name =~ /NGC 1569/) {
  890.      $distance = 2.375 * $pc2ly * 1e6;
  891.      $dist_flag = 7;
  892.      $method{7} = "  # method: Pn";
  893.    }
  894.    if($name =~ /M 90/) {
  895.      $distance = $distance_B200{"M 90"};
  896.      $dist_flag = 4;
  897.      $method{4} = "  # method: $method_B200{$name}n";
  898.    }
  899.    if($name =~ /NGC 4438/) {
  900.      $distance = $rc3_distance{"NGC 4435"};
  901.      $dist_flag = 7;
  902.      $method{7} = "  # method: M. Machacek et al. 2003, ApJn";
  903.    }
  904.   
  905.    #
  906.    # last resort for distances: (<=> TF for eta = eta_peak)
  907.    # Simple estimate using /peak/ absolute mags from (absolute) brightness
  908.    # distributions of SBF-galaxy survey, distinguishing "E" and "S"-type 
  909.    # galaxies.
  910.    #
  911.   
  912.    # if(!$distance){printf "%10s  %10.3f %4sn",$name,$Bmag,$HType;}
  913.    #next if (!$distance);
  914.   
  915.    if(! $distance){ 
  916.         
  917.      $M_abs = $M_abs_ell if ($HType =~ /^E|^Irr/);
  918.      $M_abs = $M_abs_spir if ($HType =~ /^S/);
  919.      $distance = 10**(($Bmag - $M_abs * (1 + 0.0 * (1 - 2 * rand())) + 5)/5) * $pc2ly;
  920.      $dist_flag = 0;
  921.         #print "$j     $basenamen" if ($basename);
  922.         $j++;
  923.      #printf "%10s  Distance = %8.4g ly  HType =%4sn",$name,$distance,$HType;
  924.    }
  925.    # Radius [ly]
  926.    #-------------
  927.    #
  928.    $radius = 0.5*deg2rad($D/60.0)*$distance;
  929.    #
  930.    # Position angle
  931.    #---------------
  932.    #
  933.    # use values from Steinicke's catalog
  934.    $PA = &ss(75,77);
  935.    $PA =~ s/ //g;
  936.    # assign to 0 if undefined
  937.    $PA = 0 if (! $PA);
  938.    #printf "%10s %10.2f %5sn",$name,$PA,$HType if ($HType eq "Sc");
  939.    #
  940.    # Orientation (Axis, Angle)
  941.    #---------------------------
  942.    #
  943.    &orientation($alpha,$delta,$HType,$i,$PA);
  944.    #
  945.    # absBMag (<== Bmag)
  946.    #--------------------
  947.    # use the distance from the galaxy boundary (rather than the center)
  948.    # matches with Celestia code.
  949.     #printf "%10s %15.4g %10dn",$name,$distance,$dist_flag if ($name =~ /^Msd+/|$name =~/^NGCs5196/);
  950.    $Mabs = $Bmag - 5*log(($distance - $radius)/(10*$pc2ly))/log(10);
  951.     #$DM = $Bmag - $Mabs;
  952.     #printf "%10.3f  %10.3fn",$Bmag, $DM if ($dist_flag == 2);  
  953.    # count the various distance methods used
  954.    $c_sbf++    if ($dist_flag == 1);
  955.    $c_tf++     if ($dist_flag == 2);
  956.    $c_hubble++ if ($dist_flag == 3);
  957.    $c_B200++   if ($dist_flag == 4);
  958.    $c_zcat++   if ($dist_flag == 5);
  959.    $c_ned1d++  if ($dist_flag == 6);
  960.    $c_ned++    if ($dist_flag == 8);
  961.     
  962. if($lgout){   
  963.      $dkpc = $distance /($pc2ly * 1e3);
  964. if ($dkpc < 1400){
  965. printf "%17s %15s; %10s; %9s; %5s; %8.3f;  %6.2fn",$name,$an1,$ra,$dec,$HType,$dkpc,$Mabs;
  966. }
  967. }
  968. print  DSC "Galaxy "$name$altname1$altname2$altname3"n";
  969.    print  DSC "{n";
  970.    print  DSC "        Type  "$HType"n";
  971. printf DSC "        RA        %10.4fn",$alpha;
  972.    printf DSC "        Dec       %10.4fn",$delta;
  973.    printf DSC "        Distance  %10.4g",$distance;
  974.    print  DSC "$method{$dist_flag}";
  975.    printf DSC "        Radius    %10.4gn",$radius;
  976.    printf DSC "        AbsMag    %10.4gn",$Mabs;
  977.    printf DSC "        Axis    [%8.4f %8.4f %8.4f]n",@v;
  978.    printf DSC "        Angle    %8.4fn",$angle;
  979.    print  DSC "        InfoURL "http://simbad.u-strasbg.fr/sim-id.pl?Ident=$name"n";
  980.    print  DSC "}nn";
  981.   
  982.    $count++;
  983. }
  984. # Summary output of used distance data
  985. $sum = $n_local + $c_ned1d + $c_sbf + $c_tf + $c_hubble + $c_B200 + $c_zcat + $c_ned;
  986. print  "nSummary Output:n---------------n";
  987. printf "%5d Galaxies in Totaln",$count;
  988. printf "%5d with good distance datann",$sum;
  989. printf "%5d with distances from 'catalog of neighboring galaxies'n",$n_local;
  990. printf "%5d with NED-1D averaged distancesn",$c_ned1d;
  991. printf "%5d with Surface Brightness Fluctuation (SBF) distancesn",$c_sbf;
  992. printf "%5d with Tully-Fisher distancesn",$c_tf;
  993. printf "%5d with B200 distancesn",$c_B200;
  994. printf "%5d with distances from Hubble Law (v_CMB, RC3)n",$c_hubble;
  995. printf "%5d with distances from Hubble Law (ZCAT).n",$c_zcat;
  996. printf "%5d with distances from Hubble Law (NED, batch).n",$c_ned;
  997. # like substr($_,first,last), but one-based.
  998. sub ss {
  999.    substr ($_, $_[0]-1, $_[1]-$_[0]+1);
  1000. }
  1001. sub clean {
  1002. # squeeze out superfluous spaces
  1003. my($string) = @_;
  1004. $string =~ s/^s*//;
  1005. $string =~ s/s*$//;
  1006. $string =~ s/s+/ /g;
  1007. $string;
  1008. }
  1009. sub ra2h {
  1010.    my($coord) = @_;
  1011.    my $h =  substr($coord,0,2);
  1012.    my $min =  substr($coord,3,2);
  1013.    my $sec = substr($coord,6,3);
  1014.    $h+$min/60+$sec/3600;
  1015. }
  1016. sub dec2deg {
  1017. my($coord) = @_;
  1018.    my $sign = substr($coord,0,1);
  1019.    my $deg  = substr($coord,1,2);
  1020.    my $min  = substr($coord,4,2);
  1021.    my $sec  = substr($coord,7,3);
  1022.    if ($sign eq "+") {
  1023.      $s =1;
  1024.    } else {
  1025.      $s = -1;
  1026.    }
  1027.    $s*($deg+$min/60+$sec/3600);
  1028. }
  1029. sub ra2h_rc3 {
  1030.     my($h,$min,$sec) = @_;
  1031.     $h+$min/60+$sec/3600;
  1032. }
  1033. sub dec2deg_rc3 {
  1034.     my($sign,$deg,$min,$sec) = @_;
  1035.     if ($sign eq "+"){
  1036.      $s =1;
  1037.     } else {
  1038.      $s = -1;
  1039.     }
  1040.     $s*($deg+$min/60+$sec/3600);
  1041. }
  1042. sub standardize {
  1043.    # eliminate prenulls and bring the ned1d galaxy names in sync with RC3
  1044.    # and NGC/ICrevised
  1045.    my( $name ) = @_;
  1046.     $name =~ s/ //g;
  1047. $name =~ s/bI*G//g;
  1048. $name =~ s/b0+//g;
  1049. $name =~ s/([A-Z]+)0+([1-9]+)/$1 $2/g;
  1050.     $name =~ s/(^[A-Z]+)(-*[1-9].*)/$1 $2/;    
  1051.     $name =~ s/^Eb/ESO/;
  1052.     $name =~ s/^Ub/UGC/;
  1053.     $name =~ s/^UAb/UGCA/;
  1054.     $name =~ s/^Db/DDO/;
  1055.     $name =~ s/^Nb/NGC/;
  1056.     $name =~ s/^Ib/IC/;
  1057.     $name =~ s/^ANDIV/And IV/;
  1058.     $name =~ s/(^[A-Z][a-ce-z]+)(dSph)/$1 $2/;
  1059.     $name =~ s/(^[A-Z][a-z]+G*)(I*[VAB]*)/$1 $2/ unless ($name =~ /SagDIG|dSph/);
  1060.     $name =~ s/^ARP/Arp/;
  1061.     $name =~ s/(^[A-Za-z]+)([1-9]+)/$1 $2/;
  1062.     $name =~ s/LGS -3/LGS 3/;
  1063.     $name =~ s/=w+//;
  1064.     $name =~ s/[V]//;
  1065.     #$name =~ s/^Z (d+)/ZWG $1/;
  1066.     $name =~ s/^C (d+)_0*(d+)/CGCG $1-$2/;
  1067.     $name =~ s/^P (d+)/PGC $1/;
  1068.     $name =~ s/^[KK98](d+)/KK $1/;     
  1069.     $name =~ s/Dwarf//;
  1070.     $name =~ s/-dE1//;
  1071.     $name =~ s//39$//;
  1072.     $name =~ s/&$//;
  1073.     $name =~ s/^NPMs1G(.*)/NPM1G $1/;
  1074.     
  1075.     return $name;
  1076. }
  1077. sub cmpname {
  1078.    my( $name ) = @_;
  1079.    my $num ="";
  1080.    if ($name =~ /(^[A-Z]+)s*([0-9-_AB]++*.*d*)/) {
  1081.      my $let = $1;
  1082.      $num = $2;
  1083.      $num =~ s/^-//;
  1084.      $let." ".$num;
  1085.    }
  1086. }
  1087. sub RC3type {
  1088. # Reduce the RC3 morphology scheme to simple Hubble classes
  1089. my($iType) = @_;
  1090.     return "" if (length($iType) != 7); 
  1091.     $oType = substr($iType,1,length($iType) - 3);
  1092.     $oType =~ s/^[IP].*$/Irr/;
  1093.     $oType =~ s/^L.*$/S0/;    
  1094.     $oType =~ s/^RING.*$/SBa/;
  1095.     $oType =~ s/[AX]//;
  1096.     $oType =~ s/^SB.*0/SBa/;
  1097.     $oType =~ s/^E.*(d).*$/E$1/;
  1098.     $oType =~ s/+*?*.*//g;
  1099.     $oType =~ s/^(SB*).*[89]/Irr/;    
  1100.     $oType =~ s/^(SB*).*[567]$/$1c/;
  1101.     $oType =~ s/^(SB*).*[34]$/$1b/;
  1102.     $oType =~ s/^(SB*).*[12]$/$1a/;
  1103.     $oType =~ s/^S$/S0/;
  1104.     $oType =~ s/^E$/E0/;
  1105.     return $oType;
  1106. }
  1107. sub type {
  1108. my($Type) = @_;
  1109.    if ($Type =~ /S[+?0abcdm]?|^[ES]$|SB[?0abcdm]?|d?E[+?0-7]?|Irr|IB?m?|C|RING|Ring|GxyP|P|D|^R/) {
  1110.      $Type =~ s/^E/SB0/S0/;
  1111.      $Type =~ s/^(w)+C/$1/;
  1112.      $Type =~ s//P?R?G?D?b//;
  1113.      $Type =~ s/(w+??)sB?R?M?/$1/;
  1114.      $Type =~ s/^d//;
  1115.      $Type =~ s/(w+)d-(w)/$1$2/;
  1116.      $Type =~ s/^E-?/?S0/S0/;
  1117.      $Type =~ s/^S(B?)[abc]([abc])/S$1$2/;
  1118.      $Type =~ s/SBR???$/SBa/;
  1119.      $Type =~ s/SB0/S0/;
  1120.      $Type =~ s/^E?? ?B?R?$/E0/;
  1121.      $Type =~ s/^S??$/S0/;
  1122.      $Type =~ s/^Sd$/Irr/;
  1123.      $Type =~ s/^S(B?)c?d/S$1c/;
  1124.      $Type =~ s/^IB?m?$/Irr/;
  1125.      $Type =~ s/^Irr B$/Irr/;
  1126.      $Type =~ s/^SB?d?m/Irr/;
  1127.      $Type =~ s/^C/E0/;
  1128.      $Type =~ s/^P??/Irr/;
  1129.      $Type =~ s/GxyP/Irr/;
  1130.      $Type =~ s/^Ring.*[AB]?$/S0/;
  1131.      $Type =~ s/^SB?cm/Irr/;
  1132.      $Type =~ s/S+S/Sa/;
  1133.      $Type =~ s/E+E??/E0/;
  1134.      $Type =~ s/^[cd]?D ?R?/E0/;
  1135.      $Type =~ s/E+*?C???S?/E0/;
  1136.      $Type =~ s/^Rwd$/Irr/;
  1137.      $Type =~ s/^R/S0/;
  1138.      # new for celestia-1.4.1
  1139.      $Type =~ s/S0+S0$/S0/;
  1140.      $Type =~ s/S[0c]?$/S0/;
  1141.      $Type =~ s/Spec$/Irr/;
  1142.      $Type =~ s/c?E0w+$/E0/;
  1143.      $Type =~ s/[34]S$/Sc/;
  1144.      $Type =~ s/5C$/Irr/;
  1145.      $Type =~ s/E0+*3/E0/;
  1146.      $Type =~ s/SB+C?/SBa/;
  1147.     }
  1148. return $Type;
  1149. }
  1150. sub inclination {
  1151.    my( $r ) = @_;
  1152.    # compute inclination angle $i [degrees] from $d/$D extension ratio
  1153.    my $wu = ($r**2 - 0.2**2)/(1.0 - 0.2**2);
  1154.    if ($wu > 1.0e-8) {
  1155.      3.0 + 180/pi*acos(sqrt($wu));
  1156.    } else {
  1157.      90.0;
  1158.    }
  1159. }
  1160. sub orientation {
  1161.    my($ra, $dec, $Type, $i, $PA) = @_;
  1162.    my $decrot = Math::Quaternion::rotation(deg2rad(90 - $dec),1,0,0);
  1163.    my $rarot  = Math::Quaternion::rotation(deg2rad(90 - $ra * 15),0,1,0);
  1164.    my $radecrot = $decrot * $rarot;
  1165.    my $incrot = Math::Quaternion::rotation(deg2rad($i),0,0,1);
  1166. my $pa =  Math::Quaternion::rotation(deg2rad($PA),0,1,0);
  1167.    my $eclipticsrot = Math::Quaternion::rotation(deg2rad($epsilon),1,0,0);
  1168.    #
  1169.    if ($Type =~ /^E|^Milky/) {
  1170.      $rot = $pa * $radecrot * $eclipticsrot;
  1171. } else {
  1172.      $rot = $incrot * $pa *  $radecrot * $eclipticsrot;
  1173.    }
  1174. if ($rot->rotation_angle > pi){
  1175. $rot = $rot->negate;
  1176. }
  1177. $rot   = $rot->normalize;
  1178.    $angle = $rot->rotation_angle * 180/pi;
  1179. @v     = $rot->rotation_axis;
  1180. }
  1181. sub dcmr {
  1182. # calculate the comoving distance appropriate for Hubble's law, 
  1183. # given $z, $Omega_matter=$Wm, $Omega_lambda=$Wlam.
  1184.     my($Wm, $Wlam, $z) = @_;
  1185.     my $Wr = 0.4165/($H0 * $H0); # 3 massless neutrinos to Omega (radiation)
  1186.     my $Wk = 1 - $Wm -$Wr -$Wlam; # flat universe, Omega (total) = 1
  1187.     my $az = 1/($z + 1);
  1188.     my $numpoints = 50; # support points for numerical integration
  1189.     # do integral over $a=1/(1+$z) from $az to 1 in $numpoints steps, 
  1190.     # midpoint rule
  1191.    $dcmr = 0;
  1192.    #print "$Wm $Wlam $Wk  $Wr $azn";
  1193.    for ($i = 0; $i < $numpoints; $i++) {
  1194.     my $a = $az + (1 - $az) * ($i + 0.5)/$numpoints;
  1195.     my $adot = sqrt($Wk + ($Wm/$a) + ($Wr/($a * $a)) + ($Wlam * $a * $a));
  1196.     $dcmr = $dcmr + 1/($a * $adot);
  1197. }
  1198. return $dcmr = $pc2ly * 1e6 * $c/$H0 * (1 - $az) * $dcmr/$numpoints;
  1199. }