<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
</head>
<body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Arial,Helvetica,sans-serif;" dir="ltr">
<p>here is some snippets.</p>
<p>I let the midi callback set the variables.  in a frame trigger callback I detect a new signal and execute the variables.</p>
<p><br>
</p>
<p>midi is the only viable method I can see for cross platform.  It is more open than USB and simpler. </p>
<p><br>
</p>
<p>        ########################################################################</p>
<p>        global DS1_msg</p>
<p>        DS1_msg = 0</p>
<p>        </p>
<p>        global midi_in, midi_out, midi_sysex, midi_sysex_done</p>
<p>        midi_in    = rtmidi.MidiIn()</p>
<p>        midi_out   = rtmidi.MidiOut()</p>
<p>        midi_ports = midi_out.get_ports()</p>
<p>        print midi_ports</p>
<p><br>
</p>
<p>        midi_sysex_done = False</p>
<p>        if midi_ports:</p>
<p>            print midi_ports</p>
<p>            midi_out.open_port(0)</p>
<p>            </p>
<p>            midi_in.open_port(0)</p>
<p>            midi_in.set_callback(self.midi_in_callback, data='DS1')</p>
<p><br>
</p>
<p>            sysex = [240, 0, 1, 97, 16, 7, 6, 0, 0, 247]        </p>
<p>            midi_out.send_message(sysex)</p>
<p>            from DS1 import DS1_buttons</p>
<p>            for i in range(0,29):</p>
<p>                DS1_buttons[i]=0</p>
<p><br>
</p>
<p><br>
</p>
<p>    ##################################### </p>
<p>    def midi_in_callback(self, event, data):</p>
<p><br>
</p>
<p>        global DS1_msg</p>
<p>        global midi_in, midi_out</p>
<p>        global midi_sysex, midi_sysex_done</p>
<p>        from DS1 import DS1_buttons</p>
<p><br>
</p>
<p>        msg     = event[0]</p>
<p>        midi_status = msg[0]</p>
<p>        midi_device = msg[1]</p>
<p>        midi_value  = msg[2]</p>
<p>            </p>
<p>        if midi_device == 54:</p>
<p>            midi_sysex_done = True</p>
<p>        </p>
<p>        DS1_msg     = event[0]</p>
<p><br>
</p>
<p>        # --- update Continous Controller Values</p>
<p>        if midi_status ==176:</p>
<p>            midi_sysex[midi_device] = midi_value</p>
<p><br>
</p>
<p>        # --- update Button Values</p>
<p>        if midi_status ==144:</p>
<p>            DS1_buttons[midi_device] = midi_value</p>
<p><br>
</p>
<p>    ##################################### <br>
</p>
<p><br>
</p>
<p># -*- coding: utf-8 -*-</p>
<p>###############################################################################</p>
<p>#---------1---------2---------3---------4---------5---------6---------7--------</p>
<p>###############################################################################</p>
<p># National Center for Macromolecular Imaging</p>
<p># Matthew Dougherty/matthewd@bcm.edu</p>
<p>###############################################################################</p>
<p><br>
</p>
<p>S3D_focal  = 0.5</p>
<p>DS1_buttons= {}</p>
<p><br>
</p>
<p><br>
</p>
<p>def DS1(midi_in, midi_out,msg):</p>
<p><br>
</p>
<p>    midi_status = msg[0]</p>
<p>    midi_device = msg[1]</p>
<p>    midi_value  = msg[2]</p>
<p>    #print 'DS1:',msg</p>
<p>    </p>
<p>    # --- FREEZE</p>
<p>    if midi_status ==144 and midi_device ==16:</p>
<p>        import chimera</p>
<p>        chimera.runCommand('freeze')</p>
<p>        print 'FREEZE'</p>
<p><br>
</p>
<p>    # --- reset default</p>
<p>    if midi_status ==144 and midi_device ==22:</p>
<p>        import chimera</p>
<p>        chimera.runCommand('reset default')</p>
<p>        print 'Reset Default'</p>
<p><br>
</p>
<p>    # --- update Continous Controller Values</p>
<p>    from UCP import midi_sysex</p>
<p>    if midi_status ==176:</p>
<p>        midi_sysex[midi_device] = midi_value</p>
<p><br>
</p>
<p>    # --- update Button Values</p>
<p>    if midi_status ==144:</p>
<p>        DS1_buttons[midi_device] = midi_value</p>
<p>    </p>
<p><br>
</p>
<p>    # --- toggle Layout</p>
<p>    if midi_status ==144 and midi_device ==21:</p>
<p>        from UCP import selfHID</p>
<p> </p>
<p>        if midi_value == 0:</p>
<p>           selfHID.L1()</p>
<p><br>
</p>
<p>        if midi_value == 127:</p>
<p>           selfHID.L2()</p>
<p>  </p>
<p>    # --- toggle S3D </p>
<p>    if midi_status ==144 and midi_device ==18:</p>
<p>        from UCP import selfHID</p>
<p>        selfHID.S3D()</p>
<p>        return</p>
<p><br>
</p>
<p>    # --- Volume Rendering    </p>
<p>    if midi_status ==176 and (midi_device >=1 and midi_device <= 48):</p>
<p>        DS1_VR(midi_device, midi_value)</p>
<p>        return</p>
<p><br>
</p>
<p>    if midi_status ==144 and (midi_device >=0 and midi_device <= 15):</p>
<p>        DS1_VR(midi_device, midi_value)</p>
<p>        return</p>
<p><br>
</p>
<p>    # --- Camera</p>
<p>    if midi_status ==176 and (midi_device >=96 and midi_device <= 99):</p>
<p>        DS1_Camera(midi_device, midi_value)</p>
<p>        return</p>
<p><br>
</p>
<p>    if midi_status ==176 and (midi_device >=49 and midi_device <= 53):</p>
<p>        DS1_Camera(midi_device, midi_value)</p>
<p>        return</p>
<p><br>
</p>
<p>    if midi_status ==144 and (midi_device >=25 and midi_device <= 28):</p>
<p>        DS1_buttons[midi_device] = midi_value</p>
<p>        DS1_Camera(midi_device, midi_value)</p>
<p>        return</p>
<p><br>
</p>
<p>###############################################################################</p>
<p>def DS1_VR(d,v):</p>
<p>    </p>
<p>    if DS1_buttons[20]==127:</p>
<p>        return</p>
<p><br>
</p>
<p>    from VolumeViewer import active_volume</p>
<p>    v = active_volume()</p>
<p>    if v == None:</p>
<p>        return</p>
<p><br>
</p>
<p>    levels = getattr(v, "solid_levels")</p>
<p>    colors = getattr(v, "solid_colors")</p>
<p>    cnt    = len(colors)</p>
<p>    if cnt != 8:</p>
<p>        return</p>
<p><br>
</p>
<p>    #print d,v</p>
<p><br>
</p>
<p>    from UCP import midi_sysex</p>
<p>        </p>
<p>    sbf    = getattr(v, "solid_brightness_factor")</p>
<p>    td     = getattr(v, "transparency_depth")</p>
<p>    levels = getattr(v, "solid_levels")</p>
<p>    colors = getattr(v, "solid_colors")</p>
<p><br>
</p>
<p>    kw = {}</p>
<p>    kw["transparency_depth"]      = td</p>
<p>    kw["solid_brightness_factor"] = sbf</p>
<p><br>
</p>
<p>    s = v.matrix_value_statistics(read_matrix = False)</p>
<p>    rMax = s.maximum</p>
<p>    rMin = s.minimum</p>
<p><br>
</p>
<p>    j = 0</p>
<p>    for i in range(0,8):</p>
<p>        t,a         = levels[i]</p>
<p>        cr,cg,cb,ca = colors[i]</p>
<p><br>
</p>
<p>        cr = float(midi_sysex[1+j])/127.0</p>
<p>        cg = float(midi_sysex[2+j])/127.0</p>
<p>        cb = float(midi_sysex[3+j])/127.0</p>
<p>        ca = float(midi_sysex[4+j])/127.0       </p>
<p>        a  = float(midi_sysex[41+i])/127.0</p>
<p><br>
</p>
<p>        # null transparency</p>
<p>        if DS1_buttons[i*2+1]==127:</p>
<p>            ca = 0</p>
<p>            a  = 0</p>
<p>            </p>
<p>        # lock density value</p>
<p>        if DS1_buttons[17]!=127:</p>
<p>            t = rMin+(rMax-rMin)*float(midi_sysex[5+j])/127.0</p>
<p>            </p>
<p>        print DS1_buttons[17],i,d</p>
<p>        if DS1_buttons[17]==127 and (i>0 and i<7):</p>
<p>            if (i+1)*5==d:</p>
<p>                t0,t         = levels[i-1]</p>
<p>                t1,t         = levels[i+1]</p>
<p>                t = t0+(t1-t0)*float(midi_sysex[d])/127.0</p>
<p>                print i,d,t0,t,t1</p>
<p>                </p>
<p>        if DS1_buttons[17]==127 and i==0:</p>
<p>            m,t = levels[1]</p>
<p>            t = rMin+(m-rMin)*float(midi_sysex[5+j])/127.0</p>
<p><br>
</p>
<p>        if DS1_buttons[17]==127 and i==7:</p>
<p>            m,t = levels[6]</p>
<p>            t = m + (rMax-m)*float(midi_sysex[5+j])/127.0</p>
<p>            </p>
<p>        levels[i] = (t,a)</p>
<p>        colors[i] = (cr,cg,cb,ca)</p>
<p>        j=j+5</p>
<p>    </p>
<p>    levelsOut=tuple(levels)</p>
<p>    kw["solid_levels"] = levelsOut</p>
<p>    colors[i-1] = (cr,cg,cb,ca)</p>
<p>    kw["solid_colors"] = colors</p>
<p>    v.set_parameters(**kw)</p>
<p>    v.show()</p>
<p>    </p>
<p><br>
</p>
<p>###############################################################################</p>
<p>def DS1_Camera(d,v):</p>
<p><br>
</p>
<p>    from UCP import selfHID</p>
<p>    from UCP import midi_sysex</p>
<p>    </p>
<p>    vScaled = float(v)/127.0</p>
<p>    from chimera import viewer</p>
<p>    cam = viewer.camera</p>
<p><br>
</p>
<p>    # --- Save Position</p>
<p>    if d==25 and v==127:</p>
<p>        selfHID.executeSavepos()</p>
<p>        return</p>
<p><br>
</p>
<p>    # --- Clipping Plane order of magnitude</p>
<p>    if d==50:</p>
<p>        f = float(midi_sysex[50])</p>
<p>        c = (f+0.1)**(f/60.0)-0.9</p>
<p>        print 'CP OM=', c</p>
<p>        </p>
<p>    # --- set select camera</p>
<p>    if d==96 and v==1:</p>
<p>        selfHID.executeKFinc()</p>
<p><br>
</p>
<p>    if d==96 and v==127:</p>
<p>        selfHID.executeKFdec()</p>
<p>        </p>
<p>        </p>
<p>    # --- set S3D focal plane</p>
<p>    if d==49:</p>
<p>        global S3D_focal</p>
<p>        S3D_focal = vScaled</p>
<p>        near, far = cam.nearFar</p>
<p>        cam.focal = near-(S3D_focal*(near-far))</p>
<p><br>
</p>
<p>     # --- set field of view       </p>
<p>    if d==51:</p>
<p>        sdMax = 130.0</p>
<p>        sdMin = 0.1</p>
<p>        cam.fieldOfView = (sdMax-sdMin)*vScaled+sdMin</p>
<p>        </p>
<p>    # --- set S3D eye seperation</p>
<p>    if d==52:</p>
<p>        esMax=300</p>
<p>        esMin=0.1</p>
<p>        cam.eyeSeparation  = (esMax-esMin)*vScaled+esMin</p>
<p><br>
</p>
<p>    # --- set S3D screen distance        </p>
<p>    if d==53:</p>
<p>        sdMax = 2000.0</p>
<p>        sdMin = 100.0</p>
<p>        cam.screenDistance = (sdMax-sdMin)*vScaled+sdMin</p>
<p><br>
</p>
<p><br>
</p>
<p>    # --- set near focal plane</p>
<p>    f = float(midi_sysex[50])</p>
<p>    c = (f+0.1)**(f/60.0)-0.9</p>
<p>    if d==98 and v==1:</p>
<p>        near, far = cam.nearFar</p>
<p>        near = near - c</p>
<p>        cam.nearFar = near, far</p>
<p><br>
</p>
<p>    if d==98 and v==127:</p>
<p>        near, far = cam.nearFar</p>
<p>        near = near + c</p>
<p>        cam.nearFar = near, far</p>
<p><br>
</p>
<p>    # --- set near focal plane</p>
<p>    if d==99 and v==1:</p>
<p>        near, far = cam.nearFar</p>
<p>        far = far - c</p>
<p>        cam.nearFar = near, far</p>
<p><br>
</p>
<p>    if d==99 and v==127:</p>
<p>        near, far = cam.nearFar</p>
<p>        far = far+ c</p>
<p>        cam.nearFar = near, far</p>
<p><br>
</p>
<p>       </p>
<p>        </p>
<div><br>
</div>
<p><br>
</p>
<div id="Signature">
<div id="divtagdefaultwrapper" style="font-size:12pt; color:#000000; background-color:#FFFFFF; font-family:Calibri,Arial,Helvetica,sans-serif">
<div class="BodyFragment"><font size="2">
<div class="PlainText">Matthew Dougherty<br>
National Center for Macromolecular Imaging<br>
Baylor College of Medicine<br>
<span style="font-size:13.0pt; font-family:Calibri">=================================================</span><br>
</div>
<div class="PlainText"><span style="font-size:13pt; font-family:Calibri">=================================================</span><span style="font-size:13.0pt; font-family:Calibri"><br>
</span></div>
</font></div>
</div>
</div>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Tom Goddard <goddard@sonic.net><br>
<b>Sent:</b> Monday, January 30, 2017 8:00:51 PM<br>
<b>To:</b> Dougherty, Matthew T<br>
<b>Cc:</b> chimera-dev@cgl.ucsf.edu<br>
<b>Subject:</b> Re: [chimera-dev] midi</font>
<div> </div>
</div>
<div><font size="2" color="black"><b>***CAUTION:*** This email is not from a BCM Source. Only click links or open attachments you know are safe.</b></font>
<hr>
Hi Matt,
<div class=""><br class="">
</div>
<div class="">  The RtMidi library looks like a good find.  I’ll be interested to hear how your testing goes.  Also I’d like to hear how difficult it is to include rtmidi in your tool.  We usually only ship third-party libraries that the Chimera core tools
 use — it is too difficult to compile and maintain them on all platforms.  Another issue is that all our development effort is on ChimeraX.</div>
