cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
flux.cpp
Go to the documentation of this file.
1 /* This file is part of Cloudy and is copyright (C)1978-2022 by Gary J. Ferland and
2  * others. For conditions of distribution and use see copyright notice in license.txt */
3 
4 #include "cddefines.h"
5 #include "flux.h"
6 
7 
8 Flux::fu_bits Flux::p_InternalFluxUnitNoCheck(const string& unit, size_t& len) const
9 {
10  DEBUG_ENTRY( "Flux::p_InternalFluxUnitNoCheck()" );
11 
12  len = 0;
13  fu_bits bits;
14  if( unit == "Jy" )
15  {
16  len = 2;
17  bits.set(FU_JY);
18  }
19  else if( unit == "mJy" )
20  {
21  len = 3;
22  bits.set(FU_MJY);
23  }
24  else if( unit == "MJy/sr" )
25  {
26  len = 6;
27  bits.set(FU_MJY_SR);
28  }
29  else
30  {
31  if( unit.substr(len,5) == "erg/s" )
32  {
33  len += 5;
34  bits.set(FU_ERG_S);
35  }
36  else if( unit.substr(len,1) == "W" )
37  {
38  len += 1;
39  bits.set(FU_W);
40  }
41  if( unit.substr(len,4) == "/cm2" )
42  {
43  len += 4;
44  bits.set(FU_CM2);
45  }
46  else if( unit.substr(len,3) == "/m2" )
47  {
48  len += 3;
49  bits.set(FU_M2);
50  }
51  if( unit.substr(len,2) == "/A" )
52  {
53  len += 2;
54  bits.set(FU_A);
55  }
56  if( unit.substr(len,3) == "/nm" )
57  {
58  len += 3;
59  bits.set(FU_NM);
60  }
61  else if( unit.substr(len,7) == "/micron" )
62  {
63  len += 7;
64  bits.set(FU_MU);
65  }
66  else if( unit.substr(len,3) == "/Hz" )
67  {
68  len += 3;
69  bits.set(FU_HZ);
70  }
71  if( unit.substr(len,3) == "/sr" )
72  {
73  len += 3;
74  bits.set(FU_SR);
75  }
76  else if( unit.substr(len,8) == "/arcsec2" )
77  {
78  len += 8;
79  bits.set(FU_SQAS);
80  }
81  }
82  return bits;
83 }
84 
85 Flux::fu_bits Flux::p_InternalFluxUnit(const string& unit) const
86 {
87  DEBUG_ENTRY( "Flux::p_InternalFluxUnit()" );
88 
89  size_t p;
90  fu_bits bits = p_InternalFluxUnitNoCheck( unit, p );
91  if( p != unit.length() || !p_ValidFluxUnit(bits) )
92  {
93  fprintf( ioQQQ, " insane units in Flux::InternalFluxUnit: \"%s\"\n", unit.c_str() );
95  }
96  return bits;
97 }
98 
100 {
101  DEBUG_ENTRY( "Flux::p_ValidFluxUnit()" );
102 
103  if( bits.none() )
104  return false;
105 
106  if( bits[FU_JY] )
107  bits.reset(FU_JY);
108  else if( bits[FU_MJY] )
109  bits.reset(FU_MJY);
110  else if( bits[FU_MJY_SR] )
111  bits.reset(FU_MJY_SR);
112  else
113  {
114  if( bits[FU_ERG_S] )
115  bits.reset(FU_ERG_S);
116  else if( bits[FU_W] )
117  bits.reset(FU_W);
118  else
119  return false;
120  if( bits[FU_CM2] )
121  bits.reset(FU_CM2);
122  else if( bits[FU_M2] )
123  bits.reset(FU_M2);
124  else
125  return false;
126  if( bits[FU_A] )
127  bits.reset(FU_A);
128  else if( bits[FU_NM] )
129  bits.reset(FU_NM);
130  else if( bits[FU_MU] )
131  bits.reset(FU_MU);
132  else if( bits[FU_HZ] )
133  bits.reset(FU_HZ);
134  if( bits[FU_SR] )
135  bits.reset(FU_SR);
136  else if( bits[FU_SQAS] )
137  bits.reset(FU_SQAS);
138  }
139  return bits.none();
140 }
141 
142 double Flux::p_get(fu_bits bits) const
143 {
144  DEBUG_ENTRY( "Flux::p_get()" );
145 
146  /* internal units are erg/cm^2/s (into 4pi sr in the case of an intensity) */
147  double val = p_flux;
148  if( bits[FU_W] )
149  val /= 1.e7;
150  if( bits[FU_M2] )
151  val *= 1.e4;
152  if( bits[FU_A] )
153  val /= p_energy.Angstrom();
154  if( bits[FU_NM] )
155  val /= p_energy.nm();
156  if( bits[FU_MU] )
157  val /= p_energy.micron();
158  if( bits[FU_HZ] )
159  val /= p_energy.Hz();
160  if( bits[FU_SR] )
161  val /= PI4;
162  if( bits[FU_SQAS] )
163  val /= SQAS_SKY;
164  if( bits[FU_JY] )
165  val *= 1.e23/p_energy.Hz();
166  if( bits[FU_MJY] )
167  val *= 1.e26/p_energy.Hz();
168  if( bits[FU_MJY_SR] )
169  val *= 1.e17/(PI4*p_energy.Hz());
170  return val;
171 }
172 
173 void Flux::p_set(Energy e, double value, fu_bits bits)
174 {
175  DEBUG_ENTRY( "Flux::p_set()" );
176 
177  /* internal units are erg/cm^2/s (into 4pi sr in the case of an intensity) */
178  p_energy = e;
179  p_flux = value;
180  p_userunits = bits;
181  if( bits[FU_W] )
182  p_flux *= 1.e7;
183  if( bits[FU_M2] )
184  p_flux /= 1.e4;
185  if( bits[FU_A] )
186  p_flux *= p_energy.Angstrom();
187  if( bits[FU_NM] )
188  p_flux *= p_energy.nm();
189  if( bits[FU_MU] )
190  p_flux *= p_energy.micron();
191  if( bits[FU_HZ] )
192  p_flux *= p_energy.Hz();
193  if( bits[FU_SR] )
194  p_flux *= PI4;
195  if( bits[FU_SQAS] )
196  p_flux *= SQAS_SKY;
197  if( bits[FU_JY] )
198  p_flux /= 1.e23/p_energy.Hz();
199  if( bits[FU_MJY] )
200  p_flux /= 1.e26/p_energy.Hz();
201  if( bits[FU_MJY_SR] )
202  p_flux /= 1.e17/(PI4*p_energy.Hz());
203 }
204 
205 string StandardFluxUnit(const char* chCard)
206 {
207  DEBUG_ENTRY( "StandardFluxUnit()" );
208 
209  if( nMatch(" JY ",chCard) || nMatch("JANS",chCard) )
210  return "Jy";
211  else if( nMatch("MJY/SR",chCard) )
212  return "MJy/sr";
213  else if( nMatch(" MJY",chCard) )
214  return "mJy";
215 
216  string str;
217  if( nMatch("ERG/S/",chCard) )
218  str = "erg/s";
219  else if( nMatch("W/SQ",chCard) )
220  str = "W";
221  else
222  return "";
223 
224  if( nMatch("/SQCM",chCard) )
225  str += "/cm2";
226  else if( nMatch("/SQM",chCard) )
227  str += "/m2";
228  else
229  return "";
230 
231  if( nMatch("/A ",chCard) || nMatch("/A/",chCard) )
232  str += "/A";
233  else if( nMatch("/NM",chCard) )
234  str += "/nm";
235  else if( nMatch("/MICR",chCard) )
236  str += "/micron";
237  else if( nMatch("/HZ",chCard) )
238  str += "/Hz";
239 
240  if( nMatch("/SR",chCard) )
241  str += "/sr";
242  else if( nMatch("/SQAS",chCard) )
243  str += "/arcsec2";
244 
245  if( !ValidFluxUnit(str) )
246  {
247  fprintf( ioQQQ, " No valid flux unit was recognized on this line:\n %s\n\n", chCard );
248  fprintf( ioQQQ, " See Hazy for details.\n" );
250  }
251 
252  return str;
253 }
254 
255 string Flux::uu() const
256 {
257  DEBUG_ENTRY( "Flux::uu()" );
258 
260 
261  if( p_userunits[FU_JY] )
262  return "Jy";
263  else if( p_userunits[FU_MJY] )
264  return "mJy";
265  else if( p_userunits[FU_MJY_SR] )
266  return "MJy/sr";
267 
268  string str;
269  if( p_userunits[FU_ERG_S] )
270  str = "erg/s";
271  else if( p_userunits[FU_W] )
272  str = "W";
273 
274  if( p_userunits[FU_CM2] )
275  str += "/cm2";
276  else if( p_userunits[FU_M2] )
277  str += "/m2";
278 
279  if( p_userunits[FU_A] )
280  str += "/A";
281  else if( p_userunits[FU_NM] )
282  str += "/nm";
283  else if( p_userunits[FU_MU] )
284  str += "/micron";
285  else if( p_userunits[FU_HZ] )
286  str += "/Hz";
287 
288  if( p_userunits[FU_SR] )
289  str += "/sr";
290  else if( p_userunits[FU_SQAS] )
291  str += "/arcsec2";
292 
293  return str;
294 }
double Hz() const
Definition: energy.h:61
double Angstrom() const
Definition: energy.h:77
bool p_ValidFluxUnit(fu_bits) const
Definition: flux.cpp:99
fu_bits p_userunits
Definition: flux.h:19
bool ValidFluxUnit(const string &unit)
Definition: flux.h:71
Energy p_energy
Definition: flux.h:17
fu_bits p_InternalFluxUnitNoCheck(const string &unit, size_t &len) const
Definition: flux.cpp:8
long nMatch(const char *chKey, const char *chCard)
Definition: service.cpp:525
fu_bits p_InternalFluxUnit(const string &unit) const
Definition: flux.cpp:85
FILE * ioQQQ
Definition: cddefines.cpp:7
double p_get(fu_bits bits) const
Definition: flux.cpp:142
string uu() const
Definition: flux.cpp:255
#define EXIT_FAILURE
Definition: cddefines.h:168
#define cdEXIT(FAIL)
Definition: cddefines.h:482
void p_set(Energy e, double value, fu_bits bits)
Definition: flux.cpp:173
bitset< FU_TOP > fu_bits
Definition: flux.h:15
double nm() const
Definition: energy.h:81
string StandardFluxUnit(const char *chCard)
Definition: flux.cpp:205
#define ASSERT(exp)
Definition: cddefines.h:613
double p_flux
Definition: flux.h:18
Definition: energy.h:9
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
double micron() const
Definition: energy.h:85