virtools: A tool for Radiometric Calibration of DAWN VIR data

The DAWN VIR Calibration Package is essential for transforming raw data collected by the Visible and Infrared Spectrometer (VIR) onboard NASA's DAWN spacecraft into scientifically meaningful and physically accurate measurements.

The VIR instrument, which observed planetary bodies like Vesta and Ceres, records radiance data in digital numbers (DN) that are affected by various instrumental and environmental artifacts. These include detector noise, dark current, stray light, bad pixels, spectral misalignments, and radiometric inconsistencies.

Without calibration, the raw data from VIR are not directly usable for scientific analysis, as they do not accurately represent the surface reflectance of the observed bodies.

The calibration package provides a suite of algorithms and correction procedures—often derived from both pre-flight laboratory characterizations and in-flight observations—that convert these raw measurements into radiometrically calibrated, artifact-corrected data products. These are suitable for applications such as mineralogical mapping, thermal modeling, surface composition studies, and planetary geophysics.

In short, the calibration package is a critical preprocessing step that ensures data fidelity, enabling reliable interpretation of planetary surfaces and supporting high-quality scientific research.

–With calibrated sight and spectral flame, We cut through the lies that corrupt the light. Stand tall, like a Hashira of knowledge— Power up… and let this cosmic battle begin!

🪶 Poem Through Vesta’s glow and Ceres’ shade,
The VIR spectrometer softly played.
But raw the light, not clean nor bright,
Masked by noise that veils the sight.

Dark current flowed beneath each scan,
Artifacts danced where truth began.
Odd-even shifts broke spectral grace,
And radiance lost its rightful place.

Yet code arose, both sharp and wise,
To lift the veil from distant skies.
Corrected spectra, clear and grand,
Revealed the story in rock and sand.

Now calibrated, pure and wide,
The data sings of time and tide.
In every cube, a tale made right—
A world reborn in measured light.

But the path ahead extends afar,
Each fix a step, not final star.
No end to truth, no perfect scheme—
Just clearer maps of a deeper dream.

So start with code both clear and small,
Though simple, it may yet reveal all.
For in this sea without a shore,
Each better answer calls for more.

–K.A.Rousan

📝 Note virtools is a python-package developed by myself. To use download it from github or follow this blog.

Introduction to the Data and it's format

To use the package, we first have to know what is the data we are working with. VIR actually uses the pushbroom method to capture images of the ceres surface in different wavelengths.

The left image is a diagram to show pushbroom method. There, we can see a detector array. This array actually take a image along it's length and then it is moved in a direction perpendicular to it's length giving us the image of the surface. The detector has many small detectors(pixels). Those are called samples. This value is obviously fixed (\(s=256\)). As the detector moves, it takes images. Each of these are called lines (in the diagram the rectangular patches on ground). This number is not constant, it can vary data file to data file.

The data is stored for \(b=432\) different wavelengths, i.e., the image is taken for \(432\) different wavelengths. We can think the data as different images (sample & line) for different wavelengths stacked together. So, the image is sort of like cube as shown in the previous image. One axis is band axis, one is sample axis and other is sample axis. So, if I store the cube file data as an numpy array C, then C[b,s,l] represent the value of data for band no. \(b\), sample no. \(s\) and line no. \(l\).

TypeCalled
For fixed band C[b,:,:]Image
For fixed sample C[:,s,:]Slice
For fixed line C[:,:,l]Frame

When the device takes the data, It generates \(4\) files:

  1. .LBL file : This contains info about device name, target name, wavelengths, band index, SPICE file details, distance from sun and all other things. An example of the file is here.

PDS_VERSION_ID = PDS3                                                         
LABEL_REVISION_NOTE = "MTC_11-10-2011"                                        
                                                                              
