Package ComboCode :: Package cc :: Package plotting :: Package objects :: Module PlotChem
[hide private]
[frames] | no frames]

Source Code for Module ComboCode.cc.plotting.objects.PlotChem

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  A plotting environment for Chemistry output. 
  5   
  6  Author: M. Van de Sande 
  7   
  8  """ 
  9   
 10  import os 
 11  from scipy import array 
 12  import operator 
 13  import subprocess 
 14  from scipy.interpolate import interp1d 
 15  import numpy as np 
 16   
 17  import cc.path 
 18  from cc.plotting.objects.PlottingSession import PlottingSession 
 19  from cc.tools.io import DataIO 
 20  from cc.modeling.objects import Transition 
 21  from cc.plotting import Plotting2 
 22  from cc.tools.readers import LineList 
 23  from cc.data.instruments import Pacs 
 24  from cc.modeling.objects import Star 
 25  #from cc.modeling.tools import CodeIO 
 26   
 27   
28 -class PlotChem(PlottingSession):
29 30 """ 31 Class for plotting gas lines and their information. 32 33 """ 34
35 - def __init__(self,star_name,path_chemistry='OutputClumpy',\ 36 inputfilename=None,fn_add_star=1):
37 38 """ 39 Initializing an instance of PlotGas. 40 41 @param star_name: name of the star from Star.dat, use default only 42 when never using any star model specific things 43 @type star_name: string 44 45 @keyword path_chemistry: Output modeling folder in MCMax home folder 46 47 (default: 'OutputClumpy') 48 @type path_chemistry: string 49 @keyword inputfilename: name of inputfile that is also copied to the 50 output folder of the plots, 51 if None nothing is copied 52 53 (default: None) 54 @type inputfilename: string 55 56 @keyword fn_add_star: Add the star name to the requested plot filename. 57 Only relevant if fn_plt is given in a sub method. 58 59 (default: 1) 60 @type fn_add_star: bool 61 62 63 """ 64 65 super(PlotChem, self).__init__(star_name=star_name,\ 66 path=path_chemistry,\ 67 code='Chemistry',\ 68 inputfilename=inputfilename,\ 69 fn_add_star=fn_add_star) 70 #-- Convenience path 71 cc.path.cout = os.path.join(cc.path.chemistry,self.path)
72 73 74
75 - def makeStars(self,models):
76 77 ''' 78 Make a Star list based on the Chemistry model ids. 79 80 @param models: model_ids for the Chemistry db 81 @type models: list(string) 82 83 @return: the parameter sets 84 @rtype: list[Star()] 85 86 ''' 87 88 star_grid = Star.makeStars(models=models,\ 89 id_type='Chemistry',\ 90 code='Chemistry',path=self.path) 91 [star.addCoolingPars() for star in star_grid] 92 return star_grid
93 94 95
96 - def plotVelocity(self,star_grid=[],models=[],fn_plt='',force_plot=0,cfg=''):
97 98 ''' 99 Plot velocity versus radius for every model in star_grid. 100 101 @keyword star_grid: List of Star() instances. If default, model ids 102 have to be given. 103 104 (default: []) 105 @type star_grid: list[Star()] 106 @keyword models: The model ids, only required if star_grid is [] 107 108 (default: []) 109 @type models: list[string] 110 @keyword fn_plt: A base plot filename. Includes folder. If not, a 111 default is added 112 113 (default: '') 114 @type fn_plt: string 115 @keyword force_plot: force a plotting if more than models are requested 116 117 (default: 0) 118 @type force_plot: bool 119 @keyword cfg: path to the Plotting2.plotCols config file. If default, 120 the hard-coded default plotting options are used. 121 122 (default: '') 123 @type cfg: string 124 125 ''' 126 127 print '***********************************' 128 print '** Plotting Gas Velocity Profiles' 129 if not star_grid and models: 130 star_grid = self.makeStars(models=models) 131 elif (not models and not star_grid) or (models and star_grid): 132 print '** Input is undefined or doubly defined. Aborting.' 133 return 134 135 cfg_dict = Plotting2.readCfg(cfg) 136 if cfg_dict.has_key('filename'): 137 fn_plt = cfg_dict.pop('filename') 138 139 if len(star_grid) < 20 or force_plot: 140 141 valid_sg = [star for star in star_grid 142 if star['LAST_CHEMISTRY_MODEL']] 143 144 folders = [os.path.join(cc.path.cout,'models',\ 145 star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg] 146 147 radii = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \ 148 for folder in folders] 149 temps = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'VELOCITY') \ 150 for folder in folders] 151 152 if temps: 153 keytags = [star['LAST_CHEMISTRY_MODEL'].replace('_','\_') 154 for star in valid_sg] 155 156 #-- Set filenames 157 pfn = fn_plt if fn_plt else 'velocity_profiles' 158 pfn = self.setFnPlt(pfn) 159 160 #-- Run the two plots 161 keys_cm = ['Model %i'%(i+1) 162 for i in xrange(len(star_grid))] 163 pfn = Plotting2.plotCols(x=radii,y=temps,cfg=cfg_dict,\ 164 filename=pfn,xaxis='$r$ (cm)',\ 165 yaxis=r'$v$ (km s$^{-1}$)',\ 166 figsize=(12.5,8),fontsize_ticklabels=26,\ 167 key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\ 168 keytags=keys_cm,fontsize_axis=26,fontsize_key=26) 169 print '** Plots can be found at:' 170 print pfn 171 print '***********************************'
172 173
174 - def plotTemp(self,star_grid=[],models=[],fn_plt='',force_plot=0,cfg=''):
175 176 ''' 177 Plot temperature profiles of all models. 178 179 @keyword star_grid: List of Star() instances. If default, model ids 180 have to be given. 181 182 (default: []) 183 @type star_grid: list[Star()] 184 @keyword models: The model ids, only required if star_grid is [] 185 186 (default: []) 187 @type models: list[string] 188 @keyword fn_plt: A base plot filename. Includes folder. If not, a 189 default is added 190 191 (default: '') 192 @type fn_plt: string 193 @keyword force_plot: force a plotting if more than models are requested 194 195 (default: 0) 196 @type force_plot: bool 197 @keyword cfg: path to the Plotting2.plotCols config file. If default, 198 the hard-coded default plotting options are used. 199 200 (default: '') 201 @type cfg: string 202 203 ''' 204 205 print '***********************************' 206 print '** Plotting Gas Temperature Profiles' 207 if not star_grid and models: 208 star_grid = self.makeStars(models=models) 209 elif (not models and not star_grid) or (models and star_grid): 210 print '** Input is undefined or doubly defined. Aborting.' 211 return 212 213 cfg_dict = Plotting2.readCfg(cfg) 214 if cfg_dict.has_key('filename'): 215 fn_plt = cfg_dict.pop('filename') 216 217 if len(star_grid) < 20 or force_plot: 218 219 valid_sg = [star for star in star_grid 220 if star['LAST_CHEMISTRY_MODEL']] 221 222 folders = [os.path.join(cc.path.cout,'models',\ 223 star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg] 224 225 radii = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \ 226 for folder in folders] 227 temps = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'TEMP') \ 228 for folder in folders] 229 230 if temps: 231 keytags = [star['LAST_CHEMISTRY_MODEL'].replace('_','\_') 232 for star in valid_sg] 233 234 #-- Set filenames 235 pfn = fn_plt if fn_plt else 'temperature_profiles' 236 pfn = self.setFnPlt(pfn) 237 238 #-- Run the two plots 239 keys_cm = ['Model %i'%(i+1) 240 for i in xrange(len(star_grid))] 241 pfn = Plotting2.plotCols(x=radii,y=temps,cfg=cfg_dict,\ 242 filename=pfn,xaxis='$r$ (cm)',\ 243 yaxis='$T_\mathrm{g}$ (K)',\ 244 figsize=(12.5,8),fontsize_ticklabels=26,\ 245 key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\ 246 keytags=keys_cm,fontsize_axis=26,fontsize_key=26) 247 print '** Plots can be found at:' 248 print pfn 249 print '***********************************' 250 else: 251 print '** No Chemistry models were calculated successfully.'+\ 252 'No temperature profiles can be plotted.' 253 print '***********************************'
254 255 256
257 - def plotVisualExtinction(self,star_grid=[],models=[],fn_plt='',force_plot=0,cfg=''):
258 259 ''' 260 Plot temperature profiles of all models. 261 262 @keyword star_grid: List of Star() instances. If default, model ids 263 have to be given. 264 265 (default: []) 266 @type star_grid: list[Star()] 267 @keyword models: The model ids, only required if star_grid is [] 268 269 (default: []) 270 @type models: list[string] 271 @keyword fn_plt: A base plot filename. Includes folder. If not, a 272 default is added 273 274 (default: '') 275 @type fn_plt: string 276 @keyword force_plot: force a plotting if more than models are requested 277 278 (default: 0) 279 @type force_plot: bool 280 @keyword cfg: path to the Plotting2.plotCols config file. If default, 281 the hard-coded default plotting options are used. 282 283 (default: '') 284 @type cfg: string 285 286 ''' 287 288 print '***********************************' 289 print '** Plotting Visual Extinction Profiles' 290 if not star_grid and models: 291 star_grid = self.makeStars(models=models) 292 elif (not models and not star_grid) or (models and star_grid): 293 print '** Input is undefined or doubly defined. Aborting.' 294 return 295 296 cfg_dict = Plotting2.readCfg(cfg) 297 if cfg_dict.has_key('filename'): 298 fn_plt = cfg_dict.pop('filename') 299 300 if len(star_grid) < 20 or force_plot: 301 302 valid_sg = [star for star in star_grid 303 if star['LAST_CHEMISTRY_MODEL']] 304 305 folders = [os.path.join(cc.path.cout,'models',\ 306 star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg] 307 308 radii = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \ 309 for folder in folders] 310 avs = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'A_V') \ 311 for folder in folders] 312 313 if avs: 314 keytags = [star['LAST_CHEMISTRY_MODEL'].replace('_','\_') 315 for star in valid_sg] 316 317 #-- Set filenames 318 pfn = fn_plt if fn_plt else 'visual_extinction' 319 pfn = self.setFnPlt(pfn) 320 321 #-- Run the two plots 322 keys_cm = ['Model %i'%(i+1) 323 for i in xrange(len(star_grid))] 324 pfn = Plotting2.plotCols(x=radii,y=avs,cfg=cfg_dict,\ 325 filename=pfn,xaxis='$r$ (cm)',\ 326 yaxis='$A_V$ (mag)',\ 327 figsize=(12.5,8),fontsize_ticklabels=26,\ 328 key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\ 329 keytags=keys_cm,fontsize_axis=26,fontsize_key=26) 330 print '** Plots can be found at:' 331 print pfn 332 print '***********************************' 333 else: 334 print '** No Chemistry models were calculated successfully.'+\ 335 'No temperature profiles can be plotted.' 336 print '***********************************'
337 338
339 - def plotPhotodissociationrateCo(self,star_grid=[],models=[],fn_plt='',force_plot=0,cfg=''):
340 341 ''' 342 Plot temperature profiles of all models. 343 344 @keyword star_grid: List of Star() instances. If default, model ids 345 have to be given. 346 347 (default: []) 348 @type star_grid: list[Star()] 349 @keyword models: The model ids, only required if star_grid is [] 350 351 (default: []) 352 @type models: list[string] 353 @keyword fn_plt: A base plot filename. Includes folder. If not, a 354 default is added 355 356 (default: '') 357 @type fn_plt: string 358 @keyword force_plot: force a plotting if more than models are requested 359 360 (default: 0) 361 @type force_plot: bool 362 @keyword cfg: path to the Plotting2.plotCols config file. If default, 363 the hard-coded default plotting options are used. 364 365 (default: '') 366 @type cfg: string 367 368 ''' 369 370 print '***********************************' 371 print '** Plotting Photodissociation Rate CO' 372 if not star_grid and models: 373 star_grid = self.makeStars(models=models) 374 elif (not models and not star_grid) or (models and star_grid): 375 print '** Input is undefined or doubly defined. Aborting.' 376 return 377 378 cfg_dict = Plotting2.readCfg(cfg) 379 if cfg_dict.has_key('filename'): 380 fn_plt = cfg_dict.pop('filename') 381 382 if len(star_grid) < 20 or force_plot: 383 384 valid_sg = [star for star in star_grid 385 if star['LAST_CHEMISTRY_MODEL']] 386 387 folders = [os.path.join(cc.path.cout,'models',\ 388 star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg] 389 390 radii = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \ 391 for folder in folders] 392 cos = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'COK(PHOT)') \ 393 for folder in folders] 394 395 if cos: 396 keytags = [star['LAST_CHEMISTRY_MODEL'].replace('_','\_') 397 for star in valid_sg] 398 399 #-- Set filenames 400 pfn = fn_plt if fn_plt else 'CO_photodissociation_rate' 401 pfn = self.setFnPlt(pfn) 402 403 #-- Run the two plots 404 keys_cm = ['Model %i'%(i+1) 405 for i in xrange(len(star_grid))] 406 pfn = Plotting2.plotCols(x=radii,y=cos,cfg=cfg_dict,\ 407 filename=pfn,xaxis='$r$ (cm)',\ 408 yaxis='$k_{CO,photo}$ (s$^{-1}$)',\ 409 figsize=(12.5,8),fontsize_ticklabels=26,\ 410 key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\ 411 keytags=keys_cm,fontsize_axis=26,fontsize_key=26) 412 print '** Plots can be found at:' 413 print pfn 414 print '***********************************' 415 else: 416 print '** No Chemistry models were calculated successfully.'+\ 417 'No temperature profiles can be plotted.' 418 print '***********************************'
419 420 421
422 - def plotRadiationField(self,star_grid=[],models=[],fn_plt='',force_plot=0,cfg=''):
423 424 ''' 425 Plot temperature profiles of all models. 426 427 @keyword star_grid: List of Star() instances. If default, model ids 428 have to be given. 429 430 (default: []) 431 @type star_grid: list[Star()] 432 @keyword models: The model ids, only required if star_grid is [] 433 434 (default: []) 435 @type models: list[string] 436 @keyword fn_plt: A base plot filename. Includes folder. If not, a 437 default is added 438 439 (default: '') 440 @type fn_plt: string 441 @keyword force_plot: force a plotting if more than models are requested 442 443 (default: 0) 444 @type force_plot: bool 445 @keyword cfg: path to the Plotting2.plotCols config file. If default, 446 the hard-coded default plotting options are used. 447 448 (default: '') 449 @type cfg: string 450 451 ''' 452 453 print '***********************************' 454 print '** Plotting Radiation Field' 455 if not star_grid and models: 456 star_grid = self.makeStars(models=models) 457 elif (not models and not star_grid) or (models and star_grid): 458 print '** Input is undefined or doubly defined. Aborting.' 459 return 460 461 cfg_dict = Plotting2.readCfg(cfg) 462 if cfg_dict.has_key('filename'): 463 fn_plt = cfg_dict.pop('filename') 464 465 if len(star_grid) < 20 or force_plot: 466 467 valid_sg = [star for star in star_grid 468 if star['LAST_CHEMISTRY_MODEL']] 469 470 folders = [os.path.join(cc.path.cout,'models',\ 471 star['LAST_CHEMISTRY_MODEL'])+'/' for star in valid_sg] 472 473 radii = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'RADIUS') \ 474 for folder in folders] 475 cos = [DataIO.getChemistryPhysPar(folder+'csphyspar.out', 'COK(PHOT)') \ 476 for folder in folders] 477 478 if cos: 479 keytags = [star['LAST_CHEMISTRY_MODEL'].replace('_','\_') 480 for star in valid_sg] 481 482 #-- Set filenames 483 pfn = fn_plt if fn_plt else 'radiation_field' 484 pfn = self.setFnPlt(pfn) 485 486 #-- Run the two plots 487 keys_cm = ['Model %i'%(i+1) 488 for i in xrange(len(star_grid))] 489 pfn = Plotting2.plotCols(x=radii,y=cos,cfg=cfg_dict,\ 490 filename=pfn,xaxis='$r$ (cm)',\ 491 yaxis='$I_D$ (photons /s /cm$^2$ /Hz / sr) ',\ 492 figsize=(12.5,8),fontsize_ticklabels=26,\ 493 key_location=(0.05,0.05),xlogscale=1,ylogscale=1,\ 494 keytags=keys_cm,fontsize_axis=26,fontsize_key=26) 495 print '** Plots can be found at:' 496 print pfn 497 print '***********************************' 498 else: 499 print '** No Chemistry models were calculated successfully.'+\ 500 'No temperature profiles can be plotted.' 501 print '***********************************'
502 503 504
505 - def plotAbundanceProfiles(self,star_grid=[],models=[],force_plot=0,cfg='',\ 506 fn_plt='',molecules=[],per_molecule=0,frac=1):
507 508 ''' 509 Plot abundance profiles for all molecules in every model. 510 511 @keyword star_grid: List of Star() instances. If default, model ids 512 have to be given. 513 514 (default: []) 515 @type star_grid: list[Star()] 516 @keyword models: The model ids, only required if star_grid is [] 517 518 (default: []) 519 @type models: list[string] 520 @keyword force_plot: force a plotting if more than models are requested 521 522 (default: 0) 523 @type force_plot: bool 524 @keyword cfg: path to the Plotting2.plotCols config file. If default, 525 the hard-coded default plotting options are used. 526 527 (default: '') 528 @type cfg: string 529 @keyword fn_plt: A base plot filename. Includes folder. If not, a 530 default is added 531 532 (default: '') 533 @type fn_plt: string 534 @keyword molecules: Molecules to be plotted. 535 536 (default: []) 537 @type molecules: bool 538 @keyword per_molecule: Plot one molecule for all models in one figure. 539 540 (default: 0) 541 @type per_molecule: bool 542 @keyword per_model: Plot all molecules for one model in one figure. 543 544 (default: 0) 545 @type per_model: bool 546 @keyword frac: Plot the fractional abundances. If not frac, plot number 547 densities. 548 549 (default: 1) 550 @type frac: bool 551 552 553 ''' 554 555 print '***********************************' 556 print '** Plotting Abundance Profiles' 557 if not star_grid and models: 558 star_grid = self.makeStars(models=models) 559 elif (not models and not star_grid) or (models and star_grid): 560 print '** Input is undefined or doubly defined. Aborting.' 561 return 562 pfns = [] 563 cfg_dict = Plotting2.readCfg(cfg) 564 if cfg_dict.has_key('filename'): 565 fn_plt = cfg_dict.pop('filename') 566 if cfg_dict.has_key('molecules'): 567 molecules = cfg_dict.pop('molecules') 568 if cfg_dict.has_key('per_molecule'): 569 per_molecule = cfg_dict['per_molecule'] 570 if cfg_dict.has_key('per_model'): 571 per_model = cfg_dict['per_model'] 572 573 #-- Some general plot settings 574 extra_pars = dict() 575 extra_pars['ymin'] = 1e-9 576 extra_pars['ymax'] = 1e-3 577 extra_pars['ylogscale'] = 1 578 extra_pars['xlogscale'] = 1 579 extra_pars['figsize'] = (12.5,8.5) 580 extra_pars['xaxis'] = 'cm' 581 582 #-- Dict to keep track of all data 583 ddata = dict() 584 for istar,star in enumerate(star_grid): 585 if not star['LAST_CHEMISTRY_MODEL']: continue 586 ddata[istar] = dict() 587 588 folder = os.path.join(cc.path.cout,'models',\ 589 star['LAST_CHEMISTRY_MODEL'])+'/' 590 ddata[istar]['rad'] = DataIO.getChemistryPhysPar(folder+\ 591 'csphyspar.out', 'RADIUS') 592 ddata[istar]['id'] = star['LAST_CHEMISTRY_MODEL'] 593 if frac: 594 species = DataIO.getChemistryAbundances(folder+'csfrac.out') 595 else: 596 species = DataIO.getChemistryAbundances(folder+'csnum.out') 597 598 for molec in molecules: 599 ddata[istar][molec] = species[molec] 600 601 if not per_molecule: 602 #-- Collect all data 603 radii = [ddata[istar]['rad']]*len(molecules) 604 abuns = [ddata[istar][molec] for molec in molecules] 605 keytags = molecules 606 #ids = star['LAST_CHEMISTRY_MODEL'] 607 ids = ddata[istar]['id'] 608 609 #-- Set the yaxis tag 610 yaxis = '$n_\mathrm{molec}/n_{\mathrm{H}_2}$' 611 612 #-- Set filename 613 pfn = fn_plt if fn_plt else 'abundance_profiles' 614 suff = '_'.join(list(set(ids))) 615 pfn = self.setFnPlt(pfn,fn_suffix=suff) 616 617 pfns.append(Plotting2.plotCols(x=radii,y=abuns,cfg=cfg_dict,\ 618 filename=pfn,keytags=keytags,\ 619 plot_title=ids.replace('_','\_'),\ 620 yaxis=yaxis,**extra_pars)) 621 622 if per_molecule: 623 #-- Collect all data 624 #molecs = list(set([molec for istar in ddata.keys() 625 #for molec in ddata[istar].keys()])) 626 for molec in molecules: 627 #-- Collect data 628 radii = [dstar['rad'] 629 for istar,dstar in ddata.items()] 630 abuns = [dstar[molec] 631 for istar,dstar in ddata.items()] 632 keytags = [dstar['id'].replace('_','\_') 633 for istar,dstar in ddata.items()] 634 635 #-- Set the y axis tag 636 #strmolec = ddata[0][molec]['key'] 637 yaxis = '$n_\mathrm{%s}/n_{\mathrm{H}_2}$'%str(molec) 638 639 #-- Make filename 640 pfn = fn_plt if fn_plt else 'abundance_profiles' 641 pfn = self.setFnPlt(pfn,fn_suffix=molec) 642 643 pfns.append(Plotting2.plotCols(x=radii,y=abuns,yaxis=yaxis,\ 644 filename=pfn,keytags=keytags,\ 645 cfg=cfg_dict,**extra_pars)) 646 647 if not per_molecule and pfns and pfns[0][-4:] == '.pdf': 648 pfn = fn_plt if fn_plt else 'abundance_profiles' 649 pfn = self.setFnPlt(pfn) + '.pdf' 650 DataIO.joinPdf(old=pfns,new=pfn) 651 print '** Plots can be found at:' 652 print pfn 653 print '***********************************' 654 else: 655 print '** Plots can be found at:' 656 print '\n'.join(pfns) 657 print '***********************************'
658