source: trunk/ToBeReviewed/PLOTS/LABEL/label_date.pro.new @ 39

Last change on this file since 39 was 39, checked in by pinsard, 18 years ago

upgrade of PLOTS/LABEL according to cerbere.lodyc.jussieu.fr: /usr/home/smasson/SAXO_RD/ : files

  • Property svn:executable set to *
File size: 10.5 KB
Line 
1; $Id: label_date.pro,v 1.10 2001/01/15 22:28:06 scottm Exp $
2;
3; Copyright (c) 1993-2001, Research Systems, Inc.  All rights reserved.
4;       Unauthorized reproduction prohibited.
5
6;+
7; NAME:
8;       LABEL_DATE
9;
10; PURPOSE:
11;       This function labels axes with dates and times.
12;
13; CATEGORY:
14;       Plotting.
15;
16; CALLING SEQUENCE:
17;       To set up:
18;               dummy = LABEL_DATE(DATE_FORMAT='string')
19;       To use:
20;               PLOT, x, y, XTICKFORMAT='LABEL_DATE'
21;
22; INPUTS:
23;       No explicit user defined inputs. When called from the plotting
24;       routines, the input parameters are (Axis, Index, Value [, Level])
25;
26; KEYWORD PARAMETERS:
27;       DATE_FORMAT: a format string which may contain the following:
28;                      %M for month
29;                      %N for month (2 digit abbr)
30;                      %D for day of month,
31;                      %Y for 4 digit year.
32;                      %Z for last two digits of year.
33;              %W for day of week
34;            For time:
35;              %A for AM or PM
36;                      %H for Hours, 2 digits.
37;                      %I for mInutes, 2 digits.
38;                      %S for Seconds, 2 digits.
39;                 %0--%9 following %S, indicates digits after decimal point.
40;                      %% is %.
41;
42;               If a time format string is specified, the time of day
43;               will be rounded to the nearest least significant time format
44;               specified.  E.g. if the format '%H:%I' is specified
45;               (hours:minutes) the time is rounded to the nearest minute.
46;
47;                    Other characters are passed directly thru.
48;                    For example, '%M %D, %Y' prints DEC 11, 1993
49;                      '%M %2Y' yields DEC 93
50;                      '%D-%M' yields 11-DEC
51;                      '%D/%N/%Y' yields 11/12/1993
52;                      '%M!C%Y' yields DEC on the top line, 1993 on
53;                      the bottom (!C is the new line graphic command).
54;
55;   AM_PM: The names for AM or PM. The default is ["am","pm"]
56;
57;   DAYS_OF_WEEK: The names of the days, a seven-element string array.
58;                 The default is [Sun, Mon, Tue, Wed, Thu, Fri, Sat].
59;
60;       MONTHS:  The names of the months, a twelve element string array.
61;                    The default is [Jan, Feb,..., Dec].
62;
63;   OFFSET: Set this keyword to a value representing the offset to be added
64;           to each tick value before conversion to a label. This keyword
65;           is usually used when your axis values are measured relative to
66;           a certain starting time. In this case, OFFSET should be set to
67;           the Julian date of the starting time.
68;
69;   ROUND_UP: Set this keyword to force times to be rounded up to the
70;           smallest time unit that is present in the DATE_FORMAT string.
71;           The default is for times to be truncated to the
72;           smallest time unit.
73;
74; OUTPUTS:
75;       The date string to be plotted.
76;
77; COMMON BLOCKS:
78;       LABEL_DATE_COM.
79;
80; RESTRICTIONS:
81;       Uses a common block, so only one date axis may be simultaneously active.
82;
83; PROCEDURE:
84;       Straightforward.
85;
86;       For an alternative way to label a plot axis with dates, refer to
87;       the C() format code accepted within format strings (applicable via
88;       the [XYZ]TICKFORMAT keywords).  This format code was
89;       introduced in IDL 5.2.
90;
91; EXAMPLE:
92;       For example, to plot from Jan 1, 1993, to July 12, 1994:
93;         Start_date = julday(1, 1, 1993)
94;         End_date = julday(7, 12, 1994)
95;         Dummy = LABEL_DATE(DATE_FORMAT='%N/%D')  ;Simple mm/dd
96;         x = findgen(end_date+1 - start_date) + start_date ;Time axis
97;         PLOT, x, sqrt(x), XTICKFORMAT = 'LABEL_DATE', XSTYLE=1
98;         (Plot with X axis style set to exact.)
99;
100; Example with times:
101;       For example, to plot from 3PM, Jan 1, 1993, to 5AM, Jan 3,
102;       1993:
103;       Start_date = Julday(1,1,1993)   ;Also starting offset
104;       Start_time = (3+12)/24.         ;Starting_time less offset
105;       End_time = (Julday(1,3,1993) - Start_date) + 5./24. ;Ending
106;               ;date/time - offset, note that the order of operations is
107;               ; important to avoid loss of precision.
108;       Dummy = LABEL_DATE(DATE_FORMAT='%D %M!C%H:%I', $
109;               offset=Start_date)       ;MMM NN <new line> HH:MM format
110;       x = findgen(20) * (End_time - Start_time) / 19 + start_time ;Time axis
111;       PLOT, x, sqrt(x), XTICKFORMAT = 'LABEL_DATE', XSTYLE=1
112;
113; MODIFICATION HISTORY:
114;       DMS, RSI.       April, 1993.    Written.
115;       DMS, RSI.       March, 1997.    Added Time format.
116;       DMS, RSI.       Jan, 1999.      Rounded least significant time unit
117;   CT, RSI.    May 2000. Completely rewrote to use calendar format codes.
118;                Added Level argument for new date/time TICKUNITS.
119;                Added AM_PM and DAYS_OF_WEEK keywords, '%A' and '%W' codes.
120;-
121
122
123;-------------------------------------------------- LABEL_DATE_CONVERT_FORMAT
124; Given a LABEL_DATE input string, convert codes to Calendar format codes.
125FUNCTION label_date_convert_format, format, cMonths, cAmpm, cDaysWeek
126
127        COMPILE_OPT idl2, hidden
128
129        ON_ERROR, 2
130
131        n = strlen(format)
132        newFormat = ''
133        for i=0L, n-1 do begin           ;Each format character...
134                add = strmid(format, i, 1)       ;The character.
135                if add eq '%' then begin
136                        i = i + 1  ; skip to next character
137                        c = STRUPCASE(strmid(format, i, 1))
138                        ; if format character, then convert to calendar format code
139                        case c of
140                                ; if user specified months, then width=zero to use "natural"
141                                ; month length, otherwise use the default month length (3)
142                'M': add = (N_ELEMENTS(cMonths) EQ 12) ? 'CMoA0' : 'CMoA'
143                'N': add = 'CMOI2.2'
144                'D': add = 'CDI2.2'
145                'Y': add = 'CYI4'
146                'Z': add = 'CYI2.2'
147                'H': add = 'CHI2.2'
148                'I': add = 'CMI2.2'
149                                'S': BEGIN
150                                        add = 'CSI2.2'  ; default format for seconds
151                                        ; check for additional %n code
152                                        IF (STRMID(format,i+1,1) EQ '%') THEN BEGIN
153                                                numberChar = STRMID(format,i+2,1)
154                                                number = STRPOS('0123456789',numberChar)
155                                                IF (number GE 0) THEN BEGIN
156                                                        i = i + 2  ; skip format characters
157                                                        width = STRTRIM(3+number,2) ;tens+ones+decimal
158                                                        add = 'CSF' + width + '.' + numberChar
159                                                        ; add TLn,CSI2.2 to include leading zero
160                                                        add = add + ',TL' + width + ',CSI2.2'
161                                                ENDIF
162                                        ENDIF
163                                        END
164                                'W' : add = (N_ELEMENTS(cDaysWeek) EQ 7) ? 'CDwA0' : 'CDwA'
165                                'A' : add = (N_ELEMENTS(cAmpm) EQ 2) ? 'CapA0' : 'CapA'
166                                '%' : add = '"%"'
167                                ELSE: add = '""'  ; if unknown, add null string
168                        endcase
169                endif else add = '"' + add + '"'   ; just output the character
170                newFormat = (newFormat EQ '') ? add : newFormat + ',' + add
171        endfor
172        IF (STRPOS(newFormat,'CapA') GE 0) THEN BEGIN
173                hourPos = STRPOS(newFormat,'CHI')
174                IF (hourPos GE 0) THEN newFormat = STRMID(newFormat,0,hourPos+1) + $
175                        'hI' + STRMID(newFormat,hourPos+6)
176        ENDIF
177        RETURN, '(C(' + newFormat + '))'
178END
179
180
181;----------------------------------------------------------------- LABEL_DATE
182FUNCTION LABEL_DATE, axisIn, indexIn, valueIn, levelIn, $
183        AM_PM = am_pm, $
184        DATE_FORMAT = dateFormat, $
185        DAYS_OF_WEEK = days_of_week, $
186        MONTHS = months, $
187        OFFSET = offs, $
188        ROUND_UP = round_up
189
190        COMPILE_OPT idl2
191        COMMON label_date_com, cFormatArray, cMonths, cOffset, $
192                cRoundup, cAmpm, cDaysWeek
193        ON_ERROR, 2
194
195
196        IF (N_PARAMS() LT 3) THEN $  ; use default for no inputs
197                IF NOT KEYWORD_SET(dateFormat) THEN dateFormat=''
198
199
200; process a new months vector?
201        ; if months is undefined, then make cMonths undefined
202        IF ARG_PRESENT(months) OR (N_ELEMENTS(months) GT 0) THEN BEGIN
203                cMonths = -1
204                dummy = TEMPORARY(cMonths)
205        ENDIF
206        ; if months has 12 elements, then copy it to cMonths
207        if (N_ELEMENTS(months) EQ 12) then cMonths = months
208
209
210; process a new days_of_week vector?
211        ; if days_of_week is undefined, then make cDaysWeek undefined
212        IF ARG_PRESENT(days_of_week) OR (N_ELEMENTS(days_of_week) GT 0) THEN BEGIN
213                cDaysWeek = -1
214                dummy = TEMPORARY(cDaysWeek)
215        ENDIF
216        ; if days_of_week has 2 elements, then copy it to cDaysWeek
217        if (N_ELEMENTS(days_of_week) EQ 7) then cDaysWeek = days_of_week
218
219
220; process a new AM_PM vector?
221        ; if AM_PM is undefined, then make cAmpm undefined
222        IF ARG_PRESENT(am_pm) OR (N_ELEMENTS(am_pm) GT 0) THEN BEGIN
223                cAmpm = -1
224                dummy = TEMPORARY(cAmpm)
225        ENDIF
226        ; if AM_PM has 2 elements, then copy it to cAmpm
227        if (N_ELEMENTS(am_pm) EQ 2) then cAmpm = am_pm
228
229
230; process a new cOffset?
231        IF ARG_PRESENT(offs) THEN cOffset = 0
232        IF (N_ELEMENTS(offs) GT 0) THEN cOffset = offs[0]
233        ; make sure we have an cOffset
234        IF (N_ELEMENTS(cOffset) EQ 0) THEN cOffset = 0d
235
236
237; process a new cRoundup?
238        IF (N_ELEMENTS(round_up) GT 0) THEN cRoundup = KEYWORD_SET(round_up)
239
240
241; process a new date_format string?
242        nNewFormat = N_ELEMENTS(dateFormat)
243        IF (nNewFormat GT 0) THEN BEGIN
244                cFormatArray = STRARR(nNewFormat)
245                FOR a=0L,nNewFormat-1 DO cFormatArray[a] = $
246                        LABEL_DATE_CONVERT_FORMAT(dateFormat[a],cMonths,cAmpm,cDaysWeek)
247        ENDIF
248        IF (N_ELEMENTS(cFormatArray) EQ 0) THEN cFormatArray = '(C())'
249
250
251        IF (N_PARAMS() LT 3) THEN RETURN, 0
252
253
254;------------------------------------------------------ Process an axis value
255        value1 = valueIn + cOffset   ; convert to Julian
256        date = LONG(value1)   ; Julian date
257        time = value1 - date  ; Julian time
258
259
260        IF (N_ELEMENTS(levelIn) LT 1) THEN levelIn = 0
261        nFormat = N_ELEMENTS(cFormatArray)
262        formatLevel = cFormatArray[levelIn MOD nFormat]    ; repeat cyclically
263
264
265; Round subseconds to the desired precision
266        secPos = STRPOS(formatLevel, 'CSF')
267        ; for fractional seconds, need to manually round because the "float"
268        ; format codes do rounding rather than truncation.
269        IF (secPos GE 0) THEN BEGIN
270                decimalPoint = STRPOS(formatLevel,'.',secPos)
271                sigdigits = 10d^STRMID(formatLevel, decimalPoint + 1, 1)
272                time = (ROUND(time*86400d*sigdigits,/L64)+0.1d)/(86400d*sigdigits)
273                value1 = date + time
274        ENDIF
275
276
277; Round fractional time to the least significant format specified.
278        IF KEYWORD_SET(cRoundup) THEN BEGIN
279                ; Because the "integer" format codes automatically truncate,
280                ; just add 1/2 of smallest desired time increment to do rounding.
281                ; The CASE selections must be in order from smallest units to largest,
282                ; so that rounding occurs to the least-significant unit.
283                CASE 1 OF
284                        (secPos GE 0):  ; should have already done rounding
285                        (STRPOS(formatLevel, 'CSI') GE 0): time = time + 0.5d/86400d
286                        (STRPOS(formatLevel, 'CMI') GE 0): time = time + 0.5d/1440d
287                        (STRPOS(formatLevel, 'CHI') GE 0): time = time + 0.5/24d
288                        ELSE:
289                ENDCASE
290                value1 = date + time
291        ENDIF
292
293
294; check for negative (B.C.E.) years
295        jan1_1ad = 1721424L   ; Julian date for 1 Jan, 1 C.E.
296        IF (date LT jan1_1ad) THEN BEGIN
297                yearPos = STRPOS(formatLevel,'CYI')
298                ; if there is a year code, then increase width by one for minus sign
299                IF (yearPos GE 0) THEN BEGIN
300                        yearPos = yearPos + 3
301                        width = STRTRIM(FIX(STRMID(formatLevel,yearPos,1))+1,2)
302                        formatLevel = STRMID(formatLevel, 0, yearPos) + $
303                                width + STRMID(formatLevel, yearPos+1)
304                ENDIF
305        ENDIF
306
307        RETURN, STRING(value1,FORMAT=formatLevel, $
308                MONTHS=cMonths,AM_PM=cAmpm,DAYS_OF_WEEK=cDaysWeek)
309END
Note: See TracBrowser for help on using the repository browser.