source: trunk/MagicSoft/Mars/mbase/MAstro.cc@ 2970

Last change on this file since 2970 was 2891, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 6.4 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 11/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MAstro
28// ------
29//
30////////////////////////////////////////////////////////////////////////////
31#include "MAstro.h"
32
33ClassImp(MAstro);
34
35Double_t MAstro::Trunc(Double_t val)
36{
37 /* dint(A) - truncate to nearest whole number towards zero (double) */
38 return val<0 ? TMath::Ceil(val) : TMath::Floor(val);
39}
40
41Double_t MAstro::Round(Double_t val)
42{
43 /* dnint(A) - round to nearest whole number (double) */
44 return val<0 ? TMath::Ceil(val-0.5) : TMath::Floor(val+0.5);
45}
46
47Double_t MAstro::Hms2Sec(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
48{
49 const Double_t rc = TMath::Sign((60.0 * (60.0 * (Double_t)TMath::Abs(deg) + (Double_t)min) + sec), (Double_t)deg);
50 return sgn=='-' ? -rc : rc;
51}
52
53Double_t MAstro::Dms2Rad(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
54{
55 /* pi/(180*3600): arcseconds to radians */
56#define DAS2R 4.8481368110953599358991410235794797595635330237270e-6
57 return Hms2Sec(deg, min, sec, sgn)*DAS2R;
58}
59
60Double_t MAstro::Hms2Rad(Int_t hor, UInt_t min, Double_t sec, Char_t sgn)
61{
62 /* pi/(12*3600): seconds of time to radians */
63#define DS2R 7.2722052166430399038487115353692196393452995355905e-5
64 return Hms2Sec(hor, min, sec, sgn)*DS2R;
65}
66
67Double_t MAstro::Dms2Deg(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
68{
69 return Hms2Sec(deg, min, sec, sgn)/3600.;
70}
71
72Double_t MAstro::Hms2Deg(Int_t hor, UInt_t min, Double_t sec, Char_t sgn)
73{
74 return Hms2Sec(hor, min, sec, sgn)/240.;
75}
76
77Double_t MAstro::Dms2Hor(Int_t deg, UInt_t min, Double_t sec, Char_t sgn)
78{
79 return Hms2Sec(deg, min, sec, sgn)/15.;
80}
81
82Double_t MAstro::Hms2Hor(Int_t hor, UInt_t min, Double_t sec, Char_t sgn)
83{
84 return Hms2Sec(hor, min, sec, sgn)/3600.;
85}
86
87void MAstro::Day2Hms(Double_t day, Char_t &sgn, UShort_t &hor, UShort_t &min, UShort_t &sec)
88{
89 /* Handle sign */
90 sgn = day<0?'-':'+';
91
92 /* Round interval and express in smallest units required */
93 Double_t a = Round(86400. * TMath::Abs(day)); // Days to seconds
94
95 /* Separate into fields */
96 const Double_t ah = Trunc(a/3600.);
97 a -= ah * 3600.;
98 const Double_t am = Trunc(a/60.);
99 a -= am * 60.;
100 const Double_t as = Trunc(a);
101
102 /* Return results */
103 hor = (UShort_t)ah;
104 min = (UShort_t)am;
105 sec = (UShort_t)as;
106}
107
108void MAstro::Rad2Hms(Double_t rad, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
109{
110 Day2Hms(rad/(TMath::Pi()*2), sgn, deg, min, sec);
111}
112
113void MAstro::Rad2Dms(Double_t rad, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
114{
115 Rad2Hms(rad*15, sgn, deg, min, sec);
116}
117
118void MAstro::Deg2Dms(Double_t d, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
119{
120 Day2Hms(d/24, sgn, deg, min, sec);
121}
122
123void MAstro::Deg2Hms(Double_t d, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
124{
125 Rad2Hms(d/360, sgn, deg, min, sec);
126}
127
128void MAstro::Hor2Dms(Double_t h, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
129{
130 Day2Hms(h*15/24, sgn, deg, min, sec);
131}
132
133void MAstro::Hor2Hms(Double_t h, Char_t &sgn, UShort_t &deg, UShort_t &min, UShort_t &sec)
134{
135 Day2Hms(h/24, sgn, deg, min, sec);
136}
137
138void MAstro::Day2Hm(Double_t day, Char_t &sgn, UShort_t &hor, Double_t &min)
139{
140 /* Handle sign */
141 sgn = day<0?'-':'+';
142
143 /* Round interval and express in smallest units required */
144 Double_t a = Round(86400. * TMath::Abs(day)); // Days to seconds
145
146 /* Separate into fields */
147 const Double_t ah = Trunc(a/3600.);
148 a -= ah * 3600.;
149
150 /* Return results */
151 hor = (UShort_t)ah;
152 min = a/60.;
153}
154
155void MAstro::Rad2Hm(Double_t rad, Char_t &sgn, UShort_t &deg, Double_t &min)
156{
157 Day2Hm(rad/(TMath::Pi()*2), sgn, deg, min);
158}
159
160void MAstro::Rad2Dm(Double_t rad, Char_t &sgn, UShort_t &deg, Double_t &min)
161{
162 Rad2Hm(rad*15, sgn, deg, min);
163}
164
165void MAstro::Deg2Dm(Double_t d, Char_t &sgn, UShort_t &deg, Double_t &min)
166{
167 Day2Hm(d/24, sgn, deg, min);
168}
169
170void MAstro::Deg2Hm(Double_t d, Char_t &sgn, UShort_t &deg, Double_t &min)
171{
172 Rad2Hm(d/360, sgn, deg, min);
173}
174
175void MAstro::Hor2Dm(Double_t h, Char_t &sgn, UShort_t &deg, Double_t &min)
176{
177 Day2Hm(h*15/24, sgn, deg, min);
178}
179
180void MAstro::Hor2Hm(Double_t h, Char_t &sgn, UShort_t &deg, Double_t &min)
181{
182 Day2Hm(h/24, sgn, deg, min);
183}
184
185Bool_t MAstro::String2Angle(TString &str, Double_t &ret)
186{
187 Char_t sgn;
188 Int_t d, len;
189 UInt_t m;
190 Float_t s;
191
192 // Skip whitespaces before %c and after %f
193 int n=sscanf(str.Data(), " %c %d %d %f %n", &sgn, &d, &m, &s, &len);
194
195 if (n!=4 || (sgn!='+' && sgn!='-'))
196 return kFALSE;
197
198 str.Remove(0, len);
199
200 ret = Dms2Deg(d, m, s, sgn);
201 return kTRUE;
202}
203
204void MAstro::Mjd2Ymd(UInt_t mjd, UShort_t &y, Byte_t &m, Byte_t &d)
205{
206 // Express day in Gregorian calendar
207 const ULong_t jd = mjd + 2400001;
208 const ULong_t n4 = 4*(jd+((6*((4*jd-17918)/146097))/4+1)/2-37);
209 const ULong_t nd10 = 10*(((n4-237)%1461)/4)+5;
210
211 y = n4/1461L-4712;
212 m = ((nd10/306+2)%12)+1;
213 d = (nd10%306)/10+1;
214}
215
216Int_t MAstro::Ymd2Mjd(UShort_t y, Byte_t m, Byte_t d)
217{
218 // Month lengths in days
219 static int months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
220
221 // Validate month
222 if (m<1 || m>12)
223 return -1;
224
225 // Allow for leap year
226 months[1] = (y%4==0 && (y%100!=0 || y%400==0)) ? 29 : 28;
227
228 // Validate day
229 if (d<1 || d>months[m-1])
230 return -1;
231
232 // Precalculate some values
233 const Byte_t lm = 12-m;
234 const ULong_t lm10 = 4712 + y - lm/10;
235
236 // Perform the conversion
237 return 1461L*lm10/4 + (306*((m+9)%12)+5)/10 - (3*((lm10+188)/100))/4 + d - 2399904;
238}
Note: See TracBrowser for help on using the repository browser.