diff --git a/src/Stingray.jl b/src/Stingray.jl index 6d8e74f..fc305ad 100644 --- a/src/Stingray.jl +++ b/src/Stingray.jl @@ -33,6 +33,9 @@ export bin_intervals_from_gtis include("utils.jl") include("events.jl") +include("lightcurve.jl") + export readevents, EventList, DictMetadata -end +export create_lightcurve, LightCurve +end # module Stingray diff --git a/src/events.jl b/src/events.jl index 70c54c7..52cac9f 100644 --- a/src/events.jl +++ b/src/events.jl @@ -82,4 +82,4 @@ function readevents(path; T = Float64) metadata = DictMetadata(headers) return EventList{T}(path, times, energies, metadata) -end +end \ No newline at end of file diff --git a/src/lightcurve.jl b/src/lightcurve.jl new file mode 100644 index 0000000..014f307 --- /dev/null +++ b/src/lightcurve.jl @@ -0,0 +1,50 @@ +""" + LightCurve{T} + +A structure representing a light curve, which is a time series of event counts. + +## Fields + +- `timebins::Vector{T}`: Time bins for the light curve. +- `counts::Vector{T}`: Number of events in each time bin. +- `count_error::Vector{T}`: Error estimate for each bin. +- `err_method::Symbol`: Method used for error estimation (`:poisson`). +""" +struct LightCurve{T} + timebins::Vector{T} + counts::Vector{T} + count_error::Vector{T} + err_method::Symbol +end + +""" + create_lightcurve(eventlist::EventList{T}, bin_size::T; err_method::Symbol=:poisson) + +Generate a light curve from an EventList by binning event times. + +## Arguments + +- `eventlist::EventList{T}`: The input event list. +- `bin_size::T`: The size of each time bin. +- `err_method::Symbol`: The method for error estimation (`:poisson`). + +## Returns + +A LightCurve instance containing binned event counts. + +## Notes + +- The function bins event times into intervals of `bin_size`. +- Errors are estimated using Poisson statistics. +""" +function create_lightcurve(eventlist::EventList{T}, bin_size::T; err_method::Symbol=:poisson) where T + if err_method ∉ (:poisson,) + throw(ArgumentError("Invalid error method: $err_method. Supported methods: :poisson")) + end + min_time,max_time = extrema(eventlist.times) + bins = min_time:bin_size:max_time + hist = fit(Histogram, eventlist.times, bins) + counts = hist.weights + errors = sqrt.(counts) + return LightCurve{T}(bins, counts, errors, err_method) +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 4275ebf..e54e86d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,3 +5,5 @@ using Logging include("test_fourier.jl") include("test_gti.jl") include("test_events.jl") +include("test_lightcurve.jl") + diff --git a/test/test_lightcurve.jl b/test/test_lightcurve.jl new file mode 100644 index 0000000..6ab689f --- /dev/null +++ b/test/test_lightcurve.jl @@ -0,0 +1,42 @@ +@testset "LightCurve Tests" begin + test_dir = mktempdir() + sample_file = joinpath(test_dir, "sample_lightcurve.fits") + + # Sample Data + times = [0.1, 0.5, 1.2, 2.4, 3.0, 4.1, 5.6, 6.8, 7.9, 9.2] + energies = [100, 200, 150, 180, 250, 300, 275, 220, 190, 210] + metadata = Dict("TELESCOP" => "TestScope", "MISSION" => "TestMission") + + # Create a sample FITS file for testing + f = FITS(sample_file, "w") + write(f, Int[]) # Empty primary array + table = Dict("TIME" => times, "ENERGY" => energies) + write(f, table) + close(f) + + @test isfile(sample_file) + + # test reading the sample file + eventlist = readevents(sample_file) + @test eventlist.filename == sample_file + @test length(eventlist.times) == length(times) + @test length(eventlist.energies) == length(energies) + + # expected counts for different bin sizes + bin_sizes = [1.0, 0.5, 2.0, 1.3] + expected_counts = [ + [2.0, 1.0, 2.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0], + [2.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0], + [3.0, 2.0, 2.0, 2.0], + [3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] + ] + + # Test different bin sizes + for (bin_size, expected) in zip(bin_sizes, expected_counts) + lightcurve = create_lightcurve(eventlist, bin_size, err_method=:poisson) + + @test lightcurve.err_method == :poisson + @test length(lightcurve.timebins) == length(lightcurve.counts) + 1 #bin count fix + @test lightcurve.counts == expected + end +end \ No newline at end of file