text:
"""Recognition functions for sentences using JSGF graphs."""
import base64
import itertools
import random
import time
import typing
from collections import defaultdict
from dataclasses import dataclass, field
from datetime import datetime

import networkx as nx

from .intent import Entity, Intent, Recognition, RecognitionResult
from .jsgf_graph import get_start_end_nodes
from .utils import pairwise

# -----------------------------------------------------------------------------

PathNodeType = typing.Union[int, typing.Tuple[int, typing.List[str]]]
PathType = typing.List[PathNodeType]

def recognize(
    tokens: typing.Union[str, typing.List[str]],
    graph: nx.DiGraph,
    fuzzy: bool = True,
    stop_words: typing.Optional[typing.Set[str]] = None,
    intent_filter: typing.Optional[typing.Callable[[str], bool]] = None,
    word_transform: typing.Optional[typing.Callable[[str], str]] = None,
    converters: typing.Optional[
        typing.Dict[str, typing.Callable[..., typing.Any]]
    ] = None,
    extra_converters: typing.Optional[
        typing.Dict[str, typing.Callable[..., typing.Any]]
    ] = None,
    **search_args,
) -> typing.List[Recognition]:
    """Recognize one or more intents from tokens or a sentence."""
    start_time = time.perf_counter()

    if isinstance(tokens, str):
        # Assume whitespace separation
        tokens = tokens.split()

    if fuzzy:
        # Fuzzy recognition
        best_fuzzy = best_fuzzy_cost(
            paths_fuzzy(
                tokens,
                graph,
                stop_words=stop_words,
                intent_filter=intent_filter,
                word_transform=word_transform,
                **search_args,
            )
        )

        end_time = time.perf_counter()

        if best_fuzzy:
            recognitions = []

            # Gather all successful fuzzy paths
            for fuzzy_result in best_fuzzy:
                result, recognition = path_to_recognition(
                    fuzzy_result.node_path,
                    graph,
                    cost=fuzzy_result.cost,
                    converters=converters,
                    extra_converters=extra_converters,
                )
                if result == RecognitionResult.SUCCESS:
                    assert recognition is not None
                    recognition.recognize_seconds = end_time - start_time
                    recognitions.append(recognition)

            return recognitions
    else:
        # Strict recognition
        paths = list(
            paths_strict(
                tokens,
                graph,
                intent_filter=intent_filter,
                word_transform=word_transform,
                **search_args,
            )
        )
        if (not paths) and stop_words:
            # Try again by excluding stop words
            tokens = [t for t in tokens if t not in stop_words]
            paths = list(
                paths_strict(
                    tokens,
                    graph,
                    exclude_tokens=stop_words,
                    intent_filter=intent_filter,
                    word_transform=word_transform,
                    **search_args,
                )
            )

        end_time = time.perf_counter()
        recognitions = []
        for path in paths:
            result, recognition = path_to_recognition(
                path, graph, converters=converters, extra_converters=extra_converters
            )
            if result == RecognitionResult.SUCCESS:
                assert recognition is not None
                recognition.recognize_seconds = end_time - start_time
                recognitions.append(recognition)

        return recognitions

    # No results
    return []

# -----------------------------------------------------------------------------

def paths_strict(
    tokens: typing.List[str],
    graph: nx.DiGraph,
    exclude_tokens: typing.Optional[typing.Set[str]] = None,
    max_paths: typing.Optional[int] = None,
    intent_filter: typing.Optional[typing.Callable[[str], bool]] = None,
    word_transform: typing.Optional[typing.Callable[[str], str]] = None,
) -> typing.Iterable[PathType]:
    """Match a single path from the graph exactly if possible."""
    if not tokens:
        return []

    intent_filter = intent_filter or (lambda x: True)
    word_transform = word_transform or (lambda x: x)

    # node -> attrs
    n_data = graph.nodes(data=True)

    # start state
    start_node, _ = get_start_end_nodes(graph)
    assert start_node is not None

    # Number of matching paths found
    paths_found: int = 0

    # Do breadth-first search.
    # Queue contains items of the form:
    # * current node (int)
    # * current path (int, str?) - node, matching input token
    # * remaining input tokens
    node_queue: typing.List[typing.Tuple[int, PathType, typing.List[str]]] = [
        (start_node, [], tokens)
    ]

    while node_queue:
        current_node, current_path, current_tokens = node_queue.pop(0)
        is_final = n_data[current_node].get("final", False)
        if is_final and (not current_tokens):
            # Reached final state
            paths_found += 1
            yield current_path

            if max_paths and (paths_found >= max_paths):
                break

        for next_node, edge_data in graph[current_node].items():
            next_path = list(current_path)
            next_tokens = list(current_tokens)

            ilabel = edge_data.get("ilabel", "")
            olabel = edge_data.get("olabel", "")
            matching_tokens: typing.List[str] = []

            if olabel[:9] == "__label__":
                intent_name = olabel[9:]
                if not intent_filter(intent_name):
                    # Skip intent
                    continue

            if ilabel:
                ilabel = word_transform(ilabel)

                if next_tokens:
                    # Failed to match input label
                    if ilabel != word_transform(next_tokens[0]):
                        if (not exclude_tokens) or (ilabel not in exclude_tokens):
                            # Can't exclude
                            continue
                    else:
                        # Token match
                        matching_token = next_tokens.pop(0)
                        matching_tokens.append(matching_token)
                else:
                    # Ran out of tokens
                    continue

            next_path.append((current_node, matching_tokens))

            # Continue search
            node_queue.append((next_node, next_path, next_tokens))

    # No results
    return []

# -----------------------------------------------------------------------------

@dataclass
class FuzzyResult:
    """Single path for fuzzy recognition."""

    intent_name: str
    node_path: PathType
    cost: float

@dataclass
class FuzzyCostInput:
    """Input to fuzzy cost function."""

    ilabel: str
    tokens: typing.List[str]
    stop_words: typing.Set[str]
    word_transform: typing.Optional[typing.Callable[[str], str]] = None

@dataclass
class FuzzyCostOutput:
    """Output from fuzzy cost function."""

    cost: float
    continue_search: bool = True
    matching_tokens: typing.List[str] = field(default_factory=list)

def default_fuzzy_cost(cost_input: FuzzyCostInput) -> FuzzyCostOutput:
    """Increases cost when input tokens fail to match graph. Marginal cost for stop words."""
    ilabel = cost_input.ilabel
    cost = 0.0
    tokens = cost_input.tokens
    stop_words = cost_input.stop_words
    word_transform = cost_input.word_transform or (lambda x: x)
    matching_tokens: typing.List[str] = []

    if ilabel:
        ilabel = word_transform(ilabel)
        while tokens and (ilabel != word_transform(tokens[0])):
            bad_token = word_transform(tokens.pop(0))
            if bad_token in stop_words:
                # Marginal cost to ensure paths matching stop words are preferred
                cost += 0.1
            else:
                # Mismatched token
                cost += 1

        if tokens and (ilabel == word_transform(tokens[0])):
            # Consume matching token
            matching_token = tokens.pop(0)
            matching_tokens.append(matching_token)
        else:
            # No matching token
            return FuzzyCostOutput(cost=cost, continue_search=False)

    return FuzzyCostOutput(cost=cost, matching_tokens=matching_tokens)

