text:
module ATI

import GetC.@getCFun

const libGL = @windows? "opengl32" : "libGL"

typealias GLenum Cuint
typealias GLboolean Cuchar
typealias GLbitfield Cuint
typealias GLvoid Void
typealias GLbyte Cuchar
typealias GLshort Cshort
typealias GLint Cint
typealias GLubyte Cuchar
typealias GLushort Cushort
typealias GLuint Cuint
typealias GLsizei Csize_t
typealias GLfloat Cfloat
typealias GLclampf Cfloat
typealias GLdouble Cdouble
typealias GLclampd Cdouble
typealias GLchar Cchar
typealias GLint64 Clonglong
typealias GLuint64 Culonglong
typealias GLhalf Cushort
typealias GLhalfARB Cushort
typealias GLhalfNV Cushort
typealias GLsync Ptr{Void}
typealias Pointer Ptr{Void}
typealias GLsizeiptr Cint
typealias GLintptr Cptrdiff_t
const DRAW_BUFFER0_ATI = 0x8825
export DRAW_BUFFER0_ATI
const DRAW_BUFFER10_ATI = 0x882F
export DRAW_BUFFER10_ATI
const DRAW_BUFFER11_ATI = 0x8830
export DRAW_BUFFER11_ATI
const DRAW_BUFFER12_ATI = 0x8831
export DRAW_BUFFER12_ATI
const DRAW_BUFFER13_ATI = 0x8832
export DRAW_BUFFER13_ATI
const DRAW_BUFFER14_ATI = 0x8833
export DRAW_BUFFER14_ATI
const DRAW_BUFFER15_ATI = 0x8834
export DRAW_BUFFER15_ATI
const DRAW_BUFFER1_ATI = 0x8826
export DRAW_BUFFER1_ATI
const DRAW_BUFFER2_ATI = 0x8827
export DRAW_BUFFER2_ATI
const DRAW_BUFFER3_ATI = 0x8828
export DRAW_BUFFER3_ATI
const DRAW_BUFFER4_ATI = 0x8829
export DRAW_BUFFER4_ATI
const DRAW_BUFFER5_ATI = 0x882A
export DRAW_BUFFER5_ATI
const DRAW_BUFFER6_ATI = 0x882B
export DRAW_BUFFER6_ATI
const DRAW_BUFFER7_ATI = 0x882C
export DRAW_BUFFER7_ATI
const DRAW_BUFFER8_ATI = 0x882D
export DRAW_BUFFER8_ATI
const DRAW_BUFFER9_ATI = 0x882E
export DRAW_BUFFER9_ATI
const MAX_DRAW_BUFFERS_ATI = 0x8824
export MAX_DRAW_BUFFERS_ATI
const ELEMENT_ARRAY_ATI = 0x8768
export ELEMENT_ARRAY_ATI
const ELEMENT_ARRAY_POINTER_ATI = 0x876A
export ELEMENT_ARRAY_POINTER_ATI
const ELEMENT_ARRAY_TYPE_ATI = 0x8769
export ELEMENT_ARRAY_TYPE_ATI
const BUMP_ENVMAP_ATI = 0x877B
export BUMP_ENVMAP_ATI
const BUMP_NUM_TEX_UNITS_ATI = 0x8777
export BUMP_NUM_TEX_UNITS_ATI
const BUMP_ROT_MATRIX_ATI = 0x8775
export BUMP_ROT_MATRIX_ATI
const BUMP_ROT_MATRIX_SIZE_ATI = 0x8776
export BUMP_ROT_MATRIX_SIZE_ATI
const BUMP_TARGET_ATI = 0x877C
export BUMP_TARGET_ATI
const BUMP_TEX_UNITS_ATI = 0x8778
export BUMP_TEX_UNITS_ATI
const DU8DV8_ATI = 0x877A
export DU8DV8_ATI
const DUDV_ATI = 0x8779
export DUDV_ATI
const X2X_BIT_ATI = 0x00000001
export X2X_BIT_ATI
const X4X_BIT_ATI = 0x00000002
export X4X_BIT_ATI
const X8X_BIT_ATI = 0x00000004
export X8X_BIT_ATI
const ADD_ATI = 0x8963
export ADD_ATI
const BIAS_BIT_ATI = 0x00000008
export BIAS_BIT_ATI
const BLUE_BIT_ATI = 0x00000004
export BLUE_BIT_ATI
const CND0_ATI = 0x896B
export CND0_ATI
const CND_ATI = 0x896A
export CND_ATI
const COLOR_ALPHA_PAIRING_ATI = 0x8975
export COLOR_ALPHA_PAIRING_ATI
const COMP_BIT_ATI = 0x00000002
export COMP_BIT_ATI
const CON_0_ATI = 0x8941
export CON_0_ATI
const CON_10_ATI = 0x894B
export CON_10_ATI
const CON_11_ATI = 0x894C
export CON_11_ATI
const CON_12_ATI = 0x894D
export CON_12_ATI
const CON_13_ATI = 0x894E
export CON_13_ATI
const CON_14_ATI = 0x894F
export CON_14_ATI
const CON_15_ATI = 0x8950
export CON_15_ATI
const CON_16_ATI = 0x8951
export CON_16_ATI
const CON_17_ATI = 0x8952
export CON_17_ATI
const CON_18_ATI = 0x8953
export CON_18_ATI
const CON_19_ATI = 0x8954
export CON_19_ATI
const CON_1_ATI = 0x8942
export CON_1_ATI
const CON_20_ATI = 0x8955
export CON_20_ATI
const CON_21_ATI = 0x8956
export CON_21_ATI
const CON_22_ATI = 0x8957
export CON_22_ATI
const CON_23_ATI = 0x8958
export CON_23_ATI
const CON_24_ATI = 0x8959
export CON_24_ATI
const CON_25_ATI = 0x895A
export CON_25_ATI
const CON_26_ATI = 0x895B
export CON_26_ATI
const CON_27_ATI = 0x895C
export CON_27_ATI
const CON_28_ATI = 0x895D
export CON_28_ATI
const CON_29_ATI = 0x895E
export CON_29_ATI
const CON_2_ATI = 0x8943
export CON_2_ATI
const CON_30_ATI = 0x895F
export CON_30_ATI
const CON_31_ATI = 0x8960
export CON_31_ATI
const CON_3_ATI = 0x8944
export CON_3_ATI
const CON_4_ATI = 0x8945
export CON_4_ATI
const CON_5_ATI = 0x8946
export CON_5_ATI
const CON_6_ATI = 0x8947
export CON_6_ATI
const CON_7_ATI = 0x8948
export CON_7_ATI
const CON_8_ATI = 0x8949
export CON_8_ATI
const CON_9_ATI = 0x894A
export CON_9_ATI
const DOT2_ADD_ATI = 0x896C
export DOT2_ADD_ATI
const DOT3_ATI = 0x8966
export DOT3_ATI
const DOT4_ATI = 0x8967
export DOT4_ATI
const EIGHTH_BIT_ATI = 0x00000020
export EIGHTH_BIT_ATI
const FRAGMENT_SHADER_ATI = 0x8920
export FRAGMENT_SHADER_ATI
const GREEN_BIT_ATI = 0x00000002
export GREEN_BIT_ATI
const HALF_BIT_ATI = 0x00000008
export HALF_BIT_ATI
const LERP_ATI = 0x8969
export LERP_ATI
const MAD_ATI = 0x8968
export MAD_ATI
const MOV_ATI = 0x8961
export MOV_ATI
const MUL_ATI = 0x8964
export MUL_ATI
const NEGATE_BIT_ATI = 0x00000004
export NEGATE_BIT_ATI
const NUM_FRAGMENT_CONSTANTS_ATI = 0x896F
export NUM_FRAGMENT_CONSTANTS_ATI
const NUM_FRAGMENT_REGISTERS_ATI = 0x896E
export NUM_FRAGMENT_REGISTERS_ATI
const NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI = 0x8973
export NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI
const NUM_INSTRUCTIONS_PER_PASS_ATI = 0x8971
export NUM_INSTRUCTIONS_PER_PASS_ATI
const NUM_INSTRUCTIONS_TOTAL_ATI = 0x8972
export NUM_INSTRUCTIONS_TOTAL_ATI
const NUM_LOOPBACK_COMPONENTS_ATI = 0x8974
export NUM_LOOPBACK_COMPONENTS_ATI
const NUM_PASSES_ATI = 0x8970
export NUM_PASSES_ATI
const QUARTER_BIT_ATI = 0x00000010
export QUARTER_BIT_ATI
const RED_BIT_ATI = 0x00000001
export RED_BIT_ATI
const REG_0_ATI = 0x8921
export REG_0_ATI
const REG_10_ATI = 0x892B
export REG_10_ATI
const REG_11_ATI = 0x892C
export REG_11_ATI
const REG_12_ATI = 0x892D
export REG_12_ATI
const REG_13_ATI = 0x892E
export REG_13_ATI
const REG_14_ATI = 0x892F
export REG_14_ATI
const REG_15_ATI = 0x8930
export REG_15_ATI
const REG_16_ATI = 0x8931
export REG_16_ATI
const REG_17_ATI = 0x8932
export REG_17_ATI
const REG_18_ATI = 0x8933
export REG_18_ATI
const REG_19_ATI = 0x8934
export REG_19_ATI
const REG_1_ATI = 0x8922
export REG_1_ATI
const REG_20_ATI = 0x8935
export REG_20_ATI
const REG_21_ATI = 0x8936
export REG_21_ATI
const REG_22_ATI = 0x8937
export REG_22_ATI
const REG_23_ATI = 0x8938
export REG_23_ATI
const REG_24_ATI = 0x8939
export REG_24_ATI
const REG_25_ATI = 0x893A
export REG_25_ATI
const REG_26_ATI = 0x893B
export REG_26_ATI
const REG_27_ATI = 0x893C
export REG_27_ATI
const REG_28_ATI = 0x893D
export REG_28_ATI
const REG_29_ATI = 0x893E
export REG_29_ATI
const REG_2_ATI = 0x8923
export REG_2_ATI
const REG_30_ATI = 0x893F
export REG_30_ATI
const REG_31_ATI = 0x8940
export REG_31_ATI
const REG_3_ATI = 0x8924
export REG_3_ATI
const REG_4_ATI = 0x8925
export REG_4_ATI
const REG_5_ATI = 0x8926
export REG_5_ATI
const REG_6_ATI = 0x8927
export REG_6_ATI
const REG_7_ATI = 0x8928
export REG_7_ATI
const REG_8_ATI = 0x8929
export REG_8_ATI
const REG_9_ATI = 0x892A
export REG_9_ATI
const SATURATE_BIT_ATI = 0x00000040
export SATURATE_BIT_ATI
const SECONDARY_INTERPOLATOR_ATI = 0x896D
export SECONDARY_INTERPOLATOR_ATI
const SUB_ATI = 0x8965
export SUB_ATI
const SWIZZLE_STQ_ATI = 0x8977
export SWIZZLE_STQ_ATI
const SWIZZLE_STQ_DQ_ATI = 0x8979
export SWIZZLE_STQ_DQ_ATI
const SWIZZLE_STRQ_ATI = 0x897A
export SWIZZLE_STRQ_ATI
const SWIZZLE_STRQ_DQ_ATI = 0x897B
export SWIZZLE_STRQ_DQ_ATI
const SWIZZLE_STR_ATI = 0x8976
export SWIZZLE_STR_ATI
const SWIZZLE_STR_DR_ATI = 0x8978
export SWIZZLE_STR_DR_ATI
const RENDERBUFFER_FREE_MEMORY_ATI = 0x87FD
export RENDERBUFFER_FREE_MEMORY_ATI
const TEXTURE_FREE_MEMORY_ATI = 0x87FC
export TEXTURE_FREE_MEMORY_ATI
const VBO_FREE_MEMORY_ATI = 0x87FB
export VBO_FREE_MEMORY_ATI
const COLOR_CLEAR_UNCLAMPED_VALUE_ATI = 0x8835
export COLOR_CLEAR_UNCLAMPED_VALUE_ATI
const RGBA_FLOAT_MODE_ATI = 0x8820
export RGBA_FLOAT_MODE_ATI
const MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F1
export MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI
const PN_TRIANGLES_ATI = 0x87F0
export PN_TRIANGLES_ATI
const PN_TRIANGLES_NORMAL_MODE_ATI = 0x87F3
export PN_TRIANGLES_NORMAL_MODE_ATI
const PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI = 0x87F7
export PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI
const PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI = 0x87F8
export PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI
const PN_TRIANGLES_POINT_MODE_ATI = 0x87F2
export PN_TRIANGLES_POINT_MODE_ATI
const PN_TRIANGLES_POINT_MODE_CUBIC_ATI = 0x87F6
export PN_TRIANGLES_POINT_MODE_CUBIC_ATI
const PN_TRIANGLES_POINT_MODE_LINEAR_ATI = 0x87F5
export PN_TRIANGLES_POINT_MODE_LINEAR_ATI
const PN_TRIANGLES_TESSELATION_LEVEL_ATI = 0x87F4
export PN_TRIANGLES_TESSELATION_LEVEL_ATI
const STENCIL_BACK_FAIL_ATI = 0x8801
export STENCIL_BACK_FAIL_ATI
const STENCIL_BACK_FUNC_ATI = 0x8800
export STENCIL_BACK_FUNC_ATI
const STENCIL_BACK_PASS_DEPTH_FAIL_ATI = 0x8802
export STENCIL_BACK_PASS_DEPTH_FAIL_ATI
const STENCIL_BACK_PASS_DEPTH_PASS_ATI = 0x8803
export STENCIL_BACK_PASS_DEPTH_PASS_ATI
const TEXT_FRAGMENT_SHADER_ATI = 0x8200
export TEXT_FRAGMENT_SHADER_ATI
const MODULATE_ADD_ATI = 0x8744
export MODULATE_ADD_ATI
const MODULATE_SIGNED_ADD_ATI = 0x8745
export MODULATE_SIGNED_ADD_ATI
const MODULATE_SUBTRACT_ATI = 0x8746
export MODULATE_SUBTRACT_ATI
const ALPHA_FLOAT16_ATI = 0x881C
export ALPHA_FLOAT16_ATI
const ALPHA_FLOAT32_ATI = 0x8816
export ALPHA_FLOAT32_ATI
const INTENSITY_FLOAT16_ATI = 0x881D
export INTENSITY_FLOAT16_ATI
const INTENSITY_FLOAT32_ATI = 0x8817
export INTENSITY_FLOAT32_ATI
const LUMINANCE_ALPHA_FLOAT16_ATI = 0x881F
export LUMINANCE_ALPHA_FLOAT16_ATI
const LUMINANCE_ALPHA_FLOAT32_ATI = 0x8819
export LUMINANCE_ALPHA_FLOAT32_ATI
const LUMINANCE_FLOAT16_ATI = 0x881E
export LUMINANCE_FLOAT16_ATI
const LUMINANCE_FLOAT32_ATI = 0x8818
export LUMINANCE_FLOAT32_ATI
const RGBA_FLOAT16_ATI = 0x881A
export RGBA_FLOAT16_ATI
const RGBA_FLOAT32_ATI = 0x8814
export RGBA_FLOAT32_ATI
const RGB_FLOAT16_ATI = 0x881B
export RGB_FLOAT16_ATI
const RGB_FLOAT32_ATI = 0x8815
export RGB_FLOAT32_ATI
const MIRROR_CLAMP_ATI = 0x8742
export MIRROR_CLAMP_ATI
const MIRROR_CLAMP_TO_EDGE_ATI = 0x8743
export MIRROR_CLAMP_TO_EDGE_ATI
const ARRAY_OBJECT_BUFFER_ATI = 0x8766
export ARRAY_OBJECT_BUFFER_ATI
const ARRAY_OBJECT_OFFSET_ATI = 0x8767
export ARRAY_OBJECT_OFFSET_ATI
const DISCARD_ATI = 0x8763
export DISCARD_ATI
const DYNAMIC_ATI = 0x8761
export DYNAMIC_ATI
const OBJECT_BUFFER_SIZE_ATI = 0x8764
export OBJECT_BUFFER_SIZE_ATI
const OBJECT_BUFFER_USAGE_ATI = 0x8765
export OBJECT_BUFFER_USAGE_ATI
const PRESERVE_ATI = 0x8762
export PRESERVE_ATI
const STATIC_ATI = 0x8760
export STATIC_ATI
const MAX_VERTEX_STREAMS_ATI = 0x876B
export MAX_VERTEX_STREAMS_ATI
const VERTEX_SOURCE_ATI = 0x8774
export VERTEX_SOURCE_ATI
const VERTEX_STREAM0_ATI = 0x876C
export VERTEX_STREAM0_ATI
const VERTEX_STREAM1_ATI = 0x876D
export VERTEX_STREAM1_ATI
const VERTEX_STREAM2_ATI = 0x876E
export VERTEX_STREAM2_ATI
const VERTEX_STREAM3_ATI = 0x876F
export VERTEX_STREAM3_ATI
const VERTEX_STREAM4_ATI = 0x8770
export VERTEX_STREAM4_ATI
const VERTEX_STREAM5_ATI = 0x8771
export VERTEX_STREAM5_ATI
const VERTEX_STREAM6_ATI = 0x8772
export VERTEX_STREAM6_ATI
const VERTEX_STREAM7_ATI = 0x8773
export VERTEX_STREAM7_ATI
@getCFun libGL glDrawBuffersATI glDrawBuffersATI(n::GLsizei, bufs::Ptr{GLenum})::Void
export glDrawBuffersATI
@getCFun libGL glElementPointerATI glElementPointerATI(type_::GLenum, pointer::Ptr{Void})::Void
export glElementPointerATI
@getCFun libGL glDrawElementArrayATI glDrawElementArrayATI(mode::GLenum, count::GLsizei)::Void
export glDrawElementArrayATI
@getCFun libGL glDrawRangeElementArrayATI glDrawRangeElementArrayATI(mode::GLenum, start::GLuint, END::GLuint, count::GLsizei)::Void
export glDrawRangeElementArrayATI
@getCFun libGL glTexBumpParameterivATI glTexBumpParameterivATI(pname::GLenum, param::Ptr{GLint})::Void
export glTexBumpParameterivATI
@getCFun libGL glTexBumpParameterfvATI glTexBumpParameterfvATI(pname::GLenum, param::Ptr{GLfloat})::Void
export glTexBumpParameterfvATI
@getCFun libGL glGetTexBumpParameterivATI glGetTexBumpParameterivATI(pname::GLenum, param::Ptr{GLint})::Void
export glGetTexBumpParameterivATI
@getCFun libGL glGetTexBumpParameterfvATI glGetTexBumpParameterfvATI(pname::GLenum, param::Ptr{GLfloat})::Void
export glGetTexBumpParameterfvATI
@getCFun libGL glGenFragmentShadersATI glGenFragmentShadersATI(range_::GLuint)::Cuint
export glGenFragmentShadersATI
@getCFun libGL glBindFragmentShaderATI glBindFragmentShaderATI(id::GLuint)::Void
export glBindFragmentShaderATI
@getCFun libGL glDeleteFragmentShaderATI glDeleteFragmentShaderATI(id::GLuint)::Void
export glDeleteFragmentShaderATI
@getCFun libGL glBeginFragmentShaderATI glBeginFragmentShaderATI()::Void
export glBeginFragmentShaderATI
@getCFun libGL glEndFragmentShaderATI glEndFragmentShaderATI()::Void
export glEndFragmentShaderATI
@getCFun libGL glPassTexCoordATI glPassTexCoordATI(dst::GLuint, coord::GLuint, swizzle::GLenum)::Void
export glPassTexCoordATI
@getCFun libGL glSampleMapATI glSampleMapATI(dst::GLuint, interp::GLuint, swizzle::GLenum)::Void
export glSampleMapATI
@getCFun libGL glColorFragmentOp1ATI glColorFragmentOp1ATI(op::GLenum, dst::GLuint, dstMask::GLuint, dstMod::GLuint, arg1::GLuint, arg1Rep::GLuint, arg1Mod::GLuint)::Void
export glColorFragmentOp1ATI
@getCFun libGL glColorFragmentOp2ATI glColorFragmentOp2ATI(op::GLenum, dst::GLuint, dstMask::GLuint, dstMod::GLuint, arg1::GLuint, arg1Rep::GLuint, arg1Mod::GLuint, arg2::GLuint, arg2Rep::GLuint, arg2Mod::GLuint)::Void
export glColorFragmentOp2ATI
@getCFun libGL glColorFragmentOp3ATI glColorFragmentOp3ATI(op::GLenum, dst::GLuint, dstMask::GLuint, dstMod::GLuint, arg1::GLuint, arg1Rep::GLuint, arg1Mod::GLuint, arg2::GLuint, arg2Rep::GLuint, arg2Mod::GLuint, arg3::GLuint, arg3Rep::GLuint, arg3Mod::GLuint)::Void
export glColorFragmentOp3ATI
@getCFun libGL glAlphaFragmentOp1ATI glAlphaFragmentOp1ATI(op::GLenum, dst::GLuint, dstMod::GLuint, arg1::GLuint, arg1Rep::GLuint, arg1Mod::GLuint)::Void
export glAlphaFragmentOp1ATI
@getCFun libGL glAlphaFragmentOp2ATI glAlphaFragmentOp2ATI(op::GLenum, dst::GLuint, dstMod::GLuint, arg1::GLuint, arg1Rep::GLuint, arg1Mod::GLuint, arg2::GLuint, arg2Rep::GLuint, arg2Mod::GLuint)::Void
export glAlphaFragmentOp2ATI
@getCFun libGL glAlphaFragmentOp3ATI glAlphaFragmentOp3ATI(op::GLenum, dst::GLuint, dstMod::GLuint, arg1::GLuint, arg1Rep::GLuint, arg1Mod::GLuint, arg2::GLuint, arg2Rep::GLuint, arg2Mod::GLuint, arg3::GLuint, arg3Rep::GLuint, arg3Mod::GLuint)::Void
export glAlphaFragmentOp3ATI
@getCFun libGL glSetFragmentShaderConstantATI glSetFragmentShaderConstantATI(dst::GLuint, value::Ptr{GLfloat})::Void
export glSetFragmentShaderConstantATI
@getCFun libGL glMapObjectBufferATI glMapObjectBufferATI(buffer::GLuint)::Ptr{Void}
export glMapObjectBufferATI
@getCFun libGL glUnmapObjectBufferATI glUnmapObjectBufferATI(buffer::GLuint)::Void
export glUnmapObjectBufferATI
@getCFun libGL glPNTrianglesiATI glPNTrianglesiATI(pname::GLenum, param::GLint)::Void
export glPNTrianglesiATI
@getCFun libGL glPNTrianglesfATI glPNTrianglesfATI(pname::GLenum, param::GLfloat)::Void
export glPNTrianglesfATI
@getCFun libGL glStencilOpSeparateATI glStencilOpSeparateATI(face::GLenum, sfail::GLenum, dpfail::GLenum, dppass::GLenum)::Void
export glStencilOpSeparateATI
@getCFun libGL glStencilFuncSeparateATI glStencilFuncSeparateATI(frontfunc::GLenum, backfunc::GLenum, ref::GLint, mask::GLuint)::Void
export glStencilFuncSeparateATI
@getCFun libGL glNewObjectBufferATI glNewObjectBufferATI(size::GLsizei, pointer::Ptr{Void}, usage::GLenum)::Cuint
export glNewObjectBufferATI
@getCFun libGL glIsObjectBufferATI glIsObjectBufferATI(buffer::GLuint)::Bool
export glIsObjectBufferATI
@getCFun libGL glUpdateObjectBufferATI glUpdateObjectBufferATI(buffer::GLuint, offset::GLuint, size::GLsizei, pointer::Ptr{Void}, preserve::GLenum)::Void
export glUpdateObjectBufferATI
@getCFun libGL glGetObjectBufferfvATI glGetObjectBufferfvATI(buffer::GLuint, pname::GLenum, params::Ptr{GLfloat})::Void
export glGetObjectBufferfvATI
@getCFun libGL glGetObjectBufferivATI glGetObjectBufferivATI(buffer::GLuint, pname::GLenum, params::Ptr{GLint})::Void
export glGetObjectBufferivATI
@getCFun libGL glFreeObjectBufferATI glFreeObjectBufferATI(buffer::GLuint)::Void
export glFreeObjectBufferATI
@getCFun libGL glArrayObjectATI glArrayObjectATI(array::GLenum, size::GLint, type_::GLenum, stride::GLsizei, buffer::GLuint, offset::GLuint)::Void
export glArrayObjectATI
@getCFun libGL glGetArrayObjectfvATI glGetArrayObjectfvATI(array::GLenum, pname::GLenum, params::Ptr{GLfloat})::Void
export glGetArrayObjectfvATI
@getCFun libGL glGetArrayObjectivATI glGetArrayObjectivATI(array::GLenum, pname::GLenum, params::Ptr{GLint})::Void
export glGetArrayObjectivATI
@getCFun libGL glVariantArrayObjectATI glVariantArrayObjectATI(id::GLuint, type_::GLenum, stride::GLsizei, buffer::GLuint, offset::GLuint)::Void
export glVariantArrayObjectATI
@getCFun libGL glGetVariantArrayObjectfvATI glGetVariantArrayObjectfvATI(id::GLuint, pname::GLenum, params::Ptr{GLfloat})::Void
export glGetVariantArrayObjectfvATI
@getCFun libGL glGetVariantArrayObjectivATI glGetVariantArrayObjectivATI(id::GLuint, pname::GLenum, params::Ptr{GLint})::Void
export glGetVariantArrayObjectivATI
@getCFun libGL glVertexAttribArrayObjectATI glVertexAttribArrayObjectATI(index::GLuint, size::GLint, type_::GLenum, normalized::GLboolean, stride::GLsizei, buffer::GLuint, offset::GLuint)::Void
export glVertexAttribArrayObjectATI
@getCFun libGL glGetVertexAttribArrayObjectfvATI glGetVertexAttribArrayObjectfvATI(index::GLuint, pname::GLenum, params::Ptr{GLfloat})::Void
export glGetVertexAttribArrayObjectfvATI
@getCFun libGL glGetVertexAttribArrayObjectivATI glGetVertexAttribArrayObjectivATI(index::GLuint, pname::GLenum, params::Ptr{GLint})::Void
export glGetVertexAttribArrayObjectivATI
@getCFun libGL glVertexStream1sATI glVertexStream1sATI(stream::GLenum, x::GLshort)::Void
export glVertexStream1sATI
@getCFun libGL glVertexStream1svATI glVertexStream1svATI(stream::GLenum, coords::Ptr{GLshort})::Void
export glVertexStream1svATI
@getCFun libGL glVertexStream1iATI glVertexStream1iATI(stream::GLenum, x::GLint)::Void
export glVertexStream1iATI
@getCFun libGL glVertexStream1ivATI glVertexStream1ivATI(stream::GLenum, coords::Ptr{GLint})::Void
export glVertexStream1ivATI
@getCFun libGL glVertexStream1fATI glVertexStream1fATI(stream::GLenum, x::GLfloat)::Void
export glVertexStream1fATI
@getCFun libGL glVertexStream1fvATI glVertexStream1fvATI(stream::GLenum, coords::Ptr{GLfloat})::Void
export glVertexStream1fvATI
@getCFun libGL glVertexStream1dATI glVertexStream1dATI(stream::GLenum, x::GLdouble)::Void
export glVertexStream1dATI
@getCFun libGL glVertexStream1dvATI glVertexStream1dvATI(stream::GLenum, coords::Ptr{GLdouble})::Void
export glVertexStream1dvATI
@getCFun libGL glVertexStream2sATI glVertexStream2sATI(stream::GLenum, x::GLshort, y::GLshort)::Void
export glVertexStream2sATI
@getCFun libGL glVertexStream2svATI glVertexStream2svATI(stream::GLenum, coords::Ptr{GLshort})::Void
export glVertexStream2svATI
@getCFun libGL glVertexStream2iATI glVertexStream2iATI(stream::GLenum, x::GLint, y::GLint)::Void
export glVertexStream2iATI
@getCFun libGL glVertexStream2ivATI glVertexStream2ivATI(stream::GLenum, coords::Ptr{GLint})::Void
export glVertexStream2ivATI
@getCFun libGL glVertexStream2fATI glVertexStream2fATI(stream::GLenum, x::GLfloat, y::GLfloat)::Void
export glVertexStream2fATI
@getCFun libGL glVertexStream2fvATI glVertexStream2fvATI(stream::GLenum, coords::Ptr{GLfloat})::Void
export glVertexStream2fvATI
@getCFun libGL glVertexStream2dATI glVertexStream2dATI(stream::GLenum, x::GLdouble, y::GLdouble)::Void
export glVertexStream2dATI
@getCFun libGL glVertexStream2dvATI glVertexStream2dvATI(stream::GLenum, coords::Ptr{GLdouble})::Void
export glVertexStream2dvATI
@getCFun libGL glVertexStream3sATI glVertexStream3sATI(stream::GLenum, x::GLshort, y::GLshort, z::GLshort)::Void
export glVertexStream3sATI
@getCFun libGL glVertexStream3svATI glVertexStream3svATI(stream::GLenum, coords::Ptr{GLshort})::Void
export glVertexStream3svATI
@getCFun libGL glVertexStream3iATI glVertexStream3iATI(stream::GLenum, x::GLint, y::GLint, z::GLint)::Void
export glVertexStream3iATI
@getCFun libGL glVertexStream3ivATI glVertexStream3ivATI(stream::GLenum, coords::Ptr{GLint})::Void
export glVertexStream3ivATI
@getCFun libGL glVertexStream3fATI glVertexStream3fATI(stream::GLenum, x::GLfloat, y::GLfloat, z::GLfloat)::Void
export glVertexStream3fATI
@getCFun libGL glVertexStream3fvATI glVertexStream3fvATI(stream::GLenum, coords::Ptr{GLfloat})::Void
export glVertexStream3fvATI
@getCFun libGL glVertexStream3dATI glVertexStream3dATI(stream::GLenum, x::GLdouble, y::GLdouble, z::GLdouble)::Void
export glVertexStream3dATI
@getCFun libGL glVertexStream3dvATI glVertexStream3dvATI(stream::GLenum, coords::Ptr{GLdouble})::Void
export glVertexStream3dvATI
@getCFun libGL glVertexStream4sATI glVertexStream4sATI(stream::GLenum, x::GLshort, y::GLshort, z::GLshort, w::GLshort)::Void
export glVertexStream4sATI
@getCFun libGL glVertexStream4svATI glVertexStream4svATI(stream::GLenum, coords::Ptr{GLshort})::Void
export glVertexStream4svATI
@getCFun libGL glVertexStream4iATI glVertexStream4iATI(stream::GLenum, x::GLint, y::GLint, z::GLint, w::GLint)::Void
export glVertexStream4iATI
@getCFun libGL glVertexStream4ivATI glVertexStream4ivATI(stream::GLenum, coords::Ptr{GLint})::Void
export glVertexStream4ivATI
@getCFun libGL glVertexStream4fATI glVertexStream4fATI(stream::GLenum, x::GLfloat, y::GLfloat, z::GLfloat, w::GLfloat)::Void
export glVertexStream4fATI
@getCFun libGL glVertexStream4fvATI glVertexStream4fvATI(stream::GLenum, coords::Ptr{GLfloat})::Void
export glVertexStream4fvATI
@getCFun libGL glVertexStream4dATI glVertexStream4dATI(stream::GLenum, x::GLdouble, y::GLdouble, z::GLdouble, w::GLdouble)::Void
export glVertexStream4dATI
@getCFun libGL glVertexStream4dvATI glVertexStream4dvATI(stream::GLenum, coords::Ptr{GLdouble})::Void
export glVertexStream4dvATI
@getCFun libGL glNormalStream3bATI glNormalStream3bATI(stream::GLenum, nx::GLbyte, ny::GLbyte, nz::GLbyte)::Void
export glNormalStream3bATI
@getCFun libGL glNormalStream3bvATI glNormalStream3bvATI(stream::GLenum, coords::Ptr{GLbyte})::Void
export glNormalStream3bvATI
@getCFun libGL glNormalStream3sATI glNormalStream3sATI(stream::GLenum, nx::GLshort, ny::GLshort, nz::GLshort)::Void
export glNormalStream3sATI
@getCFun libGL glNormalStream3svATI glNormalStream3svATI(stream::GLenum, coords::Ptr{GLshort})::Void
export glNormalStream3svATI
@getCFun libGL glNormalStream3iATI glNormalStream3iATI(stream::GLenum, nx::GLint, ny::GLint, nz::GLint)::Void
export glNormalStream3iATI
@getCFun libGL glNormalStream3ivATI glNormalStream3ivATI(stream::GLenum, coords::Ptr{GLint})::Void
export glNormalStream3ivATI
@getCFun libGL glNormalStream3fATI glNormalStream3fATI(stream::GLenum, nx::GLfloat, ny::GLfloat, nz::GLfloat)::Void
export glNormalStream3fATI
@getCFun libGL glNormalStream3fvATI glNormalStream3fvATI(stream::GLenum, coords::Ptr{GLfloat})::Void
export glNormalStream3fvATI
@getCFun libGL glNormalStream3dATI glNormalStream3dATI(stream::GLenum, nx::GLdouble, ny::GLdouble, nz::GLdouble)::Void
export glNormalStream3dATI
@getCFun libGL glNormalStream3dvATI glNormalStream3dvATI(stream::GLenum, coords::Ptr{GLdouble})::Void
export glNormalStream3dvATI
@getCFun libGL glClientActiveVertexStreamATI glClientActiveVertexStreamATI(stream::GLenum)::Void
export glClientActiveVertexStreamATI
@getCFun libGL glVertexBlendEnviATI glVertexBlendEnviATI(pname::GLenum, param::GLint)::Void
export glVertexBlendEnviATI
@getCFun libGL glVertexBlendEnvfATI glVertexBlendEnvfATI(pname::GLenum, param::GLfloat)::Void
export glVertexBlendEnvfATI

