3131 LO_POSITION_TO_ELEVATION_ANGLE ,
3232 LO_SW_ANGULAR_VARIABLE_NAMES ,
3333 LO_SW_PICKUP_ION_SPECIES_VARIABLE_NAMES ,
34- LO_SW_SPECIES_VARIABLE_NAMES ,
34+ LO_SW_SOLAR_WIND_SPECIES_VARIABLE_NAMES ,
3535 NSW_POSITIONS ,
36+ PIXEL_ORIENTATIONS ,
3637 PUI_POSITIONS ,
3738 SOLAR_WIND_POSITIONS ,
3839 SW_POSITIONS ,
@@ -354,11 +355,14 @@ def process_lo_angular_intensity(
354355 positions ,
355356 average_across_positions = False ,
356357 )
358+
357359 # transform positions to elevation angles
358360 if positions == SW_POSITIONS :
359361 pos_to_el = LO_POSITION_TO_ELEVATION_ANGLE ["sw" ]
362+ position_index_to_adjust = 0
360363 elif positions == NSW_POSITIONS :
361364 pos_to_el = LO_POSITION_TO_ELEVATION_ANGLE ["nsw" ]
365+ position_index_to_adjust = 9
362366 else :
363367 raise ValueError ("Unknown positions for elevation angle mapping." )
364368
@@ -369,6 +373,8 @@ def process_lo_angular_intensity(
369373 [pos_to_el [pos ] for pos in dataset ["inst_az" ].data ],
370374 )
371375 )
376+ # add uncertainties to species list
377+ species_list = species_list + [f"unc_{ var } " for var in species_list ]
372378 # Take the mean across elevation angles and restore the original dimension order
373379 dataset_converted = (
374380 dataset [species_list ]
@@ -383,8 +389,41 @@ def process_lo_angular_intensity(
383389 dataset = dataset .assign_coords (
384390 spin_angle = ("spin_sector" , dataset ["spin_sector" ].data * 15.0 + 7.5 )
385391 )
386-
387392 dataset = dataset .drop_vars (species_list ).merge (dataset_converted )
393+ # Positions 0 and 10 only observe half of the 24 spins for each esa step.
394+ # To account for this, we replicate the counts observed in position 0 and 10 for
395+ # each esa step to either spin angles 0-11 or 12-23, depending on the pixel
396+ # orientation (A/B). See section 11.2.2 of the CoDICE algorithm document
397+ a_inds = np .array (
398+ [pos for pos , orientation in PIXEL_ORIENTATIONS .items () if orientation == "A" ]
399+ )
400+ b_inds = np .array (
401+ [pos for pos , orientation in PIXEL_ORIENTATIONS .items () if orientation == "B" ]
402+ )
403+
404+ position_index = position_index_to_adjust
405+ for species in species_list :
406+ # Determine the correct spin indices based on the position
407+ spin_sectors = dataset ["spin_sector" ].data
408+ spin_inds_1 = np .where (spin_sectors >= 12 )[0 ]
409+ spin_inds_2 = np .where (spin_sectors < 12 )[0 ]
410+ # if position_index is 9, swap the spin indices
411+ if position_index == 9 :
412+ spin_inds_1 , spin_inds_2 = spin_inds_2 , spin_inds_1
413+
414+ # Assign the values to the correct positions and spin sectors
415+ dataset [species ].values [
416+ :, a_inds [:, np .newaxis ], spin_inds_1 , position_index
417+ ] = dataset [species ].values [
418+ :, a_inds [:, np .newaxis ], spin_inds_2 , position_index
419+ ]
420+
421+ dataset [species ].values [
422+ :, b_inds [:, np .newaxis ], spin_inds_2 , position_index
423+ ] = dataset [species ].values [
424+ :, b_inds [:, np .newaxis ], spin_inds_1 , position_index
425+ ]
426+
388427 return dataset
389428
390429
@@ -777,7 +816,6 @@ def process_codice_l2(
777816 # This should get science files since ancillary or spice doesn't have data_type
778817 # as data level.
779818 file_path = dependencies .get_file_paths (descriptor = descriptor )[0 ]
780-
781819 # Now form product name from descriptor
782820 descriptor = ScienceFilePath (file_path ).descriptor
783821 dataset_name = f"imap_codice_l2_{ descriptor } "
@@ -790,19 +828,23 @@ def process_codice_l2(
790828 "imap_codice_l2_lo-nsw-angular" ,
791829 "imap_codice_l2_lo-sw-angular" ,
792830 ]:
831+ cdf_attrs = ImapCdfAttributes ()
832+ cdf_attrs .add_instrument_global_attrs ("codice" )
833+
793834 l2_dataset = load_cdf (file_path ).copy ()
794835
795836 geometric_factor_lookup = get_geometric_factor_lut (dependencies )
796837 efficiency_lookup = get_efficiency_lut (dependencies )
797838 geometric_factors = compute_geometric_factors (
798839 l2_dataset , geometric_factor_lookup
799840 )
841+
800842 if dataset_name == "imap_codice_l2_lo-sw-species" :
801843 # Filter the efficiency lookup table for solar wind efficiencies
802844 efficiencies = efficiency_lookup [efficiency_lookup ["product" ] == "sw" ]
803845 # Calculate the pickup ion sunward solar wind intensities using equation
804846 # described in section 11.2.3 of algorithm document.
805- process_lo_species_intensity (
847+ l2_dataset = process_lo_species_intensity (
806848 l2_dataset ,
807849 LO_SW_PICKUP_ION_SPECIES_VARIABLE_NAMES ,
808850 geometric_factors ,
@@ -811,25 +853,31 @@ def process_codice_l2(
811853 )
812854 # Calculate the sunward solar wind species intensities using equation
813855 # described in section 11.2.3 of algorithm document.
814- process_lo_species_intensity (
856+ l2_dataset = process_lo_species_intensity (
815857 l2_dataset ,
816- LO_SW_SPECIES_VARIABLE_NAMES ,
858+ LO_SW_SOLAR_WIND_SPECIES_VARIABLE_NAMES ,
817859 geometric_factors ,
818860 efficiencies ,
819861 SOLAR_WIND_POSITIONS ,
820862 )
863+ l2_dataset .attrs .update (
864+ cdf_attrs .get_global_attributes ("imap_codice_l2_lo-sw-species" )
865+ )
821866 elif dataset_name == "imap_codice_l2_lo-nsw-species" :
822867 # Filter the efficiency lookup table for non-solar wind efficiencies
823868 efficiencies = efficiency_lookup [efficiency_lookup ["product" ] == "nsw" ]
824869 # Calculate the non-sunward species intensities using equation
825870 # described in section 11.2.3 of algorithm document.
826- process_lo_species_intensity (
871+ l2_dataset = process_lo_species_intensity (
827872 l2_dataset ,
828873 LO_NSW_SPECIES_VARIABLE_NAMES ,
829874 geometric_factors ,
830875 efficiencies ,
831876 NSW_POSITIONS ,
832877 )
878+ l2_dataset .attrs .update (
879+ cdf_attrs .get_global_attributes ("imap_codice_l2_lo-nsw-species" )
880+ )
833881 elif dataset_name == "imap_codice_l2_lo-sw-angular" :
834882 efficiencies = efficiency_lookup [efficiency_lookup ["product" ] == "sw" ]
835883 # Calculate the sunward solar wind angular intensities using equation
@@ -841,6 +889,9 @@ def process_codice_l2(
841889 efficiencies ,
842890 SW_POSITIONS ,
843891 )
892+ l2_dataset .attrs .update (
893+ cdf_attrs .get_global_attributes ("imap_codice_l2_lo-sw-angular" )
894+ )
844895 if dataset_name == "imap_codice_l2_lo-nsw-angular" :
845896 # Calculate the non sunward angular intensities
846897 efficiencies = efficiency_lookup [efficiency_lookup ["product" ] == "nsw" ]
@@ -851,7 +902,9 @@ def process_codice_l2(
851902 efficiencies ,
852903 NSW_POSITIONS ,
853904 )
854-
905+ l2_dataset .attrs .update (
906+ cdf_attrs .get_global_attributes ("imap_codice_l2_lo-nsw-angular" )
907+ )
855908 if dataset_name in [
856909 "imap_codice_l2_hi-counters-singles" ,
857910 "imap_codice_l2_hi-counters-aggregated" ,
0 commit comments