def paths_fuzzy(
    tokens: typing.List[str],
    graph: nx.DiGraph,
    stop_words: typing.Optional[typing.Set[str]] = None,
    cost_function: typing.Optional[
        typing.Callable[[FuzzyCostInput], FuzzyCostOutput]
    ] = None,
    intent_filter: typing.Optional[typing.Callable[[str], bool]] = None,
    word_transform: typing.Optional[typing.Callable[[str], str]] = None,
) -> typing.Dict[str, typing.List[FuzzyResult]]:
    """Do less strict matching using a cost function and optional stop words."""
    if not tokens:
        return {}

    intent_filter = intent_filter or (lambda x: True)
    cost_function = cost_function or default_fuzzy_cost
    stop_words = stop_words or set()

    # node -> attrs
    n_data = graph.nodes(data=True)

    # start state
    start_node: int = next(n for n, data in n_data if data.get("start"))

    # intent -> [(symbols, cost), (symbols, cost)...]
    intent_symbols_and_costs: typing.Dict[str, typing.List[FuzzyResult]] = defaultdict(
        list
    )

    # Lowest cost so far
    best_cost: float = float(len(n_data))

    # (node, in_tokens, out_path, out_count, cost, intent_name)
    node_queue: typing.List[
        typing.Tuple[int, typing.List[str], PathType, int, float, typing.Optional[str]]
    ] = [(start_node, tokens, [], 0, 0.0, None)]

    # BFS it up
    while node_queue:
        (
            q_node,
            q_in_tokens,
            q_out_path,
            q_out_count,
            q_cost,
            q_intent,
        ) = node_queue.pop(0)
        is_final: bool = n_data[q_node].get("final", False)

        # Update best intent cost on final state.
        # Don't bother reporting intents that failed to consume any tokens.
        if is_final and (q_cost < q_out_count):
            q_intent = q_intent or ""
            best_intent_cost: typing.Optional[float] = None
            best_intent_costs = intent_symbols_and_costs.get(q_intent)
            if best_intent_costs:
                best_intent_cost = best_intent_costs[0].cost

            final_cost = q_cost + len(q_in_tokens)  # remaning tokens count against
            final_path = q_out_path

            if (best_intent_cost is None) or (final_cost < best_intent_cost):
                # Overwrite best cost
                intent_symbols_and_costs[q_intent] = [
                    FuzzyResult(
                        intent_name=q_intent, node_path=final_path, cost=final_cost
                    )
                ]
            elif final_cost == best_intent_cost:
                # Add to existing list
                intent_symbols_and_costs[q_intent].append(
                    (
                        FuzzyResult(
                            intent_name=q_intent, node_path=final_path, cost=final_cost
                        )
                    )
                )

            if final_cost < best_cost:
                # Update best cost so far
                best_cost = final_cost

        if q_cost > best_cost:
            # Can't get any better
            continue

        # Process child edges
        for next_node, edge_data in graph[q_node].items():
            in_label = edge_data.get("ilabel") or ""
            out_label = edge_data.get("olabel") or ""
            next_in_tokens = list(q_in_tokens)
            next_out_path = list(q_out_path)
            next_out_count = q_out_count
            next_cost = q_cost
            next_intent = q_intent

            if out_label:
                if out_label[:9] == "__label__":
                    next_intent = out_label[9:]
                    if not intent_filter(next_intent):
                        # Skip intent
                        continue
                elif out_label[:2] != "__":
                    next_out_count += 1

            cost_output = cost_function(
                FuzzyCostInput(
                    ilabel=in_label,
                    tokens=next_in_tokens,
                    stop_words=stop_words,
                    word_transform=word_transform,
                )
            )

            next_cost += cost_output.cost

            if not cost_output.continue_search:
                continue

            # Extend current path
            next_out_path.append((q_node, cost_output.matching_tokens))

            node_queue.append(
                (
                    next_node,
                    next_in_tokens,
                    next_out_path,
                    next_out_count,
                    next_cost,
                    next_intent,
                )
            )

    return intent_symbols_and_costs

def best_fuzzy_cost(
    intent_symbols_and_costs: typing.Dict[str, typing.List[FuzzyResult]]
) -> typing.List[FuzzyResult]:
    """Return fuzzy results with cost."""
    if not intent_symbols_and_costs:
        return []

    best_cost: typing.Optional[float] = None
    best_results: typing.List[FuzzyResult] = []

    # Find all results with the lowest cost
    for fuzzy_results in intent_symbols_and_costs.values():
        if not fuzzy_results:
            continue

        # All results for a given intent should have the same cost
        if best_cost is None:
            # First result
            best_cost = fuzzy_results[0].cost
            best_results = list(fuzzy_results)
        elif fuzzy_results[0].cost < best_cost:
            # Overwrite
            best_results = list(fuzzy_results)
        elif fuzzy_results[0].cost == best_cost:
            # Add to list
            best_results.extend(fuzzy_results)

    return best_results

# -----------------------------------------------------------------------------

@dataclass
class ConverterInfo:
    """Local info for converter stack in path_to_recognition"""

    # Name + args
    key: str

    # Name of converter
    name: str

    # Optional arguments passed using name,arg1,arg2,...
    args: typing.Optional[typing.List[str]] = None

    # List of raw/substituted tokens
    tokens: typing.List[typing.Tuple[str, str, typing.List[str]]] = field(
        default_factory=list
    )

def path_to_recognition(
    node_path: typing.Iterable[PathNodeType],
    graph: nx.DiGraph,
    cost: typing.Optional[float] = None,
    converters: typing.Optional[
        typing.Dict[str, typing.Callable[..., typing.Any]]
    ] = None,
    extra_converters: typing.Optional[
        typing.Dict[str, typing.Callable[..., typing.Any]]
    ] = None,
) -> typing.Tuple[RecognitionResult, typing.Optional[Recognition]]:
    """Transform node path in graph to an intent recognition object."""
    if not node_path:
        # Empty path indicates failure
        return RecognitionResult.FAILURE, None

    converters = converters or get_default_converters()
    if extra_converters:
        # Merge in extra converters
        converters.update(extra_converters)

    node_attrs = graph.nodes(data=True)
    recognition = Recognition(intent=Intent("", confidence=1.0))

    # Step 1: go through path pairwise and gather input/output labels
    raw_sub_tokens: typing.List[typing.Tuple[str, str, typing.List[str]]] = []

    for last_node_tokens, next_node_tokens in pairwise(node_path):
        # Unpack path nodes
        if isinstance(last_node_tokens, int):
            last_node = last_node_tokens
            last_tokens = []
        else:
            last_node, last_tokens = last_node_tokens

        if isinstance(next_node_tokens, int):
            next_node = next_node_tokens
        else:
            next_node, _ = next_node_tokens

        # Get raw text
        word = node_attrs[next_node].get("word") or ""

        # Get output label
        edge_data = graph[last_node][next_node]
        olabel = edge_data.get("olabel") or ""

        if olabel[:10] == "__unpack__":
            # Decode payload as base64-encoded bytestring
            olabel = base64.decodebytes(olabel[10:].encode()).decode()

        if olabel[:9] == "__label__":
            # Intent name
            assert recognition.intent is not None
            recognition.intent.name = olabel[9:]
        elif word or olabel:
            # Keep non-empty words
            raw_sub_tokens.append((word, olabel, last_tokens))

    # Step 2: apply converters
    converter_stack: typing.List[ConverterInfo] = []
    raw_conv_tokens: typing.List[typing.Tuple[str, typing.Any, typing.List[str]]] = []

    for raw_token, sub_token, original_tokens in raw_sub_tokens:
        if sub_token and converter_stack and (sub_token[:2] != "__"):
            # Add to existing converter
            converter_stack[-1].tokens.append((raw_token, sub_token, original_tokens))
        elif sub_token[:11] == "__convert__":
            # Begin converter
            converter_key = sub_token[11:]
            converter_name = converter_key
            converter_args: typing.Optional[typing.List[str]] = None

            # Detect arguments
            if "," in converter_name:
                converter_name, *converter_args = converter_name.split(",")

            converter_stack.append(
                ConverterInfo(
                    key=converter_key, name=converter_name, args=converter_args
                )
            )
        elif sub_token[:13] == "__converted__":
            # End converter
            assert converter_stack, "Found __converted__ without a __convert__"
            last_converter = converter_stack.pop()
            actual_key = sub_token[13:]
            assert (
                last_converter.key == actual_key
            ), f"Mismatched converter name (expected {last_converter.key}, got {actual_key})"

            # Convert and add directly
            raw_tokens: typing.List[str] = []
            sub_tokens: typing.List[typing.Any] = []
            orig_tokens: typing.List[typing.List[str]] = []

            for t in last_converter.tokens:
                if t[0]:
                    raw_tokens.append(t[0])

                # Value may be 0
                if t[1] not in {None, ""}:
                    sub_tokens.append(t[1])

                if t[2]:
                    orig_tokens.append(t[2])

            # Run substituted tokens through conversion function
            converter_func = converters[last_converter.name]

            # Pass arguments as keyword "converter_args"
            converter_kwargs = (
                {"converter_args": last_converter.args} if last_converter.args else {}
            )
            converted_tokens = converter_func(*sub_tokens, **converter_kwargs)

            if converter_stack:
                # Add to parent converter
                target_list = converter_stack[-1].tokens
            else:
                # Add directly to list
                target_list = raw_conv_tokens

            # Zip 'em up
            target_list.extend(
                itertools.zip_longest(
                    raw_tokens, converted_tokens, orig_tokens, fillvalue=""
                )
            )
        else:
            raw_conv_tokens.append((raw_token, sub_token, original_tokens))

    assert not converter_stack, f"Converter(s) remaining on stack ({converter_stack})"

    # Step 3: collect entities
    entity_stack: typing.List[Entity] = []
    raw_index = 0
    sub_index = 0

    for raw_token, conv_token, original_tokens in raw_conv_tokens:
        # Handle raw (input) token
        if original_tokens:
            # Use tokens from recognition string
            recognition.raw_tokens.extend(original_tokens)
            raw_index += sum(len(t) for t in original_tokens) + len(original_tokens)

            if entity_stack:
                last_entity = entity_stack[-1]
                last_entity.raw_tokens.extend(original_tokens)
        elif raw_token:
            # Use word itself
            recognition.raw_tokens.append(raw_token)
            raw_index += len(raw_token) + 1

            if entity_stack:
                last_entity = entity_stack[-1]
                last_entity.raw_tokens.append(raw_token)

        # Handle converted (output) token
        if conv_token is not None:
            conv_token_str = str(conv_token)
            if conv_token_str:
                if conv_token_str[:9] == "__begin__":
                    # Begin tag/entity
                    entity_name = conv_token[9:]
                    entity_stack.append(
                        Entity(
                            entity=entity_name,
                            value="",
                            start=sub_index,
                            raw_start=raw_index,
                        )
                    )
                elif conv_token_str[:7] == "__end__":
                    # End tag/entity
                    assert entity_stack, "Found __end__ without a __begin__"
                    last_entity = entity_stack.pop()
                    actual_name = conv_token[7:]
                    assert (
                        last_entity.entity == actual_name
                    ), "Mismatched entity name (expected {last_entity.entity}, got {actual_name})"

                    # Assign end indexes
                    last_entity.end = sub_index - 1
                    last_entity.raw_end = raw_index - 1

                    # Create values
                    if len(last_entity.tokens) == 1:
                        # Use Python object
                        last_entity.value = last_entity.tokens[0]
                    else:
                        # Join as string
                        last_entity.value = " ".join(str(t) for t in last_entity.tokens)

                    last_entity.raw_value = " ".join(last_entity.raw_tokens)

                    # Add to recognition
                    recognition.entities.append(last_entity)
                elif conv_token_str[:10] == "__source__":
                    if entity_stack:
                        last_entity = entity_stack[-1]
                        last_entity.source = conv_token_str[10:]
                elif entity_stack:
                    # Add to most recent named entity
                    last_entity = entity_stack[-1]
                    last_entity.tokens.append(conv_token)

                    recognition.tokens.append(conv_token)
                    sub_index += len(conv_token_str) + 1
                else:
                    # Substituted text
                    recognition.tokens.append(conv_token)
                    sub_index += len(conv_token_str) + 1

    # Step 4: create text fields and compute confidence
    recognition.text = " ".join(str(t) for t in recognition.tokens)
    recognition.raw_text = " ".join(recognition.raw_tokens)

    if cost and cost > 0:
        # Set fuzzy confidence
        assert recognition.intent is not None

        recognition.intent.confidence = 1.0 - float(cost / len(recognition.raw_tokens))

    return RecognitionResult.SUCCESS, recognition