end


text:
using SQLite
using Test, Dates, Random, WeakRefStrings, Tables, DBInterface

import Base: +, ==
mutable struct Point{T}
    x::T
    y::T
end
==(a::Point, b::Point) = a.x == b.x && a.y == b.y

mutable struct Point3D{T<:Number}
    x::T
    y::T
    z::T
end
==(a::Point3D, b::Point3D) = a.x == b.x && a.y == b.y && a.z == b.z
+(a::Point3D, b::Point3D) = Point3D(a.x + b.x, a.y + b.y, a.z + b.z)

triple(x) = 3x
function add4(q)
    q+4
end
mult(args...) = *(args...)
str2arr(s) = Vector{UInt8}(s)
doublesum_step(persist, current) = persist + current
doublesum_final(persist) = 2 * persist
mycount(p, c) = p + 1
bigsum(p, c) = p + big(c)
sumpoint(p::Point3D, x, y, z) = p + Point3D(x, y, z)

dbfile = joinpath(dirname(pathof(SQLite)), "../test/Chinook_Sqlite.sqlite")
dbfile2 = joinpath(tempdir(), "test.sqlite")
cp(dbfile, dbfile2; force=true)
chmod(dbfile2, 0o777)

@testset "basics" begin

db = SQLite.DB(dbfile2)
db = DBInterface.connect(SQLite.DB, dbfile2)
# regular SQLite tests
ds = DBInterface.execute(db, "SELECT name FROM sqlite_master WHERE type='table';") |> columntable
@test length(ds) == 1
@test keys(ds) == (:name,)
@test length(ds.name) == 11

