Beispiel #1
0
    def load(self):
        """
        Load the contents of the input file into a PressureDependenceJob object.
        """
        from arkane.pdep import PressureDependenceJob
        from arkane.input import load_input_file

        # Seed with a PdepJob object
        if self.pdep is None:
            self.pdep = PressureDependenceJob(network=None)

            if self.inputFileExists():
                job_list = load_input_file(self.getInputFilename())[0]
                assert len(job_list) == 1
                job = job_list[0]
                if isinstance(job, PressureDependenceJob) is False:
                    raise Exception('Input file given did not provide a pressure dependence network.')
                self.pdep = job
                self.pdep.initialize()

            if self.pdep.network is not None:
                self.title = self.pdep.network.label
                self.save()

        return self.pdep.network
 def load(self):
     """
     Load the contents of the input file into a PressureDependenceJob object.
     """
     from arkane.pdep import PressureDependenceJob
     from arkane.input import loadInputFile
     
     # Seed with a PdepJob object
     if self.pdep is None:
         self.pdep = PressureDependenceJob(network=None)
         
         if self.inputFileExists():
             jobList = loadInputFile(self.getInputFilename())[0]
             assert len(jobList) == 1
             job = jobList[0]
             if isinstance(job, PressureDependenceJob) is False:
                 raise Exception('Input file given did not provide a pressure dependence network.')
             self.pdep = job 
             self.pdep.initialize()
     
         if self.pdep.network is not None:
             self.title = self.pdep.network.label
             self.save()
     
     return self.pdep.network
Beispiel #3
0
def pressureDependence(
    method,
    temperatures,
    pressures,
    maximumGrainSize=0.0,
    minimumNumberOfGrains=0,
    interpolation=None,
    maximumAtoms=None,
):

    from arkane.pdep import PressureDependenceJob

    # Setting the pressureDependence attribute to non-None enables pressure dependence
    rmg.pressureDependence = PressureDependenceJob(network=None)

    # Process method
    rmg.pressureDependence.method = method

    # Process interpolation model
    if isinstance(interpolation, str):
        interpolation = (interpolation, )
    if interpolation[0].lower() not in ("chebyshev", "pdeparrhenius"):
        raise InputError(
            "Interpolation model must be set to either 'Chebyshev' or 'PDepArrhenius'."
        )
    rmg.pressureDependence.interpolationModel = interpolation

    # Process temperatures
    Tmin, Tmax, Tunits, Tcount = temperatures
    rmg.pressureDependence.Tmin = Quantity(Tmin, Tunits)
    rmg.pressureDependence.Tmax = Quantity(Tmax, Tunits)
    rmg.pressureDependence.Tcount = Tcount
    rmg.pressureDependence.generateTemperatureList()

    # Process pressures
    Pmin, Pmax, Punits, Pcount = pressures
    rmg.pressureDependence.Pmin = Quantity(Pmin, Punits)
    rmg.pressureDependence.Pmax = Quantity(Pmax, Punits)
    rmg.pressureDependence.Pcount = Pcount
    rmg.pressureDependence.generatePressureList()

    # Process grain size and count
    rmg.pressureDependence.maximumGrainSize = Quantity(maximumGrainSize)
    rmg.pressureDependence.minimumGrainCount = minimumNumberOfGrains

    # Process maximum atoms
    rmg.pressureDependence.maximumAtoms = maximumAtoms

    rmg.pressureDependence.activeJRotor = True
    rmg.pressureDependence.activeKRotor = True
    rmg.pressureDependence.rmgmode = True
Beispiel #4
0
def pressureDependence(label,
                       Tmin=None,
                       Tmax=None,
                       Tcount=0,
                       Tlist=None,
                       Pmin=None,
                       Pmax=None,
                       Pcount=0,
                       Plist=None,
                       maximumGrainSize=None,
                       minimumGrainCount=0,
                       method=None,
                       interpolationModel=None,
                       activeKRotor=True,
                       activeJRotor=True,
                       rmgmode=False,
                       sensitivity_conditions=None):
    """Generate a pressure dependent job"""
    global job_list, network_dict

    if isinstance(interpolationModel, str):
        interpolationModel = (interpolationModel, )

    nwk = None
    if label in list(network_dict.keys()):
        nwk = network_dict[label]

    job = PressureDependenceJob(network=nwk,
                                Tmin=Tmin,
                                Tmax=Tmax,
                                Tcount=Tcount,
                                Tlist=Tlist,
                                Pmin=Pmin,
                                Pmax=Pmax,
                                Pcount=Pcount,
                                Plist=Plist,
                                maximumGrainSize=maximumGrainSize,
                                minimumGrainCount=minimumGrainCount,
                                method=method,
                                interpolationModel=interpolationModel,
                                activeKRotor=activeKRotor,
                                activeJRotor=activeJRotor,
                                rmgmode=rmgmode,
                                sensitivity_conditions=sensitivity_conditions)
    job_list.append(job)
