Fix parsing and display of luminosity classes Ia-0, Ia, and Ib

- Allow spaces before luminosity class in stc file
- Allow Ia-0 to be spelled "Ia-0" (as displayed), "Ia0" (as previously), or
  "I-a0" (previous display format) in stc file
- Remove str() and ostream << operators on StellarClass (only used in tests)
pull/1351/head
Andrew Tribick 2022-02-18 23:52:46 +01:00 committed by ajtribick
parent d2f53d0a56
commit 2f77629216
6 changed files with 125 additions and 106 deletions

View File

@ -387,7 +387,7 @@ static float rotperiod_M[3][10] =
const char* LumClassNames[StellarClass::Lum_Count] = {
"I-a0", "I-a", "I-b", "II", "III", "IV", "V", "VI", ""
"Ia-0", "Ia", "Ib", "II", "III", "IV", "V", "VI", ""
};
const char* SubclassNames[11] = {

View File

@ -57,62 +57,6 @@ Color StellarClass::getApparentColor(StellarClass::SpectralClass sc) const
}
}
// The << method of converting the stellar class to a string is
// preferred, but it's not always practical, especially when you've
// got a completely broken implementation of stringstreams to
// deal with (*cough* gcc *cough*).
string StellarClass::str() const
{
char s0, s1;
const char* s2 = "";
switch (getStarType())
{
case StellarClass::WhiteDwarf:
return "WD";
case StellarClass::NeutronStar:
return "Q";
case StellarClass::BlackHole:
return "X";
case StellarClass::NormalStar:
s0 = "OBAFGKMRSNWWW?LTYC"[(unsigned int) getSpectralClass()];
s1 = "0123456789"[getSubclass()];
switch (getLuminosityClass())
{
case StellarClass::Lum_Ia0:
s2 = " I-a0";
break;
case StellarClass::Lum_Ia:
s2 = " I-a";
break;
case StellarClass::Lum_Ib:
s2 = " I-b";
break;
case StellarClass::Lum_II:
s2 = " II";
break;
case StellarClass::Lum_III:
s2 = " III";
break;
case StellarClass::Lum_IV:
s2 = " IV";
break;
case StellarClass::Lum_V:
s2 = " V";
break;
case StellarClass::Lum_VI:
s2 = " VI";
break;
default: break; // Do nothing, but prevent GCC4 warnings (Beware: potentially dangerous)
}
return fmt::sprintf("%c%c%s", s0, s1, s2);
}
return "?";
}
uint16_t
StellarClass::packV1() const
{
@ -238,14 +182,6 @@ StellarClass::unpackV2(uint16_t st)
}
ostream& operator<<(ostream& os, const StellarClass& sc)
{
os << sc.str();
return os;
}
bool operator<(const StellarClass& sc0, const StellarClass& sc1)
{
return sc0.packV2() < sc1.packV2();
@ -273,6 +209,7 @@ enum ParseState
LumClassVState,
LumClassIdashState,
LumClassIaState,
LumClassIdashaState,
WDTypeState,
WDExtendedTypeState,
WDSubclassState,
@ -482,6 +419,8 @@ StellarClass::parse(const string& st)
case 'V':
state = LumClassVState;
break;
case ' ':
break;
default:
state = EndState;
break;
@ -535,7 +474,8 @@ StellarClass::parse(const string& st)
switch (c)
{
case 'a':
state = LumClassIaState;
state = LumClassIdashaState;
i++;
break;
case 'b':
lumClass = StellarClass::Lum_Ib;
@ -549,6 +489,24 @@ StellarClass::parse(const string& st)
break;
case LumClassIaState:
switch (c)
{
case '0':
lumClass = StellarClass::Lum_Ia0;
state = EndState;
break;
case '-':
state = LumClassIdashaState;
i++;
break;
default:
lumClass = StellarClass::Lum_Ia;
state = EndState;
break;
}
break;
case LumClassIdashaState:
switch (c)
{
case '0':

View File

@ -98,8 +98,6 @@ public:
Color getApparentColor() const;
Color getApparentColor(StellarClass::SpectralClass sc) const;
std::string str() const;
static StellarClass parse(const std::string&);
friend bool operator<(const StellarClass& sc0, const StellarClass& sc1);
@ -123,8 +121,6 @@ private:
};
std::ostream& operator<<(std::ostream& os, const StellarClass& sc);
// A rough ordering of stellar classes, from 'early' to 'late' . . .
// Useful for organizing a list of stars by spectral class.
bool operator<(const StellarClass& sc0, const StellarClass& sc1);

View File

@ -161,13 +161,13 @@ void printStellarClass(uint16_t sc, ostream& out)
switch (luminosityClass) //without this questionmark a nullchar is written to the file
{ //causing that a dump of stardb is not a textfile but binary.
case StellarClass::Lum_Ia0:
out << "I-a0";
out << "Ia-0";
break;
case StellarClass::Lum_Ia:
out << "I-a";
out << "Ia";
break;
case StellarClass::Lum_Ib:
out << "I-b";
out << "Ib";
break;
case StellarClass::Lum_II:
out << "II";

View File

@ -111,13 +111,13 @@ void printStellarClass(uint16_t sc, ostream& out)
switch (luminosityClass)
{
case StellarClass::Lum_Ia0:
out << "I-a0";
out << "Ia-0";
break;
case StellarClass::Lum_Ia:
out << "I-a";
out << "Ia";
break;
case StellarClass::Lum_Ib:
out << "I-b";
out << "Ib";
break;
case StellarClass::Lum_II:
out << "II";

View File

@ -1,22 +1,22 @@
#include <celengine/stellarclass.h>
#include <cstdint>
#include <catch.hpp>
#define CHECK_NORMAL_STAR(u, _class, _str) \
#include <celengine/stellarclass.h>
#define CHECK_NORMAL_STAR(u, _class) \
REQUIRE(u.getStarType() == StellarClass::NormalStar); \
REQUIRE(u.getSpectralClass() == _class); \
REQUIRE(u.getSubclass() == 5); \
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Ia0); \
REQUIRE(u.str() == _str);
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Ia0);
#define CHECK_WHITE_DWARF(u, _class, _str) \
#define CHECK_WHITE_DWARF(u, _class) \
REQUIRE(u.getStarType() == StellarClass::WhiteDwarf); \
REQUIRE(u.getSpectralClass() == _class); \
REQUIRE(u.getSubclass() == 5); \
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Unknown); \
REQUIRE(u.str() == _str);
REQUIRE(u.getLuminosityClass() == StellarClass::Lum_Unknown);
TEST_CASE("StellarClass", "[StellarClass]")
TEST_CASE("StellarClass packing", "[StellarClass]")
{
SECTION("StellarClass::Spectral_WO")
{
@ -25,21 +25,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_WO, "W5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_WO);
}
}
@ -50,21 +50,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Y, "Y5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Y);
}
}
@ -75,21 +75,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown, "?5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_Unknown);
}
}
@ -100,21 +100,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C, "C5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C, "C5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_C);
}
}
@ -125,21 +125,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L, "L5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L, "L5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_L);
}
}
@ -151,21 +151,21 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T, "T5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T, "T5 I-a0");
CHECK_NORMAL_STAR(u, StellarClass::Spectral_T);
}
}
@ -176,22 +176,87 @@ TEST_CASE("StellarClass", "[StellarClass]")
5,
StellarClass::Lum_Ia0);
uint16_t packed;
std::uint16_t packed;
StellarClass u;
SECTION("Packed as V1")
{
packed = sc.packV1();
REQUIRE(u.unpackV1(packed));
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO, "WD");
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO);
}
SECTION("Packed as V2")
{
packed = sc.packV2();
REQUIRE(u.unpackV2(packed));
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO, "WD");
CHECK_WHITE_DWARF(u, StellarClass::Spectral_DO);
}
}
}
TEST_CASE("StellarClass parsing", "[StellarClass]")
{
SECTION("Luminosity class I-a0")
{
StellarClass sc = StellarClass::parse("A9I-a0");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_A);
REQUIRE(sc.getSubclass() == 9);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia0);
}
SECTION("Luminosity class Ia-0")
{
StellarClass sc = StellarClass::parse("K Ia-0");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_K);
REQUIRE(sc.getSubclass() == StellarClass::Subclass_Unknown);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia0);
}
SECTION("Luminosity class Ia0")
{
StellarClass sc = StellarClass::parse("M3Ia0");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_M);
REQUIRE(sc.getSubclass() == 3);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia0);
}
SECTION("Luminosity class Ia")
{
StellarClass sc = StellarClass::parse("F7Ia");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_F);
REQUIRE(sc.getSubclass() == 7);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia);
}
SECTION("Luminosity class I-a")
{
StellarClass sc = StellarClass::parse("G4 I-a");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_G);
REQUIRE(sc.getSubclass() == 4);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ia);
}
SECTION("Luminosity class Ib")
{
StellarClass sc = StellarClass::parse("B6 Ib");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_B);
REQUIRE(sc.getSubclass() == 6);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ib);
}
SECTION("Luminosity class I-b")
{
StellarClass sc = StellarClass::parse("O5I-b");
REQUIRE(sc.getStarType() == StellarClass::NormalStar);
REQUIRE(sc.getSpectralClass() == StellarClass::Spectral_O);
REQUIRE(sc.getSubclass() == 5);
REQUIRE(sc.getLuminosityClass() == StellarClass::Lum_Ib);
}
}