results1 = SQLite.tables(db)
@test isequal(ds, results1)

results = DBInterface.execute(db, "SELECT * FROM Employee;") |> columntable
@test length(results) == 15
@test length(results[1]) == 8

DBInterface.execute(db, "create table temp as select * from album")
DBInterface.execute(db, "alter table temp add column colyear int")
DBInterface.execute(db, "update temp set colyear = 2014")
r = DBInterface.execute(db, "select * from temp limit 10") |> columntable
@test length(r) == 4 && length(r[1]) == 10
@test all(Bool[x == 2014 for x in r[4]])

DBInterface.execute(db, "alter table temp add column dates blob")
stmt = DBInterface.prepare(db, "update temp set dates = ?")
DBInterface.execute(stmt, (Date(2014,1,1),))

r = DBInterface.execute(db, "select * from temp limit 10") |> columntable
@test length(r) == 5 && length(r[1]) == 10
@test typeof(r[5][1]) == Date
@test all(Bool[x == Date(2014,1,1) for x in r[5]])
DBInterface.execute(db, "drop table temp")

rng = Dates.Date(2013):Dates.Day(1):Dates.Date(2013,1,5)
dt = (i=collect(rng), j=collect(rng))
tablename = dt |> SQLite.load!(db, "temp")
r = DBInterface.execute(db, "select * from $tablename") |> columntable
@test length(r) == 2 && length(r[1]) == 5
@test all([i for i in r[1]] .== collect(rng))
@test all([typeof(i) for i in r[1]] .== Dates.Date)
SQLite.drop!(db, "$tablename")

DBInterface.execute(db, "CREATE TABLE temp AS SELECT * FROM Album")
r = DBInterface.execute(db, "SELECT * FROM temp LIMIT ?", [3]) |> columntable
@test length(r) == 3 && length(r[1]) == 3
r = DBInterface.execute(db, "SELECT * FROM temp WHERE Title LIKE ?", ["%time%"]) |> columntable
@test r[1] == [76, 111, 187]
DBInterface.execute(db, "INSERT INTO temp VALUES (?1, ?3, ?2)", [0,0, "Test Album"])
r = DBInterface.execute(db, "SELECT * FROM temp WHERE AlbumId = 0") |> columntable
@test r[1][1] === 0
@test r[2][1] == "Test Album"
@test r[3][1] === 0
SQLite.drop!(db, "temp")

DBInterface.execute(db, "CREATE TABLE temp AS SELECT * FROM Album")
r = DBInterface.execute(db, "SELECT * FROM temp LIMIT :a", (a=3,)) |> columntable
@test length(r) == 3 && length(r[1]) == 3
r = DBInterface.execute(db, "SELECT * FROM temp WHERE Title LIKE @word", (word="%time%",)) |> columntable
@test r[1] == [76, 111, 187]
DBInterface.execute(db, "INSERT INTO temp VALUES (@lid, :title, \$rid)", (rid=0, lid=0, title="Test Album"))
r = DBInterface.execute(db, "SELECT * FROM temp WHERE AlbumId = 0") |> columntable
@test r[1][1] === 0
@test r[2][1] == "Test Album"
@test r[3][1] === 0
SQLite.drop!(db, "temp")

SQLite.register(db, SQLite.regexp, nargs=2, name="regexp")
r = DBInterface.execute(db, SQLite.@sr_str("SELECT LastName FROM Employee WHERE BirthDate REGEXP '^\\d{4}-08'")) |> columntable
@test r[1][1] == "Peacock"

@test_throws AssertionError SQLite.register(db, triple, nargs=186)
SQLite.register(db, triple, nargs=1)
r = DBInterface.execute(db, "SELECT triple(Total) FROM Invoice ORDER BY InvoiceId LIMIT 5") |> columntable
s = DBInterface.execute(db, "SELECT Total FROM Invoice ORDER BY InvoiceId LIMIT 5") |> columntable
for (i, j) in zip(r[1], s[1])
    @test abs(i - 3*j) < 0.02
end

SQLite.@register db add4
r = DBInterface.execute(db, "SELECT add4(AlbumId) FROM Album") |> columntable
s = DBInterface.execute(db, "SELECT AlbumId FROM Album") |> columntable
@test r[1][1] == s[1][1] + 4

SQLite.@register db mult
r = DBInterface.execute(db, "SELECT Milliseconds, Bytes FROM Track") |> columntable
s = DBInterface.execute(db, "SELECT mult(Milliseconds, Bytes) FROM Track") |> columntable
@test (r[1][1] * r[2][1]) == s[1][1]
t = DBInterface.execute(db, "SELECT mult(Milliseconds, Bytes, 3, 4) FROM Track") |> columntable
@test (r[1][1] * r[2][1] * 3 * 4) == t[1][1]

SQLite.@register db sin
u = DBInterface.execute(db, "select sin(milliseconds) from track limit 5") |> columntable
@test all(-1 .< convert(Vector{Float64},u[1]) .< 1)

SQLite.register(db, hypot; nargs=2, name="hypotenuse")
v = DBInterface.execute(db, "select hypotenuse(Milliseconds,bytes) from track limit 5") |> columntable
@test [round(Int,i) for i in v[1]] == [11175621,5521062,3997652,4339106,6301714]

SQLite.@register db str2arr
r = DBInterface.execute(db, "SELECT str2arr(LastName) FROM Employee LIMIT 2") |> columntable
@test r[1][2] == UInt8[0x45,0x64,0x77,0x61,0x72,0x64,0x73]

SQLite.@register db big
r = DBInterface.execute(db, "SELECT big(5)") |> columntable
@test r[1][1] == big(5)
@test typeof(r[1][1]) == BigInt

SQLite.register(db, 0, doublesum_step, doublesum_final, name="doublesum")
r = DBInterface.execute(db, "SELECT doublesum(UnitPrice) FROM Track") |> columntable
s = DBInterface.execute(db, "SELECT UnitPrice FROM Track") |> columntable
@test abs(r[1][1] - 2*sum(convert(Vector{Float64},s[1]))) < 0.02

SQLite.register(db, 0, mycount)
r = DBInterface.execute(db, "SELECT mycount(TrackId) FROM PlaylistTrack") |> columntable
s = DBInterface.execute(db, "SELECT count(TrackId) FROM PlaylistTrack") |> columntable
@test r[1][1] == s[1][1]

SQLite.register(db, big(0), bigsum)
r = DBInterface.execute(db, "SELECT bigsum(TrackId) FROM PlaylistTrack") |> columntable
s = DBInterface.execute(db, "SELECT TrackId FROM PlaylistTrack") |> columntable
@test r[1][1] == big(sum(convert(Vector{Int},s[1])))

DBInterface.execute(db, "CREATE TABLE points (x INT, y INT, z INT)")
DBInterface.execute(db, "INSERT INTO points VALUES (?, ?, ?)", (1, 2, 3))
DBInterface.execute(db, "INSERT INTO points VALUES (?, ?, ?)", (4, 5, 6))
DBInterface.execute(db, "INSERT INTO points VALUES (?, ?, ?)", (7, 8, 9))

SQLite.register(db, Point3D(0, 0, 0), sumpoint)
r = DBInterface.execute(db, "SELECT sumpoint(x, y, z) FROM points") |> columntable
@test r[1][1] == Point3D(12, 15, 18)
SQLite.drop!(db, "points")

db2 = DBInterface.connect(SQLite.DB)
DBInterface.execute(db2, "CREATE TABLE tab1 (r REAL, s INT)")

@test_throws SQLite.SQLiteException SQLite.drop!(db2, "nonexistant")
# should not throw anything
SQLite.drop!(db2, "nonexistant", ifexists=true)
# should drop "tab2"
SQLite.drop!(db2, "tab2", ifexists=true)
@test !in("tab2", SQLite.tables(db2)[1])

SQLite.drop!(db, "sqlite_stat1", ifexists=true)
tables = SQLite.tables(db)
@test length(tables[1]) == 11

#Test removeduplicates!
db = SQLite.DB() #In case the order of tests is changed
dt = (ints=Int64[1,1,2,2,3], strs=["A", "A", "B", "C", "C"])
tablename = dt |> SQLite.load!(db, "temp")
SQLite.removeduplicates!(db, "temp", ["ints", "strs"]) #New format
dt3 = DBInterface.execute(db, "Select * from temp") |> columntable
@test dt3[1][1] == 1
@test dt3[2][1] == "A"
@test dt3[1][2] == 2
@test dt3[2][2] == "B"
@test dt3[1][3] == 2
@test dt3[2][3] == "C"

# issue #104
db = SQLite.DB() #In case the order of tests is changed
DBInterface.execute(db, "CREATE TABLE IF NOT EXISTS tbl(a  INTEGER);")
stmt = DBInterface.prepare(db, "INSERT INTO tbl (a) VALUES (@a);")
SQLite.bind!(stmt, "@a", 1)
SQLite.clear!(stmt)

binddb = SQLite.DB()
DBInterface.execute(binddb, "CREATE TABLE temp (n NULL, i6 INT, f REAL, s TEXT, a BLOB)")
DBInterface.execute(binddb, "INSERT INTO temp VALUES (?1, ?2, ?3, ?4, ?5)", [missing, Int64(6), 6.4, "some text", b"bytearray"])
r = DBInterface.execute(binddb, "SELECT * FROM temp") |> columntable
@test isa(r[1][1], Missing)
@test isa(r[2][1], Int)
@test isa(r[3][1], Float64)
@test isa(r[4][1], AbstractString)
@test isa(r[5][1], Base.CodeUnits)

############################################

#test for #158
@test_throws SQLite.SQLiteException SQLite.DB("nonexistentdir/not_there.db")

#test for #180 (Query)
param = "Hello!"
query = DBInterface.execute(SQLite.DB(), "SELECT ?1 UNION ALL SELECT ?1", [param])
param = "x"
for row in query
    @test row[1] == "Hello!"
    GC.gc() # this must NOT garbage collect the "Hello!" bound value
