Newer
Older
Javier Vegas-Regidor
committed
import shutil
from autosubmit.config.log import Log
from earthdiagnostics import cdftools
from earthdiagnostics.constants import Basins
Javier Vegas-Regidor
committed
from earthdiagnostics.utils import Utils, TempFile
from earthdiagnostics.diagnostic import Diagnostic
from earthdiagnostics.box import Box
class HeatContent(Diagnostic):
"""
Compute the total ocean heat extent
:original author: Virginie Guemas <virginie.guemas@bsc.es>
:contributor: Javier Vegas-Regidor<javier.vegas@bsc.es>
:created: May 2012
:last modified: June 2016
:param data_manager: data management object
:type data_manager: DataManager
:param startdate: startdate
:type startdate: str
:param member: member number
:type member: int
:param chunk: chunk's number
:type chunk: int
:param mixed_layer: If 1, restricts calculation to the mixed layer, if -1 exclude it. If 0, no effect
:type mixed_layer: int
:param box: box to use for the average
:type box: Box
Javier Vegas-Regidor
committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
"""
def __init__(self, data_manager, startdate, member, chunk, basin, mixed_layer, box):
Diagnostic.__init__(self, data_manager)
self.startdate = startdate
self.member = member
self.chunk = chunk
self.basin = basin
self.mxloption = mixed_layer
self.box = box
self.required_vars = ['so', 'mlotst']
self.generated_vars = ['scvertsum']
def __str__(self):
return 'Heat content Startdate: {0} Member: {1} Chunk: {2}'.format(self.startdate, self.member,
self.chunk)
@classmethod
def generate_jobs(cls, diags, options):
"""
Creates a job for each chunk to compute the diagnostic
:param diags: Diagnostics manager class
:type diags: Diags
:param options: None
:type options: list[str]
:return:
"""
num_options = len(options) - 1
if num_options < 4:
raise Exception('You must specify the basin, mixed layer option and minimum and maximum depth to use')
if num_options > 4:
raise Exception('You must specify 4 parameters for the heat content diagnostic')
basin = Basins.parse(options[1])
mixed_layer = int(options[2])
box = Box(True)
box.min_depth = int(options[3])
box.max_depth = int(options[4])
job_list = list()
Javier Vegas-Regidor
committed
for startdate, member, chunk in diags.exp_manager.get_chunk_list():
job_list.append(HeatContent(diags.data_manager, startdate, member, chunk, basin, mixed_layer, box))
Javier Vegas-Regidor
committed
return job_list
def compute(self):
Javier Vegas-Regidor
committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
nco = Utils.nco
temperature_file = self.data_manager.get_file('ocean', 'thetao', self.startdate, self.member, self.chunk)
if self.mxloption != 0:
mlotst_file = self.data_manager.get_file('ocean', 'mlotst', self.startdate, self.member, self.chunk)
nco.ncks(input=mlotst_file, output=temperature_file, options='-A -v mlotst')
para = list()
para.append('0')
para.append('0')
para.append('0')
para.append('0')
para.append(self.box.min_depth)
para.append(self.box.max_depth)
if self.mxloption != 0:
para.append('-mxloption')
para.append(str(self.mxloption))
if self.basin != Basins.Global:
handler = Utils.openCdf('mask_regions.3d.nc')
if self.basin.fullname not in handler.variables:
raise Exception('Basin {0} is not defined on mask_regions.nc'.format(self.basin.fullname))
handler.close()
para.append('-maskfile')
para.append('mask_regions.3d.nc')
para.append('-mask')
para.append(self.basin.fullname)
shell_output = cdftools.run('cdfheatc', options=para, input=temperature_file)
ohcsum_temp = TempFile.get()
ohcvmean_temp = TempFile.get()
nco.ncks(input=temperature_file, output=ohcsum_temp, options='-O -v time')
shutil.copy(ohcsum_temp, ohcvmean_temp)
ohcsum_handler = Utils.openCdf(ohcsum_temp)
thc = ohcsum_handler.createVariable('ohcsum', float, 'time')
thc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content"
thc.long_name = "Total heat content"
thc.units = "Joules"
ohcvmean_handler = Utils.openCdf(ohcvmean_temp)
uhc = ohcvmean_handler.createVariable('ohcvmean', float, 'time')
uhc.standard_name = "integral_of_sea_water_potential_temperature_expressed_as_heat_content"
uhc.long_name = "Heat content per unit volume"
uhc.units = "Joules/m3"
time = 0
# noinspection PyUnboundLocalVariable
for lines in shell_output:
if not lines:
continue
for line in lines.split('\n'):
line = line.lstrip()
if line.startswith("Heat Content at level"):
Log.info(line)
elif line.startswith("Total Heat content/volume"):
Log.user_warning(line)
uhc[time] = line[line.index(':') + 1: line.index('Joules')]
time += 1
if line.startswith("Total Heat content "):
Log.result(line)
thc[time] = line[line.index(':') + 1: line.index('Joules')]
elif line.startswith('TIME : '):
Log.info(line)
ohcsum_handler.close()
ohcvmean_handler.close()
Utils.setminmax(ohcsum_temp, 'ohcsum')
self.data_manager.send_file(ohcsum_temp, 'ocean', 'ohcsum', self.startdate, self.member, self.chunk,
box=self.box, region=self.basin.fullname, rename_var='ohcsum')
Utils.setminmax(ohcvmean_temp, 'ohcvmean')
self.data_manager.send_file(ohcvmean_temp, 'ocean', 'ohcvmean', self.startdate, self.member, self.chunk,
box=self.box, region=self.basin.fullname, rename_var='ohcvmean')