@@ -158,6 +158,32 @@ def intracranial_mask(segmentation: Segmentation, csf_mask: MRIData) -> MRIData:
158158
159159 return mri_data
160160
161+ def parenchymal_mask (intracranial_mask : MRIData , csf_mask : MRIData ):
162+ """
163+ I/O wrapper for generating and saving an parenchymal mask from
164+ previously generated intracranial and CSF masks
165+
166+ Loads the masks, verifies they share the same physical coordinate space, and
167+ compute the difference intracranial - CSF
168+
169+ Args:
170+ intracranial_mask (MRIData): The intracranial mask (MRIData), \
171+ generated by the intracranial mask module.
172+ csf_mask (MRIData): The CSF mask (MRIData), generated by the csf mask module.
173+
174+ Returns:
175+ MRIData: An MRIData object containing the parenchymal mask.
176+ """
177+
178+ # Validate spatial alignment before array operations
179+ assert_same_space (intracranial_mask , csf_mask )
180+
181+ # Parenchymal mask is intracrnial mask - CSF = intracranial && !CSF
182+ diff_mask = np .logical_and (intracranial_mask .data , np .logical_not (csf_mask .data ))
183+ mri_data = MRIData (data = diff_mask , affine = intracranial_mask .affine )
184+
185+ return mri_data
186+
161187
162188def add_arguments (
163189 parser : argparse .ArgumentParser ,
@@ -195,9 +221,28 @@ def add_arguments(
195221 )
196222 intracranial_mask_parser .add_argument ("-o" , "--output" , type = Path , help = "Desired output path for the resulting mask" )
197223
224+
225+ parenchymal_mask_parser = subparser .add_parser (
226+ "parenchymal" , help = "Compute parenchymal mask" , formatter_class = parser .formatter_class
227+ )
228+ parenchymal_mask_parser .add_argument (
229+ "--csf-mask-path" ,
230+ type = Path ,
231+ help = "Path to the CSF mask NIfTI file, generated by \
232+ the csf mask module, i.e. mritk mask csf" ,
233+ )
234+ parenchymal_mask_parser .add_argument (
235+ "--intracranial-mask-path" ,
236+ type = Path ,
237+ help = "Path to the intracranial mask NIfTI file, generated by \
238+ the csf mask module, i.e. mritk mask intracranial" ,
239+ )
240+ parenchymal_mask_parser .add_argument ("-o" , "--output" , type = Path , help = "Desired output path for the resulting mask" )
241+
198242 if extra_args_cb is not None :
199243 extra_args_cb (csf_mask_parser )
200244 extra_args_cb (intracranial_mask_parser )
245+ extra_args_cb (parenchymal_mask_parser )
201246
202247
203248def dispatch (args ):
@@ -213,5 +258,11 @@ def dispatch(args):
213258 csf_mask = MRIData .from_file (args .pop ("csf_mask_path" ), dtype = np .single ),
214259 )
215260 intracranial_mask_data .save (args .pop ("output" ), dtype = np .uint8 )
261+ elif command == "parenchymal" :
262+ parenchymal_mask_data = parenchymal_mask (
263+ intracranial_mask = MRIData .from_file (args .pop ("intracranial_mask_path" ), dtype = np .single ),
264+ csf_mask = MRIData .from_file (args .pop ("csf_mask_path" ), dtype = np .single ),
265+ )
266+ parenchymal_mask_data .save (args .pop ("output" ), dtype = np .uint8 )
216267 else :
217268 raise ValueError (f"Unknown mask command: { command } " )
0 commit comments