/* Dataset and Product Information */                                         
DATA_SET_NAME = "DAWN VIR RAW (EDR) CERES INFRARED SPECTRA V1.0"              
DATA_SET_ID = "DAWN-A-VIR-2-EDR-IR-CERES-SPECTRA-V1.0"                        
PRODUCT_ID = "VIR_IR_1A_1_493156585"                                          
PRODUCT_TYPE = EDR                                                            
PRODUCER_FULL_NAME = "M. C. DE SANCTIS"                                       
PRODUCER_INSTITUTION_NAME = "ISTITUTO NAZIONALE DI ASTROFISICA"               
PRODUCT_CREATION_TIME = 2016-10-13T19:33:39.186                               
PRODUCT_VERSION_ID = "01"                                                     
                                                                              
/* File Information */                                                        
RECORD_TYPE = FIXED_LENGTH                                                    
RECORD_BYTES = 512                                                            
FILE_RECORDS = 15120                                                          
LABEL_RECORDS = 46                                                            
                                                                              
/* Time Information */                                                        
START_TIME = 2015-08-18T07:55:19.569                                          
STOP_TIME = 2015-08-18T08:07:59.799                                           
IMAGE_MID_TIME = 2015-08-18T08:01:39.684                                      
SPACECRAFT_CLOCK_START_COUNT = "1/493156585.1098"                             
SPACECRAFT_CLOCK_STOP_COUNT = "1/493157346.7980"                              
                                                                              
/* Mission description parameters */                                          
INSTRUMENT_HOST_NAME = "DAWN"                                                 
INSTRUMENT_HOST_ID = "DAWN"                                                   
MISSION_PHASE_NAME = "CERES SCIENCE HAMO (CSH)"                               
                                                                              
/* Instrument description parameters */                                       
INSTRUMENT_NAME = "VISIBLE AND INFRARED SPECTROMETER"                         
INSTRUMENT_ID = "VIR"                                                         
INSTRUMENT_TYPE = "IMAGING SPECTROMETER"                                      
                                                                              
/* Celestial Geometry                                       */                
RIGHT_ASCENSION                  =  279.965 <degrees>                         
DECLINATION                      =  -62.231 <degrees>                         
TWIST_ANGLE                      =  227.917 <degrees>                         
CELESTIAL_NORTH_CLOCK_ANGLE      =  312.083 <degrees>                         
QUATERNION                       = (  0.11612,                                
                                     -0.31567,                                
                                     -0.91802,                                
                                      0.21000 )                               
QUATERNION_DESC                  = "                                          
     Above parameters are calculated at the center time of the observation    
     which is 2015-08-18T08:01:39.684.  The quaternion has the form:          
     w, x, y, z (i.e. SPICE format)."                                         
                                                                              
/* Solar geometry                                          */                 
SPACECRAFT_SOLAR_DISTANCE        =   441765162.5 <km>                         
SC_SUN_POSITION_VECTOR           = ( -259675440.2 <km>,                       
                                      299958230.3 <km>,                       
                                      194294067.4 <km> )                      
                                                                              
SC_SUN_VELOCITY_VECTOR           = ( -13.502 <km/s>,                          
                                      -9.829 <km/s>,                          
                                      -1.718 <km/s> )                         
                                                                              
/* SPICE Kernels                                            */                
SPICE_FILE_NAME                  = "DAWN_CSH_R01.TM"                          
                                                                              
TARGET_NAME                      = "CAL LAMP"                                 
TARGET_TYPE                      = "CALIBRATION"                              
                                                                              
/* COORDINATE SYSTEM                                        */                
COORDINATE_SYSTEM_NAME           = "N/A"                                      
COORDINATE_SYSTEM_CENTER_NAME    = "N/A"                                      
                                                                              
/* Geometry in "IAU_VESTA" coordinates from SPICE         */                  
SUB_SPACECRAFT_LATITUDE          = "N/A"                                      
SUB_SPACECRAFT_LONGITUDE         = "N/A"                                      
SUB_SPACECRAFT_AZIMUTH           = "N/A"                                      
SPACECRAFT_ALTITUDE              = "N/A"                                      
TARGET_CENTER_DISTANCE           = "N/A"                                      
SC_TARGET_POSITION_VECTOR        = ( "N/A",                                   
                                     "N/A",                                   
                                     "N/A" )                                  
                                                                              
