Divisional charts
Generate D9 and the other divisional charts, read their whole-sign houses, and map a single longitude into a division.
A divisional chart reworks the same planetary positions through a division of each sign. The D9, for example, splits every sign into nine parts. Ascendant derives all of them from the shared Placements, so asking for more divisions costs very little extra and never changes the D1.
This guide shows how to request divisions, read the result, tell divisional charts apart from D1 in your types, and map one longitude on its own.
Supported divisions
Ascendant supports D1 plus fifteen divisional charts:
| Division | Commonly known as | Division | Commonly known as |
|---|---|---|---|
| D2 | Hora | D20 | Vimsamsa |
| D3 | Drekkana | D24 | Chaturvimsamsa |
| D4 | Chaturthamsa | D27 | Bhamsa |
| D7 | Saptamsa | D30 | Trimsamsa |
| D9 | Navamsa | D40 | Khavedamsa |
| D10 | Dasamsa | D45 | Akshavedamsa |
| D12 | Dwadasamsa | D60 | Shashtiamsa |
| D16 | Shodasamsa |
The type Chart.Division lists exactly these numbers, so TypeScript rejects any
other value at compile time.
Request divisions
Pass the divisions you want as the second argument to Chart.generate:
import { Chart, Runtime } from "astro-ascendant";
import { DateTime, ManagedRuntime } from "effect";
const runtime = ManagedRuntime.make(Runtime.MainLayer);
const located = Chart.LocatedMoment.make({
moment: Chart.Moment.make({ date: DateTime.makeUnsafe("2000-01-01T12:00:00Z") }),
latitude: 12.9716,
longitude: 77.5946,
});
const calculation = await runtime.runPromise(Chart.generate(located, [9, 10]));The result's charts always starts with D1, followed by the divisions you asked
for. They come back in numeric order with duplicates removed, so
[10, 9, 9] gives D1, D9, and D10.
To get every divisional chart at once, list them all:
const everything = [2, 3, 4, 7, 9, 10, 12, 16, 20, 24, 27, 30, 40, 45, 60] as const;
const calculation = await runtime.runPromise(Chart.generate(located, everything));D1 versus a divisional chart
calculation.charts is typed as a D1 chart followed by any number of divisional
charts, so you can split it directly:
const [d1, ...divisional] = calculation.charts;
d1.angles; // chart angles, only on D1
d1.rulingPlanets; // only on D1
d1.houses[1].subLord; // KP lords, only on D1When you have a Chart.Chart, a value that could be either, check its division
to narrow it:
const describe = (chart: Chart.Chart) =>
chart.division === 1 ? `D1 with ${chart.rulingPlanets.length} ruling planets` : `D${chart.division}`;The two kinds differ like this:
| D1 chart | Divisional chart | |
|---|---|---|
| Houses start at | The house system's cusps | The start of each sign, counted from the mapped Lagna |
| Uses the house system | Yes | No |
| Angles, KP lords, significations, ruling planets | Yes | No |
| Houses per chart | 12 | 12 |
Divisional charts have no KP data because those belong to source longitudes, and a mapped longitude is not a source longitude. Their houses are whole signs whatever house system you chose.
Read a divisional chart
Each chart has twelve houses, keyed 1 to 12. A divisional house has these
fields:
| Field | Meaning |
|---|---|
sign | The sign of the house. |
cusp | Where the house begins, which is the start of its sign (for example 240 for Sagittarius). |
signLord | The lord of that sign. |
significations | The house's classical significations. |
planets | The planets in the house, with their mapped degree and sign. |
lagna | The mapped Lagna, in the house that holds it. Otherwise null. |
A chart also records its division and its provenance, which for every
divisional chart is the Parashari whole-sign-from-mapped-lagna method.
To find where a planet sits, scan the houses. The data is one-directional on purpose: a house lists its planets, but a planet does not carry its house.
const signOf = (chart: Chart.Chart, planet: Chart.Planets) =>
Object.values(chart.houses).find((house) =>
house.planets.some((placed) => placed.name === planet),
)?.sign;
const d9 = calculation.charts.find((chart) => chart.division === 9);
const sunInD9 = d9 && signOf(d9, "Sun"); // "Leo" for the birth aboveExample: one birth through every division
For the birth above, the Lagna and Sun land in these signs:
| Division | Lagna | Sun |
|---|---|---|
| D1 | Gemini | Sagittarius |
| D2 | Leo | Cancer |
| D3 | Gemini | Aries |
| D4 | Virgo | Gemini |
| D7 | Leo | Pisces |
| D9 | Sagittarius | Leo |
| D10 | Virgo | Taurus |
| D12 | Virgo | Gemini |
| D16 | Taurus | Leo |
| D20 | Aquarius | Cancer |
| D24 | Pisces | Virgo |
| D27 | Gemini | Gemini |
| D30 | Aquarius | Sagittarius |
| D40 | Aries | Aquarius |
| D45 | Aquarius | Sagittarius |
| D60 | Capricorn | Virgo |
The D1 uses the default KP settings, Placidus houses, but the sign of each planet is the same under any house system. The house system changes only D1's cusps.
Map one longitude
If you need only the divisional position of a single longitude, skip the chart
and use getDivisionalTarget:
import { getDivisionalTarget } from "astro-ascendant/chart";
import { Effect } from "effect";
const target = await runtime.runPromise(getDivisionalTarget(256.5924, 9));
// {
// signIndex: 4, // 0 = Aries, so 4 = Leo
// degree: 29.33, // degree within the target sign
// longitude: 149.33, // the mapped longitude
// }For the Sun at 256.59° in D1, the D9 target is Leo at 29.33°, which matches the
Sun's D9 sign in the table above. For division 1, the function returns the
source position unchanged. The same function is also exported from
astro-ascendant/chart/divisional-mapping.
Where divisions are used
- Karakamsha reads the D9 sign of each Atmakaraka planet. See Jaimini calculations.
- Parashari readings use divisional charts for the quality of a result, with the Lahiri and whole-sign settings from Choose a school and settings.
When it fails
- An unsupported division number is a compile-time error. If a value gets past
the types, for example through a cast,
Chart.generateends in a defect, not a typed failure, so validate numbers from untrusted input before you pass them in. Chart.generatefails with aChartCalculationErrorat the"houses"stage if the chosen house system's D1 cusps do not divide the circle into twelve houses.getDivisionalTargetfails with aDivisionalMappingErrorwhen the longitude cannot be used.
See Errors and typed failures for how to handle them.
