Several different data formats are supported, including:
Which method is the best choice? We recommend using multitraj since it most likely to find the best trajectory. However, there is one situation in which you may want to use fiberfit: if a speedup of a factor of 2 would be of importance and you are primarily interested in high-Z (Z > 9.5) events, then fiberfit will find 98% of the trajectories of multitraj. See Centroid selection for trajectories for a more complete explanation.
The hop_param element of the trajectory quality structure can be understood as follows: each octal digit of the hop_param corresponds to one fiber layer. From right to left, the layers are Y3, X3, Y2, X2, Y1, and X1. Then, for each digit, the '1' bit is set if hopped up, '2' is set if we hopped down, and '4' is set if we switched layers while hopping.
So, for example, an octal 1062 hop parameter would indicate that
#include <softcris.h>
gcc -o foo foo.c -L/usr/local/lib -lsoftcris -lL1 -lm
As of version 4.8 of the library, we are in a state of transition regarding the reporting of error codes. Most routines still return various error codes as documented in the reference section. However, newer routines, notably the trajectory-related routines use a new method. These functions return -1 if there is an error. If the application requires more details about what went wrong, the following two routines may be used:
A list of error codes and messages is available.
Regarding the evtno structure element, it should be noted that it is not a unique event number for each event. The value of evtno is actually the ``spacecraft clock'' value of the minor frame in which the particular event started, and there can be more than one event in a minor frame. To uniquely identify an event, it is necessary to use both the evtno and the evt_offset.
Our data structure describing it looks like this:
struct sc_crisEvt { unsigned long evtno; /* event number */ unsigned long secs1996; unsigned long usec; unsigned long rfu; long npix; /* no. of soft pixels */ u_char *p; /* ptr to cris normal data for this event */ u_char evt_offset; char cam; /* which camera (guess) */ u_char nbytes; /* byte 0 - no. of bytes in this event */ u_char stim; /* stimulated event flag */ u_char prim_tel_pair; /* primary telescope pair (CRIS_AB or _CD) */ u_char buffer_id; /* event buffer id */ u_char guard_hi_or; /* guard high level "OR" */ u_char hazard; /* hazard flag */ u_char G1; /* # low level guards hit in prim. tel. pair */ u_char R1; /* range in primary tel. pair */ u_char got_2nd_tel; /* is there 2nd telescope data in this evt? */ u_char got_guard; /* transmit guard pulse heights in this evt? */ u_char centroid_err;/* centroid calculation error */ u_char nblobs; /* number of soft centroids transmitted */ u_char age; /* age - units 256 sec. */ u_char sec_tel_act; /* activity in the second telescope */ u_char G2; /* # low level guards hit in 2nd tel. pair */ u_char R2; /* range in 2nd telescope pair */ struct sc_crisHodoData hodo[SC_CRIS_MAXBLOBS]; /* SOFT hodo data */ u_short prim_tag; /* primary telescope tag bits */ short prim_ctr_ph[SC_CRIS_NCTRPH]; /* primary centr pulse hts */ short prim_guard_ph[SC_CRIS_NGUARD]; /* primary guard pulse hts */ u_short sec_tag; /* secondary telescope tag bits */ short sec_ctr_ph[SC_CRIS_NCTRPH]; /* 2ndary ctr pulse hts */ short sec_guard_ph[SC_CRIS_NGUARD]; /* 2ndary guard pulse hts */ struct sc_crisStimData stimdata; /* stimulated event parameters */ }; struct sc_crisHodoData { short x; short y; unsigned long I; }; struct sc_crisStimData { u_char ctr_hi_gain; /* REFA (center) high gain flag */ u_char ctr_pulsers; /* Flags for active REFA (center) pulsers */ u_char ctr_dac_level; /* REFA (center) DAC level */ u_char guard_hi_gain; /* REFB (guard) high gain flag */ u_char guard_pulsers; /* Flags for active REFB (guard) pulsers */ u_char guard_dac_level; /* REFB (guard) DAC level */ u_char soft_led_pulse; /* SOFT LED pulse length */ }; #define SC_CRIS_NCTRPH 10 /* no. of stack center pulse heights */ #define SC_CRIS_NGUARD 6 /* no. of stack guards */
struct sc_diagEvt { struct sc_crisEvt e; /* cris normal data */ struct sc_crisRawStack s; /* raw stack data */ u_short softp[SC_SOFT_MAXSIZE/2]; /* raw soft image data */ u_short softwds; /* no. of 16-bit words of soft image data */ }; struct sc_crisRawStack { u_short tags[4]; /* tag information */ u_short ph[SC_CRIS_NDET]; /* pulse heights - only lowest 12 bits used */ };
It is also possible to look at the raw stack information in more convenient form using the following structure and the function sc_cris_unpack_stack().
/* CRIS raw stack data (unpacked). These structures are the same as Robert * Radocinski's L1_1CrisRaw... structs. I didn't want to use the same names * as he did. These structures is used by sc_cris_stack_unpack(). */ struct sc_crisRawTag { u_char stim_puls_tag; u_char stim_off_tag; u_char hazard; u_char ghor; u_char mor; u_char hor; u_char soft_trig0; u_char soft_trig1; u_char hy_en; u_char he_en; }; struct sc_crisRawTelescopeTag { u_char z1; u_char z2; u_char z_gt_2; u_char adc2; u_char min_range; u_char e1_0, e1_1; u_char e2, e3, e4, e5, e6, e7, e8, e9, g2, g3, g4, g5, g6, g7; }; struct sc_crisRawTelescope { struct sc_crisRawTelescopeTag tag; u_short e1_0, e1_1; u_short e2, e3, e4, e5, e6, e7, e8, e9, g2, g3, g4, g5, g6, g7; }; struct sc_crisRawEvent { struct sc_crisRawTelescope ab; struct sc_crisRawTelescope cd; struct sc_crisRawTag tag; u_char CycleCount; };
/* sc_msuEvt - information about each event as it is processed */ struct sc_msuEvt { u_char *ptr; /* pointer to start of raw data for this evt */ u_long spill; /* current spill number */ u_long size; /* evt size (bytes) (includes any alignment bytes) */ u_long abs; /* absolute evt no. (corrected abs evt no for ID 6) */ u_long abs_orig; /* original (uncorrected) absolute evt no. for ID 6 */ u_long evtno; /* evt no for this type of evt */ u_long vidsize; /* size (bytes) of video data for vid system 1 */ u_long vidsize2; /* size (bytes) of video data for vid system 2 */ u_long clock; /* PC clock tick count */ u_long blobI[SC_MSU_MAXBLOBS]; /* blob intensities */ u_long blobIb[SC_MSU_MAXBLOBS]; /* blob intensities vid sys 2*/ u_short type; /* event type */ u_short exp_id; /* experiment id */ u_short nblobs; /* no. of blob centroids in this evt */ u_short blobx[SC_MSU_MAXBLOBS]; /* blob x coordinates */ u_short bloby[SC_MSU_MAXBLOBS]; /* blob y coordinates */ u_short nblobsb; /* no. of blob centroids in this evt; vid sys 2 */ u_short blobxb[SC_MSU_MAXBLOBS]; /* blob x coordinates vid sys 2 */ u_short blobyb[SC_MSU_MAXBLOBS]; /* blob y coordinates vid sys 2 */ u_char *vidptr; /* pointer to vid sys 1 raw video data (START_HDR) */ u_char *vidptr2; /* pointer to vid sys 2 raw video data (START_HDR) */ char *reply; /* pointer to reply string for reply evts */ struct sc_msuPhas phas; /* pha data */ struct sc_msuDisc disc; /* discriminator, etc. data */ int valid; /* nonzero if this data is valid (see codes above) */ }; /* sc_msuDisc - discriminator, etc stuff */ struct sc_msuDisc { u_char camdisc; /* camera discriminator */ u_char trig1, trig2; /* trigger discrims */ u_char iigain; /* image intensifier gain */ u_char coinen; /* coincidence enable mask */ u_char cointhr1, cointhr2, cointhr3; /* coincidence thresholds */ u_char camdiscb; /* cam discrim vid system 2 */ u_char trig1b, trig2b; /* trigger discrims vid sys 2 */ u_char iigainb; /* image intensifier gain vid sys 2 */ u_short scalars[6]; }; /* sc_msuPhas - pha data. The raw items do not have the parity and hazard * bits masked out. x and y are calculated from x1, x2, y1, and y2. */ struct sc_msuPhas { u_short s1, x1, x2, y1, y2, pd1, pd2, par; u_short s1_raw, x1_raw, x2_raw, y1_raw, y2_raw, pd1_raw, pd2_raw; u_short x, y; u_short s2, x1b, x2b, y1b, y2b; u_short s2_raw, x1b_raw, x2b_raw, y1b_raw, y2b_raw; u_short xb, yb; }; /* codes for the "valid" variable in the sc_msuEvt struct */ #define SC_MSU_INVALID 0 /* data in this "event" is not valid */ #define SC_MSU_EVT 1 /* event was some kind of event */ #define SC_MSU_SPILL 2 /* event was a spill marker */
struct sc_fmapElem { float fiber; /* fiber "number" + relative x position */ char ypos; /* relative y position from tab line */ short layer; /* -1 (NOLAYER) = not mapped; * else Y3=0, X3=1, Y2=2, X2=3, Y1=4, X1=5 */ };
struct sc_Coords_Traj { struct sc_softCoords C; struct sc_softTraj T; struct sc_trajQual Q; u_char blobid[SC_NLAYERS]; short sreserved; double reserved; };
struct sc_softCoords { float x1, y1, x2, y2, x3, y3; /* real x,y in mm for each XY layer */ float fiber[SC_NLAYERS]; /* fiber no. in the layer */ float ypos[SC_NLAYERS]; /* y-position in the layer */ int cam; /* camera (CAM1 or CAM2) */ short xpix[SC_NLAYERS]; /* x pixel value in the layer */ short ypix[SC_NLAYERS]; /* y pixel value in the layer */ unsigned long I[SC_NLAYERS]; /* Intensity value in the layer */ };
struct sc_trajQual { float fit_param; /* measure of fit */ int hop_param; /* measure of hopping */ float Iratio[SC_NLAYERS]; /* ratio of I to maxI in layer */ float qual_factor; /* quality factor */ short raw_dx_1000; /* dx by x_fibers * 1000 */ short raw_dy_1000; /* dy by y_fibers * 1000 */ long lreserved; double reserved; };
struct sc_evt_params { float nextqual; /* qual_param for trajectory following last */ u_char nxtrack; /* number of x_tracks */ u_char nytrack; /* number of y_tracks */ u_char ntraj; /* number of traj.s found (XXX ntraj) */ char ret_code; /* return code from trajectory routines */ char tel; char creserved[3]; };
struct sc_softTraj { double layer1x, layer1y; /* (x,y) in hodo layer 1 (mm) */ double layer2x, layer2y; /* (x,y) in hodo layer 2 (mm) */ double layer3x, layer3y; /* (x,y) in hodo layer 3 (mm) */ double stackx[SC_NSTACK]; /* x at top of each stack (mm) */ double stacky[SC_NSTACK]; /* y at top of each stack (mm) */ double theta; /* (degrees) */ double phi; /* (degrees) */ double chisqx; /* chisq for fit in XZ plane */ double chisqy; /* chisq for fit in YZ plane */ };
The following preprocessor macros can be used to access the stackx and stacky elements.
SC_NSTACK number of stack layers SC_E1 top of E1 SC_E2 top of E2 SC_E3_1 top of E3-1 SC_E3_2 top of E3-2 SC_E3 also top of E3-1 SC_E4_1 top of E4-1 SC_E4_2 top of E4-2 SC_E4 also top of E4-1 SC_E5_1 top of E5-1 SC_E5_2 top of E5-2 SC_E5 also top of E5-1 SC_E6_1 top of E6-1 SC_E6_2 top of E6-2 SC_E6 also top of E6-1 SC_E7_1 top of E7-1 SC_E7_2 top of E7-2 SC_E7 also top of E7-1 SC_E8_1 top of E8-1 SC_E8_2 top of E8-2 SC_E8 also top of E8-1 SC_E9 top of E9
struct sc_crisZ { double MeV[SC_CRIS_NCTRPH - 1]; double zbest; int range; };
/* number of bytes in the cris telemetry minor frame. This is equivalent to * the NUM_CRIS_TELEMETRY_BYTES seen in some non-Lexas programs. */ #define SC_CRIS_TELEMBYTES 58 #define SC_NEVTS_MINOR 10 struct sc_minorFrame { sc_crisSubset s; /* the raw "cris subset" data */ int major_frame_start; /* 1 if beginning of major frame */ int seq; /* sequence no. of this minor frm in major fr */ u_char hsk[3]; /* housekeeping bytes (including SYNC, CMD, * and DIAG bits */ u_char cmd[SC_CRIS_TELEMBYTES-3]; /* cmd string */ int diag; /* no. bytes of diagnostic data */ u_char diagdata[SC_CRIS_TELEMBYTES-3]; /* the diag data */ int nevt; /* no. cris normal evts in this minor frame */ struct sc_crisEvt e[SC_NEVTS_MINOR]; /* the cris normal evt data */ };sc_crisSubset - this is the cris portion of the spacecraft telemetry data. From Robert Radocinski.
typedef struct { u_int PacketSecondaryHeader; u_int TimeOfDay; u_short DayOfYear; u_short year; u_short ErrorFlags; u_short PhaseAngle; u_char facility; u_char subfacility; u_char assembly; u_char DataNature; u_char VirtualChannelId; u_char MajorFrameCount; u_char MinorFrameCount; u_char SpacecraftId; u_char FormatId; u_char MainBusVoltage; u_char MainBusCurrent; u_char CrisInternalTemperature1; u_char CrisInternalTemperature2; u_char CrisInterfaceTemperature; u_char CrisCurrent; u_char CrisData[SC_CRIS_TELEMBYTES]; } sc_crisSubset;
struct L1_1CrisHskp { uint32 ClockCycle; uint32 Second1996; uint32 microsecond; float32 MonitorP5V, MonitorP6V, MonitorM6V, MonitorP7V; float32 MonitorM7V, MonitorP12V, MonitorM12V, MonitorP13V; float32 MonitorM13V, MonitorP15V, MonitorP19V, MonitorMcp1; float32 MonitorMcp2, MonitorHvps1I, MonitorHvps2I, MonitorHvps3I; float32 MonitorHvps4I, MonitorSoftPsaI, MonitorSoftPsbI; float32 TemperatureMotherBoardElect, TemperatureMotherBoardDet; float32 TemperatureMotherBoardC, TemperatureAnalogBoard; float32 TemperaturePostRegBoard, TemperatureLogicBoard; float32 TemperatureE12Elect, TemperatureE12Det; float32 TemperatureE34Elect, TemperatureE34Det; float32 TemperatureE56Elect, TemperatureE56Det; float32 TemperatureE789Elect, TemperatureE789Det; float32 TemperatureLvps, TemperatureHvps; float32 TemperatureFiberPlaneTop0, TemperatureFiberPlaneTop1; float32 TemperatureFiberPlaneMid, TemperatureFiberPlaneBot; float32 TemperatureImageInt1Side, TemperatureImageInt1Rear; float32 TemperatureCamera1Elect, TemperatureHvps1; float32 TemperatureImageInt2Side, TemperatureImageInt2Rear; float32 TemperatureCamera2Elect, TemperatureHvps2; float32 LeakageCurrentE1a, LeakageCurrentE1b; float32 LeakageCurrentE2ab, LeakageCurrentE3ab; float32 LeakageCurrentE4ab, LeakageCurrentE5ab; float32 LeakageCurrentE6ab, LeakageCurrentE7ab; float32 LeakageCurrentE8ab, LeakageCurrentE9ab; float32 LeakageCurrentG2ab, LeakageCurrentG3ab; float32 LeakageCurrentG4ab, LeakageCurrentG5ab; float32 LeakageCurrentG6ab, LeakageCurrentG7ab; float32 LeakageCurrentE1c, LeakageCurrentE1d; float32 LeakageCurrentE2cd, LeakageCurrentE3cd; float32 LeakageCurrentE4cd, LeakageCurrentE5cd; float32 LeakageCurrentE6cd, LeakageCurrentE7cd; float32 LeakageCurrentE8cd, LeakageCurrentE9cd; float32 LeakageCurrentG2cd, LeakageCurrentG3cd; float32 LeakageCurrentG4cd, LeakageCurrentG5cd; float32 LeakageCurrentG6cd, LeakageCurrentG7cd; float32 DacG2ab, DacG3ab, DacG4ab, DacG5ab; float32 DacG6ab, DacG7ab, DacE9ab, DacG2cd; float32 DacG3cd, DacG4cd, DacG5cd, DacG6cd; float32 DacG7cd, DacE9cd; uint8 QualityMonitorP5V, QualityMonitorP6V; uint8 QualityMonitorM6V, QualityMonitorP7V; uint8 QualityMonitorM7V, QualityMonitorP12V; uint8 QualityMonitorM12V, QualityMonitorP13V; uint8 QualityMonitorM13V, QualityMonitorP15V; uint8 QualityMonitorP19V, QualityMonitorMcp1; uint8 QualityMonitorMcp2, QualityMonitorHvps1I; uint8 QualityMonitorHvps2I, QualityMonitorHvps3I; uint8 QualityMonitorHvps4I, QualityMonitorSoftPsaI; uint8 QualityMonitorSoftPsbI; uint8 QualityTemperatureMotherBoardElect; uint8 QualityTemperatureMotherBoardDet; uint8 QualityTemperatureMotherBoardC; uint8 QualityTemperatureAnalogBoard; uint8 QualityTemperaturePostRegBoard; uint8 QualityTemperatureLogicBoard; uint8 QualityTemperatureE12Elect, QualityTemperatureE12Det; uint8 QualityTemperatureE34Elect, QualityTemperatureE34Det; uint8 QualityTemperatureE56Elect, QualityTemperatureE56Det; uint8 QualityTemperatureE789Elect, QualityTemperatureE789Det; uint8 QualityTemperatureLvps, QualityTemperatureHvps; uint8 QualityTemperatureFiberPlaneTop0; uint8 QualityTemperatureFiberPlaneTop1; uint8 QualityTemperatureFiberPlaneMid; uint8 QualityTemperatureFiberPlaneBot; uint8 QualityTemperatureImageInt1Side; uint8 QualityTemperatureImageInt1Rear; uint8 QualityTemperatureCamera1Elect; uint8 QualityTemperatureHvps1; uint8 QualityTemperatureImageInt2Side; uint8 QualityTemperatureImageInt2Rear; uint8 QualityTemperatureCamera2Elect; uint8 QualityTemperatureHvps2; uint8 QualityLeakageCurrentE1a; uint8 QualityLeakageCurrentE1b; uint8 QualityLeakageCurrentE2ab; uint8 QualityLeakageCurrentE3ab; uint8 QualityLeakageCurrentE4ab; uint8 QualityLeakageCurrentE5ab; uint8 QualityLeakageCurrentE6ab; uint8 QualityLeakageCurrentE7ab; uint8 QualityLeakageCurrentE8ab; uint8 QualityLeakageCurrentE9ab; uint8 QualityLeakageCurrentG2ab; uint8 QualityLeakageCurrentG3ab; uint8 QualityLeakageCurrentG4ab; uint8 QualityLeakageCurrentG5ab; uint8 QualityLeakageCurrentG6ab; uint8 QualityLeakageCurrentG7ab; uint8 QualityLeakageCurrentE1c; uint8 QualityLeakageCurrentE1d; uint8 QualityLeakageCurrentE2cd; uint8 QualityLeakageCurrentE3cd; uint8 QualityLeakageCurrentE4cd; uint8 QualityLeakageCurrentE5cd; uint8 QualityLeakageCurrentE6cd; uint8 QualityLeakageCurrentE7cd; uint8 QualityLeakageCurrentE8cd; uint8 QualityLeakageCurrentE9cd; uint8 QualityLeakageCurrentG2cd; uint8 QualityLeakageCurrentG3cd; uint8 QualityLeakageCurrentG4cd; uint8 QualityLeakageCurrentG5cd; uint8 QualityLeakageCurrentG6cd; uint8 QualityLeakageCurrentG7cd; uint8 QualityDacG2ab, QualityDacG3ab; uint8 QualityDacG4ab, QualityDacG5ab; uint8 QualityDacG6ab, QualityDacG7ab; uint8 QualityDacE9ab, QualityDacG2cd; uint8 QualityDacG3cd, QualityDacG4cd; uint8 QualityDacG5cd, QualityDacG6cd; uint8 QualityDacG7cd, QualityDacE9cd; }; struct L1CrisHskp { uint32 ClockCycle; uint32 Second1996; uint32 microsecond; uint16 CommandTableIndex; uint16 MonitorP5V, MonitorP6V, MonitorM6V, MonitorP7V; uint16 MonitorM7V, MonitorP12V, MonitorM12V, MonitorP13V; uint16 MonitorM13V, MonitorP15V, MonitorP19V, MonitorMcp1; uint16 MonitorMcp2, MonitorHvps1I, MonitorHvps2I, MonitorHvps3I; uint16 MonitorHvps4I, MonitorSoftPsaI, MonitorSoftPsbI; uint16 TemperatureMotherBoardElect, TemperatureMotherBoardDet; uint16 TemperatureMotherBoardC, TemperatureAnalogBoard; uint16 TemperaturePostRegBoard, TemperatureLogicBoard; uint16 TemperatureE12Elect, TemperatureE12Det; uint16 TemperatureE34Elect, TemperatureE34Det; uint16 TemperatureE56Elect, TemperatureE56Det; uint16 TemperatureE789Elect, TemperatureE789Det; uint16 TemperatureLvps, TemperatureHvps; uint16 TemperatureFiberPlaneTop0, TemperatureFiberPlaneTop1; uint16 TemperatureFiberPlaneMid, TemperatureFiberPlaneBot; uint16 TemperatureImageInt1Side, TemperatureImageInt1Rear; uint16 TemperatureCamera1Elect, TemperatureHvps1; uint16 TemperatureImageInt2Side, TemperatureImageInt2Rear; uint16 TemperatureCamera2Elect, TemperatureHvps2; uint16 PostDcE1a, PostDcE1b, PostDcE2ab, PostDcE3ab; uint16 PostDcE4ab, PostDcE5ab, PostDcE6ab, PostDcE7ab; uint16 PostDcE8ab, PostDcE9ab, PostDcG2ab, PostDcG3ab; uint16 PostDcG4ab, PostDcG5ab, PostDcG6ab, PostDcG7ab; uint16 PostDcE1c, PostDcE1d, PostDcE2cd, PostDcE3cd; uint16 PostDcE4cd, PostDcE5cd, PostDcE6cd, PostDcE7cd; uint16 PostDcE8cd, PostDcE9cd, PostDcG2cd, PostDcG3cd; uint16 PostDcG4cd, PostDcG5cd, PostDcG6cd, PostDcG7cd; uint8 DacG2ab, DacG3ab, DacG4ab, DacG5ab; uint8 DacG6ab, DacG7ab, DacE9ab, DacG2cd; uint8 DacG3cd, DacG4cd, DacG5cd, DacG6cd; uint8 DacG7cd, DacE9cd, HeaterCcdA, HeaterCcdB; uint8 HeaterCris, StatusTmSide, StatusRefresh; uint8 QualityCommandTableIndex; uint8 QualityMonitorP5V, QualityMonitorP6V; uint8 QualityMonitorM6V, QualityMonitorP7V; uint8 QualityMonitorM7V, QualityMonitorP12V; uint8 QualityMonitorM12V, QualityMonitorP13V; uint8 QualityMonitorM13V, QualityMonitorP15V; uint8 QualityMonitorP19V, QualityMonitorMcp1; uint8 QualityMonitorMcp2, QualityMonitorHvps1I; uint8 QualityMonitorHvps2I, QualityMonitorHvps3I; uint8 QualityMonitorHvps4I, QualityMonitorSoftPsaI; uint8 QualityMonitorSoftPsbI; uint8 QualityTemperatureMotherBoardElect; uint8 QualityTemperatureMotherBoardDet; uint8 QualityTemperatureMotherBoardC; uint8 QualityTemperatureAnalogBoard; uint8 QualityTemperaturePostRegBoard; uint8 QualityTemperatureLogicBoard; uint8 QualityTemperatureE12Elect, QualityTemperatureE12Det; uint8 QualityTemperatureE34Elect, QualityTemperatureE34Det; uint8 QualityTemperatureE56Elect, QualityTemperatureE56Det; uint8 QualityTemperatureE789Elect, QualityTemperatureE789Det; uint8 QualityTemperatureLvps, QualityTemperatureHvps; uint8 QualityTemperatureFiberPlaneTop0; uint8 QualityTemperatureFiberPlaneTop1; uint8 QualityTemperatureFiberPlaneMid; uint8 QualityTemperatureFiberPlaneBot; uint8 QualityTemperatureImageInt1Side; uint8 QualityTemperatureImageInt1Rear; uint8 QualityTemperatureCamera1Elect; uint8 QualityTemperatureHvps1; uint8 QualityTemperatureImageInt2Side; uint8 QualityTemperatureImageInt2Rear; uint8 QualityTemperatureCamera2Elect; uint8 QualityTemperatureHvps2; uint8 QualityPostDcE1a, QualityPostDcE1b; uint8 QualityPostDcE2ab, QualityPostDcE3ab; uint8 QualityPostDcE4ab, QualityPostDcE5ab; uint8 QualityPostDcE6ab, QualityPostDcE7ab; uint8 QualityPostDcE8ab, QualityPostDcE9ab; uint8 QualityPostDcG2ab, QualityPostDcG3ab; uint8 QualityPostDcG4ab, QualityPostDcG5ab; uint8 QualityPostDcG6ab, QualityPostDcG7ab; uint8 QualityPostDcE1c, QualityPostDcE1d; uint8 QualityPostDcE2cd, QualityPostDcE3cd; uint8 QualityPostDcE4cd, QualityPostDcE5cd; uint8 QualityPostDcE6cd, QualityPostDcE7cd; uint8 QualityPostDcE8cd, QualityPostDcE9cd; uint8 QualityPostDcG2cd, QualityPostDcG3cd; uint8 QualityPostDcG4cd, QualityPostDcG5cd; uint8 QualityPostDcG6cd, QualityPostDcG7cd; uint8 QualityDacG2ab, QualityDacG3ab; uint8 QualityDacG4ab, QualityDacG5ab; uint8 QualityDacG6ab, QualityDacG7ab; uint8 QualityDacE9ab, QualityDacG2cd; uint8 QualityDacG3cd, QualityDacG4cd; uint8 QualityDacG5cd, QualityDacG6cd; uint8 QualityDacG7cd, QualityDacE9cd; uint8 QualityHeaterCcdA, QualityHeaterCcdB; uint8 QualityHeaterCris, QualityStatusTmSide; uint8 QualityStatusRefresh; }; /* ClockCycle = S/C clock of the first minor frame of the cycle */ /* */ /* Note: Quality bits are defined in the table below. If the field */ /* which the quality byte is trying to characterize contains */ /* multiple bytes, the quality byte associated with the field */ /* is the logical "or" of the individual quality bytes. */ /* */ /* Quality bits: */ /* 0x01 = Format ID error */ /* 0x02 = Minor/major counter error */ /* 0x04 = S/C clock error */ /* 0x08 = Sync bit error */ /* 0x10 = Command table index error */ /* 0x20 = Cycle number error */ /* 0x40 = Level 0 quality bit */ /* 0x80 = Level 1 quality bit */
struct L1CrisCommandEcho { uint32 ClockMinorFrame; uint32 Second1996; uint32 microsecond; uint8 NumberChars; char8 CommandEcho[MAX_NUM_CRIS_CMD_ECHO_CHARS]; }; /* ClockMinorFrame = S/C clock of the minor frame containing the */ /* command echo */ /* NumberChars = Number of characters in the command echo */ /* CommandEcho = Command echo characters */
struct L1CrisHighPriorityRate { uint32 ClockMinorFrame; uint32 Second1996; uint32 microsecond; uint32 hp[NUM_CRIS_HIGH_PRIORITY_RATES]; uint8 QualityHp[NUM_CRIS_HIGH_PRIORITY_RATES]; }; /* ClockMinorFrame = S/C clock of the minor frame in which the */ /* high priority rate accumulation began */ /* hp = high priority rates */ /* QualityHp = Quality data flags for high priority rates */ /* */ /* Note: All rates are decompressed. */ /* */ /* Note: Quality bits are defined in the table below. If the field */ /* which the quality byte is trying to characterize contains */ /* multiple bytes, the quality byte associated with the field */ /* is the logical "or" of the individual quality bytes. */ /* */ /* Quality bits: */ /* 0x01 = Format ID error */ /* 0x02 = Minor/major counter error */ /* 0x04 = S/C clock error */ /* 0x08 = Sync bit error */ /* 0x10 = Command table index error */ /* 0x20 = Cycle number error */ /* 0x40 = Level 0 quality bit */ /* 0x80 = Level 1 quality bit */
struct L1_1CrisLowPriorityRate { uint32 ClockCycle; uint32 Second1996; uint32 microsecond; float32 stmco, stmoff, z1ab, z2ab, z_gt_2ab, z1cd, z2cd, z_gt_2cd; float32 hazard, gh, mor, hor, adc2ab, mnrgab; float32 adc2cd, mnrgcd, e1a, e1b, e2ab, e3ab; float32 e4ab, e5ab, e6ab, e7ab, e8ab, e9ab; float32 g2ab, g3ab, g4ab, g5ab, g6ab, g7ab; float32 e1c, e1d, e2cd, e3cd, e4cd, e5cd; float32 e6cd, e7cd, e8cd, e9cd, g2cd, g3cd; float32 g4cd, g5cd, g6cd, g7cd; float32 EventBufferRate[NUM_CRIS_EVT_BUFFERS]; float32 livetim, helivet, hylivet, trg0rat, trg1rat, trg01; float32 ntagint, nvldint, nevproc, nrtproc, nsfterr, nbadid; float32 ncebful, nrebful, nmacsys, nhdwrej; float32 DataBufferRate[NUM_CRIS_EVT_BUFFERS], uint8 QualityStmco, QualityStmoff, QualityZ1ab, QualityZ2ab; uint8 QualityZ_gt_2ab, QualityZ1cd, QualityZ2cd, QualityZ_gt_2cd; uint8 QualityHazard, QualityGh, QualityMor, QualityHor; uint8 QualityAdc2ab, QualityMnrgab, QualityAdc2cd, QualityMnrgcd; uint8 QualityE1a, QualityE1b, QualityE2ab, QualityE3ab; uint8 QualityE4ab, QualityE5ab, QualityE6ab, QualityE7ab; uint8 QualityE8ab, QualityE9ab, QualityG2ab, QualityG3ab; uint8 QualityG4ab, QualityG5ab, QualityG6ab, QualityG7ab; uint8 QualityE1c, QualityE1d, QualityE2cd, QualityE3cd; uint8 QualityE4cd, QualityE5cd, QualityE6cd, QualityE7cd; uint8 QualityE8cd, QualityE9cd, QualityG2cd, QualityG3cd; uint8 QualityG4cd, QualityG5cd, QualityG6cd, QualityG7cd; uint8 QualityEventBufferRate[NUM_CRIS_EVT_BUFFERS]; uint8 QualityLivetim, QualityHelivet, QualityHylivet, QualityTrg0rat; uint8 QualityTrg1rat, QualityTrg01, QualityNtagint, QualityNvldint; uint8 QualityNevproc, QualityNrtproc, QualityNsfterr, QualityNbadid; uint8 QualityNcebful, QualityNrebful, QualityNmacsys, QualityNhdwrej; uint8 QualityDataBufferRate[NUM_CRIS_EVT_BUFFERS]; }; struct L1CrisLowPriorityRate { uint32 ClockCycle; uint32 Second1996; uint32 microsecond; uint32 stmco, stmoff, z1ab, z2ab, z_gt_2ab, z1cd, z2cd; uint32 z_gt_2cd, hazard, gh, mor, hor, adc2ab, mnrgab; uint32 adc2cd, mnrgcd, e1a, e1b, e2ab, e3ab, e4ab; uint32 e5ab, e6ab, e7ab, e8ab, e9ab, g2ab, g3ab; uint32 g4ab, g5ab, g6ab, g7ab, e1c, e1d, e2cd; uint32 e3cd, e4cd, e5cd, e6cd, e7cd, e8cd, e9cd; uint32 g2cd, g3cd, g4cd, g5cd, g6cd, g7cd; uint32 EventBuffer[NUM_CRIS_EVT_BUFFERS]; uint32 livetim, helivet, hylivet, trg0rat, trg1rat, trg01, ntagint; uint32 nvldint, nevproc, nrtproc, nsfterr, nbadid, ncebful, nrebful; uint32 nmacsys, nhdwrej; uint16 NumberEvents[NUM_CRIS_EVT_BUFFERS]; uint8 QualityStmco, QualityStmoff, QualityZ1ab, QualityZ2ab; uint8 QualityZ_gt_2ab, QualityZ1cd, QualityZ2cd, QualityZ_gt_2cd; uint8 QualityHazard, QualityGh, QualityMor, QualityHor; uint8 QualityAdc2ab, QualityMnrgab, QualityAdc2cd, QualityMnrgcd; uint8 QualityE1a, QualityE1b, QualityE2ab, QualityE3ab; uint8 QualityE4ab, QualityE5ab, QualityE6ab, QualityE7ab; uint8 QualityE8ab, QualityE9ab, QualityG2ab, QualityG3ab; uint8 QualityG4ab, QualityG5ab, QualityG6ab, QualityG7ab; uint8 QualityE1c, QualityE1d, QualityE2cd, QualityE3cd; uint8 QualityE4cd, QualityE5cd, QualityE6cd, QualityE7cd; uint8 QualityE8cd, QualityE9cd, QualityG2cd, QualityG3cd; uint8 QualityG4cd, QualityG5cd, QualityG6cd, QualityG7cd; uint8 QualityEventBuffer[NUM_CRIS_EVT_BUFFERS]; uint8 QualityLivetim, QualityHelivet, QualityHylivet, QualityTrg0rat; uint8 QualityTrg1rat, QualityTrg01, QualityNtagint, QualityNvldint; uint8 QualityNevproc, QualityNrtproc, QualityNsfterr, QualityNbadid; uint8 QualityNcebful, QualityNrebful, QualityNmacsys, QualityNhdwrej; uint8 QualityNumberEvents; }; /* ClockCycle = Adjusted S/C clock of the first minor frame of */ /* the cycle in which the rate was accumulated. */ /* The value 256 is subtracted from the S/C clock of */ /* the first minor frame of the cycle in which the */ /* low priority rates were readout. */ /* */ /* Note: All rates are decompressed. */ /* */ /* Note: Quality bits are defined in the table below. If the field */ /* which the quality byte is trying to characterize contains */ /* multiple bytes, the quality byte associated with the field */ /* is the logical "or" of the individual quality bytes. */ /* */ /* Quality bits: */ /* 0x01 = Format ID error */ /* 0x02 = Minor/major counter error */ /* 0x04 = S/C clock error */ /* 0x08 = Sync bit error */ /* 0x10 = Command table index error */ /* 0x20 = Cycle number error */ /* 0x40 = Level 0 quality bit */ /* 0x80 = Level 1 quality bit */
Routines from the ASC CRIS level 1.1 C library by Robert Radocinski and Bruce Sears may be freely used with softlib routines. Note that the softlib sc_crisEvt is the same structure as the level1 ce_crisEvt. Either name may be used in a softlib program.
However, softlib also provides a simplified interface to a basic set of the level 1.1 library routines. It is hoped that these routines will prove to be adequate for the most usual ways of working with level1 data. Note that softlib uses the L1 library instead of the standard ASC libraries.
In using level 1 data, the program specifies a range of days that it wants data for. Days are numbered starting with January 1, 1996 as day 1. August 27, 1997, the day the spacecraft was launched, was day 605. After specifying the range of days, any one of a number of functions can be used to examine the next normal event, diagnostic event, housekeeping structure, command echo, high prioriy rate, or low priority rate. See the reference section for the details.
The level1 library routines require that the user set an environment variable that specifies the location of the data. Here at the Experimental Astrophysics Group (LEXAS) at Washington U, the data is located at /data5/ace/data/level1 and the environment variable should have been set for you. If not, run the following commands: to see which shell you are using, run echo $SHELL.
You'll probably have to start up a new shell for the change to take effect.
Here is a code fragment that illustrates the use of the sc_L1_next_cris_evt() function.
struct ce_crisEvt c; long cnt = 0L; int curday; int day1996; int endday; int startday; long totcnt = 0L; if (argc != 3) { fprintf(stderr, "USAGE: %s startday endday\n", argv[0]); exit(1); } startday = atoi(argv[1]); endday = atoi(argv[2]); fprintf(stderr, "start %d end %d\n", startday, endday); sc_L1_set_day(startday, endday); curday = startday; while ((sc_L1_next_cris_evt(&c, &day1996)) != -1) { printf("day=%d evtno=%ld secs1996=%ld\n", day1996, c.evtno, c.secs1996); if (day1996 != curday) { fprintf(stderr, "day %d: %ld\n", curday, cnt); curday = day1996; cnt = 0; } cnt++; totcnt++; } fprintf(stderr, "day %d: %ld\n", curday, cnt); fprintf(stderr, "%s: processed %ld evts\n", argv[0], totcnt);
Here is a code fragment that illustrates the use of the sc_L1_next_hsk_raw() function.
long cnt = 0L; int curday; struct L1CrisHskp d1; int day1996; int endday; int startday; long totcnt = 0L; if (argc != 3) { fprintf(stderr, "USAGE: %s startday endday\n", argv[0]); exit(1); } startday = atoi(argv[1]); endday = atoi(argv[2]); fprintf(stderr, "start %d end %d\n", startday, endday); sc_L1_set_day(startday, endday); curday = startday; while ((sc_L1_next_hsk_raw(&d1, &day1996)) != -1) { printf("day=%d Second1996=%ld cycle=%d\n", day1996, d1.Second1996, d1.ClockCycle); if (day1996 != curday) { fprintf(stderr, "\t\tday %d: %ld\n", curday, cnt); curday = day1996; cnt = 0; } cnt++; totcnt++; } fprintf(stderr, "day %d: %ld\n", curday, cnt); fprintf(stderr, "%s: processed %ld evts\n", argv[0], totcnt);
Here is a code fragment that illustrates the use of the sc_L1_next_hipri_rate_sec() function. The _sec functions are used to return structures starting and ending at particular times during a range of days. The times are specified by using the Seconds1996 values.
long cnt = 0L; int curday; struct L1CrisHighPriorityRate d1; int day1996; int endday; int endsec; int startday; int startsec; long totcnt = 0L; if (argc != 5) { fprintf(stderr, "USAGE: %s startday endday startsec endsec\n", argv[0]); exit(1); } startday = atoi(argv[1]); endday = atoi(argv[2]); startsec = atoi(argv[3]); endsec = atoi(argv[4]); fprintf(stderr, "start %d end %d\n", startday, endday); fprintf(stderr, "start sec %d end sec %d\n", startsec, endsec); /* set the starting and ending days */ sc_L1_set_day(startday, endday); /* set the starting and ending seconds */ sc_L1_set_start_end_sec(startsec, endsec); curday = startday; /* The first struct will be after startsec on startday, * and the last one will be before endsec on endday. */ while ((sc_L1_next_hipri_rate_sec(&d1, &day1996)) != -1) { printf("day=%d Second1996=%ld cycle=%d\n", day1996, d1.Second1996, d1.ClockCycle); if (day1996 != curday) { fprintf(stderr, "\t\tday %d: %ld\n", curday, cnt); curday = day1996; cnt = 0; } cnt++; totcnt++; } fprintf(stderr, "day %d: %ld\n", curday, cnt); fprintf(stderr, "%s: processed %ld evts\n", argv[0], totcnt);
To extract the CRIS subset, the raw spacecraft data must be processed by the program cris_test_extr. This program should be installed in some standard place in the filesystem, such as /usr/local/bin/ace/cris_test_extr. The source code is found in the Util/Downlink subdirectory of the SOFT/CRIS library source directory. It uses Robert Radocinski's downlink routines.
Important! The routines described below only operate on the CRIS subset data, not on the raw ACE spacecraft data. Therefore, you must run the data through cris_test_extr first. For example, if the ACE spacecraft data is in the file /data4/ace/test_data/CRIS.970212.dsn, then run the following command:
cris_test_extr /data4/ace/test_data/CRIS.970212.dsn > crisdatand then use the resulting file crisdat as the input file for your program.
1 #include <stdio.h> 2 #include <softcris.h> 3 4 int 5 main(argc, argv) 6 int argc; 7 char *argv[]; 8 { 9 struct sc_crisEvt c; 10 FILE *fp; 11 int i; 12 int j; 13 int ret; 14 15 fp = stdin; 16 17 ret = sc_tlm_sync_major(fp); 18 if (ret == 0) { 19 /* EOF */ 20 exit(0); 21 } else if (ret < 0) { 22 /* error */ 23 exit(1); 24 } 25 fprintf(stderr,"sync after %d minor frames\n", ret); 26 while (1) { 27 ret = sc_tlm_next_cris_evt(&c, fp); 28 if (ret == 0) { 29 /* EOF */ 30 exit(0); 31 } else if (ret <= -1) { 32 /* error */ 33 exit(1); 34 } else { 35 printf("%d", c.nbytes); 36 printf(" cam %d", sc_tlm_cam_guess()); 37 printf(" mcp1 %d mcp2 %d", sc_tlm_hsk_mcp1(), sc_tlm_hsk_mcp2()); 38 } 39 } 40 }
/* sc_ch2 - data at the beginning of the chap 2 (up to the user data) */ struct sc_ch2 { u_char *p; /* ptr to raw chap 2 data */ short key; short spare; short tags1; /* verse 1 (tagbits) */ short tags0; u_char ext_tags; u_char cal_dac_hi_bytes; short cal_dac_lo_bytes; u_long time_seq; /* verse 2 (time) */ u_long time; u_long live_time; short base_peak_time[24][3]; /* verse 3 (evt data) */ short user_data_words; /* verse 4 (user data) */ short stage[8]; u_char *userp; /* ptr to raw user data */ long seq_no; /* verse 5 (stop) */ long sync; };
The main point of softlib is to determine the trajectory a particle took. To get a trajectory, you must have the data in the form of either a CRIS normal event or an MSU event. The Cookbook has recipes for getting the next event, depending on the source of the data (level1, raw dsn, GSI, or MSU). After that, one of the trajectory routines must be used. See the Cookbook questions relating to CRIS and MSU data.
struct sc_crisEvt c; int day1996; ... sc_L1_set_day(startday, endday); ... while (sc_L1_next_cris_evt(&c, &day1996) != -1) { /* process the event */ } }
struct sc_crisEvt c; int day1996; ... sc_L1_set_day(startday, endday); sc_L1_set_start_end_sec(startsec, endsec); ... while (sc_L1_next_cris_evt(&c, &day1996) != -1) { /* process the event */ } }
struct sc_crisEvt c; int day1996; ... /* we want days 105 thru 110 of year 1998 */ startday = sc_day_of_year_96(1998, 105); endday = sc_day_of_year_96(1998, 110); sc_L1_set_day(startday, endday); sc_L1_set_start_end_sec(startsec, endsec); ... while (sc_L1_next_cris_evt(&c, &day1996) != -1) { /* process the event */ } }
struct sc_diagEvt c; int day1996; ... sc_L1_set_day(startday, endday); ... while (sc_L1_next_diag(&c, &day1996) != -1) { /* process the event */ } }
struct sc_crisEvt c; FILE *fp; int i; ... while (1) { ret = sc_tlm_next_cris_evt(&c, fp); if (ret == 0) { /* EOF */ exit(0); } else if (ret <= -1) { /* error */ exit(1); } else { /* process the event */ } }
struct sc_diagEvt d; FILE *fp; int i; ... while (1) { ret = sc_tlm_next_diag(&d, fp); if (ret == 0) { /* EOF */ exit(0); } else if (ret <= -1) { /* error */ exit(1); } else { /* process the event */ } }
struct sc_crisEvt c; struct sc_diagEvt d; FILE *fp; int i; int norm; ... while (1) { ret = sc_tlm_next_evt(&c, &d, fp, &norm); if (ret == 0) { /* EOF */ exit(0); } else if (ret < -1) { /* error */ exit(1); } else { /* process the event */ if (norm) { /* got a normal evt - use c */ printf("nblobs = %d\n", c.nblobs); } else { /* got a diagnostic evt - use d */ printf("stack[2] = %u\n", d.s.ph[2]); } } }
FILE *fp; struct sc_ch2 ch2; struct sc_diagEvt d; char *filename; ... while (1) { ret = sc_gsi_next_evt(fp, &ch2, &d, filename); if (ret != SC_GSI_OK) { /* error */ break; } printf("size of normal part is %d bytes\n", d.e.nbytes); }
#include <softcris.h> #include <msu.h> ... struct sc_msuEvt e; FILE *fp; char *progname; int ret; ... progname = argv[0]; fp = stdin; ret = sc_msu_init(fp, NULL, 0, progname); if (ret != 0) { fprintf(stderr, "couldn't alloc memory\n"); exit(1); } while (1) { ret = sc_msu_next_evt(&e); if (ret < 0) { /* EOF or error */ fprintf(stderr, "error message here\n"); exit(1); } else { /* process the event */ if (e.valid == SC_MSU_EVT) { printf("vidsize cam 1 = %ld\n", e.vidsize); printf("vidsize cam 2 = %ld\n", e.vidsize2); } } }
struct sc_crisEvt c; int i; ... while (1) { sc_tlm_next_cris_evt(&c, fp); for (i = 0; i < c.nblobs; i++) { printf("x = %d y = %d intensity = %d\n", c.hodo[i].x, c.hodo[i].y, c.hodo[i].I); } }
struct sc_crisEvt c; struct sc_softCoords kp; int ret; ... while (1) { sc_tlm_next_cris_evt(&c, fp); ret = sc_cris_coords(&c, &kp, SC_CAM2); if (ret == 0) { printf("layer 1: x = %d mm y = %d mm\n", kp.x1, kp.y1); printf("layer 2: x = %d mm y = %d mm\n", kp.x2, kp.y2); printf("layer 3: x = %d mm y = %d mm\n", kp.x3, kp.y3); }
#include <softcris.h> #include <msu.h> ... struct sc_msuEvt e; FILE *fp; struct sc_softCoords k1, k2; char *progname; int ret; ... progname = argv[0]; fp = stdin; ret = sc_msu_init(fp, NULL, 0, progname); if (ret != 0) { fprintf(stderr, "couldn't alloc memory\n"); exit(1); } while (1) { ret = sc_msu_next_evt(&e); if (ret < 0) { /* EOF or error */ fprintf(stderr, "error message here\n"); exit(1); } else { /* process the event */ if (e.valid == SC_MSU_EVT) { ret = sc_msu_coords (&e, &k1, &k2); if (ret) { fprintf(stderr,"error!\n"); continue; } printf("cam 1, layer 1: fiber(X1): %.2f y offset(X1): %.2f ", k1.fiber[SC_X1], k1.ypos[SC_X1]); printf("cam 2, layer 3: real x: %.2f mm real y: %.2f mm\n", k2.x3, k2.y3); } } }
#define NTRAJ 1 /* number of trajectories desired */ struct sc_crisEvt c; int errcode; int i; int ntraj; int ret; struct sc_Coords_Traj t[NTRAJ]; ... sc_cris_set_cam(SC_CAM2); sc_traj_select_method(8); /* 8 = multitraj; 4 = fiberfit */ while (1) { sc_tlm_next_cris_evt(&c, fp); ntraj = NTRAJ; ret = sc_cris_traj(&c, t, &ntraj); if (ret == 0) { for (i=0; i<ntraj; i++) { printf("traj %d: theta=%.2f quality=%.2f\n", i, t[i].T.theta, t[i].Q.qual_factor); } } else { errcode = sc_get_err_code(); printf("%s\n", sc_get_err_str()); } }
#define NTRAJ 20 /* number of trajectories desired */ struct sc_msuEvt e; int errcode; int i; int ntraj1; int ntraj2; int ret; struct sc_Coords_Traj t1[NTRAJ]; struct sc_Coords_Traj t2[NTRAJ]; ... sc_cris_set_cam(SC_CAM2); sc_traj_select_method(8); /* 8 = multitraj; 4 = fiberfit */ while (1) { sc_next_msu_evt(&e); ntraj1 = ntraj2 = NTRAJ; ret = sc_msu_traj(&c, t1, t2, &ntraj1, &ntraj2); if ((ret & 0x01) == 0) { /* cam 1 okay */ for (i=0; i<ntraj1; i++) { printf("traj %d: cam 1: theta=%.2f quality=%.2f\n", i, t1[i].T.theta, t1[i].Q.qual_factor); } if ((ret & 0x02) == 0) { /* cam 2 okay */ for (i=0; i<ntraj2; i++) { printf("traj %d: cam 2: theta=%.2f quality=%.2f\n", i, t2[i].T.theta, t2[i].Q.qual_factor); } } }
Before you can get the trajectory, you must first get the coordinates. See these links, depending on whether you are using SOFT MSU calibration data or CRIS normal events. After you have the coordinates, use the function sc_trajectory(). Once you have calculated the coordinates, the call to sc_trajectory() is the same no matter what the source of the data.
struct sc_crisEvt c; struct sc_softCoords kp; struct sc_softTraj t; int ret; ... while (1) { sc_tlm_next_cris_evt(&c, fp); ret = sc_cris_coords(&c, &kp, SC_CAM2); if (ret == 0) { ret = sc_trajectory(&kp, &t); printf("theta = %.2f phi = %.2f\n", t.theta, t.phi); } }
struct sc_crisEvt c; struct sc_softCoords kp; struct sc_softTraj t; struct sc_crisZ z; int ret; ... while (1) { sc_tlm_next_cris_evt(&c, fp); ret = sc_cris_coords(&c, &kp, SC_CAM2); if (ret == 0) { ret = sc_trajectory(&kp, &t); if (ret == 0) { ret = sc_z(&c, &t, &z); if (ret == 0) { printf("charge = %.2f range = %d\n", z.zbest, z.range); } } } }
struct sc_diagEvt d; int i; int ret; long blob_int[SC_MSU_MAXBLOBS]; int blob_npix; char errormesg[1000]; int soft_nblobs; int x_cen[SC_MSU_MAXBLOBS], y_cen[SC_MSU_MAXBLOBS]; ... while (1) { ret = sc_tlm_next_diag(&d, fp); if (ret == 1) { ret = sc_cris_blobify((u_char *)d.softp, x_cen, y_cen, errormesg, NULL, &blob_npix, blob_int, NULL, 5, NULL, NULL); if (ret < 0) { fprintf("Error! (%d)\n", ret); } else { printf("%d blobs\n", ret); for (i=0; i < ret; i++) { printf("x = %d y = %d I = %d\n", x_cen[i], y_cen[i], blob_int[i]); } } } }
/* find up to 100 blobs per image */ sc_set_maxblobs(100);
int max; ... max = sc_get_maxblobs(); printf("maximum no. of blobs is %d\n", max);
struct sc_diagEvt d; u_short x, y, I; int ret; ... while (1) { ret = sc_tlm_next_diag(&d, fp); if (ret == 1) { ret = sc_next_pix(&x, &y, &I, d.softp); while (ret == 1) { printf("x = %d y = %d I = %d\n", x, y, I); ret = sc_next_pix(&x, &y, &I, NULL); } if (ret == -1) { fprintf(stderr,"Error!\n"); } if (ret == 0) { fprintf(stderr,"No more pixels in image\n"); } } }
struct sc_diagEvt d; u_short x, y, I; int ret; long blob_int[SC_MSU_MAXBLOBS]; int blob_npix; char errormesg[1000]; int soft_nblobs; int x_cen[SC_MSU_MAXBLOBS], y_cen[SC_MSU_MAXBLOBS]; int seg_blob[SC_MSU_MAXBLOBS]; int seg_blobtot; int seg_nblob; int seg_tot; ... while (1) { ret = sc_tlm_next_diag(&d, fp); if (ret == 1) { ret = sc_cris_blobify((u_char *)d.softp, x_cen, y_cen, errormesg, NULL, &blob_npix, blob_int, NULL, 5, NULL, NULL); sc_blob_segments(&seg_nblob, seg_blob, &seg_blobtot, &seg_tot); printf("int segres[] = {%d, ", seg_nblob); printf("%d, ", seg_blobtot); printf("%d", seg_tot); for (i=0; i < seg_nblob; i++) { printf(", %d", seg_blob[i]); } printf("};\n"); } }
int cam; int x, y; struct sc_fmapElem *f; ... f = sc_centr_to_fiber(cam, x, y); if (f != NULL) { printf("layer for (%d,%d) is %d\n", x, y, f->layer); }
Return codes
It is only required when using the functions sc_msu_next_evt() and sc_msu_next_pix(). If you are not using these routines, there is no need to run sc_msu_init(). In fact, it is a bad idea to run it because it allocates a large data buffer.
Return codes: -1 if it cannot allocate memory, else 0.
Before running this function, you must first run
sc_msu_init().
After a call to sc_msu_next_evt(), the valid
element in the sc_msuEvt struct will have one of the
following values:
Note that methods 1, 2, 3, 5, 6, and 7 are inferior variations of methods 4 or 8, and should not be used.
Note that ntraj is ignored if we are not using the multitraj method.
Note that ntraj1 and ntraj2 are ignored if we are not using the multitraj method.
Returns 0 if all goes well, else -2 for bad range, -3 for a stim event, or -4 for no min or bad min (whatever that means).
NOTE: this code is based on the work of Mike Thayer and is not well-understood by the main author of the library. Also it may not be the most up-to-date version of Mike's code.
This function returns 0 if we were able to hop successfully, else -1.
Return codes:
int sc_cris_blobify(dataptr, x_cen, y_cen, errormsg, blob_pix_ptr, blob_npix, blob_int, pix_per_blob, min_pix, Fx_cen, Fy_cen) u_char *dataptr; /* ptr to image data (in) */ int *x_cen; /* ptr to array of centroid x-coords (out) */ int *y_cen; /* ptr to array of centroid y-coords (out) */ char *errormsg; /* ptr to string that can hold a message (out) */ u_short *blob_pix_ptr; /* ptr to shorts that will hold pixel values * that are in blobs. If NULL, no pixel * values are saved. */ int *blob_npix; /* no. of pixels in blobs found */ long *blob_int; /* ptr to blob intensity values (long) */ int *pix_per_blob; /* ptr to no. of pixels in each blob (int) */ int min_pix; /* min. # pixels to form a blob - use default if < 0 */ double *Fx_cen; /* ptr to array of centroid x-coords - floating point */ double *Fy_cen; /* ptr to array of centroid y-coords - floating point */
Return values: if all went well, the number of centroids in the image is returned, else some negative value.
int sc_msu_blobify(e, x_cen, y_cen, errormsg, blob_pix_ptr, blob_npix, blob_int, pix_per_blob, min_pix, Fx_cen, Fy_cen, vidsys) struct sc_msuEvt *e; /* ptr to sc_msuEvt structure for this event (in) */ int *x_cen; /* ptr to array of centroid x-coords (out) */ int *y_cen; /* ptr to array of centroid y-coords (out) */ char *errormsg; /* ptr to string that can hold a message (out) */ /* blob_pix_ptr: ptr to shorts that will hold pixel values that are in * blobs. If NULL, no pixel values are saved. */ u_short *blob_pix_ptr; int *blob_npix; /* no. of pixels in blobs found */ long *blob_int; /* ptr to blob intensity values (long) */ int *pix_per_blob; /* ptr to no. of pixels in each blob (int) */ int min_pix; /* min. # pixels to form a blob - use default if < 0 */ double *Fx_cen; /* ptr to array of centroid x-coords - floating point */ double *Fy_cen; /* ptr to array of centroid y-coords - floating point */ int vidsys; /* vidsys: which camera to use; either 1 or 2 */
This function is similar to the sc_cris_blobify() function, except that it operates on MSU calibration data. The first argument is a pointer to an sc_msuEvt, and the argument vidsys specifies which camera to blobify: SC_CAM1 or SC_CAM2.
Format of CRIS major and minor frames Byte Item Count Bits Sum Description A. Major frame = 256 minor frames 0 a 4 8 32 4 byte offset 4 b 128 58x8 xxx minor frames w/SYNC=0 xxx c 128 58x8 yyy minor frames w/SYNC=1 B. Minor frame = 58 bytes Housekeeping bytes (Note that these bytes really start at an offset of 4 bytes from the start of the data. Those 4 bytes contain the last 4 bytes of the previous minor frame.) 0 0 1 1 1 SYNC = 0 for 1st 128 minor frames, = 1 for 2nd 128 minor frames 1 1 1 2 CMD = 1 if we have a cmd response 2 1 1 3 DIAG = 1 for diagnostic mode 3 1 5 8 housekeeping bits 1 4 1 8 16 more housekeeping bits 2 5 1 8 24 more housekeeping bits Command response (if item #1 [CMD bit] is true) 3 6 1 8 8 length L of response (bytes) 4 7 L Lx8 8+(Lx8) command echo (ascii chars) CRIS normal events (if item #2 [DIAG bit] is false) (May be continued from previous minor frame unless this is the start of a new major frame. Note that the event may have a length of 0, in which case the rest of the current minor frame should be skipped. If the normal event is longer than the space left in the minor frame, it continues in the next minor frame, unless it is the last minor frame in the major frame, in which case it is truncated or zeroed.) 3 or 4+L 8 N X Y CRIS Normal events DIAGNOSTIC mode data (if item #2 [DIAG bit] is true) (Can extend across minor and major frames. Can interrupt a CRIS normal event, which will then resume after Diag mode is done.) 3 or 4+L 9 N X Y Diagnostic mode data (Normal evt + stack data + SOFT image)
The ASC level 1 and 1.1 libraries do a great job of handling the data retrieval work for the CRIS data. However, one complexity of the libraries is that they require the application to #include a number of different header files (different ones depending on which routines are being used), and to be linked with a number of different ASC libraries. I found all this detail difficult to keep track of. It also required more complicated makefiles.
To remedy this problem, I have managed to incorporate all the level 1 and level 1.1 stuff into one header file and one library. This library is called the ``L1'' library. When using L1, the application only needs to include one header file (#include <L1.h>) and link with one additional library (-lL1). (in fact, when using softlib, the #include line is unnecessary because softlib.h does it for you. The header file and library are also placed in standard system locations (/usr/local/include and /usr/local/lib).
All this allows for simpler C programs and makefiles, promoting programmer sanity.
The L1 library and header file can be produced from the standard ASC libraries without modifying any of the original distribution files. A makefile that builds the library will hopefully be available here.
These are the error codes and messages that can be retrieved using sc_get_err_code() and sc_get_err_mesg(). See also error codes. Hopefully, the list will be updated.
0 "traj_init: bad fitfunc" 1 "traj_init: can't calloc 'blobhodo'" 2 "traj_init: can't calloc 'I'" 3 "traj_init: can't calloc 'X'" 4 "traj_init: can't calloc 'Y'" 8-13 "traj_init: can't calloc 'blob[%d]'" 14 "traj_init: Can't calloc 'Mx'" 15 "traj_init: Can't calloc 'Bx'" 16 "traj_init: Can't calloc 'My'" 17 "traj_init: Can't calloc 'By'" 100 "sc_cris_traj: recv'd NULL parameter c or t" 101 "sc_cris_traj: garbled Traj_select_method = %d", 102 "sc_cris_traj: zero pha in top detector" 103 "sc_cris_traj: more than 1 hop" 109 "sc_msu_traj: can't fix blobs both cameras" 110 "sc_msu_traj: recv'd NULL parameter" 111 "sc_msu_traj: garbled Traj_select_method = %d", 120 "sc_raw_traj: recv'd NULL parameter x,y,I,c,t, or ntraj" 121 "sc_raw_traj: garbled Traj_select_method = %d" 123 "sc_raw_traj: more than 1 hop" 200 "sc_cris_coords: recv'd NULL param" 201 "sc_cris_coords: bad Traj_select_method = %d", 202 "sc_cris_coords: nblobs (%d) > max (%d)", 210 "sc_msu_coords: nblobs (%d) and nblobsb (%d) > max (%d)", 211 "sc_msu_coords: nblobsb (%d) > max (%d)", 212 "sc_msu_coords: nblobs (%d) > max (%d)", 250 "fiber_fit: not enough blobs" 251 "fiber_fit: too many blobs" 252 "fiber_fit: too many blobs" 253 "fiber_fit: not all layers (2 or 3)" 253 "fiber_fit: not all layers" 254 "fiber_fit: not all layers (1)" 255 "fiber_fit: no X fit" 256 "fiber_fit: no Y fit" 257 "fiber_fit: bad fiber_to_real 1" 258 "fiber_fit: bad fiber_to_real 2" 259 "fiber_fit: bad fiber_to_real 3" 260 "fiber_fit: bad real x offset" 261 "fiber_fit: bad real y offset" 262 "fiber_fit: fiber bundle hit" 270 "brightest: not enough blobs" 271 "brightest: not all layers (2 or 3)" 272 "brightest: bad fiber_to_real 1" 273 "brightest: bad fiber_to_real 2" 274 "brightest: bad fiber_to_real 3" 275 "brightest: bad real x offset" 276 "brightest: bad real y offset" 277 "brightest: fiber bundle hit" 278 "brightest: not all layers (1)" 280 "sc_short_traj: not enough layers" 283 "sc_short_traj: bad fiber_to_real 2" 284 "sc_short_traj: bad fiber_to_real 3" 310 "sc_trajectory: X chisq = %.2f (> 1000.0)" 311 "sc_trajectory: Y chisq = %.2f (> 1000.0)" 420 "multitraj: recv'd NULL ptr" 421 "multitraj: not enough blobs (%d)" 422 "multitraj: too many blobs" 423 "multitraj: too many blobs" 424 "multitraj: not all layers (2 or 3)" 425 "multitraj: not all layers (1)" 426 "multitraj: fiber bundle hit" 427 "multitraj: no X fit" 429 "multitraj: no Y fit" 430 "multitraj: no fit" 431 "multitraj: bad evttype parameter" 432 "multitraj: can't calloc xtemp, ytemp, or Itemp" 500 "diag_cvt: null parameters" 501 "diag_cvt: bad normal event" 503 "diag_cvt: soft data continued into more than %d structs", 504 "diag_cvt: no end header" 510 "next_cris_evt: called with NULL parameters\n" 511 "next_cris_evt: sc_L1_set_day() not run yet\n" 512 "next_cris_evt: last evt\n" 513 "next_cris_evt: last evt (B)\n" 520 "next_diag: called with NULL parameters\n" 521 "next_diag: sc_L1_set_day() not run yet\n" 522 "next_diag: last evt\n" 530 "next_hsk_raw: called with NULL parameters\n" 531 "next_hsk_raw: sc_L1_set_day() not run yet\n" 540 "next_cmd: called with NULL parameters\n" 541 "next_cmd: sc_L1_set_day() not run yet\n" 550 "next_hipri: called with NULL parameters\n" 551 "next_hipri: sc_L1_set_day() not run yet\n" 560 "next_lopri_raw: called with NULL parameters\n" 561 "next_lopri_raw: sc_L1_set_day() not run yet\n" 570 "next_hsk: called with NULL parameters\n" 571 "next_hsk: sc_L1_set_day() not run yet\n" 580 "next_lopri: called with NULL parameters\n" 581 "next_lopri: sc_L1_set_day() not run yet\n" 1000 "sc_telescope_hit: negative radius (%d)" 1001 "sc_telescope_hit: bad stack value (%d)" 1002 "sc_telescope_hit: no hit"
Date: Tue, 27 Apr 1999 12:43:08 -0700 From: Robert.G.Radocinski@jpl.nasa.gov (Robert Radocinski) To: lijowski@cosray2.wustl.edu Subject: Re: CRIS Low priority rates Michal, The following is based on my understanding of how the CRIS firmware works. The authority on the CRIS on-board firmware is Rick Cook. However, your question deals mostly with level-1 processing and my simplified explanation of the on-board processing are strictly to clarify the difference about which you inquired. As you are aware, CRIS has an on-board buffering system for events and also maintains on-board scalars for the number of events which belong to each of the 64 on-board event buffers. When a particle causes an event to occur, CRIS usually time (256 second resolution) tags it and puts it in the raw event buffer. In the unusual case that the raw event buffer is full, CRIS will increment the NREBFUL flag and discard the event. There is another on-board firmware process that is continually examaining the raw event buffer for new events. If this second process locates an event in the raw event buffer, it will determine the event buffer number for that event and increment the on-board scalar for that buffer. In addition, if there is room in the proper section of the compressed event buffer it will put the event into the compressed event buffer; if there is no room, it will increment the NCEBFUL flag and discard the event. Once an event makes it as far as the compressed event buffer, it will make it into the telemetry. When the level-0 data reaches the ACE Science center, the level-1 processing generates the L1CrisLowPriorityRate data structures. Each data structure covers one instrument cycle (256 minor frames) and has the two 64-element arrays EventBuffer and NumberEvents. The values stored in the EventBuffer array are nothing more than the on-board scalars for each of the 64 event buffers. The values stored in the NumberEvents array are the number of compressed events for each buffer in the level-0 data that have the time tag associated with the instrument cycle. The EventBuffer array and the NumberEvents array can differ for the following reasons: 1. The on-board firmware finds an event in the raw event buffer that belongs to buffer[i] and it increments the on-board scalar for that event. If it cannot store the event in the compressed event buffer, it discards it. In this case, the event never makes it into the telemetry and therefore the level-1 processing cannot add it to the value in NumberEvents[i]. 2. On-board, there is samll time window (fractions of a second), which happens on instrument cycle (256 minor frames) boundaries, in which an event is time-tagged in one instrument cycle, but the on-board scalar is incremented in the next instrument cycle. This occurs because the event is time tagged when it is put into the raw event buffer, and the on-board event buffer scalar is incremented when the event is taken out of the raw event buffer. 3. In some cases, when a particle event occurs during a stim event, the on-board firmware produces an un-interpretable event. Since the level-1 software cannot interprect this event, it will not be able to increment the proper value of NumberEvents. 4. Lost telemetry will also make the two arrays differ. When a single minor frame is dropped, usually 1-2 compressed events are lost. Therefore, the NumberEvents array will be short 1-2 events. In the level-1.1 software package, I generate the L1_1CrisLowPriorityRate data structure from the L1CrisLowPriorityRate data structure. The values stored in the arrays EventBufferRate and DataBufferRate are generated as follows: <efficiency> = NEVPROC / (NEVPROC + NREBFUL) <live time> = <H live time> for H buffers, = <He live time> for He buffers, = <HiZ live time> for HiZ buffers. For each buffer i, EventBufferRate[i] = EventBuffer[i] / (<efficiency> * <live time>) DataBufferRate[i] = NumberEvents[i] / (<efficiency> * <live time>) where EventBuffer[i] and NumberEvents[i] come from the L1CrisLowPriorityRate data structure. I hope this explanation helps. Thanks, Robert Radocinski P.S. The terms NREBFUL, NCEBFUL, and NEVPROC were defined in the Rick Cook presentation at the Summer 1997 CRIS/SIS team meeting at Caltech.