In [1]:
Copied!
from vcat import ImageData, ImageCube
from vcat.plots.kinematic_plot import KinematicPlot
import glob
from IPython.display import Video
from vcat import ImageData, ImageCube
from vcat.plots.kinematic_plot import KinematicPlot
import glob
from IPython.display import Video
2025-10-17 17:41:48,964 - INFO - vcat - Logging initialized. Log file: Console only 2025-10-17 17:41:48,965 - INFO - vcat - Using config file VCAT_CONFIG=/home/flep98/VCAT/config.yaml 2025-10-17 17:41:48,965 - INFO - vcat - Using DIFMAP Path: /usr/local/difmap/uvf_difmap_2.5g/ 2025-10-17 17:41:48,966 - INFO - vcat - Using uv-weighting: [0, -1] 2025-10-17 17:41:48,966 - INFO - vcat - Using font: Quicksand 2025-10-17 17:41:48,966 - INFO - vcat - Using noise method: Histogram Fit 2025-10-17 17:41:48,966 - INFO - vcat - Using modelfit error method: Schinzel12 2025-10-17 17:41:48,967 - INFO - vcat - Using resolution limit method: Kovalev05
Thank you for using VCAT. Have fun with VLBI! If you are using this package please cite VCAT Team et al. 2025 ....
In [2]:
Copied!
#Let's load an image with modelfit first
dataU=ImageData("../dataset_example/3C111_U_2014_05_08/3C111_U_2014_05_08.fits",
model="../dataset_example/3C111_U_2014_05_08/3C111_U_2014_05_08.mfit") #this can be either .fits or .mod file
#let's print some info and plot it with the modelcomps and automatically associated ids
print(dataU)
dataU.plot(plot_model=True,plot_comp_ids=True,xlim=[10,-5],ylim=[-5,10])
#Let's load an image with modelfit first
dataU=ImageData("../dataset_example/3C111_U_2014_05_08/3C111_U_2014_05_08.fits",
model="../dataset_example/3C111_U_2014_05_08/3C111_U_2014_05_08.mfit") #this can be either .fits or .mod file
#let's print some info and plot it with the modelcomps and automatically associated ids
print(dataU)
dataU.plot(plot_model=True,plot_comp_ids=True,xlim=[10,-5],ylim=[-5,10])
2025-10-17 17:41:49,643 - WARNING - vcat - No .uvfits file or difmap path provided. Calculating modelfit component SNR based on the clean map only.
Image of the source 3C111 at frequency 15.2 GHz on 2014-05-08
Total cleaned flux: 3474.345 mJy
Image Noise: 0.252 mJy using method 'Histogram Fit'
No polarization data loaded.
Model information:
Model Flux: 3472.798 mJy
Number of Components: 11
Out[2]:
<vcat.plots.fits_image.FitsImage at 0x7b29c91f8490>
In [3]:
Copied!
#Let's modify the component IDs and assign them to our liking.
#Let's first use a list of the old comp_ids
old_ids=[0,1,2,3,4,5,6,7,8,9,10,11]
#and now the new IDs that we want to assign them
new_ids=[11,10,9,8,7,6,5,4,3,2,1,0]
#and finally execute the change
dataU.change_component_ids(old_ids,new_ids)
#we also want to assign the core component to be comp 1
dataU.set_core_component(1)
#let's plot it again
dataU.plot(plot_model=True,plot_comp_ids=True,xlim=[10,-5],ylim=[-5,10])
#Let's modify the component IDs and assign them to our liking.
#Let's first use a list of the old comp_ids
old_ids=[0,1,2,3,4,5,6,7,8,9,10,11]
#and now the new IDs that we want to assign them
new_ids=[11,10,9,8,7,6,5,4,3,2,1,0]
#and finally execute the change
dataU.change_component_ids(old_ids,new_ids)
#we also want to assign the core component to be comp 1
dataU.set_core_component(1)
#let's plot it again
dataU.plot(plot_model=True,plot_comp_ids=True,xlim=[10,-5],ylim=[-5,10])
Out[3]:
<vcat.plots.fits_image.FitsImage at 0x7b29bc2258b0>
In [4]:
Copied!
#Let's check if the core assignment worked
print(dataU.get_core_component())
#Let's check if the core assignment worked
print(dataU.get_core_component())
Component with ID 1 at frequency 15.2 GHz x: -0.25 mas, y:-0.15 mas Maj: 0.06 mas, Min: 0.06 mas, PA: -28.300800323486328 ° Flux: 494.0820038318634 mJy, Distance to Core: 0.00 mas
In [5]:
Copied!
#Similarly we can get info about any other component
print(dataU.get_component(10))
#Similarly we can get info about any other component
print(dataU.get_component(10))
Component with ID 10 at frequency 15.2 GHz x: 6.32 mas, y:3.58 mas Maj: 0.71 mas, Min: 0.71 mas, PA: 0.0 ° Flux: 55.47590181231499 mJy, Distance to Core: 7.55 mas
In [6]:
Copied!
#Let's load some more data
dataC=ImageData("../dataset_example/3C111_C_2014_05_08/3C111_C_2014_05_08.fits",
model="../dataset_example/3C111_C_2014_05_08/3C111_C_2014_05_08.mfit")
dataQ=ImageData("../dataset_example/3C111_Q_2014_05_08/3C111_Q_2014_05_08.fits",
model="../dataset_example/3C111_Q_2014_05_08/3C111_Q_2014_05_08.mfit")
dataW=ImageData("../dataset_example/3C111_W_2014_05_08/3C111_W_2014_05_08.fits",
model="../dataset_example/3C111_W_2014_05_08/3C111_W_2014_05_08.mfit")
dataX=ImageData("../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.fits",
model="../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.mfit")
#Now we have to manually associate the components to the right ID, this is a bit tedious and will soon be replaced with a GUI version
#For now, let's use the following associations:
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=0
dataQ.change_component_ids(old_ids,new_ids)
dataQ.set_core_component(core_id)
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=0
dataW.change_component_ids(old_ids,new_ids)
dataW.set_core_component(core_id)
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=4
dataX.change_component_ids(old_ids,new_ids)
dataX.set_core_component(core_id)
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=6
dataC.change_component_ids(old_ids,new_ids)
dataC.set_core_component(core_id)
#Let's load some more data
dataC=ImageData("../dataset_example/3C111_C_2014_05_08/3C111_C_2014_05_08.fits",
model="../dataset_example/3C111_C_2014_05_08/3C111_C_2014_05_08.mfit")
dataQ=ImageData("../dataset_example/3C111_Q_2014_05_08/3C111_Q_2014_05_08.fits",
model="../dataset_example/3C111_Q_2014_05_08/3C111_Q_2014_05_08.mfit")
dataW=ImageData("../dataset_example/3C111_W_2014_05_08/3C111_W_2014_05_08.fits",
model="../dataset_example/3C111_W_2014_05_08/3C111_W_2014_05_08.mfit")
dataX=ImageData("../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.fits",
model="../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.mfit")
#Now we have to manually associate the components to the right ID, this is a bit tedious and will soon be replaced with a GUI version
#For now, let's use the following associations:
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=0
dataQ.change_component_ids(old_ids,new_ids)
dataQ.set_core_component(core_id)
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=0
dataW.change_component_ids(old_ids,new_ids)
dataW.set_core_component(core_id)
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=4
dataX.change_component_ids(old_ids,new_ids)
dataX.set_core_component(core_id)
old_ids=[1,2,3]
new_ids=[2,3,1]
core_id=6
dataC.change_component_ids(old_ids,new_ids)
dataC.set_core_component(core_id)
2025-10-17 17:41:58,569 - WARNING - vcat - No .uvfits file or difmap path provided. Calculating modelfit component SNR based on the clean map only. 2025-10-17 17:42:00,219 - WARNING - vcat - No .uvfits file or difmap path provided. Calculating modelfit component SNR based on the clean map only. 2025-10-17 17:42:01,533 - WARNING - vcat - No .uvfits file or difmap path provided. Calculating modelfit component SNR based on the clean map only. 2025-10-17 17:42:02,779 - WARNING - vcat - No .uvfits file or difmap path provided. Calculating modelfit component SNR based on the clean map only.
In [7]:
Copied!
#Now that all components were correctly identified, we will load the images as an ImageCube for easier handling
im_cube=ImageCube([dataC,dataX,dataU,dataQ,dataW])
#we will load a file which already has all the correct component associations
im_cube.import_component_association("../dataset_example/comp_association_3C111.csv")
#let's double check the associations
im_cube.plot(plot_model=True,plot_comp_ids=True)
#Now that all components were correctly identified, we will load the images as an ImageCube for easier handling
im_cube=ImageCube([dataC,dataX,dataU,dataQ,dataW])
#we will load a file which already has all the correct component associations
im_cube.import_component_association("../dataset_example/comp_association_3C111.csv")
#let's double check the associations
im_cube.plot(plot_model=True,plot_comp_ids=True)
2025-10-17 17:42:04,212 - INFO - vcat - Importing component associations from ../dataset_example/comp_association_3C111.csv.
Out[7]:
<vcat.plots.multi_fits_image.MultiFitsImage at 0x7b29b8f95310>
In [8]:
Copied!
#We can have a look at different jet profiles, based on the modelfits.
#Let's say we want to plot the jet collimation profile, this can be done using:
x,y,y_err=im_cube.get_model_profile("maj",core_position=[0,0]) #other options are 'flux','tb'
#We can have a look at different jet profiles, based on the modelfits.
#Let's say we want to plot the jet collimation profile, this can be done using:
x,y,y_err=im_cube.get_model_profile("maj",core_position=[0,0]) #other options are 'flux','tb'
In [9]:
Copied!
#So far we have looked at a single-epoch multi-frequency dataset
#Let's also have a look at a single-frequency multi-epoch dataset
from vcat import ImageCube
import glob
#We will load some MOJAVE epochs of 0506+056 where modelfits were performed
uvf_files=glob.glob("../dataset_example/0506+056_kinematic/*.uvf")
model_files=glob.glob("../dataset_example/0506+056_kinematic/*fits")
#additionally, we set fit_comp_polarization to true,
#since we want VCAT to automatically determine the polarization properties of the modelcomps
#and their errors with fit_comp_pol_errors
#NOTE the polarization calculation takes some time! For quicker processing set those to False!
fit_comp_polarization=True
fit_comp_pol_errors=True
#Let's load them as an ImageCube
im_cube=ImageCube().import_files(uvf_files=uvf_files,model_fits_files=model_files,
fit_comp_polarization=fit_comp_polarization,
fit_comp_pol_errors=True)
#So far we have looked at a single-epoch multi-frequency dataset
#Let's also have a look at a single-frequency multi-epoch dataset
from vcat import ImageCube
import glob
#We will load some MOJAVE epochs of 0506+056 where modelfits were performed
uvf_files=glob.glob("../dataset_example/0506+056_kinematic/*.uvf")
model_files=glob.glob("../dataset_example/0506+056_kinematic/*fits")
#additionally, we set fit_comp_polarization to true,
#since we want VCAT to automatically determine the polarization properties of the modelcomps
#and their errors with fit_comp_pol_errors
#NOTE the polarization calculation takes some time! For quicker processing set those to False!
fit_comp_polarization=True
fit_comp_pol_errors=True
#Let's load them as an ImageCube
im_cube=ImageCube().import_files(uvf_files=uvf_files,model_fits_files=model_files,
fit_comp_polarization=fit_comp_polarization,
fit_comp_pol_errors=True)
2025-10-17 17:42:17,028 - INFO - vcat - Importing images: Processing: 100%|████████████████████████████████████████████████████████████████████████████████████████████| 11/11 [05:07<00:00, 27.98s/it] 2025-10-17 17:47:24,851 - INFO - vcat - Imported 11 images successfully.
In [10]:
Copied!
#We have already used the VCATNIP GUI to assign the component numbers, so we can load a component_info.csv file
import numpy as np
im_cube.import_component_association("../dataset_example/0506+056_kinematic/component_info.csv")
#We have already used the VCATNIP GUI to assign the component numbers, so we can load a component_info.csv file
import numpy as np
im_cube.import_component_association("../dataset_example/0506+056_kinematic/component_info.csv")
2025-10-17 17:47:24,861 - INFO - vcat - Importing component associations from ../dataset_example/0506+056_kinematic/component_info.csv.
In [11]:
Copied!
#We now have an ImageCube with correctly labeled components, that means we can call the kinematic fit functions
#Let's do a simple 1d linear fit of the core distance vs time
fit=im_cube.get_speed(order=1,show_plot=True,plot_errors=True)
#The returned fit parameter includes useful information about the apparent speed, critical Doppler_factor etc. of each component
print(fit)
#We now have an ImageCube with correctly labeled components, that means we can call the kinematic fit functions
#Let's do a simple 1d linear fit of the core distance vs time
fit=im_cube.get_speed(order=1,show_plot=True,plot_errors=True)
#The returned fit parameter includes useful information about the apparent speed, critical Doppler_factor etc. of each component
print(fit)
/home/flep98/anaconda3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:803: RuntimeWarning: divide by zero encountered in divide
transform = 1.0 / sigma
/home/flep98/anaconda3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:488: RuntimeWarning: invalid value encountered in multiply
return transform * (func(xdata, *params) - ydata)
/home/flep98/anaconda3/lib/python3.9/site-packages/scipy/optimize/_minpack_py.py:881: OptimizeWarning: Covariance of the parameters could not be estimated
warnings.warn('Covariance of the parameters could not be estimated',
/home/flep98/anaconda3/lib/python3.9/site-packages/astropy/units/quantity.py:611: RuntimeWarning: invalid value encountered in multiply
result = super().__array_ufunc__(function, method, *arrays, **kwargs)
/home/flep98/VCAT/vcat/kinematics.py:554: RuntimeWarning: invalid value encountered in divide
chi2 = np.sum(((dist - y_model) / dist_err) ** 2)
[{'name': 'Component 0', 'speed': 0.0, 'speed_err': inf, 'y0': -0.0, 'y0_err': -0.0, 'beta_app': 0.0, 'beta_app_err': nan, 'd_crit': 1.0, 'd_crit_err': nan, 'dist_0_est': -0.0, 't_0': 2010.5260273972603, 't_0_err': inf, 'red_chi_sqr': nan, 't_mid': 2013.7029044090127, 'linear_fit': array([ 0. , 2010.5260274]), 'cov_matrix': array([[inf, inf],
[inf, inf]])}, {'name': 'Component 1', 'speed': 1.321797671308369e-07, 'speed_err': 0.010148179131005082, 'y0': 0.38026096751506233, 'y0_err': -1.2924763312956372e-08, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': 0.38026096751506233, 't_0': -2876847.007444525, 't_0_err': 220296742758.01096, 'red_chi_sqr': 0.6251664841425155, 't_mid': 2013.7029044090127, 'linear_fit': array([ 1.32179767e-07, -2.87684701e+06]), 'cov_matrix': array([[1.02985540e-04, 2.23561081e+09],
[2.23561081e+09, 4.85306549e+22]])}, {'name': 'Component 2', 'speed': 0.006861381386113264, 'speed_err': 0.02570771999128605, 'y0': -12.239079816631516, 'y0_err': -28.616075355945885, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': -12.239079816631516, 't_0': 1783.763228990909, 't_0_err': 861.2259411150854, 'red_chi_sqr': 0.9979808322853297, 't_mid': 2013.7029044090127, 'linear_fit': array([6.86138139e-03, 1.78376323e+03]), 'cov_matrix': array([[6.60886867e-04, 2.21390224e+01],
[2.21390224e+01, 7.41710122e+05]])}, {'name': 'Component 3', 'speed': 0.11574003432859001, 'speed_err': 0.06469392163627156, 'y0': -229.99210686219223, 'y0_err': -31435.86594512278, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': -229.99210686219223, 't_0': 1987.1439316255653, 't_0_err': 14.731224706983241, 'red_chi_sqr': 0.5777004996741018, 't_mid': 2013.7029044090127, 'linear_fit': array([1.15740034e-01, 1.98714393e+03]), 'cov_matrix': array([[4.18530350e-03, 9.49253095e-01],
[9.49253095e-01, 2.17008981e+02]])}]
In [12]:
Copied!
#Alternatively, we can fit x- and y-coordinates separately, and we can choose a n-th order polynom to fit
order=2
#additionally, we can adjust the plot colors
colors=["green","purple","black","gray"]
fit=im_cube.get_speed2d(order=order,colors=colors,show_plot=True,plot_errors=True)
#Again, the returned fit dictionaries include important information about the performed fit, this time, for x- and y
print(fit)
#Alternatively, we can fit x- and y-coordinates separately, and we can choose a n-th order polynom to fit
order=2
#additionally, we can adjust the plot colors
colors=["green","purple","black","gray"]
fit=im_cube.get_speed2d(order=order,colors=colors,show_plot=True,plot_errors=True)
#Again, the returned fit dictionaries include important information about the performed fit, this time, for x- and y
print(fit)
/home/flep98/VCAT/vcat/kinematics.py:480: RuntimeWarning: divide by zero encountered in divide linear_fit, cov_matrix = np.polyfit(time, dist, order, cov='scaled', w=1./dist_err) /home/flep98/anaconda3/lib/python3.9/site-packages/numpy/lib/polynomial.py:663: RuntimeWarning: invalid value encountered in multiply rhs *= w /home/flep98/anaconda3/lib/python3.9/site-packages/numpy/lib/polynomial.py:667: RuntimeWarning: invalid value encountered in divide lhs /= scale 2025-10-17 17:47:25,130 - WARNING - vcat - Could not perform weighted fit for Component Component 0, will do unweighted. /home/flep98/VCAT/vcat/kinematics.py:499: RuntimeWarning: invalid value encountered in double_scalars t_0 = - linear_fit[-1] / speed + t_mid /home/flep98/VCAT/vcat/kinematics.py:501: RuntimeWarning: invalid value encountered in double_scalars t_0_err = np.sqrt((cov_matrix[-1, -1] / speed ** 2) + (linear_fit[-1] ** 2 * cov_matrix[0, 0] / speed ** 4)) /home/flep98/VCAT/vcat/kinematics.py:468: RuntimeWarning: invalid value encountered in divide return 1. / (N - n) * np.sum(((y - fit) / yerr) ** 2.) 2025-10-17 17:47:25,132 - WARNING - vcat - Could not perform weighted fit for Component Component 0, will do unweighted.
[[{'name': 'Component 0', 'speed': 0.0, 'speed_err': 0.0, 'y0': 0.0, 'y0_err': 0.0, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': 0.0, 't_0': nan, 't_0_err': nan, 'red_chi_sqr': nan, 't_mid': 2013.7029044090127, 'linear_fit': array([0., 0., 0.]), 'cov_matrix': array([[ 0., 0., -0.],
[ 0., 0., -0.],
[-0., -0., 0.]])}, {'name': 'Component 0', 'speed': 0.0, 'speed_err': 0.0, 'y0': 0.0, 'y0_err': 0.0, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': 0.0, 't_0': nan, 't_0_err': nan, 'red_chi_sqr': nan, 't_mid': 2013.7029044090127, 'linear_fit': array([0., 0., 0.]), 'cov_matrix': array([[ 0., 0., -0.],
[ 0., 0., -0.],
[-0., -0., 0.]])}], [{'name': 'Component 1', 'speed': 0.0037212411379664956, 'speed_err': 0.0022799306775130586, 'y0': -7.576724018814405, 'y0_err': 0.015188659061617083, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': -7.576724018814405, 't_0': 2036.0744541684744, 't_0_err': 14.301418503119157, 'red_chi_sqr': 0.8748843972575779, 't_mid': 2013.7029044090127, 'linear_fit': array([ 0.00372124, 0.02084391, -0.08324993]), 'cov_matrix': array([[ 5.19808389e-06, -8.05726863e-07, -2.83622647e-05],
[-8.05726863e-07, 1.36944129e-05, -7.88261786e-06],
[-2.83622647e-05, -7.88261786e-06, 2.30695364e-04]])}, {'name': 'Component 1', 'speed': -0.0033142537236125896, 'speed_err': 0.004246882192822962, 'y0': 6.3082560223528485, 'y0_err': 0.028292283768909136, 'beta_app': -0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': -0.0, 'dist_0_est': 6.3082560223528485, 't_0': 1903.3714822161378, 't_0_err': 141.63608735268608, 'red_chi_sqr': 0.702210796805707, 't_mid': 2013.7029044090127, 'linear_fit': array([-0.00331425, 0.01047125, -0.36566633]), 'cov_matrix': array([[ 1.80360084e-05, -2.79566408e-06, -9.84097320e-05],
[-2.79566408e-06, 4.75160752e-05, -2.73506478e-05],
[-9.84097320e-05, -2.73506478e-05, 8.00453321e-04]])}], [{'name': 'Component 2', 'speed': -0.005362155916196214, 'speed_err': 0.005598421855083155, 'y0': 10.439547726922981, 'y0_err': 0.03543727342078503, 'beta_app': -0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': -0.0, 'dist_0_est': 10.439547726922981, 't_0': 1946.893728955302, 't_0_err': 70.06528050063571, 'red_chi_sqr': 0.21391652912306416, 't_mid': 2013.7029044090127, 'linear_fit': array([-0.00536216, 0.01331445, -0.35824122]), 'cov_matrix': array([[ 3.13423273e-05, 6.53351305e-06, -1.69143576e-04],
[ 6.53351305e-06, 6.46997394e-05, -2.95995871e-05],
[-1.69143576e-04, -2.95995871e-05, 1.25580035e-03]])}, {'name': 'Component 2', 'speed': 0.016831481597218985, 'speed_err': 0.02049796389362729, 'y0': -35.50994744401432, 'y0_err': 0.12974941329373266, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': -35.50994744401432, 't_0': 2109.7339077910715, 't_0_err': 117.20368167778805, 'red_chi_sqr': 1.858521020371372, 't_mid': 2013.7029044090127, 'linear_fit': array([ 0.01683148, -0.00875483, -1.61634407]), 'cov_matrix': array([[ 4.20166524e-04, 8.75864591e-05, -2.26749175e-03],
[ 8.75864591e-05, 8.67346715e-04, -3.96803833e-04],
[-2.26749175e-03, -3.96803833e-04, 1.68349103e-02]])}], [{'name': 'Component 3', 'speed': 0.005922818305122917, 'speed_err': 0.014778022320587562, 'y0': -11.727214235018577, 'y0_err': 0.09588228035057708, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': -11.727214235018577, 't_0': 1980.005738969769, 't_0_err': 85.622111777827, 'red_chi_sqr': 0.13512681964160972, 't_mid': 2013.7029044090127, 'linear_fit': array([0.00592282, 0.02663508, 0.19958219]), 'cov_matrix': array([[ 0.00021839, 0.00011442, -0.00118246],
[ 0.00011442, 0.0005605 , -0.00046514],
[-0.00118246, -0.00046514, 0.00919341]])}, {'name': 'Component 3', 'speed': 0.005575512648345999, 'speed_err': 0.033616445316767676, 'y0': -14.319809557295454, 'y0_err': 0.21810911936178545, 'beta_app': 0.0, 'beta_app_err': 0.0, 'd_crit': 1.0, 'd_crit_err': 0.0, 'dist_0_est': -14.319809557295454, 't_0': 2568.3395340415, 't_0_err': 3344.3001189033616, 'red_chi_sqr': 1.076374538704596, 't_mid': 2013.7029044090127, 'linear_fit': array([ 0.00557551, -0.11159826, -3.09238354]), 'cov_matrix': array([[ 0.00113007, 0.00059207, -0.00611866],
[ 0.00059207, 0.00290033, -0.00240689],
[-0.00611866, -0.00240689, 0.04757159]])}]]
In [13]:
Copied!
#In addition to the component kinematics, different parameters can be plotted as well
value="tb" #choose value to plot, also "flux", or "flux+evpa" possible
#the plot method also returns the values with error, in case you want to use them for other tasks.
times, values, err = im_cube.plot_component_evolution(value)
#In addition to the component kinematics, different parameters can be plotted as well
value="tb" #choose value to plot, also "flux", or "flux+evpa" possible
#the plot method also returns the values with error, in case you want to use them for other tasks.
times, values, err = im_cube.plot_component_evolution(value)
In [14]:
Copied!
#Since VCAT automatically calculates component polarization, when a .uvf file is loaded
#it is also possible to plot polarization information for the components
value="lin_pol"
#it is possible to select only a subset of components
id=[0,3]
#This plot now shows the linearly polarized flux density with EVPAs overplotted as tilted lines for every component
times, values, err = im_cube.plot_component_evolution(value,id=id,plot_errors=True)
#Since VCAT automatically calculates component polarization, when a .uvf file is loaded
#it is also possible to plot polarization information for the components
value="lin_pol"
#it is possible to select only a subset of components
id=[0,3]
#This plot now shows the linearly polarized flux density with EVPAs overplotted as tilted lines for every component
times, values, err = im_cube.plot_component_evolution(value,id=id,plot_errors=True)
In [15]:
Copied!
#It is also possible to fit a collimation profile based on the model components
#We can introduce an snr_cut to only consider significant components
snr_cut=1
#additionally it is useful to filter out unresolved components
filter_unresolved=True
#the fit_type can be selected between "Powerlaw" and "brokenPowerlaw", and it is possible to fit r0 (fit_r0)
fit_r0=False
fit_type="brokenPowerlaw"
im_cube.fit_collimation_profile(snr_cut=snr_cut,
filter_unresolved=filter_unresolved,
fit_r0=fit_r0,
fit_type=fit_type)
#It is also possible to fit a collimation profile based on the model components
#We can introduce an snr_cut to only consider significant components
snr_cut=1
#additionally it is useful to filter out unresolved components
filter_unresolved=True
#the fit_type can be selected between "Powerlaw" and "brokenPowerlaw", and it is possible to fit r0 (fit_r0)
fit_r0=False
fit_type="brokenPowerlaw"
im_cube.fit_collimation_profile(snr_cut=snr_cut,
filter_unresolved=filter_unresolved,
fit_r0=fit_r0,
fit_type=fit_type)
only use y-error fit_type=2 Beta: [0.29309679 0.03895191 0.89207751 0.42156644] Beta Std Error: [0.01470947 0.085594 0.04805838 0.04105441] Beta Covariance: [[0.00029898 0.00154242 0.0001296 0.00057916] [0.00154242 0.01012366 0.00038394 0.00279647] [0.0001296 0.00038394 0.00319146 0.00192952] [0.00057916 0.00279647 0.00192952 0.00232901]] Residual Variance: 0.7236839580803294 Inverse Condition #: 0.0009250520871253146 Reason(s) for Halting: Sum of squares convergence
/home/flep98/VCAT/vcat/fit_functions.py:61: RuntimeWarning: invalid value encountered in power return w0*2**((au-ad)/s)*(x/xb)**au*(1+(x/xb)**s)**((ad-au)/s)
Out[15]:
<vcat.plots.jet_profile_plot.JetProfilePlot at 0x7b29b3e81940>
In [16]:
Copied!
#Moreover other component profiles can be plotted, e.g., the flux profile
value="flux" #for flux profile
#the method also returns the values with errors
dists,values,errs=im_cube.get_model_profile(value,plot=True)
#Moreover other component profiles can be plotted, e.g., the flux profile
value="flux" #for flux profile
#the method also returns the values with errors
dists,values,errs=im_cube.get_model_profile(value,plot=True)
In [17]:
Copied!
#If you are feeling very fancy, you can also create a movie of the moving components (useful for talks!)
plot_components=True
n_frames=200 #number of frames
interval=50 #milliseconds per frame
save="kinematic_movie.mp4" #output file name
#usual plot parameters can be used here as well
xlim=[5,-5]
ylim=[-7,3]
#Let's create the movie (NOTE: This may take some time!)
im_cube.movie(plot_components=plot_components,n_frames=n_frames,interval=interval,xlim=xlim,ylim=ylim,save=save)
#Let's display the movie
Video(save, embed=True)
#If you are feeling very fancy, you can also create a movie of the moving components (useful for talks!)
plot_components=True
n_frames=200 #number of frames
interval=50 #milliseconds per frame
save="kinematic_movie.mp4" #output file name
#usual plot parameters can be used here as well
xlim=[5,-5]
ylim=[-7,3]
#Let's create the movie (NOTE: This may take some time!)
im_cube.movie(plot_components=plot_components,n_frames=n_frames,interval=interval,xlim=xlim,ylim=ylim,save=save)
#Let's display the movie
Video(save, embed=True)
2025-10-17 17:47:39,691 - INFO - vcat - Creating movie Processing: 0%| | 0/200 [00:00<?, ?it/s]2025-10-17 17:47:39,692 - INFO - matplotlib.animation - Animation.save using <class 'matplotlib.animation.FFMpegWriter'> 2025-10-17 17:47:39,693 - INFO - matplotlib.animation - MovieWriter._run: running command: ffmpeg -f rawvideo -vcodec rawvideo -s 1920x1440 -pix_fmt rgba -r 20 -loglevel error -i pipe: -vcodec h264 -pix_fmt yuv420p -y kinematic_movie.mp4 /home/flep98/VCAT/vcat/kinematics.py:111: RuntimeWarning: divide by zero encountered in double_scalars self.tb = 1.22e12/(self.freq*1e-9)**2 * self.flux * (1 + self.redshift) / (maj_for_tb*self.scale) / (min_for_tb*self.scale) #Kovalev et al. 2005 /home/flep98/VCAT/vcat/kinematics.py:165: RuntimeWarning: divide by zero encountered in double_scalars SNR_p = S_p/sigma_p Processing: 201it [08:16, 2.49s/it] 2025-10-17 17:55:58,719 - INFO - vcat - Movie for 15GHz exported as 'kinematic_movie.mp4' Processing: 201it [08:19, 2.48s/it]
Out[17]:
In [18]:
Copied!
#Optionally, we can also display the components with a colormap, according to their flux density
fill_components=True
component_cmap="inferno"
save="kinematic_movie2.mp4"
#Let's create another movie
im_cube.movie(plot_components=True,fill_components=fill_components,component_cmap=component_cmap,
n_frames=n_frames,interval=interval,xlim=xlim,ylim=ylim,save=save)
#And display the movie
Video(save, embed=True)
#Optionally, we can also display the components with a colormap, according to their flux density
fill_components=True
component_cmap="inferno"
save="kinematic_movie2.mp4"
#Let's create another movie
im_cube.movie(plot_components=True,fill_components=fill_components,component_cmap=component_cmap,
n_frames=n_frames,interval=interval,xlim=xlim,ylim=ylim,save=save)
#And display the movie
Video(save, embed=True)
2025-10-17 17:56:09,228 - INFO - vcat - Creating movie Processing: 0%| | 0/200 [00:00<?, ?it/s]2025-10-17 17:56:09,230 - INFO - matplotlib.animation - Animation.save using <class 'matplotlib.animation.FFMpegWriter'> 2025-10-17 17:56:09,230 - INFO - matplotlib.animation - MovieWriter._run: running command: ffmpeg -f rawvideo -vcodec rawvideo -s 1920x1440 -pix_fmt rgba -r 20 -loglevel error -i pipe: -vcodec h264 -pix_fmt yuv420p -y kinematic_movie2.mp4 /home/flep98/VCAT/vcat/kinematics.py:111: RuntimeWarning: divide by zero encountered in double_scalars self.tb = 1.22e12/(self.freq*1e-9)**2 * self.flux * (1 + self.redshift) / (maj_for_tb*self.scale) / (min_for_tb*self.scale) #Kovalev et al. 2005 /home/flep98/VCAT/vcat/kinematics.py:165: RuntimeWarning: divide by zero encountered in double_scalars SNR_p = S_p/sigma_p Processing: 201it [08:33, 2.55s/it] 2025-10-17 18:04:45,692 - INFO - vcat - Movie for 15GHz exported as 'kinematic_movie2.mp4' Processing: 201it [08:36, 2.57s/it]
Out[18]:
In [ ]:
Copied!
In [ ]:
Copied!