QPeace Software

Overview

This document describes briefly and documents software written by Steve Schwartz, originally at Queen Mary, University of London and more recently at Imperial College London, for use with the IDFS software from SwRI as part of the his participation in the Cluster project as Co-Investigator on the PEACE electron instrument. Andrew Fazakerley (MSSL) is the PEACE Principal Investigator.

Standalone user applications such as plotaz and qjas are documented separately. The present pages document the programmer's interface to both high level routines and low level utilities, from which other applications may easily be written. In particular, full functionality is provided by the high-level routines:

Data Fetching

Contents

Copyright and License

This software is made available under the GNU Public License. SwRI IDFS software is licencsed separately and does NOT form part of this software. Some of this software also uses freely available software including the PGPLOT graphics library  and the Qt widget library. These libraries are subject to their own licensing conditions.

Requirements

QPeace software is written mainly in C, with widget applications in C++ using the Qt toolkit.  It is developed primarily on a Linux workstation (Mandrake) and tested regularly on Sun Solaris. Graphics uses the C language interface to the PGPLOT library (see http://www.astro.caltech.edu/~tjp/pgplot/). In order to compile against QPeace modules, users will need appropriate licensing authority for the IDFS software (see www.idfs.org).

Authors

Steve Schwartz (s.schwartz@imperial.ac.uk) is the original author and formal PEACE Co-Investigator.

History

26 November 2000 First issue
22 June 2001 up-dated and expanded
1 July 2002 up-dated to include pitch angle re-binning and custom energy bins
28 February 2005 Version 2: added correction for spacecraft potential, sweep gathering, and related functionality; redefined spin structure.
13 March 2005 Up-date; bug fixes.

Modules Summary


Alphabetic List of All Routines

Routine Module Purpose
add_ev2_kms Qphisc Convert km/s to eV, add specified eV (intended for the s/c potential), and convert back to km/s
add_secs_to_idfs_time Qidfs_utils Robust time arithmetic (to msec accuracy)
advance_idf_file_spin_start Qidfs_utils Advance an idf file to the start of the next spin
BIN_UNITS_STRING Qidfs_utils String of units for energy bin
BIN_UNITS_SI_conv_STRING
Qidfs_utils
String for CSDS SI_conversion attribute for energy bin
check_bins Qidfs_utils Ensure energy bins have finite width
clockstep Qpeace_pad Find start and direction for filled pitch angle bins given full 360 clock
CombineSweeps Qsweep_spin Interpolation of one sweep onto bins of another, with weights
compare_idfs_time Qidfs_utils Compare two times
compute_clockbin Qpeace_pad Position 'round full polar clock of sensor
copy_lineage Qidfs_utils Copy lineage strings and version to another lineage structure
copy_spin
Qsweep_spin Make a full copy of a spin structure
create_sweep_full_copy Qsweep_spin Make a complete copy of a sweep of data
cyclic360abs_diff Qpeace_pad Abs angular difference between two angles 'round a full circle
cyclic360pos_diff Qpeace_pad Signed angular difference between two angles 'round a full circle
diff_or_integral Qidfs_utils Decide if given psd units are an integral measure (e.g. counts) or density
divide_by_area Qsweep_spin Divide psd array of a sweep by (typically area) weights
e_bin_edges Qidfs_utils Get the energy bin limits in physical units
epoch_secs_to_idfs_time Qidfs_utils Convert secs since 0AD to idfs time
QEpochSecs Qidfs_utils (year, mon, day, hr, min, sec) -> secs since 00:00 on 0AD
exchange_b_tip_tail Qpeace_pad flip flags for +B direction
expected_first_polbin Qpeace_pad Use iel information to anticipate 1st filled sensor in 1st half of spin
fill_pad Qpeace_pad Low level routine to fill PEACE sweep structure with PAD data
fill_single_sen_sweep Qsweep_spin Lowest level routine to fill a sweep for a single PEACE sensor
fill_spin3d Qsweep_spin Deprecated as of V2.
fill_sweep Qsweep_spin Low level routine to get and fill a single sweep of data.
fill_sweep_bin_area Qsweep_spin Calculate polar areas of all sweep bins
find_az_sweep Qsweep_spin Find the sweep within a spin which contains a given azimuthal direction
find_subset_in_range Qidfs_utils Find bins in one set which overlap with given bin boundaries
free_n_spins Qsweep_spin Free up memory malloced in n spin structures
free_n_sweeps Qsweep_spin Free set of sweep structures, including bins and lineage
free_phisc_arrays Qphisc Free up internal arrays in phisc structure
free_spectro_arrays Qpeace_plot Free bin and z arrays in pgs
free_spin_data Qsweep_spin Free up memory malloced by malloc_spin_sweep
free_sweep_arrays Qsweep_spin Free up memory associated with sweep arrays. Use with caution!
free_1D_cut_arrays Qsweep_spin Free up arrays malloced by sweep_1D_cut
gather_sweeps Qsweep_spin Gather up sweeps according to various options, e.g., by n sweeps, n spins, or n.n seconds.
get_b_az Qpeace_pad Find azimuth of B from iel data.
GetNPeaceSpins Qsweep_spin High-level to get sequence of PEACE Spins
GetNPeaceSweeps Qsweep_spin High-level to get sequence of PEACE sweeps (incl PAD)
GetNPeacePADs Qpeace_pad High-level to get sequence of pitch angle distributions from the PEACE PAD virtual instrument
GetNPotCorrectedPeaceSweeps
Qsweep_spin High-level to get sequence of PEACE sweeps (incl PAD) corrrected for spacecraft potential
GetPeacePAD Qpeace_pad High-level to get a single pitch angle distribution from the PEACE PAD virtual instrument
GetPeaceSpin Qsweep_spin Self-contained routine to return a full spin structure; all idfs calls internal to this
idfs_n_spin_sweep_etime
Qsweep_spin Find the etime which is at or beyond n2count sweeps or spins
idfs_sweep_counter Qsweep_spin Count the number of sweeps between two times in the idfs database, spanning across files if necessary
idfs_sweep_nlevels
Qsweep_spin Find an idfs sensor which has filled data and return the number of energy levels
idfs_time_to_epoch_secs
Qidfs_utils
Convert idfs time to CDF Epoch SECONDS since midnight 0AD
iend_sweep_gather Qsweep_spin Find the index of the last sweep to be gathered by sweeps, spins, or seconds.
inbin Qsweep_spin Find bin which holds input value (rather trivial)
init_idf_file Qidfs_utils Open and position an idfs data file
init_pad Qpeace_pad Low-level initialisation routine for PAD virtual instrument
init_spin3d Qsweep_spin Removed in V2; not needed.
invert_array Qidfs_utils Invert the order of an array of floats
malloc_spectro_arrays Qpeace_plot Malloc bin and z arrays in pgs
malloc_spin_sweep Qsweep_spin Removed as of V2. Spins have sweeps each with their own bins, so this malloc is done at sweep level.
malloc_sweep_arrays Qsweep_spin Malloc sweep energy, angle arrays and lineage structure
mod360 Qidfs_utils Return number modulo 360, i.e., in range 0->360
msec_nano_to_sec_nano Qidfs_utils Convert milliseconds with nanosec remainder to secs with nanosec remainder
multiply_by_area Qsweep_spin Multiply psd array of a sweep by (typically area) weights
near_nice_number Qidfs_utils Find 1,2, or 5 x power of ten nearest but > magnitude to input
next_idfs_file
Qidfs_utils Go to next idfs file and position at start
nsweeps2QiCDFContents Qsweep_spin Take many sweeps of data and fill a CDFContents Object for exporting data, bins, ... Underneath this are a suite of routines to set attributes and deal with the various variables (psd, bin boundaries, etc.) not documented here.
nullify_sweep_arrays Qsweep_spin Initialize sweep array and lineage pointers to NULL
PADLiouvilleMap Qpeace_pad Map pitch angle distribution using Liouville's Theorem
PADvpara_boost
Qpeace_pad
Shift PAD (or sweep) by constant v_parallel.
PeaceGetAzSlice Qsweep_spin Get a single azimuthal slice from and IDFS data holding (no longer used as of V2).
PeaceGetAzSliceV2 Qsweep_spin Get a single azimuthal slice from and IDFS data holding, version 2.
phisc2sweep Qphisc Find by interpolation the value of s/c potential for a particular sweep, and put it in that sweep structure
phisc2sweep_all Qphisc Find the value of the s/c potential for each sweep in a set and put the values in the sweep structures
Phisc_fill_not_available Qphisc Fill phisc structure with 2 pts (used when EFW not available)
PlotTwoSweeps Qpeace_plot Plot two azimuthal slices of IDFS data in a wheel plot
polar_area Qidfs_utils Calculate the plane polar area of a given bin
pos_idf_file_spin_start Qidfs_utils Position an idf file to the start of a spin
print_bins Qidfs_utils Print out bin edges
print_idf_data Qidfs_utils stdout print of idfs data time, sensor info, and some data for diagnostics
print_idfs_lineage Qidfs_utils stdout idfs lineage project, mission, experiment, ...
print_idfs_time Qidfs_utils sdtout idfs time in various formats
print_peace_spin_info Qsweep_spin Print spin structure times, etc. to stdout
print_sweep_structure Qsweep_spin Diagnostic dump of a sweep for all sensors
print_weight Qsweep_spin Diagnostic dump of weight (or psd) array.
print_1D_cut Qsweep_spin Diagnostic print of a 1-D cut structure
PSD_UNITS_STRING Qidfs_utils String of units for phase space density
PSD_UNITS_SI_conv_STRING
Qidfs_utils
String for CSDS SI_conversion file export
QanDateToYearDoy Qidfs_utils (year, mon, day) -> (year, doy)
QanYearDoyToDate Qidfs_utils (year, doy) -> (year, mon, day)
QEpochSecs
Qidfs_utils
CDF Epoch in SECONDS since midnight 0AD
Qjas_az_panel Qpeace_plot Plot bottom (azimuths) panel in Qjas_plot
Qjas_fill_angle_t_array Qpeace_plot Fill spectrogram array; helper for Qjas_plot
Qjas_lev_panel Qpeace_plot Plot angle/time spectrogram for a single level within Qjas_plot
Qjas_plot Qpeace_plot Stack of angle/time spectrograms, one for each energy level 
Qjas_set_vpt_win_from_pgs Qpeace_plot Get PGPLOT ready for Qjas_plot
qjas_time_init Qpeace_plot Time manipulation to support Qjas_plot
read2filled_sensor Qidfs_utils Read through all sensors, forwarding in time, until find one filled with data and return which one
rebin_sweep Qsweep_spin interpolate sweep data onto new energy/angle bins
rebin_sweep_to_pa Qsweep_spin Rebin a set of sweeps onto a single pitch angle sweep structure
Rebin_n_spins_to_pa Qsweep_spin Rebin set of spins to a set of pitch angle sweeps structures
rebin_n_sweeps Qsweep_spin interpolate n sweeps onto new energy/angle bins
Rebin_n_sweeps_to_pa Qsweep_spin Interpolate n sweeps grouped onto pitch angle sweep structures
SC_NAME Qidfs_utils String of spacecraft name
SC_Pot_fetch Qphisc Get s/c potential data and fill phisc structure with it
SC_Pot_init
Qphisc
Initialise Phis sc structure (EFW lineage, NULL ptrs, and such)
scale_then_rotate_angles Qidfs_utils Scale an angle, then rotate (really multiply a float, then add)
sec_nano_to_msec_nano Qidfs_utils Convert seconds with nanosec remainder to millisecs with nanosec remainder
set_b_para_half_spin Qpeace_pad Set the half spin which contains the +B field LOOK direction
set_equal_bins Qidfs_utils Set equal size bins given min, max, number
set_equal_bins_linlog
Qidfs_utils
Set bins equal in linear or log size
set_equal_bins_half_ends
Qidfs_utils
Set bins equal in size but with half-sized end bins
set_pa_opts_defaults Qsweep_spin Set default options for pitch angle binning
set_psd_tables Qidfs_utils Set the tables and operators to convert idfs data into physical units for counts, phase space density, differential energy flux, ...
Set_Sweep_cut_options_default Qpeace_plot Defaults line,scaling, for Sweep cut plot routines
Set_sweep_wheel_options_default Qpeace_plot Set default options (colours, scaling, ...) for a sweep wheel plot
set_times_from_idf Qidfs_utils Get start, end, and sun sensor times from an idf data structure
sinsq_map Qpeace_pad Compute new sin^2 pitch angle for Liouville mapping
sort_pa_bins Qpeace_pad Sort filled/empty bins 'round full 360 clock
sweep_arithmetic Qsweep_spin Add, subtract, multiply, or divide two sweeps (interpolates as necessary)
sweep_double_levels
Qpeace_pad
Increase energy/velocity levels by factor 2
sweep_double_sensors Qpeace_pad Increase angular resolution by 2; crude interpolation and smoothing
sweep_duration_calculator Qsweep_spin Take n sweep start times and calculate number of sweeps/spin
Sweep_cuts_plot  Qpeace_plot Take multiple cuts of multiple sweeps (No longer used; see Sweep_n_cuts_plot)
sweep_make_level_missing Qphisc Set all psd corresponding to a given energy level missing (used with phisc routines for negative energy bins)
Sweep_n_cuts_plot  Qpeace_plot For n sweeps, take individually specified cuts.  Better than Sweep_cuts_plot
sweep_sc_potential_adjust Qphisc Use the values of s/c potential in a set of sweeps to correct bin boundaries and, where appropriate, phase space science values
sweeps_autoscaler Qsweep_spin Find min and max data values in set of sweeps
sweep_spin_gap_defaults Qsweep_spin Set default time interval for detecting a gap in sweeps or spins
Sweep_wheel_plot Qpeace_plot Plot a sweep of data as (half of) a wheel plot
sweep_1D_cut Qsweep_spin Select a 1D cut from a sweep structure
t1_minus_t2 Qidfs_utils Take difference between two times
test_sweeps_congruent Qsweep_spin See if two sweeps share same bin boundaries, units, ...
to_hms_time Qidfs_utils Convert an IDFS time to hour, min, sec
to_idfs_time Qidfs_utils Convert a date/time to IDFS_TIME format


Descriptions of Routines

Qidfs_utils

Routines for IDFS Lineage and Strings

Prototype Returns Description
char *SC_NAME(
  SC sc
)
character string name of spacecraft returns character string name of spacecraft corresponding to enum SC for use in lineage or annotation; e.g., SC_NAME(1) returns "CLUSTER-1"
char *PSD_UNITS_STRING(
  PSD_UNITS psdu
)
character string representation of phase space density units returns character string representation of phase space density units corresponding to enum PSD_UNITS for annotation and buttons, etc. E.g., PSD_UNITS_STRING(1) returns "Counts / Accumm"
char *PSD_UNITS_SI_conv_STRING(
PSD_UNITS psdu)
character string representation of CSDS SI conversion string for phase space density
returns character string representation of CSDS SI_conversion attribute corresponding to phase space density as per enum PSD_UNITS for file export
char *BIN_UNITS_STRING(
  BIN_UNITS bin_units
)
character string representation of energy bin units returns character string representation of energy bin units corresponding to enum BIN_UNITS for annotation and buttons, etc.
*BIN_UNITS_SI_conv_STRING
character string representation of CSDS SI conversion string for energy bin units
returns character string representation of CSDS SI_conversion attribute corresponding to energy bin units as per enum BIN_UNITS for file export, e.g., "1.e3>m s^-1" for km/s
void print_idfs_lineage(
  IDFS_LINEAGE *lng
)
void prints (to stdout) the various strings (Project, Mission, Experiment, ...) held in the structure IDFS_LINEAGE. These strings are used within IDFS to locate the correct data files
void copy_lineage(
  IDFS_LINEAGE *lincpy,
  IDFS_LINEAGE *lin)

Copy lineage strings and version from lin structure to lincpy

Routines to Manipulate Time for use by/from IDFS

Prototype Returns Description
void to_idfs_time(
  int year, int doy, int hr, int min, int sec, long nano, 
  IDFS_TIME *idftp
)
  loads the structure IDFS_TIME *idftp from the other arguments
void to_hms_time(
  IDFS_TIME *idftp,        // input 
  int *hp, int *mp, int *sp, long *np
)
  returns (hour, minute, second, nanosecond) given a structure IDFS_TIME *idftp
void sec_nano_to_msec_nano(
  long sec, long nanos, 
  long *msec, long *nanoms
)
  Converts a time given in (sec, nanoseconds) to (milliseconds, nanoseconds of millisecond). Some IDFS routines use one time format, whilst the other is also used. Indeed, some routines take one as input and return the other.  See msec_nano_to_sec_nano.
void msec_nano_to_sec_nano(
  long msec, long nanoms, 
  long *sec, long *nanos
)
  Converts a time given in (milliseconds, nanoseconds of millisecond) to (sec, nanoseconds). See sec_nano_to_msec_nano
void print_idfs_time(
  IDFS_TIME *idftp
)
  Prints (to sdtout) a representation of the time held in the srtucture IDFS_TIME *idftp
IDFS_TIME t1_minus_t2(
  IDFS_TIME *t1, IDFS_TIME *t2
)
IDFS_TIME difference  Returns as in IDFS_TIME structure the difference between two IDFS times. This routine is simple but dumb. For robust quantitative work, use QEpochSecs and related routines below.
IDFS_TIME_COMPARE compare_idfs_time(
  IDFS_TIME *t1, IDFS_TIME *t2
)
T2_LATER (-1)
SAME_TIME (0)
T1_LATER (+1)
Compares two IDFS_TIMEs and returns an enum IDFS_TIME_COMPARE
void QanYearDoyToDate(
int year, int doy, int* month, int* day 
)

Convert a (year, doy) to (year, month, day). Based on the CDF epoch routines.
void QanDateToYearDoy(
int year, int month, int day, int *doy
)

Convert (year, month, day) to (year, doy).
double QEpochSecs( 
int year, int month, int day,
  int hour, int minute, int second, int msec 
)
double holding the seconds since midnight of doy zero for 0AD Convert (year, month, day, hour, min, sec, msec) to a single real number. Based on the CDFepoch routines, but returns secs rather than msecs.
double idfs_time_to_epoch_secs(
IDFS_TIME *idft
)
double holding the seconds since midnight of doy zero for 0AD Convert time held in an IDFS_TIME structure to a single real number; accurate to msecs or a bit better, but not nanosecs.
void epoch_secs_to_idfs_time(
double epoch, IDFS_TIME *idftp)

Breakdown an epoch seconds (since 0AD) to an idfs time; only accurate to ~ msecs.
void add_secs_to_idfs_time(
IDFS_TIME *idftp, float secs2add)

Add secs2add (can be negative) to an idfs time. Passes to epoch and back, so loses sub-msec accuracy but robust.
void set_times_from_idf(IDFS_TIME *btime, IDFS_TIME *etime,
                        IDFS_TIME *sun_sen, struct idf_data *idfp)

Takes a filled idfs data structure and returns via calling arguments the beginning time, end time, and sun sensor time as IDFS TIME structures.

Routines for dealing with IDFS Files and Data Structures

Prototype Returns Description
SDDAS_SHORT init_idf_file(
  IDFS_TIME btime, 
  IDFS_TIME etime, 
  SDDAS_ULONG dkey, 
  struct idf_data *idfp,
  SDDAS_USHORT vsn
)
QUTILS_ERROR
ALL_OKAY
Open and position an IDFS file. Prior to calling this routine, the user will need to call the IDFS routine init_idfs() to initialise the IDFS system, get_version_number to set the version "vsn" to be used (this is normally placed in the IDFS_LINEAGE structure), create_idf_data_structure to create an idfs data structure, which then needs to be cast from its void declaration to the idf_data structure, and get_data_key to be passed as dkey. Returns error if either opening or position fails (console message says which).
SDDAS_SHORT next_idfs_file(
SDDAS_ULONG dkey,
IDFS_LINEAGE lng,
IDFS_TIME *time,
IDFS_TIME *etime,
struct idf_data *idfp)
QIDFS_EOF
ALL_OKAY
Finds the start time of the next idfs file, and positions to start of file. Input the etime required. Returns QIDFS_EOF if no data prior to etime, or some other error; start time returned in time.
SDDAS_SHORT pos_idf_file_spin_start(
SDDAS_ULONG dkey, 
struct idf_data *idfp, 
IDFS_LINEAGE *lineage, 
IDFS_TIME *btime, 
IDFS_TIME *etime);
Return values from idfs routines reset_experiment_info or file_pos. ALL_OKAY on success. Use information in idf_data structure to re-position the file associated with dkey to its spin start and return the spin start/stop times. Not guaranteed to work!
SDDAS_SHORT advance_idf_file_spin_start(
SDDAS_ULONG dkey, 
struct idf_data *idfp, 
IDFS_LINEAGE *lineage, 
IDFS_TIME *btime, 
IDFS_TIME *etime,
 SDDAS_SHORT sensor)
Return values from idfs  read_drec. ALL_OKAY on success Use information in idf_data structure to ADVANCE the file associated with dkey to the NEXT spin start and return the spin start/stop times. Reads data for "sensor", so pass a sensor number which is always filled (or which you need to be filled). Guards against files which have (some) records out of order
SDDAS_SHORT read2filled_sensor(
SDDAS_ULONG dkey,
IDFS_LINEAGE *lngp,
struct idf_data *idfp,
int  nsen,
int *nsen_found,
T_OR_F forward)
Return vals from read_drec
Run through all nsen sensors, forwarding through the file after the last sensor if forward==QPTRUE, looking for one which has filled_data. Return the number of that sensor. The corresponding times, etc. are returned in the idf_data structure. Return values can include NEXT_FILE_STATUS if it runs through to the end of the present idfs file without finding a filled sensor.
void print_idf_data(
  struct idf_data *ip
)
  A diagnostic routine to print out some information, including timing, number of sensors, and some data.
SDDAS_SHORT  e_bin_edges(
  SDDAS_ULONG dkey, 
  struct idf_data *idfp, 
  SDDAS_USHORT vsn, 
  float *bin_low, 
  float *bin_high, 
  BIN_UNITS bin_units, 
  int n_lev_array_len
)
QUTILS_ERROR
ALL_OKAY
Fill the pre-allocated arrays bin_low[n_lev_array_len] and bin_high[n_lev_array_len] with the energy bin levels as contained in the idf_data structure (i.e., from the last read_drec call) converted to the units specificied by the enum BIN_UNITS. Returns QUTILS_ERROR if there isn't enough space in the arrays, or if the converted data isn't a float, else returns ALL_OKAY. The arrays are turned unsorted, and therefore are typically ordered highest energy to lowest corresponding to the instrument sweep behaviour. A miscellaneous utility invert_array is provided to re-order these if required. Note that most Qpeace routines assume the energy level arrays are in ascending order.
SDDAS_SHORT set_psd_tables(
  PSD_UNITS psd_units, 
  SDDAS_CHAR *num_tbls, 
  SDDAS_CHAR *tbls_to_apply,
  SDDAS_SHORT *tbl_oper)
ALL_OKAY Fill in the number of tables (num_tbls) needed to apply, which ones (tbls_to_apply) and their corresponding operators (tbl_oper) to convert sensor data into the phase space density unit specified by PSD_UNITS enum. The arrays tblw_to_apply and tbl_oper should be sized at least MAX_TABLES_TO_APPLY.
INTERP_QUANTITY diff_or_integral(
  PSD_UNITS psu)
DIFFERENTIAL or
INTEGRAL
Check psu and decide if it is an integral quantity, e.g., counts, or a differential one, e.g., phase space density.

Miscellaneous Utilities

Prototype Returns Description
SDDAS_SHORT invert_array(
  float *arr, int n_lev
)
ALL_OKAY Inverts the order of an array of floats
double near_nice_number(
  double x
)
sign times 1,2,or 5 times a power of 10. Find a nice number near to x. Nice means a sign times 1,2, or 5 times power of 10. The Nice number is always larger in magnitude than x. This mimics the pgplot routine pgrnd, which doesn't seem to work on all machines across the c interface.
void scale_then_rotate_angles(
  float *orig, 
  float *rotscale, 
  int n,
  float rotation, 
  float scale
)
  Frst scale, then rotate angles. Actually, just multiply then add, but used, for example, to rotate sweep plots by +/- 90 degrees. Returns array rotscale[i] = (scale * orig ) + rotation. Leaves orig unchanged, and can return new values in orig by calling scale_then_rotate(origp,origp, n, ...). Units of rotation should be same as orig unless scale is used to change them.
float polar_area(
  float r1, float r2, 
  float th1_deg, float th2_deg)
plane polar area Calculate area in plane polars bounded by limits as given, i.e., 0.5 (r2^2 - r1^2)(cos th1 - cos th2)
int find_subset_in_range(
  float xlo, float xhi,
  float *xloarray, float *xhiarray, 
  int n_array,
  int *i1, int *i2)
number of overlapping bins Find bins (xloarray[i]->xhiarray[i]) which overlap with (xlo,xhi). Arrays have dimension n_array and are assumed to be sorted low->high. Indices i1 and i2 return subset of array which so overlaps, with the number of overlapping bins returned via the call. i1 and i2 are UNDEFINED if calling routine returns 0.
SDDAS_SHORT check_bins(
  float *lowbins, 
  float *hibins, 
  int nbins)
ALL_OKAY Check that lowbins[i]  != hibins[i], otherwise force finite bin size by moving ALL bin edges (except lowbins[0] and hibins[nbins-1]) to mid-way values. This should probably not be necessary, but was written to cope with initial, pre-flight VIDFs.
void print_bins(float *low, float *high, int n)
Print out cols with bin#, low, high edges
SDDAS_SHORT set_equal_bins(
float *xlobins, float *xhibins, 
int nbins, 
float xmin, float xmax)
ALL_OKAY Set nbins equal size bins from xmin to xmax
SDDAS_SHORT set_equal_bins_linlog(
float *xlobins, float *xhibins, int nbins, float xmin, float xmax, PGSpectro_linlog linlog)
PEACE3D_ERROR
ALL_OKAY
Set nbins from xmin to xmax in equal size linear or log steps. Error if nbins <1.
SDDAS_SHORT set_equal_bins_half_ends(float *xlobins, float *xhibins, int nbins,
                           float xmin, float xmax)
PEACE3D_ERROR
ALL_OKAY
Set nbins from xmin to xmax in equal size steps, but with the end bins being half the size of the rest. Error if nbins <1.
float mod360(float x) x modulo 360 Add/subtract 360 to return x in range 0->360


PEACE Sweep_Spin Routines

Sweep Data

 
Prototype Returns Description
SDDAS_SHORT malloc_sweep_arrays(
PEACE_SWEEP *swpp,
T_or_F do_pa)
PEACE3D_ERROR
ALL_OKAY
Malloc: thlo, thhi, elo, ehi, and psd bins and lineage structure. Dimensions should already be in sweep structure. If do_pa = QPTRUE, then the pa array is also malloced.
SDDAS_SHORT nullify_sweep_arrays(
PEACE_SWEEP *swpp)
ALL_OKAY
PEACE3D_ERROR
initialise sweep array pointers and lineage to NULL
PEACE_SWEEP  *create_sweep_full_copy(
  PEACE_SWEEP *swp)
pointer to sweep structure
NULL on malloc failure
Make a full copy, including bin arrays and lineage, of a sweep structure
void free_sweep_arrays(
  PEACE_SWEEP *swp)

Free bin and psd arrays and lineage. Note that a spin structure uses only ONE copy of bin boundaries for all sweeps, so this routine must be used with care.
void free_n_sweeps(int n, PEACE_SWEEP **swppp)
Free up n PEACE sweep structures, the pointers to which are in the array swppp[]. For safety, the initial pointers should have been initialised to NULL. Note that malloc_sweep_arrays is structured to ensure that the bins and psd arrays are not NULL. Note, however that this routine calls free_sweep_arrays, which tries to free bins for each sweep, so they must each have their own copy. As of V2, even sweeps inside a spin3d structure all have their own bins, so this should be safe.
SDDAS_SHORT fill_sweep(
  PEACE_SWEEP *swpp , 
  IDFS_LINEAGE *lngp,
  struct idf_data *idfp, 
  SDDAS_ULONG dkey, 
  int have_bins,
T_or_F do_pa)
return val from read_drec 
PEACE3d_ERROR
ALL_OKAY
Low level routine to fill a single sweep of PEACE 3D data for all sensors. It calls the lower level routine fill_single_sen_sweep. Note that this routine orders energy levels and psd array from lowest energy to highest. Need to set bin/psd units and lineage (in the PEACE_SWEEP structure) prior to calling this routine and position file. If have_bins is zero, the routine also fills the theta and energy bins, and lineage structure, all of which need to be allocated prior to calling this routine. If do_pa = QPTRUE, fills the pa array as well as the psd one.

SDDAS_SHORT fill_single_sen_sweep(
  PEACE_SWEEP *swpp, 
  int isen,
  SDDAS_ULONG dkey, 
  struct idf_data *idfp,
T_or_F do_pa
)
PEACE3D_ERROR
ALL_OKAY
Use the data in idfp to fill the phase space density array in the PEACE_SWEEP in the correct physical units. The converted data is copied in inverse order, so that psd[energy level 0] corresponds to the lowest energy. Ditto for pa array if do_pa = QPTRUE.
void print_sweep_structure(
  PEACE_SWEEP *swpp
)
  Stdout large diagnostic print of the entire sweep structure, including timings, energy bin levels, theta bins, azimuths, physical units options, and phase space data.
int idfs_sweep_counter
(SDDAS_ULONG dkey,
IDFS_LINEAGE *lngp,
struct idf_data *idfp,
IDFS_TIME *bt, 
IDFS_TIME *et)
SWEEP_COUNT_BAD_SENSOR_NUMBER
SWEEP_COUNT_RESET_ERR
SWEEP_COUNT_POS_ERR
number of sweeps
For the dataset corresponding to the idf_data structure (which should have been initialised and positioned prior to calling this routine), count how many sweeps there are between bt and et, crossing file boundaries if necessary. File is reset/repositioned prior to return (unless the RESET or POS err is returned), although if fetching pitch angle data, the pa virtual instrument is not, and will require a free_experiment_info and reinitialisation of the system to get everything in sync.
int idfs_sweep_nlevels
(SDDAS_ULONG dkey,
IDFS_LINEAGE *lngp,
struct idf_data *idfp,
int *nsenp)
PEACE3D_ERROR
SWEEP_NLEVELS_NOT_FOUND
number of energy levels
For the idfs dataset, find a filled sensor and return the number of energy levels for that sensor, passing back its number in *nsenp. SWEEP_NLEVELS_NOT_FOUND returned if none of the sensors is filled; the more generic PEACE3D_ERROR if read_drec had a problem.
SDDAS_SHORT idfs_n_spin_sweep_etime(
IDFS_LINEAGE *lngp,
IDFS_TIME *btimep,
IDFS_TIME *etimep,
T_OR_F do_pa,
PEACE_GATHER_CHOICE gathch, int n2count)
various IDFS return values
For given lineage and btimep, find the etime which is at or beyond n2count sweeps or spins. This routine init's the file, does its job, and then frees everything. The purpose is to be able to supply GetNPeaceSweeps with an etime

Sweep Manipulation

 
Prototype Returns Description
SDDAS_SHORT CombineSweeps(
  PEACE_SWEEP *swp_new, 
  float *weight,
  PEACE_SWEEP *swp_old, 
  INTERP_QUANTITY interpq )
ALL_OKAY Combine the contents of swp_old onto swp_new. weight is an array of same dimension as psd. On entry, it contains the pre-existing weight of swp_new (typically the area of each bin if the psd has data in it, or zero if it is initially empty). On exit, weight contains the total weight of data in each bin, which is the old weight plus overlap area(s) of bins in swp_old which overlap with this swp_new bin. Combination is done by converting swp_new to density (if interpg=INTEGRAL) and multiplying by weight, then adding swp_old (density) * overlap area for each bin, then renormalising by weights, and converting back  if interpq=INTEGRAL.
SDDAS_SHORT fill_sweep_bin_area(
  float *A, 
  PEACE_SWEEP *swpp)
ALL_OKAY Use bin information in sweep structure to calculate plane polar areas and fill array A[n_sen][n_lev]
SDDAS_SHORT divide_by_area(
  float *A,
  PEACE_SWEEP *swpp)
ALL_OKAY Divide swpp->psd element by corresponding ones in A. If A[k] is zero, set result to zero.
SDDAS_SHORT multiply_by_area(
  float *A,
  PEACE_SWEEP *swpp)
ALL_OKAY Multiply swpp->psd element by corresponding ones in A.
int test_sweeps_congruent(
PEACE_SWEEP *swp1, PEACE_SWEEP *swp2)
-1 (units differ)
0  (bin boundaries differ)
1 (identical)
Test sweeps to see if they have the same units and same bin boundaries.
PEACE_SWEEP *sweep_arithmetic(
  PEACE_SWEEP *swp_pri, 
  PEACE_SWEEP *swp_sec,
  ARITH_OPER oper)
pointer to sweep structure (NULL if fails) Perform oper between swp_pri and swp_sec. swp_pri is used for bin boundaries, and swp_sec interpolated onto them if necessary. Add, Subtract, Multiply, Divide supported.
PEACE_SWEEP *rebin_sweep(
PEACE_SWEEP *bin_holder, 
PEACE_SWEEP *swp)
pointer to sweep structure Interpolate the data in swp onto the energy/angle bins found in bin_holder.  bin_holder is unchanged.
SDDAS_SHORT rebin_n_sweeps(
PEACE_SWEEP *bin_holder, 
int nswps,
 PEACE_SWEEP **swpsinpp, 
int *nrebinned, 
PEACE_SWEEP ***swpsoutppp);
ALL_OKAY
SWEEP_REBIN_ERROR
Interpolate the data in nswps sweeps onto the energy/angle bins found in bin_holder. Bin_holder is unchanged. The actual number of sweeps rebinned is *nrebinned, and their pointers are in *swpsoutppp.  Swpsoutppp array and all internal arrays malloced. Each sweep has its own copy of energy/angle bins.
void print_weight(
  float *weight, 
  int n_th, 
  int n_lev)

Diagnostic printout of array weight[theta][levels]
void sweeps_autoscaler(
PEACE_SWEEP **swppp, int nswp, 
float *psdmin, float *psdmax)

Find min and max data values in nswp sweep structures. swppp is the pointer to the array containing the nswp pointers. Zeroes (|f|>FLT_MIN), infinities removed; non-zero (max-min) forced.
PEACE_1D_SWEEP_CUT *sweep_1D_cut(
float theta, PEACE_SWEEP *swp)
pointer to 1D cut structure or NULL Select 1-D radial cut corresponding to LOOK direction theta.
void free_1D_cut_arrays (
PEACE_1D_SWEEP_CUT *swpcut)

Frees arrays in cut structure. After this, free the cut structure itself.
void print_1D_cut(
PEACE_1D_SWEEP_CUT *swpcut)

Diagnostic print
SDDAS_SHORT rebin_sweep_to_pa(
PEACE_SWEEP **swpp, 
int nswp,
PEACE_PITCH_ANGLE_OPTS *paopts, 
PEACE_SWEEP **paswpp)
SWEEP_TO_PA_ERROR
ALL_OKAY
Take nswp sweeps, pointers in swpp, and rebin them onto a single pitch angle sweep. swpp's need to have been fetched with pitch angles. The resulting sweep is malloced and its pointer returned via *paswpp.
SDDAS_SHORT Rebin_n_sweeps_to_pa(
PEACE_SWEEP **swppp, 
int nswps, 
int nswpgrp, 
PEACE_PITCH_ANGLE_OPTS *paopts, 
PEACE_SWEEP ***paswppp_p, 
int *npaswp)
SWEEP_TO_PA_ERROR
ALL_OKAY
Take nswps sweeps, pointers in swpp, and regin them nswpgrp at a time to a set of pitch angle sweeps, the pointers to which are returned via the pointer array *paswppp_p. The actual number of such pitch angle sweeps is returned as *npaswp.
void set_pa_opts_defaults(
PEACE_PITCH_ANGLE_OPTS *paopts)

Set pitch angle options (do 13 pitch angles in angles not mu)
SDDAS_SHORT Rebin_n_spins_to_pa(
PEACE_SPIN3D **spinpp, 
int nspins, 
PEACE_PITCH_ANGLE_OPTS *paopts, 
PEACE_SWEEP ***paswppp_p)
SWEEP_TO_PA_ERROR
ALL_OKAY
Rebin nspins spins to pitch angle sweep structures.  Pointers to all nspins sweeps are returned in the pointer array *paswppp_p.
int iend_sweep_gather(PEACE_SWEEP **swppp,
int nswps, int istart,
PEACE_GATHER_CHOICE gather,
PEACE_GATHER_GAPS gaps,
float gsecs, int gswp_spin)
SWEEP_GATHER_OUT_OF_BOUNDS
-1
index of last sweep to gather
Start at swppp[istart] and find the index of the last sweep to gather given the gathering choice gather (one of the enum GATHER_SWEEPS, GATHER_SPINS, GATHER_SECS. gsecs and gswp_spin bring in the number of seconds (used for GATHER_SECS) or sweeps or spins to be gathered. gaps is a structure containing the number of seconds to be treated as a gap for sweeps and spins, and can be initialised by the sweep_spin_gap_defaults routine. On error, or if NO_GATHER is set, the routine returns -1.  If istart is set beyond nswps-1, or is negative, the OUT_OF_BOUNDS value is returned (which is also negative).
void sweep_spin_gap_defaults(
PEACE_GATHER_GAPS *gapp)

Set default gap values for sweeps and spins. (currently 1.0 and 4.5 secs respectively. For PAD/SPINPAD data, qpeace routines sweep gap is set to the spin gap one as there is only 1 effective sweep per spin, but this is not done here.
SDDAS_SHORT gather_sweeps (
PEACE_SWEEP **swppp, int nswp,
PEACE_SWEEP *binh,
PEACE_GATHER_CHOICE gatch,
PEACE_GATHER_GAPS gaps,
float gath_secs,
int gath_swp_spins,
PEACE_SWEEP ***gath_swpppp,
int *ngat)
SWEEP_GATHER_ERROR
ALL_OKAY
Gather sweeps or spins from the input set of sweeps using the gathering options in the input (see the iend_sweep_gather routine for a description). Returns *ngat sweeps in gath_swpppp, which is malloced inside this routine. SWEEP_GATHER_ERROR is returned if iend_sweep_gather returns an error.
int inbin(
float value, 
float *lobins, 
float *hibins, 
int nbins)
index i
-1 if value not within any bin;
Find i such that lobins[i] <= value < hibins[i] where  i = 0, 1, ... , nbins-1. Bins must be in ascending order.

Spin Data

 
Prototype Returns Description
SDDAS_SHORT GetPeaceSpin(
IDFS_LINEAGE *lineage,
IDFS_TIME *btime,
BIN_UNITS bin_units, 
PSD_UNITS psd_units, 
T_OR_F do_pa,
PEACE_SPIN3D *spinp
)
PEACE3D_ERROR
ALL_OKAY
High level routine to fill a PEACE 3D spin structure. Can be called without any prior idfs routine calls, and likewsie tidies prior to return. Input lineage (including extension but excluding version), start time, bin units and psd units. Pass declared but empty spin structure. On return, spin structure has had internals malloced and filled. If do_pa = QPTRUE, the pitch angle for each measurement is returned in the pa array of the sweep structures. Free using free_spin_data.
SDDAS_SHORT GetNPeaceSpins(
IDFS_LINEAGE *lineage, 
IDFS_TIME *btime,
IDFS_TIME *etime,
BIN_UNITS bin_units, 
PSD_UNITS psd_units, 
T_OR_F do_pa,
int *nspins, 
PEACE_SPIN3D ***spinppp);
PEACE3D_ERROR
ALL_OKAY
High level routine to get a set of spins within a given time range. Mallocs the spin structures and internal arrays, returning an array of pointers in *spinppp. If do_pa = QPTRUE the sweeeps in each spin also will have pitch angle arrays filled (if the pa data is found; if not, an error is generated and no data is returned). Will put together data from more than one file by multiple calls to lower level routine GetN1PeaceSpins.
PEACE_SWEEP *PeaceGetAzSlice(
  IDFS_LINEAGE *lineage, 
  IDFS_TIME *btime, 
  float az,
  BIN_UNITS bin_units,
  PSD_UNITS psd_units,
PEACE_PITCH_ANGLE_OPTS *paopts)
pointer to a complete sweep structure No longer used, but left for backward compatibility. Use PeaceGetAzSliceV2, which provides more functionality through gathering options.
PEACE_SWEEP *PeaceGetAzSliceV2(
IDFS_LINEAGE *lineage,
IDFS_TIME *btime,
IDFS_TIME *etime, float az,
BIN_UNITS bin_units,
PSD_UNITS psd_units,
PEACE_PITCH_ANGLE_OPTS *paopts,
PHISC_CHOICE phiscch,
float phisc_value,
float phisc_gapsecs,
PEACE_GATHER_CHOICE gatch,
PEACE_GATHER_GAPS gaps,
float gath_secs, int gath_swp_spins)
pointer to a complete sweep structure For given IDFS lineage and time, fill an entire spin structure, select the sweep closest to the given azimuth, and return a pointer to a complete copy of that azimuthal slice.  Use the options in paopts to determine if/how pitch angles are to be done. If so, the slice returned is the spin rebinned to pitch angle. Spin data is freed prior to return. Use phiscch to specify if, and how, energy bins should be corrected for spacecraft potential. Phisc_value is the value to use if a constant potential is to be used, or during gaps > phisc_secs in the EFS U_probe data. Set gatch to gather more than one sweep or spin or some interval in time, with gap criteria set in the gaps structure. Gath_secs determines how many seconds to gather; gath_swp_spins is used to indicate how many (integral) sweeps or spins are to be used.
SDDAS_SHORT GetNPeaceSweeps(
IDFS_LINEAGE *lngp, 
IDFS_TIME *btimep, 
IDFS_TIME *etimep, 
BIN_UNITS bin_units, 
PSD_UNITS psd_units, 
T_OR_F do_pa,
int *nswps, 
PEACE_SWEEP ***swpppp)
ALL_OKAY
other IDFS return values
Qpeace error codes
Get all PEACE sweep data within times specified. Put them each in a PEACE_SWEEP structure and return an array of pointers which points to them. Each sweep structure includes its own copies of bin boundaries and lineage. This module is self-contained and deals with all IDFS calls. It returns the pointer to an array of sweep structure pointers, and mallocs all the necessary internal storage required, including the pointer array. Inputs are self-evident from their declarations Output is malloced and filled pointer array (and the nsweeps, sweep structures to which they point!).  If virtual instrument is "PAD", this routine calls GetNPeacePADs. Combines data from more than one idfs file by calling the lower level routine GetN1PeaceSweeps multiple times.
SDDAS_SHORT GetNPotCorrectedPeaceSweeps(
IDFS_LINEAGE *lngp,
IDFS_TIME *btimep,
IDFS_TIME *etimep,
BIN_UNITS bin_units,
PSD_UNITS psd_units,
T_OR_F do_pa,
T_OR_F const_phisc,
float phisc_value,
float phisc_gapsecs,
int *nswps,
PEACE_SWEEP ***swpppp)
ALL_OKAY
PEACE3D_ERROR
Get all PEACE sweep data within times specified. Put them each in a PEACE_SWEEP structure and return an array of pointers which points to them. Each sweep structure includes its own copies of bin boundaries and lineage. This module is self-contained and deals with all IDFS calls. It returns the pointer to an array of sweep structure pointers, and mallocs all the necessary internal storage required, including the pointer array. Inputs are self-evident from their declarations. Can correct energy bins for spacecraft potential using either EFW data or a constant value. Phisc_value is used in this case, and when a gap > phisc_gapsecs appears in the EFW dataset. Output is malloced and filled pointer array (and the nsweeps, sweep structures to which they point!).  If virtual instrument is "PAD", this routine calls GetNPeacePADs.
SDDAS_SHORT nsweeps2QiCDFContents(
PEACE_SWEEP **swppp, 
int nswps,
QiCDFContents **QiCDFp);
ALL_OKAY
PEACE_SWEEPS_SIZE_DIFFER
PEACE_SWEEPS_EXPORT_ERROR
Take the nswps pointed to by swppp (e.g., as received from GetNPeaceSweeps) and fill a QiCDFContents structure with them, from which the data may be ingested into other software (e.g., QSAS) or exported to flat or CDF files. Uses QM import/export modules, as used by QSAS and Qtran. Creates the QiCDFContents object and all internal structures/arrays. Calls subsidiary functions nswps2CDF_... to deal with metadata and the various sweep bins, psd arrays, etc. (see Qsweep_spin.h and .c code for details).
QiFreeCDFContentsObj(QiCDF) from qie module to release all memory. QiWrite... routines can be used the CDFContents object to write to CDF or flat files.
SDDAS_SHORT init_spin3d(
  PEACE_SPIN3D *spin_dp,
  IDFS_LINEAGE  *lngp,
  struct idf_data *idfp,
  SDDAS_ULONG dkey, 
  int *n_sens, 
  int *n_lev
)

Removed in V2; no longer needed.
float sweep_duration_calculator(
IDFS_TIME *swpstart, int n)
-1.0 on error
Sweep start->start in secs
Take n successive sweep start times, and calculate the nominal time from the beginning of one sweep to the next by throwing away the min and max values and averaging the rest. Necessary since sweeps at spin start are forced in time, so not regularly spaced from preceding.
void print_peace_spin_info(
  PEACE_SPIN3D *spinp
)
  Stdout print of spin start, end, period, and number of sweeps/spin
SDDAS_SHORT malloc_spin_sweep(
PEACE_SPIN3D *spinp, 
int n_sen, 
int n_lev,
T_or_F do_pa
)

Removed at V2. Each sweep within a spin has its own bins, to this malloc is done at sweep level. See free_spin_data, which had been up-dated to free the new spin structs.
PEACE_SPIN3D *copy_spin (PEACE_SPIN3D *spin)
pointer to full copy of spin
or
NULL
Makes a full copy using malloc_spin_sweep and carefully copies contents.
SDDAS_SHORT free_spin_data (
  PEACE_SPIN3D *spinp
)
 ALL_OKAY Frees up all memory malloced by malloc_spin_sweep routine. Does NOT free the PEACE_SPIN3D structure itself.
SDDAS_SHORT free_n_spins(
PEACE_SPIN3D **spinpp, 
int nspins)
ALL_OKAY Frees up all memory in nspins spin structures by successive calles to free_spin_data. AND by freeing the spin structures.
SDDAS_SHORT fill_spin3d (
  PEACE_SPIN3D *spinp,
  IDFS_LINEAGE  *lngp,
  struct idf_data *idfp,
  SDDAS_ULONG dkey,
  BIN_UNITS bin_units,
  PSD_UNITS psd_units,
  PHI_ZERO_FRAME phi_frame, T_OR_F do_pa
)

Not used as of V2
int find_az_sweep ( 
  PEACE_SPIN3D *spinp, 
  float az 
)
index of sweep within spin 
containing the given azimuth
-1 if fails
Find the azimuthal slice in spinp which contains (or is closest to if the az falls in a fly-back region) the input azimuthal angle in degrees. Az is in PEACE (t_zero) coordinates. The algorithm rolls over 360->0 if necessary.


Phi sc Spacecraft Potential

Prototype
Returns
Description
void SC_Pot_init(
PEACE_SC_POTENTIAL *phisc_s)

Fill as much as possi ble of a phisc structure, e.g., with common lineage bits, NULL pointers, default gap parameters, ...)
SDDAS_SHORT SC_Pot_fetch(
PEACE_SC_POTENTIAL *phisc_s,
IDFS_TIME *btime,
IDFS_TIME *etime)
Return of Phisc_fill_not_available
PHI_SC_FATAL_ERROR
ALL_OKAY

Input phisc structure with lineage and time interval. Fetches EFW U_probe, calculates corresponding s/c potential, and fills phisc struct with the results. If there is a problem, calls Phisc_fill_not_available to cope (returns directly via this function in these cases). Fatal errors return directly.
SDDAS_SHORT Phisc_fill_not_available(
PEACE_SC_POTENTIAL *phisc,
IDFS_TIME *btime,
IDFS_TIME *etime)
PHI_SC_NON_FATAL_ERROR
For cases where the s/c potential data isn't available, creates a minimal array with two points (at btime and etime respectively) and fills them with phisc gap values; also works when a constant value is requested by the user by calling this routine instead of SC_Pot_fetch.
SDDAS_SHORT free_phisc_arrays(
PEACE_SC_POTENTIAL *phisc)
ALL_OKAY
Free all internal arrays in phisc structure
void phisc_dump(PEACE_SC_POTENTIAL *phisc)
Diagnostic dump of values and arrays in a phisc structure
SDDAS_SHORT phisc2sweep(
PEACE_SC_POTENTIAL *phisc,
PEACE_SWEEP *swpp,
int *start)
PHI_SC_NOT_FOUND
ALL_OKAY
Input a filled phisc structure and guess (*start) position where to start searching within in. Find by interpolation the value of phisc corresponding to the given sweep and insert that value in swpp->phi_sc. Times used for phisc and swpp are both start times as returned by idfs. In practice, this routine is always called first (before pitch angle rebinning or energy bin rebinning) so this time is at original sweep resolution for the sweep. For Phisc, this is the start of the spin. For spin-resolution products, this results in alignment; for higher resolution, it is actually out by up to 1/2 spin, which is probably not critical. Could be changed... If the times don't seem to overlap, PHI_SC_NOT_FOUND is returned, and the phisc gap value inserted into the sweep structure. On return, *start holds the start value used previously, making it available for reuse. NOTE: This routine does NOT adjust the bin boundaries or psd science values within the sweep; it ONLY provides the sweep with its interpolated value of phi_sc to hold internally.
SDDAS_SHORT phisc2sweep_all(
PEACE_SC_POTENTIAL *phisc,
PEACE_SWEEP **swppp,
int nswp)
PHI_SC_FATAL_ERROR (but only if phisc2sweep returns this, which it doesn't at present)
ALL_OKAY
Fill phi_sc values in all sweeps by repeated call to phisc2sweep. Remembers start value to make more efficient. NOTE: This routine does NOT adjust the bin boundaries or psd science values within the sweep; it ONLY provides the sweep with its interpolated value of phi_sc to hold internally.
SDDAS_SHORT sweep_sc_potential_adjust(
PEACE_SWEEP **swppp,
int nswps)
PHI_SC_FATAL_ERROR
ALL_OKAY
Input has sweeps with their internally held values of the spacecraft potential. This routine uses that value to adjust the bin boundaries, checking to ensure the appropriate units and algorithm are used in this process (the error return is set if the bin units aren't recognised as either eV or km/s). Additionally, it adjusts the science value held in the psd array depending on the units:

COUNTS - no change (to preserve total counts)

f(v) - no change, thanks to Liouville's theorem that f(v) remained constant as the electrons were accelerated by phisc (assumes the trajectory does not change direction, only energy - the "scalar" approximation.

Differential Energy Flux - correct as (Enew/Eold)^2 (to conserve f(v). The E's here are taken as the mid-point of the new and old energy bins.

For bins with resulting boundary(ies) negative, the psd value is replaced with the missing value.
float add_ev2_kms(float kms, float ev) new km/s float
Converts input kms (in km/s) to energy, adds ev to it, and converts back to km/s.
void sweep_make_level_missing(
PEACE_SWEEP *swpp, int ilev)

For energy level ilev, make all psd values the missing value (as carried in swpp->missing_value).


Peace PAD Data

 
 
Prototype Returns Description
SDDAS_SHORT GetPeacePAD(
IDFS_LINEAGE *lineage,
IDFS_TIME *btime,
BIN_UNITS bin_units, 
PSD_UNITS psd_units,
T_OR_F do_pa,
PEACE_SWEEP *swpp)
various IDFS return values 
(including ALL_OKAY on success)
High level routine to get a complete PAD of PEACE data. Put it in a PEACE_SWEEP structure. This module is self-contained and deals with all IDFS calls. It needs to be passed the pointer to a declared sweep structure, but it mallocs all the necessary internal storage required. Inputs are self-evident from their declarations. Output is filled sweep structure including bins and lineage.
SDDAS_SHORT GetNPeacePADs(
 IDFS_LINEAGE *lngpadp, 
IDFS_TIME *btimep,
IDFS_TIME *etimep,
BIN_UNITS bin_units, 
PSD_UNITS psd_units,
T_OR_F do_pa,
 int *npads,
 PEACE_SWEEP ***swppp)
various IDFS return values 
(including ALL_OKAY on success)
PEACE_PAD_ERROR
High-level, self-contained routine to get all PEACE PAD data within times specified. Put them each in a PEACE_SWEEP structure and return an array of pointers which points to them. Inputs are self-evident from their declarations. Output is malloced and filled pointer array (and the npads, sweep structures complete with bins and lineage to which they point!). Sweep times altered to spin start/stop. Combines data from more than one file by multiple calls to GetN1PeacePADS.
SDDAS_SHORT init_pad(
PEACE_SWEEP *swpp,
IDFS_LINEAGE *lngp, 
struct idf_data *idfp, 
SDDAS_ULONG dkey, 
float b_az,
PARALLEL_FIELD_HALF_SPIN *b_para_half_spin, 
int *isen_init)
ALL_OKAY
PEACE_PAD_ERROR
return value from set_b_para_half_spin
Routine to get some info about pad instrument from vidf and by finding a filled data record. File should be positioned prior to call. Info returned in swpp includes:
n_sen   = number of sensors  [should <= MAX_P_ANGLES -1]
n_sam   = number of energy levels in sweep
lineage
phi_lo, phi_hi  - based on b_az and sweep width
Info for pad sorting:
b_para_half_spin = flag for whether field_aligned bin is in 1st or 2nd half spin
SDDAS_SHORT  fill_pad(
PEACE_SWEEP *swpp,
IDFS_LINEAGE *lineage, 
struct idf_data *idf_padp, 
SDDAS_ULONG dkey_pad, 
BIN_UNITS bin_units, 
PSD_UNITS psd_units, 
T_OR_F do_pa,
PARALLEL_FIELD_HALF_SPIN b_half_spin, int isen)
ALL_OKAY
PEACE_PAD_ERROR
Low level routine to fill the psd array in a sweep structure with a PAD in the appropriate units by reading both halves of spin.
File should be positioned prior to call and is forwarded when last sensor is read.
psd array is dimensioned psd[pa_dim][level_dim]
int expected_first_polbin(
int b_polbin_iel, 
IDFS_LINEAGE *lngp, 
PEACE_SWEEP *swpp)
integer polar bin (sensor) Calculate expected 1st polar bin in 1st half of spin to be filled. See notes for set_b_para_half_spin for explanation. Basically,
 if LEEA this is b_polbin as returned in iel. If HEEA it is flipped to n_sensors -1 - (b_polbin_iel)
SDDAS_SHORT get_b_az(
SDDAS_ULONG dkey, 
struct idf_data *idfp, 
IDFS_LINEAGE *lineage, 
float *b_az, int *b_pol)
ALL_OKAY
PEACE_PAD_ERROR
Find the azimuthal and polar info for B from iel sensor. dkey is the data key for the iel virtual instrument. iel file should be opened and positions; will be forwarded on exit.
SDDAS_SHORT set_b_para_half_spin(
float b_az, 
IDFS_LINEAGE *lngp, 
PARALLEL_FIELD_HALF_SPIN *b_para_half_spin)
ALL_OKAY
PEACE_PAD_ERROR
Set the half spin which contains the +B field LOOK direction. given b_az contained in iel fgm virtual instrument. See source for detailed comments and algorithm.
int compute_clockbin(
int sensor, int num_sensors, 
int swp_half, int n_pa);
clock position of sensor 
around full circle (0 -> 2n_pa -1)
return position 'round full polar clock of sensor; uses index of swp_half (0 or 1)
SDDAS_SHORT sort_pa_bins(
int *inbins, int *outbins, 
int pa_dim, 
PARALLEL_FIELD_HALF_SPIN bpara_half, 
int b_polbin)
ALL_OKAY
PEACE_PAD_ERROR
inbins[i] contains the clock values for pa_dim sweeps found in data 
outbins[j] will contain the indices i in pa order, with
outbins[0] = i <=> field-aligned
outbins[pa_dim -1] = i <=> anti-field-aligned. If inbins are LOOK directions, they are left that way in outbins (i.e., no attempt is made to re-order from look to flow directions.
int exchange_b_tip_tail(
int *bpol, 
PARALLEL_FIELD_HALF_SPIN *bpara_half, 
int n_sensors)
0 (success)
PEACE_PAD_ERROR
Given presumed information on the PEACE polar bin and spin half for the b-field, choose the opposite direction. This may need doing either to get it right or to convert from look to flow directions - or both
CLOCK_DIRECTION clockstep(
int *clockbins, int *startbin, 
int nbins,  int tries_to_go)
CLOCKWISE
COUNTERCLOCKWISE
CLOCKSTEPERROR
and
actual startbin
return step (+1 or -1) required to step from field-aligned to anti-aligned bins based on info in clockbins[nbins] . Input startbin and number of tries for recursion (in case initial startbin isn't on filled/unfilled boundary).
PEACE_SWEEP* PADLiouvilleMap (
PEACE_SWEEP *swp1, 
float B1, float B2, float epot,
int n_theta_double)
pointer to created, mapped sweep (NULL on failure) Assuming swp1 is a pitch angle distribution, map it from region where |B|=B1 to one of B2 where potential is epot. This routine first interpolates swp1 onto a finer angular grid doubling the resolution n_theta_double times, then does the mapping.
PEACE_SWEEP *PADvpara_boost(
PEACE_SWEEP *swpin, float vparaboost, int thetafactor, int levelfactor)
pointer to new SWEEP structure (NULL on failure)
Shift PEACE sweep along the 0 deg axis by adding vparaboost (in km/s) to velocities. Sweep first regrid-ed onto finer mesh specified by thetafactor, levelfactor multipliers of resolution.
PEACE_SWEEP *sweep_double_levels(PEACE_SWEEP *swpin)
pointer to new SWEEP structure (NULL on failure)
Returned sweep structure has twice as many energy/velocity bins. These arek staggered with respect to the initial ones thereby simulating some interpolation and smoothing.
PEACE_SWEEP *sweep_double_sensors(
PEACE_SWEEP *swpin)
pointer to new SWEEP structure Returned sweep structure has twice as many angular bins. These are staggered with respect to the initial ones (by having smaller bins at 0,180) thereby simulating some interpolation and smoothing.
float sinsq_map (
float e1, float e2, float b2ob1, float thin)
square of sine for Liouville Mapping (>1 means particle has mirrored) return value = (e1/e2)b2ob1*sin^2(thin). Calling routine needs to test for > 1.
float cyclic360abs_diff(
float x1, float x2)
angular difference find the absolute (unsigned) difference between two angles around a 360 circle. Inputs in degrees
float cyclic360pos_diff(
float xlo, float xhi)
angular difference find the positive directed difference between two angles around a 360 circle such that adding this difference to xlo arrives at the position of xhi. Angles in degrees.

Qpeace PLOTTING Routines

 
Prototype Returns Description
PGSpectro_ret Sweep_wheel_plot(
PEACE_SWEEP *swpp, 
SWEEP_WHEEL_OPTIONS *swop)
return value from PGWheel_Plot  plot the contents of a single sweep structure as a wheel plot
void Set_sweep_wheel_options_default(
SWEEP_WHEEL_OPTIONS *swop)

Set default colours, log auto-scaling,  title position and X-window device for a sweep wheel plot.
PGSpectro_ret PlotTwoSweeps(
PEACE_SWEEP *swp_pri, 
PEACE_SWEEP *swp_sec, 
SWEEP_WHEEL_OPTIONS *swop)
PGSPECTRO_OK
PEACE3D_ERROR
Plot two peace sweeps in a wheel plot; primary on left
PGSpectro_ret Qjas_plot( 
PEACE_SWEEP *swps[], 
int nswp, 
PGSpectro *pgspec, 
IDFS_TIME idf_start, 
IDFS_TIME idf_end)
PGSPECTRO_OK
PGSPECTRO_QJAS_INCONGRUENT
return values from malloc_pgspectro_arrays and Qjas_lev_panel
Stack of angle/time spectrograms, one for each energy level for nswp sweeps. Uses options in pgspec; the routine PGSpectro_set_defaults does all this except for zscalemin/max.
void qjas_time_init(
IDFS_TIME *idf_startp, 
IDFS_TIME *idf_endp, 
char *date_start_str, 
char *date_end_str,
PGSpectro *pgs, 
double *epoch_midnight)

Set date strings in pgs
Calculate epoch of midnight prior to start date
Set time world coords for qjas start/stop
void Qjas_az_panel(
PGSpectro *pgs, 
PEACE_SWEEP **swps)

Plot the azimuths in the sweep structures as a pair-wise line plot. All the plot info must be contained in the pgspec structure
void Qjas_set_vpt_win_from_pgs(
PGSpectro *pgs)

Set pgplot viewport and world coords from info in pgs
PGSpectro_ret Qjas_lev_panel(
PGSpectro *pgs, 
PEACE_SWEEP **swps, 
int lev)
return values from Qjas_fill_angle_t_array and  PGSpectro_Plot plot a single energy level for several sweeps as an angle-time spectrogram. All relevant info must be in PGSpectro structure
PGSpectro_ret Qjas_fill_angle_t_array(
float *z,
int nswp, int nang, 
PEACE_SWEEP **sweeps, 
int lev)
PGSPECTRO_OK
PGSPECTRO_SIZE_ERROR
Fill array z[nx=nswp][ny=nang] from sweeps psd arrays for energy level lev.
PGSpectro_ret malloc_spectro_arrays(
PGSpectro *pgs, 
int nx, int ny)
PGSPECTRO_OK
PGSPECTRO_MALLOC_FAILURE
Malloc bin and z arrays in pgs
void free_spectro_arrays(PGSpectro *pgs)
Free bin and z arrays in pgs
PGSpectro_ret Sweep_cuts_plot (
PEACE_SWEEP **swpp, int nswps, 
float *thetas, int ncuts,
 SWEEP_CUT_OPTIONS *scutopt )
PGSPECTRO_OK,
PGSPECTRO_TRACE_ERROR
Plot cuts of sweep data (assumed gyrotropic around theta=0 axis). Any number of cuts can be plotted, specified by the thetas, with plot options in scutopt (see header file for details).  Plots all thetas for all sweeps; SUPERSEDED by Sweep_n_cuts_plot.
PGSpectro_ret Sweep_n_cuts_plot (
PEACE_SWEEP **swpp, int nswps, 
 float *thetas, 
SWEEP_CUT_OPTIONS *scutopt)
PGSPECTRO_OK,
PGSPECTRO_TRACE_ERROR
Plot cuts of sweep data (assumed gyrotropic around theta=0 axis). Any number of cuts can be plotted, specified by the thetas, with plot options in scutopt (see header file for details).  Plots one theta for each sweep; repeat sweep in swpp to take more than one cut.
PGSpectro_ret Set_Sweep_cut_options_default(
SWEEP_CUT_OPTIONS *scopp)
PGSPECTRO_OK Sets default line thicknesses, autoscaling

 

Page maintained by: s.schwartz@imperial.ac.uk
Last updated May 2007 (AJA)