SC_TARGET_VELOCITY_VECTOR        = ( "N/A",                                   
                                     "N/A",                                   
                                     "N/A" )                                  
                                                                              
LOCAL_HOUR_ANGLE                 = "N/A"                                      
SUB_SOLAR_LATITUDE               = "N/A"                                      
SUB_SOLAR_LONGITUDE              = "N/A"                                      
SUB_SOLAR_AZIMUTH                = "N/A"                                      
                                                                              
/* Illumination                                             */                
INCIDENCE_ANGLE                  = "N/A"                                      
EMISSION_ANGLE                   = "N/A"                                      
PHASE_ANGLE                      = "N/A"                                      
                                                                              
/* Image parameters                                         */                
SLANT_DISTANCE                   = "N/A"                                      
MINIMUM_LATITUDE                 = "N/A"                                      
CENTER_LATITUDE                  = "N/A"                                      
MAXIMUM_LATITUDE                 = "N/A"                                      
WESTERNMOST_LONGITUDE            = "N/A"                                      
CENTER_LONGITUDE                 = "N/A"                                      
EASTERNMOST_LONGITUDE            = "N/A"                                      
HORIZONTAL_PIXEL_SCALE           = "N/A"                                      
VERTICAL_PIXEL_SCALE             = "N/A"                                      
NORTH_AZIMUTH                    = "N/A"                                      
ORBIT_NUMBER                     = "N/A"                                      
                                                                              
/* Data description parameters */                                             
PROCESSING_LEVEL_ID = "2"                                                     
DATA_QUALITY_ID = "1"                                                         
DATA_QUALITY_DESC = "0:INCOMPLETE; 1:COMPLETE"                                
TELEMETRY_SOURCE_ID = "EGSE"                                                  
CHANNEL_ID = "IR"                                                             
SOFTWARE_VERSION_ID = "EGSE V1.14,AMDLSpace"                                  
                                                                              
/* Instrument status */                                                       
INSTRUMENT_MODE_ID = "C_H_SPE_H_SPA_F"                                        
INSTRUMENT_MODE_DESC =                                                        
 "S_H_SPE_H_SPA_F: Science, high spectral high spatial, Full slit             
  S_H_SPE_L_SPA_F: Science, high spectral low spatial, Full slit              
  S_H_SPE_L_SPA_F_SUM: Science, high spectral low spatial, Summing            
  S_L_SPE_H_SPA_F: Science, Low spectral high spatial, Full slit              
  S_L_SPE_L_SPA_F: Science, Low spectral low spatial, Full slit               
  S_L_SPE_L_SPA_F_SUM: Science, Low spectral low spatial, Summing             
  S_H_SPE_H_SPA_Q: Science, high spectral high spatial, Quarter slit          
  S_L_SPE_H_SPA_Q: Science, low spectral high spatial, Quarter slit           
  S_H_SPE_L_SPA_F_MEA: Science, high spectral low spatial, Meaning            
  S_L_SPE_L_SPA_F_MEA: Science, low spectral low spatial, Meaning             
  C_H_SPE_H_SPA_F: Calibration, high spectral high spatial, Full slit         
  C_H_SPE_L_SPA_F: Calibration, high spectral low spatial, Full slit          
  SPARE: CALIBRATION Spare                                                    
  C_L_SPE_H_SPA_F: Calibration, low spectral high spatial, Full slit          
  C_L_SPE_L_SPA_F: Calibration, low spectral low spatial, Full slit           
  C_H_SPE_H_SPA_Q: Calibration, high spectral high spatial, Quarter slit      
  C_L_SPE_H_SPA_Q: Calibration, low spectral high spatial, Quarter slit"      