end

db = SQLite.DB()
DBInterface.execute(db, "CREATE TABLE T (a TEXT, PRIMARY KEY (a))")

q = DBInterface.prepare(db, "INSERT INTO T VALUES(?)")
DBInterface.execute(q, ["a"])

SQLite.bind!(q, 1, "a")
@test_throws AssertionError DBInterface.execute(q)

@test SQLite.@OK SQLite.enable_load_extension(db)
show(db)
DBInterface.close!(db)

db = SQLite.DB()
DBInterface.execute(db, "CREATE TABLE T (x INT UNIQUE)")

q = DBInterface.prepare(db, "INSERT INTO T VALUES(?)")
SQLite.execute(q, (1,))
r = DBInterface.execute(db, "SELECT * FROM T") |> columntable
@test r[1][1] == 1

SQLite.execute(q, [2])
r = DBInterface.execute(db, "SELECT * FROM T") |> columntable
@test r[1][1] == 1
@test r[1][2] == 2

q = DBInterface.prepare(db, "INSERT INTO T VALUES(:x)")
SQLite.execute(q, Dict(:x => 3))
r = DBInterface.execute(db, "SELECT * FROM T") |> columntable
@test r[1][1] == 1
@test r[1][2] == 2
@test r[1][3] == 3

r = DBInterface.execute(db, strip("   SELECT * FROM T  ")) |> columntable
@test r[1][1] == 1
@test r[1][2] == 2
@test r[1][3] == 3

@test SQLite.esc_id(["1", "2", "3"]) == "\"1\",\"2\",\"3\""

SQLite.createindex!(db, "T", "x", "x_index"; unique=false)
inds = SQLite.indices(db)
@test inds.name[2] == "x"
SQLite.dropindex!(db, "x")
@test length(SQLite.indices(db).name) == 1

cols = SQLite.columns(db, "T")
@test cols.name[1] == "x"

@test SQLite.last_insert_rowid(db) == 3

r = DBInterface.execute(db, "SELECT * FROM T")
@test Tables.istable(r)
@test Tables.rowaccess(r)
@test Tables.rows(r) === r
@test Base.IteratorSize(typeof(r)) ==  Base.SizeUnknown()
@test eltype(r) == SQLite.Row
row = first(r)
SQLite.reset!(r)
row2 = first(r)
@test row[:x] == row2[:x]
@test propertynames(row) == [:x]
@test DBInterface.lastrowid(r) == 3

r = DBInterface.execute(db, "SELECT * FROM T") |> columntable
SQLite.load!(nothing, Tables.rows(r), db, "T2", "T2", true)
r2 = DBInterface.execute(db, "SELECT * FROM T2") |> columntable
@test r == r2

# throw informative error on duplicate column names #193
@test_throws ErrorException SQLite.load!((a=[1,2,3], A=[1,2,3]), db)

end # @testset

ext: jl


text:
# UnitCommitment.jl: Optimization Package for Security-Constrained Unit Commitment
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.

"""
Lazy constraint solution method described in:

    Xavier, A. S., Qiu, F., Wang, F., & Thimmapuram, P. R. (2019). Transmission
    constraint filtering in large-scale security-constrained unit commitment.
    IEEE Transactions on Power Systems, 34(3), 2457-2460.
    DOI: https://doi.org/10.1109/TPWRS.2019.2892620
"""
module XavQiuWanThi2019
import ..SolutionMethod
"""
    struct Method
        time_limit::Float64
        gap_limit::Float64
        two_phase_gap::Bool
        max_violations_per_line::Int
        max_violations_per_period::Int
    end

Fields
------

- `time_limit`:
    the time limit over the entire optimization procedure.
- `gap_limit`:
    the desired relative optimality gap.
- `two_phase_gap`:
    if true, solve the problem with large gap tolerance first, then reduce
    the gap tolerance when no further violated constraints are found.
- `max_violations_per_line`:
    maximum number of violated transmission constraints to add to the
    formulation per transmission line.
- `max_violations_per_period`:
    maximum number of violated transmission constraints to add to the
    formulation per time period.

"""
struct Method <: SolutionMethod
    time_limit::Float64
    gap_limit::Float64
    two_phase_gap::Bool
    max_violations_per_line::Int
    max_violations_per_period::Int

    function Method(;
        time_limit::Float64 = 86400.0,
        gap_limit::Float64 = 1e-3,
        two_phase_gap::Bool = true,
        max_violations_per_line::Int = 1,
        max_violations_per_period::Int = 5,
    )
        return new(
            time_limit,
            gap_limit,
            two_phase_gap,
            max_violations_per_line,
            max_violations_per_period,
        )
    end
end
end

import DataStructures: PriorityQueue

struct _Violation
    time::Int
    monitored_line::TransmissionLine
    outage_line::Union{TransmissionLine,Nothing}
    amount::Float64

    function _Violation(;
        time::Int,
        monitored_line::TransmissionLine,
        outage_line::Union{TransmissionLine,Nothing},
        amount::Float64,
    )
        return new(time, monitored_line, outage_line, amount)
    end
end

mutable struct _ViolationFilter
    max_per_line::Int
    max_total::Int
    queues::Dict{Int,PriorityQueue{_Violation,Float64}}

    function _ViolationFilter(; max_per_line::Int = 1, max_total::Int = 5)
        return new(max_per_line, max_total, Dict())
    end
end


text:
using SpecialFunctions
using FastGaussQuadrature
using ClassicalOrthogonalPolynomials
using Plots
using JLD2
using FileIO
using LinearAlgebra
using SIMD
using LoopVectorization
using BenchmarkTools
using StaticArrays
using SparseArrays
using GeometryBasics
using MAT
include("DGBasis.jl")

include("FEMGeometry.jl")

include("DGToolbox.jl")


text:
import gmsh

gmsh.initialize()

gmsh.model.add("t4")

cm = 1e-02
e1 = 4.5 * cm; e2 = 6 * cm / 2; e3 =  5 * cm / 2
h1 = 5 * cm; h2 = 10 * cm; h3 = 5 * cm; h4 = 2 * cm; h5 = 4.5 * cm
R1 = 1 * cm; R2 = 1.5 * cm; r = 1 * cm
Lc1 = 0.01
Lc2 = 0.003

function hypot(a, b)
    return sqrt(a * a + b * b)
end

ccos = (-h5*R1 + e2 * hypot(h5, hypot(e2, R1))) / (h5*h5 + e2*e2)
ssin = sqrt(1 - ccos*ccos)

factory = gmsh.model.geo
factory.addPoint(-e1-e2, 0    , 0, Lc1, 1)
factory.addPoint(-e1-e2, h1   , 0, Lc1, 2)
factory.addPoint(-e3-r , h1   , 0, Lc2, 3)
factory.addPoint(-e3-r , h1+r , 0, Lc2, 4)
factory.addPoint(-e3   , h1+r , 0, Lc2, 5)
factory.addPoint(-e3   , h1+h2, 0, Lc1, 6)
factory.addPoint( e3   , h1+h2, 0, Lc1, 7)
factory.addPoint( e3   , h1+r , 0, Lc2, 8)
factory.addPoint( e3+r , h1+r , 0, Lc2, 9)
factory.addPoint( e3+r , h1   , 0, Lc2, 10)
factory.addPoint( e1+e2, h1   , 0, Lc1, 11)
factory.addPoint( e1+e2, 0    , 0, Lc1, 12)
factory.addPoint( e2   , 0    , 0, Lc1, 13)

factory.addPoint( R1 / ssin, h5+R1*ccos, 0, Lc2, 14)
factory.addPoint( 0        , h5        , 0, Lc2, 15)
factory.addPoint(-R1 / ssin, h5+R1*ccos, 0, Lc2, 16)
factory.addPoint(-e2       , 0.0       , 0, Lc1, 17)

factory.addPoint(-R2 , h1+h3   , 0, Lc2, 18)
factory.addPoint(-R2 , h1+h3+h4, 0, Lc2, 19)
factory.addPoint( 0  , h1+h3+h4, 0, Lc2, 20)
factory.addPoint( R2 , h1+h3+h4, 0, Lc2, 21)
factory.addPoint( R2 , h1+h3   , 0, Lc2, 22)
factory.addPoint( 0  , h1+h3   , 0, Lc2, 23)

factory.addPoint( 0, h1+h3+h4+R2, 0, Lc2, 24)
factory.addPoint( 0, h1+h3-R2,    0, Lc2, 25)

factory.addLine(1 , 17, 1)
factory.addLine(17, 16, 2)

factory.addCircleArc(14,15,16, 3)

factory.addLine(14,13, 4)
factory.addLine(13,12, 5)
factory.addLine(12,11, 6)
factory.addLine(11,10, 7)
factory.addCircleArc(8,9,10, 8)
factory.addLine(8,7, 9)
factory.addLine(7,6, 10)
factory.addLine(6,5, 11)
factory.addCircleArc(3,4,5, 12)
factory.addLine(3,2, 13)
factory.addLine(2,1, 14)
factory.addLine(18,19, 15)
factory.addCircleArc(21,20,24, 16)
factory.addCircleArc(24,20,19, 17)
factory.addCircleArc(18,23,25, 18)
factory.addCircleArc(25,23,22, 19)
factory.addLine(21,22, 20)

factory.addCurveLoop([17,-15,18,19,-20,16], 21)
factory.addPlaneSurface([21], 22)
factory.addCurveLoop([11,-12,13,14,1,2,-3,4,5,6,7,-8,9,10], 23)

factory.addPlaneSurface([23,21], 24)

factory.synchronize()

v = gmsh.view.add("comments")

gmsh.view.addListDataString(v, [10, -10], ["Created with Gmsh"])

gmsh.view.addListDataString(v, [0, 0.11, 0], ["Hole"],
                            ["Align", "Center", "Font", "Helvetica"])

gmsh.option.setString("View[0].DoubleClickedCommand",
                      "Printf('View[0] has been double-clicked!');")
gmsh.option.setString(
    "Geometry.DoubleClickedLineCommand",
    "Printf('Curve %g has been double-clicked!', Geometry.DoubleClickedEntityTag);")

gmsh.model.setColor([(2, 22)], 127, 127, 127)
gmsh.model.setColor([(2, 24)], 160, 32, 240)
gmsh.model.setColor([(1, i) for i in 1:14], 255, 0, 0)
gmsh.model.setColor([(1, i) for i in 15:20], 255, 255, 0)

gmsh.model.mesh.generate(2)

gmsh.write("t4.msh")

gmsh.finalize()

# This file was generated using Literate.jl, https://github.com/fredrikekre/Literate.jl


text:
@testset "PTX" begin

include("definitions/ptx.jl")

############################################################################################

@testset "IR" begin

@testset "exceptions" begin
    foobar() = throw(DivideError())
    ir = sprint(io->ptx_code_llvm(io, foobar, Tuple{}))

    # plain exceptions should get lowered to a call to the GPU run-time
    @test occursin("gpu_report_exception", ir)
    # not a jl_throw referencing a jl_value_t representing the exception
    @test !occursin("jl_throw", ir)
end

@testset "kernel functions" begin
@testset "kernel argument attributes" begin
    kernel(x) = return

    @eval struct Aggregate
        x::Int
    end

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{Aggregate}))
    if VERSION < v"1.5.0-DEV.802"
        @test occursin(r"@.*julia_kernel.+\(({ i64 }|\[1 x i64\]) addrspace\(\d+\)?\*", ir)
    else
        @test occursin(r"@.*julia_kernel.+\(({ i64 }|\[1 x i64\])\*", ir)
    end

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{Aggregate}; kernel=true))
    @test occursin(r"@.*julia_kernel.+\(({ i64 }|\[1 x i64\])", ir)
end

@testset "property_annotations" begin
    kernel() = return

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{}; dump_module=true))
    @test !occursin("nvvm.annotations", ir)

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{};
                                         dump_module=true, kernel=true))
    @test occursin("nvvm.annotations", ir)
    @test !occursin("maxntid", ir)
    @test !occursin("reqntid", ir)
    @test !occursin("minctasm", ir)
    @test !occursin("maxnreg", ir)

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{};
                                  dump_module=true, kernel=true, maxthreads=42))
    @test occursin("maxntidx\", i32 42", ir)
    @test occursin("maxntidy\", i32 1", ir)
    @test occursin("maxntidz\", i32 1", ir)

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{};
                                  dump_module=true, kernel=true, minthreads=42))
    @test occursin("reqntidx\", i32 42", ir)
    @test occursin("reqntidy\", i32 1", ir)
    @test occursin("reqntidz\", i32 1", ir)

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{};
                                  dump_module=true, kernel=true, blocks_per_sm=42))
    @test occursin("minctasm\", i32 42", ir)

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{};
                                  dump_module=true, kernel=true, maxregs=42))
    @test occursin("maxnreg\", i32 42", ir)
end

LLVM.version() >= v"8" && @testset "calling convention" begin
    kernel() = return

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{}; dump_module=true))
    @test !occursin("ptx_kernel", ir)

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{};
                                  dump_module=true, kernel=true))
    @test occursin("ptx_kernel", ir)
end
end

end

############################################################################################

@testset "assembly" begin

@testset "child functions" begin
    # we often test using @noinline child functions, so test whether these survive
    # (despite not having side-effects)
    @noinline child(i) = sink(i)
    function parent(i)
        child(i)
        return
    end

    asm = sprint(io->ptx_code_native(io, parent, Tuple{Int64}))
    @test occursin(r"call.uni\s+julia_.*child_"m, asm)
end

@testset "kernel functions" begin
    @noinline nonentry(i) = sink(i)
    function entry(i)
        nonentry(i)
        return
    end

    asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64}; kernel=true))
    @test occursin(r"\.visible \.entry .*julia_entry", asm)
    @test !occursin(r"\.visible \.func .*julia_nonentry", asm)
    @test occursin(r"\.func .*julia_nonentry", asm)

@testset "property_annotations" begin
    asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64}; kernel=true))
    @test !occursin("maxntid", asm)

    asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64};
                                         kernel=true, maxthreads=42))
    @test occursin(".maxntid 42, 1, 1", asm)

    asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64};
                                         kernel=true, minthreads=42))
    @test occursin(".reqntid 42, 1, 1", asm)

    asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64};
                                         kernel=true, blocks_per_sm=42))
    @test occursin(".minnctapersm 42", asm)

    if LLVM.version() >= v"4.0"
        asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64};
                                             kernel=true, maxregs=42))
        @test occursin(".maxnreg 42", asm)
    end
end
end

@testset "child function reuse" begin
    # bug: depending on a child function from multiple parents resulted in
    #      the child only being present once

    @noinline child(i) = sink(i)
    function parent1(i)
        child(i)
        return
    end

    asm = sprint(io->ptx_code_native(io, parent1, Tuple{Int}))
    @test occursin(r".func julia_.*child_", asm)

    function parent2(i)
        child(i+1)
        return
    end

    asm = sprint(io->ptx_code_native(io, parent2, Tuple{Int}))
    @test occursin(r".func julia_.*child_", asm)
end

