from __future__ import absolute_import, division, print_function

import iotbx.pdb
import mmtbx.model
from mmtbx.validation.ramalyze import ramalyze
from libtbx.utils import null_out
from mmtbx.validation.comparama import add_arrows_on_plot
from PIL import Image
import sys

pdb_str = """\
ATOM     13  CB  PHE A   1      11.914  10.410  11.811  1.00  2.00           C
ATOM     14  CG  PHE A   1      11.204   9.472  12.746  1.00  2.00           C
ATOM     15  CD1 PHE A   1      10.636   8.301  12.273  1.00  2.00           C
ATOM     16  CD2 PHE A   1      11.105   9.762  14.096  1.00  2.00           C
ATOM     17  CE1 PHE A   1       9.982   7.436  13.131  1.00  2.00           C
ATOM     18  CE2 PHE A   1      10.452   8.901  14.958  1.00  2.00           C
ATOM     19  CZ  PHE A   1       9.890   7.737  14.475  1.00  2.00           C
ATOM     20  C   PHE A   1      11.828  12.443  10.351  1.00  2.00           C
ATOM     21  O   PHE A   1      11.808  12.365   9.123  1.00  2.00           O
ATOM     22  OXT PHE A   1      12.531  13.314  10.864  1.00  2.00           O
ATOM     23  N   PHE A   1       9.929  10.880  10.444  1.00  2.00           N
ATOM     24  CA  PHE A   1      11.008  11.488  11.213  1.00  2.00           C
"""