ENCODING_TYPE = "N/A"                                                         
SCAN_MODE_ID = "5"                                                            
DAWN:SCAN_PARAMETER = (0.1, 0.1, 0.26, 25)                                    
SCAN_PARAMETER_DESC = ("SCAN_START_ANGLE", "SCAN_STOP_ANGLE",                 
 "SCAN_STEP_ANGLE","SCAN_STEP_NUMBER")                                        
DAWN:SCAN_PARAMETER_UNIT = ("DEGREES", "DEGREES", "DEGREES", "DIMENSIONLESS") 
FRAME_PARAMETER = (0.0, 1, 20, 0)                                             
FRAME_PARAMETER_DESC = ("EXPOSURE_DURATION", "FRAME_SUMMING",                 
"EXTERNAL_REPETITION_TIME", "DARK_ACQUISITION_RATE")                          
DAWN:FRAME_PARAMETER_UNIT = ("S", "DIMENSIONLESS", "S", "DIMENSIONLESS")      
DAWN:VIR_IR_START_X_POSITION=0                                                
DAWN:VIR_IR_START_Y_POSITION=0                                                
MAXIMUM_INSTRUMENT_TEMPERATURE = (84.5, 135.6, 136.6, 79.0)                   
INSTRUMENT_TEMPERATURE_POINT = ("FOCAL_PLANE", "TELESCOPE", "SPECTROMETER",   
"CRYOCOOLER")                                                                 
DAWN:INSTRUMENT_TEMPERATURE_UNIT = ("K", "K", "K", "K")                       
PHOTOMETRIC_CORRECTION_TYPE = "NONE"                                          
                                                                              
/* Pointers to first record of objects in file */                             
^HISTORY = 48                                                                 
OBJECT = HISTORY                                                              
END_OBJECT = HISTORY                                                          
^QUBE = "VIR_IR_1A_1_493156585_1.QUB"                                         
                                                                              
/* Description of the object contained in the file */                         
OBJECT = QUBE                                                                 
                                                                              
/*    Standard cube Keywords */                                               
 AXES = 3                                                                     
 AXIS_NAME = (BAND, SAMPLE, LINE)                                             
 CORE_ITEMS = ( 432, 256, 35 )                                                
 CORE_ITEM_BYTES = 2                                                          
 CORE_ITEM_TYPE = MSB_INTEGER                                                 
 CORE_BASE = 0.0                                                              
 CORE_MULTIPLIER = 1.0                                                        
 CORE_VALID_MINIMUM = 0                                                       
 CORE_NULL = -32768                                                           
 CORE_LOW_REPR_SATURATION = -32767                                            
 CORE_LOW_INSTR_SATURATION = -32767                                           
 CORE_HIGH_REPR_SATURATION = -32767                                           
 CORE_HIGH_INSTR_SATURATION = -32767                                          
 CORE_NAME = "RAW DATA NUMBER"                                                
 CORE_UNIT = DIMENSIONLESS                                                    
                                                                              
/*  Suffix definition */                                                      
 SUFFIX_BYTES = 4                                                             
 SUFFIX_ITEMS = (    0,   0,    0)                                            
                                                                              
/* Spectral axis description */                                               
                                                                              
    GROUP = BAND_BIN                                                          
                                                                              
    BAND_BIN_CENTER =                                                         
(1.021,1.030,1.040,1.049,1.059,....)
 BAND_BIN_WIDTH  =                                                       
(0.0140,0.0140,0.0140,0.0140,......)
BAND_BIN_UNIT = MICROMETER                                                   
                                                                              
    BAND_BIN_ORIGINAL_BAND =                                                  
(1,2,3,4,5,6,7,8,9,10,11,12,.......)
END_GROUP = BAND_BIN                                                          
                                                                              
END_OBJECT                     = QUBE                                         
END                                                                           
                                                                              
OBJECT = HISTORY                                                              

