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