<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Static & Transient DataFrames in PyNastran
The iPython notebook for this demo can be found in
Step1:  Solid Bending
Let's show off combine=True/False.  We'll talk about the keys soon.
Step2:  Single Subcase Buckling Example
The keys cannot be "combined" despite us telling the program that it was OK.
We'll get the following values that we need to handle.
isubcase, analysis_code, sort_method, count, subtitle
isubcase -> the same key that you're used to accessing
sort_method -> 1 (SORT1), 2 (SORT2)
count -> the optimization count
subtitle -> the analysis subtitle (changes for superlements)
analysis code -> the "type" of solution 
### Partial code for calculating analysis code
Step3:  Keys
Step4:  Static Table
Step5:  Transient Table
<ASSISTANT_TASK:>
Python Code:
import os
import pandas as pd
import pyNastran
from pyNastran.op2.op2 import read_op2
pkg_path = pyNastran.__path__[0]
model_path = os.path.join(pkg_path, '..', 'models')
Explanation: Static & Transient DataFrames in PyNastran
The iPython notebook for this demo can be found in:
   - docs\quick_start\demo\op2_pandas_multi_case.ipynb
   - https://github.com/SteveDoyle2/pyNastran/tree/master/docs/quick_start/demo/op2_pandas_multi_case.ipynb
End of explanation
solid_bending_op2 = os.path.join(model_path, 'solid_bending', 'solid_bending.op2')
solid_bending = read_op2(solid_bending_op2, combine=False, debug=False)
print(solid_bending.displacements.keys())
solid_bending_op2 = os.path.join(model_path, 'solid_bending', 'solid_bending.op2')
solid_bending2 = read_op2(solid_bending_op2, combine=True, debug=False)
print(solid_bending2.displacements.keys())
Explanation: Solid Bending
Let's show off combine=True/False.  We'll talk about the keys soon.
End of explanation
op2_filename = os.path.join(model_path, 'sol_101_elements', 'buckling_solid_shell_bar.op2')
model = read_op2(op2_filename, combine=True, debug=False, build_dataframe=True)
stress_keys = model.cquad4_stress.keys()
print (stress_keys)
# isubcase, analysis_code, sort_method, count, subtitle
key0 = (1, 1, 1, 0, 'DEFAULT1')
key1 = (1, 8, 1, 0, 'DEFAULT1')
Explanation: Single Subcase Buckling Example
The keys cannot be "combined" despite us telling the program that it was OK.
We'll get the following values that we need to handle.
isubcase, analysis_code, sort_method, count, subtitle
isubcase -> the same key that you're used to accessing
sort_method -> 1 (SORT1), 2 (SORT2)
count -> the optimization count
subtitle -> the analysis subtitle (changes for superlements)
analysis code -> the "type" of solution 
### Partial code for calculating analysis code:
   if trans_word == 'LOAD STEP':  # nonlinear statics
      analysis_code = 10
  elif trans_word in ['TIME', 'TIME STEP']:  # TODO check name
      analysis_code = 6
  elif trans_word == 'EIGENVALUE':  # normal modes
      analysis_code = 2
  elif trans_word == 'FREQ':  # TODO check name
      analysis_code = 5
  elif trans_word == 'FREQUENCY':
      analysis_code = 5
  elif trans_word == 'COMPLEX EIGENVALUE':
      analysis_code = 9
  else:
      raise NotImplementedError('transient_word=%r is not supported...' % trans_word)
Let's look at an odd case:
You can do buckling as one subcase or two subcases (makes parsing it a lot easier!).
However, you have to do this once you start messing around with superelements or multi-step optimization.
For optimization, sometimes Nastran will downselect elements and do an optimization on that and print out a subset of the elements.
At the end, it will rerun an analysis to double check the constraints are satisfied.
It does not always do multi-step optimization.
End of explanation
stress_static = model.cquad4_stress[key0].data_frame
stress_transient = model.cquad4_stress[key1].data_frame
# The final calculated factor:
#   Is it a None or not?
# This defines if it's static or transient
print('stress_static.nonlinear_factor = %s' % model.cquad4_stress[key0].nonlinear_factor)
print('stress_transient.nonlinear_factor = %s' % model.cquad4_stress[key1].nonlinear_factor)
print('data_names  = %s' % model.cquad4_stress[key1].data_names)
print('loadsteps   = %s' % model.cquad4_stress[key1].lsdvmns)
print('eigenvalues = %s' % model.cquad4_stress[key1].eigrs)
Explanation: Keys:
* key0 is the "static" key
* key1 is the "buckling" key
Similarly:
 * Transient solutions can have preload
 * Frequency solutions can have loadsets (???)
Moving onto the data frames
The static case is the initial deflection state
The buckling case is "transient", where the modes (called load steps or lsdvmn here) represent the "times"
pyNastran reads these tables differently and handles them differently internally.  They look very similar though.
End of explanation
# Sets default precision of real numbers for pandas output\n"
pd.set_option('precision', 2)
stress_static.head(20)
Explanation: Static Table
End of explanation
# Sets default precision of real numbers for pandas output\n"
pd.set_option('precision', 3)
#import numpy as np
#np.set_printoptions(formatter={'all':lambda x: '%g'})
stress_transient.head(20)
Explanation: Transient Table
End of explanation
<END_TASK>