<div class=""><br class="">
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>Tom</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
<div>
<blockquote type="cite" class="">
<div class="">On Jan 28, 2017, at 11:47 AM, Dougherty, Matthew T  wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div id="divtagdefaultwrapper" dir="ltr" style="font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; font-size: 12pt; font-family: Calibri, Arial, Helvetica, sans-serif;" class="">
<div style="margin-top: 0px; margin-bottom: 0px;" class="">Hi,</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class="">I got the midi interface working with chimera, thanks.  I ended up using the rtmidi package instead of mido.</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><a href="https://urldefense.proofpoint.com/v2/url?u=https-3A__pypi.python.org_pypi_python-2Drtmidi&d=DwMFaQ&c=ZQs-KZ8oxEw0p81sqgiaRA&r=lEMX2_AJ6Iksc5dFd0-VOg&m=D2s5FN-a0IhX27WTzA4T7wVxJoMVaC7UwAgWcYwtHqM&s=sU4YDkPK3rVyfMNNljxFiK3Yrc6S921529ujMwqwcR8&e=" class="OWAAutoLink" id="LPlnk132164" previewremoved="true">https://pypi.python.org/pypi/python-rtmidi</a></div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class="">Midi will significantly reduce my reliance on accelerators.  It will give me the ability to pass multivariate parameters from hardware and modify LED displays on those devices.   Previous efforts directly
 working with USB has be difficult because of lack of compliance and limited open source methods.<br class="">