@testset "child function reuse bis" begin
    # bug: similar, but slightly different issue as above
    #      in the case of two child functions
    @noinline child1(i) = sink(i)
    @noinline child2(i) = sink(i+1)
    function parent1(i)
        child1(i) + child2(i)
        return
    end
    ptx_code_native(devnull, parent1, Tuple{Int})

    function parent2(i)
        child1(i+1) + child2(i+1)
        return
    end
    ptx_code_native(devnull, parent2, Tuple{Int})
end

@testset "indirect sysimg function use" begin
    # issue #9: re-using sysimg functions should force recompilation
    #           (host fldmod1->mod1 throws, so the PTX code shouldn't contain a throw)

    # NOTE: Int32 to test for #49

    function kernel(out)
        wid, lane = fldmod1(unsafe_load(out), Int32(32))
        unsafe_store!(out, wid)
        return
    end

    asm = sprint(io->ptx_code_native(io, kernel, Tuple{Ptr{Int32}}))
    @test !occursin("jl_throw", asm)
    @test !occursin("jl_invoke", asm)   # forced recompilation should still not invoke
end

@testset "LLVM intrinsics" begin
    # issue #13 (a): cannot select trunc
    function kernel(x)
        unsafe_trunc(Int, x)
        return
    end
    ptx_code_native(devnull, kernel, Tuple{Float64})
end

@testset "exception arguments" begin
    function kernel(a)
        unsafe_store!(a, trunc(Int, unsafe_load(a)))
        return
    end

    ptx_code_native(devnull, kernel, Tuple{Ptr{Float64}})
end

@testset "GC and TLS lowering" begin
    @eval mutable struct PleaseAllocate
        y::Csize_t
    end

    # common pattern in Julia 0.7: outlined throw to avoid a GC frame in the calling code
    @noinline function inner(x)
        sink(x.y)
        nothing
    end

    function kernel(i)
        inner(PleaseAllocate(Csize_t(42)))
        nothing
    end

    asm = sprint(io->ptx_code_native(io, kernel, Tuple{Int}))
    @test occursin("gpu_gc_pool_alloc", asm)

    # make sure that we can still ellide allocations
    function ref_kernel(ptr, i)
        data = Ref{Int64}()
        data[] = 0
        if i > 1
            data[] = 1
        else
            data[] = 2
        end
        unsafe_store!(ptr, data[], i)
        return nothing
    end

    asm = sprint(io->ptx_code_native(io, ref_kernel, Tuple{Ptr{Int64}, Int}))

    if VERSION < v"1.2.0-DEV.375"
        @test_broken !occursin("gpu_gc_pool_alloc", asm)
    else
        @test !occursin("gpu_gc_pool_alloc", asm)
    end
end

@testset "float boxes" begin
    function kernel(a,b)
        c = Int32(a)
        # the conversion to Int32 may fail, in which case the input Float32 is boxed in order to
        # pass it to the @nospecialize exception constructor. we should really avoid that (eg.
        # by avoiding @nospecialize, or optimize the unused arguments away), but for now the box
        # should just work.
        unsafe_store!(b, c)
        return
    end

    ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{Float32,Ptr{Float32}}))
    @test occursin("jl_box_float32", ir)
    ptx_code_native(devnull, kernel, Tuple{Float32,Ptr{Float32}})
end

end

############################################################################################

end


text:
import Sario: DemRsc

"""
    @allow_mapimage(funcname)

macro to make `DemRsc` functions equivalently defined for `MapImage`.

The macro just passes along the `MapImage.demrsc` to the function already defined

Usage
-------

    nearest_row(demrsc::DemRsc, lat::AbstractFloat) = Int(round(1 + (lat - d.y_first) / d.y_step))
    @allow_mapimage nearest_row

This is the same as:

    nearest_row(img::MapImage, lat) = nearest_row(img.demrsc, lat)
"""
macro allow_mapimage(funcname)
    fname = esc(funcname)
    quote
        function $fname(m::MapImage, args...; kwargs...)
            return $fname(m.demrsc, args...; kwargs...)
        end
    end
end

last_lat(d::DemRsc) = d.y_first + d.y_step * (d.rows - 1)
last_lon(d::DemRsc) = d.x_first + d.x_step * (d.cols - 1)
@allow_mapimage last_lat
@allow_mapimage last_lon

# if they pass `end` into getindex, it turns into an Int, which is already a row
# Otherwise, it's a latitude/longitude if they pass a float
_get_row(demrsc::DemRsc, x::Real) = typeof(x) <: AbstractFloat ? nearest_row(demrsc, x) : x
_get_col(demrsc::DemRsc, x::Real) = typeof(x) <: AbstractFloat ? nearest_col(demrsc, x) : x

nearest_row(d::DemRsc, lat::AbstractFloat) = Int(round(1 + (lat - d.y_first) / d.y_step))
nearest_col(d::DemRsc, lon::AbstractFloat) = Int(round(1 + (lon - d.x_first) / d.x_step))
@allow_mapimage nearest_row
@allow_mapimage nearest_col

# """Find the nearest row, col to a given lat and/or lon"""
nearest_pixel(demrsc::DemRsc, lat::AbstractFloat, lon::AbstractFloat) = (nearest_row(demrsc, lat), nearest_col(demrsc, lon))

nearest_pixel(demrsc::DemRsc,
              lats::AbstractArray{<:AbstractFloat},
              lons::AbstractArray{<:AbstractFloat}) = [nearest_pixel(demrsc, lat, lon)
                                                       for (lat, lon) in zip(lats, lons)]

@allow_mapimage nearest_pixel

# If we have just an array and not a DemRsc or MapImage:
nearest(arr::AbstractArray, point) = Int(round((point - first(arr)) / (arr[2] - arr[1])))

"""
    rowcol_to_latlon(demrsc::DemRsc, row, col)

Takes the row, col of a pixel and finds its lat/lon within the grid
"""
rowcol_to_latlon(d::DemRsc, row, col) = ((d.y_first + (row - 1) * d.y_step), (d.x_first + (col - 1) * d.x_step))
@allow_mapimage rowcol_to_latlon

# Holdover from the python function naming...
latlon_to_rowcol(demrsc::DemRsc, lat::AbstractFloat, lon::AbstractFloat) = nearest_pixel(demrsc, lat, lon)
@allow_mapimage latlon_to_rowcol

# For passing Tuples of ranges of lats/lons (or (lat1, end) )
function latlon_to_rowcol(demrsc::DemRsc,
                          lats::Tuple{<:Real, <:Real},
                          lons::Tuple{<:Real, <:Real})::Tuple{UnitRange{Int},UnitRange{Int}}
    @unpack rows, cols = demrsc

    row_bnds = [_get_row(demrsc, l) for l in lats]
    # row_bnds[1] = typeof(row_bnds[1]) <: Colon ? 1 : row_bnds[1]
    # row_bnds[2] = typeof(row_bnds[2]) <: Colon ? rows : row_bnds[2]
    # In case they put it in backwards (since it's confusing with high lats first)
    sort!(row_bnds)
    clamp!(row_bnds, 1, rows)
    rowrange = row_bnds[1]:row_bnds[2]

    col_bnds = [_get_col(demrsc, l) for l in lons]
    sort!(col_bnds)
    clamp!(col_bnds, 1, cols)
    colrange = col_bnds[1]:col_bnds[2]
    return rowrange, colrange
end

"""
Returns:
    tuple[float]: the boundaries of the intersection box of the 2 areas in order:
    (lon_left,lon_right,lat_bottom,lat_top)
"""
function intersection_corners(dem1::DemRsc, dem2::DemRsc)
    corners1 = grid_corners(dem1)
    corners2 = grid_corners(dem2)
    lons1, lats1 = zip(corners1...)
    lons2, lats2 = zip(corners2...)
    left = _max_min(lons1, lons2)
    right = _least_common(lons1, lons2)
    bottom = _max_min(lats1, lats2)
    top = _least_common(lats1, lats2)
    return left, right, bottom, top
end

intersection_corners(img1::MapImage, img2::MapImage) = intersection_corners(img1.demrsc, img2.demrsc)

_max_min(a, b) = max(minimum(a), minimum(b))
_least_common(a, b) = min(maximum(a), maximum(b))

#
function find_overlap_idxs(asc_img, desc_img, asc_demrsc::DemRsc, desc_demrsc::DemRsc)
    left, right, bottom, top = intersection_corners(asc_demrsc, desc_demrsc)
    # println(left, right, bottom, top)

    row1, col1 = nearest_pixel(asc_demrsc, top, left)
    row2, col2 = nearest_pixel(asc_demrsc, bottom, right)
    asc_idxs = (row1:row2, col1:col2)

    row1, col1 = nearest_pixel(desc_demrsc, top, left)
    row2, col2 = nearest_pixel(desc_demrsc, bottom, right)
    desc_idxs = (row1:row2, col1:col2)

    return asc_idxs, desc_idxs
end

find_overlap_idxs(asc::MapImage, desc::MapImage) = find_overlap_idxs(asc.image, desc.image, asc.demrsc, desc.demrsc)

function find_overlaps(asc_fname::AbstractString, desc_fname::AbstractString=asc_fname, dset="velos/1")
    asc_img = MapImage(asc_fname, dset_name=dset)
    desc_img = MapImage(desc_fname, dset_name=dset)
    return find_overlaps(asc_img, desc_img)
end

function find_overlaps(asc_img::MapImage, desc_img::MapImage) where {T}
    asc_idxs, desc_idxs = find_overlap_idxs(asc_img, desc_img)
    a, d = asc_img[asc_idxs...], desc_img[desc_idxs...]
    a, d = _mask_asc_desc(a, d)
    return a, d
end

function _mask_asc_desc(a, d)
    m1 = a .== 0;
    m2 = d .== 0;
    # TODO: without converting, something about this throws
    # ERROR: ArgumentError: number of indices (1) must match the parent dimensionality (2)
    mask = convert(Array{Bool}, m1 .| m2)
    a[mask] .= 0;
    d[mask] .= 0;
    return a, d
end

function grid_corners(demrsc::DemRsc)
    """Takes sizes and spacing from .rsc info, finds corner points in (x, y) form

    Returns:
        list[tuple[float]]: the corners of the latlon grid in order:
        (top right, top left, bottom left, bottom right)
    """
    left, right, bot, top = grid_extent(demrsc)
    return [(right, top), (left, top), (left, bot), (right, bot)]
end
@allow_mapimage grid_corners

"""
    grid_extent(demrsc::DemRsc)

Get the boundaries of a grid

Returns:
    tuple[float]: the boundaries of the latlon grid in order:
    (lon_left,lon_right,lat_bottom,lat_top)
"""
function grid_extent(demrsc::DemRsc)
    @unpack rows, cols, y_step, x_step, y_first, x_first = demrsc
    return (x_first, x_first .+ x_step * (cols - 1), y_first + y_step * (rows - 1), y_first)
end
@allow_mapimage grid_extent

grid_extent(xs::AbstractArray, ys::AbstractArray) = (extrema(xs)..., extrema(ys)...)

"""
    grid(demrsc::DemRsc; sparse=false)

Returns meshgrid-like arrays X, Y

Examples
------------

```jldoctest
julia> demrsc = DemRsc(x_first=1.0, y_first=2.0, x_step=0.1, y_step=-0.2, file_length=6, width=5);

julia> XX, YY = MapImages.grid(demrsc);

julia> XX[1:3, 1:3]
3×3 Array{Float64,2}:
 1.0  1.1  1.2
 1.0  1.1  1.2
 1.0  1.1  1.2

julia> YY[1:3, 1:3]
3×3 Array{Float64,2}:
 2.0  2.0  2.0
 1.8  1.8  1.8
 1.6  1.6  1.6

julia> size(XX), size(YY)
((6, 5), (6, 5))

julia> XX, YY = MapImages.grid(demrsc, sparse=true);

julia> size(XX), size(YY)
((5,), (6,))
```
"""
function grid(demrsc::DemRsc; sparse=false)
    @unpack rows, cols, y_step, x_step, y_first, x_first = demrsc
    x = range(x_first, step=x_step, length=cols)
    y = range(y_first, step=y_step, length=rows)
    sparse && return (x, y)

    # return collect(reshape(y, :, 1) .* reshape(x, 1, :))
    return collect(ones(length(y), 1) .* reshape(x, 1, :)), collect(reshape(y, :, 1) .* ones(1, length(x)))
end
@allow_mapimage grid

function from_grid(xs::AbstractArray, ys::AbstractArray)
    xs = sort(unique(xs))
    ys = sort(unique(ys), rev=true)
    DemRsc(length(xs), length(ys), xs[1], ys[1], xs[2]-xs[1], -(abs(ys[2]-ys[1])))
end

### Stitching ###
#
function outer_bbox(imgs::MapImage...)::MapImage
    demrsc = imgs[1].demrsc
    length(imgs) < 2 && return MapImage(zeros(size(imgs[1])), demrsc)

    lat1, lon1 = demrsc.y_first, demrsc.x_first
    lat2, lon2 = last_lat(demrsc), last_lon(demrsc)

    for img in imgs[2:end]
        d = img.demrsc
        lat1 = max(lat1, d.y_first)  # lat first is more north = bigger
        lon1 = min(lon1, d.x_first)
        lat2 = min(lat2, last_lat(d))
        lon2 = max(lon2, last_lon(d))
    end
    return _make_zero_img(imgs[1], lat1, lat2, lon1, lon2)
end

function _make_zero_img(img, lat1, lat2, lon1, lon2)
    demrsc = img.demrsc
    newrows = 1 + Int(round((lat2 - lat1) / demrsc.y_step))  # SHOULD be integer
    newcols = 1 + Int(round((lon2 - lon1) / demrsc.x_step))
    newdem = DemRsc(demrsc, x_first=lon1, y_first=lat1,
                    rows=newrows, cols=newcols,
                    width=newcols, file_length=newrows)
    return MapImage(zeros(eltype(img), newrows, newcols), newdem)
end

function intersect_idxs(bigger::DemRsc, smaller::DemRsc)
    topleft = nearest_pixel(bigger, smaller.y_first, smaller.x_first)
    botright = nearest_pixel(bigger, last_lat(smaller), last_lon(smaller))
    return topleft, botright
end

# TODO: clean up, make general, specify what get overwritten
# g1 is the one we keep, g2 is overwritten
function stitchint(g1::MapImage, g2::MapImage)
    out = MapImages.outer_bbox(g1, g2);
    ((r1, c1), (r2, c2)) = intersect_idxs(out, g2)
    out[r1:r2, c1:c2] .= g2.image
    ((r1, c1), (r2, c2)) = intersect_idxs(out, g1)
    out[r1:r2, c1:c2] .= g1.image
    return out
end

stitchint(f1::AbstractString, f2::AbstractString) = stitchint(MapImage(f1), MapImage(f2))

intersect_idxs(a::MapImage, b::MapImage) = intersect_idxs(a.demrsc, b.demrsc)