if sys.version_info.major == 3:
  reference_hist = [111080, 832, 645, 454, 418, 493, 367, 300, 35369, 3421, 3425,
      2800, 6623, 3317, 3801, 5680, 4466, 2545, 3101, 6944, 4291, 3131, 2951, 7023,
      3692, 4041, 6628, 3158, 4796, 2898, 7657, 4096, 3801, 3587, 3854, 3537, 4890,
      4091, 3587, 3009, 4167, 4325, 4150, 4352, 3538, 2828, 5329, 3801, 3292, 5082,
      4422, 3831, 3152, 4909, 181, 3619, 4733, 3719, 5605, 3585, 3953, 5574, 3838,
      4220, 4338, 4548, 4489, 6016, 177, 4237, 3851, 5842, 3676, 190, 4039, 5281,
      4486, 160, 5604, 5165, 5124, 5061, 204, 3877, 5619, 5073, 163, 5418, 5699,
      5611, 3980, 169, 4868, 4803, 5978, 492, 5741, 6204, 4623, 4828, 171, 5429,
      5100, 6493, 212, 5612, 6487, 5382, 146, 5911, 167, 7058, 5374, 183, 6380,
      5939, 174, 6249, 149, 6416, 6960, 189, 4397, 6641, 183, 9214, 173, 6352,
      5709, 167, 6852, 6559, 194, 8242, 215, 7655, 8511, 231, 6710, 8460, 225,
      8304, 229, 7659, 5498, 242, 8875, 8216, 235, 6256, 259, 6766, 7324, 382,
      5556, 4558, 314, 2906, 4187, 483, 5357, 7129, 8638, 8572, 194, 8010, 9463,
      10799, 9357, 224, 9640, 10362, 12175, 11532, 142, 9828, 11768, 11544, 13342,
      180, 11391, 10993, 13748, 14714, 153, 14131, 13286, 14024, 13413, 159, 16377,
      13557, 14695, 15592, 227, 16446, 17763, 18111, 15007, 16149, 36102, 18526,
      16362, 31815, 20678, 17826, 31510, 18366, 20699, 40545, 19413, 18308, 71554,
      20806, 20887, 41381, 11834, 7784, 26093, 30002, 34972, 73903, 51140, 45714,
      46026, 100884, 71777, 45025, 116852, 73026, 57319, 80114, 128337, 80770,
      42360, 63809, 119274, 155963, 142218, 187110, 321, 1474, 308, 288, 483,
      498, 512, 649974, 505, 399, 1054, 658, 560, 803, 2555, 1680574, 170332,
      823, 771, 668, 448, 361, 408, 465, 370, 326, 319, 530, 297, 278, 395, 242,
      404, 431, 489, 383, 262, 350, 284, 215, 219, 418, 240, 314, 286, 324, 313,
      631, 362, 255, 200, 239, 288, 258, 516, 239, 193, 243, 196, 192, 275, 197,
      275, 351, 604, 218, 608, 479, 474, 484, 238, 374, 859, 623, 554, 497, 490,
      534, 1279, 849, 593, 1036, 620, 1263, 1469, 1072, 939, 1475, 2079, 1447,
      2112, 1760, 2244, 198, 3461, 2839, 2921, 3671, 3293, 3388, 3352, 2694, 3187,
      3752, 3379, 3750, 3721, 2146, 4432, 2573, 3158, 4458, 3067, 4239, 3058, 2872,
      4124, 3044, 3740, 4064, 3871, 3109, 3135, 4809, 2974, 4911, 2910, 3724, 3793,
      3517, 3837, 3547, 4892, 4074, 3614, 2988, 4168, 4292, 4126, 4505, 3497, 2838,
      5270, 4121, 3410, 5083, 4571, 3927, 3226, 4934, 208, 3842, 4722, 3708, 5693,
      3572, 4003, 5625, 3951, 4236, 4396, 4533, 4523, 5990, 7895, 5889, 3602, 4026,
      5345, 4489, 5632, 10153, 5093, 3892, 5588, 5364, 5440, 5708, 5685, 8716, 4854,
      5954, 5728, 6251, 4657, 4813, 10403, 6540, 5673, 6485, 5354, 5980, 7121, 11608,
      5962, 6319, 6464, 7013, 4423, 6748, 15193, 5714, 6922, 6559, 8318, 7587, 8594,
      7069, 16662, 7694, 5518, 8955, 8260, 6291, 6768, 12704, 4636, 3051, 9454, 15659,
      8566, 17290, 20063, 19878, 23600, 21359, 24691, 22381, 44661, 14115, 27075,
      29490, 27835, 31731, 35710, 30885, 36067, 34703, 31758, 38644, 31559, 38877,
      40511, 37468, 55208, 41349, 41617, 19555, 26204, 65031, 73896, 96401, 103653,
      114721, 92347, 142025, 137029, 127955, 122449, 162137, 176160, 282055, 46609,
      1222, 57, 68, 131, 648593, 69, 95, 102, 1622466, 170311, 807, 785, 523, 405,
      412, 411, 455, 314, 263, 284, 469, 267, 323, 446, 201, 403, 353, 434, 298,
      459, 236, 390, 198, 199, 327, 215, 219, 251, 220, 180, 546, 290, 252, 310,
      175, 148, 156, 153, 289, 323, 222, 189, 183, 162, 183, 158, 305, 224, 203,
      145, 264, 235, 198, 232, 243, 180, 245, 271, 213, 244, 247, 338, 518, 264,
      280, 301, 283, 280, 223, 242, 248, 174, 182, 205, 212, 222, 185, 185, 256,
      242, 251, 328, 233, 258, 244, 229, 229, 191, 238, 135, 191, 175, 172, 172,
      608, 228, 194, 140, 248, 197, 168, 141, 273, 207, 203, 195, 628, 223, 209,
      763, 459, 155, 384, 423, 170, 212, 329, 276, 767, 550, 176, 404, 393, 130,
      567, 435, 411, 1165, 305, 487, 540, 405, 927, 593, 381, 1231, 1503, 263,
      1119, 904, 253, 1402, 2043, 192, 1418, 2355, 374, 1722, 209, 2249, 3477,
      192, 2822, 2844, 190, 6657, 3311, 3228, 2933, 6559, 3294, 3764, 5594, 4429,
      2501, 3093, 6897, 4169, 3053, 2883, 6933, 3700, 4069, 6585, 3098, 4840,
      2938, 7625, 3781, 3843, 7177, 8231, 7459, 7013, 8260, 4377, 6246, 8872,
      8228, 8102, 8164, 8155, 9150, 3608, 9406, 7688, 8702, 10320, 7920, 9387,
      9164, 9996, 10177, 8832, 10517, 10902, 9471, 9508, 11512, 10730, 10088,
      27937, 11955, 18027, 17409, 19413, 20024, 11725, 21371, 22652, 24248, 22257,
      20345, 12632, 9443, 15697, 25745, 20229, 20001, 33230, 23040, 24600, 24570,
      41748, 27233, 29590, 30321, 52224, 67385, 66304, 69771, 79316, 92443, 82585,
      45118, 138556, 199942, 206844, 278981, 250313, 338002, 328632, 1268, 167,
      2271005, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 5760000]