Beispiel #5
0
    def saveForm(self, posted, form):
        """
        Save form data into input.py file specified by the path.
        """
        # Clean past history
        self.rmg = RMG()

        # Databases
        #self.rmg.databaseDirectory = settings['database.directory']
        self.rmg.thermoLibraries = []
        if posted.thermo_libraries.all():
            self.rmg.thermoLibraries = [
                item.thermolib.encode()
                for item in posted.thermo_libraries.all()
            ]
        self.rmg.reactionLibraries = []
        self.rmg.seedMechanisms = []
        if posted.reaction_libraries.all():
            for item in posted.reaction_libraries.all():
                if not item.seedmech and not item.edge:
                    self.rmg.reactionLibraries.append(
                        (item.reactionlib.encode(), False))
                elif not item.seedmech:
                    self.rmg.reactionLibraries.append(
                        (item.reactionlib.encode(), True))
                else:
                    self.rmg.seedMechanisms.append(item.reactionlib.encode())
        self.rmg.statmechLibraries = []
        self.rmg.kineticsDepositories = 'default'
        self.rmg.kineticsFamilies = 'default'
        self.rmg.kineticsEstimator = 'rate rules'

        # Species
        self.rmg.initialSpecies = []
        speciesDict = {}
        initialMoleFractions = {}
        self.rmg.reactionModel = CoreEdgeReactionModel()
        for item in posted.reactor_species.all():
            structure = Molecule().fromAdjacencyList(item.adjlist.encode())
            spec, isNew = self.rmg.reactionModel.makeNewSpecies(
                structure,
                label=item.name.encode(),
                reactive=False if item.inert else True)
            self.rmg.initialSpecies.append(spec)
            speciesDict[item.name.encode()] = spec
            initialMoleFractions[spec] = item.molefrac

        # Reactor systems
        self.rmg.reactionSystems = []
        for item in posted.reactor_systems.all():
            T = Quantity(item.temperature, item.temperature_units.encode())
            P = Quantity(item.pressure, item.pressure_units.encode())
            termination = []
            if item.conversion:
                termination.append(
                    TerminationConversion(speciesDict[item.species.encode()],
                                          item.conversion))
            termination.append(
                TerminationTime(
                    Quantity(item.terminationtime, item.time_units.encode())))
            # Sensitivity Analysis
            sensitiveSpecies = []
            if item.sensitivity:
                if isinstance(item.sensitivity.encode(), str):
                    sensitivity = item.sensitivity.encode().split(',')
                for spec in sensitivity:
                    sensitiveSpecies.append(speciesDict[spec.strip()])
            system = SimpleReactor(T, P, initialMoleFractions, termination,
                                   sensitiveSpecies, item.sensitivityThreshold)
            self.rmg.reactionSystems.append(system)

        # Simulator tolerances
        self.rmg.absoluteTolerance = form.cleaned_data['simulator_atol']
        self.rmg.relativeTolerance = form.cleaned_data['simulator_rtol']
        self.rmg.sensitivityAbsoluteTolerance = form.cleaned_data[
            'simulator_sens_atol']
        self.rmg.sensitivityRelativeTolerance = form.cleaned_data[
            'simulator_sens_rtol']
        self.rmg.fluxToleranceKeepInEdge = form.cleaned_data[
            'toleranceKeepInEdge']
        self.rmg.fluxToleranceMoveToCore = form.cleaned_data[
            'toleranceMoveToCore']
        self.rmg.fluxToleranceInterrupt = form.cleaned_data[
            'toleranceInterruptSimulation']
        self.rmg.maximumEdgeSpecies = form.cleaned_data['maximumEdgeSpecies']
        self.rmg.minCoreSizeForPrune = form.cleaned_data['minCoreSizeForPrune']
        self.rmg.minSpeciesExistIterationsForPrune = form.cleaned_data[
            'minSpeciesExistIterationsForPrune']
        self.rmg.filterReactions = form.cleaned_data['filterReactions']

        # Pressure Dependence
        pdep = form.cleaned_data['pdep'].encode()
        if pdep != 'off':
            self.rmg.pressureDependence = PressureDependenceJob(network=None)
            self.rmg.pressureDependence.method = pdep

            # Process interpolation model
            if form.cleaned_data['interpolation'].encode() == 'chebyshev':
                self.rmg.pressureDependence.interpolationModel = (
                    form.cleaned_data['interpolation'].encode(),
                    form.cleaned_data['temp_basis'],
                    form.cleaned_data['p_basis'])
            else:
                self.rmg.pressureDependence.interpolationModel = (
                    form.cleaned_data['interpolation'].encode(), )

            # Temperature and pressure range
            self.rmg.pressureDependence.Tmin = Quantity(
                form.cleaned_data['temp_low'],
                form.cleaned_data['temprange_units'].encode())
            self.rmg.pressureDependence.Tmax = Quantity(
                form.cleaned_data['temp_high'],
                form.cleaned_data['temprange_units'].encode())
            self.rmg.pressureDependence.Tcount = form.cleaned_data[
                'temp_interp']
            self.rmg.pressureDependence.generateTemperatureList()
            self.rmg.pressureDependence.Pmin = Quantity(
                form.cleaned_data['p_low'],
                form.cleaned_data['prange_units'].encode())
            self.rmg.pressureDependence.Pmax = Quantity(
                form.cleaned_data['p_high'],
                form.cleaned_data['prange_units'].encode())
            self.rmg.pressureDependence.Pcount = form.cleaned_data['p_interp']
            self.rmg.pressureDependence.generatePressureList()

            # Process grain size and count
            self.rmg.pressureDependence.grainSize = Quantity(
                form.cleaned_data['maximumGrainSize'],
                form.cleaned_data['grainsize_units'].encode())
            self.rmg.pressureDependence.grainCount = form.cleaned_data[
                'minimumNumberOfGrains']

            self.rmg.pressureDependence.maximumAtoms = form.cleaned_data[
                'maximumAtoms']
        # Additional Options
        self.rmg.units = 'si'
        self.rmg.saveRestartPeriod = Quantity(
            form.cleaned_data['saveRestartPeriod'],
            form.cleaned_data['saveRestartPeriodUnits'].encode(
            )) if form.cleaned_data['saveRestartPeriod'] else None
        self.rmg.generateOutputHTML = form.cleaned_data['generateOutputHTML']
        self.rmg.generatePlots = form.cleaned_data['generatePlots']
        self.rmg.saveSimulationProfiles = form.cleaned_data[
            'saveSimulationProfiles']
        self.rmg.saveEdgeSpecies = form.cleaned_data['saveEdgeSpecies']
        self.rmg.verboseComments = form.cleaned_data['verboseComments']

        # Species Constraints
        speciesConstraints = form.cleaned_data['speciesConstraints']
        if speciesConstraints == 'on':
            allowed = []
            if form.cleaned_data['allowed_inputSpecies']:
                allowed.append('input species')
            if form.cleaned_data['allowed_seedMechanisms']:
                allowed.append('seed mechanisms')
            if form.cleaned_data['allowed_reactionLibraries']:
                allowed.append('reaction libraries')
            self.rmg.speciesConstraints['allowed'] = allowed
            self.rmg.speciesConstraints[
                'maximumCarbonAtoms'] = form.cleaned_data['maximumCarbonAtoms']
            self.rmg.speciesConstraints[
                'maximumOxygenAtoms'] = form.cleaned_data['maximumOxygenAtoms']
            self.rmg.speciesConstraints[
                'maximumNitrogenAtoms'] = form.cleaned_data[
                    'maximumNitrogenAtoms']
            self.rmg.speciesConstraints[
                'maximumSiliconAtoms'] = form.cleaned_data[
                    'maximumSiliconAtoms']
            self.rmg.speciesConstraints[
                'maximumSulfurAtoms'] = form.cleaned_data['maximumSulfurAtoms']
            self.rmg.speciesConstraints[
                'maximumHeavyAtoms'] = form.cleaned_data['maximumHeavyAtoms']
            self.rmg.speciesConstraints[
                'maximumRadicalElectrons'] = form.cleaned_data[
                    'maximumRadicalElectrons']
            self.rmg.speciesConstraints['allowSingletO2'] = form.cleaned_data[
                'allowSingletO2']

        # Quantum Calculations
        quantumCalc = form.cleaned_data['quantumCalc']
        if quantumCalc == 'on':
            from rmgpy.qm.main import QMCalculator
            self.rmg.quantumMechanics = QMCalculator(
                software=form.cleaned_data['software'].encode(),
                method=form.cleaned_data['method'].encode(),
                fileStore=form.cleaned_data['fileStore'].encode(),
                scratchDirectory=form.cleaned_data['scratchDirectory'].encode(
                ),
                onlyCyclics=form.cleaned_data['onlyCyclics'],
                maxRadicalNumber=form.cleaned_data['maxRadicalNumber'],
            )

        # Save the input.py file
        self.rmg.saveInput(self.savepath)