"""Find the distance between two lat/lon points on Earth

    latlon_to_dist(lat_lon_start, lat_lon_end, R=6378)

Uses the haversine formula: https://en.wikipedia.org/wiki/Haversine_formula
so it does not account for the ellopsoidal Earth shape. Will be with about
0.5-1% of the correct value.

Notes: lats and lons are in degrees, and the values used for R Earth
(6373 km) are optimized for locations around 39 degrees from the equator

Reference: https://andrew.hedges.name/experiments/haversine/
"""
function latlon_to_dist(lat_lon_start, lat_lon_end, R=6378)
    lat1, lon1 = lat_lon_start
    lat2, lon2 = lat_lon_end
    dlat = deg2rad(lat2 - lat1)
    dlon = deg2rad(lon2 - lon1)
    lat1 = deg2rad(lat1)
    lat2 = deg2rad(lat2)
    a = (sin(dlat / 2)^2) + (cos(lat1) * cos(lat2) * sin(dlon / 2)^2)
    c = 2 * atan(sqrt(a), sqrt(1 - a))
    return R * c
end
function rowcol_to_dist(demrsc::DemRsc, rowcol1, rowcol2, R=6378)
    latlon1 = rowcol_to_latlon(demrsc, rowcol1...)
    latlon2 = rowcol_to_latlon(demrsc, rowcol2...)
    return latlon_to_dist(latlon1, latlon2, R)
end
@allow_mapimage rowcol_to_dist

"""Find the degrees separation for distance km assuming distance along great circle arc """
km_to_deg(km, R=6378) = 360 * km / (2π * R)


text:
using MyExample
using Test

@testset "MyExample.jl" begin

    @test my_f(2,1) == 7
    @test my_f(2,3) == 13
    @test my_f(1,1) == 5

end

@testset "Derivative Tests" begin
    @test derivative_of_my_f(2,1) == 2
end


text:
module SaveREPL

export saveREPL

immutable REPLEntry
    time::String
    mode::String
    command::String
end

function saveREPL(path::String)
    println("\tWhich lines would you like to save?")
    print("\tLines: ")
    lines = chomp(replace(readline(), " ", ""))
    println("Save lines $lines to $path? [Y/n]")
    confirm = lowercase(strip(readline()))
    if confirm == "y"
        julia_history = history()
        f = open(path, "w")
        write(f, script(julia_history, lines))
        close(f)
    end
end

function script(histories, lines)
    lines = reverse(split(lines, ','))
    output = ""
    history = reverse(histories)
    for line in lines
        if contains(line, ":") # found range
            line_range = int(reverse(split(line, ':')))
            if length(line_range) == 2
                line_range = range(line_range[1],-1,line_range[2])
            elseif length(line_range) == 3
                line_range[2] = -line_range[2]
                line_range = range(line_range...)
            end
            entries = history[line_range+1]
        else
            entries = [history[int(line)+1]]
        end
        for entry in entries
            entry.mode == "julia" || error("cannot output shell or help modes")
            output *= entry.command
        end
    end
    return output
end

function history()
    julia_history = open(Base.REPL.find_hist_file())
    line = readline(julia_history)
    histories = REPLEntry[]
    while !eof(julia_history)
        if contains(line, "# time: ")
            time = replace(chomp(line), "# time: ", "")
            mode = replace(chomp(readline(julia_history)), "# mode: ", "")
            line = readline(julia_history)
            command = ""
            while beginswith(line, "\t")
                command *= replace(line, "\t", "", 1)
                line = readline(julia_history)
            end
            push!(histories, REPLEntry(time, mode, command))
        end
    end
    close(julia_history)
    return histories
end

end # module


text:
using SnoopCompile, InteractiveUtils, MethodAnalysis, Test

const qualify_mi = Base.VERSION >= v"1.7.0-DEV.5"  # julia PR #38608

module SnooprTests
f(x::Int)  = 1
f(x::Bool) = 2
applyf(container) = f(container[1])
callapplyf(container) = applyf(container)

# "multi-caller". Mimics invalidations triggered by defining ==(::SomeType, ::Any)
mc(x, y) = false
mc(x::Int, y::Int) = x === y
mc(x::Symbol, y::Symbol) = x === y
function mcc(container, y)
    x = container[1]
    return mc(x, y)
end
function mcc(container, y, extra)
    x = container[1]
    return mc(x, y) + extra
end
mccc1(container, y) = mcc(container, y)
mccc2(container, y) = mcc(container, y, 10)

struct MyInt <: Integer
    x::Int
end

end

# For recursive filtermod
module Inner
    op(a, b) = a + b
end
module Outer
    using ..Inner
    function runop(list)
        acc = 0
        for item in list
            acc = Inner.op(acc, item)
        end
        return acc
    end
end

@testset "@snoopr" begin
    prefix = qualify_mi ? "$(@__MODULE__).SnooprTests." : ""

    c = Any[1]
    @test SnooprTests.callapplyf(c) == 1
    mi1 = instance(SnooprTests.applyf, (Vector{Any},))
    mi2 = instance(SnooprTests.callapplyf, (Vector{Any},))

    invs = @snoopr SnooprTests.f(::AbstractFloat) = 3
    @test !isempty(invs)
    umis = uinvalidated(invs)
    @test !isempty(umis)
    trees = invalidation_trees(invs)

    methinvs = only(trees)
    m = which(SnooprTests.f, (AbstractFloat,))
    @test methinvs.method == m
    @test methinvs.reason === :inserting
    sig, root = only(methinvs.mt_backedges)
    @test sig === Tuple{typeof(SnooprTests.f), Any}
    @test root.mi == mi1
    @test SnoopCompile.getroot(root) === root
    @test root.depth == 0
    child = only(root.children)
    @test child.mi == mi2
    @test SnoopCompile.getroot(child) === root
    @test child.depth == 1
    @test isempty(child.children)
    @test isempty(methinvs.backedges)

    io = IOBuffer()
    print(io, methinvs)
    str = String(take!(io))
    @test startswith(str, "inserting f(::AbstractFloat)")
    @test occursin("mt_backedges: 1: signature", str)
    @test occursin("triggered MethodInstance for $(prefix)applyf(::$(Vector{Any})) (1 children)", str)

    cf = Any[1.0f0]
    @test SnooprTests.callapplyf(cf) == 3
    mi3 = instance(SnooprTests.f, (AbstractFloat,))
    invs = @snoopr SnooprTests.f(::Float32) = 4
    @test !isempty(invs)
    trees = invalidation_trees(invs)

    methinvs = only(trees)
    m = which(SnooprTests.f, (Float32,))
    # These next are identical to the above
    @test methinvs.method == m
    @test methinvs.reason === :inserting
    root = only(methinvs.backedges)
    @test root.mi == mi3
    @test SnoopCompile.getroot(root) === root
    @test root.depth == 0
    child = only(root.children)
    @test child.mi == mi1
    @test SnoopCompile.getroot(child) === root
    @test child.depth == 1
    cchild = only(child.children)
    @test cchild.mi == mi2
    @test SnoopCompile.getroot(cchild) === root
    @test cchild.depth == 2
    @test isempty(cchild.children)

    @test  any(nd->nd.mi == mi1, root)
    @test !any(nd->nd.mi == mi3, child)

    print(io, methinvs)
    str = String(take!(io))
    @test startswith(str, "inserting f(::Float32)")
    @test occursin("backedges: 1: superseding f(::AbstractFloat)", str)
    @test occursin("with MethodInstance for $(prefix)f(::AbstractFloat) (2 children)", str)

    show(io, root; minchildren=1)
    str = String(take!(io))
    lines = split(chomp(str), '\n')
    @test length(lines) == 3
    @test lines[1] == "MethodInstance for $(prefix)f(::AbstractFloat) (2 children)"
    @test lines[2] == " MethodInstance for $(prefix)applyf(::$(Vector{Any})) (1 children)"
    show(io, root; minchildren=2)
    str = String(take!(io))
    lines = split(chomp(str), '\n')
    @test length(lines) == 2
    @test lines[1] == "MethodInstance for $(prefix)f(::AbstractFloat) (2 children)"
    @test lines[2] == "⋮"

    ftrees = filtermod(@__MODULE__, trees)
    ftree = only(ftrees)
    @test ftree.backedges == methinvs.backedges
    @test isempty(ftree.mt_backedges)

    cai = Any[1]
    cas = Any[:sym]
    @test SnooprTests.mccc1(cai, 1)
    @test !SnooprTests.mccc1(cai, 2)
    @test !SnooprTests.mccc1(cas, 1)
    @test SnooprTests.mccc2(cai, 1) == 11
    @test SnooprTests.mccc2(cai, 2) == 10
    @test SnooprTests.mccc2(cas, 1) == 10
    trees = invalidation_trees(@snoopr SnooprTests.mc(x::AbstractFloat, y::Int) = x == y)
    root = only(trees).backedges[1]
    @test length(root.children) == 2
    m = which(SnooprTests.mccc1, (Any, Any))
    ft = findcaller(m, trees)
    fnode = only(ft.backedges)
    while !isempty(fnode.children)
        fnode = only(fnode.children)
    end
    @test fnode.mi.def === m

    # Method deletion
    m = which(SnooprTests.f, (Bool,))
    invs = @snoopr Base.delete_method(m)
    trees = invalidation_trees(invs)
    tree = only(trees)
    @test tree.reason === :deleting
    @test tree.method == m

    # Exclusion of Core.Compiler methods
    invs = @snoopr (::Type{T})(x::SnooprTests.MyInt) where T<:Integer = T(x.x)
    umis1 = uinvalidated(invs)
    umis2 = uinvalidated(invs; exclude_corecompiler=false)
    @test length(umis2) > length(umis1) + 20

    # recursive filtermod
    list = Union{Int,String}[1,2]
    Outer.runop(list)
    invs = @snoopr Inner.op(a, b::String) = a + length(b)
    trees = invalidation_trees(invs)
    @test length(trees) == 1
    @test length(filtermod(Inner, trees)) == 1
    @test isempty(filtermod(Outer, trees))
    @test length(filtermod(Outer, trees; recursive=true)) == 1
end


text:
abstract type FlowOp{I,t₀,t₁,T} <: ImplicitOp{T} end
abstract type FlowOpWithAdjoint{I,t₀,t₁,T} <: FlowOp{I,t₀,t₁,T} end

# interface
function velocity end
function velocityᴴ end
function negδvelocityᴴ end