END_OBJECT = HISTORY
  1. .QUB file: This contains the actual data. This stores the image as Digital Number as normally happens for CCD type devices. This is the data we have to convert in radinace or reflectance. We can't directly open this data (so can't show you here).

  2. HK_.LBL file: This contains the column names for the other data file of detail information of the device like temperature of detector, temp of spectroscope, shutter status, exposure time for each lines.

PDS_VERSION_ID                = "PDS3"                                        
DATA_SET_ID                   = "DAWN-A-VIR-2-EDR-IR-CERES-SPECTRA-V1.0"      
PRODUCT_ID                    = "VIR_IR_1A_1_493156585_HK"                    
PRODUCT_TYPE                  = "ENGINEERING_DATA"                            
PRODUCT_VERSION_ID            = "01"                                          
PRODUCT_CREATION_TIME         = 2016-10-13T19:33:39.186                       
                                                                              
RECORD_TYPE                   = FIXED_LENGTH                                  
RECORD_BYTES                  = 288                                           
FILE_RECORDS                  = 35                                            
                                                                              
START_TIME                    = 2015-08-18T07:55:19.569                       
STOP_TIME                     = 2015-08-18T08:07:59.799                       
SPACECRAFT_CLOCK_START_COUNT  = "1/493156585.1098"                            
SPACECRAFT_CLOCK_STOP_COUNT   = "1/493157346.7980"                            
                                                                              
INSTRUMENT_HOST_NAME          = "DAWN"                                        
INSTRUMENT_HOST_ID            = "DAWN"                                        
MISSION_PHASE_NAME            = "CERES SCIENCE HAMO (CSH)"                    
TARGET_NAME                   = "CAL LAMP"                                    
INSTRUMENT_NAME               = "VISIBLE AND INFRARED SPECTROMETER"           
INSTRUMENT_ID                 = "VIR"                                         
DESCRIPTION                   = ""                                            
                                                                              
^TABLE                        = "VIR_IR_1A_1_493156585_HK_1.TAB"              
OBJECT                        = TABLE                                         
  INTERCHANGE_FORMAT          = ASCII                                         
  ROWS                        = 35                                            
  COLUMNS                     = 33                                            
  ROW_BYTES                   = 288                                           
  DESCRIPTION                 = ""                                            
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "VERSION, TYPE, SECONDARY HEADER FLAG"        
    COLUMN_NUMBER             = 1                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 1                                             
    BYTES                     = 2                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "APID"                                        
    COLUMN_NUMBER             = 2                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 4                                             
    BYTES                     = 3                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "PACKET SEQUENCE CONTROL"                     
    COLUMN_NUMBER             = 3                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 8                                             
    BYTES                     = 5                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "PACKETS LENGTH"                              
    COLUMN_NUMBER             = 4                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 14                                            
    BYTES                     = 4                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "SCET TIME (CLOCK)"                           
    COLUMN_NUMBER             = 5                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_REAL                                    
    START_BYTE                = 19                                            
    BYTES                     = 12                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "FRAME NUMBER"                                
    COLUMN_NUMBER             = 6                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 34                                            
    BYTES                     = 3                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "FRAME COUNT"                                 
    COLUMN_NUMBER             = 7                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 38                                            
    BYTES                     = 3                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "SUBFRAME COUNT"                              
    COLUMN_NUMBER             = 8                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 42                                            
    BYTES                     = 2                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "PACKETS COUNT"                               
    COLUMN_NUMBER             = 9                                             
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = ASCII_INTEGER                                 
    START_BYTE                = 45                                            
    BYTES                     = 2                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "SHUTTER STATUS"                              
    COLUMN_NUMBER             = 10                                            
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = CHARACTER                                     
    START_BYTE                = 48                                            
    BYTES                     = 8                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "CHANNEL ID"                                  
    COLUMN_NUMBER             = 11                                            
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = CHARACTER                                     
    START_BYTE                = 57                                            
    BYTES                     = 3                                             
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "COMPRESSION MODE"                            
    COLUMN_NUMBER             = 12                                            
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = CHARACTER                                     
    START_BYTE                = 61                                            
    BYTES                     = 20                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "SPECTRAL RANGE"                              
    COLUMN_NUMBER             = 13                                            
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = CHARACTER                                     
    START_BYTE                = 82                                            
    BYTES                     = 24                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "CURRENT MODE"                                
    COLUMN_NUMBER             = 14                                            
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = CHARACTER                                     
    START_BYTE                = 107                                           
    BYTES                     = 12                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "CURRENT SUBMODE"                             
    COLUMN_NUMBER             = 15                                            
    UNIT                      = "N/A"                                         
    DATA_TYPE                 = CHARACTER                                     
    START_BYTE                = 120                                           
    BYTES                     = 14                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "IR EXPO"                                     
    COLUMN_NUMBER             = 16                                            
    UNIT                      = "S"                                           
    DATA_TYPE                 = ASCII_REAL                                    
    START_BYTE                = 135                                           
    BYTES                     = 10                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "IR TEMP"                                     
    COLUMN_NUMBER             = 17                                            
    UNIT                      = "K"                                           
    DATA_TYPE                 = ASCII_REAL                                    
    START_BYTE                = 146                                           
    BYTES                     = 10                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "CCD EXPO"                                    
    COLUMN_NUMBER             = 18                                            
    UNIT                      = "S"                                           
    DATA_TYPE                 = ASCII_REAL                                    
    START_BYTE                = 157                                           
    BYTES                     = 10                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN                                        
                                                                              
  OBJECT                      = COLUMN                                        
    NAME                      = "CCD TEMP"                                    
    COLUMN_NUMBER             = 19                                            
    UNIT                      = "K"                                           
    DATA_TYPE                 = ASCII_REAL                                    
    START_BYTE                = 168                                           
    BYTES                     = 10                                            
    DESCRIPTION               = ""                                            
  END_OBJECT                  = COLUMN
  1. HK.TAB file: This contains the data corresponding to the table names in the previous HK.LBL file. It looks like,

