In [1]:
Copied!
from vcat import ImageData
from vcat import ImageData
2025-09-07 21:31:41,033 - INFO - vcat - Logging initialized. Log file: Console only. 2025-09-07 21:31:41,033 - INFO - vcat - No environment variable VCAT_CONFIG found, will use defaults. 2025-09-07 21:31:41,034 - INFO - vcat - Using DIFMAP path: /usr/local/difmap/uvf_difmap_2.5g/
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 some data
data=ImageData("../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.fits", #Stokes I Fits
"../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.uvf") #uvf file (not necessary, but better)
#get some info and plot it
print(data)
data.plot()
#Let's load some data
data=ImageData("../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.fits", #Stokes I Fits
"../dataset_example/3C111_X_2014_05_08/3C111_X_2014_05_08.uvf") #uvf file (not necessary, but better)
#get some info and plot it
print(data)
data.plot()
Image of the source 3C111 at frequency 8.4 GHz on 2014-05-08
Total cleaned flux: 3815.199 mJy
Image Noise: 0.246 mJy using method 'Histogram Fit'
No polarization data loaded.
No model loaded. Clean model info:
Model Flux: 3815.199 mJy
Number of Components: 1555
Out[2]:
<vcat.plots.fits_image.FitsImage at 0x7f94ba22b370>
In [3]:
Copied!
#There are currently two methods implemented to derive a ridgeline
#Let's start with the "slices" method which will rotate the jet to the y-axis and then performs an analysis on each horizontal pixelslice
#Note that this method might not work for strongly bent jets
#To get the ridgeline we can do
ridgeline, _ = data.get_ridgeline(method="slices")
#this operation will automatically attach the new ridgeline to the ImageData object (data.ridgeline), so we can immediately plot it
data.plot(plot_ridgeline=True,ridgeline_color="green")
#There are currently two methods implemented to derive a ridgeline
#Let's start with the "slices" method which will rotate the jet to the y-axis and then performs an analysis on each horizontal pixelslice
#Note that this method might not work for strongly bent jets
#To get the ridgeline we can do
ridgeline, _ = data.get_ridgeline(method="slices")
#this operation will automatically attach the new ridgeline to the ImageData object (data.ridgeline), so we can immediately plot it
data.plot(plot_ridgeline=True,ridgeline_color="green")
2025-09-07 21:31:58,775 - INFO - vcat - Automatically determined jet direction 63.0°.
Out[3]:
<vcat.plots.fits_image.FitsImage at 0x7f95019a8190>
In [4]:
Copied!
#The ridgeline itself has some useful plot methods that can be used as follows:
#For better visibility, we will arrange them in a 2x2 subplot grid using matplotlib
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2,figsize=(12,10))
#Flux profile
ridgeline.plot("intensity",fig=fig,ax=ax[0,0],show=False)
#opening angle
ridgeline.plot("open_angle",fig=fig,ax=ax[0,1],show=False)
#jet width/collimation profile, including fits
ridgeline.plot("width",fig=fig,ax=ax[1,0],fit=True,show=False)
#ridgeline itself
ridgeline.plot("ridgeline",fig=fig,ax=ax[1,1],show=False)
#and finally display all the plots
plt.tight_layout()
plt.show()
#Note that all of these values are also accesible manually, if you prefer doing your own custom plots
open_angle=data.ridgeline.open_angle #.width, .dist, .intensity, .X_ridg, .Y.ridg
#The ridgeline itself has some useful plot methods that can be used as follows:
#For better visibility, we will arrange them in a 2x2 subplot grid using matplotlib
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2,figsize=(12,10))
#Flux profile
ridgeline.plot("intensity",fig=fig,ax=ax[0,0],show=False)
#opening angle
ridgeline.plot("open_angle",fig=fig,ax=ax[0,1],show=False)
#jet width/collimation profile, including fits
ridgeline.plot("width",fig=fig,ax=ax[1,0],fit=True,show=False)
#ridgeline itself
ridgeline.plot("ridgeline",fig=fig,ax=ax[1,1],show=False)
#and finally display all the plots
plt.tight_layout()
plt.show()
#Note that all of these values are also accesible manually, if you prefer doing your own custom plots
open_angle=data.ridgeline.open_angle #.width, .dist, .intensity, .X_ridg, .Y.ridg
In [5]:
Copied!
#If the automatic detection does not work, we can choose to manually provide the jet angle
jet_angle=63
auto_rotate=False
#additionally, we also want to find the counterjet, this is possible by setting
counterjet=True
#Additionally we can apply some cuts for the fits
cut_radial=3.0 #signal-to-noise cut for pixels to consider in the fit
cut_final=5.0 #signal-to-noise cut for the final peak flux
#And adjust the final chi-squared value which is used to determine good fits for the width and opening angle
chi_sq_val=100.0
#Let's do the fit again including counterjet
ridgeline, counter_ridgeline = data.get_ridgeline("slices",counterjet=counterjet,jet_angle=jet_angle,auto_rotate=auto_rotate,
cut_radial=cut_radial,cut_final=cut_final,chi_sq_val=chi_sq_val)
#and plot the data including the counterjet
data.plot(plot_ridgeline=True,ridgeline_color="green",plot_counter_ridgeline=True,counter_ridgeline_color="purple")
#If the automatic detection does not work, we can choose to manually provide the jet angle
jet_angle=63
auto_rotate=False
#additionally, we also want to find the counterjet, this is possible by setting
counterjet=True
#Additionally we can apply some cuts for the fits
cut_radial=3.0 #signal-to-noise cut for pixels to consider in the fit
cut_final=5.0 #signal-to-noise cut for the final peak flux
#And adjust the final chi-squared value which is used to determine good fits for the width and opening angle
chi_sq_val=100.0
#Let's do the fit again including counterjet
ridgeline, counter_ridgeline = data.get_ridgeline("slices",counterjet=counterjet,jet_angle=jet_angle,auto_rotate=auto_rotate,
cut_radial=cut_radial,cut_final=cut_final,chi_sq_val=chi_sq_val)
#and plot the data including the counterjet
data.plot(plot_ridgeline=True,ridgeline_color="green",plot_counter_ridgeline=True,counter_ridgeline_color="purple")
Out[5]:
<vcat.plots.fits_image.FitsImage at 0x7f9500a5b640>
In [6]:
Copied!
#if there is a counterjet ridgeline and a jet ridgeline defined, we can plot the jet to counterjet profile
data.jet_to_counterjet_profile()
#if there is a counterjet ridgeline and a jet ridgeline defined, we can plot the jet to counterjet profile
data.jet_to_counterjet_profile()
In [7]:
Copied!
#Let's also have a look at the second method that is implemented, called "polar",
#This method converts the image to polar coordinates and performs a gaussian fit for every azimuthal slice
#This method currently only works without counterjet
data=data.center()
#sometimes this method can be problematic in the inner region close to the jet, so you can define a start_radius in mas where to begin the fit
start_radius=1.5 #mas
#Let's give it a try:
ridgeline, _ = data.get_ridgeline("polar",start_radius=start_radius)
#let's plot it
data.plot(plot_ridgeline=True,ridgeline_color="green")
#Let's also have a look at the second method that is implemented, called "polar",
#This method converts the image to polar coordinates and performs a gaussian fit for every azimuthal slice
#This method currently only works without counterjet
data=data.center()
#sometimes this method can be problematic in the inner region close to the jet, so you can define a start_radius in mas where to begin the fit
start_radius=1.5 #mas
#Let's give it a try:
ridgeline, _ = data.get_ridgeline("polar",start_radius=start_radius)
#let's plot it
data.plot(plot_ridgeline=True,ridgeline_color="green")
2025-09-07 21:33:30,012 - INFO - vcat - will apply shift (x,y): [-0.04000000009455 : 0.0] mas 2025-09-07 21:33:49,154 - INFO - vcat - Automatically determined jet direction 63.0°.
Out[7]:
<vcat.plots.fits_image.FitsImage at 0x7f9500651130>
In [8]:
Copied!
#Let's create the same ridgeline plots as before for comparison with the 'slices' method:
#For better visibility, we will arrange them in a 2x2 subplot grid using matplotlib
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2,figsize=(12,10))
#Flux profile
ridgeline.plot("intensity",fig=fig,ax=ax[0,0],show=False)
#opening angle
ridgeline.plot("open_angle",fig=fig,ax=ax[0,1],show=False)
#jet width/collimation profile, including fits
ridgeline.plot("width",fig=fig,ax=ax[1,0],fit=True,show=False)
#ridgeline itself
ridgeline.plot("ridgeline",fig=fig,ax=ax[1,1],show=False)
#and finally display all the plots
plt.tight_layout()
plt.show()
#Let's create the same ridgeline plots as before for comparison with the 'slices' method:
#For better visibility, we will arrange them in a 2x2 subplot grid using matplotlib
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2,2,figsize=(12,10))
#Flux profile
ridgeline.plot("intensity",fig=fig,ax=ax[0,0],show=False)
#opening angle
ridgeline.plot("open_angle",fig=fig,ax=ax[0,1],show=False)
#jet width/collimation profile, including fits
ridgeline.plot("width",fig=fig,ax=ax[1,0],fit=True,show=False)
#ridgeline itself
ridgeline.plot("ridgeline",fig=fig,ax=ax[1,1],show=False)
#and finally display all the plots
plt.tight_layout()
plt.show()
In [ ]:
Copied!