# -----------------------------------------------------------------------------

def bool_converter(obj: typing.Any) -> bool:
    """Returns False if argument is 'false' string or zero."""
    return (obj != 0) and (str(obj).lower() != "false")

def get_default_converters() -> typing.Dict[str, typing.Callable[..., typing.Any]]:
    """Get built-in fsticuffs converters"""
    return {
        "int": lambda *args: map(int, args),
        "float": lambda *args: map(float, args),
        "bool": lambda *args: map(bool_converter, args),
        "lower": lambda *args: map(str.lower, args),
        "upper": lambda *args: map(str.upper, args),
        "object": lambda *args: [
            {"value": args[0] if len(args) == 1 else " ".join(str(a) for a in args)}
        ],
        "kind": lambda *args, converter_args=None: [
            {"kind": converter_args[0], **a} for a in args
        ],
        "unit": lambda *args, converter_args=None: [
            {"unit": converter_args[0], **a} for a in args
        ],
        "datetime": lambda *args, converter_args=None: [
            datetime.strptime(" ".join(str(a) for a in args), *(converter_args or []))
        ],
    }

# -----------------------------------------------------------------------------

def sample_by_intent(
    intent_graph: nx.DiGraph,
    num_samples: typing.Optional[int] = None,
    **recognition_args,
) -> typing.Dict[str, typing.List[Recognition]]:
    """Sample sentences from a graph."""

    sentences_by_intent: typing.Dict[str, typing.List[Recognition]] = defaultdict(list)

    start_node, end_node = get_start_end_nodes(intent_graph)
    assert (start_node is not None) and (
        end_node is not None
    ), "Missing start/end node(s)"

    if num_samples is not None:
        # Randomly sample
        paths = random.sample(
            list(nx.all_simple_paths(intent_graph, start_node, end_node)), num_samples
        )
    else:
        # Use generator
        paths = nx.all_simple_paths(intent_graph, start_node, end_node)

    for path in paths:
        _, recognition = path_to_recognition(path, intent_graph, **recognition_args)
        assert recognition, "Path failed"
        if recognition.intent:
            sentences_by_intent[recognition.intent.name].append(recognition)

    return sentences_by_intent

max_stars_repo_name: daniele-athome/rhasspy-nlu

max_issues_repo_name: daniele-athome/rhasspy-nlu

max_forks_repo_name: daniele-athome/rhasspy-nlu

reason: import networkx


text:
import torch
import torchvision
import matplotlib.pyplot as plt
import numpy as np
from torch import nn
from torch.autograd import Variable
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

torch.manual_seed(1)

#hyper params

EPOCH = 10
BATCH_SIZE = 64
LR =0.005
DOWNLOAD = False
N_TEST_IMG  =5

#data
trainData = torchvision.datasets.MNIST\
            (root = './mnist/',train = True,
             transform = torchvision.transforms.ToTensor(),
             download = DOWNLOAD)
trainLoader = torch.utils.data.DataLoader(dataset = trainData,
                                          batch_size=BATCH_SIZE,shuffle = True)

# plot an example
# print(trainData.train_data.size())
# print(trainData.train_labels.size())
# plt.imshow(trainData.train_data[2].numpy(),cmap = 'gray')
# plt.show()

class AutoEncoder(nn.Module):
    def __init__(self):
        super(AutoEncoder, self).__init__()
        self.encoder = nn.Sequential(
            nn.Linear(28*28,128),
            nn.Tanh(),
            nn.Linear(128,64),
            nn.Tanh(),
            nn.Linear(64,12),
            nn.Tanh(),
            nn.Linear(12,3)
        )
        self.decoder = nn.Sequential(
            nn.Linear(3,12),
            nn.Tanh(),
            nn.Linear(12,64),
            nn.Tanh(),
            nn.Linear(64,128),
            nn.Tanh(),
            nn.Linear(128,28*28),
            nn.Sigmoid()    # FORCE OUTPUT INTO (0,1)
        )

    def forward(self, x):
        encoded = self.encoder(x)
        decoded = self.decoder(encoded)
        return encoded,decoded  # decoded can be used as generated data

autoencoder = AutoEncoder()

optimizer = torch.optim.Adam(autoencoder.parameters(),lr = LR)
Loss = nn.MSELoss()

# initialize figure
f, a = plt.subplots(2, N_TEST_IMG, figsize=(5, 2))
plt.ion()   # continuously plot

# original data (first row) for viewing
view_data = trainData.train_data[:N_TEST_IMG].view(-1, 28*28).type(torch.FloatTensor)/255.
for i in range(N_TEST_IMG):
    a[0][i].imshow(np.reshape(view_data.data.numpy()[i], (28, 28)), cmap='gray'); a[0][i].set_xticks(()); a[0][i].set_yticks(())

for epoch in range(EPOCH):
    for step,(x,y) in enumerate(trainLoader):
        b_x = Variable(x.view(-1,28*28))
        b_y = Variable(x.view(-1,28*28))
        b_label = Variable(y)

        encoded, decoded = autoencoder(b_x)

        loss = Loss(decoded,b_y)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if step %100 == 0:
            print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy())

            # plotting decoded image (second row)
            _, decoded_data = autoencoder(view_data)
            for i in range(N_TEST_IMG):
                a[1][i].clear()
                a[1][i].imshow(np.reshape(decoded_data.data.numpy()[i], (28, 28)), cmap='gray')
                a[1][i].set_xticks(()); a[1][i].set_yticks(())
            plt.draw(); plt.pause(0.05)

