3535# =============================================================================#
3636
3737import argparse
38- import multiprocessing as mp
3938import os
4039import sys
4140import time
4241from functools import partial
4342
4443import astropy .io .fits as pf
4544import numpy as np
46- from tqdm .auto import tqdm
4745from tqdm .contrib .concurrent import process_map
4846
4947from RMtools_3D .do_RMsynth_3D import readFitsCube
@@ -329,7 +327,8 @@ def savefits_mask(data, header, outDir, prefixOut):
329327 headMask = strip_fits_dims (header = header , minDim = 2 )
330328 headMask ["DATAMAX" ] = 1
331329 headMask ["DATAMIN" ] = 0
332- del headMask ["BUNIT" ]
330+ if "BUNIT" in headMask :
331+ del headMask ["BUNIT" ]
333332
334333 mskArr = np .where (data > 0 , 1.0 , np .nan )
335334 MaskfitsFile = os .path .join (outDir , prefixOut + "mask.fits" )
@@ -348,17 +347,16 @@ def savefits_Coeffs(data, dataerr, header, polyOrd, outDir, prefixOut):
348347 prefixOut: prefix to use on the output name
349348 """
350349
351- headcoeff = strip_fits_dims (header = header , minDim = 2 )
352- headcoeff ["BUNIT" ] = ""
353- if "BTYPE" in headcoeff :
354- del headcoeff ["BTYPE" ]
350+ header ["BUNIT" ] = ""
351+ if "BTYPE" in header :
352+ del header ["BTYPE" ]
355353
356354 for i in range (np .abs (polyOrd ) + 1 ):
357355 outname = os .path .join (outDir , prefixOut + "coeff" + str (i ) + ".fits" )
358- pf .writeto (outname , data [i ], headcoeff , overwrite = True )
356+ pf .writeto (outname , data [i ], header , overwrite = True )
359357
360358 outname = os .path .join (outDir , prefixOut + "coeff" + str (i ) + "err.fits" )
361- pf .writeto (outname , dataerr [i ], headcoeff , overwrite = True )
359+ pf .writeto (outname , dataerr [i ], header , overwrite = True )
362360
363361
364362def savefits_model_I (data , header , outDir , prefixOut ):
@@ -422,10 +420,12 @@ def fit_spectra_I(
422420 outs ["I" ] = pixImodel .astype ("float32" )
423421 outs ["coeffs" ] = pixFitDict ["p" ].astype ("float32" )
424422 outs ["coeffs_err" ] = pixFitDict ["perror" ].astype ("float32" )
425- outs ["chiSq" ] = pixFitDict ["chiSq" ]. astype ( "float32" )
426- outs ["chiSqRed" ] = pixFitDict ["chiSqRed" ]. astype ( "float32" )
423+ outs ["chiSq" ] = pixFitDict ["chiSq" ]
424+ outs ["chiSqRed" ] = pixFitDict ["chiSqRed" ]
427425 outs ["nIter" ] = pixFitDict ["nIter" ]
428- outs ["AIC" ] = pixFitDict ["AIC" ].astype ("float32" )
426+ outs ["AIC" ] = pixFitDict ["AIC" ]
427+ outs ["covar" ] = pixFitDict ["pcov" ]
428+ outs ["reference_frequency_Hz" ] = pixFitDict ["reference_frequency_Hz" ]
429429
430430 return outs
431431
@@ -501,7 +501,11 @@ def make_model_I(
501501
502502 coeffs = np .array ([mskArr ] * 6 )
503503 coeffs_error = np .array ([mskArr ] * 6 )
504+ reffreq = np .squeeze (np .array ([mskArr ]))
505+
506+ covars = np .array ([[mskArr ] * 6 ] * 6 )
504507 datacube = np .squeeze (datacube )
508+
505509 # Select only the spectra with emission
506510 srcData = np .rot90 (datacube [:, mskSrc > 0 ])
507511
@@ -547,36 +551,72 @@ def make_model_I(
547551 for _ , an in enumerate (xy ):
548552 i , x , y = an
549553
550- modelIcube [:, x , y ] = results [_ ]["I" ]
554+ modelIcube [:, x , y ] = results [i ]["I" ]
555+ reffreq [x , y ] = results [i ]["reference_frequency_Hz" ]
556+ covars [:, :, x , y ] = results [i ]["covar" ]
551557
552558 for k , j , l in zip (
553- range (len (coeffs )), results [_ ]["coeffs" ], results [_ ]["coeffs_err" ]
559+ range (len (coeffs )), results [i ]["coeffs" ], results [i ]["coeffs_err" ]
554560 ):
555561 coeffs [5 - k , x , y ] = j
556562 coeffs_error [5 - k , x , y ] = l
557563
558- header ["HISTORY" ] = "Stokes I model fitted by RM-Tools"
564+ headcoeff ["HISTORY" ] = "Stokes I model fitted by RM-Tools"
559565 if polyOrd < 0 :
560- header ["HISTORY" ] = (
566+ headcoeff ["HISTORY" ] = (
561567 f"Fit model is dynamic order { fit_function } -polynomial, max order { - polyOrd } "
562568 )
563569 else :
564- header ["HISTORY" ] = f"Fit model is { polyOrd } -order { fit_function } -polynomial"
570+ headcoeff ["HISTORY" ] = f"Fit model is { polyOrd } -order { fit_function } -polynomial"
565571
566- print ("Saving mask image." )
567- savefits_mask (data = mskSrc , header = header , outDir = outDir , prefixOut = prefixOut )
572+ if verbose :
573+ print ("Saving mask image." )
574+ savefits_mask (data = mskSrc , header = headcoeff , outDir = outDir , prefixOut = prefixOut )
568575
569- print ("Saving model I coefficients." )
576+ if verbose :
577+ print ("Saving model I coefficients." )
570578 savefits_Coeffs (
571579 data = coeffs ,
572580 dataerr = coeffs_error ,
573- header = header ,
581+ header = headcoeff ,
574582 polyOrd = polyOrd ,
575583 outDir = outDir ,
576584 prefixOut = prefixOut ,
577585 )
578586
579- print ("Saving model I cube image. " )
587+ # Save frequency map
588+ head_freq = headcoeff .copy ()
589+ head_freq ["BUNIT" ] = "Hz"
590+ if "BTYPE" in headcoeff :
591+ del headcoeff ["BTYPE" ]
592+
593+ outname = os .path .join (outDir , prefixOut + "reffreq.fits" )
594+ pf .writeto (outname , reffreq , head_freq , overwrite = True )
595+
596+ # Save covariance maps -- these are necessary if/when converting the model
597+ # reference frequency.
598+ # Structure will be a single file as a 4D cube, with the 3rd and 4th dimensions
599+ # iterating over the two axes of the covariance matrix.
600+ head_covar = headcoeff .copy ()
601+ head_covar ["NAXIS" ] = 4
602+ head_covar ["NAXIS3" ] = 6
603+ head_covar ["NAXIS4" ] = 6
604+ head_covar ["CTYPE3" ] = "INDEX"
605+ head_covar ["CTYPE4" ] = "INDEX"
606+ head_covar ["CRVAL3" ] = 0
607+ head_covar ["CRVAL4" ] = 0
608+ head_covar ["CDELT3" ] = 1
609+ head_covar ["CDELT4" ] = 1
610+ head_covar ["CRPIX3" ] = 1
611+ head_covar ["CRPIX4" ] = 1
612+ head_covar ["CUNIT3" ] = ""
613+ head_covar ["CUNIT4" ] = ""
614+
615+ outname = os .path .join (outDir , prefixOut + "covariance.fits" )
616+ pf .writeto (outname , covars , head_covar , overwrite = True )
617+
618+ if verbose :
619+ print ("Saving model I cube image. " )
580620 savefits_model_I (data = modelIcube , header = header , outDir = outDir , prefixOut = prefixOut )
581621
582622 np .savetxt (os .path .join (outDir , prefixOut + "noise.dat" ), rms_Arr )
0 commit comments