else:
  reference_hist = [111089, 836, 637, 524, 406, 484, 368, 330, 35365, 3425, 3430,
      2874, 6621, 3319, 3814, 5685, 4456, 2546, 3099, 6959, 4282, 3118, 2946, 7024,
      3701, 4054, 6626, 3163, 4803, 2889, 7661, 3841, 3806, 3582, 3856, 3572, 4895,
      4091, 3593, 3004, 4158, 4326, 4148, 4351, 3545, 2824, 5323, 3804, 3288, 5080,
      4432, 3836, 3150, 4903, 176, 3621, 4734, 3721, 5605, 3713, 3947, 5576, 3834,
      4074, 4341, 4516, 4486, 6125, 167, 4234, 3849, 5846, 3673, 190, 4043, 5274,
      4479, 162, 5600, 5164, 5128, 5060, 197, 3880, 5616, 5074, 160, 5423, 5706,
      5613, 3979, 192, 4865, 4808, 5978, 244, 5740, 6205, 4624, 4826, 170, 5429,
      5115, 6512, 207, 5615, 6481, 5404, 150, 5902, 171, 7064, 5376, 185, 6381,
      5978, 169, 6250, 147, 6452, 6961, 189, 4390, 6728, 180, 9208, 179, 6143,
      5709, 195, 6850, 6673, 188, 8240, 223, 7655, 8523, 229, 6712, 8464, 235,
      8303, 229, 7666, 5498, 237, 8868, 8217, 231, 6255, 266, 6768, 7325, 383,
      5549, 4734, 317, 2913, 4195, 257, 5362, 7136, 8627, 8674, 190, 8008, 9467,
      10811, 9351, 213, 9642, 10356, 12179, 11535, 138, 9827, 11768, 11539, 13338,
      187, 11383, 10984, 13745, 14754, 159, 14130, 13284, 14078, 13418, 166, 16377,
      13380, 14727, 15585, 224, 16505, 17762, 18118, 15012, 16175, 36093, 18533,
      16372, 31832, 20683, 17827, 31507, 18379, 20700, 40547, 19430, 18316, 71553,
      20799, 20889, 41387, 11831, 7775, 26087, 30085, 34971, 73909, 51143, 45512,
      46024, 100879, 71774, 45164, 116843, 73022, 57321, 80118, 128338, 80769,
      42354, 63785, 119293, 155957, 142223, 187109, 319, 1472, 320, 292, 489,
      491, 514, 649983, 506, 409, 1023, 758, 554, 790, 2583, 1680397, 170342,
      828, 761, 739, 433, 353, 410, 495, 366, 330, 323, 604, 295, 280, 408, 246,
      396, 431, 488, 398, 252, 338, 278, 218, 227, 430, 240, 317, 293, 314, 317,
      378, 365, 252, 199, 277, 293, 256, 523, 234, 183, 244, 196, 192, 281, 193,
      269, 354, 601, 217, 617, 484, 472, 478, 234, 374, 862, 623, 554, 625, 484,
      537, 1276, 701, 597, 1004, 617, 1372, 1458, 1069, 936, 1478, 2077, 1447,
      2114, 1753, 2238, 200, 3458, 2838, 2926, 3669, 3284, 3391, 3349, 2694, 3184,
      3757, 3387, 3753, 3721, 2169, 4429, 2576, 3159, 4210, 3066, 4240, 3067, 2862,
      4111, 3029, 3768, 4062, 3856, 3134, 3137, 4836, 2990, 4903, 2914, 3730, 3794,
      3520, 3838, 3585, 4886, 4076, 3612, 3026, 4169, 4291, 4119, 4592, 3494, 2834,
      5275, 3912, 3410, 5111, 4570, 4040, 3220, 4932, 216, 3842, 4733, 3706, 5694,
      3576, 4013, 5624, 3951, 4243, 4396, 4528, 4516, 5991, 7891, 5887, 3609, 4028,
      5346, 4490, 5625, 10329, 5096, 3899, 5596, 5139, 5443, 5714, 5673, 8819, 4850,
      5953, 5731, 6263, 4650, 4802, 10405, 6535, 5677, 6487, 5351, 5979, 7121, 11603,
      5958, 6326, 6457, 7004, 4420, 6787, 15200, 5713, 6920, 6614, 8322, 7595, 8594,
      6892, 16694, 7687, 5515, 9014, 8259, 6298, 6773, 12730, 4627, 3057, 9466, 15676,
      8571, 17291, 20060, 19892, 23600, 21361, 24708, 22389, 44660, 14108, 27077, 29496,
      27832, 31723, 35703, 30968, 36066, 34709, 31761, 38442, 31557, 38871, 40509,
      37607, 55200, 41344, 41619, 19558, 26206, 65030, 73890, 96394, 103654, 114729,
      92341, 142022, 137028, 127952, 122462, 162141, 176165, 282054, 46617, 1221, 56,
      78, 100, 648693, 63, 81, 131, 1622289, 170322, 811, 775, 597, 387, 403, 412,
      487, 310, 267, 288, 543, 265, 325, 458, 206, 393, 356, 431, 313, 451, 223,
      383, 201, 207, 340, 213, 224, 258, 209, 185, 293, 294, 248, 309, 211, 155,
      154, 159, 284, 315, 222, 187, 183, 168, 181, 150, 309, 220, 203, 155, 269,
      233, 191, 229, 245, 181, 246, 271, 341, 238, 248, 336, 371, 267, 248, 298,
      392, 270, 219, 240, 250, 173, 181, 208, 205, 215, 186, 183, 254, 246, 251,
      320, 235, 257, 245, 224, 234, 197, 241, 133, 215, 172, 175, 173, 359, 228,
      195, 141, 248, 196, 168, 156, 291, 201, 201, 186, 648, 237, 202, 710, 511,
      169, 385, 424, 209, 207, 330, 276, 804, 551, 175, 398, 480, 127, 562, 441,
      202, 1164, 333, 486, 653, 399, 926, 601, 381, 1242, 1501, 265, 1123, 914,
      252, 1403, 2049, 192, 1413, 2348, 375, 1718, 207, 2256, 3479, 193, 2823,
      2836, 366, 6660, 3318, 3236, 2708, 6562, 3301, 3753, 5696, 4425, 2499, 3097,
      6909, 4162, 3042, 2885, 6928, 3704, 4071, 6581, 3097, 4840, 2933, 7621, 3789,
      3833, 7168, 8227, 7500, 7020, 8258, 4375, 6300, 8876, 8236, 8102, 7988, 8187,
      9143, 3606, 9467, 7685, 8709, 10326, 7945, 9378, 9171, 10006, 10194, 8837,
      10518, 10899, 9484, 9509, 11514, 10748, 10096, 27936, 11948, 18029, 17415,
      19410, 20016, 11718, 21454, 22651, 24254, 22260, 20143, 12629, 9439, 15695,
      25884, 20221, 19996, 33232, 23044, 24601, 24569, 41742, 27226, 29591, 30329,
      52218, 67382, 66303, 69768, 79329, 92447, 82589, 45118, 138564, 199941, 206843,
      278991, 250282, 338102, 328626, 1254, 196, 2270828, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5760000]