plt.ioff()
plt.show()

# visualize in 3D plot
view_data = trainData.train_data[:200].view(-1, 28*28).type(torch.FloatTensor)/255.
encoded_data, _ = autoencoder(view_data)
fig = plt.figure(2)
ax = Axes3D(fig)

X, Y, Z = encoded_data.data[:, 0].numpy(), encoded_data.data[:, 1].numpy(), encoded_data.data[:, 2].numpy()
values = trainData.train_labels[:200].numpy()

for x, y, z, s in zip(X, Y, Z, values):
    c = cm.rainbow(int(255*s/9))
    ax.text(x, y, z, s, backgroundcolor=c)

ax.set_xlim(X.min(), X.max()); ax.set_ylim(Y.min(), Y.max()); ax.set_zlim(Z.min(), Z.max())
plt.show()

ext: py

reason: import numpy


text:
import numpy as np
import tensorflow as tf
from dnc.controller import BaseController

"""
A 1-layer LSTM recurrent neural network with 256 hidden units
Note: the state of the LSTM is not saved in a variable becuase we want
the state to reset to zero on every input sequnece
"""

class RecurrentController(BaseController):

    def network_vars(self):
        self.lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(256)
        self.state = self.lstm_cell.zero_state(self.batch_size, tf.float32)

    def network_op(self, X, state):
        X = tf.convert_to_tensor(X)
        return self.lstm_cell(X, state)

    def get_state(self):
        return self.state

    def update_state(self, new_state):
        return tf.no_op()


text:
# text2d.py
#
# Implements the Text2D class, a very simple implementation which maps
# glyphs from a bitmap file to actual text rendering on the screen using vispy
#
# Author: Rodrigo R. M. B. Maia
# http://www.github.com/rmaia3d

import struct

from vispy import gloo
# from vispy import app
import numpy as np

class Text2D:
    # Class that encapsulates all related methods to printing 2D text
    # to the screen using the texture mapping scheme
    # Assumes a 16rows by 16columns bitmap file containing the character glyphs
    # starting from char code 32 (ascii table).
    # For now, only constant spacing fonts supported, assumed to use half of each
    # alloted glyph square for width (e.g., if each glyph is 32x32px in a 512x512px
    # bitmap, glyph width is assumed to be 16px)
    T2DV_SHADER = """
    #version 120
    attribute vec2 a_position;
    attribute vec2 a_texcoord;
    uniform vec2 a_screensize;
    varying vec2 v_texcoord;

    void main (void)
    {
        // Normalize the position coords (which are passed in
        // bottom left total px values) to [-1:1]
        vec2 n_pos = (a_position - (a_screensize / 2.)) / (a_screensize / 2.);
        gl_Position = vec4(n_pos, 0.0, 1.0);
        v_texcoord = a_texcoord;
    }
    """

    T2DF_SHADER = """
    #version 120
    uniform sampler2D u_tex1;
    uniform vec4 text_color;
    varying vec2 v_texcoord;

    void main()
    {
        // Sample the alpha channel from the texture R component
        // (Since glyphs are assumed to be RGB=(FF, FF, FF), just the R component is ok)
        // This is needed to ensure the texture background color becomes transparent
        vec4 sampled = vec4(1.0, 1.0, 1.0, texture2D(u_tex1, v_texcoord).r);
        // Apply the passed text_color parameter
        gl_FragColor = text_color * sampled;
    }
    """

    def __init__(self):
        self.font_img = None
        self.font_bmp_path = "Monospace821BT.bmp"
        self.font_color = (1.0, 1.0, 1.0, 1.0)
        self.font_size_px = 12

        self.f_mrg = 0      # Lateral space between glyphs, default 0px abs
        self.scr_w = 500
        self.scr_h = 500

        self.import_font_bmp()

        self.text2d_shader = gloo.Program(self.T2DV_SHADER, self.T2DF_SHADER)
        self.text2d_shader['text_color'] = self.font_color
        self.text2d_shader['u_tex1'] = gloo.Texture2D(
            self.font_img, interpolation="linear")

        # Initialize to some dummy data
        self.text2d_shader['a_position'] = np.array(
            [[-1, -1], [+1, -1], [-1, +1], [+1, +1]]).astype(np.float32)
        self.text2d_shader['a_texcoord'] = np.array(
            [[0, 0], [1.0, 0.0], [0, 1.0], [1.0, 1.0]]).astype(np.float32)

    def set_font_bmp_path(self, new_path):
        self.font_bmp_path = new_path
        self.import_font_bmp()
        self.text2d_shader['u_tex1'] = gloo.Texture2D(
            self.font_img, interpolation="linear")

    def set_font_color(self, new_color):
        # new_color should be a normalized [0:1] (r, g, b, a) tuple
        self.font_color = new_color
        self.text2d_shader['text_color'] = self.font_color

    def set_font_size(self, new_size):
        # Font size (height) in absolute pixels
        self.font_size_px = new_size

    def update_screen_size(self, new_width, new_height):
        # Absolute pixel screen (framebuffer) size
        # Reference to generate the normalized coordinates in the vertex shader
        self.scr_w = new_width
        self.scr_h = new_height
        self.text2d_shader['a_screensize'] = (self.scr_w, self.scr_h)

    def print_text(self, string, abs_pos_x, abs_pos_y):
        # pos_x and pos_y should be absolute pixel coordinates of left
        # bottom part of text rectangle starting from bottom left of the screen
        verts, uvs = self.get_text_vertex_uv(string, abs_pos_x, abs_pos_y)

        # Bind the data to the buffers
        self.text2d_shader['a_position'] = gloo.VertexBuffer(
            np.array(verts).astype(np.float32))

        self.text2d_shader['a_texcoord'] = gloo.VertexBuffer(
            np.array(uvs).astype(np.float32))

        self.text2d_shader.draw('triangles')

    def get_text_extents(self, text_string):
        # Using the currently set font size (height), the lateral spacing
        # and assuming fonts are constant width = half height, returns
        # the total absolute pixel dimensions of the passed string if printed
        # - Note that the font height parameter realates to the maximum height
        # a font with top and lower decorations will have, so simpler (no decorations)
        # and lowercase characters can have smaller heights than specified
        hgt = self.font_size_px
        wid = len(text_string) * ((hgt / 2) + self.f_mrg)

        return wid, hgt

    def import_font_bmp(self):
        # Reads the font bmp file, getting the attributes from the header fields
        # and saves the bits themselves into a numpy array
        infile = open(self.font_bmp_path, "rb")
        contents = bytearray(infile.read())
        infile.close()

        # Get filesize - offset 2
        data = [contents[2], contents[3], contents[4], contents[5]]
        fsize = struct.unpack("I", bytearray(data))

        # Start of data - offset 10 (usually = 54)
        sdata = contents[10]

        # File width (pixels) - offset 18
        f_wid = [contents[18], contents[19], contents[20], contents[21]]
        f_wid = struct.unpack("I", bytearray(f_wid))

        # File height (pixels) - offset 22
        f_hgt = [contents[22], contents[23], contents[24], contents[25]]
        f_hgt = struct.unpack("I", bytearray(f_hgt))

        # Bits per pixel - ofsset 28
        bpp = contents[28]
        bytes_px = bpp // 8

        # Start at the offset and go to the end of the file
        pix_lst = []
        for i in range(sdata, fsize[0], 3):
            r = contents[i]
            g = contents[i + 1]
            b = contents[i + 2]
            pix_lst.append((r, g, b))

        # Convert to W x H numpy array of bytes_px item tuples (RGB)
        im = np.array(pix_lst)
        im = im.reshape((f_wid[0], f_hgt[0], bytes_px)).astype(np.float32)

        # Store the final bits array
        self.font_img = im

    def get_text_vertex_uv(self, string, pos_x, pos_y):
        # Position should be passed in absolute pixels starting from bottom left
        # Assuming fixed width font, width = height / 2
        # In 512x512 bitmap, each character square in texture is 32x32px,
        # with the font being 16px wide and 32px tall originally
        f_w = self.font_size_px / 2
        verts = []
        uvs = []
        for i, c in enumerate(string):
            # Character quad vertices
            up_left = (pos_x + (i * f_w), pos_y + self.font_size_px)
            up_right = (pos_x + (i * f_w) + f_w + self.f_mrg,
                        pos_y + self.font_size_px)
            down_right = (up_right[0], pos_y)
            down_left = (up_left[0], pos_y)

            # Character texture coordinates
            # Font bitmap has been generated starting at character 32 (ascii)
            # 16 rows x 16 columns
            ascii_code = ord(c)
            row = (ascii_code - 32) // 16  # Integer division
            col = ascii_code % 16
            uv_y = row
            uv_x = col
            # Normalize to [0:1] range, divide by 16 because 16x16 rows x columns
            uv_x /= 16.
            uv_y /= 16.

            # Build the uv vertices
            # (mapping to the the actual squares)
            # Column 0 is top and UV is bottom left
            uv_up_left = (uv_x, 0.995 - uv_y)
            uv_up_right = (uv_x + 0.5 / 16., 0.995 - uv_y)
            uv_down_right = (uv_up_right[0], 0.995 - (uv_y + 0.995 / 16.))
            uv_down_left = (uv_x, uv_down_right[1])

            # Add the quad vertices (forming 2 triangles)
            verts.append(up_left)
            verts.append(down_left)
            verts.append(up_right)

            verts.append(down_right)
            verts.append(up_right)
            verts.append(down_left)

            # Add the corresponding UV vertices (same order)
            uvs.append(uv_up_left)
            uvs.append(uv_down_left)
            uvs.append(uv_up_right)

            uvs.append(uv_down_right)
            uvs.append(uv_up_right)
            uvs.append(uv_down_left)
        return verts, uvs