# define integrations for L*f, L'*f, L\f, and L'\f
*(Lϕ::                FlowOp{I,t₀,t₁},  f::Field) where {I,t₀,t₁} = @⌛ odesolve(I,  velocity(cache(Lϕ, f),f)..., t₀, t₁)
*(Lϕ::Adjoint{<:Any,<:FlowOp{I,t₀,t₁}}, f::Field) where {I,t₀,t₁} = @⌛ odesolve(I, velocityᴴ(cache(Lϕ',f),f)..., t₁, t₀)
\(Lϕ::                FlowOp{I,t₀,t₁},  f::Field) where {I,t₀,t₁} = @⌛ odesolve(I,  velocity(cache(Lϕ, f),f)..., t₁, t₀)
\(Lϕ::Adjoint{<:Any,<:FlowOp{I,t₀,t₁}}, f::Field) where {I,t₀,t₁} = @⌛ odesolve(I, velocityᴴ(cache(Lϕ',f),f)..., t₀, t₁)

@adjoint (::Type{L})(ϕ) where {L<:FlowOp} = L(ϕ), Δ -> (Δ,)
@adjoint (Lϕ::FlowOp)(ϕ′) = Lϕ(ϕ′), Δ -> (nothing, Δ)

# for FlowOps (without adjoint), use Zygote to take a gradient through the ODE solver

@adjoint *(Lϕ::FlowOp{I,t₀,t₁}, f::Field{B}) where {I,t₀,t₁,B} =
    Zygote.pullback((Lϕ,f)->odesolve(I, velocity(cache(Lϕ, f),f)..., t₀, t₁), Lϕ, f)

@adjoint \(Lϕ::FlowOp{I,t₀,t₁}, f::Field{B}) where {I,t₀,t₁,B} =
    Zygote.pullback((Lϕ,f)->odesolve(I, velocity(cache(Lϕ, f),f)..., t₁, t₀), Lϕ, f)

# FlowOpWithAdjoint provide their own velocity for computing the gradient

@adjoint function *(Lϕ::FlowOpWithAdjoint{I,t₀,t₁}, f::Field{B}) where {I,t₀,t₁,B}
    cLϕ = cache(Lϕ,f)
    f̃ = cLϕ * f
    function back(Δ)
        (_,δf,δϕ) = @⌛ odesolve(I, negδvelocityᴴ(cLϕ, FieldTuple(f̃,Δ))..., t₁, t₀)
        δϕ, B(δf)
    end
    f̃, back
end

@adjoint function \(Lϕ::FlowOpWithAdjoint{I,t₀,t₁}, f̃::Field{B}) where {I,t₀,t₁,B}
    cLϕ = cache(Lϕ,f̃)
    f = cLϕ \ f̃
    function back(Δ)
        (_,δf,δϕ) = @⌛ odesolve(I, negδvelocityᴴ(cLϕ, FieldTuple(f,Δ))..., t₀, t₁)
        δϕ, B(δf)
    end
    f, back
end


text:
using SequentialMonteCarlo
using RNGPool
import SMCExamples.LinearGaussian: defaultLGModel, makeLGLOPModel,
  makeLGAPFModel

setRNGs(0)

n = 1000
modelBootstrap, theta, ys, ko = defaultLGModel(n)

N = 1024*256
nt = Threads.nthreads()

println(ko.logZhats[n])

smcio = SMCIO{modelBootstrap.particle, modelBootstrap.pScratch}(N, n, nt, false, 2.0)
@time smc!(modelBootstrap, smcio)
@time smc!(modelBootstrap, smcio)
println([smcio.logZhats[n], N*smcio.Vhat1s[n]])

modelLOP = makeLGLOPModel(theta, ys)
smcio = SMCIO{modelLOP.particle, modelLOP.pScratch}(N, n, nt, false, 2.0)
@time smc!(modelLOP, smcio)
@time smc!(modelLOP, smcio)
println([smcio.logZhats[n], N*smcio.Vhat1s[n]])

modelAPF = makeLGAPFModel(theta, ys)
smcio = SMCIO{modelAPF.particle, modelAPF.pScratch}(N, n, nt, false, 2.0)
@time smc!(modelAPF, smcio)
@time smc!(modelAPF, smcio)
println([smcio.logZhats[n], N*smcio.Vhat1s[n]])


text:
module SCRIPT

BUFFER = zeros(Float32,128^3*400)

function init(inputs::Dict{Symbol,Any})
	FILE = Base.@__FILE__
  println("Script: $(basename(FILE))")
  global BUFFER = zeros(Float32,128^3*6*40)
end

function update()
end

function render()
end

end #SCRIPT

max_stars_repo_name: Gilga/JLGLAssets

max_issues_repo_name: Gilga/JLGLAssets

max_forks_repo_name: Gilga/JLGLAssets


text:
# Jorge Fernández de Cossío Díaz ( @cossio ) wrote the kabsch, rmsd and center! functions.

"""
`kabsch(A::AbstractMatrix{Float64}, B::AbstractMatrix{Float64})`

This function takes two sets of points, `A` (refrence) and `B` as NxD matrices, where D
is the dimension and N is the number of points.
Assumes that the centroids of `A` and `B` are at the origin of coordinates.
You can call `center!` on each matrix before calling `kabsch` to center the matrices
in the `(0.0, 0.0, 0.0)`.
Rotates `B` so that `rmsd(A,B)` is minimized.
Returns the rotation matrix. You should do `B * RotationMatrix` to get the rotated B.
"""
function kabsch(A::AbstractMatrix{Float64}, B::AbstractMatrix{Float64})
    @assert size(A) == size(B)
    M::AbstractMatrix{Float64} = B' * A
    χ = Matrix{Float64}(I, size(M, 1), size(M, 2))
    χ[end,end] = sign(det(M))
    u::AbstractMatrix{Float64}, σ::Vector{Float64}, v::AbstractMatrix{Float64} = svd(M)
    return u * χ * v'
end

"""
`center!(A::AbstractMatrix{Float64})`

Takes a set of points `A` as an NxD matrix (N: number of points, D: dimension).
Translates `A` in place so that its centroid is at the origin of coordinates
"""
function center!(A::AbstractMatrix{Float64})
    for i = 1:size(A)[2]
        A[:,i] .-= mean(A[:,i])
    end
end

"""
`rmsd(A::AbstractMatrix{Float64}, B::AbstractMatrix{Float64})`

Return RMSD between two sets of points `A` and `B`, given as NxD matrices
(N: number of points, D: dimension).
"""
function rmsd(A::AbstractMatrix{Float64}, B::AbstractMatrix{Float64})
    @assert size(A) == size(B)
    N, D = size(A)
    s::Float64 = 0.0
    for i=1:N, j=1:D
        s += (B[i,j]::Float64 - A[i,j]::Float64)^2
    end
    return sqrt(s / N)
end

"""
`rmsd(A::AbstractVector{PDBResidue}, B::AbstractVector{PDBResidue}; superimposed::Bool=false)`

Returns the Cα RMSD value between two PDB structures: `A` and `B`.
If the structures are already superimposed between them,
use `superimposed=true` to avoid a new superimposition (`superimposed` is `false` by default).
"""
function rmsd(A::AbstractVector{PDBResidue}, B::AbstractVector{PDBResidue};
                        superimposed::Bool=false)
    if superimposed
        rmsd(CAmatrix(A),CAmatrix(B))
    else
        superimpose(A, B)[end]::Float64
    end
end

# Kabsch for Vector{PDBResidues}
# ==============================

"Returns the Cα with best occupancy in the `PDBResidue`."
function getCA(res::PDBResidue)
    @assert length(res) != 0 "There is no atoms in the residue."
    CAs = findatoms(res, "CA")
    @assert length(CAs) != 0 "There is no alpha carbons in the residue."
    CAindex = selectbestoccupancy(res, CAs)
    res.atoms[CAindex]
end

"""
Returns a matrix with the x, y and z coordinates of the Cα with best occupancy for each
`PDBResidue` of the ATOM group. If a residue doesn't have a Cα, its Cα coordinates are NaNs.
"""
function CAmatrix(residues::AbstractVector{PDBResidue})
    len = length(residues)
    CAlist = Array{Float64}(undef, 3 * len)
    j = 0
    r = 0
    @inbounds for i in 1:len
        res = residues[i]
        if (res.id.group == "ATOM") && (length(res) > 0)
            r += 1
            CAs = findatoms(res, "CA")
            if length(CAs) != 0
                CAindex = selectbestoccupancy(res, CAs)
                coord = res.atoms[CAindex].coordinates
                CAlist[j+=1] = coord.x
                CAlist[j+=1] = coord.y
                CAlist[j+=1] = coord.z
            else
                CAlist[j+=1] = NaN
                CAlist[j+=1] = NaN
                CAlist[j+=1] = NaN
            end
        end
    end
    reshape(resize!(CAlist,j),(3,r))'
end

"Returns a matrix with the x, y, z coordinates of each atom in each `PDBResidue`"
function coordinatesmatrix(res::PDBResidue)
    atoms = res.atoms
    len = length(atoms)
    mat = Array{Float64}(undef, 3, len)
    for i in 1:len
        coord = atoms[i].coordinates
        mat[1,i] = coord.x
        mat[2,i] = coord.y
        mat[3,i] = coord.z
    end
    mat'
end

coordinatesmatrix(residues::AbstractVector{PDBResidue}) = vcat(map(coordinatesmatrix, residues)...)

"""
Returns a `Matrix{Float64}` with the centered coordinates of all the atoms in `residues`.
An optional positional argument `CA` (default: `true`) defines if only Cα carbons should
be used to center the matrix.
"""
function centeredcoordinates(residues::AbstractVector{PDBResidue}, CA::Bool=true)
    coordinates = PDB.coordinatesmatrix(residues)
    meancoord = CA ? mean(PDB.CAmatrix(residues), dims=1) : mean(coordinates, dims=1)
    coordinates .- meancoord
end

"""
Returns a new `Vector{PDBResidue}` with the `PDBResidue`s having centered coordinates.
An optional positional argument `CA` (default: `true`) defines if only Cα carbons should
be used to center the matrix.
"""
function centeredresidues(residues::AbstractVector{PDBResidue}, CA::Bool=true)
    coordinates = centeredcoordinates(residues, CA)
    change_coordinates(residues, coordinates)
end

"""
`change_coordinates(atom::PDBAtom, coordinates::Coordinates)`

Returns a new `PDBAtom` but with a new `coordinates`
"""
function change_coordinates(atom::PDBAtom, coordinates::Coordinates)
    PDBAtom(coordinates,
            identity(atom.atom),
            identity(atom.element),
            copy(atom.occupancy),
            identity(atom.B))
end

"""
`change_coordinates(residue::PDBResidue, coordinates::AbstractMatrix{Float64}, offset::Int=1)`

Returns a new `PDBResidues` with (x,y,z) from a coordinates `AbstractMatrix{Float64}`
You can give an `offset` indicating in wich matrix row starts the (x,y,z) coordinates
of the residue.
"""
function change_coordinates(residue::PDBResidue, coordinates::AbstractMatrix{Float64}, offset::Int=1)
    centeredatoms = map(residue.atoms) do atom
        atoms = change_coordinates(atom, Coordinates(vec(coordinates[offset,:])))
        offset += 1
        return atoms
    end
    PDBResidue(residue.id, centeredatoms)
end

"""
`change_coordinates(residues::AbstractVector{PDBResidue}, coordinates::AbstractMatrix{Float64})`

Returns a new `Vector{PDBResidues}` with (x,y,z) from a coordinates `Matrix{Float64}`
"""
function change_coordinates(residues::AbstractVector{PDBResidue}, coordinates::AbstractMatrix{Float64})
    nres = length(residues)
    updated = Array{PDBResidue}(undef, nres)
    j = 1
    for i in 1:nres
        residue = residues[i]
        updated[i] = change_coordinates(residue, coordinates, j)
        j += length(residue)
    end
    updated
end

"Returns a new `PDBAtom` but with a `B` as B-factor"
function _change_B(atom::PDBAtom, B::String)
    PDBAtom(copy(atom.coordinates),
            copy(atom.atom),
            copy(atom.element),
            copy(atom.occupancy),
            B)
end

_iscentered(x::Float64, y::Float64, z::Float64) = (abs(x) <= 1e-13) && (abs(y) <= 1e-13) && (abs(z) <= 1e-13)

_iscentered(meanCα::AbstractVector{Float64}) = _iscentered(meanCα[1], meanCα[2], meanCα[3])

_iscentered(CA::AbstractMatrix{Float64}) = _iscentered(vec(mean(CA, dims=1)))

"""
Return the matching CA matrices after deleting the rows/residues where the CA
is missing in at least one structure.
"""
function _get_matched_Cαs(A::AbstractVector{PDBResidue},
                          B::AbstractVector{PDBResidue})
    length_A = length(A)
    if length_A != length(B)
        throw(ArgumentError("PDBResidue vectors should have the same length."))
    end
    ACα = PDB.CAmatrix(A)
    BCα = PDB.CAmatrix(B)
    without_Cα = isnan.(ACα[:,1]) .| isnan.(BCα[:,1])
    if any(without_Cα)
        n_without_ca = sum(without_Cα)
        if length_A - n_without_ca == 0
            throw(ArgumentError("There are not alpha-carbons to align."))
        end
        @warn string("Using ", length_A - n_without_ca,
            " residues for RMSD calculation because there are ", n_without_ca,
            " residues without CA: ", findall(without_Cα))
        with_Cα = .!without_Cα
        return ACα[with_Cα, :], BCα[with_Cα, :]
    end
    ACα, BCα
end

"""
This function takes `A::AbstractVector{PDBResidue}` (reference) and
`B::AbstractVector{PDBResidue}`. Translates `A` and `B` to the origin of coordinates,
and rotates `B` so that `rmsd(A,B)` is minimized with the Kabsch algorithm
(using only their α carbons).
Returns the rotated and translated versions of `A` and `B`, and the RMSD value.
"""
function superimpose(A::AbstractVector{PDBResidue}, B::AbstractVector{PDBResidue})
    ACα, BCα = _get_matched_Cαs(A, B)
    Bxyz = PDB.coordinatesmatrix(B)
    meanACα = vec(mean(ACα, dims=1))
    meanBCα = vec(mean(BCα, dims=1))
    if !_iscentered(meanBCα)
        @inbounds BCα[:,1] .-= meanBCα[1]
        @inbounds BCα[:,2] .-= meanBCα[2]
        @inbounds BCα[:,3] .-= meanBCα[3]
        @inbounds Bxyz[:,1] .-= meanBCα[1]
        @inbounds Bxyz[:,2] .-= meanBCα[2]
        @inbounds Bxyz[:,3] .-= meanBCα[3]
    end
    if !_iscentered(meanACα)
        @inbounds ACα[:,1] .-= meanACα[1]
        @inbounds ACα[:,2] .-= meanACα[2]
        @inbounds ACα[:,3] .-= meanACα[3]
        Axyz = PDB.coordinatesmatrix(A)
        @inbounds Axyz[:,1] .-= meanACα[1]
        @inbounds Axyz[:,2] .-= meanACα[2]
        @inbounds Axyz[:,3] .-= meanACα[3]
        RotationMatrix = PDB.kabsch(ACα, BCα)
        return(
            change_coordinates(A, Axyz),
            change_coordinates(B, Bxyz * RotationMatrix),
            PDB.rmsd(ACα, BCα * RotationMatrix)
            )
    else
        RotationMatrix = PDB.kabsch(ACα, BCα)
        return(
            A,
            change_coordinates(B, Bxyz * RotationMatrix),
            PDB.rmsd(ACα, BCα * RotationMatrix)
            )
    end
end

# RMSF: Root Mean-Square-average distance (Fluctuation)
# -----------------------------------------------------

"This looks for errors in the input to rmsf methods"
function _rmsf_test(vector)
    n = length(vector)
    if n < 2
        throw(ArgumentError("You need at least two matrices/structures"))
    end
    sizes = unique(Tuple{Int,Int}[ size(s) for s in vector ])
    if length(sizes) > 1
        throw(ArgumentError("Matrices/Structures must have the same number of rows/atoms"))
    end
    if sizes[1][2] != 3
        throw(ArgumentError("Matrices should have 3 columns (x, y, z)"))
    end
end

"""
Calculates the average/mean position of each atom in a set of structure.
The function takes a vector (`AbstractVector`) of vectors (`AbstractVector{PDBResidue}`)
or matrices (`AbstractMatrix{Float64}`) as first argument. As second (optional) argument this
function can take an `AbstractVector{Float64}` of matrix/structure weights to return a
weighted mean. When a AbstractVector{PDBResidue} is used, if the keyword argument `calpha` is
`false` the RMSF is calculated for all the atoms. By default only alpha carbons are used
(default: `calpha=true`).
"""
function mean_coordinates(vec::AbstractVector{T}) where T <: AbstractMatrix{Float64}
    _rmsf_test(vec)
    n = length(vec)
    reduce(+, vec) ./ n
end

function mean_coordinates(vec::AbstractVector{T},
                          matrixweights::AbstractVector{Float64}) where T <: AbstractMatrix{Float64}
    _rmsf_test(vec)
    @assert length(vec) == length(matrixweights) "The number of matrix weights must be equal to the number of matrices."
    n = sum(matrixweights)
    reduce(+, (vec .* matrixweights)) ./ n
end

function mean_coordinates(vec::AbstractVector{T};
                          calpha::Bool=true) where T <: AbstractVector{PDBResidue}
    mean_coordinates(map(calpha ? CAmatrix : coordinatesmatrix, vec))
end

function mean_coordinates(vec::AbstractVector{T},
                          args...; calpha::Bool=true) where T <: AbstractVector{PDBResidue}
    mean_coordinates(map(calpha ? CAmatrix : coordinatesmatrix, vec), args...)
end

"""
Calculates the RMSF (Root Mean-Square-Fluctuation) between an atom and its average
position in a set of structures. The function takes a vector (`AbstractVector`) of
vectors (`AbstractVector{PDBResidue}`) or matrices (`AbstractMatrix{Float64}`) as first
argument. As second (optional) argument this function can take an `AbstractVector{Float64}`
of matrix/structure weights to return the root weighted mean-square-fluctuation around
the weighted mean structure. When a Vector{PDBResidue} is used, if the keyword argument
`calpha` is `false` the RMSF is calculated for all the atoms. By default only alpha
carbons are used (default: `calpha=true`).
"""
function rmsf(vector::AbstractVector{T}) where T <: AbstractMatrix{Float64}
    m = mean_coordinates(vector)
    # MIToS RMSF is calculated as in Eq. 6 from:
    # Kuzmanic, Antonija, and Bojan Zagrovic.
    # "Determination of ensemble-average pairwise root mean-square deviation from experimental B-factors."
    # Biophysical journal 98.5 (2010): 861-871.
    vec(sqrt.(mean(map( mat -> mapslices(x -> sum(abs2, x), mat .- m, dims=2), vector ))))
end

function rmsf(vector::AbstractVector{T},
              matrixweights::AbstractVector{Float64}) where T <: AbstractMatrix{Float64}
    m = mean_coordinates(vector, matrixweights)
    d = map( mat -> mapslices(x -> sum(abs2, x), mat .- m, dims=2), vector )
    vec(sqrt.(sum(d .* matrixweights)/sum(matrixweights)))
end

function rmsf(vec::AbstractVector{T}; calpha::Bool=true) where T <: AbstractVector{PDBResidue}
    rmsf(map(calpha ? CAmatrix : coordinatesmatrix, vec))
end

function rmsf(vec::AbstractVector{T},
              matrixweights::AbstractVector{Float64};
              calpha::Bool=true) where T <: AbstractVector{PDBResidue}
    rmsf(map(calpha ? CAmatrix : coordinatesmatrix, vec), matrixweights)
end


text:
abstract type AbstractRealLineDiscretizer{T}  <: AbstractVector{T} end

unwrap(x) = x
wrap(x, val) = val

function Base.size(discr::AbstractRealLineDiscretizer)
    (Base.length(discr), )
end

struct RealLineDiscretizer{L, R, T, G <:AbstractVector{T}} <: AbstractRealLineDiscretizer{Interval{L, R, T}}
    grid::G
end

function RealLineDiscretizer{L,R}(grid::G) where {L, R, T, G<:AbstractVector{T}}
    Tinf = hasinf(T) ? T : InfExtendedReal{T}
    RealLineDiscretizer{L,R,Tinf,G}(grid)
end

function Base.length(discr::RealLineDiscretizer)
    length(discr.grid) + 1
end

function Base.getindex(discr::RealLineDiscretizer{L,R,T}, i::Int) where {L,R,T}
    grid = discr.grid
    n = length(grid)
    if i==1
        Interval{L,R,T}(-∞, first(grid))
    elseif i==n+1
        Interval{L,R,T}(last(grid), +∞)
    elseif 1 < i <= n
        Interval{L,R,T}(grid[i-1], grid[i])
    else
        throw(IndexError("Out of bounds"))
    end
end

struct BoundedIntervalDiscretizer{L, R, T, G <:AbstractVector{T}} <: AbstractRealLineDiscretizer{Interval{L, R, T}}
    grid::G
end

function BoundedIntervalDiscretizer{L,R}(grid::G) where {L, R, T, G<:AbstractVector{T}}
    BoundedIntervalDiscretizer{L,R,T,G}(grid)
end

function Base.length(discr::BoundedIntervalDiscretizer)
    length(discr.grid) - 1
end

function Base.getindex(discr::BoundedIntervalDiscretizer{L,R,T}, i::Int) where {L,R,T}
    grid = discr.grid
    n = length(grid)
    if 1 <= i <= n-1
        Interval{L,R,T}(grid[i], grid[i+1])
    else
        throw(IndexError("Out of bounds"))
    end
end

function _discretize(sorted_intervals::AbstractRealLineDiscretizer, x)
    n = length(sorted_intervals)
    left, right = 1, n
    for i = 1:n
        middle = div(left + right, 2)
        middle_interval = sorted_intervals[middle]
        if x ⊆ middle_interval
            return (middle, middle_interval)
        elseif _isless(x, rightendpoint(middle_interval))
            right = middle - 1
        else
            left = middle + 1
        end
    end
    throw(ArgumentError("x seems does not lie inside any interval of the discretization."))
end

function (discr::AbstractRealLineDiscretizer)(x)
    x_val = unwrap(x)
    x_val_discr = last(_discretize(discr, x_val))
    wrap(x, x_val_discr)
end

function Base.findfirst(discr, x)
    x_val = unwrap(x)
    first(_discretize(discr, x_val))
end

function IntervalSets.closedendpoints(discr::Union{BoundedIntervalDiscretizer, RealLineDiscretizer})
    IntervalSets.closedendpoints(discr[1])
end
function IntervalSets.isleftclosed(d::Union{BoundedIntervalDiscretizer, RealLineDiscretizer})
    closedendpoints(d)[1]
end
function IntervalSets.isrightclosed(d::Union{BoundedIntervalDiscretizer, RealLineDiscretizer})
    closedendpoints(d)[2]
end
function IntervalSets.isleftopen(d::Union{BoundedIntervalDiscretizer, RealLineDiscretizer})
    !isleftclosed(d)
end
function IntervalSets.isrightopen(d::Union{BoundedIntervalDiscretizer, RealLineDiscretizer})
    !isrightclosed(d)
end

struct FiniteSupportDiscretizer{T, G <:AbstractVector{T}} <: AbstractRealLineDiscretizer{T}
    grid::G
end

function Base.length(discr::FiniteSupportDiscretizer)
    length(discr.grid)
end

function Base.getindex(discr::FiniteSupportDiscretizer, i::Int)
    Base.getindex(discr.grid, i)
end

function _discretize(discr::FiniteSupportDiscretizer, x)
    idx = findfirst( ==(x), discr)
    isnothing(idx) && throw("x not in the supported grid")
    (idx, discr[idx])
end

#function discretize(x)
#    y = unwrap(x)
#    discretize(y)
#    wrap(y)
#end


text:
using Test,Documenter,EspyInsideFunction
println("\nEspy test suite\n")

@testset "EspyInsideFunction.jl package" begin
    include("TestEspy.jl")
    include("EspyDemo.jl")
    doctest(EspyInsideFunction)
end
;

max_stars_repo_name: PhilippeMaincon/Espy


text:
using UnitfulPlots
using Test
using Plots
using Unitful.DefaultSymbols

# write your own tests here
@testset "At least create one plot" begin
    data = rand(10)*m

    @test isa(plot(data), Plots.Plot) == true
end


text:
@testset "Utils" begin
    s = @inferred(LightGraphs.sample!([1:10;], 3))
    @test length(s) == 3
    for  e in s
        @test 1 <= e <= 10
    end

    s = @inferred(LightGraphs.sample!([1:10;], 6, exclude=[1,2]))
    @test length(s) == 6
    for e in s
        @test 3 <= e <= 10
    end

    s = @inferred(LightGraphs.sample(1:10, 6, exclude=[1,2]))
    @test length(s) == 6
    for e in s
        @test 3 <= e <= 10
    end
end

max_stars_repo_name: AsileBcd/JohnsonCycles

max_issues_repo_name: AsileBcd/JohnsonCycles

max_forks_repo_name: AsileBcd/JohnsonCycles


text:
Base.isnull(X::NullableArray, I::Int...) = X.isnull[I...]
Base.values(X::NullableArray, I::Int...) = X.values[I...]

@doc """
`size(X::NullableArray, [d::Real])`

Return a tuple containing the lengths of each dimension of `X`, or if `d` is
specific, the length of `X` along dimension `d`.
""" ->
Base.size(X::NullableArray) = size(X.values) # -> NTuple{Int}

@doc """
`similar(X::NullableArray, [T], [dims])`

Allocate an uninitialized `NullableArray` of element type `T` and with
size `dims`. If unspecified, `T` and `dims` default to the element type and size
equal to that of `X`.
""" ->
function Base.similar{T}(X::NullableArray, ::Type{T}, dims::Dims)
    T<:Nullable ? NullableArray(eltype(T), dims) : NullableArray(T, dims)
end

@doc """
`copy(X::NullableArray)`

Return a shallow copy of `X`; the outer structure of `X` will be copied, but
all elements will be identical to those of `X`.
""" ->
Base.copy{T}(X::NullableArray{T}) = Base.copy!(similar(X, T), X)

@doc """
`copy!(dest::NullableArray, src::NullableArray)`

Copy the initialized values of a source NullableArray into the respective
indices of the destination NullableArray. If an entry in `src` is null, then
this method nullifies the respective entry in `dest`.
""" ->
function Base.copy!(dest::NullableArray,
                    src::NullableArray) # -> NullableArray{T, N}
    if isbits(eltype(dest)) && isbits(eltype(src))
        copy!(dest.values, src.values)
    else
        dest_values = dest.values
        src_values = src.values
        length(dest_values) >= length(src_values) || throw(BoundsError())
        # copy only initilialized values from src into dest
        for i in 1:length(src_values)
            @inbounds !(src.isnull[i]) && (dest.values[i] = src.values[i])
        end
    end
    copy!(dest.isnull, src.isnull)
    return dest
end

@doc """
`fill!(X::NullableArray, x::Nullable)`

Fill `X` with the value `x`. If `x` is empty, then `fill!(X, x)` nullifies each
entry of `X`. Otherwise, `fill!(X, x)` fills `X.values` with the value of `x`
and designates each entry of `X` as present.
""" ->
function Base.fill!(X::NullableArray, x::Nullable) # -> NullableArray{T, N}
    if isnull(x)
        fill!(X.isnull, true)
    else
        fill!(X.values, get(x))
        fill!(X.isnull, false)
    end
    return X
end

@doc """
`fill!(X::NullableArray, x::Nullable)`

Fill `X` with the value `x` and designate each entry as present. If `x` is an
object reference, all elements will refer to the same object. Note that
`fill!(X, Foo())` will return `X` filled with the result of evaluating `Foo()`
once.
""" ->
function Base.fill!(X::NullableArray, x::Any) # -> NullableArray{T, N}
    fill!(X.values, x)
    fill!(X.isnull, false)
    return X
end

@doc """
`Base.deepcopy(X::NullableArray)`

Return a `NullableArray` object whose internal `values` and `isnull` fields are
deep copies of `X.values` and `X.isnull` respectively.
""" ->
function Base.deepcopy(X::NullableArray) # -> NullableArray{T}
    return NullableArray(deepcopy(X.values), deepcopy(X.isnull))
end

@doc """
`resize!(X::NullableVector, n::Int)`

Resize a one-dimensional `NullableArray` `X` to contain precisely `n` elements.
If `n` is greater than the current length of `X`, then each new entry will be
designated as null.
""" ->
function Base.resize!{T}(X::NullableArray{T,1}, n::Int) # -> NullableArray{T, 1}
    resize!(X.values, n)
    oldn = length(X.isnull)
    resize!(X.isnull, n)
    X.isnull[oldn+1:n] = true
    return X
end

function Base.reshape(X::NullableArray, dims::Dims) # -> NullableArray
    NullableArray(reshape(X.values, dims), reshape(X.isnull, dims))
end

@doc """
`ndims(X::NullableArray)`

Returns the number of dimensions of `X`.
""" ->
Base.ndims(X::NullableArray) = ndims(X.values) # -> Int

@doc """
`length(X::NullableArray)`

Returns the maximum index `i` for which `getindex(X, i)` is valid.
""" ->
Base.length(X::NullableArray) = length(X.values) # -> Int

@doc """
`endof(X::NullableArray)`

Returns the last entry of `X`.
""" ->
Base.endof(X::NullableArray) = endof(X.values) # -> Int

@doc """

""" ->
function Base.find(X::NullableArray{Bool}) # -> Array{Int}
    ntrue = 0
    @inbounds for (i, isnull) in enumerate(X.isnull)
        ntrue += !isnull && X.values[i]
    end
    res = Array(Int, ntrue)
    ind = 1
    @inbounds for (i, isnull) in enumerate(X.isnull)
        if !isnull && X.values[i]
            res[ind] = i
            ind += 1
        end
    end
    return res
end

_isnull(x::Any) = false
_isnull(x::Nullable) = isnull(x)

@doc """
`dropnull(X::AbstractVector)`

Return a vector containing only the non-null entries of `X`,
unwrapping `Nullable` entries. A copy is always returned, even when
`X` does not contain any null values.
""" ->
function dropnull(X::AbstractVector)                 # -> AbstractVector
    Y = filter(x->!_isnull(x), X)
    res = similar(Y)
    for i in eachindex(Y, res)
        res[i] = isa(Y[i], Nullable) ? Y[i].value : Y[i]
    end
    res
end
function dropnull{T<:Nullable}(X::AbstractVector{T}) # -> AbstractVector
    Y = filter(x->!_isnull(x), X)
    res = similar(Y, eltype(T))
    for i in eachindex(Y, res)
        res[i] = Y[i].value
    end
    res
end
dropnull(X::NullableVector) = X.values[!X.isnull]    # -> Vector

@doc """
`anynull(X)`

Returns whether or not any entries of `X` are null.
""" ->
anynull(X::Any) = any(_isnull, X)           # -> Bool
anynull(X::NullableArray) = any(X.isnull)   # -> Bool

@doc """
`allnull(X)`

Returns whether or not all the entries in `X` are null.
""" ->
allnull(X::Any) = all(_isnull, X)           # -> Bool
allnull(X::NullableArray) = all(X.isnull)   # -> Bool

@doc """
`isnan(X::NullableArray)`

Test whether each entry of `X` is null and if not, test whether the entry is
not a number (`NaN`). Return the results as `NullableArray{Bool}`. Note that
null entries of `X` will be reflected by null entries of the resultant
`NullableArray`.
""" ->
function Base.isnan(X::NullableArray) # -> NullableArray{Bool}
    return NullableArray(isnan(X.values), copy(X.isnull))
end

@doc """
`isfinite(X::NullableArray)`

Test whether each entry of `X` is null and if not, test whether the entry is
finite. Return the results as `NullableArray{Bool}`. Note that
null entries of `X` will be reflected by null entries of the resultant
`NullableArray`.
""" ->
function Base.isfinite(X::NullableArray) # -> NullableArray{Bool}
    res = Array(Bool, size(X))
    for i in eachindex(X)
        if !X.isnull[i]
            res[i] = isfinite(X.values[i])
        end
    end
    return NullableArray(res, copy(X.isnull))
end

@doc """
`convert(T, X::NullableArray)`

Convert `X` to an `AbstractArray` of type `T`. Note that if `X` contains any
null entries then calling `convert` without supplying a replacement value for
null entries will result in an error.

Currently supported return type arguments include: `Array`, `Array{T}`,
`Vector`, `Matrix`.

`convert(T, X::NullableArray, replacement)`

Convert `X` to an `AbstractArray` of type `T` and replace all null entries of
`X` with `replacement` in the result.
""" ->
function Base.convert{S, T, N}(::Type{Array{S, N}},
                               X::NullableArray{T, N}) # -> Array{S, N}
    if anynull(X)
        throw(NullException())
    else
        return convert(Array{S, N}, X.values)
    end
end

function Base.convert{S, T, N}(::Type{Array{S}},
                               X::NullableArray{T, N}) # -> Array{S, N}
    return convert(Array{S, N}, X)
end

function Base.convert{T}(::Type{Vector}, X::NullableVector{T}) # -> Vector{T}
    return convert(Array{T, 1}, X)
end

function Base.convert{T}(::Type{Matrix}, X::NullableMatrix{T}) # -> Matrix{T}
    return convert(Array{T, 2}, X)
end

function Base.convert{T, N}(::Type{Array},
                            X::NullableArray{T, N}) # -> Array{T, N}
    return convert(Array{T, N}, X)
end

# Conversions with replacements for handling null values

function Base.convert{S, T, N}(::Type{Array{S, N}},
                               X::NullableArray{T, N},
                               replacement::Any) # -> Array{S, N}
    replacementS = convert(S, replacement)
    res = Array(S, size(X))
    for i in 1:length(X)
        if X.isnull[i]
            res[i] = replacementS
        else
            res[i] = X.values[i]
        end
    end
    return res
end

function Base.convert{T}(::Type{Vector},
                         X::NullableVector{T},
                         replacement::Any) # -> Vector{T}
    return convert(Array{T, 1}, X, replacement)
end

function Base.convert{T}(::Type{Matrix},
                         X::NullableMatrix{T},
                         replacement::Any) # -> Matrix{T}
    return convert(Array{T, 2}, X, replacement)
end

function Base.convert{T, N}(::Type{Array},
                            X::NullableArray{T, N},
                            replacement::Any) # -> Array{T, N}
    return convert(Array{T, N}, X, replacement)
end

@doc """
`float(X::NullableArray)`

Return a copy of `X` in which each non-null entry is converted to a floating
point type. Note that this method will throw an error for arguments `X` whose
element type is not "isbits".
""" ->
function Base.float(X::NullableArray) # -> NullableArray{T, N}
    isbits(eltype(X)) || error()
    return NullableArray(float(X.values), copy(X.isnull))
end


text:
function median_threshold(in_img::AbstractMatrix)
    tipo = typeof(in_img)
    img = convert(Array{Float32},in_img)

    d = size(img)
    a = 0
    total = 0.0

    for i=1:d[1]
        for j=1:d[2]
            if img[i,j] != 0.0
                total += img[i,j]
                a += 1
            end
        end
    end

    level = total/a

    for i=1:d[1]
        for j=1:d[2]
            if img[i,j] > level
                img[i,j] = 1.0
            else
                img[i,j] = 0.0
            end
        end
    end

    return(convert(tipo,img))
end