[docs]defini_periods(self,**kwargs):datei=self.dateidatef=self.datefnho=self.nhonhours=self.nhours# List of sub-simulation windowsself.subsimu_dates=date_range(datei,datef,period=self.periods)# Check that subperiods are all of the same lengthifnp.unique(np.diff(self.subsimu_dates)).size>1:raiseException("Trying to run CHIMERE on a simulation window not fitting the ""sub-simulation length. \nPlease check the compatibility between ""the duration of your sub-simulations ({}) and the simulation ""window ({} to {}): \n""Guessed sub-periods: \n".format(self.periods,datei,datef)+"\n".join([" - {}: {}".format(d0,d1-d0)ford0,d1inzip(self.subsimu_dates[:-1],self.subsimu_dates[1:])]))# Time steps defined by the usernphour_ref=self.nphour_ref# Numbers of time steps per hour really used in the simulationself.tstep_dates={}self.tstep_all=[]self.nhour={}self.subtstep={}self.input_dates={}# Stop-or-more functionlist_to_stop=self.stopORmorelist_spec_stop=[]list_thld_stop=[]forlinlist_to_stop:list_spec_stop.append(l[0])list_thld_stop.append(l[1])iflist_thld_stop!=[]andlist_spec_stop!=[]:info("Looking at concentrations small enough to stop simulations")self.list_spec_stop=list_spec_stopself.list_thld_stop=list_thld_stop# Loop over sub simulationsforddinself.subsimu_dates[:-1]:# time-steps in METEO.nc, computed by diagmettry:met=dd.strftime(f"{self.meteo.dir}/{self.meteo.file}")debug(f"Reading {met} to initialize nphourm")ds_met=xr.open_dataset(met)if"nphourm2"inds_met.variables:nbstep=ds_met.variables["nphourm2"].values.astype(int)elif"nphourm"inds_met.variables:nbstep=ds_met.variables["nphourm"].values.astype(int)else:raiseException(f"The file {met} is available, but no information is "f"available about nphourm. Please check your file")exceptIOError:debug(f"{met} is not available. Using nphourref (={nphour_ref}).")nbstep=nhours*[nphour_ref]exceptAttributeError:debug("No meteo plugin was defined in the Yaml. "f"Using default plugin with nphourref (={nphour_ref}).")nbstep=nhours*[nphour_ref]# Loop on hours and check CFLself.tstep_dates[dd]=[]self.nhour[dd]=[]self.subtstep[dd]=[]fornhinrange(nhours):nphour=nbstep[nh]ifnphour_ref<nbstep[nh]elsenphour_ref# Frequency in seconds# TODO: Check with FORTRAN: nphour rounding?freq="{}s".format(int(3600//nphour))# List of time steps# TODO: what about chemical time steps?# the time step to really use is nphour*ichemstepddhi=dd+datetime.timedelta(hours=nh)ddhe=dd+datetime.timedelta(hours=nh+1)drange=list(pd.date_range(ddhi,ddhe,freq=freq).to_pydatetime())self.tstep_dates[dd].extend(drange[:-1])self.tstep_all.extend(drange[:-1])# Saving substep indexes for matching with observationnphour_int=len(drange)-1self.subtstep[dd].extend(list(range(1,nphour_int+1)))self.nhour[dd].extend(nphour_int*[nh+1])# List of dates for which inputs are neededself.input_dates[dd]=pd.date_range(dd,periods=nhours+1,freq="1h").to_pydatetime()# Include last time stepself.tstep_dates[dd].append(ddhe)self.tstep_dates[dd]=np.array(self.tstep_dates[dd])# Include very last time stepself.tstep_all.append(ddhe)self.tstep_all=np.array(self.tstep_all)# Initializes dictionary to keep in memory whether observations were# already dumped for a given periodself.iniobs={ddi:Falseforddiinself.subsimu_dates}self.nbobs_prior={ddi:0forddiinself.subsimu_dates}self.nbdatatot_prior={ddi:0forddiinself.subsimu_dates}self.reset_obs={ddi:Trueforddiinself.subsimu_dates}# Keep track for stop-or-more function (initialize run = True)self.runsimu={ddi:Trueforddiinself.subsimu_dates}# Keep in memory whether a given period has a successor period# The info is used by the adjoint to fetch or not the aend fileself.chain={ddi:Trueforddiinself.subsimu_dates[:-1]}self.chain[self.subsimu_dates[-2]]=False