text:
import json
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from wordcloud import WordCloud

def create_wordclouds():
    """
    Creating word clouds for each of the evaluation sentiment texts for QA, FAQ and JuggleChat. Results
    of word cloud experimentation unfortunately did not yield and useful visualizations.
    :return:
    """

    faq_eval = pd.read_csv('data/evaluation_results_faq.csv')['evaluation_sentiment'].tolist()
    faq_eval_text = ''.join(faq_eval)
    jugglechat_eval = pd.read_csv('data/evaluation_results_jugglechat.csv')['evaluation_sentiment'].tolist()
    jugglechat_eval_text = ''.join(jugglechat_eval)
    qa_eval = pd.read_csv('data/evaluation_results_qa.csv')['evaluation_sentiment'].tolist()
    qa_eval_text = ''.join(qa_eval)

    wordcloud = WordCloud(max_font_size=40, collocations=False).generate(faq_eval_text)
    plt.figure()
    plt.imshow(wordcloud, interpolation="bilinear")
    plt.savefig("faq_wordcloud.png", dpi=300)
    plt.cla()
    plt.close()

    wordcloud = WordCloud(max_font_size=40, collocations=False).generate(qa_eval_text)
    plt.figure()
    plt.imshow(wordcloud, interpolation="bilinear")
    plt.axis("off")
    plt.savefig("qa_wordcloud.png", dpi=300)
    plt.cla()
    plt.close()

    wordcloud = WordCloud(max_font_size=40, collocations=False).generate(jugglechat_eval_text)
    plt.figure()
    plt.imshow(wordcloud, interpolation="bilinear")
    plt.axis("off")
    plt.savefig("jugglechat_wordcloud.png", dpi=300)
    plt.cla()
    plt.close()

def plot_quiz_results():
    """
    Plots mean quiz scores for each experimental group.
    :return:
    """
    with open("results.json", "r") as results:
        results_json = json.load(results)

    mean_quiz_score_control = results_json['mean_quiz_score_control']
    mean_quiz_score_jugglechat = results_json['mean_quiz_score_jugglechat']
    mean_quiz_score_faq = results_json['mean_quiz_score_faq']
    mean_quiz_score_qa = results_json['mean_quiz_score_qa']
    mean_quiz_scores = [
        mean_quiz_score_control,
        mean_quiz_score_jugglechat,
        mean_quiz_score_faq,
        mean_quiz_score_qa]

    experimental_groups = ['Control', 'JuggleChat', 'FAQ', 'QA']

    mean_series = pd.Series(mean_quiz_scores)
    plt.figure()
    ax = mean_series.plot(kind='bar')

    for bar in ax.patches:
        y_location = bar.get_height() + .025
        ax.text(bar.get_x(), y_location,
                str(round(bar.get_height(), 5)), fontsize=10,
                color='black')

    plt.ylim(bottom=0, top=0.6)
    y_position = np.arange(len(experimental_groups))
    plt.bar(y_position, mean_quiz_scores, align='center', color='#4a4a4a')
    plt.xticks(y_position, experimental_groups, rotation='horizontal')
    plt.ylabel('Mean Quiz Scores')
    plt.savefig('images/quiz_scores.png')
    plt.close()

def plot_sentiment_results():
    """
    Plots mean sentiment for each experimental group.
    :return:
    """
    with open("results.json", "r") as results:
        results_json = json.load(results)

    mean_sentiment_faq = results_json['mean_sentiment_faq']
    mean_sentiment_jugglechat = results_json['mean_sentiment_jugglechat']
    mean_sentiment_qa = results_json['mean_sentiment_qa']
    mean_sentiments = [
        mean_sentiment_faq,
        mean_sentiment_jugglechat,
        mean_sentiment_qa]

    experimental_groups = ['FAQ', 'JuggleChat', 'QA']

    mean_series = pd.Series(mean_sentiments)
    plt.figure()
    ax = mean_series.plot(kind='bar')

    for bar in ax.patches:
        x_location = bar.get_x() + 0.125
        y_location = bar.get_height() + .025
        ax.text(x_location, y_location,
                str(round(bar.get_height(), 2)),
                fontsize=10, color='black')

    plt.ylim(bottom=0, top=0.5)
    y_position = np.arange(len(experimental_groups))
    plt.bar(y_position, mean_sentiments, align='center', color='grey')
    plt.xticks(y_position, experimental_groups, rotation='horizontal')
    plt.ylabel('Mean Sentiment')
    plt.savefig('images/sentiments.png')
    plt.close()

def plot_accuracy_and_usefulness():
    """
    Plots mean accuracy ratings and usefulness ratings for each experimental group. Contains code
    inspired from: https://matplotlib.org/gallery/api/barchart.html
    """
    with open("results.json", "r") as results:
        results_json = json.load(results)

    experimental_groups = ['FAQ', 'JuggleChat', 'QA']

    accuracy = [
        round(results_json['mean_accuracy_rating_faq'], 3),
        round(results_json['mean_accuracy_rating_jugglechat'], 3),
        round(results_json['mean_accuracy_rating_qa'], 3)
    ]
    usefulness = [
        round(results_json['mean_usefulness_rating_faq'], 3),
        round(results_json['mean_usefulness_rating_jugglechat'], 3),
        round(results_json['mean_usefulness_rating_qa'], 3)
    ]

    bar_width = 0.3

    accuracy_positions = np.arange(len(experimental_groups))
    usefulness_positions = [x + bar_width for x in accuracy_positions]

    fig, ax = plt.subplots()

    accuracy_bars = ax.bar(accuracy_positions, accuracy, bar_width,
                           color='#666666', label='Accuracy Rating', edgecolor='white')
    usefulness_bars = ax.bar(usefulness_positions, usefulness, bar_width,
                             color='#adadad', label='Usefulness Rating', edgecolor='white')

    ax.set_xticks([tick + bar_width/2 for tick in range(len(accuracy))])
    ax.set_xticklabels(experimental_groups)
    ax.legend()

    def autolabel(rects, xpos='center'):
        xpos = xpos.lower()
        ha = {'center': 'center', 'right': 'left', 'left': 'right'}
        offset = {'center': 0.5, 'right': 0.2, 'left': 0.8}

        for rect in rects:
            height = rect.get_height()
            ax.text(rect.get_x() + rect.get_width() * offset[xpos], 1.001 * height,
                    '{}'.format(height), ha=ha[xpos], va='bottom')

    autolabel(accuracy_bars, "left")
    autolabel(usefulness_bars, "right")

    plt.savefig("images/accuracy_usefulness.png", dpi=300)
    plt.close()

if __name__ == "__main__":
    plot_quiz_results()
    plot_sentiment_results()
    plot_accuracy_and_usefulness()

max_stars_repo_name: aaronbriel/jugglechat

