CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/FWCore/Utilities/scripts/cfg-viewer.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: latin-1 -*-
00003 from optparse import OptionParser
00004 import imp
00005 import re
00006 import sys
00007 import shutil
00008 import os
00009 import FWCore.ParameterSet.Config as cms
00010     
00011 modsNames=[]
00012 newModsNames,oldMods,allMods=[],[],[]
00013 
00014 class generateBrowser:
00015   def __init__(self,htmlFile, cfgFile):
00016     self.html = htmlFile
00017     self.theDir=''
00018     self.pathName = "paths.html"
00019     self.js = "search.js"
00020     self.thecss = "style.css"
00021 
00022     rest= html.rsplit('/',1)    
00023     # Find where the html file is to be stored.
00024     # store everything else there, move other stuff there.
00025     if(len(rest)>1):
00026       self.theDir=rest[0]+'/'
00027       if(not os.path.isdir(self.theDir)):
00028         os.mkdir(self.theDir)
00029     self.javascript("%s%s"%(self.theDir,self.js))
00030     self.css("%s%s"%(self.theDir,self.thecss))
00031     self.pathLi="""
00032     <li class="expand %(className)s" data-name="%(nameID)s">%(nameID)s:</li>
00033     """ 
00034     self.cfg = imp.load_source("cfg", cfgFile)
00035     # do the psets (in other file, provide link to it.)
00036     psetTypes = open("%sparamTypes.js"%(self.theDir),'w')
00037     psetTypes.close()
00038     print "Starting print out of psets."
00039     self.doPsets()
00040     print "Finished finding psets. Now onto paths..."
00041     self.doPaths()
00042     print "Paths done"
00043 
00044   def doPaths(self):
00045     modHTMLName= "%sparamTypes.js"%(self.theDir)
00046     modToPathName = "%smodToPath.js" %(self.theDir)
00047     tempFile ="%stemp.js"%(self.theDir)
00048     f={modHTMLName:"params",modToPathName:"modules"}
00049     o={modHTMLName:"a",modToPathName:"w"}
00050     theS="var %s={"
00051     for key in f.keys():
00052       curFile = open(key,o[key])
00053       curFile.write(theS%(f[key]))
00054       curFile.close() 
00055     first = True
00056     liToBeWritten, frmPathHolder="", "";
00057     className, theS,frmPathStr ="path","",'%s%s:["%s"]'
00058     newModsStr, oldModsStr='%s\n%s:["%s"]', '%s"%s",%s'
00059     dataFile= open(modHTMLName,'a')
00060     v = visitor(dataFile)
00061     paths = self.cfg.process.paths
00062     global oldMods
00063     global allMods
00064     global newModsNames
00065     for item in paths.keys():
00066       oldMods=[] # module names which have been seen before.
00067        # needed so we can add this path name to the dictionary in modToPath.js
00068       allMods =[]# set of current path modules names including duplciates.       
00069       newModsNames=[] # set of current paths module name without duplicates.
00070       # could get oldMods from all Mods if we take away all newModsNames
00071       liToBeWritten +=format(self.pathLi,nameID=item,className=className)
00072       paths[item].visit(v)
00073       frmPathHolder +=frmPathStr%(theS,item,"\",\"".join(allMods))
00074       fromMod = open(modToPathName, 'r')
00075       fromModTemp = open(tempFile, 'w')
00076       for line in fromMod:
00077         tLine= re.sub('\[.*?\]', "",line) 
00078         result = re.split(':|,', tLine[tLine.find('{')+1:])
00079         namesFound = [x for i, x in enumerate(result)if not i%2]
00080         # the new names we have is going to be smaller, 
00081         # so we'll loop round that
00082         for each in oldMods:
00083           if(each in namesFound):
00084             oldMods.remove(each)
00085             index = line.find(each)+len(each)+2 #  as will have :[ after it
00086             line =  oldModsStr %(line[:index],item,line[index:])
00087         fromModTemp.write(line)
00088       fromMod.close()
00089       for each in newModsNames:
00090         fromModTemp.write(newModsStr%(theS,each,item))
00091         theS=","
00092       fromModTemp.close()
00093       os.rename(tempFile,modToPathName)
00094       if(first):
00095         theS=","
00096         first=False
00097     out = open("%s%s"%(self.theDir,self.pathName), 'w')
00098     self.printStart(self.js,self.thecss, """disabled="True" """, out)
00099     out.write("<a href='%s'> See Psets</a>&nbsp;\n<ul>%s"\
00100       "</ul>\n</body>\n</html>"%(self.html.rsplit('/',1)[-1],liToBeWritten))
00101     out.close()
00102     dataFile.write("};\nfunction getAllParams(){\n"\
00103                     "var newD ={};\n var keys = Object.keys(params);\n"\
00104                     "for(var i=0; i <keys.length; i++){ \n"\
00105                     "  newD[keys[i]]= params[keys[i]][\"parameters\"];\n}"\
00106                     " return newD;}\n"\
00107                     " function getParams(modName){\n"\
00108                     " return params[modName][\"parameters\"];}\n"\
00109                     "function getInnerParams(parentsNames){\n"\
00110                     "var curList=params[parentsNames[0]][\"parameters\"];\n"\
00111                     "for(var i=1; i < parentsNames.length;i++){\n"\
00112                     "  for(var p=0; p < curList.length;p++){\n"\
00113                     "      if(curList[p][0]==parentsNames[i]){\n"\
00114                     "        var found = curList[p][1];\n"\
00115                     "        break;\n }\n}\n curList = found;\n}\n"\
00116                     "  return curList;}\n"\
00117                     "function getFile(name){\n"\
00118                     "return params[name][\"file\"];\n}"\
00119                     "function getType(name){\n"\
00120                     "return params[name][\"type\"];\n}")
00121     fromPath= open("%spathToMod.js" %(self.theDir),'w')
00122     fromPath.write("var paths={%s}\n "\
00123      "function getModules(thePath){\n"\
00124     "return paths[thePath];\n}"\
00125     "\n function keys(){\n return Object.keys(paths); "\
00126     "\n}" %(frmPathHolder))
00127     fromPath.close()
00128     fromMod = open(modToPathName, 'a')
00129     fromMod.write("}\n function getPaths(theMod){\n"\
00130     "return modules[theMod];\n}")
00131     fromMod.close()
00132 
00133   def doPsets(self):
00134     addC,writeOut,toParamWrite= "","",""
00135     first = True
00136     outStr=self.pathLi
00137     pStr="%s%s:'%s'"
00138     classN = "module"
00139     process = self.cfg.process
00140     psets = process.psets
00141     theDict ={}
00142     for pset in psets:
00143       writeOut+=format(outStr,nameID=pset,className=classN)
00144       psetCfg = process.__dict__[pset]
00145       res = do(psetCfg.parameters_(),[])
00146       theDict[pset] = res
00147       if(first):
00148         addC=","
00149         first=False
00150     out = open(self.html, 'w')
00151     self.printStart(self.js, self.thecss ,"", out)
00152     out.write("<a href=\"%s\"> See Paths</a>\n<ul>"\
00153             "%s</ul></html>"%(self.pathName,writeOut))
00154     out.close()
00155 
00156     psetTypes = open("%sparamTypes.js"%(self.theDir),'w')
00157     psetTypes.write("psetParams=%s\nfunction getAllpsetParams(){\n"\
00158                     "return psetParams;}\n"\
00159                     " function getpsetParams(modName){\n"\
00160                     " return psetParams[modName];}\n"\
00161                     "function getInnerpsetParams(parentsNames){\n"\
00162                     "var currentList = psetParams[parentsNames[0]];\n"\
00163                     "for(var i=1; i < parentsNames.length;i++){\n"\
00164                     "  for(var p=0; p < currentList.length;p++){\n"\
00165                     "      if(currentList[p][0]==parentsNames[i]){\n"\
00166                     "        var found = currentList[p][1];\n"\
00167                     "        break;\n }\n}\n currentList = found;\n}\n"\
00168                     "  return currentList;}\n"%(theDict))
00169 
00170   # Start of html files.
00171   def printStart(self,js, css, dis, out):
00172     scripts ="""
00173    <script type="text/javascript" src="paramTypes.js"></script>
00174     """
00175     classType="pset"
00176     buttons="""
00177     <option id="module" selected="selected">module</option>
00178     """
00179     if(len(dis)>0):
00180       classType="path"
00181       buttons="""
00182       <option id="path" selected="selected">Path</option>
00183       <option id="module">module</option>
00184       <option value="type">Type</option>
00185       <option value="Parameter">Parameter</option>
00186       <option value="value">value</option>
00187       """
00188       scripts= """
00189       <script type="text/javascript" src="pathToMod.js"></script>
00190       <script type="text/javascript" src="modToPath.js"></script>
00191       <script type="text/javascript" src="paramTypes.js"></script>
00192       """
00193     out.write( """
00194     <!DOCTYPE html>
00195     <html>
00196       <head>
00197         <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
00198         <title>cfg-browser</title>
00199        <script type="text/javascript" 
00200        src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
00201        </script>
00202         %(scripts)s
00203         <script type="text/javascript" src="%(js)s"></script>
00204 
00205         <link href="%(css)s" rel="stylesheet" type="text/css"/>
00206       </head>
00207       <body>
00208       <!--form name="input" action="html_form_action.asp" method="get"--> 
00209       <form name="searchInput" onsubmit="return false;">
00210       <input type="text" id="searchWord"/>
00211       <select id="searchType">
00212       %(option)s
00213       </select>
00214        
00215        <input type="submit" value="Search" id="search" disabled/></form> 
00216       <br/><p id="searchNumber"></p><br/>
00217       <a id="hide" style="cursor:default; color:#CCCCCC;" 
00218       class="%(class)sReset"
00219       href="javascript:;" >
00220        Hide All</a>
00221       <br/><br/>
00222    <span id="pageType" data-type=%(class)s></span>
00223 
00224   <input type="submit" id ="searchReset" style="display:none" 
00225   value="Reset search results." class="%(class)sReset"/>
00226   <br/><input type="checkbox" id="ShowFiles" value="File"/>Show module File.
00227   <br/>
00228 
00229     """%{'js':js,'option':buttons, 'css':css, 'dis':dis,
00230        'scripts':scripts, 'class':classType})
00231 
00232   def javascript(self,thejs):
00233     jsFile = open(thejs, 'w')
00234     jsFile.write( """    
00235 $(document).ready(function(){ 
00236    $(document).on('click', '#search', function(e){     
00237     numFound = 0;
00238     var par = $(this).parent();
00239     var id = $(par).find('#searchType').attr('id');
00240     var option = $('#'+id+' option:selected').text();
00241     var val = $(par).find('#searchWord').val()
00242     var reg = new RegExp("("+val+")", "gi");
00243     switch(option){
00244     case "Path":
00245       reset('li.path', e, true);
00246       numFound = topLevelMatch(keys(),reg,false); // will stay the same
00247     
00248     case "module":
00249       if(typeof modKeys != 'function' && false){
00250         //if modKeys is not defined means we're using pset html.
00251         //maybe change this so instead we define top layer li with class top
00252         reset('li.module', e, true);
00253         //numFound = topLevelMatch
00254         numFound = topLevelMatch( $('li.module'),reg,true);
00255       }
00256       else{
00257        // for now pretend that its in html.
00258         //searchReplaceHTML(reg, "module");
00259         // if not in the html
00260         //Okay can either, get allmatched modules and add them 
00261         // to all html parents
00262         // or go round paths and get all matched modules adding to tghe path
00263         var strings = allMods(reg);
00264         var Li = $(document.createElement('li')).attr(
00265                                            "class","module expand");
00266         console.log("hereiam before");
00267         searchReplaceNonHTML(strings,Li, reg)
00268       } 
00269    
00270     case "File Name":
00271       //get all modules names, get files for all modules
00272       // once we have a list of all modules we want
00273       // add those modules to
00274     
00275     case "Parameter":
00276       // gives the params which match the reg.
00277       numFound = lowerLevels(reg,doInnerParams, e)
00278       
00279     case "Type":
00280       reset('li.path',e,true);
00281       // similar to params except we're looking at 
00282       // the types and not the params names.
00283       // so need to get all the params, loop over the keys
00284       var matches = matchValue(reg);
00285       console.log("matches are "+ matches)
00286     
00287     case "value":
00288       numFound = lowerLevels(reg,doInnerValue, e)
00289     }
00290     $('#searchNumber').html(numFound+" found.");
00291     $('#searchReset').show();
00292   });
00293 
00294 //do Params, values.
00295 function lowerLevels(reg,funcCall, e){
00296   reset('li.path', e, true);
00297   var numFound=0;
00298    if($("span[id='pageType']").attr("data-type")=="pset"){
00299         var matches = getAllpsetParams();
00300       }
00301       else var matches = getAllParams();
00302 
00303   var keys = Object.keys(matches);
00304   for(var i=0; i < keys.length; i++){
00305     var theKey = keys[i];
00306     var params = matches[theKey];
00307     var theMod = moduleLI.clone().attr("data-name",theKey).text(theKey);
00308     // need to make the ul 
00309     tempNumber =0;
00310     var theUL = funcCall(params,reg);
00311     if(tempNumber ==0)continue;
00312     theMod.append(theUL);
00313     // for now just do parents
00314     var pathsAddTo = getPaths(theKey);
00315     var mul =0;
00316     for(var k=0; k < pathsAddTo.length;k++){
00317       // all paths to be added to.
00318       var theP = pathsAddTo[k];
00319       // find the parent.
00320       $('li.path[name='+theP+']').each(function(){
00321         // for each one add the theMod.
00322         $(this).children().empty();
00323         $(this).append(theMod.clone());
00324         mul +=1;
00325        });
00326     }
00327     numFound += (tempNumber*mul)
00328   }
00329   return numFound;
00330 }
00331 
00332 function doInnerValue(modules,reg){
00333   var theUL = UL.clone();
00334   // okay we have a list where we want to check the 
00335   // inner list is an inner list.
00336   for(var i=0; i < modules.length; i++){
00337     var innerList= modules[i];
00338     var theName = innerList[0];
00339     var next = innerList[1];
00340     // next could be inner or could be what we want.
00341     if(typeof(next)=="object"){
00342       // we have inner params, recurse!
00343       var oldNum = tempNumber 
00344       var newUL = doInnerValue(next, reg); // will return a ul.
00345       if(tempNumber == oldNum){
00346         var li= LIExpand.clone().attr("data-name", theName).html(theName);
00347       }
00348       else {
00349         var li= LIExpanded.clone().attr("data-name", theName).html(theName);
00350         li.append(newUL);
00351       }
00352     }
00353     else{
00354       // else do normal and make the
00355       // rename the value
00356       var newValue = next.replace(reg, "<em>$1</em>"); 
00357       if(newValue != next){
00358          tempNumber +=next.match(reg).length;
00359       }   
00360       var li= paramLI.clone().attr("data-name",theName).html(theName);
00361       var theClass="value";
00362       li.append(span.clone().attr("class", "value").html(": "+newValue));
00363       innerList.slice(2).forEach(function(i){
00364         li.append(span.clone().attr("class", "type").text(" ("+i+")"));
00365       });
00366     }
00367     theUL.append(li);
00368   }
00369   return theUL;
00370   }
00371 
00372 function doInnerParams(params,reg){
00373   var theUL = UL.clone();
00374   // okay we have a list where we want to check the 
00375   // inner list is an inner list.
00376   for(var i=0; i < params.length; i++){
00377     var param = params[i];// it's name.
00378     var theName = param[0];
00379     var newName = theName.replace(reg, "<em>$1</em>");
00380     if(newName != theName){
00381        tempNumber +=theName.match(reg).length;
00382     }
00383     var next = param[1];
00384     if(typeof(next)=="object"){
00385       // we have inner params, recurse!
00386       //var cloLI= LIExpand.clone().attr("name", theName).text(theName);
00387       //var ul = UL.clone();
00388       var old = tempNumber;
00389       var newUL = doInnerParams(next, reg); // will return a ul.
00390       if(old == tempNumber){
00391         var li= LIExpand.clone().attr("data-name", theName).html(newName);
00392       }
00393       else {
00394         var li= LIExpanded.clone().attr("data-name", theName).html(newName);
00395         li.append(newUL);
00396       }
00397     }
00398     else{
00399       // else do normal and make the 
00400       var li= paramLI.clone().attr("data-name",theName).html(newName);
00401       var theClass="value";
00402       for(var w=1; w < param.length;w++){
00403         // do types etc.
00404         if(w==1)
00405           li.append(span.clone().attr("class", "value").text(": "+param[w]));
00406         else
00407           li.append(span.clone().attr("class", "type").text(
00408                                            " ("+param[w]+")"));
00409       }
00410     }
00411     theUL.append(li);
00412   }
00413   return theUL;
00414   }
00415   var LI= $(document.createElement('li'));
00416   var moduleLI= LI.clone().attr("class","module expand");
00417   var paramLI= LI.clone().attr("class","param expanded");
00418   var UL = $(document.createElement('ul'));
00419   var span = $(document.createElement('span'));
00420   var LIExpand = LI.clone().attr("class","expand paramInner");
00421   var LIExpanded = LI.clone().attr("class","expanded paramInner");
00422 // All params send here.
00423 //[[normaloparam, value,type]
00424 //[inner[innervalues, value,type]][norm, value, type]]
00425 // we will get [normaloparam, value,type] etc
00426 var numFound =0;
00427 var tempNumber =0;
00428   /*
00429    String format should have where they want the string to go as name.
00430    For module just now. //
00431   */// stringformat would be what we want it to go in,
00432   function searchReplaceNonHTML(strings, theLi, regex){
00433     // we have the things we want, the string should just be the
00434     // what we want to be shwn i.e. an LI, which we clone.
00435     var UL = $(document.createElement('ul'));
00436     for(var i=0; i <strings.length; i++){
00437       var thisOne = strings[i]; // e.g. generator
00438       //here i have the string and now i will
00439       //need a format string or something, to know what to put around it?
00440       var LI = theLi.clone().attr("data-name", thisOne).html(
00441                  thisOne.replace(regex, "<em>$1</em>"));
00442       var paths = getPaths(thisOne);
00443       for (var p=0; p < paths.length; p++){
00444         // need to find the path on the page and add the module to it.
00445         $('li.path[name='+paths[p]+']').each(function(){
00446           // for each add this LI
00447           if($(this).children('ul').length ==0){
00448             $(this).append(UL.clone().append(LI.clone()));
00449           }
00450           else{
00451             $(this).children('ul').append(LI.clone()); 
00452             // so all paths dont point to the same LI,maybe can change this? 
00453           }
00454           $(this).attr("class","expanded path");
00455         });
00456       }
00457     }
00458   }
00459   /*
00460    Search when what we're looking for is in HTML but not topLevel element.
00461    To be global replace, find should be regexp object with g.
00462   */
00463   function searchReplaceHTML(find,identifier){
00464     var found =0;
00465     var foundParents=[];
00466     var notFoundLI=[];
00467     $("li ."+identifier).each(function(){
00468       var howMany=0;
00469       if(howmany = $(this).attr("data-name").match(find)){
00470        // we found you 
00471        found +=howMany
00472        $(this).html() = $(this).html().replace(find,"<em>$1</em>");
00473       // now find parents
00474       // if parents not already showen show them
00475       $(this).parents('ul').each(function(){
00476         if(foundParents.indexOf(this) ==-1){
00477           $(this).show();
00478           foundParents.append(this);
00479         }
00480         else{
00481          // already done these parents
00482          return false;// (i.e. break out loop);// the parents loop.
00483         }
00484       });
00485     }
00486     else{
00487      notFoundLI.append(this);
00488      // not a match, can just try and find a ul parent, 
00489     //if there is one, then we need to know whether to
00490      // hide it.TODO or do nothing.
00491     }
00492     });
00493     // now we have list of parents we want to hide all other parents
00494     $(notFoundLI).each(function(){
00495       $(this).parents('ul').each(function(){
00496         if(foundParents.indexOf(this) ==-1){
00497           $(this).hide();
00498         }
00499         else{
00500          // already done these parents
00501          return false;// (i.e. break out loop);// the parents loop.
00502         }
00503       });
00504     });
00505     return found;
00506   }
00507   /*
00508     Resets search ouput.
00509   */
00510   $(document).on('click', '#searchReset', function(e){
00511     $('#searchNumber').html("");
00512     if($(this).attr('class') == "pathReset"){
00513       reset('li.path',e,true); 
00514     }
00515     else{
00516       reset('li.module',e,true); 
00517     }
00518     $(this).hide();
00519   });
00520   /*
00521     Hides children of top level. TODO: Done - works
00522   */
00523   $(document).on('click', '#hide', function(e){
00524     //for hiding we just get top level and remove children.
00525     if($(this).css('cursor')!='default'){
00526       $('#searchNumber').html("");
00527       if($(this).attr('class') == "pathReset"){
00528         var selec ='li.path';
00529       }
00530       else var selec ='li.module';
00531       $(selec).each(function(){
00532         if(removeChildren(this, e))toggleExpand(this, e);
00533       });
00534       $(this).css('color','#CCCCCC');
00535       $(this).css('cursor','default');
00536     }
00537   });
00538   /*
00539     Retrieves and expands path elements. - works
00540   */
00541   $(document).on('click', '.path.expand',function(event){
00542     var UL = addModules(getModules($(this).attr('data-name')));
00543     $(this).append(UL); 
00544     $('#hide').css('color','')
00545     $('#hide').css('cursor','')
00546   });
00547   /*
00548     Adds modules to a list and returns list.
00549   */
00550   function addModules(results){
00551     var UL = $(document.createElement("ul"));
00552     var LI = $(document.createElement('li')).attr("class","module expand");
00553     for(var i=0; i < results.length; i++){
00554       var theName = results[i];
00555       var val = theName+"("+getType(theName)+")"
00556       if(document.getElementById("ShowFiles").checked)
00557         val+=" ("+getFile(theName)+")"
00558       UL.append(LI.clone().attr("data-name", theName).text(val));
00559     }
00560    return UL;
00561   }
00562 
00563   /*
00564     Retrieve and expands module elements.
00565     //changed to deal with new data format,
00566     //(data now seperate from html specification) - works
00567   */
00568   $(document).on('click','.module.expand', function(event){
00569     addParams(this);
00570     event.stopPropagation();
00571   });
00572 
00573   /*
00574     Add params to the object. Object can be of any type 
00575     (normally module or param).
00576     It's name needs to be in the data to find its parameters. - works
00577   */
00578   function addParams(obj, results){
00579     var LIBasic = $(document.createElement('li')).attr("class","param");
00580     var LIExpand = LIBasic.clone().attr("class","expand paramInner");
00581     var span = $(document.createElement("span"));
00582     var UL = $(document.createElement("ul"));
00583     // getParams returns list of list.
00584     // Format:[[name,value,type,trackedornot]].CHANGED!!
00585     // new format 
00586    // :[[name, value,type,trackedornot],[namePset,[name,value,type]]]
00587     // If 2nd element is list then its a pset.
00588     var objName = $(obj).attr('data-name');
00589     if(!results){
00590       if($("span[id='pageType']").attr("data-type")=="pset"){
00591         var results = getpsetParams(objName);
00592       }
00593       else {
00594         var results = getParams(objName);
00595         var type = getType(objName);
00596         if(type == "Sequence"){
00597          // inside will be names of modules 
00598         //- so do the same as if this was a path obj
00599          var ul = addModules(results);
00600          $(obj).append(ul);
00601          return
00602         }
00603        }
00604     }
00605     for(var i =0; i < results.length; i++){
00606       var all = results[i].slice();
00607       var theName = all.shift(); 
00608       if(typeof(all[0]) == "object"){
00609         var cloLI= LIExpand.clone().attr("data-name", theName).text(theName);
00610         //for(var p=0; p < all[0].length;p++){
00611           // add all children.
00612         //}
00613       }
00614       else{
00615         // Not a Pset.
00616         var cloLI = LIBasic.clone().attr("data-name", theName).text(theName);
00617         var value = all.shift()
00618         // formating so lots of strings look nicer
00619         if(value.indexOf(",")>-1)
00620            value = "<ul>"+value.replace(/,/g, "</li><li>")+"</li></ul>"
00621         cloLI.append(span.clone().attr("class","value").html(": "+value))  
00622         for(var p=0; p < all.length; p++){       
00623           cloLI.append(span.clone().attr("class","type").text(
00624             " ("+all[p]+")"))
00625         } 
00626       } 
00627       UL.append(cloLI);
00628     }
00629     $(obj).append(UL);
00630     $('#hide').css('color','')
00631     $('#hide').css('cursor','')
00632   }
00633   /*
00634     Hides/Shows children from class param.
00635     //changed to deal with new data format - works
00636   */  
00637 $(document).on('click', '.paramInner.expand, .paramInner.expanded',
00638    function(event){
00639    if($(this).children('ul').length ==0){
00640      // find parents
00641      var theClass =""
00642      var obj = this;
00643      var parents =[$(this).attr("data-name")]
00644      while(theClass.indexOf("module")==-1){
00645        obj = $(obj).parent();
00646        if(obj.prop("tagName")=="UL") continue;
00647        var parName = obj.attr("data-name");
00648        parents.unshift(parName);
00649        theClass = obj.attr("class");
00650       }
00651       if($("span[id='pageType']").attr("data-type")=="pset"){
00652         var result = getInnerpsetParams(parents);
00653       }
00654       else var result = getInnerParams(parents);
00655       addParams(this, result);
00656     }
00657     else{
00658       $(this).children('ul').toggle();
00659     }
00660     event.stopPropagation();
00661   });
00662   // Needed to stop the propagation of event when it should not be expanded.
00663   $(document).on('click', '.param',function(event){
00664      if($(this).find('ul').length >0){
00665        $(this).find('ul').toggle();
00666      }
00667     event.stopPropagation();
00668   });
00669   /*
00670     Removes children from expanded paths or modules.
00671   */
00672   $(document).on('click', '.path.expanded, .module.expanded',function(event){
00673     removeChildren(this,event);
00674   });
00675   
00676   // Toggles class names.
00677   $(document).on('click','.expand, .expanded', function(event){
00678     toggleExpand(this, event);
00679   });
00680   /*
00681     Does matching for top level list elements.
00682     Returns number of matches.
00683   */
00684   function topLevelMatch(list, reg, haveLIs){
00685     var numFound =0;
00686     for(var p=0; p < list.length; p++){
00687       if(haveLIs){
00688        var li = $(list[p]);
00689        var item = li.attr('data-name'); 
00690       }
00691       else{
00692         var item = list[p];
00693         var li= $('li[name='+item+']');
00694       }
00695       if(num=item.match(reg)){
00696         numFound +=num.length;
00697         li.html(li.html().replace(reg, "<em>$1</em>"));
00698       }
00699       else{
00700         li.hide();
00701       }
00702     }
00703     return numFound;
00704   }
00705   /*
00706     Removes highlights from selector, removes also children 
00707     if rmChildren == true.
00708   */
00709   function reset(selector, e, rmChildren){
00710     var rm = new RegExp('<em>|</em>', 'g');
00711     $(selector).each(function(i){
00712     var html = $(this).html();
00713     if(html.match(rm)){
00714       $(this).html(html.replace(rm, '')); 
00715     }
00716     else{
00717       $(this).show(); 
00718     }
00719     if(rmChildren)if(removeChildren(this, e))toggleExpand(this, e);}); 
00720   }
00721   /*
00722     Removes children from parent.
00723   */
00724   function removeChildren(parent, event){
00725     var c = $(parent).children('ul');
00726     if(c.length >0){
00727       $(c).remove();
00728       event.stopPropagation();
00729       return true;
00730     }
00731     return false;
00732   }
00733    /*
00734     Helper function toggles classes.
00735   */
00736   function toggleExpand(me,event){
00737     $(me).toggleClass("expanded expand");
00738     event.stopPropagation();
00739   }
00740 });
00741     """)
00742     jsFile.close()
00743 
00744   def css(self,thecss):
00745     cssFile= open(thecss, 'w')
00746     cssFile.write( """
00747 
00748 em {
00749   background-color: rgb(255,255,0);
00750   font-style: normal;
00751 }
00752 .module{
00753   color: #0000CC
00754 }
00755 .param {
00756   color: #9999CC;
00757   cursor:default; 
00758 }
00759 .paramInner {
00760   color: #9999FF;
00761   cursor:default; 
00762 }
00763 .value{
00764    color:#0000FF;
00765 }
00766 .type{
00767   color: #00CCFF;
00768 }
00769 
00770 ul {
00771   list-style-type:none;
00772   padding-left:0.6em;
00773 }
00774  .expand:before{
00775     content:'›';
00776     float: left;
00777     margin-right: 10px;
00778 }
00779  .expanded:before, .param:before{
00780     content:'ˇ';
00781     float: left;
00782     margin-right: 10px;
00783 }
00784 .expand, .expanded, .param{
00785   cursor:pointer;
00786 }
00787     
00788     """)
00789     cssFile.close()
00790 
00791 """
00792   Do module Objects e.g. producers etc
00793 """
00794 
00795 def doModules(modObj, dataFile, seq, seqs, currentName, innerSeq):
00796   name = modObj.label_()
00797   typ = re.sub("<|>|'", "", str(type(modObj))).split(".")[-1]
00798   if(seq==0):allMods.append(name)
00799   elif(not innerSeq and currentName not in allMods):
00800     allMods.append(currentName)
00801   if(name not in modsNames):
00802     theList = do(modObj.parameters_(), [])
00803     modsNames.append(name)
00804     newModsNames.append(name)
00805     filename = modObj._filename.split("/")[-1]
00806     theS =""
00807     if(len(modsNames) > 1): theS=","
00808     theS+="%s:%s"
00809     d = getParamSeqDict(theList, typ, filename)
00810     dataFile.write(theS%(name, d)) 
00811     if(seq >0):
00812       seqs[currentName].append(name)
00813       
00814   else:
00815     oldMods.append(name) 
00816 
00817 def format(s, **kwds):
00818   return s % kwds
00819   
00820 class visitor:
00821   def __init__(self, df):
00822     self.df = df
00823     self.seq = 0
00824     self.currentName =""
00825     self.oldNames =[]
00826     self.done =[]
00827     self.seqs={}
00828     self.innerSeq = False
00829 
00830   def enter(self, value):
00831     if(isinstance(value,cms._Module)):
00832       doModules(value, self.df, self.seq,
00833                 self.seqs, self.currentName, self.innerSeq)
00834     if(isinstance(value,cms.Sequence)):
00835       if(len(self.currentName) >0):self.oldNames.insert(0, self.currentName)
00836       if(self.seq >0):
00837         # this is an inner sequence
00838         self.innerSeq = True;
00839         self.seqs[self.currentName].append(value.label())
00840       self.currentName = value.label()
00841       self.seqs[self.currentName] = []
00842       self.seq +=1
00843 
00844   def leave(self, value):
00845     if(isinstance(value,cms.Sequence)):
00846       name = value.label()
00847       if(name in self.oldNames):self.oldNames.remove(name)
00848       if(self.currentName == name and len(self.oldNames) >0):
00849         self.currentName = self.oldNames.pop(0)
00850       if(name not in self.done):
00851         d = getParamSeqDict(self.seqs.pop(name),
00852               re.sub("<|>|'", "", str(type(value))).split(".")[-1], "")
00853         self.df.write(",%s:%s"%(name,d)) 
00854         self.done.append(name)  
00855       self.seq -=1
00856       if(self.seq==0): self.innerSeq = False;
00857 
00858 # Used to enforce dictionary in datfile have same format.
00859 def getParamSeqDict(params, typ, fil):
00860   d={}
00861   d["parameters"] = params
00862   d["type"] = typ
00863   d["file"] =fil
00864   return d
00865 
00866 """
00867  Prints out inner details of parameters.
00868 """
00869 def do(params, o):
00870   for item in params:
00871     thing = params[item]
00872     if(hasattr(thing, "parameters_")):
00873       theList =[]
00874       theList.append("%s(%s)"%(item,thing.configTypeName()))
00875       # do will now return the list that the thing takes
00876       theList.append(do(getattr(thing,"parameters_")(),[]))
00877       o.append(theList)
00878     elif(thing.configTypeName()== "VPSet"):
00879           theList =[]
00880           theList.append("%s(%s)"%(item,thing.configTypeName()))
00881           newInS = "%s-%d"
00882           li2 =[]
00883           for popped in thing:
00884             if(hasattr(popped, "parameters_")):
00885               innerList =[]
00886               innerList.append("(%s)"%(popped.configTypeName()))
00887               innerList.append(do(getattr(popped,"parameters_")(),[]))
00888               li2.append(innerList)
00889           theList.append(li2)   
00890           o.append(theList)
00891     else:
00892       # easy version. Just save what we have - 
00893       # all going to have the same module..
00894       # have parent as an input, so we can send it.
00895       theList =[]
00896       theList.append(item)
00897       theType = thing.configTypeName()
00898       if(hasattr(thing, "pop") and len(thing)>0):
00899         value = "%s"% (",".join(str(li) for li in thing))
00900       else:
00901         value = thing.configValue()
00902       theList.append(value)
00903       
00904       if(theType =="double" or theType =="int"):
00905         theList.append(theType)
00906       else:
00907         if(thing.isTracked()):
00908           theList.append(theType)
00909           theList.append("tracked")
00910       o.append(theList)        
00911   return o
00912 
00913 if __name__ == "__main__":
00914   parser = OptionParser(usage="%prog <cfg-file> <html-file>")
00915   flags =['-c', '-o']
00916   parser.add_option("-c", "--cfg_file", dest="_cfgfile",
00917                     help="The configuration file.")
00918   parser.add_option("-o", "--html_file", dest="_htmlfile",
00919                     help="The output html file.")
00920   opts, args = parser.parse_args()
00921   cfg, html = opts._cfgfile, opts._htmlfile
00922   more =0
00923   cfgGet, htmlGet = False, False
00924   if(cfg == None):
00925      cfgGet = True
00926      more +=1
00927   if(html == None):
00928     htmlGet = True
00929     more+=1 
00930   if len(args) < more:
00931     parser.error("Please provide one and only one configuration"\
00932                   "file and one output file.")
00933   if(cfgGet): cfg = args[0]
00934   if(htmlGet): html = args[1]
00935   try:
00936     f = open(cfg)
00937   except:
00938     parser.error("File %s does not exist." % cfg) 
00939   generateBrowser(html,cfg)