<br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class="">The software I developed allows the DS1 control surface to easily control volume rendering and stereographics.  </div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__lividinstruments.com_products_ds1_&d=DwMFaQ&c=ZQs-KZ8oxEw0p81sqgiaRA&r=lEMX2_AJ6Iksc5dFd0-VOg&m=D2s5FN-a0IhX27WTzA4T7wVxJoMVaC7UwAgWcYwtHqM&s=znUNVAMdLozE-1DIKMbrlrDReCP0Qr7QYpzObLdpP5s&e=" class="OWAAutoLink" id="LPlnk295138" previewremoved="true">http://lividinstruments.com/products/ds1/</a> <br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class="">I am anticipating this will improve operational viz for tomograms.  If users demonstrate value in device, will release as an chimera extension.  Internal NCMI testing begins next week.</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class="">Also looking at other inexpensive midi devices.  </div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><span style="font-size: 12pt;" class=""><br class="">
</span></div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><span style="font-size: 12pt;" class="">Recommending chimera ship with rtmidi library. </span></div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class="">thanks, </div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div style="margin-top: 0px; margin-bottom: 0px;" class=""><br class="">
</div>
<div id="Signature" class="">
<div id="divtagdefaultwrapper" style="font-size: 12pt; background-color: rgb(255, 255, 255); font-family: Calibri, Arial, Helvetica, sans-serif;" class="">
<div class="BodyFragment"><font size="2" class="">
<div class="PlainText">Matthew Dougherty<br class="">
National Center for Macromolecular Imaging<br class="">
Baylor College of Medicine<br class="">
<span style="font-size: 13pt; font-family: Calibri;" class="">=================================================</span><br class="">
</div>
<div class="PlainText"><span style="font-size: 13pt; font-family: Calibri;" class="">=================================================</span><span style="font-size: 13pt; font-family: Calibri;" class=""><br class="">
</span></div>
</font></div>
</div>
</div>
</div>
<span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Chimera-dev
 mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<a href="mailto:Chimera-dev@cgl.ucsf.edu" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">Chimera-dev@cgl.ucsf.edu</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">
<a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__plato.cgl.ucsf.edu_mailman_listinfo_chimera-2Ddev&d=DwMFaQ&c=ZQs-KZ8oxEw0p81sqgiaRA&r=lEMX2_AJ6Iksc5dFd0-VOg&m=D2s5FN-a0IhX27WTzA4T7wVxJoMVaC7UwAgWcYwtHqM&s=F5OTntuRw1fKYlzDhQ4C0mt2ahkwt3oZD7OgxeL8d6A&e=" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">http://plato.cgl.ucsf.edu/mailman/listinfo/chimera-dev</a></div>
</blockquote>
</div>
<br class="">
</div>
</div>
</body>
</html>