Data cube
Velocity field map
baygaudGUI.py
baygaudCLAF.py
BAYGAUD supports graphic user interface powered with python-tkinter. You can run it with python3 (dependencies required, see installation tab)
python3 baygaudGUI.py
Then a window like below will pop-up.
At first, you need to set a path to BAYGAUD.
Locate the directory where you've installed BAYGAUD.
Then, you could see a file named 'baygaud' under /src/bin
Next, you need to set a path to a data cube.
Click the 'Browse' button next to the 'Cube' entry and set the path.
Then, if there is a map with a name containing 'mom1' or 'MOM1', the program will ask you if you want to set it as a 'Reference velocity map'.
If it doesn't ask or recommends the wrong one, you can always set the reference velocity map manually.
Setting both, moment maps will show up on the left screen.
NOTE: mom0: intensity, mom1: intensity weighted mean velocity, mom2: intensity weighted velocity dispersion
(The example galaxy is one of the THINGS galaxy (Walter+2008) NGC5055)
With the left screen showing up, you will be able to see some entries have been filled up as well.
The entries with name 'nax#_s0' or 'e0' determines area to be cropped.
You can use these parameters to chop out the area without signals.
Increasing nax1_s0 will chop out left-hand side of the image, and nax1_e0 will chop out right-hand side of the image.
By default, these will be set not to crop the image.
Below them, there are two entries with name 'Cores per segment' and 'Division along nax2'.
'Cores per segment' determines the number of cores that are going to be used per segment, and it also determines the horizontal number of pixels of a segment.
For example, if the 'Cores per segment' = 5, and NAXIS1 of data is 156, there will be 31 segments in the horizontal direction.
Note that it is not 32 segments to be made - The left over part is thrown away.
So if you don't want the output image to have different size than input, you want to set this value exactly same as a divisor of NAXIS1.
Or, just conveniently you can set it as 1.
'Divisions along nax2' determines the number of parts along NAXIS2 direction, as its name suggests.
For example, if it's 2, there will be 2 parts (1 division) in the NAXIS2 direction and if you have set 'Cores per segment' as 1, there will be total of NAXIS1*2 segments to be made.
It also throws away the leftover part. - If NAXIS2 = 103 and 'Divisions along nax2' = 2, there will be 2 parts with 51 pixels in the vertical direction and one left part with 1 pixel will be gone.
So if you don't want the image to be cropped, you can set it as 1 as well on this one.
Doing so as above, you will have as same as below
On the bottom of the window, you will be able to see entries with 'n_gauss' and 'ncores_total'
'n_gauss' is the maximum number of Gaussian components to be fitted.
That is, BAYGAUD won't guess the profile with number of Gaussians greater than this value.
You can give 3, or 4 normally.
If you are not sure about it, you can quickly check the shape of the profile by clicking on a certain position on the left screen.
Finally for 'ncores_total', it is a number of cores that are going to be used in the calculation.
For example, if ncores_total = 10 and Cores per segment = 1, program will run 10 segments in parallel.
With all the entries filled up, we are now ready to run the calculation.
Hit the 'Run' button
Then a window with progress status will pop up like the image above.
If you want to stop the code, please do not just close the window, but use 'Kill all' button. (That's because just closing the window, some process' may still survive and continue the calculation.)
You can also kill individual segments by selecting and clicking 'Kill selected' button.
Some pieces of information will show up in the terminal you ran baygaudGUI.py, so take a look at it if something seem to go wrong or stuck.
With all the segments done, the program will start to merge segments into one piece again.
The multiple Gaussian fitting with BAYGAUD is now done.
Now we need to classify the components according to the fitted result.
Let's move on.
If the classification has completed, we can see the output in the /baygaud_output.cube_name/output_merged/classified/ directory.
And there are many directories.
ps_gfit : perfect single gaussian ( G = 1 )
1chan_cnm : among 1channel resolution and cold gas ( 1 channel resolution ~ 4 )
cnm_wnm_gfit : among cnm and wnm gas ( 4 < vdisp < 8 )
wnm_hot_gfit : among wnm and hot gas ( 8 < vdisp < 99 )
cold_gfit : don't use it
warm_gfit : don't use it
primary : primary component among multiple gaussian components
vdisp_acc_gfit : accumulated gas components (involving cold~hot gas)
vdisp_step : 1 channel resolution intervals...step별로
vdisp_steps_ng_projected : don't use it
In vdisp_acc_gfit directory, 1.1.1.fits ~ 20.3.10 fits files exist.
first number : step number
middle number: one of the gaussian components. randomly distributed. ( In this case , the gaussian component number = 3 )
last number: numbering
0: background
1: intensity
2: vel-dispersion
3: vel
4: log-evidence
5: optimal number of Gaussian
6: flux std
7: s/n
8: s/n of the highest flux
9: s/n of the lowest flux
10: low s/n flag
$ vi classify_baygaud_main.hanning_regridded.cube.py
You should set the environment global variables below.
n_gauss : the number we input in the generate_baygaud_segs_scripts process. e.g., 2, 3, 4, ....
_cube.name : input the cube.fits name e.g., galaxy_name.cube_Vel.fits
bulk_ref_vf : input the cube_ref_vf name e.g., galaxy_name.moment1.fits
n_sub = 11 : # of sub-files
sn_limit = 2 : the SN of a profile should be larger than this value.
channel_width = 3.97 # [km/s] : you can check this by reading the fits's header
CDEL3 = 3974.09
CUNIT3 = m/s
In this case, the channel_width will be 3.97 [km/s]
vel_bulk_limit = 5 # [km/s] : If the variation is larger than 5 , the gas component is regarded as non-circular gas component. As the number is smaller, we can extract the closer components to bulk components.
vdisp_cnm = 4.0 # [km/s] : if the vel_dispersion is smaller than this value, the gas is regarded as cold neutral medium gas.
vdisp_wnm = 8 # [km/s] : if the vel_dispersion is larger than this value, the gas is regarded as warm neutral medium gas.
vdisp_hot = 99 # [km/s] : Set the large number.. If the vel_dispersion is larger than this value, it is hot gas.
If the setting is done, let's proceed on the classification step.
$ python classify_baygaud_main.hanning_regridded.cube.py
# added by hj
Before you run baygaudGUI.py, install all required dependencies:
python3-tk
libbz2-dev
numpy
matplotlib
glob
astropy
spectral_cube
natsort
tqdm
fitsio
# ms
Firstly, we are going to cut the cube into parts, which we will call them 'segments'.
Doing so, progress can be saved if there goes something wrong in the middle of the computing process.
This can be done with 'generate_baygaud_segs_scripts.cusped0'.
Open it with any text editor you have, for example;
code generate_baygaud_segs_scripts.cusped0
At the very first part, you'll be able to see
set main_baygaud =
set ncolm_per_core =
set nsegments_nax2 =
set n_cores_total =
set sleep_time =
set bayes_factor_limit =
main_baygaud should be given with the path where script baygaud is.
It should be at <baygaud directory>/src/bin/baygaud
ncolm_per_core is the horizontal pixel length of the segment, and also the amount of core that'll be used per segment.
So if the given cube has it's NAXIS1 = 600 and you give ncolm_per_core = 2, it will make 300 divisions in horizontal direction.
nsegments_nax2 is the number of divisions in the vertical direction.
If you give it 4, there will be 4 divisions in the vertical direction.
Continuing from the example in ncolm_per_core, if the given cube has its' NAXIS1=NAXIS2=600, and you give ncolm_per_core = 2 with nsegments_nax2 = 2, there will be 2 divisions in the vertical direction and 300 divisions in horizontal direction, resulting total 600 segments to run.
n_cores_total controls how many segments to be run at the same time.
It designates one core per a segment, so giving number means the amount of segments to be run at a same time.
sleep_time is sleeping time between running segments in second unit.
Note that it starts to count from the moment you run a segment, so if a segment is done later than given sleep_time it will add another segment to calculate before the already-running-one completed, which may lead to overload the cores.
It is recommended to set this value after try running a segment to figure out how much time it take to finish for a single segment.
bayes_factor_limit
In this example, we've set like below;
set main_baygaud = ~/lib/baygaud.v1.3.0/src/bin/baygaud
set ncolm_per_core = 10
set nsegments_nax2 = 2
set n_cores_total = 12
set sleep_time = 50
set bayes_factor_limit = 3.2
In the next part, you can set MultiNest parameters.
Setting as below should be ok but if you want more details, see Feroz et al. (2008) and/or https://johannesbuchner.github.io/PyMultiNest/pymultinest_run.html
set int = 1
set const_eff_mode = 1
set nlive = 100
set mmodal = 0
set efr = 0.9
set tol = 0.3
set feedback = 0
set write_multinest_outputfile = 1
set max_iter = 0
Below the multinest part, you'll be able to see
set nax1_s0 =
set nax1_e0 =
set nax2_s0 =
set nax2_e0 =
The galaxy may not be filling entire region of the cube, or you may want to run some specified zone in the cube.
In this case you can set upper values to specify a zone to run.
Each s0 and e0 should be given with starting pixel and ending pixel respectively.
For example, if the cube has NAXIS1=600 and you give nax1_s0 = 200, and nax1_e0=400, BAYGAUD will only run from 200 to 400 pixels in AXIS1 direction.
In this example, we'll set as
set nax1_s0 = 20
set nax1_e0 = 80
set nax2_s0 = 7
set nax2_e0 = 80
Which will only use the zone in the figure below
Now you are ready to run the segment generating script.
Run with following command:
./generate_baygaud_segs_scripts.cusped0
Then it will say like below;
.........................................................1.wdir 2.nax1 3.nax2 4.cube.fits 5. ref.vf.fits 6.n_gauss & should be in Firstly, set up below values.........................................................<some number><some numbers>@: Assignment missing expression.It says it's missing some expressions.
To give expressions, the command should be followed with what specified in the console
wdir is the path where your cube and velocity map is
nax1 is the NAXIS1 of the cube
nax2 is the NAXIS2 of the cube
cube.fits is the name of the cube file
ref.vf.fits is the name of the velocity field file
n_gauss is the n_gauss limit you want BAYGAUD to process with (integer, 3 will be enough for this example)
These can be given with a spacing, such as
./generate_baygaud_segs_scripts.cusped0 wdir nax1 nax2 cube.fits ref.vf.fits n_gauss
In this example,
./generate_baygaud_segs_scripts.cusped0 ${PWD} 103 103 DDO_154_NA_CUBE_THINGS.REGR.FITS DDO_154_NA_MOM1_THINGS.REGR.FITS 3
Then the console will print out like below;
.........................................................1.wdir 2.nax1 3.nax2 4.cube.fits 5. ref.vf.fits 6.n_gaussDDO_154_NA_CUBE_THINGS.REGR.FITS & DDO_154_NA_MOM1_THINGS.REGR.FITS should be in /home/mandu/workspace/baygaud_tutorials/DDO_154Firstly, set up below values.........................................................020 7 80 7901 0 01 0 11 0 21 0 31 0 41 0 51 0 61 0 71 0 81 0 91 0 101 0 11It says there're total 12 segments have been generated.
Let's go check them; these are under segs_scripts/
cd segs_scripts
Let's try running one of .csh files to check how much time it is needed to run one.
./_sub1.csh
Then it will show up like below;
BUNIT is JY/BEAMCUNIT3 is M/SSKY-MEAN:-0.000247 SKY-STD:0.000496| rank- 1 -- x[ 21 22] y[ 7 43] -------------------------------------------------------- | ( 21 7) -- s/n= 2.3 < 3.0 (1 gaussfit only) || rank- 5 -- x[ 25 26] y[ 7 43] -------------------------------------------------------- | ( 25 7) -- s/n= 1.1 < 3.0 (1 gaussfit only) |It took about 40 secs to complete.
So setting sleep time around a one or couple of minutes may do good.
Let's go edit the sleep time part in generate_baygaud_segs_scripts.cusped0
code generate_baygaud_segs_scripts.cusped0
And set as
set sleep_time = 100
Save, quit, and regenerate the segments;
./generate_baygaud_segs_scripts.cusped0 ${PWD} 103 103 DDO_154_NA_CUBE_THINGS.REGR.FITS DDO_154_NA_MOM1_THINGS.REGR.FITS 3
You can run all the segments in order by using all.segs.~.csh file, which should be made in your current directory.
./all.segs.DDO_154_NA_CUBE_THINGS.REGR.FITS.csh
It took one for ~40 secs to complete, so running all 12 segments may take at least ~300 seconds.
Grab a coffee and let's sit back for a while.
When it's done, an output directory 'baygaud_output~' with subdirectories will be generated.
cd baygaud_output.DDO_154_NA_CUBE_THINGS.REGR.FITS
Inside, you'll be able to see directories with naming _sub#
These are outputs by each segments, so need to be merged again to get a full picture, which will do next.
NOTE: Currently installing merge_fits at local does not seem to be working well; Do merging in the server for a meantime.
merge_segs.csh is coded with in mind to process multiple datas at once.
So it requires some lists to run.
Let's make these first.
Go to the upper directory of the input fits we put.
cd ~/workspace/baygaud_tutorials
And, with your text editor, open a new file with name 'galaxy_name.list'
code galaxy_name.list
In this example, we're only processing a single galaxy data that are under directory of DDO_154/.
So what we're going to write here is only
DDO_154
exactly same as the directory name.
Save and quit.
Next, you need one more list with name 'galaxy_cube_fits.list'
code galaxy_cube_fits.list
In here, we give the name of the cube fits
DDO_154_NA_CUBE_THINGS.REGR.FITS
Save and quit.
Now lists are ready.
Let's open and edit the merge_segs.csh
code merge_segs.csh
Setting two paths is all we have to do
set main_mergefits =
set host_dir =
On main_mergefits, you give a path to where merge_fits code is.
On host_dir, you give where your galaxy folder (containing cube fits) is.
In this example,
set main_mergefits = ~/lib/merge_fits.26.July2019/src/bin
set host_dir = ~/workspace/baygaud_tutorials
And it done setting.
Let's go run the merge script
./merge_segs.csh
It won't take long to complete, and will show up like below
DDO_154_NA_MOM1_THINGS.REGR.FITS 12BAYGAUD OUTPUT DIR: ~NOTE: When it fails with 'Segmentation fault (Core dumped)', try deleting fits file that is generated under baygaud_output~ directory, and rerun.
When it's done, an output_merged directory should be made under baygaud_output
cd DDO_154/baygaud_output.DDO_154_NA_CUBE_THINGS.REGR.FITS/output/merged
ncolm_per_core: number of columns to distribute to one column. (e.g., RA)
nsegments_nax2: number of segments in axis 2 (e.g., DEC)
n_cores_total: number of total cores to run BAYGAUD
sleep_time: break time after BAYGAUD runs N segments (N=n_cores_total / ncolm_per_core) in seconds
nax1_s0: set number of pixels you will consider to make background for ax1 (e.g., RA) -> from the first index to nax1_s0
nax2_s0: set number of pixels you will consider to make background for ax2 (e.g., DEC) -> from the first index to nax2_s0
profile_sn_limit: cutoff limit of signal to noise (2~3 generally)
bayes_factor_limit: when BAYGAUD finds more reliable optimal gaussian number, it uses Bayes factor for the model selection. This value is the evidence of the optimal gaussian number over the evidence of null gaussian number.
(한 픽셀에서 optimal gaussian number를 결정할 때, model selection을 하게 되는데, 이 때 선택되는 optimal gaussian number는 바로 다음으로 높은 evidence를 가지는 gaussian component number보다 적어도 3.2배 커야한다(?))