Beispiel #6
0
class Network(models.Model):
    """
    A Django model of a pressure-dependent reaction network.
    """
    id = models.CharField(max_length=32, primary_key=True, default=_createId)
    title = models.CharField(max_length=50)
    input_file = models.FileField(upload_to=uploadTo, verbose_name='Input file')
    input_text = models.TextField(blank=True, verbose_name='')
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    def __init__(self, *args, **kwargs):
        super(Network, self).__init__(*args, **kwargs)
        self.pdep = None

    def getDirname(self):
        """
        Return the absolute path of the directory that the Network object uses
        to store files.
        """
        return os.path.join(settings.MEDIA_ROOT, 'pdep', 'networks', str(self.pk))

    def getInputFilename(self):
        """
        Return the absolute path of the input file.
        """
        return os.path.join(self.getDirname(), 'input.py')

    def getOutputFilename(self):
        """
        Return the absolute path of the output file.
        """
        return os.path.join(self.getDirname(), 'output.py')

    def getLogFilename(self):
        """
        Return the absolute path of the log file.
        """
        return os.path.join(self.getDirname(), 'arkane.log')

    def getSurfaceFilenamePNG(self):
        """
        Return the absolute path of the PES image file in PNG format.
        """
        return os.path.join(self.getDirname(), 'network.png')

    def getSurfaceFilenamePDF(self):
        """
        Return the absolute path of the PES image file in PDF format.
        """
        return os.path.join(self.getDirname(), 'network.pdf')

    def getSurfaceFilenameSVG(self):
        """
        Return the absolute path of the PES image file in SVG format.
        """
        return os.path.join(self.getDirname(), 'network.svg')

    def getLastModifiedDate(self):
        """
        Return the date on which the network was most recently modified.
        """
        if not self.inputFileExists():
            return 'unknown'

        mtime = os.path.getmtime(self.getInputFilename())
        if self.outputFileExists():
            mtime0 = os.path.getmtime(self.getOutputFilename())
            if mtime < mtime0:
                mtime = mtime0
        if self.surfaceFilePDFExists():
            mtime0 = os.path.getmtime(self.getSurfaceFilenamePDF())
            if mtime < mtime0:
                mtime = mtime0
        if self.surfaceFilePNGExists():
            mtime0 = os.path.getmtime(self.getSurfaceFilenamePNG())
            if mtime < mtime0:
                mtime = mtime0
        if self.surfaceFileSVGExists():
            mtime0 = os.path.getmtime(self.getSurfaceFilenameSVG())
            if mtime < mtime0:
                mtime = mtime0

        gmtime = time.gmtime(mtime)
        return time.strftime("%d %b %Y", gmtime)

    def inputFileExists(self):
        """
        Return ``True`` if the input file exists on the server or ``False`` if
        not.
        """
        return os.path.exists(self.getInputFilename())

    def outputFileExists(self):
        """
        Return ``True`` if the output file exists on the server or ``False`` if
        not.
        """
        return os.path.exists(self.getOutputFilename())

    def logFileExists(self):
        """
        Return ``True`` if the log file exists on the server or ``False`` if
        not.
        """
        return os.path.exists(self.getLogFilename())

    def surfaceFilePNGExists(self):
        """
        Return ``True`` if a potential energy surface PNG image file exists or
        ``False`` if not.
        """
        return os.path.exists(self.getSurfaceFilenamePNG())

    def surfaceFilePDFExists(self):
        """
        Return ``True`` if a potential energy surface PDF image file exists or
        ``False`` if not.
        """
        return os.path.exists(self.getSurfaceFilenamePDF())

    def surfaceFileSVGExists(self):
        """
        Return ``True`` if a potential energy surface SVG image file exists or
        ``False`` if not.
        """
        return os.path.exists(self.getSurfaceFilenameSVG())

    def outputFileOutOfDate(self):
        """
        Return ``True`` if the output file is out of date or ``False`` if
        not.
        """
        return self.outputFileExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getOutputFilename())

    def surfaceFilePNGOutOfDate(self):
        """
        Return ``True`` if a potential energy surface PNG image file is out of
        date or ``False`` if not.
        """
        return self.surfaceFilePNGExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getSurfaceFilenamePNG())

    def surfaceFilePDFOutOfDate(self):
        """
        Return ``True`` if a potential energy surface PDF image file is out of
        date or ``False`` if not.
        """
        return self.surfaceFilePDFExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getSurfaceFilenamePDF())

    def surfaceFileSVGOutOfDate(self):
        """
        Return ``True`` if a potential energy surface SVG image file is out of
        date or ``False`` if not.
        """
        return self.surfaceFileSVGExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getSurfaceFilenameSVG())

    def createDir(self):
        """
        Create the directory (and any other needed parent directories) that
        the Network uses for storing files.
        """
        try:
            os.makedirs(self.getDirname())
        except OSError:
            # Fail silently on any OS errors
            pass

    def deleteInputFile(self):
        """
        Delete the input file for this network from the server.
        """
        if self.inputFileExists():
            os.remove(self.getInputFilename())

    def deleteOutputFile(self):
        """
        Delete the output file for this network from the server.
        """
        if self.outputFileExists():
            os.remove(self.getOutputFilename())

    def deleteSurfaceFilePNG(self):
        """
        Delete the PES image file in PNF format for this network from the
        server.
        """
        if os.path.exists(self.getSurfaceFilenamePNG()):
            os.remove(self.getSurfaceFilenamePNG())

    def deleteSurfaceFilePDF(self):
        """
        Delete the PES image file in PDF format for this network from the
        server.
        """
        if os.path.exists(self.getSurfaceFilenamePDF()):
            os.remove(self.getSurfaceFilenamePDF())

    def deleteSurfaceFileSVG(self):
        """
        Delete the PES image file in SVG format for this network from the
        server.
        """
        if os.path.exists(self.getSurfaceFilenameSVG()):
            os.remove(self.getSurfaceFilenameSVG())

    def loadInputText(self):
        """
        Load the input file text into the inputText field.
        """
        self.inputText = ''
        if self.inputFileExists():
            f = open(self.getInputFilename(), 'r')
            for line in f:
                self.inputText += line
            f.close()

    def saveInputText(self):
        """
        Save the contents of the inputText field to the input file.
        """
        f_path = self.getInputFilename()
        self.createDir()
        f = open(f_path, 'w')
        for line in self.inputText.splitlines():
            f.write(line + '\n')
        f.close()

    def load(self):
        """
        Load the contents of the input file into a PressureDependenceJob object.
        """
        from arkane.pdep import PressureDependenceJob
        from arkane.input import load_input_file

        # Seed with a PdepJob object
        if self.pdep is None:
            self.pdep = PressureDependenceJob(network=None)

            if self.inputFileExists():
                job_list = load_input_file(self.getInputFilename())[0]
                assert len(job_list) == 1
                job = job_list[0]
                if isinstance(job, PressureDependenceJob) is False:
                    raise Exception('Input file given did not provide a pressure dependence network.')
                self.pdep = job
                self.pdep.initialize()

            if self.pdep.network is not None:
                self.title = self.pdep.network.label
                self.save()

        return self.pdep.network
