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