max_issues_repo_name: aaronbriel/jugglechat

max_forks_repo_name: aaronbriel/jugglechat


text:
import argparse
import torch
import clip
import os
import json
import numpy as np
from PIL import Image
import tqdm

def parse_args():
    parser = argparse.ArgumentParser()

    parser.add_argument('--captions',
                        default=None,
                        help='captions, one per line.')
    parser.add_argument('--image_dir',
                        default=None,
                        help='image dir')

    parser.add_argument('--clip_model',
                        default='ViT-B/32',
                        choices=['ViT-B/32', 'RN50', 'RN101', 'RN50x4', 'ViT-B/16', 'RN50x16'])

    parser.add_argument('--feature_out_dir',
                        default='clip_features')

    parser.add_argument('--limit',
                        default=-1,
                        type=int)

    parser.add_argument('--load_weights',
                        default=None,
                        type=str)

    args = parser.parse_args()

    if not os.path.exists(args.feature_out_dir):
        os.makedirs(args.feature_out_dir)

    if args.image_dir:
        args.images = [args.image_dir + '/' + x for x in os.listdir(args.image_dir) if '.jpg' in x]
        print('extracting {} image features'.format(len(args.images)))
    else:
        args.images = None

    if args.captions:
        args.captions_out_base = args.feature_out_dir + '/' + args.captions.split('/')[-1].split('.')[0] + '_caption_features~{}'.format(args.clip_model.replace('/',''))
        if args.limit > 0:
            args.captions_out_base += '~limit{}'.format(args.limit)
        if args.load_weights:
            args.captions_out_base += '~initweights'
        print('extracting captions to: {}'.format(args.captions_out_base))
    if args.images:
        args.images_out_base = args.feature_out_dir + '/' + args.image_dir.split('/')[-2] + '_image_features~{}'.format(args.clip_model.replace('/',''))
        if args.limit > 0:
            args.images_out_base += '~limit{}'.format(args.limit)
        if args.load_weights:
            args.images_out_base += '~initweights'
        print('extracting images to: {}'.format(args.images_out_base))

    return args

def extract_all_captions(captions, model, preprocess, args, batch_size=256):
    batches = np.array_split(captions, int(len(captions) / batch_size))
    all_text_features = []
    with torch.no_grad():
        for b in tqdm.tqdm(batches):
            b = clip.tokenize(b).to(args.device)
            all_text_features.append(model.encode_text(b).cpu().numpy())
    all_text_features = np.vstack(all_text_features)
    return all_text_features

def extract_all_images(images, model, preprocess, args, batch_size=256):
    batches = np.array_split(images, int(len(images) / batch_size))
    all_image_features = []
    with torch.no_grad():
        for b in tqdm.tqdm(batches):
            b = torch.stack([preprocess(Image.open(im)) for im in b]).to(args.device)
            all_image_features.append(model.encode_image(b).cpu().numpy())
    all_image_features = np.vstack(all_image_features)
    return all_image_features

def main():
    args = parse_args()
    np.random.seed(1)
    args.device = "cuda" if torch.cuda.is_available() else "cpu"

    model, preprocess = clip.load(args.clip_model, device=args.device)
    model.eval()
    if args.load_weights:
        print('Loading weights from {}'.format(args.load_weights))
        state = torch.load(args.load_weights)['model_state_dict']
        state.update({'input_resolution': model.input_resolution,
                      'context_length':model.context_length,
                      'vocab_size':model.vocab_size})
        model.load_state_dict(state)

    if args.captions:
        with open(args.captions) as f:
            all_captions = [x.strip() for x in f.readlines()]
        print('extracting text features for {} captions'.format(len(all_captions)))
        unique_captions = list(set(all_captions))
        print('of those, {} were unique'.format(len(unique_captions)))
        if args.limit > 0 :
            np.random.shuffle(unique_captions)
            unique_captions = unique_captions[:args.limit]
            print('limiting to {}'.format(len(unique_captions)))
        all_text_features = extract_all_captions(unique_captions, model, preprocess, args)
        with open(args.captions_out_base + '~cap2row.json', 'w') as f:
            f.write(json.dumps({cap:idx for idx, cap in enumerate(unique_captions)}))
        print('saving {} array'.format(all_text_features.shape))
        np.save(args.captions_out_base + '.npy', all_text_features)

    if args.images:
        ordered_ids, ordered_paths = [], []
        for cpath in args.images:
            cid = '.'.join(cpath.split('/')[-1].split('.')[:-1])
            ordered_ids.append(cid)
            ordered_paths.append(cpath)

        if args.limit > 0:
            perm = np.random.permutation(args.limit)
            ordered_ids = [ordered_ids[idx] for idx in perm]
            ordered_paths = [ordered_paths[idx] for idx in perm]
            print('limiting to {}'.format(len(unique_captions)))

        all_image_features = extract_all_images(ordered_paths, model, preprocess, args)

        with open(args.images_out_base + '~im2row.json', 'w') as f:
            f.write(json.dumps({cid:idx for idx, cid in enumerate(ordered_ids)}))
        print('saving {} array'.format(all_image_features.shape))
        np.save(args.images_out_base + '.npy', all_image_features)

if __name__ == '__main__':
    main()

max_stars_repo_name: jmhessel/meshed-memory-transformer

max_issues_repo_name: jmhessel/meshed-memory-transformer

max_forks_repo_name: jmhessel/meshed-memory-transformer


text:
import numpy as np
a = 9999
print(np.sqrt(9999))


text:
# Missions.py
#
# Created:  May 2015, T. Lukaczyk
# Modified: Jan 2016, Carlos/Tarik

# ----------------------------------------------------------------------
#   Imports
# ----------------------------------------------------------------------

import SUAVE
from SUAVE.Core import Units

import numpy as np

# ----------------------------------------------------------------------
#   Define the Mission
# ----------------------------------------------------------------------

def setup(analyses):

    # the mission container
    missions = SUAVE.Analyses.Mission.Mission.Container()

    # ------------------------------------------------------------------
    #   Base Mission
    # ------------------------------------------------------------------
    base_mission = base(analyses)  # mission for performance
    missions.base = base_mission

    # Maximum range mission
    mission_max_range = max_range_setup(analyses)  # mission for MTOW
    missions.max_range = mission_max_range

    # Short field mission
    mission_short_field = short_field_setup(analyses)  # mission for Short Field
    missions.short_field = mission_short_field

    # Takeoff mission initialization
    #missions.takeoff_initialization = takeoff_mission_initialization(analyses)

    # Takeoff mission
    missions.takeoff = takeoff_mission_setup(analyses)

    # Sideline Takeoff mission
    missions.sideline_takeoff = sideline_mission_setup(analyses)

    # Landing mission
    missions.landing = landing_mission_setup(analyses)

    # ------------------------------------------------------------------
    #   Mission for Takeoff Field Lengths
    # ------------------------------------------------------------------
    takeoff = SUAVE.Analyses.Mission.Mission(base_mission) #Short_Field_Constrained()
    takeoff.tag = 'takeoff_field'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   = 0.0
    airport.delta_isa  = 0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()

    takeoff.airport = airport
    missions.append(takeoff)

    return missions

