cubevis 0.5.24__py3-none-any.whl → 0.5.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cubevis might be problematic. Click here for more details.
- cubevis/__js__/cubevisjs.min.js +3 -2
- cubevis/__version__.py +1 -1
- cubevis/bokeh/models/__init__.py +1 -0
- cubevis/bokeh/models/_shared_dict.py +23 -0
- cubevis/toolbox/_cube.py +57 -15
- cubevis/toolbox/_interactive_clean_ui.mustache +26 -19
- cubevis/toolbox/_interactive_clean_ui.py +26 -19
- {cubevis-0.5.24.dist-info → cubevis-0.5.25.dist-info}/METADATA +1 -1
- {cubevis-0.5.24.dist-info → cubevis-0.5.25.dist-info}/RECORD +11 -10
- {cubevis-0.5.24.dist-info → cubevis-0.5.25.dist-info}/WHEEL +0 -0
- {cubevis-0.5.24.dist-info → cubevis-0.5.25.dist-info}/licenses/LICENSE +0 -0
cubevis/__js__/cubevisjs.min.js
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
}
|
|
43
43
|
})
|
|
44
44
|
({
|
|
45
|
-
"
|
|
45
|
+
"97397933dc": function _(a,t,e,o,c){o();const i=a("tslib"),n=a("b33e822163");c("DataPipe",n.DataPipe);const s=a("2889e0dd45");c("ImagePipe",s.ImagePipe);const p=a("de65005924");c("ImageDataSource",p.ImageDataSource);const r=a("02e3c3e46c");c("SpectraDataSource",r.SpectraDataSource);const S=a("64b16deff9");c("UpdatableDataSource",S.UpdatableDataSource);const D=a("b6ae454f0d");c("WcsTicks",D.WcsTicks);const T=a("cb7d28d6b3");c("DragTool",T.DragTool);const d=a("01959f25a3");c("CBResetTool",d.CBResetTool);const l=a("e3901fa9f2");c("serialize",l.serialize),c("deserialize",l.deserialize);const u=a("9f961622ce");c("TipButton",u.TipButton);const b=a("ca4c845905");c("Tip",b.Tip);const g=a("50a1e32f01");c("SharedDict",g.SharedDict);const f=a("b55081402e");c("EditSpan",f.EditSpan);const E=a("9144bfc7a5");c("EvTextInput",E.EvTextInput);const I=a("74e0abef8a");c("EvPolyAnnotation",I.EvPolyAnnotation);const P=i.__importStar(a("15b954190c"));e.find=P;(0,a("@bokehjs/base").register_models)({DataPipe:n.DataPipe,ImagePipe:s.ImagePipe,ImageDataSource:p.ImageDataSource,SpectraDataSource:r.SpectraDataSource,UpdatableDataSource:S.UpdatableDataSource,WcsTicks:D.WcsTicks,DragTool:T.DragTool,CBResetTool:d.CBResetTool,Tip:b.Tip,TipButton:u.TipButton,SharedDict:g.SharedDict,EditSpan:f.EditSpan,EvTextInput:E.EvTextInput,EvPolyAnnotation:I.EvPolyAnnotation})},
|
|
46
46
|
"b33e822163": function _(e,s,t,i,n){var o;i();const c=e("@bokehjs/models/sources/data_source"),a=e("e3901fa9f2"),d=e("@bokehjs/core/util/callbacks");class l extends c.DataSource{constructor(e){super(e),this.send_queue={},this.connection_queue=[],this.pending={},this.incoming_callbacks={}}initialize(){super.initialize();let e=`ws://${this.address[0]}:${this.address[1]}`;console.log("datapipe url:",e);var s=void 0;document.shutdown_in_progress_=!1;var t=()=>{void 0!==this.websocket&&this.websocket.close(),this.websocket=new WebSocket(e),this.websocket.binaryType="arraybuffer",this.websocket.addEventListener("error",(e=>{console.log("error encountered:",e)})),this.websocket.onmessage=e=>{if("string"==typeof e.data||e.data instanceof String){let s=(0,a.deserialize)(e.data);if("id"in s&&"direction"in s&&"message"in s){let{id:e,message:t,direction:i}=s;if(void 0===t&&console.log("Error, event failure",s),"j2p"==i)if(e in this.pending){let{cb:i}=this.pending[e];if(delete this.pending[e],e in this.send_queue&&this.send_queue[e].length>0){let{cb:s,msg:t}=this.send_queue[e].shift();this.pending[e]={cb:s},this.websocket.send((0,a.serialize)(t))}void 0===t?console.log("DROPPING ERROR FOR NOW (maybe need error callbacks)",s):i(t)}else console.log("message received but could not find id");else if(e in this.incoming_callbacks){let s=this.incoming_callbacks[e](t);this.websocket.send((0,a.serialize)({id:e,direction:i,message:s,session:casalib.object_id(this)}))}}else console.log(`datapipe received message without one of 'id', 'message' or 'direction': ${s}`)}else console.log("datapipe received binary data",e.data.byteLength,"bytes")},this.websocket.onopen=()=>{for(s?0==s.connected&&console.log(`connection reestablished at ${new Date}`):this.websocket.send((0,a.serialize)({id:"initialize",direction:"j2p",session:casalib.object_id(this)})),s=new casalib.ReconnectState;this.connection_queue.length>0;){let e=this.connection_queue.shift();this.send.apply(e[0],e[1])}},this.websocket.onclose=()=>{if(s&&1==s.connected&&(console.log(`connection lost at ${new Date}`),s.connected=!1,!document.shutdown_in_progress_)){console.log(`connection lost at ${new Date}`);var e=s;function i(n){0==s.connected&&(console.log(`${n+1}\treconnection attempt ${new Date}`),t(),e.backoff(),e.retries>0?setTimeout(i,e.timeout,n+1):0==s.connected&&console.log(`aborting reconnection after ${n} attempts ${new Date}`))}i(0)}}};t();(()=>{null!=this.init_script&&(0,d.execute)(this.init_script,this)})()}register(e,s){this.incoming_callbacks[e]=s}send(e,s,t,i=!1){let n={id:e,message:s,direction:"j2p",session:casalib.object_id(this)};if(!this.websocket||e in this.pending)if(e in this.send_queue)if("boolean"==typeof i&&i&&this.send_queue[e].length>0)this.send_queue[e][0].msg=n,this.send_queue[e][0].cb=t;else if("function"==typeof i&&this.send_queue[e].length>0){let o=!1;for(const c of this.send_queue[e])i(c.msg.message)&&(c.msg=n,c.cb=t,o=!0);o||this.send_queue[e].push({cb:t,msg:n})}else this.send_queue[e].push({cb:t,msg:n});else this.send_queue[e]=[{cb:t,msg:n}];else if(this.websocket.readyState===WebSocket.CONNECTING)this.connection_queue.push([this,[e,s,t]]);else if(e in this.send_queue&&this.send_queue[e].length>0){this.send_queue[e].push({cb:t,msg:n});{let{cb:d,msg:l}=this.send_queue[e].shift();if(this.pending[e]={cb:d},this.websocket.readyState===WebSocket.OPEN)this.websocket.send((0,a.serialize)(l));else{let u=20,h=this;function r(){h.websocket.readyState===WebSocket.OPEN?h.websocket.send((0,a.serialize)(l)):(u-=1,u>0&&setTimeout(r,3e3))}setTimeout(r,3e3)}}}else if(this.websocket.readyState===WebSocket.OPEN)this.pending[e]={cb:t},this.websocket.send((0,a.serialize)(n));else{let b=20,g=this;function _(){g.websocket.readyState===WebSocket.OPEN?(g.pending[e]={cb:t},g.websocket.send((0,a.serialize)(n))):(b-=1,b>0&&setTimeout(_,3e3))}setTimeout(_,3e3)}}}t.DataPipe=l,o=l,l.__name__="DataPipe",l.__module__="cubevis.bokeh.sources._data_pipe",o.define((({Any:e,Tuple:s,String:t,Number:i})=>({init_script:[e,null],address:[s(t,i)]})))},
|
|
47
47
|
"e3901fa9f2": function _(e,r,s,i,o){i();const l=e("@bokehjs/base"),a=e("@bokehjs/core/resolvers"),t=e("@bokehjs/core/serialization/deserializer"),n=e("@bokehjs/core/serialization/serializer"),{deserialize:c}=new class{constructor(){this.resolver=new a.ModelResolver(l.default_resolver),this.deserializer=new t.Deserializer(this.resolver),this.deserialize=e=>{try{return this.deserializer.decode(JSON.parse(e))}catch(r){return console.group("deserialize error"),console.log(e),console.log(r),console.groupEnd(),{}}}}};s.deserialize=c;const{serialize:z}=new class{constructor(){this.serializer=new n.Serializer,this.serialize=e=>JSON.stringify(this.serializer.encode(e))}};s.serialize=z},
|
|
48
48
|
"2889e0dd45": function _(i,e,s,t,n){var a;t();const o=i("@bokehjs/models/sources/column_data_source"),d=i("b33e822163");class r extends d.DataPipe{constructor(i){super(i),this.position={},this._wcs=null}initialize(){super.initialize(),this.fits_header_json&&(this._wcs=new casalib.coordtxl.WCSTransform(new casalib.coordtxl.MapKeywordProvider(JSON.parse(this.fits_header_json))))}channel(i,e,s){this.position[s]={index:i};let t={action:"channel",index:i,id:s};super.send(this.dataid,t,(i=>{null!=this._histogram_source&&"hist"in i&&"top"in i.hist&&"bottom"in i.hist&&"left"in i.hist&&"right"in i.hist&&(this._histogram_source.data=i.hist),e(i)}))}spectrum(i,e,s,t=!1){let n={action:"spectrum",index:i,id:s};super.send(this.dataid,n,e,t)}adjust_colormap(i,e,s,t,n=!1){const a={action:"adjust-colormap",bounds:i,transfer:e,id:t};super.send(this.dataid,a,s,n)}refresh(i,e,s=[0,0]){let{index:t}=e in this.position?this.position[e]:{index:s};if(2===t.length){let s={action:"channel",index:t,id:e};super.send(this.dataid,s,i)}else if(3===t.length){let s={action:"spectrum",index:t,id:e};super.send(this.dataid,s,i)}}wcs(){return this._wcs}}s.ImagePipe=r,a=r,r.__name__="ImagePipe",r.__module__="cubevis.bokeh.sources._image_pipe",a.define((({Number:i,Nullable:e,String:s,Tuple:t,Ref:n})=>({dataid:[s],shape:[t(i,i,i,i)],fits_header_json:[e(s),null],_histogram_source:[e(n(o.ColumnDataSource)),null]})))},
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"01959f25a3": function _(e,o,l,s,t){var c;s();const _=e("@bokehjs/models/tools/actions/reset_tool"),i=e("@bokehjs/styles/icons.css"),a=e("@bokehjs/core/util/callbacks");class n extends _.ResetToolView{doit(){const{precallback:e,postcallback:o}=this.model;null!=e&&(0,a.execute)(e,this.model),this.plot_view.reset(),null!=o&&(0,a.execute)(o,this.model)}}l.CBResetToolView=n,n.__name__="CBResetToolView";class r extends _.ResetTool{constructor(e){super(e),this.tool_name="CBReset",this.tool_icon=i.tool_icon_reset}}l.CBResetTool=r,c=r,r.__name__="CBResetTool",r.__module__="cubevis.bokeh.tools._cbreset_tool",c.prototype.default_view=n,c.define((({Any:e,Nullable:o})=>({precallback:[o(e),null],postcallback:[o(e),null]}))),c.register_alias("cbreset",(()=>new c))},
|
|
57
57
|
"9f961622ce": function _(e,t,i,o,s){var n;o();const l=e("@bokehjs/models/widgets/abstract_button"),c=e("@bokehjs/models/ui/tooltip"),d=e("@bokehjs/models/ui/icons/builtin_icon"),u=e("@bokehjs/core/build_views"),h=e("@bokehjs/core/bokeh_events"),r=e("@bokehjs/core/util/object");class a extends l.AbstractButtonView{constructor(){super(...arguments),this.isMouseInside=!1}click(){this.model.trigger_event(new h.ButtonClick),super.click()}*children(){yield*super.children(),yield this.tooltip}Show(){this.tooltip.model.setv({visible:!0,closable:!1})}unShow(){this.tooltip.model.setv({visible:!1,closable:!1})}async lazy_initialize(){const{hover_wait:e}=this.model;this.debouncedShow=casalib.debounce((()=>{this.isMouseInside&&this.Show()}),1e3*e),await super.lazy_initialize();const{tooltip:t}=this.model;this.tooltip=await(0,u.build_view)(t,{parent:this})}remove(){this.tooltip.remove(),super.remove()}render(){super.render(),this.el.addEventListener("mouseenter",(()=>{this.isMouseInside=!0,this.debouncedShow()})),this.el.addEventListener("mouseleave",(()=>{this.isMouseInside=!1,this.debouncedShow.cancel(),this.unShow()})),document.addEventListener("mousedown",(e=>{if(void 0===(0,r.dict)(this.model.js_event_callbacks).get(h.ButtonClick.prototype.event_name)){if(e.composedPath().includes(this.tooltip.el))return;this.debouncedShow.cancel(),this.unShow()}else this.isMouseInside=!1,this.debouncedShow.cancel(),this.unShow()})),window.addEventListener("blur",(()=>{this.debouncedShow.cancel(),this.unShow()}))}}i.TipButtonView=a,a.__name__="TipButtonView";class b extends l.AbstractButton{constructor(e){super(e)}on_click(e){this.on_event(h.ButtonClick,e)}}i.TipButton=b,n=b,b.__name__="TipButton",b.__module__="cubevis.bokeh.models._tip_button",n.prototype.default_view=a,n.define((({Ref:e,Number:t})=>({tooltip:[e(c.Tooltip)],hover_wait:[t,1.5]}))),n.override({label:"",icon:new d.BuiltinIcon({icon_name:"help",size:18}),button_type:"default"})},
|
|
58
58
|
"ca4c845905": function _(e,i,s,t,o){var l;t();const d=e("@bokehjs/models/layouts/layout_dom"),n=e("@bokehjs/models/ui/ui_element"),h=e("@bokehjs/models/ui/tooltip"),r=e("@bokehjs/core/dom"),a=e("@bokehjs/core/build_views");class c extends d.LayoutDOMView{constructor(){super(...arguments),this.isMouseInside=!1}stylesheets(){return[...super.stylesheets(),"*, *:before, *:after { box-sizing: border-box; } fieldset { border: 0px; margin: 0px; padding: 0px; }"]}Show(){this.tooltip.model.setv({visible:!0,closable:!1})}unShow(){this.tooltip.model.setv({visible:!1,closable:!1})}async lazy_initialize(){const{hover_wait:e}=this.model;this.debouncedShow=casalib.debounce((()=>{this.isMouseInside&&this.Show()}),1e3*e),await super.lazy_initialize(),await this.build_child_views();const{tooltip:i}=this.model;this.tooltip=await(0,a.build_view)(i,{parent:this})}remove(){this.tooltip.remove(),super.remove()}connect_signals(){super.connect_signals();const{child:e}=this.model.properties;this.on_change(e,(()=>this.update_children())),this.el.addEventListener("mouseenter",(e=>{this.mouseenter.emit(e)})),this.el.addEventListener("mouseleave",(e=>{this.mouseleave.emit(e)}))}*children(){yield*super.children(),yield this.tooltip}get child_models(){return[this.model.child]}render(){super.render(),this.el.addEventListener("mouseenter",(()=>{this.isMouseInside=!0,this.debouncedShow()})),this.el.addEventListener("mouseleave",(()=>{this.isMouseInside=!1,this.debouncedShow.cancel(),this.unShow()})),window.addEventListener("blur",(()=>{this.debouncedShow.cancel(),this.unShow()})),this.el.addEventListener("click",(()=>{this.debouncedShow.cancel(),this.unShow()}));const e=this.child_views.map((e=>e.el));this.fieldset_el=(0,r.fieldset)({},...e),this.shadow_el.appendChild(this.fieldset_el)}_update_children(){const e=this.child_views.map((e=>e.el));this.fieldset_el.append(...e)}}s.TipView=c,c.__name__="TipView";class u extends d.LayoutDOM{constructor(e){super(e)}}s.Tip=u,l=u,u.__name__="Tip",u.__module__="cubevis.bokeh.models._tip",l.prototype.default_view=c,l.define((({Ref:e,Number:i})=>({child:[e(n.UIElement)],tooltip:[e(h.Tooltip)],hover_wait:[i,1.5]})))},
|
|
59
|
+
"50a1e32f01": function _(e,s,i,n,t){var a;n();const c=e("@bokehjs/core/view"),o=e("@bokehjs/model");class _ extends c.View{initialize(){super.initialize()}connect_signals(){super.connect_signals();const{values:e}=this.model.properties;this.on_change(e,(()=>this.values_changed()))}values_changed(){}}i.SharedDictView=_,_.__name__="SharedDictView";class d extends o.Model{constructor(e){super(e)}}i.SharedDict=d,a=d,d.__name__="SharedDict",d.__module__="cubevis.bokeh.models._shared_dict",a.prototype.default_view=_,a.define((({Dict:e,Unknown:s})=>({values:[e(s),{}]})))},
|
|
59
60
|
"b55081402e": function _(e,n,t,_,s){var a;_();const o=e("@bokehjs/models/annotations/span"),p=e("@bokehjs/core/bokeh_events");class r extends o.SpanView{on_pan_start(e){const n=super.on_pan_start(e);return this.model.trigger_event(new p.LODStart),n}on_pan(e){super.on_pan(e)}on_pan_end(e){super.on_pan_end(e),this.model.trigger_event(new p.LODEnd)}}t.EditSpanView=r,r.__name__="EditSpanView";class d extends o.Span{constructor(e){super(e)}}t.EditSpan=d,a=d,d.__name__="EditSpan",d.__module__="cubevis.bokeh.models._edit_span",a.prototype.default_view=r},
|
|
60
61
|
"9144bfc7a5": function _(e,t,s,n,r){var i;n();const l=e("@bokehjs/models/widgets/text_input"),o=e("@bokehjs/core/dom"),u=e("@bokehjs/core/bokeh_events");class _ extends l.TextInputView{stylesheets(){return[...super.stylesheets(),new o.InlineStyleSheet(".bk-input-prefix { padding: 0 var(--padding-vertical); }")]}connect_signals(){super.connect_signals(),this.el.addEventListener("mouseenter",(e=>{this.model.trigger_event(new u.MouseEnter(e.screenX,e.screenY,e.x,e.y,{shift:e.shiftKey,ctrl:e.ctrlKey,alt:e.altKey}))})),this.el.addEventListener("mouseleave",(e=>{this.model.trigger_event(new u.MouseLeave(e.screenX,e.screenY,e.x,e.y,{shift:e.shiftKey,ctrl:e.ctrlKey,alt:e.altKey}))}))}render(){super.render()}}s.EvTextInputView=_,_.__name__="EvTextInputView";class c extends l.TextInput{constructor(e){super(e)}}s.EvTextInput=c,i=c,c.__name__="EvTextInput",c.__module__="cubevis.bokeh.models._ev_text_input",i.prototype.default_view=_},
|
|
61
62
|
"74e0abef8a": function _(e,t,n,s,o){var i;s();const r=e("@bokehjs/models/annotations/poly_annotation"),a=e("@bokehjs/core/bokeh_events");class _ extends r.PolyAnnotationView{on_enter(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.MouseEnter(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt}),o=super.on_enter(e);return this.model.trigger_event(s),o}on_leave(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.MouseLeave(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt});super.on_leave(e),this.model.trigger_event(s)}on_pan_start(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.PanStart(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt}),o=super.on_pan_start(e);return this.model.trigger_event(s),o}on_pan_end(e){const{x_scale:t,y_scale:n}=this.plot_view.frame,s=new a.PanEnd(e.sx,e.sy,t.invert(e.sx),n.invert(e.sy),{shift:e.modifiers.shift,ctrl:e.modifiers.ctrl,alt:e.modifiers.alt});super.on_pan_end(e),this.model.trigger_event(s)}on_pan(e){super.on_pan(e);const t=new a.RangesUpdate(e.sx,e.sx+e.dx,e.sy,e.sy+e.dy);this.model.trigger_event(t)}}n.EvPolyAnnotationView=_,_.__name__="EvPolyAnnotationView";class l extends r.PolyAnnotation{constructor(e){super(e)}}n.EvPolyAnnotation=l,i=l,l.__name__="EvPolyAnnotation",l.__module__="cubevis.bokeh.annotations._ev_poly_annotation",i.prototype.default_view=_},
|
|
62
|
-
}, "
|
|
63
|
+
}, "97397933dc", {"index":"97397933dc","src/bokeh/sources/data_pipe":"b33e822163","src/bokeh/util/conversions":"e3901fa9f2","src/bokeh/sources/image_pipe":"2889e0dd45","src/bokeh/sources/image_data_source":"de65005924","src/bokeh/sources/spectra_data_source":"02e3c3e46c","src/bokeh/sources/updatable_data_source":"64b16deff9","src/bokeh/format/wcs_ticks":"b6ae454f0d","src/bokeh/tools/drag_tool":"cb7d28d6b3","src/bokeh/events":"949501ff1c","src/bokeh/util/find":"15b954190c","src/bokeh/tools/cbreset_tool":"01959f25a3","src/bokeh/models/tip_button":"9f961622ce","src/bokeh/models/tip":"ca4c845905","src/bokeh/models/shared_dict":"50a1e32f01","src/bokeh/models/edit_span":"b55081402e","src/bokeh/models/ev_text_input":"9144bfc7a5","src/bokeh/annotations/ev_poly_annotation":"74e0abef8a"}, {});});
|
cubevis/__version__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.5.
|
|
1
|
+
__version__ = '0.5.25'
|
cubevis/bokeh/models/__init__.py
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from bokeh.models import Model
|
|
2
|
+
from bokeh.models.layouts import LayoutDOM, UIElement
|
|
3
|
+
from bokeh.core.properties import Dict, Any, String, Required
|
|
4
|
+
|
|
5
|
+
class SharedDict(Model):
|
|
6
|
+
'''Display a tooltip for the child element
|
|
7
|
+
'''
|
|
8
|
+
|
|
9
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
10
|
+
if len(args) != 1 and "values" not in kwargs:
|
|
11
|
+
raise ValueError("a 'values' argument must be supplied")
|
|
12
|
+
elif len(args) == 1 and "values" in kwargs:
|
|
13
|
+
raise ValueError("'values' supplied as both a positional argument and a keyword")
|
|
14
|
+
elif len(args) > 1:
|
|
15
|
+
raise ValueError("only one 'values' can be supplied as a positional argument")
|
|
16
|
+
elif len(args) > 0:
|
|
17
|
+
kwargs["values"] = args[0]
|
|
18
|
+
|
|
19
|
+
super().__init__(**kwargs)
|
|
20
|
+
|
|
21
|
+
values = Required(Dict(String, Any), help="""
|
|
22
|
+
Python dictionary to be shared among multiple JavaScript callbacks.
|
|
23
|
+
""")
|
cubevis/toolbox/_cube.py
CHANGED
|
@@ -55,7 +55,7 @@ from cubevis.bokeh.format import WcsTicks
|
|
|
55
55
|
from cubevis.bokeh.models import EditSpan
|
|
56
56
|
from ..data import casaimage
|
|
57
57
|
from ..utils import pack_arrays, find_ws_address, set_attributes, resource_manager, polygon_indexes, is_interactive_jupyter, have_firefox
|
|
58
|
-
from ..bokeh.models import EvTextInput
|
|
58
|
+
from ..bokeh.models import EvTextInput, SharedDict
|
|
59
59
|
from ..bokeh.tools import CBResetTool
|
|
60
60
|
from ..bokeh.state import available_palettes, find_palette, default_palette
|
|
61
61
|
from ..bokeh.annotations import EvPolyAnnotation
|
|
@@ -188,6 +188,12 @@ class CubeMask:
|
|
|
188
188
|
self._image_freeze_cb = [ ] # CustomJS to be invoked when the use freezes cursor tracking (by typing 'f')
|
|
189
189
|
self._image_unfreeze_cb = [ ] # CustomJS to be invoked when cursor tracking is unfrozen
|
|
190
190
|
|
|
191
|
+
###
|
|
192
|
+
### This state object is provided as "this.disable_add_sub" when "init_script" is called.
|
|
193
|
+
### By setting "disable_add_sub.values.disabled = True", the user can disable mask updates.
|
|
194
|
+
###
|
|
195
|
+
self._mask_add_sub_disable = SharedDict( { 'disabled': False, 'message': None } )
|
|
196
|
+
|
|
191
197
|
if self._mask_path:
|
|
192
198
|
###########################################################################################################################
|
|
193
199
|
### JavaScript init script to be run early in the startup. Piggybacked off of the ImagePipe initialization ###
|
|
@@ -1456,6 +1462,7 @@ class CubeMask:
|
|
|
1456
1462
|
contour_ds=self._bitmask_contour_ds,
|
|
1457
1463
|
status=self._status_div, statprec=7,
|
|
1458
1464
|
selector=self._bitmask_color_selector,
|
|
1465
|
+
disable_add_sub = self._mask_add_sub_disable,
|
|
1459
1466
|
user_init_script = self.init_script,
|
|
1460
1467
|
freeze_cb = self._image_freeze_cb )
|
|
1461
1468
|
|
|
@@ -1465,7 +1472,8 @@ class CubeMask:
|
|
|
1465
1472
|
''' + self._js['mask-state-init'] +
|
|
1466
1473
|
( self._js['func-curmasks']( ) +
|
|
1467
1474
|
self._js['key-state-funcs']
|
|
1468
|
-
if self._mask_path is None else '' )
|
|
1475
|
+
if self._mask_path is None else '' ) +
|
|
1476
|
+
self._js['update-status'] + self._js['setup-key-mgmt'] +
|
|
1469
1477
|
"""// This function is called to collect the masks and/or stop
|
|
1470
1478
|
// -->> collect_masks( ) is only defined if bitmask cube is NOT used
|
|
1471
1479
|
document._cube_done = ( final_polys=null, cb=null ) => {
|
|
@@ -1511,6 +1519,8 @@ class CubeMask:
|
|
|
1511
1519
|
stats_source.data = data
|
|
1512
1520
|
}
|
|
1513
1521
|
if ( stats_source ) source.update_statistics( stats_source.data ) /*** round pre-filled floats ***/
|
|
1522
|
+
/*** this is the hook that allows the user to disable mask changes ***/
|
|
1523
|
+
this.disable_add_sub = disable_add_sub
|
|
1514
1524
|
if ( user_init_script ) { user_init_script.execute(this) }
|
|
1515
1525
|
""" )
|
|
1516
1526
|
|
|
@@ -1619,12 +1629,6 @@ class CubeMask:
|
|
|
1619
1629
|
{input_screen}.value_ = {input_screen}.value = center.toFixed(5)
|
|
1620
1630
|
}}'''
|
|
1621
1631
|
|
|
1622
|
-
update_status = '''function update_status( str ) {
|
|
1623
|
-
const msg = `<b style='color:red;'>${str}</b>`
|
|
1624
|
-
status.text = msg
|
|
1625
|
-
setTimeout( ( ) => { if ( status.text == msg ) status.text = '' }, 5000 )
|
|
1626
|
-
}'''
|
|
1627
|
-
|
|
1628
1632
|
self._region_controls['tracking']['color-picker'].child.js_on_change( 'color',
|
|
1629
1633
|
CustomJS( args=dict( tracker=self._region_controls['tracking']['pointer'] ),
|
|
1630
1634
|
code='''tracker.line_color = cb_obj.color
|
|
@@ -1685,15 +1689,15 @@ class CubeMask:
|
|
|
1685
1689
|
text=text, source=self._image_source,
|
|
1686
1690
|
status=self._region_controls['coord']['status'],
|
|
1687
1691
|
stokes=(index,s) ),
|
|
1688
|
-
code=parse_ranges +
|
|
1692
|
+
code=parse_ranges + self._js['update-status'] +
|
|
1689
1693
|
#self._js['func-curmasks']('isource') +
|
|
1690
1694
|
'''if ( tracker._current_region ) {
|
|
1691
1695
|
status.text=''
|
|
1692
1696
|
const ranges = casalib.strparse_intranges(cb_obj.value,true)
|
|
1693
1697
|
const minmax = casalib.minmax(ranges.flat(Infinity))
|
|
1694
1698
|
|
|
1695
|
-
if ( minmax[0] < 0 )
|
|
1696
|
-
else if ( minmax[1] >= source.num_chans[1] )
|
|
1699
|
+
if ( minmax[0] < 0 ) update_status_error('negative range')
|
|
1700
|
+
else if ( minmax[1] >= source.num_chans[1] ) update_status_error('exceeds channel range')
|
|
1697
1701
|
else {
|
|
1698
1702
|
const chans_as_set = ranges.reduce(
|
|
1699
1703
|
(set,v) => casalib.forexpr( v[0], v[1], (s,i) => s.add([stokes[0],i]), set),
|
|
@@ -1704,7 +1708,7 @@ class CubeMask:
|
|
|
1704
1708
|
if (chan[0] == stokes[0]) acc.push(chan[1])
|
|
1705
1709
|
return acc }, chans_as_set, [ ] ) )
|
|
1706
1710
|
}
|
|
1707
|
-
} else
|
|
1711
|
+
} else update_status_error('no region selected')''' ) )
|
|
1708
1712
|
|
|
1709
1713
|
###
|
|
1710
1714
|
### set _region_controls_newpoly so it can be passed along and eventuall called by
|
|
@@ -1832,8 +1836,10 @@ class CubeMask:
|
|
|
1832
1836
|
mask_region_button=self._mask_add_sub['mask'],
|
|
1833
1837
|
mask_region_ds=self._bitmask_contour_maskmod_ds,
|
|
1834
1838
|
contour_ds=self._bitmask_contour_ds,
|
|
1839
|
+
disable_add_sub = self._mask_add_sub_disable,
|
|
1835
1840
|
status=self._status_div ),
|
|
1836
|
-
code=self.
|
|
1841
|
+
code=self._js['update-status'] +
|
|
1842
|
+
self._js_mode_code['bitmask-hotkey-setup-add-sub'] +
|
|
1837
1843
|
'''if ( cb_obj._mode == 'cube' ) mask_add_cube( )
|
|
1838
1844
|
else mask_add_chan( )''' )
|
|
1839
1845
|
self._mask_add_sub['sub'].callback = CustomJS( args=dict( annotations=self._annotations,
|
|
@@ -1845,8 +1851,10 @@ class CubeMask:
|
|
|
1845
1851
|
mask_region_button=self._mask_add_sub['mask'],
|
|
1846
1852
|
mask_region_ds=self._bitmask_contour_maskmod_ds,
|
|
1847
1853
|
contour_ds=self._bitmask_contour_ds,
|
|
1854
|
+
disable_add_sub = self._mask_add_sub_disable,
|
|
1848
1855
|
status=self._status_div ),
|
|
1849
|
-
code=self.
|
|
1856
|
+
code=self._js['update-status'] +
|
|
1857
|
+
self._js_mode_code['bitmask-hotkey-setup-add-sub'] +
|
|
1850
1858
|
'''if ( cb_obj._mode == 'cube' ) mask_sub_cube( )
|
|
1851
1859
|
else mask_sub_chan( )''' )
|
|
1852
1860
|
|
|
@@ -1858,8 +1866,10 @@ class CubeMask:
|
|
|
1858
1866
|
mask_region_button=self._mask_add_sub['mask'],
|
|
1859
1867
|
mask_region_icons=self._mask_icons_,
|
|
1860
1868
|
source=self._image_source,
|
|
1869
|
+
disable_add_sub = self._mask_add_sub_disable,
|
|
1861
1870
|
status=self._status_div ),
|
|
1862
|
-
code=self.
|
|
1871
|
+
code=self._js['update-status'] +
|
|
1872
|
+
self._js_mode_code['bitmask-hotkey-setup-add-sub'] +
|
|
1863
1873
|
'''if ( mask_region_button.icon == mask_region_icons['on'] ) source._mask.clear( )
|
|
1864
1874
|
else source.mask.set( region )''' )
|
|
1865
1875
|
|
|
@@ -2258,6 +2268,7 @@ class CubeMask:
|
|
|
2258
2268
|
###########################################################################################################################
|
|
2259
2269
|
self._js_mode_code = {
|
|
2260
2270
|
'bitmask-hotkey-setup-add-sub': '''
|
|
2271
|
+
const default_add_sub_disabled_text = 'mask ops currently disabled'
|
|
2261
2272
|
function mask_mod_result( msg ) {
|
|
2262
2273
|
if ( msg.result == 'success' ) {
|
|
2263
2274
|
if ( 'update' in msg && 'clear_region' in msg.update && msg.update.clear_region ) {
|
|
@@ -2268,6 +2279,12 @@ class CubeMask:
|
|
|
2268
2279
|
}
|
|
2269
2280
|
}
|
|
2270
2281
|
function mask_add_chan( ) {
|
|
2282
|
+
if ( disable_add_sub.values.disabled ) {
|
|
2283
|
+
update_status_error( disable_add_sub.values.message ?
|
|
2284
|
+
disable_add_sub.values.message :
|
|
2285
|
+
default_add_sub_disabled_text )
|
|
2286
|
+
return
|
|
2287
|
+
}
|
|
2271
2288
|
const anno = source._mask.get( )
|
|
2272
2289
|
if ( anno.xs.length > 0 && anno.ys.length > 0 ) {
|
|
2273
2290
|
ctrl.send( ids['mask-mod'],
|
|
@@ -2287,6 +2304,12 @@ class CubeMask:
|
|
|
2287
2304
|
} else if ( status ) status.text = '<p>no region found</p>'
|
|
2288
2305
|
}
|
|
2289
2306
|
function mask_sub_chan( ) {
|
|
2307
|
+
if ( disable_add_sub.values.disabled ) {
|
|
2308
|
+
update_status_error( disable_add_sub.values.message ?
|
|
2309
|
+
disable_add_sub.values.message :
|
|
2310
|
+
default_add_sub_disabled_text )
|
|
2311
|
+
return
|
|
2312
|
+
}
|
|
2290
2313
|
if ( annotations[0].xs.length > 0 && annotations[0].ys.length > 0 ) {
|
|
2291
2314
|
ctrl.send( ids['mask-mod'],
|
|
2292
2315
|
{ scope: 'chan',
|
|
@@ -2305,6 +2328,12 @@ class CubeMask:
|
|
|
2305
2328
|
} else if ( status ) status.text = '<p>no region found</p>'
|
|
2306
2329
|
}
|
|
2307
2330
|
function mask_add_cube( ) {
|
|
2331
|
+
if ( disable_add_sub.values.disabled ) {
|
|
2332
|
+
update_status_error( disable_add_sub.values.message ?
|
|
2333
|
+
disable_add_sub.values.message :
|
|
2334
|
+
default_add_sub_disabled_text )
|
|
2335
|
+
return
|
|
2336
|
+
}
|
|
2308
2337
|
if ( annotations[0].xs.length > 0 && annotations[0].ys.length > 0 ) {
|
|
2309
2338
|
ctrl.send( ids['mask-mod'],
|
|
2310
2339
|
{ scope: 'cube',
|
|
@@ -2323,6 +2352,12 @@ class CubeMask:
|
|
|
2323
2352
|
} else if ( status ) status.text = '<p>no region found</p>'
|
|
2324
2353
|
}
|
|
2325
2354
|
function mask_sub_cube( ) {
|
|
2355
|
+
if ( disable_add_sub.values.disabled ) {
|
|
2356
|
+
update_status_error( disable_add_sub.values.message ?
|
|
2357
|
+
disable_add_sub.values.message :
|
|
2358
|
+
default_add_sub_disabled_text )
|
|
2359
|
+
return
|
|
2360
|
+
}
|
|
2326
2361
|
if ( annotations[0].xs.length > 0 && annotations[0].ys.length > 0 ) {
|
|
2327
2362
|
ctrl.send( ids['mask-mod'],
|
|
2328
2363
|
{ scope: 'cube',
|
|
@@ -2829,6 +2864,13 @@ class CubeMask:
|
|
|
2829
2864
|
|
|
2830
2865
|
self._js = { ### ImagePipe initialization code which manages the shift-key behavior which swiches between
|
|
2831
2866
|
### addition/subtraction to a single channel VS add/sub from all channels of the cube...
|
|
2867
|
+
'update-status': '''function update_status_error( str ) {
|
|
2868
|
+
if ( status ) {
|
|
2869
|
+
const msg = `<b style='color:red;'>${str}</b>`
|
|
2870
|
+
status.text = msg
|
|
2871
|
+
setTimeout( ( ) => { if ( status.text === msg ) status.text = '' }, 5000 )
|
|
2872
|
+
}
|
|
2873
|
+
}''',
|
|
2832
2874
|
'cube-init': '''add._mode = 'chan'
|
|
2833
2875
|
sub._mode = 'chan'
|
|
2834
2876
|
let foo = casalib.is_empty
|
|
@@ -279,6 +279,23 @@ class InteractiveCleanUI:
|
|
|
279
279
|
imdetails['path']['residual'] = join( output_dir, self._clean['gclean_paths'][imid]['residualname'] )
|
|
280
280
|
imdetails['path']['mask'] = join( output_dir, self._clean['gclean_paths'][imid]['maskname'] )
|
|
281
281
|
|
|
282
|
+
###
|
|
283
|
+
### There is one set of tclean controls for all images/outlier/etc. because
|
|
284
|
+
### in the final version gclean will handle the iterations for all fields...
|
|
285
|
+
###
|
|
286
|
+
cwidth = 64
|
|
287
|
+
cheight = 40
|
|
288
|
+
self._control['iteration'] = { }
|
|
289
|
+
self._control['iteration']['continue'] = TipButton( max_width=cwidth, max_height=cheight, name='continue',
|
|
290
|
+
icon=svg_icon(icon_name="iclean-continue", size=18),
|
|
291
|
+
tooltip=Tooltip( content=HTML( '''Stop after <b>one major cycle</b> or when any stopping criteria is met.''' ), position='left') )
|
|
292
|
+
self._control['iteration']['finish'] = TipButton( max_width=cwidth, max_height=cheight, name='finish',
|
|
293
|
+
icon=svg_icon(icon_name="iclean-finish", size=18),
|
|
294
|
+
tooltip=Tooltip( content=HTML( '''<b>Continue</b> until some stopping criteria is met.''' ), position='left') )
|
|
295
|
+
self._control['iteration']['stop'] = TipButton( button_type="danger", max_width=cwidth, max_height=cheight, name='stop',
|
|
296
|
+
icon=svg_icon(icon_name="iclean-stop", size=18),
|
|
297
|
+
tooltip=Tooltip( content=HTML( '''<p>Clicking a <font color="red">red</font> stop button will cause this tab to close and control will return to Python.<p>Clicking an <font color="orange">orange</font> stop button will cause <tt>tclean</tt> to stop after the current major cycle.''' ), position='left' ) )
|
|
298
|
+
|
|
282
299
|
for idx, (imid, imdetails) in enumerate(self._clean_targets.items( )):
|
|
283
300
|
imdetails['gui'] = { }
|
|
284
301
|
|
|
@@ -291,8 +308,13 @@ class InteractiveCleanUI:
|
|
|
291
308
|
###
|
|
292
309
|
imdetails['gui']['cube'] = CubeMask( imdetails['path']['residual'], mask=imdetails['path']['mask'], abort=self._abort_handler,
|
|
293
310
|
init_script=CustomJS( args=dict( initial_convergence_state=self._init_values["convergence_state"],
|
|
311
|
+
clean_ctrl=self._control['iteration'],
|
|
294
312
|
name=imid ),
|
|
295
|
-
code='''document._casa_convergence_data = initial_convergence_state
|
|
313
|
+
code='''document._casa_convergence_data = initial_convergence_state
|
|
314
|
+
clean_ctrl.continue.disable_add_sub = this.disable_add_sub.values
|
|
315
|
+
clean_ctrl.finish.disable_add_sub = this.disable_add_sub.values
|
|
316
|
+
clean_ctrl.stop.disable_add_sub = this.disable_add_sub.values
|
|
317
|
+
this.disable_add_sub.values.message = "cannot modify mask during cleaning"''' )
|
|
296
318
|
if idx == 0 else None )
|
|
297
319
|
|
|
298
320
|
###
|
|
@@ -588,24 +610,6 @@ class InteractiveCleanUI:
|
|
|
588
610
|
#print("%s: %s" % ( btn, self._clean_ids[btn] ) )
|
|
589
611
|
self._pipe['control'].register( self._clean_ids[btn], clean_handler )
|
|
590
612
|
|
|
591
|
-
|
|
592
|
-
###
|
|
593
|
-
### There is one set of tclean controls for all images/outlier/etc. because
|
|
594
|
-
### in the final version gclean will handle the iterations for all fields...
|
|
595
|
-
###
|
|
596
|
-
cwidth = 64
|
|
597
|
-
cheight = 40
|
|
598
|
-
self._control['iteration'] = { }
|
|
599
|
-
self._control['iteration']['continue'] = TipButton( max_width=cwidth, max_height=cheight, name='continue',
|
|
600
|
-
icon=svg_icon(icon_name="iclean-continue", size=18),
|
|
601
|
-
tooltip=Tooltip( content=HTML( '''Stop after <b>one major cycle</b> or when any stopping criteria is met.''' ), position='left') )
|
|
602
|
-
self._control['iteration']['finish'] = TipButton( max_width=cwidth, max_height=cheight, name='finish',
|
|
603
|
-
icon=svg_icon(icon_name="iclean-finish", size=18),
|
|
604
|
-
tooltip=Tooltip( content=HTML( '''<b>Continue</b> until some stopping criteria is met.''' ), position='left') )
|
|
605
|
-
self._control['iteration']['stop'] = TipButton( button_type="danger", max_width=cwidth, max_height=cheight, name='stop',
|
|
606
|
-
icon=svg_icon(icon_name="iclean-stop", size=18),
|
|
607
|
-
tooltip=Tooltip( content=HTML( '''<p>Clicking a <font color="red">red</font> stop button will cause this tab to close and control will return to Python.<p>Clicking an <font color="orange">orange</font> stop button will cause <tt>tclean</tt> to stop after the current major cycle.''' ), position='left' ) )
|
|
608
|
-
|
|
609
613
|
###
|
|
610
614
|
### The single SHARED help button will be supplied by the first CubeMask...
|
|
611
615
|
###
|
|
@@ -785,6 +789,7 @@ class InteractiveCleanUI:
|
|
|
785
789
|
margin=(-1, 0, -10, 0), button_type='light',
|
|
786
790
|
stylesheets=[ InlineStyleSheet( css='''.bk-btn { border: 0px solid #ccc; padding: 0 var(--padding-vertical) var(--padding-horizontal); margin-top: 3px; }''' ) ] )
|
|
787
791
|
|
|
792
|
+
|
|
788
793
|
self._control['iteration']['cb'] = CustomJS( args=dict( images_state={ k: { 'status': v['gui']['stopcode'],
|
|
789
794
|
'automask': v['gui']['params']['automask'],
|
|
790
795
|
'iteration': v['gui']['params']['iteration'],
|
|
@@ -1453,6 +1458,7 @@ class InteractiveCleanUI:
|
|
|
1453
1458
|
)
|
|
1454
1459
|
}
|
|
1455
1460
|
)
|
|
1461
|
+
clean_ctrl.continue.disable_add_sub.disabled = true
|
|
1456
1462
|
clean_ctrl.continue.disabled = true
|
|
1457
1463
|
clean_ctrl.finish.disabled = true
|
|
1458
1464
|
clean_ctrl.stop.disabled = with_stop
|
|
@@ -1477,6 +1483,7 @@ class InteractiveCleanUI:
|
|
|
1477
1483
|
|
|
1478
1484
|
clean_ctrl.stop.disabled = false
|
|
1479
1485
|
if ( ! only_stop ) {
|
|
1486
|
+
clean_ctrl.continue.disable_add_sub.disabled = false
|
|
1480
1487
|
clean_ctrl.continue.disabled = false
|
|
1481
1488
|
clean_ctrl.finish.disabled = false
|
|
1482
1489
|
}
|
|
@@ -278,6 +278,23 @@ class InteractiveCleanUI:
|
|
|
278
278
|
imdetails['path']['residual'] = join( output_dir, self._clean['gclean_paths'][imid]['residualname'] )
|
|
279
279
|
imdetails['path']['mask'] = join( output_dir, self._clean['gclean_paths'][imid]['maskname'] )
|
|
280
280
|
|
|
281
|
+
###
|
|
282
|
+
### There is one set of tclean controls for all images/outlier/etc. because
|
|
283
|
+
### in the final version gclean will handle the iterations for all fields...
|
|
284
|
+
###
|
|
285
|
+
cwidth = 64
|
|
286
|
+
cheight = 40
|
|
287
|
+
self._control['iteration'] = { }
|
|
288
|
+
self._control['iteration']['continue'] = TipButton( max_width=cwidth, max_height=cheight, name='continue',
|
|
289
|
+
icon=svg_icon(icon_name="iclean-continue", size=18),
|
|
290
|
+
tooltip=Tooltip( content=HTML( '''Stop after <b>one major cycle</b> or when any stopping criteria is met.''' ), position='left') )
|
|
291
|
+
self._control['iteration']['finish'] = TipButton( max_width=cwidth, max_height=cheight, name='finish',
|
|
292
|
+
icon=svg_icon(icon_name="iclean-finish", size=18),
|
|
293
|
+
tooltip=Tooltip( content=HTML( '''<b>Continue</b> until some stopping criteria is met.''' ), position='left') )
|
|
294
|
+
self._control['iteration']['stop'] = TipButton( button_type="danger", max_width=cwidth, max_height=cheight, name='stop',
|
|
295
|
+
icon=svg_icon(icon_name="iclean-stop", size=18),
|
|
296
|
+
tooltip=Tooltip( content=HTML( '''<p>Clicking a <font color="red">red</font> stop button will cause this tab to close and control will return to Python.<p>Clicking an <font color="orange">orange</font> stop button will cause <tt>tclean</tt> to stop after the current major cycle.''' ), position='left' ) )
|
|
297
|
+
|
|
281
298
|
for idx, (imid, imdetails) in enumerate(self._clean_targets.items( )):
|
|
282
299
|
imdetails['gui'] = { }
|
|
283
300
|
|
|
@@ -290,8 +307,13 @@ class InteractiveCleanUI:
|
|
|
290
307
|
###
|
|
291
308
|
imdetails['gui']['cube'] = CubeMask( imdetails['path']['residual'], mask=imdetails['path']['mask'], abort=self._abort_handler,
|
|
292
309
|
init_script=CustomJS( args=dict( initial_convergence_state=self._init_values["convergence_state"],
|
|
310
|
+
clean_ctrl=self._control['iteration'],
|
|
293
311
|
name=imid ),
|
|
294
|
-
code='''document._casa_convergence_data = initial_convergence_state
|
|
312
|
+
code='''document._casa_convergence_data = initial_convergence_state
|
|
313
|
+
clean_ctrl.continue.disable_add_sub = this.disable_add_sub.values
|
|
314
|
+
clean_ctrl.finish.disable_add_sub = this.disable_add_sub.values
|
|
315
|
+
clean_ctrl.stop.disable_add_sub = this.disable_add_sub.values
|
|
316
|
+
this.disable_add_sub.values.message = "cannot modify mask during cleaning"''' )
|
|
295
317
|
if idx == 0 else None )
|
|
296
318
|
|
|
297
319
|
###
|
|
@@ -587,24 +609,6 @@ class InteractiveCleanUI:
|
|
|
587
609
|
#print("%s: %s" % ( btn, self._clean_ids[btn] ) )
|
|
588
610
|
self._pipe['control'].register( self._clean_ids[btn], clean_handler )
|
|
589
611
|
|
|
590
|
-
|
|
591
|
-
###
|
|
592
|
-
### There is one set of tclean controls for all images/outlier/etc. because
|
|
593
|
-
### in the final version gclean will handle the iterations for all fields...
|
|
594
|
-
###
|
|
595
|
-
cwidth = 64
|
|
596
|
-
cheight = 40
|
|
597
|
-
self._control['iteration'] = { }
|
|
598
|
-
self._control['iteration']['continue'] = TipButton( max_width=cwidth, max_height=cheight, name='continue',
|
|
599
|
-
icon=svg_icon(icon_name="iclean-continue", size=18),
|
|
600
|
-
tooltip=Tooltip( content=HTML( '''Stop after <b>one major cycle</b> or when any stopping criteria is met.''' ), position='left') )
|
|
601
|
-
self._control['iteration']['finish'] = TipButton( max_width=cwidth, max_height=cheight, name='finish',
|
|
602
|
-
icon=svg_icon(icon_name="iclean-finish", size=18),
|
|
603
|
-
tooltip=Tooltip( content=HTML( '''<b>Continue</b> until some stopping criteria is met.''' ), position='left') )
|
|
604
|
-
self._control['iteration']['stop'] = TipButton( button_type="danger", max_width=cwidth, max_height=cheight, name='stop',
|
|
605
|
-
icon=svg_icon(icon_name="iclean-stop", size=18),
|
|
606
|
-
tooltip=Tooltip( content=HTML( '''<p>Clicking a <font color="red">red</font> stop button will cause this tab to close and control will return to Python.<p>Clicking an <font color="orange">orange</font> stop button will cause <tt>tclean</tt> to stop after the current major cycle.''' ), position='left' ) )
|
|
607
|
-
|
|
608
612
|
###
|
|
609
613
|
### The single SHARED help button will be supplied by the first CubeMask...
|
|
610
614
|
###
|
|
@@ -784,6 +788,7 @@ class InteractiveCleanUI:
|
|
|
784
788
|
margin=(-1, 0, -10, 0), button_type='light',
|
|
785
789
|
stylesheets=[ InlineStyleSheet( css='''.bk-btn { border: 0px solid #ccc; padding: 0 var(--padding-vertical) var(--padding-horizontal); margin-top: 3px; }''' ) ] )
|
|
786
790
|
|
|
791
|
+
|
|
787
792
|
self._control['iteration']['cb'] = CustomJS( args=dict( images_state={ k: { 'status': v['gui']['stopcode'],
|
|
788
793
|
'automask': v['gui']['params']['automask'],
|
|
789
794
|
'iteration': v['gui']['params']['iteration'],
|
|
@@ -1452,6 +1457,7 @@ class InteractiveCleanUI:
|
|
|
1452
1457
|
)
|
|
1453
1458
|
}
|
|
1454
1459
|
)
|
|
1460
|
+
clean_ctrl.continue.disable_add_sub.disabled = true
|
|
1455
1461
|
clean_ctrl.continue.disabled = true
|
|
1456
1462
|
clean_ctrl.finish.disabled = true
|
|
1457
1463
|
clean_ctrl.stop.disabled = with_stop
|
|
@@ -1476,6 +1482,7 @@ class InteractiveCleanUI:
|
|
|
1476
1482
|
|
|
1477
1483
|
clean_ctrl.stop.disabled = false
|
|
1478
1484
|
if ( ! only_stop ) {
|
|
1485
|
+
clean_ctrl.continue.disable_add_sub.disabled = false
|
|
1479
1486
|
clean_ctrl.continue.disabled = false
|
|
1480
1487
|
clean_ctrl.finish.disabled = false
|
|
1481
1488
|
}
|
|
@@ -29,7 +29,7 @@ cubevis/__js__/bokeh-3.6.1.min.js,sha256=SPRs94Q-H-aj8MCsXNu4ok1ouQQLTgXxZnk0-BB
|
|
|
29
29
|
cubevis/__js__/bokeh-tables-3.6.1.min.js,sha256=wINufoBiINmP_PERwhN_1GkidJOsJQ_3vFKUDui7rl8,301216
|
|
30
30
|
cubevis/__js__/bokeh-widgets-3.6.1.min.js,sha256=NE3tFbbxoaMjnJ0XednWJxbAGl-vSR0fxE_kX8keuDQ,311821
|
|
31
31
|
cubevis/__js__/casalib.min.js,sha256=JLZ_3i5JlbNJw2nsx7pewysxzoD3sVpSiWdgJCLbhi0,91107
|
|
32
|
-
cubevis/__js__/cubevisjs.min.js,sha256=
|
|
32
|
+
cubevis/__js__/cubevisjs.min.js,sha256=60KOq5Nt2OW_eGuJ_BcI-GndTEQAL4gZNkbZE9Lve0M,28238
|
|
33
33
|
cubevis/bokeh/__init__.py,sha256=XvuKcU9-bAv1CPb_O81VJTNLlHQC-zBg_Ig9_q4RkM4,1371
|
|
34
34
|
cubevis/bokeh/annotations/__init__.py,sha256=tjDIPKbg-rh7Iu3coFWvmX-j2yNj9KuKmRp1aTo71ww,50
|
|
35
35
|
cubevis/bokeh/annotations/_ev_poly_annotation.py,sha256=0ayX21gxNnm5-4s5VRKiaJ23DCSvbvpsU6oym9q2bk0,173
|
|
@@ -37,9 +37,10 @@ cubevis/bokeh/components/__init__.py,sha256=BQOqgBtlDpu6ENrY42nYeS73n2ZSMogJgM2L
|
|
|
37
37
|
cubevis/bokeh/format/__init__.py,sha256=umNotXSRR23675c44x3h5h2ILbZX8xrDFCztvriYjEw,1424
|
|
38
38
|
cubevis/bokeh/format/_time_ticks.py,sha256=j-DcPh7RfGE8iX2bPjLQDQPIbiAbmjiEWQnKmdMWA3I,1773
|
|
39
39
|
cubevis/bokeh/format/_wcs_ticks.py,sha256=x-ObJiCxBvfqCEk8ySh0NU1ZQUPFUdHRHztjwPSPECI,1827
|
|
40
|
-
cubevis/bokeh/models/__init__.py,sha256=
|
|
40
|
+
cubevis/bokeh/models/__init__.py,sha256=rlZbGqSv0nmg5At9fZDofK3tF8PLM6sp7hpE3Bgi6Wg,167
|
|
41
41
|
cubevis/bokeh/models/_edit_span.py,sha256=7o59ZS0bF_Q_WtstvViWXP-2PiY_F7_zCecTqKcmz0E,196
|
|
42
42
|
cubevis/bokeh/models/_ev_text_input.py,sha256=SGtefXkWK6jHEk4EneZ_hEUGwoIWwVGjwqLjGsAXMpY,158
|
|
43
|
+
cubevis/bokeh/models/_shared_dict.py,sha256=AWjLMOKVAXWHSF4gcK2RbxF442QlzQ7hMR0oaODCqB0,901
|
|
43
44
|
cubevis/bokeh/models/_tip.py,sha256=bnlCOYXsNdgEYKDbsQ6hEVrKOjCXEDxtuwE3sldOeEU,1396
|
|
44
45
|
cubevis/bokeh/models/_tip_button.py,sha256=Dw4aO37o0J3n6EoaJ3ui1y8d04qNn3x2dbKiwiQpArM,1577
|
|
45
46
|
cubevis/bokeh/sources/__init__.py,sha256=4FsudFuVU4o7VG5OG3K1tiMoxIXcJWNz_K9yzMDE8ls,1581
|
|
@@ -95,9 +96,9 @@ cubevis/remote/_local.py,sha256=PcPCFcwttTFZd3O33-5pqDuGKQKK6CA0gz1MTIkTiNI,1032
|
|
|
95
96
|
cubevis/remote/_remote_kernel.py,sha256=wfu7ZzKn-oCxZxzDIkC5puBvGf8WbCLYL3CzM56_FNc,2652
|
|
96
97
|
cubevis/toolbox/__init__.py,sha256=xzqwAG9863d7UKBVBRw7FrRUQbvCdFcLBq4vTpg63DU,1487
|
|
97
98
|
cubevis/toolbox/_app_context.py,sha256=0tRY2SSbSCM6RKLFs_T707_ehWkJXPvnLlE1P9cLXJY,3024
|
|
98
|
-
cubevis/toolbox/_cube.py,sha256=
|
|
99
|
-
cubevis/toolbox/_interactive_clean_ui.mustache,sha256=
|
|
100
|
-
cubevis/toolbox/_interactive_clean_ui.py,sha256=
|
|
99
|
+
cubevis/toolbox/_cube.py,sha256=Jjf40aahUo6ZT9KP8b1RUbBtdd1CSLtE48RQF6q4EkQ,298496
|
|
100
|
+
cubevis/toolbox/_interactive_clean_ui.mustache,sha256=EyihZ-ZNe1hMxdQfkH2lPEo_Km-Kb7ZVcDF3VBzuxNE,111910
|
|
101
|
+
cubevis/toolbox/_interactive_clean_ui.py,sha256=FJdGxbdNHOVlSy0PZULQAUXwdVdAHBEpLGOTe-_0lHs,111821
|
|
101
102
|
cubevis/toolbox/_interactiveclean_wrappers.py,sha256=XqyCGz33CMDhszTxnwZ_3-64GszUK1XYnGKUOxl9sas,5071
|
|
102
103
|
cubevis/toolbox/_region_list.py,sha256=_1RvnXwqMoaAq8CPy-6IyhabLi_snXqO566onehI2y0,8957
|
|
103
104
|
cubevis/utils/_ResourceManager.py,sha256=SaaR29etabRiKxmUK-aWvAm4v_OPFJH8CX7bNFm0Lgo,3410
|
|
@@ -114,8 +115,8 @@ cubevis/utils/_pkgs.py,sha256=mu2CCzndmJZYP81UkFhxveW_CisWLUvagJVolHOEVgM,2294
|
|
|
114
115
|
cubevis/utils/_regions.py,sha256=TdAg4ZUUyhg3nFmX9_KLboqmc0LkyOdEW8M1WDR5Udk,1669
|
|
115
116
|
cubevis/utils/_static.py,sha256=rN-sqXNqQ5R2M3wmPHU1GPP5OTyyWQlUPRuimCrht-g,2347
|
|
116
117
|
cubevis/utils/_tiles.py,sha256=A9W1X61VOhBMTOKXVajzOIoiV2FBdO5N2SFB9SUpDOo,7336
|
|
117
|
-
cubevis/__version__.py,sha256=
|
|
118
|
-
cubevis-0.5.
|
|
119
|
-
cubevis-0.5.
|
|
120
|
-
cubevis-0.5.
|
|
121
|
-
cubevis-0.5.
|
|
118
|
+
cubevis/__version__.py,sha256=kSyf03ZyJGgJcFLGc0Q1b3QZ1UfFrJEhukKkhdMWiAM,22
|
|
119
|
+
cubevis-0.5.25.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
|
|
120
|
+
cubevis-0.5.25.dist-info/METADATA,sha256=_5negZulwCmL_4YPAbnW31Bod3XBEgsg3cv2xxPKmA8,2629
|
|
121
|
+
cubevis-0.5.25.dist-info/licenses/LICENSE,sha256=IMF9i4xIpgCADf0U-V1cuf9HBmqWQd3qtI3FSuyW4zE,26526
|
|
122
|
+
cubevis-0.5.25.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|