Beispiel #7
0
def loadFAMEInput(path, moleculeDict=None):
    """
    Load the contents of a FAME input file into the MEASURE object. FAME
    is an early version of MEASURE written in Fortran and used by RMG-Java.
    This script enables importing FAME input files into MEASURE so we can
    use the additional functionality that MEASURE provides. Note that it
    is mostly designed to load the FAME input files generated automatically
    by RMG-Java, and may not load hand-crafted FAME input files. If you
    specify a `moleculeDict`, then this script will use it to associate
    the species with their structures.
    """
    def readMeaningfulLine(f):
        line = f.readline()
        while line != '':
            line = line.strip()
            if len(line) > 0 and line[0] != '#':
                return line
            else:
                line = f.readline()
        return ''

    moleculeDict = moleculeDict or {}

    logging.info('Loading file "{0}"...'.format(path))
    f = open(path)

    job = PressureDependenceJob(network=None)

    # Read method
    method = readMeaningfulLine(f).lower()
    if method == 'modifiedstrongcollision':
        job.method = 'modified strong collision'
    elif method == 'reservoirstate':
        job.method = 'reservoir state'

    # Read temperatures
    Tcount, Tunits, Tmin, Tmax = readMeaningfulLine(f).split()
    job.Tmin = Quantity(float(Tmin), Tunits)
    job.Tmax = Quantity(float(Tmax), Tunits)
    job.Tcount = int(Tcount)
    Tlist = []
    for i in range(int(Tcount)):
        Tlist.append(float(readMeaningfulLine(f)))
    job.Tlist = Quantity(Tlist, Tunits)

    # Read pressures
    Pcount, Punits, Pmin, Pmax = readMeaningfulLine(f).split()
    job.Pmin = Quantity(float(Pmin), Punits)
    job.Pmax = Quantity(float(Pmax), Punits)
    job.Pcount = int(Pcount)
    Plist = []
    for i in range(int(Pcount)):
        Plist.append(float(readMeaningfulLine(f)))
    job.Plist = Quantity(Plist, Punits)

    # Read interpolation model
    model = readMeaningfulLine(f).split()
    if model[0].lower() == 'chebyshev':
        job.interpolationModel = ('chebyshev', int(model[1]), int(model[2]))
    elif model[0].lower() == 'pdeparrhenius':
        job.interpolationModel = ('pdeparrhenius', )

    # Read grain size or number of grains
    job.minimumGrainCount = 0
    job.maximumGrainSize = None
    for i in range(2):
        data = readMeaningfulLine(f).split()
        if data[0].lower() == 'numgrains':
            job.minimumGrainCount = int(data[1])
        elif data[0].lower() == 'grainsize':
            job.maximumGrainSize = (float(data[2]), data[1])

    # A FAME file is almost certainly created during an RMG job, so use RMG mode
    job.rmgmode = True

    # Create the Network
    job.network = Network()

    # Read collision model
    data = readMeaningfulLine(f)
    assert data.lower() == 'singleexpdown'
    alpha0units, alpha0 = readMeaningfulLine(f).split()
    T0units, T0 = readMeaningfulLine(f).split()
    n = readMeaningfulLine(f)
    energyTransferModel = SingleExponentialDown(
        alpha0=Quantity(float(alpha0), alpha0units),
        T0=Quantity(float(T0), T0units),
        n=float(n),
    )

    speciesDict = {}

    # Read bath gas parameters
    bathGas = Species(label='bath_gas',
                      energyTransferModel=energyTransferModel)
    molWtunits, molWt = readMeaningfulLine(f).split()
    if molWtunits == 'u': molWtunits = 'amu'
    bathGas.molecularWeight = Quantity(float(molWt), molWtunits)
    sigmaLJunits, sigmaLJ = readMeaningfulLine(f).split()
    epsilonLJunits, epsilonLJ = readMeaningfulLine(f).split()
    assert epsilonLJunits == 'J'
    bathGas.transportData = TransportData(
        sigma=Quantity(float(sigmaLJ), sigmaLJunits),
        epsilon=Quantity(float(epsilonLJ) / constants.kB, 'K'),
    )
    job.network.bathGas = {bathGas: 1.0}

    # Read species data
    Nspec = int(readMeaningfulLine(f))
    for i in range(Nspec):
        species = Species()
        species.conformer = Conformer()
        species.energyTransferModel = energyTransferModel

        # Read species label
        species.label = readMeaningfulLine(f)
        speciesDict[species.label] = species
        if species.label in moleculeDict:
            species.molecule = [moleculeDict[species.label]]

        # Read species E0
        E0units, E0 = readMeaningfulLine(f).split()
        species.conformer.E0 = Quantity(float(E0), E0units)
        species.conformer.E0.units = 'kJ/mol'

        # Read species thermo data
        H298units, H298 = readMeaningfulLine(f).split()
        S298units, S298 = readMeaningfulLine(f).split()
        Cpcount, Cpunits = readMeaningfulLine(f).split()
        Cpdata = []
        for i in range(int(Cpcount)):
            Cpdata.append(float(readMeaningfulLine(f)))
        if S298units == 'J/mol*K': S298units = 'J/(mol*K)'
        if Cpunits == 'J/mol*K': Cpunits = 'J/(mol*K)'
        species.thermo = ThermoData(
            H298=Quantity(float(H298), H298units),
            S298=Quantity(float(S298), S298units),
            Tdata=Quantity([300, 400, 500, 600, 800, 1000, 1500], "K"),
            Cpdata=Quantity(Cpdata, Cpunits),
            Cp0=(Cpdata[0], Cpunits),
            CpInf=(Cpdata[-1], Cpunits),
        )

        # Read species collision parameters
        molWtunits, molWt = readMeaningfulLine(f).split()
        if molWtunits == 'u': molWtunits = 'amu'
        species.molecularWeight = Quantity(float(molWt), molWtunits)
        sigmaLJunits, sigmaLJ = readMeaningfulLine(f).split()
        epsilonLJunits, epsilonLJ = readMeaningfulLine(f).split()
        assert epsilonLJunits == 'J'
        species.transportData = TransportData(
            sigma=Quantity(float(sigmaLJ), sigmaLJunits),
            epsilon=Quantity(float(epsilonLJ) / constants.kB, 'K'),
        )

        # Read species vibrational frequencies
        freqCount, freqUnits = readMeaningfulLine(f).split()
        frequencies = []
        for j in range(int(freqCount)):
            frequencies.append(float(readMeaningfulLine(f)))
        species.conformer.modes.append(
            HarmonicOscillator(frequencies=Quantity(frequencies, freqUnits), ))

        # Read species external rotors
        rotCount, rotUnits = readMeaningfulLine(f).split()
        if int(rotCount) > 0:
            raise NotImplementedError(
                'Cannot handle external rotational modes in FAME input.')

        # Read species internal rotors
        freqCount, freqUnits = readMeaningfulLine(f).split()
        frequencies = []
        for j in range(int(freqCount)):
            frequencies.append(float(readMeaningfulLine(f)))
        barrCount, barrUnits = readMeaningfulLine(f).split()
        barriers = []
        for j in range(int(barrCount)):
            barriers.append(float(readMeaningfulLine(f)))
        if barrUnits == 'cm^-1':
            barrUnits = 'J/mol'
            barriers = [
                barr * constants.h * constants.c * constants.Na * 100.
                for barr in barriers
            ]
        elif barrUnits in ['Hz', 's^-1']:
            barrUnits = 'J/mol'
            barriers = [barr * constants.h * constants.Na for barr in barriers]
        elif barrUnits != 'J/mol':
            raise Exception(
                'Unexpected units "{0}" for hindered rotor barrier height.'.
                format(barrUnits))
        inertia = [
            V0 / 2.0 / (nu * constants.c * 100.)**2 / constants.Na
            for nu, V0 in zip(frequencies, barriers)
        ]
        for I, V0 in zip(inertia, barriers):
            species.conformer.modes.append(
                HinderedRotor(
                    inertia=Quantity(I, "kg*m^2"),
                    barrier=Quantity(V0, barrUnits),
                    symmetry=1,
                    semiclassical=False,
                ))

        # Read overall symmetry number
        species.conformer.spinMultiplicity = int(readMeaningfulLine(f))

    # Read isomer, reactant channel, and product channel data
    Nisom = int(readMeaningfulLine(f))
    Nreac = int(readMeaningfulLine(f))
    Nprod = int(readMeaningfulLine(f))
    for i in range(Nisom):
        data = readMeaningfulLine(f).split()
        assert data[0] == '1'
        job.network.isomers.append(speciesDict[data[1]])
    for i in range(Nreac):
        data = readMeaningfulLine(f).split()
        assert data[0] == '2'
        job.network.reactants.append(
            [speciesDict[data[1]], speciesDict[data[2]]])
    for i in range(Nprod):
        data = readMeaningfulLine(f).split()
        if data[0] == '1':
            job.network.products.append([speciesDict[data[1]]])
        elif data[0] == '2':
            job.network.products.append(
                [speciesDict[data[1]], speciesDict[data[2]]])

    # Read path reactions
    Nrxn = int(readMeaningfulLine(f))
    for i in range(Nrxn):

        # Read and ignore reaction equation
        equation = readMeaningfulLine(f)
        reaction = Reaction(transitionState=TransitionState(), reversible=True)
        job.network.pathReactions.append(reaction)
        reaction.transitionState.conformer = Conformer()

        # Read reactant and product indices
        data = readMeaningfulLine(f).split()
        reac = int(data[0]) - 1
        prod = int(data[1]) - 1
        if reac < Nisom:
            reaction.reactants = [job.network.isomers[reac]]
        elif reac < Nisom + Nreac:
            reaction.reactants = job.network.reactants[reac - Nisom]
        else:
            reaction.reactants = job.network.products[reac - Nisom - Nreac]
        if prod < Nisom:
            reaction.products = [job.network.isomers[prod]]
        elif prod < Nisom + Nreac:
            reaction.products = job.network.reactants[prod - Nisom]
        else:
            reaction.products = job.network.products[prod - Nisom - Nreac]

        # Read reaction E0
        E0units, E0 = readMeaningfulLine(f).split()
        reaction.transitionState.conformer.E0 = Quantity(float(E0), E0units)
        reaction.transitionState.conformer.E0.units = 'kJ/mol'

        # Read high-pressure limit kinetics
        data = readMeaningfulLine(f)
        assert data.lower() == 'arrhenius'
        Aunits, A = readMeaningfulLine(f).split()
        if '/' in Aunits:
            index = Aunits.find('/')
            Aunits = '{0}/({1})'.format(Aunits[0:index], Aunits[index + 1:])
        Eaunits, Ea = readMeaningfulLine(f).split()
        n = readMeaningfulLine(f)
        reaction.kinetics = Arrhenius(
            A=Quantity(float(A), Aunits),
            Ea=Quantity(float(Ea), Eaunits),
            n=Quantity(float(n)),
        )
        reaction.kinetics.Ea.units = 'kJ/mol'

    f.close()

    job.network.isomers = [
        Configuration(isomer) for isomer in job.network.isomers
    ]
    job.network.reactants = [
        Configuration(*reactants) for reactants in job.network.reactants
    ]
    job.network.products = [
        Configuration(*products) for products in job.network.products
    ]

    return job