def exercise_1(prefix="tst_add_arrows_on_plot_1"):
  model = mmtbx.model.manager(
      model_input = iotbx.pdb.input(source_info=None, lines=pdb_str))
  rama = ramalyze(model.get_hierarchy(), out=null_out())
  plots = rama.get_plots(
      show_labels=True,
      point_style='bo',
      markersize=1,
      markeredgecolor="black",
      dpi=300,
      markerfacecolor="white")

  ad_testing = []
  ad_testing.append( ((60,-120), (120, -120)) )
  ad_testing.append( ((-125, 120), (-125,  179)) )
  ad_testing.append( ((-120, 120), (-120, -120)) ) # wrapping up
  ad_testing.append( ((-115, -120), (-115, 120)) ) # wrapping down
  ad_testing.append( ((120, -60), (-120, -60)) ) # wrapping right
  ad_testing.append( ((-120, -65), (120, -65)) ) # wrapping left
  ad_testing.append( ((120, 0), (-120, 60)) ) # diag right
  ad_testing.append( ((-120, 55), (120, -5)) )# diag left
  ad_testing.append( ((-60, 120), (0, -120)) ) # diag up
  ad_testing.append( ((5, -120), (-55, 120)) ) # diag up
  ad_testing.append( ((150, 150), (-150, -150)) ) # going to top right corner straight
  ad_testing.append( ((140, 155), (-130, -140)) ) # going to top right corner not straight
  ad_testing.append( ((150, -150), (-150, 150)) ) # going to bottom right corner straight
  ad_testing.append( ((140, -155), (-130, 140)) ) # going to bottom right corner not straight
  ad_testing.append( ((-150, 150), (150, -150)) ) # going to top left corner straight
  ad_testing.append( ((-140, 155), (130, -140)) ) # going to top left corner not straight
  ad_testing.append( ((-150, -150), (150, 150)) ) # going to bottom left corner straight
  ad_testing.append( ((-140, -155), (130, 140)) ) # going to bottom left corner not straight

  plot = plots[0]
  add_arrows_on_plot(
      plot,
      ad_testing,
      color="red")
  plot_file_name = "%s.png" % prefix
  plot.save_image(plot_file_name, dpi=300)

  img = Image.open(plot_file_name)
  hist = img.histogram()
  # print(hist)
  hist_ok = True
  for ref, res in zip(reference_hist, hist):
    if (ref != res) and not (0.98 < ref/res < 1.02):
      hist_ok = False
      # print (ref, res, ref/res)
  assert hist_ok

if __name__ == '__main__':
  exercise_1()
