00001 
00002 
00003 
00004 #include "cddefines.h"
00005 #include "physconst.h"
00006 #include "energy.h"
00007 #include "flux.h"
00008 
00009 
00010 Flux::fu_bits Flux::p_InternalFluxUnitNoCheck(const string& unit, size_t& len) const
00011 {
00012         DEBUG_ENTRY( "Flux::p_InternalFluxUnitNoCheck()" );
00013 
00014         len = 0;
00015         fu_bits bits;
00016         if( unit == "Jy" )
00017         {
00018                 len = 2;
00019                 bits.set(FU_JY);
00020         }
00021         else if( unit == "mJy" )
00022         {
00023                 len = 3;
00024                 bits.set(FU_MJY);
00025         }
00026         else if( unit == "MJy/sr" )
00027         {
00028                 len = 6;
00029                 bits.set(FU_MJY_SR);
00030         }
00031         else
00032         {
00033                 if( unit.substr(len,5) == "erg/s" )
00034                 {
00035                         len += 5;
00036                         bits.set(FU_ERG_S);
00037                 }
00038                 else if( unit.substr(len,1) == "W" )
00039                 {
00040                         len += 1;
00041                         bits.set(FU_W);
00042                 }
00043                 if( unit.substr(len,4) == "/cm2" )
00044                 {
00045                         len += 4;
00046                         bits.set(FU_CM2);
00047                 }
00048                 else if( unit.substr(len,3) == "/m2" )
00049                 {
00050                         len += 3;
00051                         bits.set(FU_M2);
00052                 }
00053                 if( unit.substr(len,2) == "/A" )
00054                 {
00055                         len += 2;
00056                         bits.set(FU_A);
00057                 }
00058                 if( unit.substr(len,3) == "/nm" )
00059                 {
00060                         len += 3;
00061                         bits.set(FU_NM);
00062                 }
00063                 else if( unit.substr(len,7) == "/micron" )
00064                 {
00065                         len += 7;
00066                         bits.set(FU_MU);
00067                 }
00068                 else if( unit.substr(len,3) == "/Hz" )
00069                 {
00070                         len += 3;
00071                         bits.set(FU_HZ);
00072                 }
00073                 if( unit.substr(len,3) == "/sr" )
00074                 {
00075                         len += 3;
00076                         bits.set(FU_SR);
00077                 }
00078                 else if( unit.substr(len,8) == "/arcsec2" )
00079                 {
00080                         len += 8;
00081                         bits.set(FU_SQAS);
00082                 }
00083         }
00084         return bits;
00085 }
00086 
00087 Flux::fu_bits Flux::p_InternalFluxUnit(const string& unit) const
00088 {
00089         DEBUG_ENTRY( "Flux::p_InternalFluxUnit()" );
00090 
00091         size_t p;
00092         fu_bits bits = p_InternalFluxUnitNoCheck( unit, p );
00093         if( p != unit.length() || !p_ValidFluxUnit(bits) )
00094         {
00095                 fprintf( ioQQQ, " insane units in Flux::InternalFluxUnit: \"%s\"\n", unit.c_str() );
00096                 cdEXIT(EXIT_FAILURE);
00097         }       
00098         return bits;
00099 }
00100 
00101 bool Flux::p_ValidFluxUnit(fu_bits bits) const
00102 {
00103         DEBUG_ENTRY( "Flux::p_ValidFluxUnit()" );
00104 
00105         if( bits.none() )
00106                 return false;
00107 
00108         if( bits[FU_JY] )
00109                 bits.reset(FU_JY);
00110         else if( bits[FU_MJY] )
00111                 bits.reset(FU_MJY);
00112         else if( bits[FU_MJY_SR] )
00113                 bits.reset(FU_MJY_SR);
00114         else
00115         {
00116                 if( bits[FU_ERG_S] )
00117                         bits.reset(FU_ERG_S);
00118                 else if( bits[FU_W] )
00119                         bits.reset(FU_W);
00120                 else
00121                         return false;
00122                 if( bits[FU_CM2] )
00123                         bits.reset(FU_CM2);
00124                 else if( bits[FU_M2] )
00125                         bits.reset(FU_M2);
00126                 else
00127                         return false;
00128                 if( bits[FU_A] )
00129                         bits.reset(FU_A);
00130                 else if( bits[FU_NM] )
00131                         bits.reset(FU_NM);
00132                 else if( bits[FU_MU] )
00133                         bits.reset(FU_MU);
00134                 else if( bits[FU_HZ] )
00135                         bits.reset(FU_HZ);
00136                 if( bits[FU_SR] )
00137                         bits.reset(FU_SR);
00138                 else if( bits[FU_SQAS] )
00139                         bits.reset(FU_SQAS);
00140         }
00141         return bits.none();
00142 }
00143 
00144 double Flux::p_get(fu_bits bits) const
00145 {
00146         DEBUG_ENTRY( "Flux::p_get()" );
00147 
00148         
00149         double val = p_flux;
00150         if( bits[FU_W] )
00151                 val /= 1.e7;
00152         if( bits[FU_M2] )
00153                 val *= 1.e4;
00154         if( bits[FU_A] )
00155                 val /= p_energy.Angstrom();
00156         if( bits[FU_NM] )
00157                 val /= p_energy.nm();
00158         if( bits[FU_MU] )
00159                 val /= p_energy.micron();
00160         if( bits[FU_HZ] )
00161                 val /= p_energy.Hz();
00162         if( bits[FU_SR] )
00163                 val /= PI4;
00164         if( bits[FU_SQAS] )
00165                 val /= SQAS_SKY;
00166         if( bits[FU_JY] )
00167                 val *= 1.e23/p_energy.Hz();
00168         if( bits[FU_MJY] )
00169                 val *= 1.e26/p_energy.Hz();
00170         if( bits[FU_MJY_SR] )
00171                 val *= 1.e17/(PI4*p_energy.Hz());
00172         return val;
00173 }
00174 
00175 void Flux::p_set(Energy e, double value, fu_bits bits)
00176 {
00177         DEBUG_ENTRY( "Flux::p_set()" );
00178 
00179         
00180         p_energy = e;
00181         p_flux = value;
00182         p_userunits = bits;
00183         if( bits[FU_W] )
00184                 p_flux *= 1.e7;
00185         if( bits[FU_M2] )
00186                 p_flux /= 1.e4;
00187         if( bits[FU_A] )
00188                 p_flux *= p_energy.Angstrom();
00189         if( bits[FU_NM] )
00190                 p_flux *= p_energy.nm();
00191         if( bits[FU_MU] )
00192                 p_flux *= p_energy.micron();
00193         if( bits[FU_HZ] )
00194                 p_flux *= p_energy.Hz();
00195         if( bits[FU_SR] )
00196                 p_flux *= PI4;
00197         if( bits[FU_SQAS] )
00198                 p_flux *= SQAS_SKY;
00199         if( bits[FU_JY] )
00200                 p_flux /= 1.e23/p_energy.Hz();
00201         if( bits[FU_MJY] )
00202                 p_flux /= 1.e26/p_energy.Hz();
00203         if( bits[FU_MJY_SR] )
00204                 p_flux /= 1.e17/(PI4*p_energy.Hz());
00205 }
00206 
00207 string StandardFluxUnit(const char* chCard)
00208 {
00209         DEBUG_ENTRY( "StandardFluxUnit()" );
00210 
00211         if( nMatch(" JY ",chCard) || nMatch("JANS",chCard) )
00212                 return "Jy";
00213         else if( nMatch("MJY/SR",chCard) )
00214                 return "MJy/sr";
00215         else if( nMatch(" MJY",chCard) )
00216                 return "mJy";
00217 
00218         string str;
00219         if( nMatch("ERG/S/",chCard) )
00220                 str = "erg/s";
00221         else if( nMatch("W/SQ",chCard) )
00222                 str = "W";
00223         else
00224                 return "";
00225 
00226         if( nMatch("/SQCM",chCard) )
00227                 str += "/cm2";
00228         else if( nMatch("/SQM",chCard) )
00229                 str += "/m2";
00230         else
00231                 return "";
00232 
00233         if( nMatch("/A ",chCard) || nMatch("/A/",chCard) )
00234                 str += "/A";
00235         else if( nMatch("/NM",chCard) )
00236                 str += "/nm";
00237         else if( nMatch("/MICR",chCard) )
00238                 str += "/micron";
00239         else if( nMatch("/HZ",chCard) )
00240                 str += "/Hz";
00241 
00242         if( nMatch("/SR",chCard) )
00243                 str += "/sr";
00244         else if( nMatch("/SQAS",chCard) )
00245                 str += "/arcsec2";
00246 
00247         if( !ValidFluxUnit(str) )
00248         {
00249                 fprintf( ioQQQ, " No valid flux unit was recognized on this line:\n %s\n\n", chCard );
00250                 fprintf( ioQQQ, " See Hazy for details.\n" );
00251                 cdEXIT(EXIT_FAILURE);
00252         }
00253 
00254         return str;
00255 }
00256 
00257 string Flux::uu() const
00258 {
00259         DEBUG_ENTRY( "Flux::uu()" );
00260 
00261         ASSERT( p_ValidFluxUnit(p_userunits) );
00262 
00263         if( p_userunits[FU_JY] )
00264                 return "Jy";
00265         else if( p_userunits[FU_MJY] )
00266                 return "mJy";
00267         else if( p_userunits[FU_MJY_SR] )
00268                 return "MJy/sr";
00269 
00270         string str;
00271         if( p_userunits[FU_ERG_S] )
00272                 str = "erg/s";
00273         else if( p_userunits[FU_W] )
00274                 str = "W";
00275 
00276         if( p_userunits[FU_CM2] )
00277                 str += "/cm2";
00278         else if( p_userunits[FU_M2] )
00279                 str += "/m2";
00280 
00281         if( p_userunits[FU_A] )
00282                 str += "/A";
00283         else if( p_userunits[FU_NM] )
00284                 str += "/nm";
00285         else if( p_userunits[FU_MU] )
00286                 str += "/micron";
00287         else if( p_userunits[FU_HZ] )
00288                 str += "/Hz";
00289 
00290         if( p_userunits[FU_SR] )
00291                 str += "/sr";
00292         else if( p_userunits[FU_SQAS] )
00293                 str += "/arcsec2";
00294 
00295         return str;
00296 }