def loadFAMEInput(path, moleculeDict=None):
    """
    Load the contents of a FAME input file into the MEASURE object. FAME
    is an early version of MEASURE written in Fortran and used by RMG-Java.
    This script enables importing FAME input files into MEASURE so we can
    use the additional functionality that MEASURE provides. Note that it
    is mostly designed to load the FAME input files generated automatically
    by RMG-Java, and may not load hand-crafted FAME input files. If you
    specify a `moleculeDict`, then this script will use it to associate
    the species with their structures.
    """
    
    def readMeaningfulLine(f):
        line = f.readline()
        while line != '':
            line = line.strip()
            if len(line) > 0 and line[0] != '#':
                return line
            else:
                line = f.readline()
        return ''

    moleculeDict = moleculeDict or {}

    logging.info('Loading file "{0}"...'.format(path))
    f = open(path)

    job = PressureDependenceJob(network=None)
    
    # Read method
    method = readMeaningfulLine(f).lower()
    if method == 'modifiedstrongcollision': 
        job.method = 'modified strong collision'
    elif method == 'reservoirstate': 
        job.method = 'reservoir state'

    # Read temperatures
    Tcount, Tunits, Tmin, Tmax = readMeaningfulLine(f).split()
    job.Tmin = Quantity(float(Tmin), Tunits) 
    job.Tmax = Quantity(float(Tmax), Tunits)
    job.Tcount = int(Tcount)
    Tlist = []
    for i in range(int(Tcount)):
        Tlist.append(float(readMeaningfulLine(f)))
    job.Tlist = Quantity(Tlist, Tunits)
    
    # Read pressures
    Pcount, Punits, Pmin, Pmax = readMeaningfulLine(f).split()
    job.Pmin = Quantity(float(Pmin), Punits) 
    job.Pmax = Quantity(float(Pmax), Punits)
    job.Pcount = int(Pcount)
    Plist = []
    for i in range(int(Pcount)):
        Plist.append(float(readMeaningfulLine(f)))
    job.Plist = Quantity(Plist, Punits)
    
    # Read interpolation model
    model = readMeaningfulLine(f).split()
    if model[0].lower() == 'chebyshev':
        job.interpolationModel = ('chebyshev', int(model[1]), int(model[2]))
    elif model[0].lower() == 'pdeparrhenius':
        job.interpolationModel = ('pdeparrhenius',)
    
    # Read grain size or number of grains
    job.minimumGrainCount = 0
    job.maximumGrainSize = None
    for i in range(2):
        data = readMeaningfulLine(f).split()
        if data[0].lower() == 'numgrains':
            job.minimumGrainCount = int(data[1])
        elif data[0].lower() == 'grainsize':
            job.maximumGrainSize = (float(data[2]), data[1])

    # A FAME file is almost certainly created during an RMG job, so use RMG mode
    job.rmgmode = True

    # Create the Network
    job.network = Network()

    # Read collision model
    data = readMeaningfulLine(f)
    assert data.lower() == 'singleexpdown'
    alpha0units, alpha0 = readMeaningfulLine(f).split()
    T0units, T0 = readMeaningfulLine(f).split()
    n = readMeaningfulLine(f)
    energyTransferModel = SingleExponentialDown(
        alpha0 = Quantity(float(alpha0), alpha0units),
        T0 = Quantity(float(T0), T0units),
        n = float(n),
    )
    
    speciesDict = {}

    # Read bath gas parameters
    bathGas = Species(label='bath_gas', energyTransferModel=energyTransferModel)
    molWtunits, molWt = readMeaningfulLine(f).split()
    if molWtunits == 'u': molWtunits = 'amu'
    bathGas.molecularWeight = Quantity(float(molWt), molWtunits)
    sigmaLJunits, sigmaLJ = readMeaningfulLine(f).split()
    epsilonLJunits, epsilonLJ = readMeaningfulLine(f).split()
    assert epsilonLJunits == 'J'
    bathGas.transportData = TransportData(
        sigma = Quantity(float(sigmaLJ), sigmaLJunits),
        epsilon = Quantity(float(epsilonLJ) / constants.kB, 'K'),
    )
    job.network.bathGas = {bathGas: 1.0}
    
    # Read species data
    Nspec = int(readMeaningfulLine(f))
    for i in range(Nspec):
        species = Species()
        species.conformer = Conformer()
        species.energyTransferModel = energyTransferModel
        
        # Read species label
        species.label = readMeaningfulLine(f)
        speciesDict[species.label] = species
        if species.label in moleculeDict:
            species.molecule = [moleculeDict[species.label]]
        
        # Read species E0
        E0units, E0 = readMeaningfulLine(f).split()
        species.conformer.E0 = Quantity(float(E0), E0units)
        species.conformer.E0.units = 'kJ/mol'
        
        # Read species thermo data
        H298units, H298 = readMeaningfulLine(f).split()
        S298units, S298 = readMeaningfulLine(f).split()
        Cpcount, Cpunits = readMeaningfulLine(f).split()
        Cpdata = []
        for i in range(int(Cpcount)):
            Cpdata.append(float(readMeaningfulLine(f)))
        if S298units == 'J/mol*K': S298units = 'J/(mol*K)'
        if Cpunits == 'J/mol*K': Cpunits = 'J/(mol*K)'
        species.thermo = ThermoData(
            H298 = Quantity(float(H298), H298units),
            S298 = Quantity(float(S298), S298units),
            Tdata = Quantity([300,400,500,600,800,1000,1500], "K"),
            Cpdata = Quantity(Cpdata, Cpunits),
            Cp0 = (Cpdata[0], Cpunits),
            CpInf = (Cpdata[-1], Cpunits),
        )
        
        # Read species collision parameters
        molWtunits, molWt = readMeaningfulLine(f).split()
        if molWtunits == 'u': molWtunits = 'amu'
        species.molecularWeight = Quantity(float(molWt), molWtunits)
        sigmaLJunits, sigmaLJ = readMeaningfulLine(f).split()
        epsilonLJunits, epsilonLJ = readMeaningfulLine(f).split()
        assert epsilonLJunits == 'J'
        species.transportData = TransportData(
            sigma = Quantity(float(sigmaLJ), sigmaLJunits),
            epsilon = Quantity(float(epsilonLJ) / constants.kB, 'K'),
        )
        
        # Read species vibrational frequencies
        freqCount, freqUnits = readMeaningfulLine(f).split()
        frequencies = []
        for j in range(int(freqCount)):
            frequencies.append(float(readMeaningfulLine(f)))
        species.conformer.modes.append(HarmonicOscillator(
            frequencies = Quantity(frequencies, freqUnits),
        ))
        
        # Read species external rotors
        rotCount, rotUnits = readMeaningfulLine(f).split()
        if int(rotCount) > 0:
            raise NotImplementedError('Cannot handle external rotational modes in FAME input.')
        
        # Read species internal rotors
        freqCount, freqUnits = readMeaningfulLine(f).split()
        frequencies = []
        for j in range(int(freqCount)):
            frequencies.append(float(readMeaningfulLine(f)))
        barrCount, barrUnits = readMeaningfulLine(f).split()
        barriers = []
        for j in range(int(barrCount)):
            barriers.append(float(readMeaningfulLine(f)))
        if barrUnits == 'cm^-1':
            barrUnits = 'J/mol'
            barriers = [barr * constants.h * constants.c * constants.Na * 100. for barr in barriers]
        elif barrUnits in ['Hz', 's^-1']:
            barrUnits = 'J/mol'
            barriers = [barr * constants.h * constants.Na for barr in barriers]
        elif barrUnits != 'J/mol':
            raise Exception('Unexpected units "{0}" for hindered rotor barrier height.'.format(barrUnits))
        inertia = [V0 / 2.0 / (nu * constants.c * 100.)**2 / constants.Na for nu, V0 in zip(frequencies, barriers)]
        for I, V0 in zip(inertia, barriers):
            species.conformer.modes.append(HinderedRotor(
                inertia = Quantity(I,"kg*m^2"), 
                barrier = Quantity(V0,barrUnits), 
                symmetry = 1,
                semiclassical = False,
            ))
            
        # Read overall symmetry number
        species.conformer.spinMultiplicity = int(readMeaningfulLine(f))
        
    # Read isomer, reactant channel, and product channel data
    Nisom = int(readMeaningfulLine(f))
    Nreac = int(readMeaningfulLine(f))
    Nprod = int(readMeaningfulLine(f))
    for i in range(Nisom):
        data = readMeaningfulLine(f).split()
        assert data[0] == '1'
        job.network.isomers.append(speciesDict[data[1]])
    for i in range(Nreac):
        data = readMeaningfulLine(f).split()
        assert data[0] == '2'
        job.network.reactants.append([speciesDict[data[1]], speciesDict[data[2]]])
    for i in range(Nprod):
        data = readMeaningfulLine(f).split()
        if data[0] == '1':
            job.network.products.append([speciesDict[data[1]]])
        elif data[0] == '2':
            job.network.products.append([speciesDict[data[1]], speciesDict[data[2]]])

    # Read path reactions
    Nrxn = int(readMeaningfulLine(f))
    for i in range(Nrxn):
        
        # Read and ignore reaction equation
        equation = readMeaningfulLine(f)
        reaction = Reaction(transitionState=TransitionState(), reversible=True)
        job.network.pathReactions.append(reaction)
        reaction.transitionState.conformer = Conformer()
        
        # Read reactant and product indices
        data = readMeaningfulLine(f).split()
        reac = int(data[0]) - 1
        prod = int(data[1]) - 1
        if reac < Nisom:
            reaction.reactants = [job.network.isomers[reac]]
        elif reac < Nisom+Nreac:
            reaction.reactants = job.network.reactants[reac-Nisom]
        else:
            reaction.reactants = job.network.products[reac-Nisom-Nreac]
        if prod < Nisom:
            reaction.products = [job.network.isomers[prod]]
        elif prod < Nisom+Nreac:
            reaction.products = job.network.reactants[prod-Nisom]
        else:
            reaction.products = job.network.products[prod-Nisom-Nreac]
        
        # Read reaction E0
        E0units, E0 = readMeaningfulLine(f).split()
        reaction.transitionState.conformer.E0 = Quantity(float(E0), E0units)
        reaction.transitionState.conformer.E0.units = 'kJ/mol'
        
        # Read high-pressure limit kinetics
        data = readMeaningfulLine(f)
        assert data.lower() == 'arrhenius'
        Aunits, A = readMeaningfulLine(f).split()
        if '/' in Aunits:
            index = Aunits.find('/')
            Aunits = '{0}/({1})'.format(Aunits[0:index], Aunits[index+1:])
        Eaunits, Ea = readMeaningfulLine(f).split()
        n = readMeaningfulLine(f)
        reaction.kinetics = Arrhenius(
            A = Quantity(float(A), Aunits),
            Ea = Quantity(float(Ea), Eaunits),
            n = Quantity(float(n)),
        )
        reaction.kinetics.Ea.units = 'kJ/mol'

    f.close()
    
    job.network.isomers = [Configuration(isomer) for isomer in job.network.isomers]
    job.network.reactants = [Configuration(*reactants) for reactants in job.network.reactants]
    job.network.products = [Configuration(*products) for products in job.network.products]

    return job
