cloudy  trunk
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
species_pseudo_cont.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 /*SaveSpecies generate output for the save species command */
4 #include "cddefines.h"
5 #include "continuum.h"
6 #include "trace.h"
7 #include "save.h"
8 #include "radius.h"
9 #include "generic_state.h"
10 #include "mole.h"
11 #include "species.h"
12 #include "lines.h"
13 #include "lines_service.h"
14 
15 
16 
18 
19 
21 {
22  UNSET = 0,
23  INWARD = 1,
24  OUTWARD = 2,
25  TOTAL = 3
26 };
27 
28 STATIC string getIntenTypeStr( const int ipContType )
29 {
30  DEBUG_ENTRY( "getIntenTypeStr()" );
31 
32  switch( ipContType )
33  {
34  case UNSET:
35  return "Not Set";
36  case INWARD:
37  return "Inward";
38  case OUTWARD:
39  return "Outward";
40  case TOTAL:
41  return "Total";
42  default:
43  TotalInsanity();
44  }
45 }
46 
47 void getSpecies( const string &speciesLabel, genericState &species )
48 {
49  DEBUG_ENTRY( "getSpecies()" );
50 
51  vector<genericState> v = matchGeneric( speciesLabel.c_str(), false );
52  if( v.size() != 1 )
53  {
54  fprintf( ioQQQ, "Error: Incorrect number of matches (%d) for species '%s'\n",
55  int(v.size()), speciesLabel.c_str() );
57  }
58  // printf( "sp= '%s'\n", v[0].label().c_str() );
59  species = v[0];
60 }
61 
62 
63 
64 /*==============================================================================*/
65 /* BASE CLASS */
66 /*==============================================================================*/
67 class band_cont
68 {
69 protected:
70  string speciesLabel;
71  long int nBins;
73  vector<realnum> inten_inward,
75 public:
76  virtual ~band_cont() = 0;
77  string label() const { return speciesLabel; }
78  long bins() const { return nBins; }
79 protected:
80  bool check_index( const long ibin ) const
81  {
82  return (ibin < 0 || ibin >= nBins) ? false : true;
83  }
84  virtual void check_index_fatal( const long ibin ) const = 0;
85  virtual void sumBand( double *sumOutward, double *sumInward ) const = 0;
86 public:
87  void accumulate( bool lgReset, double dVeffAper );
88  virtual realnum getWl( const long ibin ) const = 0;
89  double getInten( const long ibin, const int ipContType ) const;
90 };
91 
93 
94 void band_cont::accumulate( bool lgReset = true, double dVeffAper = 1.0 )
95 {
96  DEBUG_ENTRY( "band_cont::accumulate()" );
97 
98  // initialize
99  if( lgReset )
100  {
101  for( long ibin = 0; ibin < nBins; ibin++ )
102  {
103  inten_inward[ ibin ] = 0.;
104  inten_outward[ ibin ] = 0.;
105  }
106  }
107 
108  // integrate
109  vector<double> sumOutward( nBins ), sumInward( nBins );
110 
111  sumBand( get_ptr(sumOutward), get_ptr(sumInward) );
112 
113  for( long ibin = 0; ibin < nBins; ibin++ )
114  {
115  inten_inward[ ibin ] += realnum(sumInward[ ibin ] * dVeffAper);
116  inten_outward[ ibin ] += realnum(sumOutward[ ibin ] * dVeffAper);
117  }
118 }
119 
120 double band_cont::getInten( const long ibin, const int ipContType ) const
121 {
122  DEBUG_ENTRY( "band_cont::getInten()" );
123 
124  check_index_fatal( ibin );
125 
126  double inten = 0.;
127  switch( ipContType )
128  {
129  case INWARD:
130  inten = inten_inward[ ibin ];
131  break;
132  case OUTWARD:
133  inten = inten_outward[ ibin ];
134  break;
135  case TOTAL:
136  inten = inten_inward[ ibin ] + inten_outward[ ibin ];
137  break;
138  default:
139  fprintf( ioQQQ, "Error: Illegal continuum type: %d\n",
140  ipContType );
141  cdEXIT( EXIT_FAILURE );
142  break;
143  }
144 
145  return inten;
146 }
147 
148 
149 /*==============================================================================*/
150 /* PSEUDO CONTINUA */
151 /*==============================================================================*/
152 class pseudo_cont : public band_cont
153 {
154 private:
155  double wlLo,
156  wlHi;
157  double log_wlLo,
158  log_step;
159  vector<realnum> wl;
160 public:
161  void setup( string &label, double wlo, double whi, long nb );
162 private:
163  void sumBand( double *sumOutward, double *sumInward ) const;
164  void check_index_fatal( const long ibin ) const
165  {
166  if( ! check_index( ibin ) )
167  {
168  fprintf( ioQQQ, "Error: Pseudo-continuum bin (%ld) "
169  "for species '%s' "
170  "out of range (0, %ld)\n",
171  ibin,
172  speciesLabel.c_str(),
173  nBins-1
174  );
175  cdEXIT( EXIT_FAILURE );
176  }
177  }
178 public:
179  realnum getWl( const long ibin ) const
180  {
181  check_index_fatal( ibin );
182  double mid_wl = 0.5 * ( wl[ ibin ] + wl[ ibin+1 ] );
183  return realnum( AnuUnit( realnum( RYDLAM/ mid_wl ) ) );
184  }
185 };
186 
187 void pseudo_cont::setup( string &label, double wlo, double whi, long nb )
188 {
189  DEBUG_ENTRY( "pseudo_cont::setup()" );
190 
192  wlLo = wlo;
193  wlHi = whi;
194  nBins = nb;
195  wl.resize( nBins + 1 );
196  inten_inward.resize( nBins );
197  inten_outward.resize( nBins );
198 
199  log_step = log10( wlHi / wlLo ) / nBins;
200  log_wlLo = log10( wlLo );
201  for( long ibin = 0; ibin < nBins+1; ++ibin )
202  {
203  // bounds of cells in Angstroms
204  wl[ ibin ] = exp10( log_wlLo + ibin*log_step );
205  // fprintf( stdout, "ibin= %ld\t wl= %g\n",
206  // ibin, wl[ ibin ] );
207  }
208 
210  // printf( "sp= '%s'\n", species.label().c_str() );
211 }
212 
213 void pseudo_cont::sumBand( double *sumOutward, double *sumInward ) const
214 {
215  DEBUG_ENTRY( "pseudo_cont::sumBand()" );
216 
217  for( long i=0; i<nBins; ++i )
218  {
219  sumOutward[i] = 0.;
220  sumInward[i] = 0.;
221  }
222 
223  if( density( species ) <= SMALLFLOAT )
224  return;
225 
226  if( species.sp->lines == NULL )
227  {
228  fprintf( ioQQQ,
229  "WARNING: Species '%s' does not have any data for 'save species continuum'.\n",
230  species.label().c_str() );
231  return;
232  }
233 
234  double log_step_inv = 1. / log_step;
235 
236  for( TransitionProxy::iterator tr = species.sp->lines->begin();
237  tr != species.sp->lines->end(); ++tr )
238  {
239  if( (*tr).WLAng() < wlLo || (*tr).WLAng() > wlHi )
240  continue;
241 
242  double bin = (log10( (*tr).WLAng() ) - log_wlLo) * log_step_inv;
243  long ibin = long( bin );
244  if( ! check_index( ibin ) )
245  continue;
246 
247  {
248  enum { DEBUG_BAND = false };
249  if( DEBUG_BAND && (*tr).Emis().xIntensity() > 0. )
250  {
251  fprintf( ioQQQ,
252  "WLAng= %g\t wl(i)= %g\t wl(i+1)= %g\t "
253  "bin= %g\t ibin= %ld\t inten= %g\t "
254  "frac_inw= %g\n",
255  (*tr).WLAng(),
256  wl[ibin], wl[ibin+1],
257  bin, ibin,
258  (*tr).Emis().xIntensity(),
259  (*tr).Emis().FracInwd() );
260  }
261  }
262 
263  sumOutward[ ibin ] += (*tr).Emis().xIntensity() *
264  MAX2( 0., 1-(*tr).Emis().FracInwd() );
265  sumInward[ ibin ] += (*tr).Emis().xIntensity() *
266  (*tr).Emis().FracInwd();
267  }
268 }
269 /*============================================================================*/
270 
271 static vector< pseudo_cont > PseudoCont;
272 
273 STATIC void getPseudoIndex( const string &speciesLabel,
274  vector<pseudo_cont>::iterator &this_it )
275 {
276  DEBUG_ENTRY( "getPseudoIndex()" );
277 
278  this_it = PseudoCont.end();
279 
280  for( vector<pseudo_cont>::iterator it = PseudoCont.begin();
281  it != PseudoCont.end(); ++it )
282  {
283  // fprintf( ioQQQ, "'%s'\t '%s'\n",
284  // speciesLabel.c_str(),
285  // (*it).label().c_str() );
286  if( speciesLabel == (*it).label() )
287  {
288  this_it = it;
289  break;
290  }
291  }
292 }
293 
294 STATIC long getAdjPseudoIndex( const string &speciesLabel )
295 {
296  DEBUG_ENTRY( "getAdjPseudoIndex()" );
297 
298  long index = -1;
299  for( size_t jps = 0; jps < save.setPseudoCont.size(); jps++ )
300  {
301  // fprintf( ioQQQ,
302  // "'%s'\t '%s'\n",
303  // speciesLabel.c_str(),
304  // save.setPseudoCont[ jps ].c_str() );
305  if( speciesLabel == save.setPseudoCont[ jps ].speciesLabel )
306  {
307  index = long( jps );
308  }
309  }
310 
311  return index;
312 }
313 
314 STATIC void getPseudoWlRange( const string &speciesLabel,
315  double &wlLo, double &wlHi, long &nBins )
316 {
317  DEBUG_ENTRY( "getPseudoWlRange()" );
318 
319  wlLo = pseudoContDef.wlLo;
320  wlHi = pseudoContDef.wlHi;
321  nBins = pseudoContDef.nBins;
322 
323  long index = getAdjPseudoIndex( speciesLabel );
324 
325  if( index >= 0 && index < long(save.setPseudoCont.size()) )
326  {
327  wlLo = save.setPseudoCont[ index ].wlLo;
328  wlHi = save.setPseudoCont[ index ].wlHi;
329  nBins = save.setPseudoCont[ index ].nBins;
330  }
331 
332  // fprintf( stdout,
333  // "'%s'\t xLamLow = %g\t xLamHi = %g\t nBins = %ld\n",
334  // speciesLabel.c_str(), wlLo, wlHi, nBins );
335 }
336 
337 STATIC void PseudoContCreate( long ips )
338 {
339  DEBUG_ENTRY( "PseudoContCreate()" );
340 
341  double wlLo,
342  wlHi;
343  long int nBins;
344 
346  wlLo, wlHi, nBins );
347 
348  PseudoCont[ ips ].setup( save.contSaveSpeciesLabel[ ips ],
349  wlLo, wlHi, nBins );
350  return;
351 }
352 
354 {
355  DEBUG_ENTRY( "PseudoContCreate()" );
356 
357  if( PseudoCont.size() != 0 )
358  return;
359 
360  PseudoCont.resize( save.contSaveSpeciesLabel.size() );
361 
362  for( size_t ips = 0; ips < save.contSaveSpeciesLabel.size(); ips++ )
363  {
364  PseudoContCreate( ips );
365  }
366 }
367 
368 /*============================================================================*/
369 
371 {
372  DEBUG_ENTRY( "PseudoContAccum()" );
373 
374  if( LineSave.ipass != 1 )
375  return;
376 
377  for( vector<pseudo_cont>::iterator it = PseudoCont.begin();
378  it != PseudoCont.end(); ++it )
379  {
380  (*it).accumulate( nzone == 1, radius.dVeffAper );
381  }
382 }
383 
384 /*============================================================================*/
385 
386 STATIC long resolveSpecType( const char *saveSpec )
387 {
388  DEBUG_ENTRY( "resolveSpecType()" );
389 
390  long ipContType = UNSET;
391  if( strcmp( saveSpec, "CONi" ) == 0 )
392  {
393  ipContType = INWARD;
394  }
395  else if( strcmp( saveSpec, "CONo" ) == 0 )
396  {
397  ipContType = OUTWARD;
398  }
399  else if( strcmp( saveSpec, "CONt" ) == 0 )
400  {
401  ipContType = TOTAL;
402  }
403  return ipContType;
404 }
405 
406 void SaveSpeciesPseudoCont( const long ipPun, const string &speciesLabel )
407 {
408  DEBUG_ENTRY( "SaveSpeciesPseudoCont()" );
409 
410  vector<pseudo_cont>::iterator it;
411  getPseudoIndex( speciesLabel, it );
412  if( it == PseudoCont.end() )
413  {
414  fprintf( ioQQQ,
415  "Error: Species continuum data unmatched for species '%s'\n",
416  speciesLabel.c_str() );
417  cdEXIT( EXIT_FAILURE );
418  }
419 
420  if( save.punarg[ipPun][0] == 1 )
421  {
422  long ipContType = resolveSpecType( save.chSaveArgs[ ipPun ] );
423 
424  // row format used for grids - one time print of wavelength grid first
425  if( save.lgSaveHeader(ipPun) )
426  {
427  // one time print of continuum header
428  fprintf( save.params[ipPun].ipPnunit,
429  "#%s ", speciesLabel.c_str() );
430  switch( ipContType )
431  {
432  case INWARD:
433  fprintf( save.params[ipPun].ipPnunit, "inward" );
434  break;
435  case OUTWARD:
436  fprintf( save.params[ipPun].ipPnunit, "outward" );
437  break;
438  case TOTAL:
439  fprintf( save.params[ipPun].ipPnunit, "total" );
440  break;
441  default:
442  TotalInsanity();
443  }
444  fprintf( save.params[ipPun].ipPnunit,
445  ": Energy\t%s Int[erg cm-2 s-1]\n",
446  getIntenTypeStr( ipContType ).c_str() );
447 
448  for( long ibin = 0; ibin < (*it).bins(); ibin++ )
449  {
450  if( ibin > 0 )
451  fprintf( save.params[ipPun].ipPnunit, "\t" );
452  fprintf( save.params[ipPun].ipPnunit,
453  "%.5e",
454  (*it).getWl( ibin ) );
455  }
456  fprintf( save.params[ipPun].ipPnunit, "\n");
457  save.SaveHeaderDone(ipPun);
458  }
459 
460  /* give intensities */
461  // fprintf( save.params[ipPun].ipPnunit, "%s\t",
462  // getIntenTypeStr( ipContType ).c_str() );
463  for( long ibin = 0; ibin < (*it).bins(); ibin++ )
464  {
465  fprintf( save.params[ipPun].ipPnunit, "%e",
466  (*it).getInten( ibin, ipContType ));
467  if( ibin < (*it).bins()-1 )
468  {
469  fprintf( save.params[ipPun].ipPnunit, "\t" );
470  }
471  }
472  fprintf( save.params[ipPun].ipPnunit, "\n");
473  }
474  else if( save.punarg[ipPun][0] == 2 )
475  {
476  // the default, four columns, wl, total, inward, outward
477  // one time print of header
478  if( save.lgSaveHeader(ipPun) )
479  {
480  fprintf( save.params[ipPun].ipPnunit,
481  "#%s ", speciesLabel.c_str() );
482  fprintf( save.params[ipPun].ipPnunit,
483  "wl\ttotal\tinward\toutward\n" );
484  save.SaveHeaderDone(ipPun);
485  }
486  // printf("ips= %ld\tbins= %ld\n", ips, PseudoCont[ ips ].bins());
487  for( long ibin = 0; ibin < (*it).bins(); ibin++ )
488  {
489  fprintf( save.params[ipPun].ipPnunit, "%.5f",
490  (*it).getWl( ibin ) );
491  fprintf( save.params[ipPun].ipPnunit, "\t%e",
492  (*it).getInten( ibin, TOTAL ) );
493  fprintf( save.params[ipPun].ipPnunit, "\t%e",
494  (*it).getInten( ibin, INWARD ) );
495  fprintf( save.params[ipPun].ipPnunit, "\t%e",
496  (*it).getInten( ibin, OUTWARD ) );
497  fprintf( save.params[ipPun].ipPnunit, "\n");
498  }
499  }
500 }
501 
502 
503 
504 /*==============================================================================*/
505 /* BANDS */
506 /*==============================================================================*/
508 {
509 private:
510  string fileBands;
511  vector<realnum> prt_wl,
512  wlLo,
513  wlHi;
514  long nBands;
515 public:
516  void setup( const string &fname )
517  {
518  fileBands = fname;
519  }
520  string bandFilename() const
521  {
522  return fileBands;
523  }
524  bool load();
525  long get_nBands() const
526  {
527  return nBands;
528  }
529  realnum getWl( const long iband ) const
530  {
531  return double( prt_wl[ iband ] );
532  }
533  realnum getWlLo( const long iband ) const
534  {
535  return wlLo[ iband ];
536  }
537  realnum getWlHi( const long iband ) const
538  {
539  return wlHi[ iband ];
540  }
541 };
542 
544 {
545  DEBUG_ENTRY( "bands_file::load()" );
546 
547  /* get FeII band data */
548  if( trace.lgTrace )
549  {
550  fprintf( ioQQQ, " BandsCreate opening %s:", fileBands.c_str() );
551  }
552 
553  FILE *ioDATA = open_data( fileBands.c_str(), "r" );
554 
555  /* now count how many bands are in the file */
556  nBands = 0;
557 
558  char chLine[FILENAME_PATH_LENGTH_2];
559 
560  if( fileBands == "FeII_bands.ini" )
561  {
562  /* first line is a version number and does not count */
563  char chLine[FILENAME_PATH_LENGTH_2];
564  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
565  {
566  fprintf( ioQQQ, " BandsCreate could not read first line of %s.\n",
567  fileBands.c_str() );
568  return false;
569  }
570  }
571 
572  while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
573  {
574  /* we want to count the lines that do not start with #
575  * since these contain data */
576  if( chLine[0] != '#')
577  ++nBands;
578  }
579 
580  /* now rewind the file so we can read it a second time*/
581  if( fseek( ioDATA , 0 , SEEK_SET ) != 0 )
582  {
583  fprintf( ioQQQ, " BandsCreate could not rewind %s.\n",
584  fileBands.c_str() );
585  return false;
586  }
587 
588  prt_wl.resize( nBands );
589  wlLo.resize( nBands );
590  wlHi.resize( nBands );
591 
592  /* first line is a version number - now confirm that it is valid */
593  if( fileBands == "FeII_bands.ini" )
594  {
595  if( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) == NULL )
596  {
597  fprintf( ioQQQ, " BandsCreate could not read first line of %s.\n",
598  fileBands.c_str() );
599  return false;
600  }
601  {
602  long i = 1;
603  const long int iyr = 9, imo=6 , idy = 11;
604  long iyrread, imoread , idyread;
605  bool lgEOL;
606  iyrread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
607  imoread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
608  idyread = (long)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
609 
610  if(( iyrread != iyr ) ||
611  ( imoread != imo ) ||
612  ( idyread != idy ) )
613  {
614  fprintf( ioQQQ,
615  " PROBLEM BandsCreate: the version of %s is not the "
616  "current version.\n",
617  fileBands.c_str() );
618  fprintf( ioQQQ,
619  " BandsCreate: I expected the magic numbers %li %li %li "
620  "but found %li %li %li.\n",
621  iyr, imo , idy ,iyrread, imoread , idyread );
622  return false;
623  }
624  }
625  }
626 
627  /* now read in data again, but save it this time */
628  long k = 0;
629  while( read_whole_line( chLine , (int)sizeof(chLine) , ioDATA ) != NULL )
630  {
631  bool lgEOL;
632 
633  /* we want to count the lines that do not start with #
634  * since these contain data */
635  if( chLine[0] != '#')
636  {
637  long i = 1;
638  prt_wl[k] = (realnum)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
639  if( lgEOL )
640  {
641  fprintf( ioQQQ, " There should have been a number on this band column 1. Sorry.\n" );
642  fprintf( ioQQQ, "string==%s==\n" ,chLine );
643  return false;
644  }
645  wlLo[k] = (realnum)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
646  if( lgEOL )
647  {
648  fprintf( ioQQQ, " There should have been a number on this band column 2. Sorry.\n" );
649  fprintf( ioQQQ, "string==%s==\n" ,chLine );
650  return false;
651  }
652  wlHi[k] = (realnum)FFmtRead(chLine,&i,sizeof(chLine),&lgEOL);
653  if( lgEOL )
654  {
655  fprintf( ioQQQ, " There should have been a number on this band column 3. Sorry.\n" );
656  fprintf( ioQQQ, "string==%s==\n" ,chLine );
657  return false;
658  }
659  /* fprintf(ioQQQ,
660  " band data %f %f %f \n",
661  prt_wl[k], wlLo[k],wlHi[k] ); */
662  ++k;
663  }
664  }
665  /* now validate this incoming data */
666  for( long i=0; i < nBands; ++i )
667  {
668  /* make sure all are positive */
669  if( prt_wl[i] <=0. || wlLo[i] <=0. || wlHi[i] <=0. )
670  {
671  fprintf( ioQQQ, " band %li has none positive entry.\n",i );
672  return false;
673  }
674  /* make sure bands bounds are in correct order, shorter - longer wavelength*/
675  if( wlLo[i] >= wlHi[i] )
676  {
677  fprintf( ioQQQ, " band %li has improper bounds.\n" ,i );
678  return false;
679  }
680  }
681 
682  fclose(ioDATA);
683 
684  /* return success */
685  return true;
686 }
687 
688 /*==============================================================================*/
689 static vector<bands_file> Bands;
690 
691 STATIC void findBandsFile( const string &filename,
692  vector<bands_file>::iterator &this_it )
693 {
694  DEBUG_ENTRY( "findBandsFile()" );
695 
696  this_it = Bands.end();
697  for( vector<bands_file>::iterator it = Bands.begin();
698  it != Bands.end(); ++it )
699  {
700  if( (*it).bandFilename() == filename )
701  {
702  this_it = it;
703  break;
704  }
705  }
706 }
707 
708 STATIC void addBandsFile( const string &filename )
709 {
710  DEBUG_ENTRY( "addBandsFile()" );
711 
712  vector<bands_file>::iterator it;
713  findBandsFile( filename, it );
714 
715  if( it == Bands.end() )
716  {
717  bands_file b_tmp;
718  b_tmp.setup( filename );
719  b_tmp.load();
720  Bands.push_back( b_tmp );
721  }
722 }
723 
724 
725 
726 /*==============================================================================*/
727 /* SPECIES BAND EMISSION */
728 /*==============================================================================*/
729 class species_bands : public band_cont
730 {
731 private:
732  string bandLabel,
733  comment;
734  vector<bands_file>::iterator bands_it;
735 public:
736  string inwdLabel; // Set below; not permissible here pre-C++11
737 
738  void setup( const string &splab, vector<bands_file>::iterator it )
739  {
740  speciesLabel = splab;
741  getSpecies( splab, species );
742  // printf("species: '%s'\n", species.label().c_str());
743 
744  bands_it = it;
745  nBins = (*bands_it).get_nBands();
746  inten_inward.resize( nBins );
747  inten_outward.resize( nBins );
748 
749  for( long iband = 0; iband < nBins; ++iband )
750  {
751  inten_inward[ iband ] = 0.;
752  inten_outward[ iband ] = 0.;
753  }
754 
755  inwdLabel = "Inwd";
756 
757  string spectralLabel;
758  chemical_to_spectral( speciesLabel, spectralLabel );
759  // printf("spectralLabel = '%s'\n", spectralLabel.c_str());
760  bandLabel = spectralLabel + "b";
761  comment = spectralLabel + " emission in bands defined in " +
762  (*bands_it).bandFilename();
763  }
764 private:
765  void check_index_fatal( const long iband ) const
766  {
767  if( ! check_index( iband ) )
768  {
769  fprintf( ioQQQ, "Error: Band (%ld) "
770  "for species '%s' "
771  "from file '%s' "
772  "out of range (0, %ld)\n",
773  iband,
774  speciesLabel.c_str(),
775  (*bands_it).bandFilename().c_str(),
776  nBins-1
777  );
778  cdEXIT( EXIT_FAILURE );
779  }
780  }
781  void sumBand( double *sumOutward, double *sumInward ) const;
782 public:
783  void insert();
784 public:
785  string bandFilename() const { return (*bands_it).bandFilename(); }
786  string getLabel() const { return bandLabel; }
787  realnum getWl( const long iband ) const
788  {
789  check_index_fatal( iband );
790  return (*bands_it).getWl( iband );
791  }
792  realnum getWlLo( const long iband ) const
793  {
794  check_index_fatal( iband );
795  return (*bands_it).getWlLo( iband );
796  }
797  realnum getWlHi( const long iband ) const
798  {
799  check_index_fatal( iband );
800  return (*bands_it).getWlHi( iband );
801  }
802 };
803 
804 void species_bands::sumBand( double *sumOutward, double *sumInward ) const
805 {
806  DEBUG_ENTRY( "species_bands::sumBand()" );
807 
808  for( long i=0; i<nBins; ++i )
809  {
810  sumOutward[i] = 0.;
811  sumInward[i] = 0.;
812  }
813 
814  if( density( species ) <= SMALLFLOAT )
815  return;
816 
817  if( species.sp->lines == NULL )
818  {
819  fprintf( ioQQQ,
820  "WARNING: Species '%s' does not have any data for 'save species bands'.\n",
821  species.label().c_str() );
822  return;
823  }
824 
825  for( TransitionProxy::iterator tr = species.sp->lines->begin();
826  tr != species.sp->lines->end(); ++tr )
827  {
828  for( long iband = 0; iband < nBins; ++iband )
829  {
830  if( (*tr).WLAng() >= getWlLo( iband ) &&
831  (*tr).WLAng() < getWlHi( iband ) )
832  {
833  sumOutward[ iband ] += (*tr).Emis().xIntensity() *
834  MAX2( 0., 1-(*tr).Emis().FracInwd() );
835  sumInward[ iband ] += (*tr).Emis().xIntensity() *
836  (*tr).Emis().FracInwd();
837  }
838  }
839  }
840 }
841 
843 {
844  DEBUG_ENTRY( "species_bands::insert()" );
845 
846  for( long iband = 0; iband < nBins; iband++ )
847  {
848  long ipnt;
849  PntForLine( double( getWl( iband ) ), bandLabel.c_str(), &ipnt );
850  lindst( inten_inward[ iband ] + inten_outward[ iband ],
851  getWl( iband ),
852  bandLabel.c_str(),
853  ipnt, 't', false,
854  (" total " + comment ).c_str() );
855  lindst( inten_inward[ iband ],
856  getWl( iband ),
857  inwdLabel.c_str(),
858  ipnt, 't', false,
859  (" inward " + comment ).c_str() );
860  }
861 }
862 /*============================================================================*/
863 
864 static vector<species_bands> SpecBands;
865 
866 STATIC void getSpecBandsIndex( const string &speciesLabel, const string &fileBands,
867  vector<species_bands>::iterator &this_it )
868 {
869  DEBUG_ENTRY( "getSpecBandsIndex()" );
870 
871  this_it = SpecBands.end();
872 
873  for( vector<species_bands>::iterator it = SpecBands.begin();
874  it != SpecBands.end(); ++it )
875  {
876  if( speciesLabel == (*it).label() &&
877  fileBands == (*it).bandFilename() )
878  {
879  this_it = it;
880  break;
881  }
882  }
883 }
884 
885 /*============================================================================*/
886 
888 {
889  DEBUG_ENTRY( "SpeciesBandsCreate()" );
890 
891  // Already initialized
892  if( SpecBands.size() != 0 )
893  return;
894 
895  for( vector<save_species_bands>::iterator it = save.specBands.begin();
896  it != save.specBands.end(); ++it )
897  {
898  addBandsFile( (*it).filename );
899  }
900 
901  for( vector<save_species_bands>::iterator it = save.specBands.begin();
902  it != save.specBands.end(); ++it )
903  {
904  vector<bands_file>::iterator b_it;
905  findBandsFile( (*it).filename, b_it );
906 
907  species_bands sb_tmp;
908  sb_tmp.setup( (*it).speciesLabel, b_it );
909  SpecBands.push_back( sb_tmp );
910  }
911 }
912 
913 /*============================================================================*/
914 
916 {
917  DEBUG_ENTRY( "SpeciesBandsAccum()" );
918 
919  for( vector<species_bands>::iterator it = SpecBands.begin();
920  it != SpecBands.end(); ++it )
921  {
922  (*it).accumulate();
923  (*it).insert();
924  }
925 }
926 
927 /*============================================================================*/
928 
929 
930 void SaveSpeciesBands( const long ipPun, const string &speciesLabel,
931  const string &fileBands )
932 {
933  DEBUG_ENTRY( "SaveSpeciesBands()" );
934 
935  vector<species_bands>::iterator it;
936  getSpecBandsIndex( speciesLabel, fileBands, it );
937  if( it == SpecBands.end() )
938  {
939  fprintf( ioQQQ,
940  "Error: Species band data unmatched for species "
941  "'%s' and bands from file '%s'\n",
942  speciesLabel.c_str(), fileBands.c_str() );
943  cdEXIT( EXIT_FAILURE );
944  }
945 
946  if( save.lgSaveHeader(ipPun) )
947  {
948  // one time print of header
949  fprintf( save.params[ipPun].ipPnunit, "#Wl(A)\t Intensity: Total\t Inward\t Outward\n" );
950  save.SaveHeaderDone(ipPun);
951  }
952 
953  const int ipEmType = 0; // intrinsic
954  long itot, inwd;
955  double tot_emiss, inwd_emiss;
956 
957  for( long iband = 0; iband < (*it).bins(); iband++ )
958  {
959  itot = LineSave.findline( (*it).getLabel().c_str(), (*it).getWl( iband ) );
960  tot_emiss = LineSave.lines[itot].SumLine(ipEmType) * radius.Conv2PrtInten;
961 
962  inwd = LineSave.findline( (*it).inwdLabel.c_str(), (*it).getWl( iband ) );
963  inwd_emiss = LineSave.lines[inwd].SumLine(ipEmType) * radius.Conv2PrtInten;
964 
965  ASSERT( tot_emiss >= 0. && inwd_emiss >= 0. &&
966  tot_emiss - inwd_emiss >= 0. );
967 
968  fprintf( save.params[ipPun].ipPnunit, "%g", (*it).getWl( iband ) );
969  fprintf( save.params[ipPun].ipPnunit, "\t%e", tot_emiss );
970  fprintf( save.params[ipPun].ipPnunit, "\t%e", inwd_emiss );
971  fprintf( save.params[ipPun].ipPnunit, "\t%e",
972  tot_emiss - inwd_emiss );
973  fprintf( save.params[ipPun].ipPnunit, "\n" );
974  }
975 }
realnum punarg[LIMPUN][3]
Definition: save.h:372
FILE * open_data(const char *fname, const char *mode, access_scheme scheme)
Definition: cpu.cpp:765
realnum getWlLo(const long iband) const
STATIC long int ipPun
Definition: save_do.cpp:367
static vector< pseudo_cont > PseudoCont
double exp10(double x)
Definition: cddefines.h:1368
const int FILENAME_PATH_LENGTH_2
Definition: cddefines.h:296
T * get_ptr(T *v)
Definition: cddefines.h:1109
NORETURN void TotalInsanity(void)
Definition: service.cpp:971
vector< realnum > prt_wl
static vector< bands_file > Bands
long findline(const char *chLabel, realnum wavelength)
Definition: lines.cpp:294
vector< save_species_bands > specBands
Definition: save.h:514
const realnum SMALLFLOAT
Definition: cpu.h:246
long nBins
Definition: species.h:77
double getInten(const long ibin, const int ipContType) const
void lindst(double xEmiss, realnum wavelength, const char *chLab, long int ipnt, char chInfo, bool lgOutToo, const char *chComment)
string bandFilename() const
STATIC void getPseudoWlRange(const string &speciesLabel, double &wlLo, double &wlHi, long &nBins)
realnum getWlLo(const long iband) const
void setup(const string &fname)
t_LineSave LineSave
Definition: lines.cpp:10
void SaveSpeciesBands(const long ipPun, const string &speciesLabel, const string &fileBands)
void SpeciesPseudoContCreate()
vector< genericState > matchGeneric(const char *chLabel, bool lgValidate)
realnum wlHi
Definition: species.h:76
void getSpecies(const string &speciesLabel, genericState &species)
FILE * ioQQQ
Definition: cddefines.cpp:7
long int nzone
Definition: cddefines.cpp:14
FILE * ipPnunit
Definition: save.h:195
t_pseudo_cont pseudoContDef
string bandFilename() const
vector< LinSv > lines
Definition: lines.h:132
realnum getWl(const long ibin) const
void PntForLine(double wavelength, const char *chLabel, long int *ipnt)
vector< realnum > wlLo
virtual ~band_cont()=0
STATIC void PseudoContCreate(long ips)
bool check_index(const long ibin) const
t_trace trace
Definition: trace.cpp:5
void check_index_fatal(const long iband) const
STATIC string getIntenTypeStr(const int ipContType)
void setup(const string &splab, vector< bands_file >::iterator it)
void sumBand(double *sumOutward, double *sumInward) const
#define STATIC
Definition: cddefines.h:118
bool lgTrace
Definition: trace.h:12
char chSaveArgs[LIMPUN][5]
Definition: save.h:383
realnum getWlHi(const long iband) const
STATIC long resolveSpecType(const char *saveSpec)
void chemical_to_spectral(const string chLabelChem, string &chLabelSpec)
Definition: species.cpp:983
long bins() const
STATIC void addBandsFile(const string &filename)
realnum wlLo
Definition: species.h:75
virtual void sumBand(double *sumOutward, double *sumInward) const =0
float realnum
Definition: cddefines.h:124
#define EXIT_FAILURE
Definition: cddefines.h:168
#define cdEXIT(FAIL)
Definition: cddefines.h:482
long get_nBands() const
virtual realnum getWl(const long ibin) const =0
t_radius radius
Definition: radius.cpp:5
double AnuUnit(realnum energy)
Definition: service.cpp:197
SaveParams params[LIMPUN]
Definition: save.h:278
realnum getWl(const long iband) const
vector< realnum > inten_inward
void SpeciesBandsCreate()
double Conv2PrtInten
Definition: radius.h:153
vector< string > contSaveSpeciesLabel
Definition: save.h:509
string label() const
void SaveHeaderDone(int ipPun)
Definition: save.h:364
#define ASSERT(exp)
Definition: cddefines.h:613
double density(const genericState &gs)
STATIC void getPseudoIndex(const string &speciesLabel, vector< pseudo_cont >::iterator &this_it)
STATIC void findBandsFile(const string &filename, vector< bands_file >::iterator &this_it)
#define DEBUG_ENTRY(funcname)
Definition: cddefines.h:723
string getLabel() const
void accumulate(bool lgReset, double dVeffAper)
vector< realnum > wl
#define MAX2(a, b)
Definition: cddefines.h:824
vector< bands_file >::iterator bands_it
int fprintf(const Output &stream, const char *format,...)
Definition: service.cpp:1121
STATIC void getSpecBandsIndex(const string &speciesLabel, const string &fileBands, vector< species_bands >::iterator &this_it)
static vector< species_bands > SpecBands
void check_index_fatal(const long ibin) const
STATIC long getAdjPseudoIndex(const string &speciesLabel)
void SaveSpeciesPseudoCont(const long ipPun, const string &speciesLabel)
realnum getWlHi(const long iband) const
char * read_whole_line(char *chLine, int nChar, FILE *ioIN)
Definition: service.cpp:70
void SpeciesBandsAccum()
void SpeciesPseudoContAccum()
t_save save
Definition: save.cpp:5
void setup(string &label, double wlo, double whi, long nb)
void sumBand(double *sumOutward, double *sumInward) const
realnum getWl(const long iband) const
bool lgSaveHeader(int ipPun) const
Definition: save.h:360
vector< realnum > inten_outward
long int ipass
Definition: lines.h:96
double dVeffAper
Definition: radius.h:93
vector< adjPseudoCont > setPseudoCont
Definition: save.h:510
vector< realnum > wlHi
virtual void check_index_fatal(const long ibin) const =0
double FFmtRead(const char *chCard, long int *ipnt, long int last, bool *lgEOL)
Definition: service.cpp:381
genericState species