Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-25 02:29:37

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     // Select the dropdown element
0094     const jsonDropdown = document.getElementById('jsonDropdown');
0095     // Function to fetch data based on selected file
0096     async function fetchData(file) {
0097         showLoadingSpinner(); // Show loading spinner
0098         try {
0099             const response = await fetch(file); // Fetch the selected JSON file
0100             const data = await response.json(); // Parse JSON data from the response
0101             processData(data); // Call the function to process the fetched data
0102         } catch (error) {
0103             console.error('Error fetching data:', error);
0104         }finally {
0105             hideLoadingSpinner(); // Hide loading spinner
0106         }
0107     }
0108     
0109     // Function to process the fetched data
0110     function processData(data) {
0111         const left = document.querySelector('.name_div');
0112         const div = document.querySelector('.graph_div');
0113         const bottom = document.querySelector('.time_div');
0114         const graph = document.getElementById('graph_view');
0115         const graph_context = graph.getContext('2d');
0116         const name_view = document.getElementById('name_view');
0117         const name_context = name_view.getContext('2d');
0118         const time_view = document.getElementById('time_view');
0119         const time_context = time_view.getContext('2d');
0120         const selected_view = document.getElementById('selected_paragraph');
0121         const zoom_in_button = document.getElementById('zoom_in');
0122         const zoom_out_button = document.getElementById('zoom_out');
0123         let selected_item = null;
0124         selected_view.innerHTML = "Selected: [click on box in graph]";
0125         let mouse_is_down = false;
0126         
0127         let rows = 0;
0128         for( let grouping of data.transitions ) {
0129             for( let slot in grouping.slots ) {
0130                 ++rows;
0131             }
0132         }
0133 
0134         const max_graph_height = kRowHeight*rows;
0135         
0136         //same scale as window coordinates
0137         let graph_vertical_offset = 0.;
0138         let minVisibleTime = 0.;
0139         let timeZoomFactor = 1.0;
0140         
0141         function maxTime() {
0142             let maxTime = 0;
0143             for( let grouping of data.transitions) {
0144                 for( let slot of grouping.slots) {
0145                     for (let transition of slot) {
0146                         if (maxTime < transition.finish) {
0147                             maxTime = transition.finish;
0148                         }
0149                     }
0150                 }
0151             }
0152             
0153             maxTime = Math.ceil(maxTime);
0154             
0155             const digits = maxTime.toString().length;
0156             const digitsToZeroOut = digits -2;
0157             if (digitsToZeroOut > 0) {
0158                 for(let i = 0; i < digitsToZeroOut; ++i) {
0159                     maxTime /= 10;
0160                 }
0161                 maxTime *=10;
0162                 maxTime +=9;
0163                 for( let i = 1; i < digitsToZeroOut; ++i) {
0164                     maxTime *=10;
0165                 }
0166                 maxTime = Math.ceil(maxTime);
0167             }
0168             return maxTime;
0169         }
0170         
0171         const kEndTime = maxTime();
0172         
0173         function drawNames() {
0174             name_context.setTransform(1,0,0,1,0,0);
0175             name_context.fillStyle = "#AACD6E"
0176             name_context.fillRect(0,0,name_view.width,name_view.height);
0177             name_context.scale(1,1)
0178             name_context.fillStyle = "black"
0179             name_context.strokeStyle = "black"
0180             name_context.font = '9pt monospace';                //context.font = "50px";
0181             
0182             let offset = kRowHeight/2 + graph_vertical_offset;
0183             for( let grouping of data.transitions ) {
0184                 name_context.fillText(grouping.name, 0, offset);
0185                 offset += grouping.slots.length*kRowHeight;
0186             }
0187         }
0188         
0189         function timeStepPower() {
0190             let timeDecade = 0;
0191             let nSteps = time_view.width/kInitPixelsPerSecond/timeZoomFactor;
0192             while (nSteps < 3) {
0193                 --timeDecade;
0194                 nSteps *=10.;
0195             }
0196             while (nSteps > 20) {
0197                 ++timeDecade;
0198                 nSteps /=10.;
0199             }
0200             return timeDecade;
0201         }
0202         
0203         function drawTime() {
0204             time_context.save()
0205             time_context.setTransform(1,0,0,1,0,0);
0206             time_context.fillStyle = "#CD6E6E";
0207             time_context.fillRect(0,0,time_view.width,time_view.height);
0208             time_context.restore();
0209             time_context.scale(1,1);
0210             const end = kEndTime;
0211             const timePower = timeStepPower();
0212             const stepSize = Math.pow(10., timePower);
0213             let fixedValue = timePower;
0214             if (fixedValue < 0 ) {
0215                 fixedValue *= -1;
0216             }
0217             
0218             const tickDistance = stepSize/10.*kInitPixelsPerSecond*timeZoomFactor;
0219             const bigTickDistance = stepSize*kInitPixelsPerSecond*timeZoomFactor;
0220             for( let bigTick = 0; bigTick < end; bigTick +=stepSize) {
0221                 let t = (bigTick-minVisibleTime)*kInitPixelsPerSecond*timeZoomFactor;
0222                 if ((t + bigTickDistance) < 0 ) continue;
0223                 if (t > time_view.width) break;
0224                 graph_context.strokeStyle = "black";
0225                 time_context.beginPath()
0226                 time_context.moveTo(t,0)
0227                 time_context.lineTo(t, time_view.height/2);
0228                 time_context.stroke()
0229                 const sec = bigTick.toFixed(fixedValue);
0230                 
0231                 time_context.fillText(sec.toString()+"s", t, time_view.height*0.75)
0232                 for(let tick = 1; tick < 10; ++tick) {
0233                     let pos = t+tick*tickDistance;
0234                     time_context.beginPath();
0235                     time_context.moveTo(pos,0);
0236                     time_context.lineTo(pos, time_view.height/4);
0237                     time_context.stroke();
0238                 }
0239             }
0240         }
0241         
0242         function colorToUse(transition) {
0243             if (!transition.isSrc) {
0244                 if ( ('act' in transition) && transition.act != 2) {
0245                     return activityToColor[transition.act];
0246                 } else {
0247                     return typeToColor[transition.type+kTypeOffset];
0248                 }
0249             }
0250             return kSourceColor;
0251         }
0252         
0253         function drawGraph() {
0254             const scale = kInitPixelsPerSecond * timeZoomFactor;
0255             const maxVisibleTime = time_view.width/scale+minVisibleTime;
0256             //console.log(minVisibleTime);
0257             graph_context.save();
0258             graph_context.setTransform(1,0,0,1,0,0);
0259             graph_context.fillStyle = "#D5D6C6"
0260             graph_context.fillRect(0,0,graph.width,graph.height);
0261             graph_context.restore();
0262             
0263             graph_context.strokeStyle = "black";
0264             graph_context.scale(1,1);
0265             
0266             let offset = graph_vertical_offset;
0267             for( let grouping of data.transitions) {
0268                 if (offset > graph.height) break;
0269                 for( let slot of grouping.slots ) {
0270                     if (offset > graph.height) break;
0271                     if (offset+kBoxHeight >= 0) {
0272                         for( let transition of slot) {
0273                             if (maxVisibleTime < transition.start) {
0274                                 break;
0275                             }
0276                             if (minVisibleTime > transition.finish) {
0277                                 continue;
0278                             }
0279                             if(transition == selected_item) {
0280                                 graph_context.fillStyle = "white";
0281                             } else {
0282                                 graph_context.fillStyle = colorToUse(transition);
0283                             }
0284                             graph_context.fillRect(scale*(transition.start-minVisibleTime), offset, scale*(transition.finish-transition.start), kBoxHeight);
0285                         }
0286                     }
0287                     offset += kRowHeight;
0288                 }
0289             }
0290             drawNames();
0291             drawTime();
0292             
0293         }
0294         graph.width = div.clientWidth;
0295         const kInitPixelsPerSecond = graph.width/kEndTime;
0296         const max_graph_width = graph.width;
0297         
0298         graph.height = div.clientHeight
0299         name_view.width = left.clientWidth
0300         name_view.height = left.clientHeight
0301         time_view.width = bottom.clientWidth
0302         time_view.height = bottom.clientHeight
0303         drawGraph()
0304         
0305         let graph_isDragging = false;
0306         let graph_mouseDown = false;
0307         let graph_mouseDownPosition = {x:0, y:0};
0308         let graph_dragStartPosition = { x: 0, y: 0 };
0309         
0310         let time_isDragging = false;
0311         let time_dragStartPosition = 0;
0312         
0313         function graph_translate(xDiff, yDiff) {
0314             let original = minVisibleTime;
0315             minVisibleTime -= xDiff/kInitPixelsPerSecond/timeZoomFactor;
0316             //console.log(xDiff, original, minVisibleTime);
0317             const timeEnd = (max_graph_width)/kInitPixelsPerSecond/timeZoomFactor+minVisibleTime;
0318             if (timeEnd > kEndTime) {
0319                 minVisibleTime = kEndTime - max_graph_width/kInitPixelsPerSecond/timeZoomFactor;
0320             }
0321             if (minVisibleTime < 0) {
0322                 minVisibleTime = 0;
0323             }
0324             original = graph_vertical_offset;
0325             graph_vertical_offset += yDiff;
0326             if (graph_vertical_offset < -max_graph_height) {
0327                 graph_vertical_offset = -max_graph_height;
0328             }
0329             if (graph_vertical_offset > 0) {
0330                 graph_vertical_offset = 0;
0331             }
0332         }
0333         
0334         function getTransformedPoint(x, y) {
0335             const originalPoint = new DOMPoint(x, y);
0336             return graph_context.getTransform().invertSelf().transformPoint(originalPoint);
0337         }
0338         
0339         function graph_onMouseDown(event) {
0340             graph_mouseDown = true;
0341             graph_mouseDownPosition = {x:event.offsetX, y:event.offsetY};
0342             graph_dragStartPosition = getTransformedPoint(event.offsetX, event.offsetY);
0343         }
0344         
0345         function graph_onMouseMove(event) {
0346             let currentTransformedCursor = getTransformedPoint(event.offsetX, event.offsetY);
0347             
0348             if (graph_mouseDown) {
0349                 if (Math.abs(graph_mouseDownPosition.x-event.offsetX)> 5 ||
0350                     Math.abs(graph_mouseDownPosition.y-event.offsetY)> 5) {
0351                     graph_isDragging = true;
0352                 }
0353             }
0354             if (graph_isDragging) {
0355                 graph_translate(currentTransformedCursor.x - graph_dragStartPosition.x, currentTransformedCursor.y - graph_dragStartPosition.y);
0356                 graph_dragStartPosition.x = currentTransformedCursor.x;
0357                 graph_dragStartPosition.y = currentTransformedCursor.y;
0358                 drawGraph();
0359             }
0360         }
0361         
0362         function moduleName(id) {
0363             if (id ==0) {
0364                 return "source";
0365             }
0366             return "";
0367         }
0368         
0369         function doUnselection() {
0370             selected_view.innerHTML = "Selected: [click on box in graph]";
0371             selected_item = null;
0372         }
0373         
0374         function moduleIdToName(id) {
0375             if (id < 0) {
0376                 return data.esModules[-1*id];
0377             }
0378             return data.modules[id];
0379         }
0380         
0381         function duration(t) {
0382             if (t < 0.001) {
0383                 return (t*1000000).toFixed()+"us";
0384             }
0385             if (t < 0.1) {
0386                 return (t*1000).toFixed(3)+"ms";
0387             }
0388             return t.toFixed(6)+"s";
0389         }
0390         
0391         function updateSelectedView(item) {
0392             if ('isSrc' in item) {
0393                 if (item.isSrc) {
0394                     if(item.mod) {
0395                         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);
0396 
0397                     } else {
0398                         selected_view.innerHTML = "Selected: source "+typeToName[item.type+kTypeOffset]+" id: "+item.id+" run: "+item.sync[0]
0399                         +" 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);
0400                     }
0401                 } else {
0402                     selected_view.innerHTML = "Selected: "+typeToName[item.type+kTypeOffset]+" id: "+item.id+" run: "+item.sync[0]
0403                     +" 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);
0404                 }
0405             } else {
0406                 let transform = '';
0407                 if (item.call != 0 && item.mod > 0) {
0408                     transform = ' transform '
0409                 }
0410                 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);
0411             }
0412         }
0413         function doSelection(items, x) {
0414             let time = x/kInitPixelsPerSecond/timeZoomFactor+minVisibleTime;
0415             //console.log(time);
0416             if( time < 0 || time > kEndTime) {
0417                 doUnselection();
0418                 drawGraph();
0419                 return;
0420             }
0421             selected_item = null;
0422             for( let item of items) {
0423                 if (time < item.start) {
0424                     break;
0425                 }
0426                 if (time > item.start && time < item.finish) {
0427                     selected_item = item;
0428                     if ( overlappingTransitions.includes(selected_item.type)) {
0429                         continue;
0430                     } else {
0431                         break;
0432                     }
0433                 }
0434             }
0435             if (selected_item) {
0436                 updateSelectedView(selected_item);
0437             } else {
0438                 doUnselection();
0439             }
0440             drawGraph();
0441         }
0442         
0443         function graph_onMouseUp(event) {
0444             if (graph_mouseDown && ! graph_isDragging) {
0445                 //trying to select
0446                 const selectionPoint = getTransformedPoint(event.offsetX, event.offsetY);
0447                 const vertIndex = Math.floor((selectionPoint.y-graph_vertical_offset)/kRowHeight);
0448                 
0449                 let presentIndex = 0;
0450                 let container = null;
0451             outer: for(let grouping of data.transitions) {
0452                 for(let slot of grouping.slots) {
0453                     if (presentIndex == vertIndex) {
0454                         container = slot;
0455                         break outer;
0456                     }
0457                     ++presentIndex;
0458                 }
0459             }
0460                 if (!container) {
0461                     doUnselection();
0462                     drawGraph();
0463                 } else {
0464                     doSelection(container, selectionPoint.x);
0465                 }
0466             }
0467             graph_isDragging = false;
0468             graph_mouseDown = false;
0469         }
0470         
0471         function graph_onMouseOut() {
0472             graph_isDragging = false
0473             graph_mouseDown = false;
0474         }
0475         function graph_onWheel(event) {
0476             if (event.ctrlKey) {
0477                 let currentTransformedCursor = getTransformedPoint(event.offsetX, event.offsetY);
0478                 const zoom = event.deltaY < 0 ? 1.02 : 0.98;
0479                 const originalScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0480                 timeZoomFactor *= zoom;
0481                 const newScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0482                 //Keep the cursor at the same time and change zoom around that point
0483                 minVisibleTime = minVisibleTime + currentTransformedCursor.x*(originalScale-newScale);
0484             } else {
0485                 graph_translate(-1*event.deltaX, -1*event.deltaY);
0486             }
0487             drawGraph();
0488             event.preventDefault()
0489         }
0490 
0491         window.addEventListener('resize',function(){
0492             graph_context.canvas.width = graph.clientWidth;
0493             graph_context.canvas.height = graph.clientHeight;
0494             name_context.canvas.width = name_view.clientWidth;
0495             name_context.canvas.height = name_view.clientHeight;
0496             time_context.canvas.width = time_view.clientWidth;
0497             time_context.canvas.height = time_view.clientHeight;
0498             drawGraph();
0499         }, false);
0500         graph.addEventListener('mousedown', graph_onMouseDown)
0501         graph.addEventListener('mousemove', graph_onMouseMove)
0502         graph.addEventListener('mouseup', graph_onMouseUp)
0503         graph.addEventListener('mouseout', graph_onMouseOut)
0504         graph.addEventListener('wheel', graph_onWheel);
0505         
0506         function time_onMouseDown(event) {
0507             time_isDragging = true;
0508             time_dragStartPosition = getTransformedPoint(event.offsetX, 0).x;
0509         }
0510         
0511         function time_onMouseMove(event) {
0512             let currentTransformedCursor = getTransformedPoint(event.offsetX, 0);
0513             
0514             if (time_isDragging) {
0515                 graph_translate(currentTransformedCursor.x - time_dragStartPosition, 0);
0516                 time_dragStartPosition = currentTransformedCursor.x;
0517                 drawGraph();
0518             }
0519         }
0520         
0521         function time_onMouseUp() {
0522             time_isDragging = false;
0523         }
0524         
0525         function time_onMouseOut() {
0526             time_isDragging = false
0527         }
0528         
0529         function time_onWheel(event) {
0530             if (event.ctrlKey) {
0531                 let currentTransformedCursor = getTransformedPoint(event.offsetX, event.offsetY);
0532                 const zoom = event.deltaY < 0 ? 1.02 : 0.98;
0533                 const originalScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0534                 timeZoomFactor *= zoom;
0535                 const newScale = 1./timeZoomFactor/kInitPixelsPerSecond;
0536                 //Keep the cursor at the same time and change zoom around that point
0537                 minVisibleTime = minVisibleTime + currentTransformedCursor.x*(originalScale-newScale);
0538             } else {
0539                 graph_translate(-1*event.deltaX, 0);
0540             }
0541             //console.log(minVisibleTime);
0542             drawGraph();
0543             event.preventDefault();
0544             
0545         }
0546         
0547         time_view.addEventListener('mousedown', time_onMouseDown)
0548         time_view.addEventListener('mousemove', time_onMouseMove)
0549         time_view.addEventListener('mouseup', time_onMouseUp)
0550         time_view.addEventListener('mouseout', time_onMouseOut)
0551         time_view.addEventListener('wheel', time_onWheel);
0552         
0553         function zoom_in_click(event) {
0554             const zoom = 1.1;
0555             const originalScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0556             timeZoomFactor *= zoom;
0557             const newScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0558             //Keep the center of the view at the same time and change zoom around that point
0559             minVisibleTime = minVisibleTime + max_graph_width/2*(originalScale-newScale);
0560             drawGraph();
0561         }
0562         function zoom_out_click(event) {
0563             const zoom = 0.909;
0564             const originalScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0565             timeZoomFactor *= zoom;
0566             const newScale = 1. / timeZoomFactor / kInitPixelsPerSecond;
0567             //Keep the center of the view at the same time and change zoom around that point
0568             minVisibleTime = minVisibleTime + max_graph_width/2*(originalScale-newScale);
0569             drawGraph();
0570         }
0571         zoom_in_button.addEventListener("click", zoom_in_click);
0572         zoom_out_button.addEventListener("click", zoom_out_click);
0573 
0574         function name_onWheel(event) {
0575             let offset = 0;
0576             graph_translate(0, -1*event.deltaY);
0577             drawGraph();
0578             event.preventDefault()
0579         }
0580         name_view.addEventListener('wheel', name_onWheel);
0581     }
0582     async function populateDropdown() {
0583         showLoadingSpinner(); // Show loading spinner
0584         try {
0585             const response = await fetch('/list-json');
0586             const jsonFiles = await response.json();
0587             const dropdown = document.getElementById('jsonDropdown');
0588             
0589             jsonFiles.forEach(file => {
0590                 const option = document.createElement('option');
0591                 option.value = file;
0592                 option.textContent = file;
0593                 dropdown.appendChild(option);
0594             });
0595         } catch (error) {
0596             console.error('Error fetching JSON file list:', error);
0597         }
0598         finally {
0599             hideLoadingSpinner(); // Hide loading spinner
0600         }
0601     }
0602     // Event listener for dropdown change
0603     jsonDropdown.addEventListener('change', function() {
0604         const selectedFile = this.value; // Get the selected value from the dropdown
0605         if (selectedFile) {
0606             hideSelectFilePrompt(); // Hide select file prompt
0607             fetchData(selectedFile); // Fetch the selected JSON file
0608         } else {
0609             console.log('No file selected');
0610         }
0611     });
0612     
0613 populateDropdown();
0614 function showLoadingSpinner() {
0615     document.getElementById('loadingSpinner').style.display = 'block';
0616 }
0617 
0618 function hideLoadingSpinner() {
0619     document.getElementById('loadingSpinner').style.display = 'none';
0620 }
0621 // Functions to show and hide the select file prompt
0622 function showSelectFilePrompt() {
0623     document.getElementById('selectFilePrompt').style.display = 'block';
0624 }
0625 
0626 function hideSelectFilePrompt() {
0627     document.getElementById('selectFilePrompt').style.display = 'none';
0628 }
0629 
0630 };