class Network(models.Model):
    """
    A Django model of a pressure-dependent reaction network. 
    """
    id = models.CharField(max_length=32, primary_key=True, default=_createId)
    title = models.CharField(max_length=50)
    inputFile = models.FileField(upload_to=uploadTo, verbose_name='Input file')
    inputText = models.TextField(blank=True, verbose_name='')
    user = models.ForeignKey(User)

    def __init__(self, *args, **kwargs):
        super(Network, self).__init__(*args, **kwargs)
        self.pdep = None

    def getDirname(self):
        """
        Return the absolute path of the directory that the Network object uses
        to store files.
        """
        return os.path.join(settings.MEDIA_ROOT, 'pdep', 'networks', str(self.pk))
    
    def getInputFilename(self):
        """
        Return the absolute path of the input file.
        """
        return os.path.join(self.getDirname(), 'input.py')
    
    def getOutputFilename(self):
        """
        Return the absolute path of the output file.
        """
        return os.path.join(self.getDirname(), 'output.py')
    
    def getLogFilename(self):
        """
        Return the absolute path of the log file.
        """
        return os.path.join(self.getDirname(), 'arkane.log')
    
    def getSurfaceFilenamePNG(self):
        """
        Return the absolute path of the PES image file in PNG format.
        """
        return os.path.join(self.getDirname(), 'network.png')
    
    def getSurfaceFilenamePDF(self):
        """
        Return the absolute path of the PES image file in PDF format.
        """
        return os.path.join(self.getDirname(), 'network.pdf')
    
    def getSurfaceFilenameSVG(self):
        """
        Return the absolute path of the PES image file in SVG format.
        """
        return os.path.join(self.getDirname(), 'network.svg')
    
    def getLastModifiedDate(self):
        """
        Return the date on which the network was most recently modified.
        """
        if not self.inputFileExists(): return 'unknown'
        
        mtime = os.path.getmtime(self.getInputFilename())
        if self.outputFileExists():
            mtime0 = os.path.getmtime(self.getOutputFilename())
            if mtime < mtime0: mtime = mtime0
        if self.surfaceFilePDFExists():
            mtime0 = os.path.getmtime(self.getSurfaceFilenamePDF())
            if mtime < mtime0: mtime = mtime0
        if self.surfaceFilePNGExists():
            mtime0 = os.path.getmtime(self.getSurfaceFilenamePNG())
            if mtime < mtime0: mtime = mtime0
        if self.surfaceFileSVGExists():
            mtime0 = os.path.getmtime(self.getSurfaceFilenameSVG())
            if mtime < mtime0: mtime = mtime0
        
        gmtime = time.gmtime(mtime)
        return time.strftime("%d %b %Y", gmtime)
        
    def inputFileExists(self):
        """
        Return ``True`` if the input file exists on the server or ``False`` if
        not.
        """
        return os.path.exists(self.getInputFilename())
        
    def outputFileExists(self):
        """
        Return ``True`` if the output file exists on the server or ``False`` if
        not.
        """
        return os.path.exists(self.getOutputFilename())
        
    def logFileExists(self):
        """
        Return ``True`` if the log file exists on the server or ``False`` if
        not.
        """
        return os.path.exists(self.getLogFilename())
        
    def surfaceFilePNGExists(self):
        """
        Return ``True`` if a potential energy surface PNG image file exists or
        ``False`` if not.
        """
        return os.path.exists(self.getSurfaceFilenamePNG())
        
    def surfaceFilePDFExists(self):
        """
        Return ``True`` if a potential energy surface PDF image file exists or
        ``False`` if not.
        """
        return os.path.exists(self.getSurfaceFilenamePDF())
        
    def surfaceFileSVGExists(self):
        """
        Return ``True`` if a potential energy surface SVG image file exists or
        ``False`` if not.
        """
        return os.path.exists(self.getSurfaceFilenameSVG())
        
    def outputFileOutOfDate(self):
        """
        Return ``True`` if the output file is out of date or ``False`` if
        not.
        """
        return self.outputFileExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getOutputFilename())
        
    def surfaceFilePNGOutOfDate(self):
        """
        Return ``True`` if a potential energy surface PNG image file is out of 
        date or ``False`` if not.
        """
        return self.surfaceFilePNGExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getSurfaceFilenamePNG())
        
    def surfaceFilePDFOutOfDate(self):
        """
        Return ``True`` if a potential energy surface PDF image file is out of
        date or ``False`` if not.
        """
        return self.surfaceFilePDFExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getSurfaceFilenamePDF())
        
    def surfaceFileSVGOutOfDate(self):
        """
        Return ``True`` if a potential energy surface SVG image file is out of
        date or ``False`` if not.
        """
        return self.surfaceFileSVGExists() and os.path.getmtime(self.getInputFilename()) > os.path.getmtime(self.getSurfaceFilenameSVG())
        
    def createDir(self):
        """
        Create the directory (and any other needed parent directories) that
        the Network uses for storing files.
        """
        try:
            os.makedirs(self.getDirname())
        except OSError:
            # Fail silently on any OS errors
            pass
        
    def deleteInputFile(self):
        """
        Delete the input file for this network from the server.
        """
        if self.inputFileExists():
            os.remove(self.getInputFilename())
        
    def deleteOutputFile(self):
        """
        Delete the output file for this network from the server.
        """
        if self.outputFileExists():
            os.remove(self.getOutputFilename())
        
    def deleteSurfaceFilePNG(self):
        """
        Delete the PES image file in PNF format for this network from the 
        server.
        """
        if os.path.exists(self.getSurfaceFilenamePNG()):
            os.remove(self.getSurfaceFilenamePNG())
        
    def deleteSurfaceFilePDF(self):
        """
        Delete the PES image file in PDF format for this network from the 
        server.
        """
        if os.path.exists(self.getSurfaceFilenamePDF()):
            os.remove(self.getSurfaceFilenamePDF())
        
    def deleteSurfaceFileSVG(self):
        """
        Delete the PES image file in SVG format for this network from the 
        server.
        """
        if os.path.exists(self.getSurfaceFilenameSVG()):
            os.remove(self.getSurfaceFilenameSVG())
        
    def loadInputText(self):
        """
        Load the input file text into the inputText field.
        """
        self.inputText = ''
        if self.inputFileExists():
            f = open(self.getInputFilename(),'r')
            for line in f:
                self.inputText += line
            f.close()
        
    def saveInputText(self):
        """
        Save the contents of the inputText field to the input file.
        """
        fpath = self.getInputFilename()
        self.createDir()
        f = open(fpath,'w')
        for line in self.inputText.splitlines():
            f.write(line + '\n')
        f.close()
    
    def load(self):
        """
        Load the contents of the input file into a PressureDependenceJob object.
        """
        from arkane.pdep import PressureDependenceJob
        from arkane.input import loadInputFile
        
        # Seed with a PdepJob object
        if self.pdep is None:
            self.pdep = PressureDependenceJob(network=None)
            
            if self.inputFileExists():
                jobList = loadInputFile(self.getInputFilename())[0]
                assert len(jobList) == 1
                job = jobList[0]
                if isinstance(job, PressureDependenceJob) is False:
                    raise Exception('Input file given did not provide a pressure dependence network.')
                self.pdep = job 
                self.pdep.initialize()
        
            if self.pdep.network is not None:
                self.title = self.pdep.network.label
                self.save()
        
        return self.pdep.network