def base(analyses):

    # ------------------------------------------------------------------
    #   Initialize the Mission
    # ------------------------------------------------------------------

    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'base'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   = 0.0
    airport.delta_isa  = 0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()

    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()
    atmosphere=SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976()
    planet = SUAVE.Attributes.Planets.Earth()
     # ------------------------------------------------------------------
    #   First Climb Segment: Constant Speed, Constant Throttle
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_1"

    # connect vehicle configuration
    segment.analyses.extend( analyses.base )

    # define segment attributes
    segment.atmosphere     = atmosphere
    segment.planet         = planet

    segment.altitude_start = 0.0   * Units.km
    segment.altitude_end   = 3.048 * Units.km
    segment.air_speed      = 138.0 * Units['m/s']
    segment.climb_rate     = 2900. * Units['ft/min']

    # add to misison
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Second Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_2"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 3.657 * Units.km
    segment.air_speed    = 168.0 * Units['m/s']
    segment.climb_rate   = 2500. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Third Climb Segment: Constant Speed, Constant Climb Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_3"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 25000. * Units.ft
    segment.air_speed    = 200.0  * Units['m/s']
    segment.climb_rate   = 1800. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

     # ------------------------------------------------------------------
    #   Fourth Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_4"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 32000. * Units.ft
    segment.air_speed    = 230.0* Units['m/s']
    segment.climb_rate   = 900. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Fifth Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_5"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 37000. * Units.ft
    segment.air_speed    = 230.0  * Units['m/s']
    segment.climb_rate   = 300.   * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Cruise Segment: constant speed, constant altitude
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Speed_Constant_Altitude()
    segment.tag = "cruise"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere = atmosphere
    segment.planet     = planet

    segment.air_speed  = 450. * Units.knots
    segment.distance   = 2050. * Units.nmi

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   First Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_1"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 9.31  * Units.km
    segment.air_speed    = 440.0 * Units.knots
    segment.descent_rate = 2600. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Second Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_2"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 3.657 * Units.km
    segment.air_speed    = 365.0 * Units.knots
    segment.descent_rate = 2300. * Units['ft/min']

    # append to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Third Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_3"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 0.0   * Units.km
    segment.air_speed    = 250.0 * Units.knots
    segment.descent_rate = 1500. * Units['ft/min']

    # append to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Mission definition complete
    # ------------------------------------------------------------------

    #------------------------------------------------------------------
    ###         Reserve mission
    #------------------------------------------------------------------

    # ------------------------------------------------------------------
    #   First Climb Segment: constant Mach, constant segment angle
    # ------------------------------------------------------------------

    #segment = Segments.Climb.Constant_Speed_Constant_Rate(base_segment)
    segment = Segments.Climb.Linear_Mach_Constant_Rate(base_segment)
    segment.tag = "reserve_climb_1"

    segment.analyses.extend( analyses.cruise )

    segment.altitude_start = 0.0   * Units.km
    segment.altitude_end   = 15000.0 * Units.ft
    segment.climb_rate     = 1800.   * Units['ft/min']
    segment.mach_end       = 0.3
    segment.mach_start     = 0.2

    # add to misison
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Cruise Segment: constant speed, constant altitude
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Speed_Constant_Altitude(base_segment)
    segment.tag = "reserve_cruise"

    segment.analyses.extend( analyses.cruise )

    segment.air_speed  = 96.66 * Units['m/s']
    segment.distance   = 100.0 * Units.nautical_mile
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Loiter Segment: constant mach, constant time
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Mach_Constant_Altitude_Loiter(base_segment)
    segment.tag = "reserve_loiter"

    segment.analyses.extend( analyses.cruise )

    segment.mach = 0.5
    segment.time = 30.0 * Units.minutes

    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Fifth Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Linear_Mach_Constant_Rate(base_segment)
    segment.tag = "reserve_descent_1_base"

    segment.analyses.extend( analyses.landing )
    analyses.landing.aerodynamics.settings.spoiler_drag_increment = 0.00

    segment.altitude_end = 0.0   * Units.km
    segment.descent_rate = 3.0   * Units['m/s']

    segment.mach_end    = 0.24
    segment.mach_start  = 0.3

    # append to mission
    mission.append_segment(segment)

    #------------------------------------------------------------------
    ###         Reserve mission completed
    #------------------------------------------------------------------

    return mission

def max_range_setup(analyses):

    # ------------------------------------------------------------------
    #   Initialize the Mission
    # ------------------------------------------------------------------

    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'the_mission'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   =  0.0  * Units.ft
    airport.delta_isa  =  0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()

    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()
    atmosphere=SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976()
    planet = SUAVE.Attributes.Planets.Earth()
    # ------------------------------------------------------------------
    #   First Climb Segment: Constant Speed, Constant Throttle
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_1"

    # connect vehicle configuration
    segment.analyses.extend( analyses.takeoff )

    # define segment attributes
    segment.atmosphere     = atmosphere
    segment.planet         = planet

    segment.altitude_start = 0.0   * Units.km
    segment.altitude_end   = 3.048 * Units.km
    segment.air_speed      = 138.0 * Units['m/s']
    segment.climb_rate     = 2900. * Units['ft/min']

    # add to misison
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Second Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_2"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 3.657 * Units.km
    segment.air_speed    = 168.0 * Units['m/s']
    segment.climb_rate   = 2500. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Third Climb Segment: Constant Speed, Constant Climb Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_3"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 25000. * Units.ft
    segment.air_speed    = 200.0  * Units['m/s']
    segment.climb_rate   = 1700. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

     # ------------------------------------------------------------------
    #   Fourth Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_4"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 32000. * Units.ft
    segment.air_speed    = 225.0* Units['m/s']
    segment.climb_rate   = 800. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Fifth Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_5"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 36999. * Units.ft
    segment.air_speed    = 230.0  * Units['m/s']
    segment.climb_rate   = 300.   * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Cruise Segment: constant speed, constant altitude
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Speed_Constant_Altitude()
    segment.tag = "cruise"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere = atmosphere
    segment.planet     = planet

    segment.air_speed  = 450. * Units.knots
    segment.distance   = 2050. * Units.nmi

    segment.state.numerics.number_control_points = 10

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   First Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_1"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 9.31  * Units.km
    segment.air_speed    = 440.0 * Units.knots
    segment.descent_rate = 2600. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Second Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_2"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 3.657 * Units.km
    segment.air_speed    = 365.0 * Units.knots
    segment.descent_rate = 2300. * Units['ft/min']

    # append to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Third Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_3"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 0.0   * Units.km
    segment.air_speed    = 250.0 * Units.knots
    segment.descent_rate = 1500. * Units['ft/min']

    # append to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Mission definition complete
    # ------------------------------------------------------------------

    #------------------------------------------------------------------
    ###         Reserve mission
    #------------------------------------------------------------------

    # ------------------------------------------------------------------
    #   First Climb Segment: constant Mach, constant segment angle
    # ------------------------------------------------------------------

    #segment = Segments.Climb.Constant_Speed_Constant_Rate(base_segment)
    segment = Segments.Climb.Linear_Mach_Constant_Rate(base_segment)
    segment.tag = "reserve_climb_1"

    segment.analyses.extend( analyses.cruise )

    segment.altitude_start = 0.0   * Units.km
    segment.altitude_end   = 15000.0 * Units.ft
    segment.climb_rate     = 1800.   * Units['ft/min']
    segment.mach_end       = 0.3
    segment.mach_start     = 0.2

    # add to misison
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Cruise Segment: constant speed, constant altitude
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Speed_Constant_Altitude(base_segment)
    segment.tag = "reserve_cruise"

    segment.analyses.extend( analyses.cruise )

    segment.air_speed  = 96.66 * Units['m/s']
    segment.distance   = 100.0 * Units.nautical_mile
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Loiter Segment: constant mach, constant time
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Mach_Constant_Altitude_Loiter(base_segment)
    segment.tag = "reserve_loiter"

    segment.analyses.extend( analyses.cruise )

    segment.mach = 0.5
    segment.time = 30.0 * Units.minutes

    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Fifth Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Linear_Mach_Constant_Rate(base_segment)
    segment.tag = "reserve_descent_1_max_range"

    segment.analyses.extend( analyses.landing )
    analyses.landing.aerodynamics.settings.spoiler_drag_increment = 0.00

    segment.altitude_end = 0.0   * Units.km
    segment.descent_rate = 3.0   * Units['m/s']

    segment.mach_end    = 0.24
    segment.mach_start  = 0.3

    # append to mission
    mission.append_segment(segment)

    #------------------------------------------------------------------
    ###         Reserve mission completed
    #------------------------------------------------------------------

    return mission

