1#!/usr/bin/perl
2
3use Math::Libm ':all';
4
5open(BINDAT,"<doubles99.txt")|| die "Can not read doubles99.txt\n";
6open(ELMTS, ">visualbins.stc") || die "Can not create visualbins.stc\n";
7
8# boilerplate
9($ver = "Revision: 1.6.0 ") =~ s/\$//g;
10($me = $0) =~ s/.*\///;
11($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime;
12$year += 1900;
13$mon += 1;
14print ELMTS "# ---------------------------------------\n";
15print ELMTS "# Orbits of visual binaries for Celestia: $me, $ver,\n";
16print ELMTS "# ---------------------------------------\n";
17print ELMTS "# from S. Soederhjelm, Astronomy and Astrophysics, v.341, p.121-140 (1999).\n";
18print ELMTS "# Refereed publication freely available at\n";
19print ELMTS "# http://adsabs.harvard.edu/cgi-bin/nph-bib_query?1999A%26A...341..121S\n";
20print ELMTS "#\n";
21print ELMTS "# Binaries within 25 ly distance have been commented out here.\n";
22print ELMTS "# They are included in Celestia's 'nearstars.stc'.\n";
23print ELMTS "# This update features SIMBAD-compatible nomenclature for all barycenters.\n";
24print ELMTS "# Leading and alternative star designations were extracted via SIMBAD's\n";
25print ELMTS "# scripting facility, available at http://simbad.u-strasbg.fr/simbad/,\n";
26print ELMTS "# and from Celestia's 'starnames.dat'.\n";
27print ELMTS "# Missing spectral types for components were added from scanning\n";
28print ELMTS "# 'The Washington Visual Double Star Catalog (WDS) (Mason+ 2001-2009)',\n";
29print ELMTS "# http://cdsarc.u-strasbg.fr/viz-bin/Cat?B/wds,\n";
30print ELMTS "# and from redoubled entries in Celestia's 'spectbins.stc'\n";
31print ELMTS "# \n";
32print ELMTS "# Coordinates and distances for barycenters and numerous spectral types are from\n";
33print ELMTS "# Celestia's stars, ('stars.txt' merged with 'revised.stc'), based on\n";
34print ELMTS "# Floor van Leeuwen, 2007 'Hipparcos, the New Reduction of the Raw Data',\n";
35print ELMTS "# Astrophysics & Space Science Library #350.\n";
36print ELMTS "# available at http://cdsarc.u-strasbg.fr/viz-bin/Cat?I/311\n";
37print ELMTS "#\n";
38print ELMTS "# Processed $year-$mon-$mday $hour:$min:$sec UTC\n";
39print ELMTS "# by Dr. Fridger Schrempp, fridger.schrempp\@desy.de\n";
40print ELMTS "# ------------------------------------------------------ \n";
41print ELMTS "\n";
42
43#
44# constants
45#
46$pi = 3.14159265359;
47$ly2AU = 63239.7;
48$d_sol = 1.0/$ly2AU; # in ly
49$c = $ly2AU/3600.0*$pi/180.0; # conversion a["] -> a[ly]
50$cons='And|Cap|Col|Dra|Lac|Mus|Psc|Tau|Ant|Car|Com|Eql|Leo|Nor|Pup|Tel|Aps|Cas|CrA|Eri|Lep|Oct|Pyx|TrA|Aql|Cen|CrB|For|Lib|Oph|Ret|Tri|Aqr|Cep|Crt|Gem|LMi|Ori|Scl|Tuc|Ara|Cet|Cru|Gru|Lup|Pav|Sco|UMa|Ari|Cha|Crv|Her|Lyn|Peg|Sct|UMi|Aur|Cir|CVn|Hor|Lyr|Per|Ser|Vel|Boo|CMa|Cyg|Hya|Men|Phe|Sex|Vir|Cae|CMi|Del|Hyi|Mic|Pic|Sge|Vol|Cam|Cnc|Dor|Ind|Mon|PsA|Sgr|Vul';
51
52@commenting_out = ("","#  Star already in 'nearstars.stc', since d < 25 ly\n#\n", "# Commented out to avoid redoubling\n#\n");
53
54@quality = ("","","\# lacking, used HIP data of the entire system!", "\# mentioned in D.Pourbaix's paper (discussion)");
55
56#
57# check for matching entries in Pourbaix' spectroscopic data
58#
59open(SPECT,"<Pourbaix-stars.txt")|| die "Can not read Pourbaix-stars.txt\n";
60while (<SPECT>){
61    chop();
62    next if (/^#/);
63    s/_+//g;
64    ($hipSp,$nameSp,$hd,$mvA,$colorSpA,$mvB,$colorSpB,$type,$ref) = split(/\|/);
65    $colorSpA{$hipSp} = $colorSpA;
66    $colorSpB{$hipSp} = $colorSpB;
67    $mvSpA{$hipSp} = $mvA;
68    $mvSpB{$hipSp} = $mvB;
69
70    #print "$hipSp  $altSp{$hipSp} $colorSpA{$hipSp}  $colorSpB{$hipSp}\n";
71}
72close (SPECT);
73#
74# implement matching Celestia starnames
75#
76open(STN,"<starnames.dat")|| die "Can not read starnames.dat\n";
77while (<STN>){
78    chop();
79    # extract main name
80    ($hipStn, $name1, $dummy) = ($_ =~ /(^\d+):([a-zA-Z]+\s?[a-zA-Z]{4,}):(.*)/);
81     # is there a second name?
82    ($name2, $dummy2) = ($dummy =~ /(^[a-zA-Z]+\s?[a-zA-Z]{4,}):(.*)/);
83    if ($name1){
84        $name1A = "$name1 A";
85        $name1B = "$name1 B";
86    }
87    if ($name2){
88        $name2  = ":$name2";
89        $name2A = "$name2 A";
90        $name2B = "$name2 B";
91    } else {
92        $name2A = "";
93        $name2B = "";
94    }
95    $Stn{$hipStn}  = $name1.$name2;
96    $StnA{$hipStn} = $name1A.$name2A;
97    $StnB{$hipStn} = $name1B.$name2B;
98
99    #print "$hipStn      $Stn{$hipStn}  $StnA{$hipStn}  $StnB{$hipStn}\n" if $Stn{$hipStn};
100}
101close (STN);
102#
103# implement SIMBAD naming compatibility, via SIMBATCH ('simbad.txt' output)
104#
105open(SIMBAD,"<simbad_vis.txt")|| die "Can not read simbad_vis.txt\n";
106while (<SIMBAD>){
107    chop();
108    $alt  = ""; $altA = ""; $altB = ""; $nx = ":"; $comp="";
109    if (/^Identifiers=/){
110        if (/\|HIP (\d+)\|/){$hipSim = $1;}
111        if (/\|.*\s([a-zA-Z]+ )($cons)(\s?[A-B]?)\|/){
112            $comp = $3;
113            $constell = $2;
114            $pre  = $1;
115            $pre  =~ tr/a-z/A-Z/;
116            $pre  =~ s/KSI/XI/g;
117            &update ($pre, $constell, $comp);
118        }
119        if (/\|V\*\s(V\d+ )($cons)(\s?[A-B]?)\|/){
120            $comp = $3;
121            $constell = $2;
122            $pre  = $1;
123            &update ($pre, $constell, $comp);
124        }
125        if (/\|.*\s(\w+\.0\d )(($cons))/){
126            $constell = $2;
127            $pre  = $1;
128            $pre  =~ s/\.01/1/g;
129            $pre  =~ s/\.02/2/g;
130            $pre  =~ tr/a-z/A-Z/;
131            $pre  =~ s/KSI/XI/g;
132            &update ($pre, $constell, " ");
133        }
134        if (/\|.?\s(\d+ )($cons)(\s?[A-B]?)\|/){
135            $comp = $3;
136            $constell = $2;
137            $pre  = $1;
138            &update ($pre, $constell, $comp);
139        }
140        if (/\|(GJ \d+)(\s?[A-C]*)\|/){
141            $pre = $1;
142            $comp = $2;
143            &update ($pre, "", $comp);
144        }
145        if (/\|(ADS \d+)(\s?[A-P]*)\|/){
146            $pre = $1;
147            $comp = $2;
148            &update ($pre, "", $comp);
149        }
150        if (/\|(CCDM\sJ\d+[\+\-]\d+)([A-P]*)\|/){
151            $pre = $1;
152            $comp = $2;
153            &update ($pre, "", $comp);
154        }
155        if (/\|(p\.\sWDS\sJ\d+[\+\-]\d+)([A-P]*)\|/){
156            $pre = $1;
157            $comp = $2;
158            # &update ($pre, "", $comp);
159            $pre =~ s/p\.\sWDS\sJ//g;
160            $wdsSim{$hipSim} = $pre;
161            #print "$hipSim  $wdsSim{$hipSim}\n";
162        }
163
164
165        $alt{$hipSim, 'AB'} = $alt?$alt:"HIP $hipSim";
166        $alt{$hipSim, 'A'}  = $altA?$altA:"HIP $hipSim A";
167        $alt{$hipSim, 'B'}  = $altB?$altB:"HIP $hipSim B";
168
169        if ($Stn{$hipSim}){
170            $alt{$hipSim, 'AB'} =  $Stn{$hipSim}.$nx.$alt{$hipSim, 'AB'};
171            $alt{$hipSim, 'A'}  =  $StnA{$hipSim}.$nx.$alt{$hipSim, 'A'};
172            $alt{$hipSim, 'B'}  =  $StnB{$hipSim}.$nx.$alt{$hipSim, 'B'};
173        }
174
175        ($orbitRef{$hipSim},$tmp) = split(":",$alt{$hipSim, 'AB'});
176    }
177}
178close(SIMBAD);
179#
180# read in WDS looking for spectral types
181#
182open(WDS,"< wds.dat")|| die "Can not read wds.dat\n";
183while (<WDS>){
184    chop();
185    $wds     = &clean(&ss(1,10));
186    ($sptype1, $sptype2) = split(/[\/ \+]+/,&clean(&ss(71,80)));
187
188    # ($sptype1, $sptype2)
189    $sptype1{$wds} = $sptype1;
190    $sptype2{$wds} = $sptype2;
191}
192close(WDS);
193#
194# read in the entire stars.txt for fast lookup
195#
196open(HIP,"< stars.txt")|| die "Can not read stars.txt\n";
197while (<HIP>){
198    chop();
199    $line = $_;
200    ($hipnr,$tmp) = split (/  /);
201
202    # squeeze out all spaces and use as a key
203
204    $stars{$hipnr} = &clean($line);
205}
206close (HIP);
207
208#
209# merge with corrections in revised.stc
210#
211open(HIPREV,"<revised.stc")|| die "Can not read revised.stc\n";
212while (<HIPREV>){
213    next if (/^#/);
214    if (/(^\d+)/ || /^Modify (\d+)/){
215        $hiprev = $1;
216        ($h,$c1,$c2,$dd,$magapp,$color) = split(/[ \t]+/,$stars{$hiprev});
217#        if (!$stars{$hiprev}){
218#            print "ORG: HIP star missing!\n";
219#        } else {
220#            print "ORG: HIP $stars{$hiprev}\n";
221#        }
222        next;
223    }
224    next if(/^\{/);
225    if(/RA\b\s+([\d.]+)/){$c1              = $1; next;}
226    if(/Dec\b\s+([-\d.]+)/){$c2            = $1; next;}
227    if(/Distance\b\s+([\d.]+)/){$dd        = $1; next;}
228    if(/SpectralType\b\s+\"(.*)\"/){$color = $1; next;}
229    if(/AppMag\b\s+([\d.]+)/){$magapp      = $1; next;}
230    if (/^\}/){
231        $stars{$hiprev} = join (" ",$hiprev,$c1,$c2,$dd,$magapp,$color);
232#       print "REV: HIP $stars{$hiprev}\n\n";
233    }
234}
235close (HIPREV);
236
237$count = 0;
238$k = 0;
239$kAwds = 0; $kBwds = 0; $kAsb = 0; $kBsb = 0; $kAhip = 0; $kBhip = 0;
240while (<BINDAT>) {
241	next if (/^R.*$/);
242	chop();
243	($hip,$n_hip,$Hp1,$dm2m1,$V_I,$plx,$plxHIP,$Hpa,$Msum,$q,$Per,$T,$a,$e,$i,$omega,$OMEGA,$recno) = split (/\|/,$_);
244	# squeeze out all superfluous spaces
245	$hip   =~s/ //g;
246	$n_hip =~s/ //g;
247	$plx   =~s/ //g;
248	$q     =~s/ //g;
249    $dm2m1 =~s/ //g;
250
251	next if($plx eq "");
252    $d=1000/($ly2AU*$plx)*3600/$pi*180; # d in [ly]; $plx in [mas]
253	next if ($q eq "");
254	$m1 = $Msum/(1.0+$q);
255	$m2 = $m1*$q;
256
257	$a2 = $d*$c*$a/(1.0 + $q); # a2 [ly]
258	$a1 = $a2*$q;              # a1 [ly]
259	next if ($n_hip eq "b");
260	next if ($stars{$hip} eq "");
261
262    $comment_flag = 0;
263    $onoff = "";
264    #
265	# extract distance [ly] from 'stars.txt & revised stc'
266	# use it to compile absolute magnitude
267	#
268	($h,$c1,$c2,$dd,$magapp,$color) = split(/[ \t]+/,$stars{$hip});
269	#
270    # coordinates in decimal-degrees
271    #
272    $c1 =~ s/ //g;
273    $c2 =~ s/ //g;
274
275    #
276    # app.mag of secondary
277    #
278    $Hp2 = $Hp1 + $dm2m1;
279
280    #print "$hip  $Hp1  $dm2m1  $Hp2\n";
281
282    $epsrel = 0;
283    if($d){ $epsrel = 100 * ($dd - $d)/$d;}
284	if($epsrel > 10){
285		print STDOUT "Distance mismatch of $epsrel % with (revised) stars.txt for HIP $hip\n";
286	}
287	$d = $dd;
288    #
289    # comment out all binaries with earthbound distance <= 25 ly.
290    # They are included in Grant Hutchison's 'nearstars.stc' file
291    #
292    if ($d <= 25){
293        $onoff = "# ";
294        $comment_flag = 1;
295        #print "$hip   $d\n";
296    }
297
298	$color =~ s/ //g;
299
300    if ($color =~ /(\w+)\/(\w+)/){
301        $hipcolorA = $1;
302        $hipcolorB = $2;
303    } else {
304        $hipcolorA = $color;
305        $hipcolorB = $color;
306    }
307    #
308    # separate spectral types of both components
309    #
310    if ($sptype1{$wdsSim{$hip}}){
311       # scan first the WDS catalog for spectral types
312        $spectA = $sptype1{$wdsSim{$hip}};
313        $quA = $quality[0];
314        $kAwds++ if !$onoff;
315    } elsif ($colorSpA{$hip}){
316        # use up next the known spectral types from D. Pourbaix
317        $spectA = $colorSpA{$hip};
318        $quA = $quality[1];
319        #print "$hip A-color: $spectA\n";
320        $kAsb++ if !$onoff;
321    } else {
322        # identify the leftovers with the system spectral type from HIP
323        $spectA = $hipcolorA;
324        $quA = $quality[2];
325        $kAhip++ if !$onoff;
326    }
327    if ($sptype2{$wdsSim{$hip}}){
328        # scan first the WDS catalog for spectral types
329        $spectB = $sptype2{$wdsSim{$hip}};
330        $quB = $quality[0];
331        $kBwds++ if !$onoff;
332    } elsif ($colorSpB{$hip}){
333        # use up next the known spectral types from D. Pourbaix
334        $spectB = $colorSpB{$hip};
335        $quB = $quality[1];
336        #print "$hip B-color: $spectB\n";
337        $kBsb++ if !$onoff;
338    } else {
339        # identify the leftovers with the system spectral type from HIP
340        $spectB = $hipcolorB;
341        $quB = $quality[2];
342        $kBhip++ if !$onoff;
343    }
344    # cleaning up for Celestia
345    $spectA =~ s/[a-z]|\.{2,}|\-I?V|:|\+//g;
346    $spectB =~ s/[a-z]|\.{2,}|\-I?V|:|\+//g;
347    $spectA = "\"$spectA\"";
348    $spectB = "\"$spectB\"";
349
350    #printf "%2s %6d %10.2f %12s %8s %8s %8s %8s\n", $onoff, $hip, $d,  $sptype1{$wdsSim{$hip}},$sptype2{$wdsSim{$hip}},$colorSpA{$hip},$colorSpB{$hip},$hipcolorB;
351
352    #printf "%2s %6d %15s %10.2f %10.2f %5s\n", $onoff, $hip, $wdsSim{$hip}, $d, $Hp1, $Hp2;
353
354    #if ($alt{$hip,'AB'} =~/($cons)/){$k++; print "$k   $alt{$hip,'AB'}\n";}
355    #print STDOUT "$Period $SemiMajorAxis $Eccentricity $Inclination $AscendingNode $ArgOfPeri $MeanAnomaly\n";
356
357    &RotOrbits($c1,$c2,$Per,$a,$i,$OMEGA,$T,$e,$omega,$d);
358	print  ELMTS "$onoff Barycenter $hip \"$alt{$hip,'AB'}\"\n";
359	print  ELMTS "$onoff {\n";
360	printf ELMTS "$onoff     RA       %10.6f\n", $c1;
361	printf ELMTS "$onoff     Dec      %10.6f\n",$c2;
362	printf ELMTS "$onoff     Distance %10.6f\n",$d;
363    print  ELMTS "$onoff }\n";
364	print  ELMTS "$onoff \n";
365	print  ELMTS "$onoff \"$alt{$hip,'A'}\"\n";
366	print  ELMTS "$onoff {\n";
367	print  ELMTS "$onoff     OrbitBarycenter \"$orbitRef{$hip}\"\n";
368    printf ELMTS "$onoff     SpectralType    %-8s %-40s\n",$spectA,$quA;
369    printf ELMTS "$onoff     AppMag          %-5.2f\n",$Hp1;
370    print  ELMTS "$onoff \n";
371	print  ELMTS "$onoff     EllipticalOrbit {\n";
372	printf ELMTS "$onoff         Period          %10.3f\n",$Period;
373	printf ELMTS "$onoff         SemiMajorAxis   %10.3f \# mass ratio %4.2f : %4.2f\n",$a1,$m1,$m2;
374	printf ELMTS "$onoff         Eccentricity    %10.3f\n",$Eccentricity;
375	printf ELMTS "$onoff         Inclination     %10.3f\n",$Inclination;
376	printf ELMTS "$onoff         AscendingNode   %10.3f\n",$AscendingNode;
377	$ArgOfPeri1 = $ArgOfPeri - 180;
378	if ($ArgOfPeri1 < 0.0) { $ArgOfPeri1 = $ArgOfPeri + 180; }
379	printf ELMTS "$onoff         ArgOfPericenter %10.3f\n",$ArgOfPeri1;
380	printf ELMTS "$onoff         MeanAnomaly     %10.3f\n",$MeanAnomaly;
381	print  ELMTS "$onoff     }\n";
382	print  ELMTS "$onoff }\n\n";
383	print  ELMTS "$onoff \"$alt{$hip,'B'}\"\n";
384	print  ELMTS "$onoff {\n";
385	print  ELMTS "$onoff     OrbitBarycenter \"$orbitRef{$hip}\"\n";
386	printf ELMTS "$onoff     SpectralType    %-8s %-40s\n",$spectB,$quB;
387    printf ELMTS "$onoff     AppMag          %-5.2f\n",$Hp2;
388	print  ELMTS "$onoff \n";
389	print  ELMTS "$onoff     EllipticalOrbit {\n";
390	printf ELMTS "$onoff         Period          %10.3f\n",$Period;
391	printf ELMTS "$onoff         SemiMajorAxis   %10.3f \# mass ratio %4.2f : %4.2f\n",$a2,$m1,$m2;
392	printf ELMTS "$onoff         Eccentricity    %10.3f\n",$Eccentricity;
393	printf ELMTS "$onoff         Inclination     %10.3f\n",$Inclination;
394	printf ELMTS "$onoff         AscendingNode   %10.3f\n",$AscendingNode;
395	printf ELMTS "$onoff         ArgOfPericenter %10.3f\n",$ArgOfPeri;
396	printf ELMTS "$onoff         MeanAnomaly     %10.3f\n",$MeanAnomaly;
397	printf ELMTS "$onoff     }\n";
398	print  ELMTS "$onoff }\n\n";
399	$count++ if !$onoff;
400}
401close (BINDAT);
402
403print STDOUT "\nNumber of enabled visual binaries: $count\n";
404print "\nA component:\n------------\n";
405printf STDOUT "\nspectral types from WDS catalog: => %3d\n",$kAwds;
406printf STDOUT "spectral types from 'spectbins': => %3d\n",$kAsb;
407printf STDOUT "spectral types from HIP catalog: => %3d\n",$kAhip;
408print "\nB component:\n------------\n";
409printf STDOUT "spectral types from WDS catalog: => %3d\n", $kBwds;
410printf STDOUT "spectral types from 'spectbins': => %3d\n",$kBsb;
411printf STDOUT "spectral types from HIP catalog: => %3d\n\n",$kBhip;
412
413
414sub RotOrbits {
415
416my($ra_deg,$del_deg,$P,$a_arcsec,$i,$PA_of_Node,$Epoch_of_peri,$e,$Arg_of_peri
417,$dist_ly) = @_;
418my $del_rad = -$del_deg*$pi/180.0;
419my $ra_rad = $ra_deg*$pi/180.0 - $pi;
420my $eps = $pi/180.0*23.4392911;
421my $ii = $pi/180.0*(90.0 - $i);
422my $om = $pi/180.0*($PA_of_Node - 270.0);
423my $alpha = atan(cos($ii)*cos($pi/180.0*($PA_of_Node))/(sin($ii)*cos($del_rad) -
424cos($ii)*sin($del_rad)*sin($pi/180.0*($PA_of_Node)))) + $ra_rad;
425if( sin($ii)*cos($del_rad)-cos($ii)*sin($del_rad)*sin($pi/180.0*$PA_of_Node) < 0 ) { $alpha = $alpha + $pi };
426my $delta=asin(cos($ii)*cos($del_rad)*sin($pi/180.0*$PA_of_Node)+sin($ii)*sin(
427$del_rad));
428my $lambda=atan((sin($alpha)*cos($eps)+tan($delta)*sin($eps))/cos($alpha));
429if( cos($alpha) < 0 ) { $lambda = $lambda + $pi };
430my $beta = asin(sin($delta)*cos($eps) - cos($delta)*sin($eps)*sin($alpha));
431my $alphaOm = atan(cos($om)/(-sin($del_rad))/sin($om)) + $ra_rad;
432if( -sin($del_rad)*sin($om) < 0 ) { $alphaOm = $alphaOm + $pi };
433my $deltaOm = asin(cos($del_rad)*sin($om));
434my $lambdaOm = atan((sin($alphaOm)*cos($eps) +
435tan($deltaOm)*sin($eps))/cos($alphaOm));
436if( cos($alphaOm) < 0 ) { $lambdaOm = $lambdaOm + $pi };
437my $betaOm = asin(sin($deltaOm)*cos($eps) -
438cos($deltaOm)*sin($eps)*sin($alphaOm));
439my $sign = $betaOm > 0? 1.0:-1.0;
440my $dd = acos(cos($betaOm)*cos($lambdaOm - $lambda - $pi/2.0))*$sign;
441$Period = $P;
442$SemiMajorAxis = $dist_ly*63239.7*tan($pi/180.0*$a_arcsec/3600.0);
443$Eccentricity =  $e;
444$Inclination = 90 - $beta/$pi*180;
445$AscendingNode = $lambda/$pi*180 + 90  - floor(($lambda/$pi*180+90)/360.0)*360;
446$ArgOfPeri = $Arg_of_peri + $dd/$pi*180 - floor(($Arg_of_peri + $dd/$pi*180)/360.0)*360;
447$MeanAnomaly = 360*((2000.0 - $Epoch_of_peri)/$P - floor((2000.0 - $Epoch_of_peri)/$P));
448}
449
450sub clean {
451# squeeze out superfluous spaces
452my($string) = @_;
453$string =~ s/^\s*//;
454$string =~ s/\s*$//;
455$string =~ s/\s+/ /g;
456$string;
457}
458
459# like substr($_,first,last), but one-based.
460sub ss {
461    substr ($_, $_[0]-1, $_[1]-$_[0]+1);
462}
463sub update {
464my($pre, $constell, $comp) = @_;
465# component parser for visual binaries
466my $name = $pre.$constell;
467my ($a, $b) = "";
468
469if (!$comp||$comp eq " "){$a = " A"; $b = " B"; $comp = "";}
470elsif ($comp =~ /(\s?)ABC?P?/){$a = $1."A"; $b = $1."B";}
471elsif ($comp =~ /\b[AB]\b/){$a = $comp."a"; $b = $comp."b";}
472elsif ($comp =~ /(\s?)BC/){$a = $1."B"; $b = $1."C";}
473elsif ($comp =~ /(\s?)([AB])([PC])/){$a = $1.$2; $b = $1.$3;}
474
475$alt  = $alt?$alt.$nx.$name.$comp:$name.$comp;
476$altA = $altA?$altA.$nx.$name.$a:$name.$a;
477$altB = $altB?$altB.$nx.$name.$b:$name.$b;
478}
479
480