8 102     0 1017 493156585.1020   5   1  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.000000  84.482243   0.000000 170.251659   0.066178   0.997557 135.007163 137.163745  77.109671 140.777476   0.007059 142.686342  0  0  0  0  9216  1
 8 102   456 1017 493156605.1000   5   2  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.000000  84.482243   0.000000 170.251659   0.066178   0.997557 135.065449 137.192888  77.672624 140.762904   0.007071 142.700913  0  0  0  0  9216  1
 8 102   912 1017 493156625.1000   5   3  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.000000  84.482243   0.000000 170.222171   0.066178   0.997557 135.036306 137.178316  77.672624 140.748333   0.007383 142.686342  0  0  0  0  9216  1
 8 102  1368 1017 493156645.1000   5   4  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.000000  84.513481   0.000000 170.207427   0.066178   0.997557 135.036306 137.163745  77.561390 140.748333   0.007151 142.686342  0  0  0  0  9216  1
 8 102  1824 1017 493156665.1000   5   5  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.000000  84.419766   0.000000 170.236915   0.066178   0.997557 135.036306 137.178316  77.673980 140.762904   0.006509 142.686342  0  0  0  0  9216  1
 8 102  2508 1017 493156677.4550   5   1  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.513481   1.000000 170.207427   0.066178   0.997557 135.036306 137.207459  78.949101 140.704618   0.007218 142.700913  0  0  0  0  9216  2
 8 102  2964 1017 493156697.0500   5   2  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.607197   1.000000 170.222171   0.066178   0.997557 135.050877 137.178316  78.639817 140.748333   0.006668 142.671770  0  0  0  0  9216  2
 8 102  3420 1017 493156717.0500   5   3  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.544720   1.000000 170.207427   0.066178   0.997557 135.036306 137.149173  78.641173 140.762904   0.006601 142.671770  0  0  0  0  9216  2
 8 102  3876 1017 493156737.0500   5   4  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.607197   1.000000 170.207427   0.066178   0.997557 135.036306 137.222031  78.753764 140.704618   0.007065 142.715485  0  0  0  0  9216  2
 8 102  4332 1017 493156757.0500   5   5  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.669674   1.000000 170.222171   0.066178   0.997557 135.050877 137.163745  78.578774 140.748333   0.007206 142.700913  0  0  0  0  9216  2
 8 102  4788 1017 493156769.1400   5   1  0  1   closed  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.669674   1.000000 170.207427   0.066178   0.997557 135.021734 137.178316  79.014214 140.748333   0.007169 142.686342  0  0  0  0  9216  3
 8 102  5244 1017 493156789.0500   5   2  0  1   closed  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.669674   1.000000 170.207427   0.066178   0.997557 134.992591 137.178316  78.725277 140.748333   0.007261 142.686342  0  0  0  0  9216  3
 8 102  5700 1017 493156809.0500   5   3  0  1   closed  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.669674   1.000000 170.207427   0.066178   0.997557 135.007163 137.207459  78.726633 140.777476   0.007187 142.715485  0  0  0  0  9216  3
 8 102  6156 1017 493156829.0500   5   4  0  1   closed  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.607197   1.000000 170.222171   0.066178   0.997557 135.036306 137.163745  78.653382 140.762904   0.006601 142.686342  0  0  0  0  9216  3
 8 102  6612 1017 493156849.0500   5   5  0  1   closed  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.732151   1.000000 170.207427   0.066178   0.997557 135.021734 137.178316  78.722564 140.777476   0.006527 142.700913  0  0  0  0  9216  3
 8 102  6840 1017 493156921.0510   5   1  0  1     open  IR  data_not_compressed  all_spectral_sub-frames  calibration  H_SPE_H_SPA_F   0.500000  84.669674  20.000000 170.310635   0.066178   0.997557 135.021734 137.149173  78.622182 140.748333   0.007200 142.671770  0  0  0  0  9216  4