def short_field_setup(analyses):

    # ------------------------------------------------------------------
    #   Initialize the Mission
    # ------------------------------------------------------------------

    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'the_mission'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   =  0.0  * Units.ft
    airport.delta_isa  =  0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()

    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()
    atmosphere=SUAVE.Attributes.Atmospheres.Earth.US_Standard_1976()
    planet = SUAVE.Attributes.Planets.Earth()
    # ------------------------------------------------------------------
    #   First Climb Segment: Constant Speed, Constant Throttle
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_1"

    # connect vehicle configuration
    segment.analyses.extend( analyses.short_field_takeoff )

    # define segment attributes
    segment.atmosphere     = atmosphere
    segment.planet         = planet

    segment.altitude_start = 0.0   * Units.km
    segment.altitude_end   = 3.048 * Units.km
    segment.air_speed      = 138.0 * Units['m/s']
    segment.climb_rate     = 2900. * Units['ft/min']

    # add to misison
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Second Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_2"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 3.657 * Units.km
    segment.air_speed    = 168.0 * Units['m/s']
    segment.climb_rate   = 2500. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Third Climb Segment: Constant Speed, Constant Climb Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_3"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 25000. * Units.ft
    segment.air_speed    = 200.0  * Units['m/s']
    segment.climb_rate   = 1800. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

     # ------------------------------------------------------------------
    #   Fourth Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_4"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 32000. * Units.ft
    segment.air_speed    = 230.0* Units['m/s']
    segment.climb_rate   = 900. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Fifth Climb Segment: Constant Speed, Constant Rate
    # ------------------------------------------------------------------

    segment = Segments.Climb.Constant_Speed_Constant_Rate()
    segment.tag = "climb_5"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 37000. * Units.ft
    segment.air_speed    = 230.0  * Units['m/s']
    segment.climb_rate   = 300.   * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Cruise Segment: constant speed, constant altitude
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Speed_Constant_Altitude()
    segment.tag = "cruise"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere = atmosphere
    segment.planet     = planet

    segment.air_speed  = 450. * Units.knots
    segment.distance   = 2050. * Units.nmi

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   First Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_1"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 9.31  * Units.km
    segment.air_speed    = 440.0 * Units.knots
    segment.descent_rate = 2600. * Units['ft/min']

    # add to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Second Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_2"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 3.657 * Units.km
    segment.air_speed    = 365.0 * Units.knots
    segment.descent_rate = 2300. * Units['ft/min']

    # append to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Third Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Constant_Speed_Constant_Rate()
    segment.tag = "descent_3"

    # connect vehicle configuration
    segment.analyses.extend( analyses.cruise )

    # segment attributes
    segment.atmosphere   = atmosphere
    segment.planet       = planet

    segment.altitude_end = 0.0   * Units.km
    segment.air_speed    = 250.0 * Units.knots
    segment.descent_rate = 1500. * Units['ft/min']

    # append to mission
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Mission definition complete
    # ------------------------------------------------------------------

    #------------------------------------------------------------------
    ###         Reserve mission
    #------------------------------------------------------------------

    # ------------------------------------------------------------------
    #   First Climb Segment: constant Mach, constant segment angle
    # ------------------------------------------------------------------

    #segment = Segments.Climb.Constant_Speed_Constant_Rate(base_segment)
    segment = Segments.Climb.Linear_Mach_Constant_Rate(base_segment)
    segment.tag = "reserve_climb_1"

    segment.analyses.extend( analyses.cruise )

    segment.altitude_start = 0.0   * Units.km
    segment.altitude_end   = 15000.0 * Units.ft
    segment.climb_rate     = 1800.   * Units['ft/min']
    segment.mach_end       = 0.3
    segment.mach_start     = 0.2

    # add to misison
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Cruise Segment: constant speed, constant altitude
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Speed_Constant_Altitude(base_segment)
    segment.tag = "reserve_cruise"

    segment.analyses.extend( analyses.cruise )

    segment.air_speed  = 96.66 * Units['m/s']
    segment.distance   = 100.0 * Units.nautical_mile
    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Loiter Segment: constant mach, constant time
    # ------------------------------------------------------------------

    segment = Segments.Cruise.Constant_Mach_Constant_Altitude_Loiter(base_segment)
    segment.tag = "reserve_loiter"

    segment.analyses.extend( analyses.cruise )

    segment.mach = 0.5
    segment.time = 30.0 * Units.minutes

    mission.append_segment(segment)

    # ------------------------------------------------------------------
    #   Fifth Descent Segment: consant speed, constant segment rate
    # ------------------------------------------------------------------

    segment = Segments.Descent.Linear_Mach_Constant_Rate(base_segment)
    segment.tag = "reserve_descent_1_short_field"

    segment.analyses.extend( analyses.landing )
    analyses.landing.aerodynamics.settings.spoiler_drag_increment = 0.00

    segment.altitude_end = 0.0   * Units.km
    segment.descent_rate = 3.0   * Units['m/s']

    segment.mach_end    = 0.24
    segment.mach_start  = 0.3

    # append to mission
    mission.append_segment(segment)

    #------------------------------------------------------------------
    ###         Reserve mission completed
    #------------------------------------------------------------------

    return mission

def takeoff_mission_setup(analyses):

    # ------------------------------------------------------------------
    #   Initialize the Mission segment for takeoff
    # ------------------------------------------------------------------
    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'takeoff'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   =  0.0  * Units.ft
    airport.delta_isa  =  0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()

    # Climb Segment: Constant throttle, constant speed
    segment = Segments.Climb.Constant_Throttle_Constant_Speed(base_segment)
    segment.tag = "climb"
    segment.analyses.extend( analyses.takeoff )
    segment.altitude_start =  35. *  Units.fts
    segment.altitude_end   = 304.8 *  Units.meter
    segment.air_speed      = 85.4 * Units['m/s']
    segment.throttle       = 1.
    segment.state.numerics.number_control_points = 10
    #segment.state.numerics.discretization_method = SUAVE.Methods.Utilities.Chebyshev.linear_data
    mission.append_segment(segment)

    # Cutback Segment: Constant speed, constant segment angle
    segment = Segments.Climb.Constant_Speed_Constant_Angle_Noise(base_segment)
    segment.tag = "cutback"
    segment.analyses.extend( analyses.takeoff )
    segment.air_speed    = 85.4 * Units['m/s']
    segment.climb_angle   = 2.86  * Units.degrees
    #segment.state.numerics.discretization_method = SUAVE.Methods.Utilities.Chebyshev.linear_data
    mission.append_segment(segment)

    return mission

def sideline_mission_setup(analyses):
    # ------------------------------------------------------------------
    #   Initialize the Mission segment for takeoff
    # ------------------------------------------------------------------
    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'sideline_takeoff'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   =  0.0  * Units.ft
    airport.delta_isa  =  0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()

    # Climb Segment: Constant throttle, constant speed
    segment = Segments.Climb.Constant_Throttle_Constant_Speed(base_segment)
    segment.tag = "climb"
    segment.analyses.extend( analyses.takeoff )
    segment.altitude_start =  35. *  Units.fts
    segment.altitude_end   = 1600 *  Units.fts
    segment.air_speed      = 85.4 * Units['m/s']
    segment.throttle       = 1.
    segment.state.numerics.number_control_points = 10
    #segment.state.numerics.discretization_method = SUAVE.Methods.Utilities.Chebyshev.linear_data
    mission.append_segment(segment)

    return mission

def takeoff_mission_initialization(analyses):

    # ------------------------------------------------------------------
    #   Initialize the Mission segment for takeoff
    # ------------------------------------------------------------------
    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'takeoff_initialization'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   =  0.0  * Units.ft
    airport.delta_isa  =  0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()

    # Climb Segment: Constant speed, constant segment angle
    segment = Segments.Climb.Constant_Throttle_Constant_Speed(base_segment)
    segment.tag = "climb"
    segment.analyses.extend( analyses.takeoff )
    segment.altitude_start =  35. *  Units.fts
    segment.altitude_end   = 300. * Units.meter
    segment.air_speed      =  85.4 * Units['m/s']
    segment.throttle       = 1.
    segment.state.numerics.number_control_points = 5
    mission.append_segment(segment)

    return mission

def landing_mission_setup(analyses):

    # ------------------------------------------------------------------
    #   Initialize the Mission segment for landing
    # ------------------------------------------------------------------
    mission = SUAVE.Analyses.Mission.Sequential_Segments()
    mission.tag = 'landing'

    #airport
    airport = SUAVE.Attributes.Airports.Airport()
    airport.altitude   =  0.0  * Units.ft
    airport.delta_isa  =  0.0
    airport.atmosphere = SUAVE.Analyses.Atmospheric.US_Standard_1976()
    mission.airport = airport

    # unpack Segments module
    Segments = SUAVE.Analyses.Mission.Segments

    # base segment
    base_segment = Segments.Segment()
    # ------------------------------------------------------------------
    #   Descent Segment: Constant speed, constant segment angle
    # ------------------------------------------------------------------
    segment = Segments.Descent.Constant_Speed_Constant_Angle_Noise(base_segment)
    segment.tag = "descent"
    segment.analyses.extend( analyses.landing )

    segment.air_speed    = 67. * Units['m/s']
    segment.descent_angle = 3.0   * Units.degrees
    #segment.state.numerics.discretization_method = SUAVE.Methods.Utilities.Chebyshev.linear_data
    mission.append_segment(segment)

    return mission