44import os
55import re
66import sys
7+ from pathlib import Path
78
89import numpy as np
910from astropy .io import fits
@@ -335,15 +336,15 @@ def _generate_ini_file(
335336 is_harmonic = False ,
336337):
337338 """Generate a CosmoSIS INI configuration file from template with modifications."""
338- template_path = f "cosmosis_config/ { template_base } "
339- output_path = f"cosmosis_config/ cosmosis_pipeline_{ args .cosmosis_root } { suffix } .ini"
339+ template_path = Path ( "cosmosis_config" ) / template_base
340+ output_path = Path ( args . output_config_dir ) / f" cosmosis_pipeline_{ args .config_name_base } { suffix } .ini"
340341
341342 with open (template_path , "r" ) as f :
342343 config_content = f .read ()
343344
344345 modifications = []
345346
346- relative_fits_file = f"data/ { args .cosmosis_root } /cosmosis_ { args . cosmosis_root } .fits"
347+ relative_fits_file = args .config_relative_fits
347348 default_section = (
348349 f"[DEFAULT]\n SCRATCH = { args .data_dir } \n FITS_FILE = { relative_fits_file } "
349350 )
@@ -396,6 +397,8 @@ def _generate_ini_file(
396397 pattern , replacement , config_content , flags = re .MULTILINE
397398 )
398399
400+ output_path .parent .mkdir (parents = True , exist_ok = True )
401+
399402 with open (output_path , "w" ) as f :
400403 f .write (config_content )
401404
@@ -420,7 +423,7 @@ def generate_cosmosis_config(args):
420423 else :
421424 priors_file = "priors.ini"
422425
423- os .makedirs ("cosmosis_config" , exist_ok = True )
426+ os .makedirs (args . output_config_dir , exist_ok = True )
424427
425428 _generate_ini_file (
426429 args ,
@@ -454,21 +457,40 @@ def parse_args():
454457 description = "Prepare CosmoSIS inference FITS files from real or mock data. "
455458 "Supports multiple xi input formats (separate files, combined FITS)." ,
456459 epilog = """
457- Example for SP v1.4.6_A:
458- python cosmo_inference/scripts/cosmosis_fitting.py \\
459- --cosmosis-root "SP_v1.4.6_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1" \\
460- --data-dir "/n09data/guerrini/output_chains" \\
460+ Example for SP_v1.4.6_leak_corr (real data):
461+ python /n17data/cdaley/unions/pure_eb/code/sp_validation/cosmo_inference/scripts/cosmosis_fitting.py \\
462+ --cosmosis-root "SP_v1.4.6_leak_corr_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1" \\
463+ --data-dir "/n09data/guerrini/output_chains/SP_v1.4.6_leak_corr_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1" \\
464+ --nz-file "/n17data/sguerrini/UNIONS/WL/nz/v1.4.6/nz_SP_v1.4.6_A.txt" \\
465+ --output-root "/home/guerrini/sp_validation/cosmo_inference" \\
466+ --xi "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/xi_plus_SP_v1.4.6_leak_corr_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
467+ "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/xi_minus_SP_v1.4.6_leak_corr_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
468+ --cov-xi "/n17data/cdaley/unions/pure_eb/code/sp_validation/cosmo_inference/data/covariance/covariance_SP_v1.4.6_leak_corr_A_ng_minsep=1.0_maxsep=250.0_nbins=20_masked/covariance_SP_v1.4.6_leak_corr_A_ng_minsep=1.0_maxsep=250.0_nbins=20_masked_processed.txt" \\
469+ --use-rho-tau \\
470+ --rho-stats "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/rho_tau_stats/rho_stats_SP_v1.4.6_leak_corr_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
471+ --tau-stats "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/rho_tau_stats/tau_stats_SP_v1.4.6_leak_corr_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
472+ --cov-tau "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/rho_tau_stats/cov_tau_SP_v1.4.6_leak_corr_minsep=1.0_maxsep=250.0_nbins=20_npatch=1_th.npy" \\
473+ --cl-file "/home/guerrini/sp_validation/notebooks/cosmo_val/output/pseudo_cl_SP_v1.4.6_leak_corr.fits" \\
474+ --cov-cl "/home/guerrini/sp_validation/notebooks/cosmo_val/output/pseudo_cl_cov_g_ng_iNKA_SP_v1.4.6_leak_corr.fits"
475+
476+ Example for glass mock v0 (mock data):
477+ python /n17data/cdaley/unions/pure_eb/code/sp_validation/cosmo_inference/scripts/cosmosis_fitting.py \\
478+ --mock \\
479+ --cosmosis-root "glass_mock_v0_00001" \\
480+ --data-dir "/n09data/guerrini/glass_mock_chains/glass_mock_v0_00001" \\
461481 --nz-file "/n17data/sguerrini/UNIONS/WL/nz/v1.4.6/nz_SP_v1.4.6_A.txt" \\
462- --out-file "cosmo_inference/data/SP_v1.4.6_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1/cosmosis_SP_v1.4.6_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits " \\
463- --xi "notebooks/cosmo_val/output/xi_plus_SP_v1.4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits " \\
464- "notebooks/cosmo_val/output/xi_minus_SP_v1 .4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1 .fits" \\
465- --cov-xi "cosmo_inference/data/covariance/covariance_SP_v1.4.6_A_ng_minsep=1.0_maxsep=250.0_nbins=20_processed .txt" \\
482+ --output-root "/home/guerrini/sp_validation/cosmo_inference " \\
483+ --output-basename "glass_mocks/v0/glass_mock_00001 " \\
484+ --xi "/n09data/guerrini/glass_mock_v1 .4.6/results/xi_glass_mock_00001_4096_nbins=20 .fits" \\
485+ --cov-xi "/n17data/cdaley/unions/pure_eb/code/sp_validation/ cosmo_inference/data/covariance/covariance_SP_v1.4.6_A_ng_minsep=1.0_maxsep=250.0_nbins=20_masked/covariance_SP_v1.4.6_A_ng_minsep=1.0_maxsep=250.0_nbins=20_masked_processed .txt" \\
466486 --use-rho-tau \\
467- --rho-stats "notebooks/cosmo_val/output/rho_tau_stats/rho_stats_SP_v1.4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
468- --tau-stats "notebooks/cosmo_val/output/rho_tau_stats/tau_stats_SP_v1.4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
469- --cov-tau "notebooks/cosmo_val/output/rho_tau_stats/cov_tau_SP_v1.4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1_th.npy"
487+ --rho-stats "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/rho_tau_stats/rho_stats_SP_v1.4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1.fits" \\
488+ --tau-stats "/n17data/cdaley/unions/pure_eb/results/glass_mock_rhotau_samples/00001/tau_stats_sampled.fits" \\
489+ --cov-tau "/n17data/cdaley/unions/pure_eb/code/sp_validation/notebooks/cosmo_val/output/rho_tau_stats/cov_tau_SP_v1.4.6_minsep=1.0_maxsep=250.0_nbins=20_npatch=1_th.npy" \\
490+ --cl-file "/n09data/guerrini/glass_mock_v1.4.6/results/cl_glass_mock_00001_4096.npy" \\
491+ --cov-cl "/home/guerrini/sp_validation/notebooks/cosmo_val/output/pseudo_cl_cov_g_ng_iNKA_SP_v1.4.6.fits"
470492 """ ,
471- formatter_class = argparse .RawDescriptionHelpFormatter
493+ formatter_class = argparse .RawDescriptionHelpFormatter ,
472494 )
473495
474496 parser .add_argument (
@@ -478,9 +500,6 @@ def parse_args():
478500 "--data-dir" , type = str , required = True , help = "Output MCMC chain directory"
479501 )
480502 parser .add_argument ("--nz-file" , type = str , required = True , help = "Path to n(z) file" )
481- parser .add_argument (
482- "--out-file" , type = str , required = True , help = "Path to output FITS file"
483- )
484503 parser .add_argument (
485504 "--xi" ,
486505 nargs = "+" ,
@@ -490,7 +509,6 @@ def parse_args():
490509 parser .add_argument (
491510 "--cov-xi" , type = str , required = True , help = "Xi covariance matrix file"
492511 )
493-
494512 parser .add_argument (
495513 "--use-rho-tau" ,
496514 action = "store_true" ,
@@ -529,6 +547,24 @@ def parse_args():
529547 parser .add_argument (
530548 "--mock" , action = "store_true" , help = "Mock data mode"
531549 )
550+ parser .add_argument (
551+ "--output-root" ,
552+ type = str ,
553+ required = True ,
554+ help = (
555+ "Cosmo inference root directory (e.g., /home/guerrini/sp_validation/cosmo_inference). "
556+ "FITS and config files are written under this root."
557+ ),
558+ )
559+ parser .add_argument (
560+ "--output-basename" ,
561+ type = str ,
562+ required = False ,
563+ help = (
564+ "Optional override for the output sub-directory/basename inside --output-root. "
565+ "Defaults to --cosmosis-root."
566+ ),
567+ )
532568
533569 return parser .parse_args ()
534570
@@ -537,13 +573,31 @@ def parse_args():
537573 args = parse_args ()
538574
539575 try :
576+ output_basename = args .output_basename or args .cosmosis_root
577+ output_root_path = Path (args .output_root ).expanduser ().resolve ()
578+ output_basename_path = Path (output_basename )
579+ data_dir_root = output_root_path / "data" / output_basename_path
580+ config_dir_root = output_root_path / "cosmosis_config"
581+ data_dir_root .mkdir (parents = True , exist_ok = True )
582+ config_dir_root .mkdir (parents = True , exist_ok = True )
583+ out_file_path = data_dir_root / f"cosmosis_{ args .cosmosis_root } .fits"
584+ args .output_root = str (output_root_path )
585+ args .output_config_dir = str (config_dir_root )
586+ args .output_basename = str (output_basename_path )
587+ args .config_name_base = str (output_basename_path ).replace ("/" , "_" )
588+ args .config_relative_fits = str (
589+ Path ("data" ) / output_basename_path / f"cosmosis_{ args .cosmosis_root } .fits"
590+ )
591+
540592 print ("=" * 60 )
541593 print ("COSMOSIS_FITTING.PY" )
542594 print ("=" * 60 )
543595 print (f"cosmosis_root: { args .cosmosis_root } " )
544596 print (f"data_dir: { args .data_dir } " )
545597 print (f"nz_file: { args .nz_file } " )
546- print (f"out_file: { args .out_file } " )
598+ print (f"output_root: { args .output_root } " )
599+ print (f"output_basename: { args .output_basename } " )
600+ print (f"out_file: { out_file_path } " )
547601 print (f"xi files: { args .xi } " )
548602 print (f"cov_xi: { args .cov_xi } " )
549603 print (f"use_rho_tau: { args .use_rho_tau } " )
@@ -568,9 +622,6 @@ def parse_args():
568622 raise ValueError ("--cl-file is required when --cov-cl is provided" )
569623
570624 os .makedirs (args .data_dir , exist_ok = True )
571- output_dir = os .path .dirname (args .out_file )
572- os .makedirs (output_dir , exist_ok = True )
573-
574625 print ("Loading xi correlation functions..." )
575626 if args .mock :
576627 # Mock mode expects a single combined FITS file
@@ -638,8 +689,8 @@ def parse_args():
638689 hdu_list .extend ([tau_0_p_hdu , tau_2_p_hdu , rho_hdu ])
639690
640691 hdul = fits .HDUList (hdu_list )
641- hdul .writeto (args . out_file , overwrite = True )
642- print (f"✓ FITS file written to { args . out_file } " )
692+ hdul .writeto (str ( out_file_path ) , overwrite = True )
693+ print (f"✓ FITS file written to { out_file_path } " )
643694 print ()
644695
645696 generate_cosmosis_config (args )
0 commit comments