We have to use these files together to convert the data in the qub file into radiance and reflectance. Let's see now how.

Setting up the package:

First you have to install the package to install it. For now the package is written for IR data. This is quite general so it should work for the visible spectra too. But the detilt function is needed for that, which is not added for now.

To use this package, we have to first install it. For installing here is a bash script (if you want you can just directly download and use from git),

#!/bin/bash
ENV_DIR="./virtools-venv"
REPO_URL="https://github.com/aburousan/virtools.git"
CLONE_DIR="./virtools"

echo "Creating virtual environment in $ENV_DIR"
python3 -m venv "$ENV_DIR"
source "$ENV_DIR/bin/activate"

pip install --upgrade pip setuptools wheel build

echo "Cloning repo..."
rm -rf "$CLONE_DIR"
git clone "$REPO_URL" "$CLONE_DIR"
cd "$CLONE_DIR" || exit 1
pip install numpy scipy matplotlib scikit-image pvl PyWavelets
python3 -m build
pip install dist/*.whl

echo "virtools installed in virtualenv at $ENV_DIR"
echo "To activate: source $ENV_DIR/bin/activate"

This will create a environment in python and install the package there. For installing in conda, use:

#!/bin/bash

ENV_NAME="virtools-env"
PYTHON_VERSION="3.10"
REPO_URL="https://github.com/aburousan/virtools.git"
CLONE_DIR="./virtools"

echo "Creating conda environment: $ENV_NAME"
conda create -y -n "$ENV_NAME" python=$PYTHON_VERSION

source "$(conda info --base)/etc/profile.d/conda.sh"
conda activate "$ENV_NAME"

echo "Cloning repo..."
rm -rf "$CLONE_DIR"
git clone "$REPO_URL" "$CLONE_DIR"
cd "$CLONE_DIR" || exit 1

echo "Installing dependencies..."
conda install -y numpy scipy matplotlib scikit-image pip
pip install pvl PyWavelets build

python3 -m build
pip install dist/*.whl

echo "virtools installed in conda env: $ENV_NAME"

Once these two are ran, the package is installed in your system and you can just activate the environment to run the code.

Importing the data:

The data which is recored is stored in fortran format in MSB format. So, while importing we have to correct the endianness and aslo the array type. There are mainly two functions for importing data:

  1. load_qub_from_lbl is a function which takes lbl and qub file names with location. It will load a dictionary of all lbl file data and a numpy array with qun file data. It also returns a mask (depending on the optional argument flag_mask) of the locations of the saturated and nan value pixels.

  2. load_qub_from_lbl_name is a function which takes only the base folder and lbl file name. It will then load all four data files (lbl file data as previously, qub file data along with hk.lbl and hk.tab data file).

Example:

File_name_unc = "VIR_IR_1A_1_495681682"
base_folder_name = "/Data/rousan/Ceres_Data/DWNCHVIR_I1A-170324/DWNCHVIR_I1A/DATA/20150816_HAMO/20150909_CYCLE3/"
lbl_file_unc = base_folder_name+File_name_unc+"_1.LBL"
qub_file_unc = base_folder_name+File_name_unc+"_1.QUB"
lbl_hk_file_unc = base_folder_name+File_name_unc+"_HK_1.LBL"
tab_hk_file_unc = base_folder_name+File_name_unc+"_HK_1.TAB"

This are the file names with location. Now pass it to the function:

cube_array,lbl_data, flag_mask=load_qub_from_lbl(lbl_file_unc,qub_file_unc,return_flag_mask=True)

The actual data is saved inside the cube_array array. lbl_data contains the meta data. Let's extract the datas from these python numpy aray and meta-data we will need.

bands, samples, lines = lbl_data["shape"]
wvlen_center = lbl_data["wave_length_cen"]
wvlen_width = lbl_data["wave_width"]
wvlen_band_val = lbl_data["wave_length_band_val"]
exposure_time = lbl_data["exposure_time"]
spacecraft_solar_dist = lbl_data["spacecraft_solar_dist"]

Now, we also need the data from house keeping files. For that there are some more functions:

hk = extract_hk_data(lbl_hk_file_unc, tab_hk_file_unc)
exposure_times = np.array(hk["data"]["exposure_time_ir"])
ir_temps = np.array(hk["data"]["ir_temp"])
spec_temps = np.array(hk["data"]["spect_temp"])
closed_index = hk["closed_indexes"]

If we want, we can directly use the other file to import the whole data. wvlen_center contains the wavelength values in \(\mu m\) & wvlen_band_val contains the band values (like eg:\(1,2,3,\cdots,\)). closed_index is contains the index of the lines for which the shutter was closed, hence giving us the dark frames.

Calibration

First thing after importing the data, we need to locate the defective pixels and then interpolate it. I am usingg the spline for that. There is a function for exactly that.

cube_def_rem = fix_defective_pixels_with_spline(cube_array,defective_ir_pixels,wvlen_center,FILTER_BANDS_IR)

Here FILTER_BANDS_IR and defective_ir_pixels are numpy arraies which contains the location of filter regions(OSF regions) and detective pixel locations. This gives us an interpolated data. To see the data(image at a specific wavelength/band no.) we have a function called show_band_image.

show_band_image(cube_def_rem,200,cbar_label="DN")

This gives:

This contains bias,dark current,thermal background and many other things. Now, we will remove these effects to get the actual signal.

After this to model thermal current, we have to use the dark frames. This will be done by using a function which will detect calibration frames in a folder.


–> –>

Hope this helps you in some way. If you like it then share with others if possible.

If you have some queries, do let me know in the comments or contact me using my using the informations that are given on the page About Me.

CC BY-SA 4.0 Kazi Abu Rousan. Last modified: August 05, 2025. Website built with Franklin.jl and the Julia programming language.