wmglobalqueue 2.4.5.1__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.
- Utils/CPMetrics.py +270 -0
- Utils/CertTools.py +100 -0
- Utils/EmailAlert.py +50 -0
- Utils/ExtendedUnitTestCase.py +62 -0
- Utils/FileTools.py +182 -0
- Utils/IteratorTools.py +80 -0
- Utils/MathUtils.py +31 -0
- Utils/MemoryCache.py +119 -0
- Utils/Patterns.py +24 -0
- Utils/Pipeline.py +137 -0
- Utils/PortForward.py +97 -0
- Utils/ProcFS.py +112 -0
- Utils/ProcessStats.py +194 -0
- Utils/PythonVersion.py +17 -0
- Utils/Signals.py +36 -0
- Utils/TemporaryEnvironment.py +27 -0
- Utils/Throttled.py +227 -0
- Utils/Timers.py +130 -0
- Utils/Timestamps.py +86 -0
- Utils/TokenManager.py +143 -0
- Utils/Tracing.py +60 -0
- Utils/TwPrint.py +98 -0
- Utils/Utilities.py +318 -0
- Utils/__init__.py +11 -0
- Utils/wmcoreDTools.py +707 -0
- WMCore/ACDC/Collection.py +57 -0
- WMCore/ACDC/CollectionTypes.py +12 -0
- WMCore/ACDC/CouchCollection.py +67 -0
- WMCore/ACDC/CouchFileset.py +238 -0
- WMCore/ACDC/CouchService.py +73 -0
- WMCore/ACDC/DataCollectionService.py +485 -0
- WMCore/ACDC/Fileset.py +94 -0
- WMCore/ACDC/__init__.py +11 -0
- WMCore/Algorithms/Alarm.py +39 -0
- WMCore/Algorithms/MathAlgos.py +274 -0
- WMCore/Algorithms/MiscAlgos.py +67 -0
- WMCore/Algorithms/ParseXMLFile.py +115 -0
- WMCore/Algorithms/Permissions.py +27 -0
- WMCore/Algorithms/Singleton.py +58 -0
- WMCore/Algorithms/SubprocessAlgos.py +129 -0
- WMCore/Algorithms/__init__.py +7 -0
- WMCore/Cache/GenericDataCache.py +98 -0
- WMCore/Cache/WMConfigCache.py +572 -0
- WMCore/Cache/__init__.py +0 -0
- WMCore/Configuration.py +659 -0
- WMCore/DAOFactory.py +47 -0
- WMCore/DataStructs/File.py +177 -0
- WMCore/DataStructs/Fileset.py +140 -0
- WMCore/DataStructs/Job.py +182 -0
- WMCore/DataStructs/JobGroup.py +142 -0
- WMCore/DataStructs/JobPackage.py +49 -0
- WMCore/DataStructs/LumiList.py +734 -0
- WMCore/DataStructs/Mask.py +219 -0
- WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
- WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
- WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
- WMCore/DataStructs/MathStructs/__init__.py +0 -0
- WMCore/DataStructs/Pickleable.py +24 -0
- WMCore/DataStructs/Run.py +256 -0
- WMCore/DataStructs/Subscription.py +175 -0
- WMCore/DataStructs/WMObject.py +47 -0
- WMCore/DataStructs/WorkUnit.py +112 -0
- WMCore/DataStructs/Workflow.py +60 -0
- WMCore/DataStructs/__init__.py +8 -0
- WMCore/Database/CMSCouch.py +1430 -0
- WMCore/Database/ConfigDBMap.py +29 -0
- WMCore/Database/CouchMonitoring.py +450 -0
- WMCore/Database/CouchUtils.py +118 -0
- WMCore/Database/DBCore.py +198 -0
- WMCore/Database/DBCreator.py +113 -0
- WMCore/Database/DBExceptionHandler.py +59 -0
- WMCore/Database/DBFactory.py +117 -0
- WMCore/Database/DBFormatter.py +177 -0
- WMCore/Database/Dialects.py +13 -0
- WMCore/Database/ExecuteDAO.py +327 -0
- WMCore/Database/MongoDB.py +241 -0
- WMCore/Database/MySQL/Destroy.py +42 -0
- WMCore/Database/MySQL/ListUserContent.py +20 -0
- WMCore/Database/MySQL/__init__.py +9 -0
- WMCore/Database/MySQLCore.py +132 -0
- WMCore/Database/Oracle/Destroy.py +56 -0
- WMCore/Database/Oracle/ListUserContent.py +19 -0
- WMCore/Database/Oracle/__init__.py +9 -0
- WMCore/Database/ResultSet.py +44 -0
- WMCore/Database/Transaction.py +91 -0
- WMCore/Database/__init__.py +9 -0
- WMCore/Database/ipy_profile_couch.py +438 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
- WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
- WMCore/GlobalWorkQueue/__init__.py +0 -0
- WMCore/GroupUser/CouchObject.py +127 -0
- WMCore/GroupUser/Decorators.py +51 -0
- WMCore/GroupUser/Group.py +33 -0
- WMCore/GroupUser/Interface.py +73 -0
- WMCore/GroupUser/User.py +96 -0
- WMCore/GroupUser/__init__.py +11 -0
- WMCore/Lexicon.py +836 -0
- WMCore/REST/Auth.py +202 -0
- WMCore/REST/CherryPyPeriodicTask.py +166 -0
- WMCore/REST/Error.py +333 -0
- WMCore/REST/Format.py +642 -0
- WMCore/REST/HeartbeatMonitorBase.py +90 -0
- WMCore/REST/Main.py +636 -0
- WMCore/REST/Server.py +2435 -0
- WMCore/REST/Services.py +24 -0
- WMCore/REST/Test.py +120 -0
- WMCore/REST/Tools.py +38 -0
- WMCore/REST/Validation.py +250 -0
- WMCore/REST/__init__.py +1 -0
- WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
- WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
- WMCore/ReqMgr/DataStructs/__init__.py +0 -0
- WMCore/ReqMgr/__init__.py +1 -0
- WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
- WMCore/Services/AlertManager/__init__.py +0 -0
- WMCore/Services/CRIC/CRIC.py +238 -0
- WMCore/Services/CRIC/__init__.py +0 -0
- WMCore/Services/DBS/DBS3Reader.py +1044 -0
- WMCore/Services/DBS/DBSConcurrency.py +44 -0
- WMCore/Services/DBS/DBSErrors.py +112 -0
- WMCore/Services/DBS/DBSReader.py +23 -0
- WMCore/Services/DBS/DBSUtils.py +166 -0
- WMCore/Services/DBS/DBSWriterObjects.py +381 -0
- WMCore/Services/DBS/ProdException.py +133 -0
- WMCore/Services/DBS/__init__.py +8 -0
- WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
- WMCore/Services/FWJRDB/__init__.py +0 -0
- WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
- WMCore/Services/HTTPS/__init__.py +0 -0
- WMCore/Services/LogDB/LogDB.py +201 -0
- WMCore/Services/LogDB/LogDBBackend.py +191 -0
- WMCore/Services/LogDB/LogDBExceptions.py +11 -0
- WMCore/Services/LogDB/LogDBReport.py +85 -0
- WMCore/Services/LogDB/__init__.py +0 -0
- WMCore/Services/MSPileup/__init__.py +0 -0
- WMCore/Services/MSUtils/MSUtils.py +54 -0
- WMCore/Services/MSUtils/__init__.py +0 -0
- WMCore/Services/McM/McM.py +173 -0
- WMCore/Services/McM/__init__.py +8 -0
- WMCore/Services/MonIT/Grafana.py +133 -0
- WMCore/Services/MonIT/__init__.py +0 -0
- WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
- WMCore/Services/PyCondor/__init__.py +0 -0
- WMCore/Services/ReqMgr/ReqMgr.py +261 -0
- WMCore/Services/ReqMgr/__init__.py +0 -0
- WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
- WMCore/Services/ReqMgrAux/__init__.py +0 -0
- WMCore/Services/RequestDB/RequestDBReader.py +267 -0
- WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
- WMCore/Services/RequestDB/__init__.py +0 -0
- WMCore/Services/Requests.py +624 -0
- WMCore/Services/Rucio/Rucio.py +1290 -0
- WMCore/Services/Rucio/RucioUtils.py +74 -0
- WMCore/Services/Rucio/__init__.py +0 -0
- WMCore/Services/RucioConMon/RucioConMon.py +121 -0
- WMCore/Services/RucioConMon/__init__.py +0 -0
- WMCore/Services/Service.py +400 -0
- WMCore/Services/StompAMQ/__init__.py +0 -0
- WMCore/Services/TagCollector/TagCollector.py +155 -0
- WMCore/Services/TagCollector/XMLUtils.py +98 -0
- WMCore/Services/TagCollector/__init__.py +0 -0
- WMCore/Services/UUIDLib.py +13 -0
- WMCore/Services/UserFileCache/UserFileCache.py +160 -0
- WMCore/Services/UserFileCache/__init__.py +8 -0
- WMCore/Services/WMAgent/WMAgent.py +63 -0
- WMCore/Services/WMAgent/__init__.py +0 -0
- WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
- WMCore/Services/WMArchive/DataMap.py +463 -0
- WMCore/Services/WMArchive/WMArchive.py +33 -0
- WMCore/Services/WMArchive/__init__.py +0 -0
- WMCore/Services/WMBS/WMBS.py +97 -0
- WMCore/Services/WMBS/__init__.py +0 -0
- WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
- WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
- WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
- WMCore/Services/WMStats/WMStatsReader.py +445 -0
- WMCore/Services/WMStats/WMStatsWriter.py +273 -0
- WMCore/Services/WMStats/__init__.py +0 -0
- WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
- WMCore/Services/WMStatsServer/__init__.py +0 -0
- WMCore/Services/WorkQueue/WorkQueue.py +492 -0
- WMCore/Services/WorkQueue/__init__.py +0 -0
- WMCore/Services/__init__.py +8 -0
- WMCore/Services/pycurl_manager.py +574 -0
- WMCore/WMBase.py +50 -0
- WMCore/WMConnectionBase.py +164 -0
- WMCore/WMException.py +183 -0
- WMCore/WMExceptions.py +269 -0
- WMCore/WMFactory.py +76 -0
- WMCore/WMInit.py +377 -0
- WMCore/WMLogging.py +104 -0
- WMCore/WMSpec/ConfigSectionTree.py +442 -0
- WMCore/WMSpec/Persistency.py +135 -0
- WMCore/WMSpec/Steps/BuildMaster.py +87 -0
- WMCore/WMSpec/Steps/BuildTools.py +201 -0
- WMCore/WMSpec/Steps/Builder.py +97 -0
- WMCore/WMSpec/Steps/Diagnostic.py +89 -0
- WMCore/WMSpec/Steps/Emulator.py +62 -0
- WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
- WMCore/WMSpec/Steps/Executor.py +210 -0
- WMCore/WMSpec/Steps/StepFactory.py +213 -0
- WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
- WMCore/WMSpec/Steps/Template.py +204 -0
- WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
- WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
- WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
- WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
- WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
- WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
- WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
- WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
- WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
- WMCore/WMSpec/Steps/__init__.py +8 -0
- WMCore/WMSpec/Utilities.py +63 -0
- WMCore/WMSpec/WMSpecErrors.py +12 -0
- WMCore/WMSpec/WMStep.py +347 -0
- WMCore/WMSpec/WMTask.py +1997 -0
- WMCore/WMSpec/WMWorkload.py +2288 -0
- WMCore/WMSpec/WMWorkloadTools.py +382 -0
- WMCore/WMSpec/__init__.py +9 -0
- WMCore/WorkQueue/DataLocationMapper.py +273 -0
- WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
- WMCore/WorkQueue/DataStructs/Block.py +48 -0
- WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
- WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
- WMCore/WorkQueue/DataStructs/__init__.py +0 -0
- WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
- WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
- WMCore/WorkQueue/Policy/End/__init__.py +32 -0
- WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
- WMCore/WorkQueue/Policy/Start/Block.py +258 -0
- WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
- WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
- WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
- WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
- WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
- WMCore/WorkQueue/Policy/__init__.py +57 -0
- WMCore/WorkQueue/WMBSHelper.py +772 -0
- WMCore/WorkQueue/WorkQueue.py +1237 -0
- WMCore/WorkQueue/WorkQueueBackend.py +750 -0
- WMCore/WorkQueue/WorkQueueBase.py +39 -0
- WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
- WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
- WMCore/WorkQueue/WorkQueueUtils.py +130 -0
- WMCore/WorkQueue/__init__.py +13 -0
- WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
- WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
- WMCore/Wrappers/__init__.py +6 -0
- WMCore/__init__.py +10 -0
- wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-patch +15 -0
- wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-unpatch +8 -0
- wmglobalqueue-2.4.5.1.data/data/bin/wmc-httpd +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/README.md +40 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/language +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
- wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
- wmglobalqueue-2.4.5.1.dist-info/METADATA +26 -0
- wmglobalqueue-2.4.5.1.dist-info/RECORD +347 -0
- wmglobalqueue-2.4.5.1.dist-info/WHEEL +5 -0
- wmglobalqueue-2.4.5.1.dist-info/licenses/LICENSE +202 -0
- wmglobalqueue-2.4.5.1.dist-info/licenses/NOTICE +16 -0
- wmglobalqueue-2.4.5.1.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_Mask_
|
|
4
|
+
|
|
5
|
+
Basic Mask object that can be used to restrict the run/lumi/event range in a
|
|
6
|
+
job in two ways:
|
|
7
|
+
|
|
8
|
+
- Inclusive: The stuff within the mask is processed
|
|
9
|
+
- Exclusive: The stuff outside of the mask is processed
|
|
10
|
+
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from builtins import range
|
|
14
|
+
from WMCore.DataStructs.Run import Run
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Mask(dict):
|
|
18
|
+
"""
|
|
19
|
+
_Mask_
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, **kwargs):
|
|
23
|
+
dict.__init__(self, **kwargs)
|
|
24
|
+
self.inclusive = True
|
|
25
|
+
self.setdefault("inclusivemask", True)
|
|
26
|
+
self.setdefault("FirstEvent", None)
|
|
27
|
+
self.setdefault("LastEvent", None)
|
|
28
|
+
self.setdefault("FirstLumi", None)
|
|
29
|
+
self.setdefault("LastLumi", None)
|
|
30
|
+
self.setdefault("FirstRun", None)
|
|
31
|
+
self.setdefault("LastRun", None)
|
|
32
|
+
self.setdefault("runAndLumis", {})
|
|
33
|
+
|
|
34
|
+
def setMaxAndSkipEvents(self, maxEvents, skipEvents):
|
|
35
|
+
"""
|
|
36
|
+
_setMaxAndSkipEvents_
|
|
37
|
+
|
|
38
|
+
Set FirstEvent & LastEvent fields as max & skip events
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
self['FirstEvent'] = skipEvents
|
|
43
|
+
if maxEvents is not None:
|
|
44
|
+
self['LastEvent'] = skipEvents + maxEvents
|
|
45
|
+
|
|
46
|
+
return
|
|
47
|
+
|
|
48
|
+
def setMaxAndSkipLumis(self, maxLumis, skipLumi):
|
|
49
|
+
"""
|
|
50
|
+
_setMaxAndSkipLumis
|
|
51
|
+
|
|
52
|
+
Set the Maximum number of lumi sections and the starting point
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
self['FirstLumi'] = skipLumi
|
|
57
|
+
self['LastLumi'] = skipLumi + maxLumis
|
|
58
|
+
|
|
59
|
+
return
|
|
60
|
+
|
|
61
|
+
def setMaxAndSkipRuns(self, maxRuns, skipRun):
|
|
62
|
+
"""
|
|
63
|
+
_setMaxAndSkipRuns
|
|
64
|
+
|
|
65
|
+
Set the Maximum number of runss and the starting point
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
self['FirstRun'] = skipRun
|
|
70
|
+
self['LastRun'] = skipRun + maxRuns
|
|
71
|
+
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
def getMaxEvents(self):
|
|
75
|
+
"""
|
|
76
|
+
_getMaxEvents_
|
|
77
|
+
|
|
78
|
+
return maxevents setting
|
|
79
|
+
|
|
80
|
+
"""
|
|
81
|
+
if self['LastEvent'] is None or self['FirstEvent'] is None:
|
|
82
|
+
return None
|
|
83
|
+
return self['LastEvent'] - self['FirstEvent'] + 1
|
|
84
|
+
|
|
85
|
+
def getMax(self, keyType=None):
|
|
86
|
+
"""
|
|
87
|
+
_getMax_
|
|
88
|
+
|
|
89
|
+
returns the maximum number of runs/events/etc of the type of the type string
|
|
90
|
+
"""
|
|
91
|
+
if 'First%s' % (keyType) not in self:
|
|
92
|
+
return None
|
|
93
|
+
if self['First%s' % (keyType)] is None or self['Last%s' % (keyType)] is None:
|
|
94
|
+
return None
|
|
95
|
+
return self['Last%s' % (keyType)] - self['First%s' % (keyType)] + 1
|
|
96
|
+
|
|
97
|
+
def addRun(self, run):
|
|
98
|
+
"""
|
|
99
|
+
_addRun_
|
|
100
|
+
|
|
101
|
+
Add a run object
|
|
102
|
+
"""
|
|
103
|
+
run.lumis.sort()
|
|
104
|
+
firstLumi = run.lumis[0]
|
|
105
|
+
lastLumi = run.lumis[0]
|
|
106
|
+
for lumi in run.lumis:
|
|
107
|
+
if lumi <= lastLumi + 1:
|
|
108
|
+
lastLumi = lumi
|
|
109
|
+
else:
|
|
110
|
+
self.addRunAndLumis(run.run, lumis=[firstLumi, lastLumi])
|
|
111
|
+
firstLumi = lumi
|
|
112
|
+
lastLumi = lumi
|
|
113
|
+
self.addRunAndLumis(run.run, lumis=[firstLumi, lastLumi])
|
|
114
|
+
return
|
|
115
|
+
|
|
116
|
+
def addRunWithLumiRanges(self, run, lumiList):
|
|
117
|
+
"""
|
|
118
|
+
_addRunWithLumiRanges_
|
|
119
|
+
|
|
120
|
+
Add to runAndLumis with call signature
|
|
121
|
+
addRunWithLumiRanges(run=run, lumiList = [[start1,end1], [start2, end2], ...]
|
|
122
|
+
"""
|
|
123
|
+
self['runAndLumis'][run] = lumiList
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
def addRunAndLumis(self, run, lumis=None):
|
|
127
|
+
"""
|
|
128
|
+
_addRunAndLumis_
|
|
129
|
+
|
|
130
|
+
Add runs and lumis directly
|
|
131
|
+
TODO: The name of this function is a little misleading. If you pass a list of lumis
|
|
132
|
+
it ignores the content of the list and adds a range based on the max/min in
|
|
133
|
+
the list. Missing lumis in the list are ignored.
|
|
134
|
+
|
|
135
|
+
NOTE: If the new run/lumi range overlaps with the pre-existing lumi ranges in the
|
|
136
|
+
mask, no attempt is made to merge these together. This can result in a mask
|
|
137
|
+
with duplicate lumis.
|
|
138
|
+
"""
|
|
139
|
+
lumis = lumis or []
|
|
140
|
+
if not isinstance(lumis, list):
|
|
141
|
+
lumis = list(lumis)
|
|
142
|
+
|
|
143
|
+
if run not in self['runAndLumis']:
|
|
144
|
+
self['runAndLumis'][run] = []
|
|
145
|
+
|
|
146
|
+
self['runAndLumis'][run].append([min(lumis), max(lumis)])
|
|
147
|
+
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
def getRunAndLumis(self):
|
|
151
|
+
"""
|
|
152
|
+
_getRunAndLumis_
|
|
153
|
+
|
|
154
|
+
Return list of active runs and lumis
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
return self['runAndLumis']
|
|
158
|
+
|
|
159
|
+
def runLumiInMask(self, run, lumi):
|
|
160
|
+
"""
|
|
161
|
+
_runLumiInMask_
|
|
162
|
+
|
|
163
|
+
See if a particular runLumi is in the mask
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
if self['runAndLumis'] == {}:
|
|
167
|
+
# Empty dictionary
|
|
168
|
+
# ALWAYS TRUE
|
|
169
|
+
return True
|
|
170
|
+
|
|
171
|
+
if run not in self['runAndLumis']:
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
for pair in self['runAndLumis'][run]:
|
|
175
|
+
# Go through each max and min pair
|
|
176
|
+
if pair[0] <= lumi and pair[1] >= lumi:
|
|
177
|
+
# Then the lumi is bracketed
|
|
178
|
+
return True
|
|
179
|
+
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
def filterRunLumisByMask(self, runs):
|
|
183
|
+
"""
|
|
184
|
+
_filterRunLumisByMask_
|
|
185
|
+
|
|
186
|
+
Pass a Mask a list of run objects, get back a list of
|
|
187
|
+
run objects that correspond to the actual mask allowed values
|
|
188
|
+
"""
|
|
189
|
+
if self['runAndLumis'] == {}:
|
|
190
|
+
# Empty dictionary
|
|
191
|
+
# ALWAYS TRUE
|
|
192
|
+
return runs
|
|
193
|
+
|
|
194
|
+
runDict = {}
|
|
195
|
+
for r in runs:
|
|
196
|
+
if r.run in runDict:
|
|
197
|
+
runDict[r.run].extendLumis(r.lumis)
|
|
198
|
+
else:
|
|
199
|
+
runDict[r.run] = r
|
|
200
|
+
|
|
201
|
+
maskRuns = set(self["runAndLumis"].keys())
|
|
202
|
+
passedRuns = set([r.run for r in runs])
|
|
203
|
+
filteredRuns = maskRuns.intersection(passedRuns)
|
|
204
|
+
|
|
205
|
+
newRuns = set()
|
|
206
|
+
for runNumber in filteredRuns:
|
|
207
|
+
maskLumis = set()
|
|
208
|
+
for pair in self["runAndLumis"][runNumber]:
|
|
209
|
+
if pair[0] == pair[1]:
|
|
210
|
+
maskLumis.add(pair[0])
|
|
211
|
+
else:
|
|
212
|
+
maskLumis = maskLumis.union(list(range(pair[0], pair[1] + 1)))
|
|
213
|
+
|
|
214
|
+
filteredLumis = set(runDict[runNumber].lumis).intersection(maskLumis)
|
|
215
|
+
if len(filteredLumis) > 0:
|
|
216
|
+
filteredLumiEvents = [(lumi, runDict[runNumber].getEventsByLumi(lumi)) for lumi in filteredLumis]
|
|
217
|
+
newRuns.add(Run(runNumber, *filteredLumiEvents))
|
|
218
|
+
|
|
219
|
+
return newRuns
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_ContinuousSummaryHistogram_
|
|
3
|
+
|
|
4
|
+
Continuous histogram module, to be used by the TaskArchiver
|
|
5
|
+
to store histograms in the summary where the data is a continuous number.
|
|
6
|
+
|
|
7
|
+
Created on Nov 20, 2012
|
|
8
|
+
|
|
9
|
+
@author: dballest
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import division
|
|
12
|
+
import math
|
|
13
|
+
|
|
14
|
+
from WMCore.DataStructs.MathStructs.SummaryHistogram import SummaryHistogram
|
|
15
|
+
from WMCore.Algorithms.MathAlgos import validateNumericInput
|
|
16
|
+
from WMCore.Algorithms.MathAlgos import calculateRunningAverageAndQValue, calculateStdDevFromQ
|
|
17
|
+
|
|
18
|
+
class ContinuousSummaryHistogram(SummaryHistogram):
|
|
19
|
+
"""
|
|
20
|
+
_ContinuousSummaryHistogram_
|
|
21
|
+
|
|
22
|
+
A histogram where there are continuous points
|
|
23
|
+
with certain frequency, it follows
|
|
24
|
+
that there is only one value in Y and
|
|
25
|
+
that the average and standard deviation are
|
|
26
|
+
not calculated on the frequency values but the X values.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, title, xLabel, yLabel = None,
|
|
30
|
+
roundingDecimals = 2, nBins = None,
|
|
31
|
+
dropOutliers = False, sigmaLimit = 5,
|
|
32
|
+
storeHistogram = True):
|
|
33
|
+
"""
|
|
34
|
+
__init__
|
|
35
|
+
|
|
36
|
+
Initialize a more complex histogram structure, containing different
|
|
37
|
+
data to calculate online average and standard deviations. This data is also
|
|
38
|
+
stored in the JSON to allow rebuilding and adding histograms.
|
|
39
|
+
|
|
40
|
+
All histograms are binned when requested, the resolution can be specified
|
|
41
|
+
through nBins, otherwise the value used is the one recommended in:
|
|
42
|
+
Wand, M.P. (1997), "Data-Based Choice of Histogram Bin Width," The American Statistician, 51, 59-64.
|
|
43
|
+
|
|
44
|
+
If specified, outlier farther than sigmaLimit standard deviations from the
|
|
45
|
+
mean will not be included in the binned histogram.
|
|
46
|
+
"""
|
|
47
|
+
# Initialize the parent object
|
|
48
|
+
SummaryHistogram.__init__(self, title, xLabel)
|
|
49
|
+
|
|
50
|
+
# Indicate this is a discrete histogram
|
|
51
|
+
self.continuous = True
|
|
52
|
+
|
|
53
|
+
# Add data only used in the continuous version
|
|
54
|
+
self.yLabel = yLabel
|
|
55
|
+
self.nPoints = 0
|
|
56
|
+
self.QValue = None
|
|
57
|
+
self.average = None
|
|
58
|
+
|
|
59
|
+
# Configuration parameters for the continuous histograms
|
|
60
|
+
self.roundingDecimals = roundingDecimals
|
|
61
|
+
self.fixedNBins = nBins
|
|
62
|
+
self.dropOutliers = dropOutliers
|
|
63
|
+
self.sigmaLimit = sigmaLimit
|
|
64
|
+
self.binned = False
|
|
65
|
+
self.storeHistogram = storeHistogram
|
|
66
|
+
|
|
67
|
+
# Override initialization of some attributes
|
|
68
|
+
self.average = 0.0
|
|
69
|
+
self.stdDev = 0.0
|
|
70
|
+
|
|
71
|
+
return
|
|
72
|
+
|
|
73
|
+
def addPoint(self, xValue, yLabel = None):
|
|
74
|
+
"""
|
|
75
|
+
_addPoint_
|
|
76
|
+
|
|
77
|
+
Add a point from a continuous set (only-numbers allowed currently) to the histogram data,
|
|
78
|
+
calculate the running average and standard deviation.
|
|
79
|
+
If no y-label had been specified before, one must be supplied
|
|
80
|
+
otherwise the given y-label must be either None or equal
|
|
81
|
+
to the stored value.
|
|
82
|
+
"""
|
|
83
|
+
if self.binned:
|
|
84
|
+
# Points can't be added to binned histograms!
|
|
85
|
+
raise Exception("Points can't be added to binned histograms")
|
|
86
|
+
|
|
87
|
+
if self.yLabel is None and yLabel is None:
|
|
88
|
+
raise Exception("Some y-label must be stored for the histogram")
|
|
89
|
+
elif self.yLabel is None:
|
|
90
|
+
self.yLabel = yLabel
|
|
91
|
+
elif yLabel is not None and self.yLabel != yLabel:
|
|
92
|
+
raise Exception("Only one y-label is allowed on continuous histograms")
|
|
93
|
+
|
|
94
|
+
if not validateNumericInput(xValue):
|
|
95
|
+
# Do nothing if it is not a number
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
xValue = float(xValue)
|
|
99
|
+
xValue = round(xValue, self.roundingDecimals)
|
|
100
|
+
|
|
101
|
+
if self.storeHistogram:
|
|
102
|
+
if xValue not in self.data:
|
|
103
|
+
self.data[xValue] = 0
|
|
104
|
+
self.data[xValue] += 1
|
|
105
|
+
|
|
106
|
+
self.nPoints += 1
|
|
107
|
+
|
|
108
|
+
(self.average, self.QValue) = calculateRunningAverageAndQValue(xValue, self.nPoints, self.average, self.QValue)
|
|
109
|
+
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
def __add__(self, other):
|
|
113
|
+
#TODO: For HG1302, support multiple agents properly in the workload summary
|
|
114
|
+
raise NotImplementedError
|
|
115
|
+
|
|
116
|
+
def toJSON(self):
|
|
117
|
+
"""
|
|
118
|
+
_toJSON_
|
|
119
|
+
|
|
120
|
+
Bin the histogram if any, calculate the standard deviation. Store
|
|
121
|
+
the internal data needed for reconstruction of the histogram
|
|
122
|
+
from JSON and call superclass toJSON method.
|
|
123
|
+
"""
|
|
124
|
+
if self.nPoints:
|
|
125
|
+
self.stdDev = calculateStdDevFromQ(self.QValue, self.nPoints)
|
|
126
|
+
if not self.binned and self.storeHistogram:
|
|
127
|
+
self.binHistogram()
|
|
128
|
+
self.jsonInternal = {}
|
|
129
|
+
self.jsonInternal['yLabel'] = self.yLabel
|
|
130
|
+
self.jsonInternal['QValue'] = self.QValue
|
|
131
|
+
self.jsonInternal['nPoints'] = self.nPoints
|
|
132
|
+
return SummaryHistogram.toJSON(self)
|
|
133
|
+
|
|
134
|
+
def binHistogram(self):
|
|
135
|
+
"""
|
|
136
|
+
_binHistogram_
|
|
137
|
+
|
|
138
|
+
Histograms of continuous data must be binned,
|
|
139
|
+
this takes care of that using given or optimal parameters.
|
|
140
|
+
Note that this modifies the data object,
|
|
141
|
+
and points can't be added to the histogram after this.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
if not self.nPoints:
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
self.binned = True
|
|
148
|
+
|
|
149
|
+
# Number of bins can be specified or calculated based on number of points
|
|
150
|
+
nBins = self.fixedNBins
|
|
151
|
+
if nBins is None:
|
|
152
|
+
nBins = int(math.floor((5.0 / 3.0) * math.pow(self.nPoints, 1.0 / 3.0)))
|
|
153
|
+
|
|
154
|
+
# Define min and max
|
|
155
|
+
if not self.dropOutliers:
|
|
156
|
+
upperLimit = max(self.data.keys())
|
|
157
|
+
lowerLimit = min(self.data.keys())
|
|
158
|
+
else:
|
|
159
|
+
stdDev = calculateStdDevFromQ(self.QValue, self.nPoints)
|
|
160
|
+
upperLimit = self.average + (stdDev * self.sigmaLimit)
|
|
161
|
+
lowerLimit = self.average - (stdDev * self.sigmaLimit)
|
|
162
|
+
|
|
163
|
+
# Incremental delta
|
|
164
|
+
delta = abs(float(upperLimit - lowerLimit)) / nBins
|
|
165
|
+
|
|
166
|
+
# Build the bins, it's a list of tuples for now
|
|
167
|
+
bins = []
|
|
168
|
+
|
|
169
|
+
a = lowerLimit
|
|
170
|
+
b = lowerLimit + delta
|
|
171
|
+
while len(bins) < nBins:
|
|
172
|
+
bins.append((a, b))
|
|
173
|
+
a += delta
|
|
174
|
+
b += delta
|
|
175
|
+
# Go through data and populate the binned histogram
|
|
176
|
+
binnedHisto = {}
|
|
177
|
+
currentBin = 0
|
|
178
|
+
currentPoint = 0
|
|
179
|
+
sortedData = sorted(self.data.keys())
|
|
180
|
+
while currentPoint < len(sortedData):
|
|
181
|
+
point = sortedData[currentPoint]
|
|
182
|
+
encodedTuple = "%s,%s" % (bins[currentBin][0], bins[currentBin][1])
|
|
183
|
+
if encodedTuple not in binnedHisto:
|
|
184
|
+
binnedHisto[encodedTuple] = 0
|
|
185
|
+
if point > upperLimit or point < lowerLimit:
|
|
186
|
+
currentPoint += 1
|
|
187
|
+
elif currentBin == len(bins) - 1:
|
|
188
|
+
binnedHisto[encodedTuple] += self.data[point]
|
|
189
|
+
currentPoint += 1
|
|
190
|
+
elif point >= bins[currentBin][0] and point < bins[currentBin][1]:
|
|
191
|
+
binnedHisto[encodedTuple] += self.data[point]
|
|
192
|
+
currentPoint += 1
|
|
193
|
+
else:
|
|
194
|
+
currentBin += 1
|
|
195
|
+
|
|
196
|
+
self.data = binnedHisto
|
|
197
|
+
return
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_DiscreteSummaryHistogram_
|
|
3
|
+
|
|
4
|
+
Discrete histogram module, to be used by the TaskArchiver
|
|
5
|
+
to store histograms in the summary where the data is categorical.
|
|
6
|
+
|
|
7
|
+
Created on Nov 20, 2012
|
|
8
|
+
|
|
9
|
+
@author: dballest
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from WMCore.DataStructs.MathStructs.SummaryHistogram import SummaryHistogram
|
|
13
|
+
from WMCore.Algorithms.MathAlgos import getAverageStdDev
|
|
14
|
+
|
|
15
|
+
class DiscreteSummaryHistogram(SummaryHistogram):
|
|
16
|
+
"""
|
|
17
|
+
_DiscreteSummaryHistogram_
|
|
18
|
+
|
|
19
|
+
A histogram where the data is organized by
|
|
20
|
+
a finite number of categories, it can have
|
|
21
|
+
many values for each category.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def __init__(self, title, xLabel):
|
|
26
|
+
"""
|
|
27
|
+
__init__
|
|
28
|
+
|
|
29
|
+
Initialize a simpler histogram that only stores
|
|
30
|
+
the histogram. Everything else is calculated when the JSON is requested.
|
|
31
|
+
"""
|
|
32
|
+
# Initialize the parent object
|
|
33
|
+
SummaryHistogram.__init__(self, title, xLabel)
|
|
34
|
+
|
|
35
|
+
# Indicate this is a discrete histogram
|
|
36
|
+
self.continuous = False
|
|
37
|
+
|
|
38
|
+
# Add data only used in the discrete version
|
|
39
|
+
self.yLabels = set()
|
|
40
|
+
|
|
41
|
+
# Override initialization of some attributes
|
|
42
|
+
self.average = {}
|
|
43
|
+
self.stdDev = {}
|
|
44
|
+
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
def addPoint(self, xValue, yLabel):
|
|
48
|
+
"""
|
|
49
|
+
_addPoint_
|
|
50
|
+
|
|
51
|
+
Add point to discrete histogram,
|
|
52
|
+
x value is a category and therefore not rounded.
|
|
53
|
+
There can be many yLabel and standard deviations are
|
|
54
|
+
not calculated online. Histograms are always stored.
|
|
55
|
+
"""
|
|
56
|
+
if xValue not in self.data:
|
|
57
|
+
# Record the category
|
|
58
|
+
self.data[xValue] = {}
|
|
59
|
+
for label in self.yLabels:
|
|
60
|
+
self.data[xValue][label] = 0
|
|
61
|
+
|
|
62
|
+
if yLabel not in self.yLabels:
|
|
63
|
+
# Record the label
|
|
64
|
+
self.yLabels.add(yLabel)
|
|
65
|
+
self.average[yLabel] = 0.0
|
|
66
|
+
self.stdDev[yLabel] = 0.0
|
|
67
|
+
for category in self.data:
|
|
68
|
+
self.data[category][yLabel] = 0
|
|
69
|
+
|
|
70
|
+
self.data[xValue][yLabel] += 1
|
|
71
|
+
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
def __add__(self, other):
|
|
75
|
+
#TODO: For HG1302, support multiple agents properly in the workload summary
|
|
76
|
+
raise NotImplementedError
|
|
77
|
+
|
|
78
|
+
def toJSON(self):
|
|
79
|
+
"""
|
|
80
|
+
_toJSON_
|
|
81
|
+
|
|
82
|
+
Calculate average and standard deviation, store it
|
|
83
|
+
and call the parent class toJSON method
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
for yLabel in self.yLabels:
|
|
87
|
+
numList = []
|
|
88
|
+
for xValue in self.data:
|
|
89
|
+
numList.append(self.data[xValue][yLabel])
|
|
90
|
+
(self.average[yLabel], self.stdDev[yLabel]) = getAverageStdDev(numList)
|
|
91
|
+
|
|
92
|
+
return SummaryHistogram.toJSON(self)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""
|
|
2
|
+
_SummaryHistogram_
|
|
3
|
+
|
|
4
|
+
Histogram module, to be used by the TaskArchiver
|
|
5
|
+
to store histograms in the summary.
|
|
6
|
+
|
|
7
|
+
Created on Nov 16, 2012
|
|
8
|
+
|
|
9
|
+
@author: dballest
|
|
10
|
+
"""
|
|
11
|
+
from builtins import str
|
|
12
|
+
from WMCore.DataStructs.WMObject import WMObject
|
|
13
|
+
|
|
14
|
+
class SummaryHistogram(WMObject):
|
|
15
|
+
"""
|
|
16
|
+
_SummaryHistogram_
|
|
17
|
+
|
|
18
|
+
Histogram object, provides familiar CRUD methods
|
|
19
|
+
which take care of most of the statistical
|
|
20
|
+
calculations when adding points, this object
|
|
21
|
+
can also be converted into a dictionary
|
|
22
|
+
for JSON documents. It knows how to combine
|
|
23
|
+
with other histograms and create itself from
|
|
24
|
+
a dictionary provided it has matching structure.
|
|
25
|
+
|
|
26
|
+
This is an interface, the real work is done
|
|
27
|
+
by the ContinuousSummaryHistogram and
|
|
28
|
+
DiscreteSummaryHistogram objects
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, title = None, xLabel = None):
|
|
32
|
+
"""
|
|
33
|
+
__init__
|
|
34
|
+
Initialize the elements in the object.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
# Meta-information about the histogram, it can be changed at any point
|
|
38
|
+
self.title = title
|
|
39
|
+
self.xLabel = xLabel
|
|
40
|
+
|
|
41
|
+
# These shouldn't be touched from anything outside the SummaryHistogram object and children classes
|
|
42
|
+
self.continuous = None
|
|
43
|
+
self.jsonInternal = None
|
|
44
|
+
self.data = {}
|
|
45
|
+
self.average = None
|
|
46
|
+
self.stdDev = None
|
|
47
|
+
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
def setTitle(self, newTitle):
|
|
51
|
+
"""
|
|
52
|
+
_setTitle_
|
|
53
|
+
|
|
54
|
+
Set the title
|
|
55
|
+
"""
|
|
56
|
+
self.title = newTitle
|
|
57
|
+
return
|
|
58
|
+
|
|
59
|
+
def setHorizontalLabel(self, xLabel):
|
|
60
|
+
"""
|
|
61
|
+
_setHorizontalLabel_
|
|
62
|
+
|
|
63
|
+
Set the label on the x axis
|
|
64
|
+
"""
|
|
65
|
+
self.xLabel = xLabel
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
def addPoint(self, xValue, yLabel):
|
|
69
|
+
"""
|
|
70
|
+
_addPoint_
|
|
71
|
+
|
|
72
|
+
Add a point to the histogram data, a histogram
|
|
73
|
+
can have many types of y values for the same x if
|
|
74
|
+
x is continuous otherwise it is only one yLabel.
|
|
75
|
+
They should be in a similar scale for best results.
|
|
76
|
+
"""
|
|
77
|
+
raise NotImplementedError("SummaryHistogram objects can't be used, use either the continuous or discrete implementation")
|
|
78
|
+
|
|
79
|
+
def toJSON(self):
|
|
80
|
+
"""
|
|
81
|
+
_toJSON_
|
|
82
|
+
|
|
83
|
+
Return a dictionary which is compatible
|
|
84
|
+
with a JSON object
|
|
85
|
+
"""
|
|
86
|
+
if self.continuous is None:
|
|
87
|
+
raise TypeError("toJSON can't be called on a bare SummaryHistogram object")
|
|
88
|
+
|
|
89
|
+
# Get what the children classes did
|
|
90
|
+
jsonDict = {}
|
|
91
|
+
jsonDict['internalData'] = self.jsonInternal or {}
|
|
92
|
+
|
|
93
|
+
# Add the common things
|
|
94
|
+
jsonDict['title'] = self.title
|
|
95
|
+
jsonDict['xLabel'] = self.xLabel
|
|
96
|
+
jsonDict['continuous'] = self.continuous
|
|
97
|
+
jsonDict['data'] = self.data
|
|
98
|
+
jsonDict['stdDev'] = self.stdDev
|
|
99
|
+
jsonDict['average'] = self.average
|
|
100
|
+
|
|
101
|
+
return jsonDict
|
|
102
|
+
|
|
103
|
+
def __add__(self, other):
|
|
104
|
+
"""
|
|
105
|
+
__add__
|
|
106
|
+
|
|
107
|
+
Add two histograms, combine statistics.
|
|
108
|
+
"""
|
|
109
|
+
raise NotImplementedError("SummaryHistogram objects can't be used, use either the continuous or discrete implementation")
|
|
110
|
+
|
|
111
|
+
def __str__(self):
|
|
112
|
+
"""
|
|
113
|
+
__str__
|
|
114
|
+
|
|
115
|
+
Return the str object of the JSON
|
|
116
|
+
"""
|
|
117
|
+
return str(self.toJSON())
|
|
File without changes
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
_Pickleable_
|
|
4
|
+
|
|
5
|
+
An object that can be persisted using pickle
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
__all__ = []
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
from WMCore.DataStructs.WMObject import WMObject
|
|
12
|
+
|
|
13
|
+
class Pickleable(WMObject):
|
|
14
|
+
def save(self):
|
|
15
|
+
"""
|
|
16
|
+
Pickle the object
|
|
17
|
+
"""
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
def load(self):
|
|
21
|
+
"""
|
|
22
|
+
Load the object from a pickle file
|
|
23
|
+
"""
|
|
24
|
+
pass
|