read_stars Function

private function read_stars(self) result(ok)

Read the stars of the catalog into self%stars.

Arguments

Type IntentOptional Attributes Name
type(SkySphere), intent(inout) :: self

Return Value logical


Calls

proc~~read_stars~~CallsGraph proc~read_stars read_stars proc~add_name add_name proc~read_stars->proc~add_name proc~after_fields after_fields proc~read_stars->proc~after_fields proc~find_data_file find_data_file proc~read_stars->proc~find_data_file proc~raw_size raw_size proc~read_stars->proc~raw_size proc~size_of size_of proc~read_stars->proc~size_of proc~star_to_point star_to_point proc~read_stars->proc~star_to_point proc~find_in_dirs find_in_dirs proc~find_data_file->proc~find_in_dirs proc~star_to_point->proc~raw_size

Called by

proc~~read_stars~~CalledByGraph proc~read_stars read_stars proc~set_star_data SkySphere%set_star_data proc~set_star_data->proc~read_stars

Source Code

    logical function read_stars(self) result(ok)
        type(SkySphere), intent(inout) :: self
        character(len=:), allocatable :: path
        character(len=1024) :: line
        character(len=64) :: label
        real(wp) :: ra_limit, ra, dec, mag, ci, raw_min, raw_max, ratio, size, dim, dir(3), rgb(3)
        real(c_float), allocatable :: tmp(:,:)
        integer :: unit, status, k

        ok = .false.
        path = find_data_file(self%catalog)
        if (len(path) == 0) then
            write(*, '(a)') 'vkframes: star catalog '//self%catalog//' not found (set VKFRAMES_DATA_PATH)'
            return
        end if
        open(newunit=unit, file=path, status='old', action='read', iostat=status)
        if (status /= 0) then
            write(*, '(a)') 'vkframes: could not open the star catalog '//path
            return
        end if

        ! right ascension in hours, unless the header says "ra_<limit>"
        ra_limit = 24.0_wp
        read(unit, '(a)', iostat=status) line
        if (status == 0) then
            read(line, *, iostat=status) label
            k = index(label, '_')
            if (status == 0 .and. k > 0) then
                read(label(k+1:), *, iostat=status) ra_limit
                if (status /= 0 .or. ra_limit <= 0.0_wp) ra_limit = 24.0_wp
            end if
        end if

        ! sizes from brightness, scaled from [raw_min, raw_max] to [min_size, max_size]
        raw_max = raw_size(self%min_mag)                ! the brightest: the largest
        raw_min = raw_size(self%max_mag)
        if (.not. allocated(self%stars)) allocate(self%stars(8, min(self%max_stars, 1024)))
        self%n_stars = 0
        self%n_names = 0
        self%mag_range = [huge(1.0_wp), -huge(1.0_wp)]
        do while (self%n_stars < self%max_stars)
            read(unit, '(a)', iostat=status) line
            if (status /= 0) exit
            read(line, *, iostat=status) ra, dec, mag, ci
            if (status /= 0) then
                read(line, *, iostat=status) ra, dec, mag
                if (status /= 0) cycle
                ci = 0.0_wp
            end if
            if (mag < self%min_mag .or. mag > self%max_mag) cycle

            call star_to_point(ra / ra_limit * 2.0_wp * pi, dec * pi / 180.0_wp, mag, ci, dir, rgb, size)
            ratio = 0.0_wp
            if (raw_max /= raw_min) then
                ratio = (size - raw_min) / (raw_max - raw_min)
                size = self%min_size + ratio * (self%max_size - self%min_size)
            else
                size = self%min_size
            end if
            dim = max(self%min_dim, ratio)            ! big stars at full color, small ones dimmed

            if (self%n_stars == size_of(self%stars)) then
                allocate(tmp(8, min(self%max_stars, 2 * self%n_stars)))
                tmp(:, 1:self%n_stars) = self%stars(:, 1:self%n_stars)
                call move_alloc(tmp, self%stars)
            end if
            self%n_stars = self%n_stars + 1
            self%stars(:, self%n_stars) = real([dir, size, dim * rgb, 1.0_wp], c_float)
            self%mag_range = [min(self%mag_range(1), mag), max(self%mag_range(2), mag)]
            call add_name(self, after_fields(line, 4), mag)
        end do
        close(unit)
        if (self%n_stars == 0) self%mag_range = 0.0_wp
        ok = .true.
    end function read_stars