Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-07-18 23:17:44

0001 const kBoxHeight = 15;
0002 const kRowHeight = 20;
0003 
0004 const kTypeOffset = 16
0005 const kSourceColor = "#DD00DD";
0006 const typeToColor = [
0007     "#000000", //destructor
0008     0, // unused -15
0009     0, //unused -14
0010     0, //unused -13
0011     "#FF0000", //endjob
0012     "#FF7777", //endstream
0013     "#BBBBBB", //write process block
0014     "#FFFFFF", //end process block
0015     0, //unused -8
0016     "#0000BB", //write end run
0017     "#0000FF", //global end run
0018     "#0000FF", //stream end run
0019     "#00BB00", //write end lumi
0020     "#00FF00", //global end lumi
0021     "#00FF00", //stream end lumi
0022     "#CCCC00", //clear event
0023     "#FFFF00", //event
0024     0, //unused 1
0025     "#007700", //stream begin lumi
0026     "#007700", //global begin lumi
0027     0, //unused 4
0028     "#000077", //stream begin run
0029     "#000077", //global begin run
0030     0, //unused 7
0031     "#BBBBBB", //access input process block
0032     "#FFFFFF", //begin process block
0033     kSourceColor, //open file
0034     "#FF7777", //begin stream
0035     "#FF0000", //begin job
0036     "#00FFFF", //sync
0037     "#007777", //sync enqueue
0038     kSourceColor, // getNextTransition
0039     "#DD00DD", //construction
0040     "#FF0000", //startup
0041 ]
0042 
0043 const overlappingTransitions =[15]
0044 
0045 const typeToName = [
0046     "destructor",
0047     0, //unused -15
0048     0, //unused -14
0049     0, //unused -13
0050     "end job",
0051     "end stream",
0052     "write process block",
0053     "end process block",
0054     0, //unused -8
0055     "write end run",
0056     "global end run", //global end run
0057     "stream end run", //stream end run
0058     "write end lumi", //write end lumi
0059     "global end lumi", //global end lumi
0060     "stream end lumi", //stream end lumi
0061     "clear event",
0062     "event", //event
0063     0, //unused 1
0064     "stream begin lumi", //stream begin lumi
0065     "global begin lumi", //global begin lumi
0066     0, //unused 4
0067     "stream begin run", //stream begin run
0068     "global begin run", //global begin run
0069     0, //unused 7
0070     "access input process block", //access input process block
0071     "begin process block", //begin process block
0072     "open file",
0073     "begin stream", //begin stream
0074     "begin job", //begin job
0075     "EventSetup synch", //sync
0076     "EventSetup sych enqueue", //sync enqueue
0077     "find next transition",
0078     "construction", //construction
0079     "startup", //startup
0080 ]
0081 
0082 const activityToName = [  "prefetch",
0083                           "acquire",
0084                           "process",
0085                           "delayedGet",
0086                         "externalWork"]
0087 
0088 const activityToColor = ["#FF5F1F", "#CC7722", null, "#FF4433", "#8B4513"];
0089 /* const promiseOfSomeData = fetch("modules_data.json").then(r=>r.json()).then(data => {
0090     return data;
0091 }); */
0092 window.onload = async() => {
0093     
0094     const response = await fetch("modules_data.json");
0095     const data = await response.json();
0096     const left = document.querySelector('.name_div');
0097     const div = document.querySelector('.graph_div');
0098     const bottom = document.querySelector('.time_div');
0099     const graph = document.getElementById('graph_view');
0100     const graph_context = graph.getContext('2d');
0101     const name_view = document.getElementById('name_view');
0102     const name_context = name_view.getContext('2d');
0103     const time_view = document.getElementById('time_view');
0104     const time_context = time_view.getContext('2d');
0105     const selected_view = document.getElementById('selected_paragraph');
0106     const zoom_in_button = document.getElementById('zoom_in');
0107     const zoom_out_button = document.getElementById('zoom_out');
0108     let selected_item = null;
0109     selected_view.innerHTML = "Selected: [click on box in graph]";
0110     let mouse_is_down = false;
0111     
0112     let rows = 0;
0113     for( let grouping of data.transitions ) {
0114         for( let slot in grouping.slots ) {
0115             ++rows;
0116         }
0117     }
0118 
0119     const max_graph_height = kRowHeight*rows;
0120     
0121     //same scale as window coordinates
0122     let graph_vertical_offset = 0.;
0123     let minVisibleTime = 0.;
0124     let timeZoomFactor = 1.0;
0125     
0126     function maxTime() {
0127         let maxTime = 0;
0128         for( let grouping of data.transitions) {
0129             for( let slot of grouping.slots) {
0130                 for (let transition of slot) {
0131                     if (maxTime < transition.finish) {
0132                         maxTime = transition.finish;
0133                     }
0134                 }
0135             }
0136         }
0137         
0138         maxTime = Math.ceil(maxTime);
0139         
0140         const digits = maxTime.toString().length;
0141         const digitsToZeroOut = digits -2;
0142         if (digitsToZeroOut > 0) {
0143             for(let i = 0; i < digitsToZeroOut; ++i) {
0144                 maxTime /= 10;
0145             }
0146             maxTime *=10;
0147             maxTime +=9;
0148             for( let i = 1; i < digitsToZeroOut; ++i) {
0149                 maxTime *=10;
0150             }
0151             maxTime = Math.ceil(maxTime);
0152         }
0153         return maxTime;
0154     }
0155     
0156     const kEndTime = maxTime();
0157     
0158     function drawNames() {
0159         name_context.setTransform(1,0,0,1,0,0);
0160         name_context.fillStyle = "#AACD6E"
0161         name_context.fillRect(0,0,name_view.width,name_view.height);
0162         name_context.scale(1,1)
0163         name_context.fillStyle = "black"
0164         name_context.strokeStyle = "black"
0165         name_context.font = '9pt monospace';            //context.font = "50px";
0166         
0167         let offset = kRowHeight/2 + graph_vertical_offset;
0168         for( let grouping of data.transitions ) {
0169             name_context.fillText(grouping.name, 0, offset);
0170             offset += grouping.slots.length*kRowHeight;
0171         }
0172     }
0173     
0174     function timeStepPower() {
0175         let timeDecade = 0;
0176         let nSteps = time_view.width/kInitPixelsPerSecond/timeZoomFactor;
0177         while (nSteps < 3) {
0178             --timeDecade;
0179             nSteps *=10.;
0180         }
0181         while (nSteps > 20) {
0182             ++timeDecade;
0183             nSteps /=10.;
0184         }
0185         return timeDecade;
0186     }
0187     
0188     function drawTime() {
0189         time_context.save()
0190         time_context.setTransform(1,0,0,1,0,0);
0191         time_context.fillStyle = "#CD6E6E";
0192         time_context.fillRect(0,0,time_view.width,time_view.height);
0193         time_context.restore();
0194         time_context.scale(1,1);
0195         const end = kEndTime;
0196         const timePower = timeStepPower();
0197         const stepSize = Math.pow(10., timePower);
0198         let fixedValue = timePower;
0199         if (fixedValue < 0 ) {
0200             fixedValue *= -1;
0201         }
0202         
0203         const tickDistance = stepSize/10.*kInitPixelsPerSecond*timeZoomFactor;
0204         const bigTickDistance = stepSize*kInitPixelsPerSecond*timeZoomFactor;
0205         for( let bigTick = 0; bigTick < end; bigTick +=stepSize) {
0206             let t = (bigTick-minVisibleTime)*kInitPixelsPerSecond*timeZoomFactor;
0207             if ((t + bigTickDistance) < 0 ) continue;
0208             if (t > time_view.width) break;
0209             graph_context.strokeStyle = "black";
0210             time_context.beginPath()
0211             time_context.moveTo(t,0)
0212             time_context.lineTo(t, time_view.height/2);
0213             time_context.stroke()
0214             const sec = bigTick.toFixed(fixedValue);
0215             
0216             time_context.fillText(sec.toString()+"s", t, time_view.height*0.75)
0217             for(let tick = 1; tick < 10; ++tick) {
0218                 let pos = t+tick*tickDistance;
0219                 time_context.beginPath();
0220                 time_context.moveTo(pos,0);
0221                 time_context.lineTo(pos, time_view.height/4);
0222                 time_context.stroke();
0223             }
0224         }
0225     }
0226     
0227     function colorToUse(transition) {
0228         if (!transition.isSrc) {
0229             if ( ('act' in transition) && transition.act != 2) {
0230                 return activityToColor[transition.act];
0231             } else {
0232                 return typeToColor[transition.type+kTypeOffset];
0233             }
0234         }
0235         return kSourceColor;
0236     }
0237     
0238     function drawGraph() {
0239         const scale = kInitPixelsPerSecond * timeZoomFactor;
0240         const maxVisibleTime = time_view.width/scale+minVisibleTime;
0241         //console.log(minVisibleTime);
0242         graph_context.save();
0243         graph_context.setTransform(1,0,0,1,0,0);
0244         graph_context.fillStyle = "#D5D6C6"
0245         graph_context.fillRect(0,0,graph.width,graph.height);
0246         graph_context.restore();
0247         
0248         graph_context.strokeStyle = "black";
0249         graph_context.scale(1,1);
0250         
0251         let offset = graph_vertical_offset;
0252         for( let grouping of data.transitions) {
0253             if (offset > graph.height) break;
0254             for( let slot of grouping.slots ) {
0255                 if (offset > graph.height) break;
0256                 if (offset+kBoxHeight >= 0) {
0257                     for( let transition of slot) {
0258                         if (maxVisibleTime < transition.start) {
0259                             break;
0260                         }
0261                         if (minVisibleTime > transition.finish) {
0262                             continue;
0263                         }
0264                         if(transition == selected_item) {
0265                             graph_context.fillStyle = "white";
0266                         } else {
0267                             graph_context.fillStyle = colorToUse(transition);
0268                         }
0269                         graph_context.fillRect(scale*(transition.start-minVisibleTime), offset, scale*(transition.finish-transition.start), kBoxHeight);
0270                     }
0271                 }
0272                 offset += kRowHeight;
0273             }
0274         }
0275         drawNames();
0276         drawTime();
0277         
0278     }
0279     graph.width = div.clientWidth;
0280     const kInitPixelsPerSecond = graph.width/kEndTime;
0281     const max_graph_width = graph.width;
0282     
0283     graph.height = div.clientHeight
0284     name_view.width = left.clientWidth
0285     name_view.height = left.clientHeight
0286     time_view.width = bottom.clientWidth
0287     time_view.height = bottom.clientHeight
0288     drawGraph()
0289     
0290     let graph_isDragging = false;
0291     let graph_mouseDown = false;
0292     let graph_mouseDownPosition = {x:0, y:0};
0293     let graph_dragStartPosition = { x: 0, y: 0 };
0294     
0295     let time_isDragging = false;
0296     let time_dragStartPosition = 0;
0297     
0298     function graph_translate(xDiff, yDiff) {
0299         let original = minVisibleTime;
0300         minVisibleTime -= xDiff/kInitPixelsPerSecond/timeZoomFactor;
0301         //console.log(xDiff, original, minVisibleTime);
0302         const timeEnd = (max_graph_width)/kInitPixelsPerSecond/timeZoomFactor+minVisibleTime;
0303         if (timeEnd > kEndTime) {
0304             minVisibleTime = kEndTime - max_graph_width/kInitPixelsPerSecond/timeZoomFactor;
0305         }
0306         if (minVisibleTime < 0) {
0307             minVisibleTime = 0;
0308         }
0309         original = graph_vertical_offset;
0310         graph_vertical_offset += yDiff;
0311         if (graph_vertical_offset < -max_graph_height) {
0312             graph_vertical_offset = -max_graph_height;
0313         }
0314         if (graph_vertical_offset > 0) {
0315             graph_vertical_offset = 0;
0316         }
0317     }
0318     
0319     function getTransformedPoint(x, y) {
0320         const originalPoint = new DOMPoint(x, y);
0321         return graph_context.getTransform().invertSelf().transformPoint(originalPoint);
0322     }
0323     
0324     function graph_onMouseDown(event) {
0325         graph_mouseDown = true;
0326         graph_mouseDownPosition = {x:event.offsetX, y:event.offsetY};
0327         graph_dragStartPosition = getTransformedPoint(event.offsetX, event.offsetY);
0328     }
0329     
0330     function graph_onMouseMove(event) {
0331         let currentTransformedCursor = getTransformedPoint(event.offsetX, event.offsetY);
0332         
0333         if (graph_mouseDown) {
0334             if (Math.abs(graph_mouseDownPosition.x-event.offsetX)> 5 ||
0335                 Math.abs(graph_mouseDownPosition.y-event.offsetY)> 5) {
0336                 graph_isDragging = true;
0337             }
0338         }
0339         if (graph_isDragging) {
0340             graph_translate(currentTransformedCursor.x - graph_dragStartPosition.x, currentTransformedCursor.y - graph_dragStartPosition.y);
0341             graph_dragStartPosition.x = currentTransformedCursor.x;
0342             graph_dragStartPosition.y = currentTransformedCursor.y;
0343             drawGraph();
0344         }
0345     }
0346     
0347     function moduleName(id) {
0348         if (id ==0) {
0349             return "source";
0350         }
0351         return "";
0352     }
0353     
0354     function doUnselection() {
0355         selected_view.innerHTML = "Selected: [click on box in graph]";
0356         selected_item = null;
0357     }
0358     
0359     function moduleIdToName(id) {
0360         if (id < 0) {
0361             return data.esModules[-1*id];
0362         }
0363         return data.modules[id];
0364     }
0365     
0366     function duration(t) {
0367         if (t < 0.001) {
0368             return (t*1000000).toFixed()+"us";
0369         }
0370         if (t < 0.1) {
0371             return (t*1000).toFixed(3)+"ms";
0372         }
0373         return t.toFixed(6)+"s";
0374     }
0375     
0376     function updateSelectedView(item) {
0377         if ('isSrc' in item) {
0378             if (item.isSrc) {
0379                 if(item.mod) {
0380                     selected_view.innerHTML ="Selected: source reading data product: for module "+item.mod+" "+moduleIdToName(item.mod)+ " while "+activityToName[item.act]+" "+typeToName[item.type+kTypeOffset] +" start: "+item.start.toFixed(6)+"s finish: "+item.finish.toFixed(6)+"s duration: "+duration(item.finish-item.start);
0381 
0382                 } else {
0383                     selected_view.innerHTML = "Selected: source "+typeToName[item.type+kTypeOffset]+" id: "+item.id+" run: "+item.sync[0]
0384                     +" lumi: "+item.sync[1]+ " event: "+item.sync[2]+" start: "+item.start.toFixed(6)+"s finish:"+item.finish.toFixed(6)+"s duration: "+duration(item.finish-item.start);
0385                 }
0386             } else {
0387                 selected_view.innerHTML = "Selected: "+typeToName[item.type+kTypeOffset]+" id: "+item.id+" run: "+item.sync[0]
0388                 +" lumi: "+item.sync[1]+ " event: "+item.sync[2]+" start: "+item.start.toFixed(6)+"s finish:"+item.finish.toFixed(6)+"s duration: "+duration(item.finish-item.start);
0389             }
0390         } else {
0391             let transform = '';
0392             if (item.call != 0 && item.mod > 0) {
0393                 transform = ' transform '
0394             }
0395             selected_view.innerHTML ="Selected: module : "+item.mod+" "+moduleIdToName(item.mod)+ " while "+activityToName[item.act]+transform+" "+typeToName[item.type+kTypeOffset] +" start: "+item.start.toFixed(6)+"s finish: "+item.finish.toFixed(6)+"s duration: "+duration(item.finish-item.start);
0396         }
0397     }
0398     function doSelection(items, x) {
0399         let time = x/kInitPixelsPerSecond/timeZoomFactor+minVisibleTime;
0400         //console.log(time);
0401         if( time < 0 || time > kEndTime) {
0402             doUnselection();
0403             drawGraph();
0404             return;
0405         }
0406         selected_item = null;
0407         for( let item of items) {
0408             if (time < item.start) {
0409                 break;
0410             }
0411             if (time > item.start && time < item.finish) {
0412                 selected_item = item;
0413                 if ( overlappingTransitions.includes(selected_item.type)) {
0414                     continue;
0415                 } else {
0416                     break;
0417                 }
0418             }
0419         }
0420         if (selected_item) {
0421             updateSelectedView(selected_item);
0422         } else {
0423             doUnselection();
0424         }
0425         drawGraph();
0426     }
0427     
0428     function graph_onMouseUp(event) {
0429         if (graph_mouseDown && ! graph_isDragging) {
0430             //trying to select
0431             const selectionPoint = getTransformedPoint(event.offsetX, event.offsetY);
0432             const vertIndex = Math.floor((selectionPoint.y-graph_vertical_offset)/kRowHeight);
0433             
0434             let presentIndex = 0;
0435             let container = null;
0436         outer: for(let grouping of data.transitions) {
0437             for(let slot of grouping.slots) {
0438                 if (presentIndex == vertIndex) {
0439                     container = slot;
0440                     break outer;
0441                 }
0442                 ++presentIndex;
0443             }
0444         }
0445             if (!container) {
0446                 doUnselection();
0447                 drawGraph();
0448             } else {
0449                 doSelection(container, selectionPoint.x);
0450             }
0451         }
0452         graph_isDragging = false;
0453         graph_mouseDown = false;
0454     }
0455     
0456     function graph_onMouseOut() {
0457         graph_isDragging = false
0458         graph_mouseDown = false;
0459     }
0460     function graph_onWheel(event) {
0461         if (event.ctrlKey) {
0462             let currentTransformedCursor = getTransformedPoint(event.offsetX, event.offsetY);
0463             const zoom = event.deltaY < 0 ? 1.02 : 0.98;
0464             const originalScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0465             timeZoomFactor *= zoom;
0466             const newScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0467             //Keep the cursor at the same time and change zoom around that point
0468             minVisibleTime = minVisibleTime + currentTransformedCursor.x*(originalScale-newScale);
0469         } else {
0470             graph_translate(-1*event.deltaX, -1*event.deltaY);
0471         }
0472         drawGraph();
0473         event.preventDefault()
0474     }
0475 
0476     window.addEventListener('resize',function(){
0477                 graph_context.canvas.width = graph.clientWidth;
0478                 graph_context.canvas.height = graph.clientHeight;
0479                 name_context.canvas.width = name_view.clientWidth;
0480                 name_context.canvas.height = name_view.clientHeight;
0481                 time_context.canvas.width = time_view.clientWidth;
0482                 time_context.canvas.height = time_view.clientHeight;
0483                 drawGraph();
0484         }, false);
0485     graph.addEventListener('mousedown', graph_onMouseDown)
0486     graph.addEventListener('mousemove', graph_onMouseMove)
0487     graph.addEventListener('mouseup', graph_onMouseUp)
0488     graph.addEventListener('mouseout', graph_onMouseOut)
0489     graph.addEventListener('wheel', graph_onWheel);
0490     
0491     function time_onMouseDown(event) {
0492         time_isDragging = true;
0493         time_dragStartPosition = getTransformedPoint(event.offsetX, 0).x;
0494     }
0495     
0496     function time_onMouseMove(event) {
0497         let currentTransformedCursor = getTransformedPoint(event.offsetX, 0);
0498         
0499         if (time_isDragging) {
0500             graph_translate(currentTransformedCursor.x - time_dragStartPosition, 0);
0501             time_dragStartPosition = currentTransformedCursor.x;
0502             drawGraph();
0503         }
0504     }
0505     
0506     function time_onMouseUp() {
0507         time_isDragging = false;
0508     }
0509     
0510     function time_onMouseOut() {
0511         time_isDragging = false
0512     }
0513     
0514     function time_onWheel(event) {
0515         if (event.ctrlKey) {
0516             let currentTransformedCursor = getTransformedPoint(event.offsetX, event.offsetY);
0517             const zoom = event.deltaY < 0 ? 1.02 : 0.98;
0518             const originalScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0519             timeZoomFactor *= zoom;
0520             const newScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0521             //Keep the cursor at the same time and change zoom around that point
0522             minVisibleTime = minVisibleTime + currentTransformedCursor.x*(originalScale-newScale);
0523         } else {
0524             graph_translate(-1*event.deltaX, 0);
0525         }
0526         //console.log(minVisibleTime);
0527         drawGraph();
0528         event.preventDefault();
0529         
0530     }
0531     
0532     time_view.addEventListener('mousedown', time_onMouseDown)
0533     time_view.addEventListener('mousemove', time_onMouseMove)
0534     time_view.addEventListener('mouseup', time_onMouseUp)
0535     time_view.addEventListener('mouseout', time_onMouseOut)
0536     time_view.addEventListener('wheel', time_onWheel);
0537     
0538     function zoom_in_click(event) {
0539         const zoom = 1.1;
0540         const originalScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0541         timeZoomFactor *= zoom;
0542         const newScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0543         //Keep the center of the view at the same time and change zoom around that point
0544         minVisibleTime = minVisibleTime + max_graph_width/2*(originalScale-newScale);
0545         drawGraph();
0546     }
0547     function zoom_out_click(event) {
0548         const zoom = 0.909;
0549         const originalScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0550         timeZoomFactor *= zoom;
0551         const newScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0552         //Keep the center of the view at the same time and change zoom around that point
0553         minVisibleTime = minVisibleTime + max_graph_width/2*(originalScale-newScale);
0554         drawGraph();
0555     }
0556     zoom_in_button.addEventListener("click", zoom_in_click);
0557     zoom_out_button.addEventListener("click", zoom_out_click);
0558 
0559     function name_onWheel(event) {
0560         let offset = 0;
0561         graph_translate(0, -1*event.deltaY);
0562         drawGraph();
0563         event.preventDefault()
0564     }
0565     name_view.addEventListener('wheel', name_onWheel);
0566 }