//============================================================================ // SiClusteringModule.hh // --------------------- // AC++ module that performs cluster reconstruction in silicon detectors. // The module optionally applies calibration corrections to the silicon // raw data. // // R. Snider // Johns Hopkins University // 3-June-1997 //============================================================================ #include "TrackingMods/SiClusteringModule.hh" #include "AbsEnv/AbsEnv.hh" #include "DBManager/PackageManager.hh" #include "Edm/Handle.hh" #include "Edm/GenericConstHandle.hh" #include "ErrorLogger_i/gERRLOG.hh" #include "GeometryBase/CdfDetector.hh" #include "RegionalObjects/UniverseRegion.hh" #include "RRL3/GrowResultList.hh" #include "SiliconGeometry/AbsSiDetectorNode.hh" #include "SiliconGeometry/CdfHalfLadder.hh" #include "SiliconGeometry/CdfHalfLadderSet.hh" #include "SiliconGeometry/SiDigiCode.hh" #include "SvxDaqObjects/Correctors/SiStripCorrectorManager.hh" #include "SvxDaqObjects/Correctors/DBCorrector.hh" #include "SvxDaqObjects/Correctors/L00Corrector.hh" #include "TrackingObjects/SiData/PrecisionSet.hh" #include "TrackingObjects/SiData/SiChipInfo.hh" #include "TrackingObjects/SiData/SiClusterSet.hh" #include "TrackingObjects/SiData/SiHdiInfo.hh" #include "TrackingObjects/SiData/SiHitSet.hh" #include "TrackingObjects/SiData/SiPortCardInfo.hh" #include "TrackingObjects/SiData/SiRecoDataRep.hh" #include "TrackingObjects/SiData/SiVrbInfo.hh" #include "TrackingObjects/SiData/SiVrbInfoSet.hh" #include "TrackingObjects/Storable/StorableRun2SiStripSet.hh" #include "TrackingSI/ClusterFinding/SiClusterCorrector.hh" #include "TrackingSI/ClusterFinding/SiClusterFinder.hh" #include "TrackingSI/ClusterFinding/SiStratClusterFinder.hh" #include #include #include using std::cout; using std::endl; //========================================================================= // Constructor, destructor //========================================================================= SiClusteringModule::SiClusteringModule( const char* const theName, const char* const theDescription ) : AppModule( theName, theDescription ), _regionalMode ("RegionalMode", this, false), _newFramework ("NewFramework", this, true), _inputDataFromBanks ("InputFromBanks",this, true), _processName ("ProcessName",this,"PROD"), // // _stripCorrFlagBad ("FlagBad", this, true), _stripCorrFlagNonIntLadders ("FlagNonIntLadders", this, false), _stripCorrUseChipOn ("UseSiChipOn", this, true), _stripCorrRemoveBad ("RemoveBad", this, false), _stripCorrSubtractPedestal("SubtractPedestal", this, true), _stripCorrRemoveUnderThreshold("RemoveUnderThreshold", this, true), _stripCorrNSigmaCut ("NSigmaCut", this, 2.0), _stripCorrDcmsMode ("DcmsMode", this, "DEFAULT"), _stripCorrDcmsOffset ("DcmsOffset", this, -999), _stripCorrDefaultDbName("DefaultDbName",this, "TakeFromCalibrationManager"), _stripCorrPedRun ("PedDBRun", this, -1), _stripCorrPedVersion ("PedDBVersion", this, -1), _stripCorrPedStatus ("PedDBStatus", this, "UNDEFINED"), _stripCorrDeadRun ("DeadDBRun", this, -1), _stripCorrDeadVersion ("DeadDBVersion", this, -1), _stripCorrDeadStatus ("DeadDBStatus", this, "UNDEFINED"), _stripCorrMaskRun ("MaskDBRun", this, -1), _stripCorrMaskVersion ("MaskDBVersion", this, -1), _stripCorrMaskStatus ("MaskDBStatus", this, "UNDEFINED"), _stripCorrIntLadderDB ("IntLadderDB", this, ""), _stripCorrIntLadderDBRun("IntLadderDBRun", this, -1), _stripCorrUseL00PedFit("UseL00PedFit", this, true), _stripCorrL00FitOrder ("L00FitOrder", this, 6), _stripCorrL00FitIter ("L00FitIter", this, 3), _stripCorrL00ADCmax ("L00ADCmax", this, 7.5), _stripCorrLiveDangerouslyAndSkipCalibration( "LiveDangerouslyAndSkipCalibration",this,false), // // _stripCorrInLevel3 ("InLevel3", this, false), _stripCorrPedestalCorrectorAllowed("PedestalCorrectorAllowed", this, true), // Allow rescaling of noise read from DB. Must specify ALL LAYERS! _stripCorrPhiNoiseScale("PhiNoiseScale",this,0,0), _stripCorrZNoiseScale("ZNoiseScale",this,0,0), // // _dataRepCommand ("DataRep", this, SiRecoDataRep::reference().dataRep(), SiDataRep::RUN2V1_3BS), _selectDataRepByBankVersion( "DataRepFromBankVersion", this, false ), _inputStripSetDescription("InputStripSetDescr", this, ""), _inputBanksDescription("InputBanksDescr", this, ""), _readSIXD ("ReadSIXD",this,true), _readISLD ("ReadISLD",this,true), _monitorMode ("MonitorMode", this, true), _useNNDataUnpacker ("UseNNDataUnpacker", this, true), _useNNChipThreshold ("UseNNChipThreshold", this, true), _writeClusterBanks ("OutputBanks", this, true), _outputDescription ("OutputDescr", this, ""), _writeStripBanks ("WriteStripBanks", this, false), _pickClusterFinder ("ClusterFinder", this, "SIMPLE"), _correctClusterCentroids("CorrectClusterCentroids", this, true), _centroidCorrectionModel("CentroidCorrectionModel", this, "DATA"), _oldSimData ("OldSimData", this, false), _pathName ("pathName",this,"default"), _printNClusters ("PrintNClusters", this, false), _generateTestStrips ("GenerateTestData", this, false), _printInputStrips ("PrintInput", this, false), _printOutputClusters ("PrintOutput", this, false), _printOutputClusterBanks("PrintOutputBanks", this, false), _printDebugInfoLevel ("DebugLevel", this, 0 ), _debugRegional ("DebugRegional",this,false), // _phiStripParams( this ), _zStripParams( this ), _thresholdMenus(), _hitResolutionCommand( "HitResoln", this ), // // The new clustering framework // _clusterFinder( 0 ), _phiClusParam( 0 ), _sasClusParam( 0 ), _zClusParam( 0 ), _l00ClusParam( 0 ), _extL00ClusParam( 0 ), _extendedL00Alg("extendedL00Alg", this, true), // // The old clustering framework // _theClusterFinder( 0 ), _theClusterCorrector( 0 ), _userForbidsCali( false ), _userForcesCali( false ), _performCali( true ), _realisticMC( false ), _theStripCorrectorManager( 0 ), _dbCorr( 0 ), _l00Corr( 0 ), _dbNameToPass("ofotl_prd_read") { //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Parameters in main menu //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ commands()->append( &_regionalMode ); commands()->append( &_newFramework ); commands()->append( &_processName ); commands()->append( &_dataRepCommand ); commands()->append( &_selectDataRepByBankVersion ); commands()->append( &_inputDataFromBanks ); commands()->append( &_inputStripSetDescription ); commands()->append( &_inputBanksDescription ); commands()->append( &_readSIXD ); commands()->append( &_readISLD ); commands()->append( &_monitorMode ); commands()->append( &_useNNDataUnpacker ); commands()->append( &_useNNChipThreshold ); commands()->append( &_writeClusterBanks ); commands()->append( &_outputDescription ); commands()->append( &_writeStripBanks); commands()->append( &_pickClusterFinder ); commands()->append( &_correctClusterCentroids ); commands()->append( &_centroidCorrectionModel ); commands()->append( &_oldSimData ); commands()->append( &_pathName ); std::list< std::string > enumNames; enumNames.push_back( "SIMPLE" ); // enumNames.push_back( "THRESHOLD" ); // enumNames.push_back( "ABSTHRESHOLD" ); _pickClusterFinder.initValidList( enumNames ); std::list< std::string > enumNames2; enumNames2.push_back( "NONE" ); enumNames2.push_back( "DATA" ); enumNames2.push_back( "PHYSICAL" ); enumNames2.push_back( "PARAMETERIZED" ); enumNames2.push_back( "NOMAGNETICFIELD" ); _centroidCorrectionModel.initValidList( enumNames2 ); std::list< std::string > enumDcmsNames; enumDcmsNames.push_back( "DEFAULT" ); enumDcmsNames.push_back( "f" ); enumDcmsNames.push_back( "false" ); enumDcmsNames.push_back( "t" ); enumDcmsNames.push_back( "true" ); _stripCorrDcmsMode.initValidList( enumDcmsNames ); _regionalMode.addDescription( "\t\tEnable regionalized clustering. Currently, global clustering\n\ \t\toperates in regional mode. Setting this value to 'false'\n\ \t\tdirects clustering to use the new (global) clustering framework."); _newFramework.addDescription("\t\tUse the new clustering framework"); _processName.addDescription("\tProcess name for input objects"); _selectDataRepByBankVersion.addDescription( "\t\tSelect data rep by input bank version if 'true'.\n\ \t\tOverrides selection via DataRep command." ); _inputDataFromBanks.addDescription( "\t\tSelect input data source:\n\ \t\ttrue = input data from SIXD / ISLD\n\ \t\tfalse = input data from StorableRun2SiStripSet\n\ \t\tin the event record." ); _inputStripSetDescription.addDescription( "\t\tSpecify description of input strip set to use.\n\ \t\tNote: applies only if InputFromBanks = false." ); _inputBanksDescription.addDescription( "\t\tSpecify description of SIXD / ISLD Banks to use.\n\ \t\tNote: applies only if InputFromBanks = true." ); _readSIXD.addDescription( "\t\tRead SIXD bank\n\ \t\tOnly when reading Raw data - does not work when puffing" ); _readISLD.addDescription( "\t\tRead ISLD bank\n\ \t\tOnly when reading Raw data - does not work when puffing" ); _writeClusterBanks.addDescription( "\t\tAppend output objects (strip set, SiClusterSet and\n\ \t\tSiHitSet) to the event record. Note: strip set\n\ \t\tis not appended if InputFromBanks = true." ); _outputDescription.addDescription( "\t\tDescription to use for output hit and cluster sets\n\ \t\twhen InputFromBanks = false." ); _monitorMode.addDescription( "\t\tMonitor Silicon errors, the SiVrbInfoSet is filled\n\ \t\tevery event and a report of errors printed off at\n\ \t\tthe end; also modifies behaviour of NNData bank unpacker"); _useNNDataUnpacker.addDescription( "\t\tUse the correcting/diagnosing bank unpacker.\n\ \t\tOnly valid for data without regionalisation."); _useNNChipThreshold.addDescription( "\t\tUse chip threshold from the databse in NN upacker\n\ \t\tOnly valid with the NN uppacker."); _writeStripBanks.addDescription( "\t\tAppend/attach CORRECTED strip banks. New SVX/ISLD\n\ \t\tbanks are written and the strip set made to point\n\ \t\tto them. This option is available ONLY if strip\n\ \t\tcorrections are enabled"); // _pickClusterFinder.addDescription( // " Specify clustering algorithm. Note if you pick ABS\n\ // then the thresholds specified in the cluster menus\n\ // are absolute rather than relative to sigma noise" ); _pickClusterFinder.addDescription( "\t\tSpecify clustering algorithm. Note that thresholds\n\ \t\tare relative to sigma noise. This option is disabled\n\ \t\tif 'RegionalMode' is false." ); _correctClusterCentroids.addDescription( "\t\tCorrect cluster positions for Hall Effect" ); _centroidCorrectionModel.addDescription( "\t\tSpecify model for Hall Effect correction" ); _centroidCorrectionModel.addDescription( "\t\tCorrect cluster centroids in old simulation data" ); _pathName.addDescription( "\t\tSet path name used in regional tracking" ); //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Sub-menus for new clustering framework. //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ _newPhiMenu.initialize( "NewPhiParam", this ); _newPhiMenu.initTitle( "Phi-strip clustering parameters for new framework" ); _newSasMenu.initialize( "NewSasParam", this ); _newSasMenu.initTitle( "SAS-strip clustering parameters for new framework" ); _newZMenu.initialize( "NewZParam", this ); _newZMenu.initTitle( "Z-strip clustering parameters for new framework" ); _newL00Menu.initialize( "NewL00Param", this ); _newL00Menu.initTitle( "L00 clustering parameters for new framework" ); _extL00Menu.initialize( "ExtL00Param", this ); _extL00Menu.initTitle( "Extended L00 clustering parameters (new framework)" ); commands()->append( &_extendedL00Alg ); _extendedL00Alg.addDescription( "\t\tUse extended L00 strategy when 'true'" ); commands()->append( &_newPhiMenu ); commands()->append( &_newSasMenu ); commands()->append( &_newZMenu ); commands()->append( &_newL00Menu ); commands()->append( &_extL00Menu ); _initNew(); //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Sub-menu for strip correctors //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ commands()->append( &_stripCorrectorMenu ); _stripCorrectorMenu.initialize( "StripCorrectorMenu", this ); _stripCorrectorMenu.initTitle( "Parameters for the strip correction" ); _stripCorrectorMenu.commands()->append( &_stripCorrFlagBad ); _stripCorrectorMenu.commands()->append( &_stripCorrFlagNonIntLadders ); _stripCorrectorMenu.commands()->append( &_stripCorrUseChipOn ); _stripCorrectorMenu.commands()->append( &_stripCorrRemoveBad ); _stripCorrectorMenu.commands()->append( &_stripCorrSubtractPedestal ); _stripCorrectorMenu.commands()->append( &_stripCorrRemoveUnderThreshold ); _stripCorrectorMenu.commands()->append( &_stripCorrNSigmaCut ); _stripCorrectorMenu.commands()->append( &_stripCorrDcmsMode ); _stripCorrectorMenu.commands()->append( &_stripCorrDcmsOffset ); _stripCorrectorMenu.commands()->append( &_stripCorrDefaultDbName ); _stripCorrectorMenu.commands()->append( &_stripCorrPedRun ); _stripCorrectorMenu.commands()->append( &_stripCorrPedVersion ); _stripCorrectorMenu.commands()->append( &_stripCorrPedStatus ); _stripCorrectorMenu.commands()->append( &_stripCorrDeadRun ); _stripCorrectorMenu.commands()->append( &_stripCorrDeadVersion ); _stripCorrectorMenu.commands()->append( &_stripCorrDeadStatus ); _stripCorrectorMenu.commands()->append( &_stripCorrMaskRun ); _stripCorrectorMenu.commands()->append( &_stripCorrMaskVersion ); _stripCorrectorMenu.commands()->append( &_stripCorrMaskStatus ); _stripCorrectorMenu.commands()->append( &_stripCorrIntLadderDB ); _stripCorrectorMenu.commands()->append( &_stripCorrIntLadderDBRun ); _stripCorrectorMenu.commands()->append( &_stripCorrUseL00PedFit ); _stripCorrectorMenu.commands()->append( &_stripCorrL00FitOrder ); _stripCorrectorMenu.commands()->append( &_stripCorrL00FitIter ); _stripCorrectorMenu.commands()->append( &_stripCorrL00ADCmax ); _stripCorrectorMenu.commands()->append( &_stripCorrLiveDangerouslyAndSkipCalibration ); _stripCorrectorMenu.commands()->append( &_stripCorrInLevel3 ); _stripCorrectorMenu.commands()->append( &_stripCorrPedestalCorrectorAllowed ); _stripCorrectorMenu.commands()->append( &_stripCorrPhiNoiseScale ); _stripCorrectorMenu.commands()->append( &_stripCorrZNoiseScale ); _stripCorrFlagBad.addDescription( "\t\tBad channels are flagged, but not removed." ); _stripCorrFlagNonIntLadders.addDescription( "\t\tChannels in non-integrated ladders are flagged bad, but not removed." ); _stripCorrUseChipOn.addDescription( "\t\tUse Chip On to indentify non active and non intergrated ladder for flagging." ); _stripCorrRemoveBad.addDescription( "\t\tADC count for bad channels is set to 0." ); _stripCorrSubtractPedestal.addDescription( "\t\tPedestal is subtracted from the ADC count." ); _stripCorrRemoveUnderThreshold.addDescription( "\t\tStrips with ADC-ped < N*sigma are set to 0." ); _stripCorrNSigmaCut.addDescription( "\t\tSets the N (in sigmas) for the UnderThreshold cut." ); _stripCorrDcmsMode.addDescription( "\t\tDCMS (dynamic common-mode suppression) mode." ); _stripCorrDcmsOffset.addDescription( "\t\tShift in ADC count for the DCMS mode." ); _stripCorrDefaultDbName.addDescription( "\t\tDefault DB name (e.g., ofotl_prd_read)" ); _stripCorrPedRun.addDescription( "\t\tGet pedestals from this DB run (need run/ver/status)." ); _stripCorrPedVersion.addDescription( "\t\tGet pedestals from this DB version (need run/ver/status)." ); _stripCorrPedStatus.addDescription( "\t\tGet pedestals from this DB status (need run/ver/status)." ); _stripCorrDeadRun.addDescription( "\t\tGet bad channels from this DB run (need run/ver/status)." ); _stripCorrDeadVersion.addDescription( "\t\tGet bad channels from this DB version (need run/ver/status)." ); _stripCorrDeadStatus.addDescription( "\t\tGet bad channels from this DB status (need run/ver/status)." ); _stripCorrMaskRun.addDescription( "\t\tGet L00 fit mask from this DB run (need run/ver/status)." ); _stripCorrMaskVersion.addDescription( "\t\tGet L00 fit mask from this DB version (need run/ver/status)." ); _stripCorrMaskStatus.addDescription( "\t\tGet L00 fit mask from this DB status (need run/ver/status)." ); _stripCorrIntLadderDB.addDescription( "\t\tGet list of integrated ladders from hdwdb (ofotl_prd_read)" ); _stripCorrIntLadderDBRun.addDescription( "\t\tCan override runnumber for hdwdb access (-1=use default runnumber)" ); _stripCorrUseL00PedFit.addDescription( "\t\tUse special pedestal fits for L00. See L00FitOrder,\n\ \t\tL00FitIter, L00ADCmax."); _stripCorrL00FitOrder.addDescription( "\t\tSet Chebyshev poly order for L00 pedestal fitting."); _stripCorrL00FitIter.addDescription( "\t\tSet number of iterations for L00 pedestal fitting."); _stripCorrL00ADCmax.addDescription( "\t\tSet max ADC for signal cut in L00 pedestal fitting."); _stripCorrLiveDangerouslyAndSkipCalibration.addDescription( "\t\tDon't do any calibration"); _stripCorrInLevel3.addDescription( "\t\tSet the flag indicating this runs inside Level 3."); _stripCorrPedestalCorrectorAllowed.addDescription( "\t\tAllow/forbid creation of the pedestal corrector, which is a\n\ \t\tsecondary PedestalUpdator that acts after the original\n\ \t\tPedestalUpdator. The first one is associated with\n\ \t\tPROD_PHYSICS_SVX and the second one (which corrects the\n\ \t\tfirst) with FIB_PHYSICS_SVX."); _stripCorrPhiNoiseScale.addDescription( "\t\tCan rescale the noise read from the DB by this multiplicative factor.\n\ \t\tYou must give a value for EACH layer (all 7!)"); _stripCorrZNoiseScale.addDescription( "\t\tCan rescale the noise read from the DB by this multiplicative factor.\n\ \t\tYou must give a value for EACH layer including something for the z-side of L00!"); //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Clustering parameters //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ //------------------------------------------------------ // Command for configuring silicon hit resolutions //------------------------------------------------------ commands()->append( &_hitResolutionCommand ); //------------------------------------------------------ // Sub-menus for clustering parameters //------------------------------------------------------ _phiStripMenu.initialize( "PhiClusParam", this ); commands()->append( &_phiStripMenu ); _phiStripMenu.initTitle( "Clustering params for Phi/SAS strips" ); _phiStripMenu.commands()->append( &_phiStripParams.lowThreshParm() ); _phiStripMenu.commands()->append( &_phiStripParams.maxLengthParm() ); _phiStripMenu.commands()->append( &_phiStripParams.minPeakSepParm() ); _phiStripMenu.commands()->append( &_phiStripParams.minDeltaQParm() ); _zStripMenu.initialize( "ZClusParam", this ); commands()->append( &_zStripMenu ); _zStripMenu.initTitle( "Clustering params for 90-deg Z strips" ); _zStripMenu.commands()->append( &_zStripParams.lowThreshParm() ); _zStripMenu.commands()->append( &_zStripParams.maxLengthParm() ); _zStripMenu.commands()->append( &_zStripParams.minPeakSepParm() ); _zStripMenu.commands()->append( &_zStripParams.minDeltaQParm() ); //------------------------------------------------------ // Cluster thresholds: add a sub-menu to the clustering // parameter menu for each // threshold set //------------------------------------------------------ // Phi-strip clustering thresholds // std::vector & phiThresh = _phiStripParams.clusterThreshList(); for ( int i = 0 ; i < phiThresh.size() ; ++i ) { std::ostringstream menuTitle, menuCommand; if ( i + 1 < phiThresh.size() ) { menuCommand << (i + 1) << "stripThresh"; menuTitle << "Thresholds for " << (i + 1) << " strip clusters"; } else { menuCommand << (i + 1) << "stripThresh"; menuTitle << "Thresholds for " << (i + 1) << " strip or longer clusters"; } _thresholdMenus.push_back( new APPMenu() ); _thresholdMenus.back()->initialize( menuCommand.str().c_str(), this, &_phiStripMenu ); _thresholdMenus.back()->initTitle( menuTitle.str().c_str() ); _phiStripMenu.commands()->append( _thresholdMenus.back() ); _thresholdMenus.back()->commands() ->append( &( phiThresh[i]->peakThreshParm() ) ); _thresholdMenus.back()->commands() ->append( &( phiThresh[i]->sideThreshParm() ) ); _thresholdMenus.back()->commands() ->append( &( phiThresh[i]->qTotThreshParm() ) ); } // Z-strip clustering thresholds // std::vector & zThresh = _zStripParams.clusterThreshList(); for ( int i = 0 ; i < zThresh.size() ; ++i ) { std::ostringstream menuTitle, menuCommand; if ( i + 1 < phiThresh.size() ) { menuCommand << (i + 1) << "stripThresh"; menuTitle << "Thresholds for " << (i + 1) << " strip clusters"; } else { menuCommand << (i + 1) << "stripThresh"; menuTitle << "Thresholds for " << (i + 1) << " strip or longer clusters"; } _thresholdMenus.push_back( new APPMenu() ); _thresholdMenus.back()->initialize( menuCommand.str().c_str(), this, &_zStripMenu ); _thresholdMenus.back()->initTitle( menuTitle.str().c_str() ); _zStripMenu.commands()->append( _thresholdMenus.back() ); _thresholdMenus.back()->commands() ->append( &( zThresh[i]->peakThreshParm() ) ); _thresholdMenus.back()->commands() ->append( &( zThresh[i]->sideThreshParm() ) ); _thresholdMenus.back()->commands() ->append( &( zThresh[i]->qTotThreshParm() ) ); } //----------------------------------------------------------- // Set default clustering parameters //----------------------------------------------------------- _phiStripParams.lowThreshParm().set( 2 ); _phiStripParams.maxLengthParm().set( 32 ); _phiStripParams.minDeltaQParm().set( 10 ); _zStripParams.lowThreshParm().set( 2 ); _zStripParams.maxLengthParm().set( 64 ); _zStripParams.minDeltaQParm().set( 20 ); // Cluster thresholds. // Only peak thresholds are currently implemented. // Set defaults to values used in production clustering. phiThresh[0]->peakThreshParm().set( 4.0 ); phiThresh[1]->peakThreshParm().set( 3.0 ); phiThresh[2]->peakThreshParm().set( 2.0 ); zThresh[0]->peakThreshParm().set( 4.0 ); zThresh[1]->peakThreshParm().set( 3.0 ); zThresh[2]->peakThreshParm().set( 2.0 ); _phiStripParams.setScale( SiRecoDataRep::instance()->dataShift() ); _zStripParams.setScale( SiRecoDataRep::instance()->dataShift() ); //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Parameters in DebugMenu //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ commands()->append( &_debugSubMenu ); _debugSubMenu.initialize("DebugMenu", this); _debugSubMenu.initTitle( "SiClusteringModule debug menu" ) ; _debugSubMenu.commands()->append( &_printNClusters ); _debugSubMenu.commands()->append( &_generateTestStrips ); _debugSubMenu.commands()->append( &_printInputStrips ); _debugSubMenu.commands()->append( &_printOutputClusters ); _debugSubMenu.commands()->append( &_printOutputClusterBanks ); _debugSubMenu.commands()->append( &_printDebugInfoLevel ); _debugSubMenu.commands()->append( &_debugRegional ); // Initialize default parameter set name to "SIMPLE" _parmName.set( "SIMPLE" ); } SiClusteringModule::~SiClusteringModule() { delete _theClusterFinder; delete _theClusterCorrector; for ( int i = 0 ; i < _thresholdMenus.size() ; ++i ) { delete _thresholdMenus[i]; } delete _theStripCorrectorManager; delete _dbCorr; delete _l00Corr; // The new framework // delete _clusterFinder; delete _phiClusParam; delete _sasClusParam; delete _zClusParam; delete _l00ClusParam; delete _extL00ClusParam; } //============================================================== // Operations //============================================================== AppResult SiClusteringModule::beginJob( AbsEvent* aJob ) { //---------------------------------------------------------- // Init and decide whether to correct clusters //---------------------------------------------------------- _theClusterCorrector = new SiClusterCorrector; if ( _correctClusterCentroids.value() ) { _theClusterCorrector->setCorrectClusters( 1 ); } if ( !_correctClusterCentroids.value() ) { _theClusterCorrector->setCorrectClusters( 0 ); } if ( _centroidCorrectionModel.value() == "NONE" ) { _theClusterCorrector->setCentroidCorrectionModel( 0 ); } if ( _centroidCorrectionModel.value() == "PHYSICAL" || _centroidCorrectionModel.value() == "DATA") { _theClusterCorrector->setCentroidCorrectionModel( 1 ); } if ( _centroidCorrectionModel.value() == "PARAMETERIZED" ) { _theClusterCorrector->setCentroidCorrectionModel( 2 ); } if ( _centroidCorrectionModel.value() == "NOMAGNETICFIELD" ) { _theClusterCorrector->setCentroidCorrectionModel( 3 ); } if ( _oldSimData.value() ) { _theClusterCorrector->setOldSimData( 1 ); } _theClusterCorrector->initClusterCorrector(); //---------------------------------------------------------- // Create choosen cluster finder object //---------------------------------------------------------- const AbsSiDetectorNode * siDet = CdfDetector::instance()->getSiDetector(); if ( !_regionalMode.value() ) { _clusterFinder = new SiStratClusterFinder(); _beginJobNew(); } else if ( _pickClusterFinder.value() == "SIMPLE" ) { _theClusterFinder = new SiClusterFinder( _hitResolutionCommand.resolnSet() ); // Set scale here in case user changed parameters // _phiStripParams.setScale( SiRecoDataRep::instance()->dataShift() ); _zStripParams.setScale( SiRecoDataRep::instance()->dataShift() ); _theClusterFinder->setPhiParameters( &_phiStripParams ); _theClusterFinder->setZParameters( &_zStripParams ); //---------------------------------------------------------- // Load detector geometry and cluster corrector into the cluster finder //---------------------------------------------------------- _theClusterFinder->setWaferSet( siDet->getWaferSet() ); _theClusterFinder->setClusterCorrector( _theClusterCorrector ); } // We first determine whether there will be ANY database access at all! // We skip it if: // - user requests that neither pedestal nor status info should // be processed // - user requests that all calibration code be skipped (this // is probably redundant with the above flags) // - we are in the Monte Carlo but the user did not explicitly request // that this request be ignored. _userForbidsCali = ( _stripCorrLiveDangerouslyAndSkipCalibration.value() || ( !_stripCorrFlagBad.value() && !_stripCorrSubtractPedestal.value() ) ); _userForcesCali = false; // need a new talk-to verb for this // The bottom line: if the user forbids calibration, that's it, // regardless of anything else. If she doesn't, then we check whether // we are in the MC. If we are, the calibration is also off, except // if the user forces it specifically for the Monte Carlo (e.g. when // building a `realistic' MC...) // _performCali = !_userForbidsCali; // Final decision is reached ine each event with the following expression: // _performCali = !_userForbidsCali // && (userForcesCali || !AbsEnv::monteFlag() ); // Some public announcements: // if ( _userForbidsCali ) { ERRLOG( ELwarning, "[NOSICAL]" ) << "You are living dangerously and skipping the\n" << " the silicon calibration.\n" << "\t Skipping silicon calibration is not recommended." << endmsg; } if ( _performCali ) { //--- Create the default DB corrector and pass various flags to it. // _dbCorr = new DBCorrector(); _dbCorr->setDoPedestal( _stripCorrSubtractPedestal.value() ); _dbCorr->setDoStatus( _stripCorrFlagBad.value() ); _dbCorr->setDoIntLadders( _stripCorrFlagNonIntLadders.value() ); _dbCorr->setUseChipOn( _stripCorrUseChipOn.value() ); _dbCorr->pickIntLaddersTable( _stripCorrIntLadderDB.value(), _stripCorrIntLadderDBRun.value() ); if ( _stripCorrInLevel3.value() ) { //--- This block allows us to set various flags for Level 3, //--- At the moment there is only one, but there could be more, //--- as necessitated by the Level 3 needs. _dbCorr->setNoPedestalSubtraction(true); } //--- A flag to satisfy the production memory exhaustion paranoia. _dbCorr->setPedestalCorrectorAllowed( _stripCorrPedestalCorrectorAllowed.value() ); // If the user specified a list of factors to rescale the noise from the DB by, // then tell the corrector about it. He must have given us all 8 layers for phi and z. if (_stripCorrPhiNoiseScale.size() !=0 || _stripCorrZNoiseScale.size() !=0) { if (_stripCorrPhiNoiseScale.size() == 8 && _stripCorrZNoiseScale.size() == 8) { std::vector phiScale; for (AbsParmList::ConstIterator i=_stripCorrPhiNoiseScale.begin(); i!=_stripCorrPhiNoiseScale.end(); i++) phiScale.push_back( *i ); std::vector zScale; for (AbsParmList::ConstIterator i=_stripCorrZNoiseScale.begin(); i!=_stripCorrZNoiseScale.end(); i++) zScale.push_back( *i ); _dbCorr->setPhiNoiseScaling( phiScale ); _dbCorr->setZNoiseScaling( zScale ); } else { ERRLOG( ELerror, "Err:86" ) << "@SUB=SiClusteringModule::beginJob" << "You need to give me all 8 layer of both phi and z in your PhiNoiseScale and ZNoiseScale talk-to's\n" << "I will now continue, but with no noise rescaling." << endmsg; } } // Dave Waters : don't even make a L00Corrector unless we need it. // This avoids database access to SiStripMask if ( _stripCorrUseL00PedFit.value() ) { _l00Corr = new L00Corrector( 0, _dbCorr ); _l00Corr->setFitL00pedsWithFallbackToDPS(); _l00Corr->setL00FitOrder( _stripCorrL00FitOrder.value() ); _l00Corr->setL00FitIter( _stripCorrL00FitIter.value() ); _l00Corr->setL00ADCmax( _stripCorrL00ADCmax.value() ); _l00Corr->setStripMasksRun( _stripCorrMaskRun.value() ); _l00Corr->setStripMasksVer( _stripCorrMaskVersion.value() ); _l00Corr->setStripMasksStat( _stripCorrMaskStatus.value() ); // _l00Corr = new DBCorrector(); } _theStripCorrectorManager = new SiStripCorrectorManager(); //--- Retrieve the underlying container for ease of use. (Container is //--- VectorIndexedMap) // SiStripCorrectorManager::collection_type & corrSet = _theStripCorrectorManager->contents(); //--- Iterate over the numerology, and set a SiStripCorrector //--- for each digi code. // const AbsSiNumerology * numerology = siDet->getNumerology(); AbsSiNumerology::ConstIterator h = numerology->begin(); AbsSiNumerology::ConstIterator hend = numerology->end(); for ( ; h!=hend ; ++h ) { // if ( h->getLayer() == 0 && _stripCorrUseL00PedFit.value() ) { // &&& Aaron: SiDigiCode phiCode = h->getPSideDigiCode(); corrSet[phiCode] = _l00Corr; // this is NULL if no L00 ped fits. } else { SiDigiCode phiCode = h->getPSideDigiCode(); corrSet[phiCode] = _dbCorr; // Ditto for Z side SiDigiCode zCode = h->getNSideDigiCode(); corrSet[zCode] = _dbCorr; } } } //---------------------------------------------------------- // Setup the SiVrbInfoSets if required //---------------------------------------------------------- if( _monitorMode.value() ) { SiVrbInfoSet::DetType svxType = SiVrbInfoSet::SVXII, islType = SiVrbInfoSet::ISL; _svxDaqInfo = new SiVrbInfoSet( svxType ); _islDaqInfo = new SiVrbInfoSet( islType ); } return AppResult::OK; } AppResult SiClusteringModule::beginRun( AbsEvent* aRun ) { //------------------------------------------------------------------ // This is where database access would be performed. The database // stores pedestal and strip noise values. //------------------------------------------------------------------ if ( AbsEnv::instance()->monteFlag() && AbsEnv::instance()->runNumber() > 100000 ) { _realisticMC=true; } // PM, Sep 2000: Joe wrote the class RecentCalibrations. A // singleton of this class is registered with the database server // and receives notifications of any changes to the pedestals or hot and // dead channels. Therefore we don't have to do anything here, and // just in every event fetch a const pointers to SiPedInfoSet and // SiDeadInfoSet, and use them. // PM, Oct 2000: however, we sometimes want to pick (run,version,status) // by hand, and that can be optimally done right here. if ( _performCali ) { if ( _realisticMC ) { _userForcesCali = true; } //--- See if we need to create a non-default database access for //--- pedestals in which we pick a non-default (run,version,status) //--- combination. if ( ( _stripCorrPedRun.value() != -1 ) && ( _stripCorrPedVersion.value() != -1 ) && ( _stripCorrPedStatus.value() != "UNDEFINED" ) ) { DBCorrector::pickPedestalTable( _stripCorrPedRun.value(), _stripCorrPedVersion.value(), _stripCorrPedStatus.value() ); //--- We at this point force the calibrations, even in MC! _userForcesCali = true; } //--- See if we need to create a non-default database access for //--- dead channels in which we pick a non-default (run,version,status) //--- combination. if ( ( _stripCorrDeadRun.value() != -1 ) && ( _stripCorrDeadVersion.value() != -1 ) && ( _stripCorrDeadStatus.value() != "UNDEFINED" ) ) { DBCorrector::pickStatusTable( _stripCorrDeadRun.value(), _stripCorrDeadVersion.value(), _stripCorrDeadStatus.value() ); //--- We at this point force the calibrations, even in MC! _userForcesCali = true; } //--- DCMS-on-related stuff std::string dcmsModeVal = _stripCorrDcmsMode.value(); if ( dcmsModeVal != "DEFAULT" ) { if ( dcmsModeVal[0] == 't' ) // t or true { DBCorrector::setDcmsMode( true ); } else // the only other choices are f/false { DBCorrector::setDcmsMode( false ); } } if ( _stripCorrDcmsOffset.value() != -999 ) { DBCorrector::setDcmsOffset( _stripCorrDcmsOffset.value() ); } // --- DSW, 10.02.2002. By default, use the database set in // CalibrationManager. However if this talk-to parameter has // been overridden, use the specified string instead. if ( _stripCorrDefaultDbName.value() == "TakeFromCalibrationManager" ) { PackageManager m; _dbNameToPass = m.defaultID(); } else { _dbNameToPass = _stripCorrDefaultDbName.value(); } // std::cout << "SiClusteringModule::beginRun : _dbNameToPass = " << _dbNameToPass << std::endl; //--- Change the default DB if desired. DBCorrector::setDefaultDbName(_dbNameToPass); _dbCorr->loadCalibrations(); } return AppResult::OK; } AppResult SiClusteringModule::endJob( AbsEvent* aJob ) { std::cout << endl << " SiClusteringModule end job " << std::endl; // AST Jul13-01 add endRun to print out Silicon Errors // if(_monitorMode.value()) { std::cout << endl << "SiVrbInfoSet Error report on Faulty HDIs" << std::endl; _svxDaqInfo->errorReport(); std::cout << endl << std::endl; _islDaqInfo->errorReport(); std::cout << endl << std::endl; delete _svxDaqInfo; delete _islDaqInfo; } return AppResult::OK; } AppResult SiClusteringModule::event( AbsEvent* anEvent ) { if ( _regionalMode.value() ) { return _doRegional( anEvent ); } if ( !_newFramework.value() ) { ERRLOG( ELerror, "Operation not implemented" ) << "@SUB=SiClusteringModule::event" << "New clustering framework not yet implemented. Event skipped." << endmsg; return AppResult::OK; } //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Get the input strip set //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ StorableRun2SiStripSet_h hStrips; StorableRun2SiStripSet_ch chStrips; if ( !_generateTestStrips.value() ) { if ( _inputDataFromBanks.value() ) { StorableRun2SiStripSet * pStrips = new StorableRun2SiStripSet(); StorableRun2SiStripSet & strips = *pStrips; hStrips = pStrips; chStrips = hStrips; strips.set_description( _inputBanksDescription.value() ); strips.setReadSIXD(_readSIXD.value()); strips.setReadISLD(_readISLD.value()); if ( currentRCPID().isValid() ) { strips.set_rcp_id( currentRCPID() ); } // Possibly override data-driven data rep selection // strips.selectDataRepByBankVersion( _selectDataRepByBankVersion.value() ); // Set up which unpacker to use and whether to use chip thresholds // strips.useNNDataUnpacker( _useNNDataUnpacker.value() ); strips.useNNChipThreshold( _useNNChipThreshold.value() ); // Set monitor mode (used by NNData unpacker too) // strips.setMonitorMode( _monitorMode.value() ); if ( _monitorMode.value() ) { strips.setSvxSiVrbInfoSet( _svxDaqInfo ); strips.setIslSiVrbInfoSet( _islDaqInfo ); } // Read SIXD and ISLD banks. // strips.setDefaultDbName(_dbNameToPass); if ( !strips.loadFromBanks( anEvent ) ) { return AppResult::OK; } // Flag readout errors // if ( !AbsEnv::instance()->monteFlag() && strips.bankReadoutError() ) { // errlog( ELwarning, "Readout errors detected in Silicon Raw Banks (SIXD, ISLD)" ) // << "SUB=@SiClusteringModule::event"; // std::bitset<12> errorBits( strips.bankReadoutError() ); // if ( errorBits.test(0) ) errlog << "NOT_CHIP"; // if ( errorBits.test(1) ) errlog << "STRIP_ORDER"; // if ( errorBits.test(2) ) errlog << "CHIP_MISMATCH"; // if ( errorBits.test(3) ) errlog << "INVALID_WORD"; // if ( errorBits.test(4) ) errlog << "NO_EOF"; // if ( errorBits.test(5) ) errlog << "EOR_MISPLACE"; // if ( errorBits.test(6) ) errlog << "CHIP_INVALID"; // if ( errorBits.test(7) ) errlog << "CHIP_COUNT"; // if ( errorBits.test(8) ) errlog << "STATUS_FAULT"; // if ( errorBits.test(9) ) errlog << "DROPPED_READOUT_EOR"; // if ( errorBits.test(10) ) errlog << "UNKNOWN_WORD"; // if ( errorBits.test(11) ) errlog << "CHIP_SIDEERROR"; // errlog << endmsg; if ( 1 == 2 ) { if ( verbose() ) { errlog << "++++++++++++++++++++++++++++++++++++++++++++++"; errlog << "++FULL REPORT OF READOUT ERRORS ON STD::COUT++"; errlog << "++++++++++++++++++++++++++++++++++++++++++++++"; if( _monitorMode.value() ) { _svxDaqInfo->print( std::cout ); _islDaqInfo->print( std::cout ); } else { // set up a temporary Vrb Info Set SiVrbInfoSet svxDaqInfo; SiVrbInfoSet islDaqInfo; SiVrbInfoSet::DetType svxType = SiVrbInfoSet::SVXII, islType = SiVrbInfoSet::ISL; svxDaqInfo.daqInfoSetUp( svxType ); islDaqInfo.daqInfoSetUp( islType ); StorableRun2SiStripSet * throwAwayStripSet = new StorableRun2SiStripSet; throwAwayStripSet->setSvxSiVrbInfoSet( &svxDaqInfo ); throwAwayStripSet->setIslSiVrbInfoSet( &islDaqInfo ); throwAwayStripSet->loadFromBanks( anEvent ); svxDaqInfo.print( std::cout ); islDaqInfo.print( std::cout ); throwAwayStripSet->destroy(); } errlog << "+++++++++++++++++++++++++++++++++++++++++++++"; errlog << "++END, REPORT OF READOUT ERRORS++++++++++++++"; errlog << "+++++++++++++++++++++++++++++++++++++++++++++"; } errlog << "No clustering will be performed"; errlog << endmsg; return AppResult::OK; } } _performCali = !_userForbidsCali && (_userForcesCali || !AbsEnv::instance()->monteFlag() ); if ( _performCali ) { if ( !_correctStrips( strips ) ) { // Something went wrong in the strip correction and // it's meaninless to proceed with clustering. // return AppResult::OK; } if ( _writeStripBanks.value() ) { strips.writeBanks( anEvent, "CORRECTED" ); } } } else { // Get strip set out of the event. In all cases, just // grab the first one satisfying the search criteria. // if ( _inputStripSetDescription.value() == "" ) { EventRecord::ConstIterator iss( anEvent, "StorableRun2SiStripSet","*",_processName.value() ); if ( iss.is_valid() ) { chStrips = iss; } else { return AppResult::OK; } } else { StorableObject::ANDSelector s = StorableObject::SelectByClassName( "StorableRun2SiStripSet" ) && StorableObject::SelectByDescription( _inputStripSetDescription.value() ); EventRecord::ConstIterator iss( anEvent, s ); if ( iss.is_valid() ) { chStrips = iss; } else { return AppResult::OK; } } } } else { // Generate test strip set // StorableRun2SiStripSet * pStrips = new StorableRun2SiStripSet(); _generateStripData( *pStrips ); hStrips = pStrips; chStrips = hStrips; } //----------------------------------------------------------------- // Print input //----------------------------------------------------------------- if ( _printInputStrips.value() ) { std::cout << std::endl << "Input strip data:" << std::endl << *chStrips << std::endl; } //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Create output objects //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ SiClusterSet_h hClusters( new SiClusterSet ); SiHitSet_h hHits( new SiHitSet ); hHits->setClusterSet( hClusters ); hClusters->setStripSet( chStrips ); //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Perform clustering //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ int stat = _clusterFinder->findClusters( *chStrips, *hClusters, *hHits ); if ( stat != 0 ) { ERRLOG( ELerror, "Si clustering error" ) << "@SUB=SiClusteringModule::event" << "findClusters returns " << stat << ". No clusters found" << endmsg; return AppResult::OK; } hClusters->renumber(); hHits->renumber(); //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Print any output information requested //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ if ( _printNClusters.value() ) { std::cout << "SiClusteringModule: " << "Ncluster = " << hClusters->nEntries() << " " << "Nhit = " << hHits->nEntries() << std::endl; } if ( _printOutputClusters.value() ) { std::cout << std::endl << *hHits << std::endl; } //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Deal with output as requested //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ if ( _writeClusterBanks.value() ) { // Set RCP id's of output objects if appropriate // if ( currentRCPID().isValid() ) { hStrips->set_rcp_id( currentRCPID() ); hHits->set_rcp_id( currentRCPID() ); hClusters->set_rcp_id( currentRCPID() ); } //----------------------------------------------------- // First, store the strip set in the event. This // should only be done if the strip set was loaded // from banks. //----------------------------------------------------- if ( _inputDataFromBanks.value() ) { if ( _printDebugInfoLevel.value() > 0 ) { std::cout << "Appending strip set to the event" << std::endl; } hStrips->set_description( "GlobalSI_StripSet" ); anEvent->append( hStrips ); } //---------------------------------------------------- // Now store the clusters and hits //---------------------------------------------------- if ( _printDebugInfoLevel.value() > 0 ) { std::cout << "Appending hit and cluster sets to event" << std::endl; } if ( _inputDataFromBanks.value() ) { hHits->set_description( "GlobalSI_HitSet" ); hClusters->set_description( "Global_SI_ClusterSet" ); } else { hHits->set_description( _outputDescription.value() ); hClusters->set_description( _outputDescription.value() ); } anEvent->append( hClusters ); anEvent->append( hHits ); if ( _printDebugInfoLevel.value() > 0 ) { std::cout << "Finished appending hits and clusters to event" << std::endl; } } return AppResult::OK; } AppResult SiClusteringModule::_doRegional( AbsEvent * anEvent ) { std::string dbm, dbm0; int evntnr; if ( _debugRegional.value() ) { dbm0 = "SiClusteringModule::event("; dbm = _pathName.value()+":"; evntnr = AbsEnv::instance()->trigNumber(); } //----------------------------------------------------------------- // Set up strip data. We can either get data from Trybos banks // (TRYSiStripSet), or from internal memory (SiStripSet). In // principle, we can select which via a talk-to. Since there is // no talk-to, assume that we need to get data from Trybos. // Note that we can generate a small number of test clusters // within an SiStripSet. //----------------------------------------------------------------- // Save the current state of the output stream format and change it to // fixed format const std::ios_base::fmtflags oldopts = std::cout.flags(); std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield ); std::streamsize old_prec = std::cout.precision( 4 ); // Region counter : int regionIndex = 0; // -------------------------------------------------------------------------- // EDM2 implementation of regional tracking. Each region has an associated // GrowResultList, to which the results of tracking inside that region are // appended. The regions themselves are already stored in the GrowResultLists. // --------------------------------------------------------------------------- // Set the Selectors for this path. First, obviously, the class name itself : StorableObject::SelectByClassName class_name( "GrowResultList" ); // and secondly, only GrowResultLists from this path : StorableObject::SelectByDescription description( _pathName.value() ); // Are there any GrowResultLists that fit the bill? If not, then make // one for global tracking : EventRecord::ConstIterator GrowResultListIter( anEvent, class_name && description ); if ( !GrowResultListIter.is_valid() ) { Handle growH( new GrowResultList() ); growH->set_description( _pathName.value() ); Handle universeH( new UniverseRegion() ); growH->push_back( Link( universeH ) ); anEvent->append( universeH ) ; anEvent->append( growH ); } //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ // Main loop over the GrowResultLists. Note that both regional // and global clustering can be performed within this loop, depending // upon the results of the test above, or the regions within the // GrowResultsLists. //--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ for ( EventRecord::ConstIterator GrowResultListIter( anEvent, description && class_name ); GrowResultListIter != anEvent->end() ; ++GrowResultListIter ) { if ( _debugRegional.value() ) { std::cout << dbm0 << evntnr << ") (" << dbm << "): found a GrowResultList with object_id = " << GrowResultListIter->object_id() << " and description = " << GrowResultListIter->description() << std::endl; } ConstHandle GrowResultListCH( GrowResultListIter ); // Only need to do the clustering if the cluster data is not already // in the GrowResultList. This could be the case if the RegionDefModule // ran in "reuseResult"-mode and copied the links // to already existing results into the GrowResultList // GrowResultList::typeIterator hitIter( GrowResultListCH ); if ( _debugRegional.value() ) { if ( hitIter.is_valid() ) { std::cout << dbm0 << evntnr << ") (" << dbm << "): GrowResultList already contains a SiHitSet -> SKIPPING" << std::endl; } } if ( hitIter.is_valid() ) continue; // Find the PhysicsRegion in the GrowResultList. Skip if no PhysicsRegion // is found. GrowResultList::typeIterator physicsIter( GrowResultListCH ); if ( !physicsIter.is_valid() ) continue; if ( _debugRegional.value() ) { std::cout << dbm0 << evntnr << ") (" << dbm << "): GrowResultList contains a link to a " << (*physicsIter)->myType() << std::endl; } const GeometricRegion * gRegion = (*physicsIter)->theGeometricRegion(); ++regionIndex; //------------------------------------------------------ // Find / configure the input data //------------------------------------------------------ // We need both of these pointers to be able to handle both the // case in which the strip set is obtained from the event record, // and the case in which it is created using the raw data banks, // as specified by the user. // StorableRun2SiStripSet * pStripSet = 0; const StorableRun2SiStripSet * cpStripSet = 0; if ( !_generateTestStrips.value() ) { // Read data from the event. // if ( _inputDataFromBanks.value() ) { pStripSet = new StorableRun2SiStripSet(); pStripSet->set_description( _inputBanksDescription.value() ); pStripSet->setReadSIXD(_readSIXD.value()); pStripSet->setReadISLD(_readISLD.value()); cpStripSet = pStripSet; // Possibly override data-driven data rep selection pStripSet-> selectDataRepByBankVersion( _selectDataRepByBankVersion.value() ); // Set up which unpacker to use and whether to use chip thresholds pStripSet->useNNDataUnpacker( _useNNDataUnpacker.value() ); pStripSet->useNNChipThreshold( _useNNChipThreshold.value() ); // Set monitor mode (used by NNData unpacker too) pStripSet->setMonitorMode( _monitorMode.value() ); // AST Jul13-01 set the SiVrbInfoSets if Monitoring mode is //requested if( _monitorMode.value() ) { pStripSet->setSvxSiVrbInfoSet( _svxDaqInfo ); pStripSet->setIslSiVrbInfoSet( _islDaqInfo ); } // Read data from SIXD and ISLD banks. This is the // normal case. // // DSW 21.01.99 Pass region for regional strip set building : // if ( !pStripSet->loadFromBanks( anEvent, *gRegion ) ) { pStripSet->destroy(); continue; // bail if no raw data banks } // Flag readout errors here: if ( !AbsEnv::instance()->monteFlag() && pStripSet->bankReadoutError() ) { // errlog( ELwarning, "Readout errors detected in Silicon Raw Banks (SIXD, ISLD)" ) // << "SUB=@SiClusteringModule::event"; // std::bitset<12> errorBits(pStripSet->bankReadoutError()); // if (errorBits.test(0)) errlog << "NOT_CHIP"; // if (errorBits.test(1)) errlog << "STRIP_ORDER"; // if (errorBits.test(2)) errlog << "CHIP_MISMATCH"; // if (errorBits.test(3)) errlog << "INVALID_WORD"; // if (errorBits.test(4)) errlog << "NO_EOF"; // if (errorBits.test(5)) errlog << "EOR_MISPLACE"; // if (errorBits.test(6)) errlog << "CHIP_INVALID"; // if (errorBits.test(7)) errlog << "CHIP_COUNT"; // if (errorBits.test(8)) errlog << "STATUS_FAULT"; // if (errorBits.test(9)) errlog << "DROPPED_READOUT_EOR"; // if (errorBits.test(10)) errlog << "UNKNOWN_WORD"; // if (errorBits.test(11)) errlog << "CHIP_SIDEERROR"; // errlog << endmsg; // if (errorBits.test(1)) if ( 1 == 2 ) { if ( _verbose.value() ) { errlog << "++++++++++++++++++++++++++++++++++++++++++++++"; errlog << "++FULL REPORT OF READOUT ERRORS ON STD::COUT++"; errlog << "++++++++++++++++++++++++++++++++++++++++++++++"; if( _monitorMode.value() ) { _svxDaqInfo->print( std::cout ); _islDaqInfo->print( std::cout ); } else { // set up a temporary Vrb Info Set SiVrbInfoSet svxDaqInfo; SiVrbInfoSet islDaqInfo; SiVrbInfoSet::DetType svxType = SiVrbInfoSet::SVXII, islType = SiVrbInfoSet::ISL; svxDaqInfo.daqInfoSetUp( svxType ); islDaqInfo.daqInfoSetUp( islType ); StorableRun2SiStripSet * throwAwayStripSet = new StorableRun2SiStripSet; throwAwayStripSet->setSvxSiVrbInfoSet( &svxDaqInfo ); throwAwayStripSet->setIslSiVrbInfoSet( &islDaqInfo ); throwAwayStripSet->setReadSIXD(_readSIXD.value()); throwAwayStripSet->setReadISLD(_readISLD.value()); throwAwayStripSet->loadFromBanks( anEvent, *gRegion ); svxDaqInfo.print( std::cout ); islDaqInfo.print( std::cout ); throwAwayStripSet->destroy(); } errlog << "+++++++++++++++++++++++++++++++++++++++++++++"; errlog << "++END, REPORT OF READOUT ERRORS++++++++++++++"; errlog << "+++++++++++++++++++++++++++++++++++++++++++++"; } errlog << "No clustering will be performed"; errlog << endmsg; pStripSet->destroy();; return AppResult::OK; } } // Apply pedestal and hot/dead/half-dead channel corrections. // _performCali = !_userForbidsCali && (_userForcesCali || !AbsEnv::instance()->monteFlag() ); if ( _performCali ) { if ( !_correctStrips( *pStripSet ) ) { // //--- Something went wrong in the strip correction and //--- it's meaningless to proceed with clustering. // pStripSet->destroy(); // clean up memory! return AppResult::OK; } if ( _writeStripBanks.value()) { if ( currentRCPID().isValid() ) { pStripSet->set_rcp_id( currentRCPID() ); } pStripSet->writeBanks( anEvent, "CORRECTED" ); } } } else { // Try to find input data in a strip set previously stored // in the event record // StorableObject::SelectByClassName nameSel( "StorableRun2SiStripSet" ); if ( _inputStripSetDescription.value() == "" ) { // No description string specified. Just grab // the first strip set in the event // EventRecord::ConstIterator i( anEvent, nameSel ); if ( i.is_valid() ) { StorableRun2SiStripSet_ch ch( i ); cpStripSet = &*ch; } else { // No input data for this event // return AppResult::OK; } } else { // Find the strip set with the specified description // EventRecord::ConstIterator i( anEvent, nameSel && StorableObject:: SelectByDescription( _inputStripSetDescription.value() ) ); if ( i.is_valid() ) { StorableRun2SiStripSet_ch ch( i ); cpStripSet = &*ch; } else { // No input data for this event // return AppResult::OK; } } } } else { // Generate test data internally. // pStripSet = new StorableRun2SiStripSet(); _generateStripData( *pStripSet ); cpStripSet = pStripSet; } _theClusterFinder->setStripSet( cpStripSet ); //----------------------------------------------------------------- // Print input strips if requested. //----------------------------------------------------------------- if ( _printInputStrips.value() ) { std::cout << std::endl << "Input strip data:" << std::endl << *cpStripSet << std::endl; } //----------------------------------------------------------------- // Create output objects for the results of clustering. //----------------------------------------------------------------- SiHitSet * hitSet = new SiHitSet(); SiClusterSet * clusterSet = new SiClusterSet(); //----------------------------------------------------------------- // Now create links amonst the hit set, the cluster set and the // strip set.. //----------------------------------------------------------------- hitSet->setClusterSet( Link( clusterSet ) ); clusterSet->setStripSet( ConstLink( cpStripSet ) ); //----------------------------------------------------------------- // Point cluster finder to output objects //----------------------------------------------------------------- _theClusterFinder->setClusterSet( clusterSet ); _theClusterFinder->setHitSet( hitSet ); //----------------------------------------------------------------- // Perform clustering (regional or global) //----------------------------------------------------------------- _theClusterFinder->findClusters(); hitSet->renumber(); // re-number the hit id's clusterSet->renumber(); // and the cluster id's //----------------------------------------------------------------- // Print output if requested. //----------------------------------------------------------------- if ( _printNClusters.value() ) { std::cout << "SiClusteringModule: " << "Ncluster = " << clusterSet->nEntries() << " " << "Nhit = " << hitSet->nEntries() << std::endl; } if ( _printOutputClusters.value() ) { std::cout << std::endl << *hitSet << std::endl; } //--------------------------------------------------------------- // ... make histograms, etc.... //--------------------------------------------------------------- //--------------------------------------------------------------- // Save cluster bank if necessary, delete input // and output objects //--------------------------------------------------------------- if ( _writeClusterBanks.value() ) { // Set RCP id's of output objects if appropriate // if ( currentRCPID().isValid() ) { pStripSet->set_rcp_id( currentRCPID() ); hitSet->set_rcp_id( currentRCPID() ); clusterSet->set_rcp_id( currentRCPID() ); } //----------------------------------------------------- // First, store the strip set in the event. This // should not be done if the strip set was obtained // directly from the event, rather than created // in this module from raw data banks or internally // generated data. //----------------------------------------------------- if ( _inputDataFromBanks.value() ) { if ( _printDebugInfoLevel.value() > 0 ) { std::cout << "Appending strip set to the event" << std::endl; } // Set an appropriate description : // if ( &gRegion->myType() == &WorldRegion::_myType ) { pStripSet->set_description( "GlobalSI_StripSet" ); } else { pStripSet->set_description( "RegionalSI_StripSet" ); } // Get the GenericConstantHandle back in order to add to the // regional GrowResultLists : // StorableRun2SiStripSet_h hStripSet( pStripSet ); if ( currentRCPID().isValid() ) { hStripSet->set_rcp_id( currentRCPID() ); } GenericConstHandle pStripSetGCH = anEvent->append( hStripSet ); // Append the strip set to the GrowResultList for this region : // GrowResultListCH->push_back( Link( const_cast( pStripSetGCH.operator->() ) ) ); } //--------------------------------------------------------- // Now the clustering results (SiHitSet and SiClusterSet) //--------------------------------------------------------- if ( _printDebugInfoLevel.value() > 0 ) { std::cout << "Writing cluster data to persistent storage" << std::endl; } // Set an appropriate description : // if ( &gRegion->myType() == &WorldRegion::_myType ) { // Use the description string specified by the user if // the input data was obtained from a strip set // already stored in the event record (i.e., not // created by this module from raw data banks or // internally generated test data. Otherwise, use // the normal defaults. // if ( _inputDataFromBanks.value() ) { hitSet->set_description( "GlobalSI_HitSet" ); clusterSet->set_description( "GlobalSI_ClusterSet" ); } else { hitSet->set_description( _outputDescription.value() ); clusterSet->set_description( _outputDescription.value() ); } } else { hitSet->set_description( "RegionalSI_HitSet" ); clusterSet->set_description( "RegionalSI_ClusterSet" ); } Handle siHitSetH( hitSet ); if ( currentRCPID().isValid() ) { siHitSetH->set_rcp_id( currentRCPID() ); } GenericConstHandle pSiHitSetGCH= anEvent->append( siHitSetH ); Handle siClusterSetH( clusterSet ); anEvent->append( siClusterSetH ); // Append the cluster data to the GrowResultList for this region : // GrowResultListCH->push_back( Link( const_cast( pSiHitSetGCH.operator->() ) ) ); if ( _printDebugInfoLevel.value() > 0 ) { std::cout << "Finished writing hit data to persistent storage" << std::endl; } } else { if ( pStripSet ) { pStripSet->destroy(); } hitSet->destroy(); clusterSet->destroy(); } } //----------------------------------------------------------------- // Done. //----------------------------------------------------------------- // Return output stream to its original format // std::cout.precision(old_prec); std::cout.flags(oldopts); return AppResult::OK; } AppModule* SiClusteringModule::clone(const char* cloneName) { return new SiClusteringModule( cloneName, "this is a clone SiClusteringModule" ); } //----------------------------------------------------------------------- // In the event of no Trybos data, generate some fake clusters. These // clusters are taken from real data. //----------------------------------------------------------------------- void SiClusteringModule::_generateStripData( SiStripSet & stripSet ) { std::vector dataList; DataCluster data; //------------------------------------------------------------- // Data on barrel 0, wedge 0, layer 0, phi side //------------------------------------------------------------- data.detCode.setBarrel( 0 ); data.detCode.setHalfLadder( 0 ); data.detCode.setPhiWedge( 0 ); data.detCode.setLayer( 0 ); data.detCode.setLadder( 0 ); data.detCode.setPnSide( 0 ); data.firstStrip = 10; data.charge = new std::list; data.charge->push_back( 4 ); data.charge->push_back( 6 ); data.charge->push_back( 17 ); data.charge->push_back( 16 ); dataList.push_back( data ); data.firstStrip = 20; data.charge = new std::list; data.charge->push_back( 4 ); data.charge->push_back( 7 ); data.charge->push_back( 5 ); data.charge->push_back( 7 ); data.charge->push_back( 6 ); dataList.push_back( data ); data.firstStrip = 30; data.charge = new std::list; data.charge->push_back( 20 ); data.charge->push_back( 42 ); dataList.push_back( data ); data.firstStrip = 35; data.charge = new std::list; data.charge->push_back( 2 ); data.charge->push_back( 2 ); data.charge->push_back( 2 ); dataList.push_back( data ); data.firstStrip = 40; data.charge = new std::list; data.charge->push_back( 3 ); data.charge->push_back( 21 ); data.charge->push_back( 11 ); dataList.push_back( data ); data.firstStrip = 50; data.charge = new std::list; data.charge->push_back( 13 ); dataList.push_back( data ); data.firstStrip = 60; data.charge = new std::list; data.charge->push_back( 31 ); data.charge->push_back( 3 ); data.charge->push_back( 53 ); data.charge->push_back( 29 ); data.charge->push_back( 23 ); data.charge->push_back( 8 ); dataList.push_back( data ); data.firstStrip = 70; data.charge = new std::list; data.charge->push_back( 17 ); data.charge->push_back( 10 ); data.charge->push_back( 11 ); dataList.push_back( data ); data.firstStrip = 80; data.charge = new std::list; data.charge->push_back( 15 ); data.charge->push_back( 9 ); data.charge->push_back( 52 ); data.charge->push_back( 85 ); dataList.push_back( data ); //------------------------------------------------------------- // Data on barrel 0, wedge 2, layer 3, phi side //------------------------------------------------------------- data.detCode.setBarrel( 0 ); data.detCode.setHalfLadder( 1 ); data.detCode.setPhiWedge( 2 ); data.detCode.setLayer( 3 ); data.detCode.setLadder( 0 ); data.detCode.setPnSide( 0 ); data.firstStrip = 10; data.charge = new std::list; data.charge->push_back( 15 ); data.charge->push_back( 6 ); data.charge->push_back( 11 ); data.charge->push_back( 4 ); dataList.push_back( data ); data.firstStrip = 20; data.charge = new std::list; data.charge->push_back( 9 ); data.charge->push_back( 52 ); data.charge->push_back( 75 ); data.charge->push_back( 46 ); data.charge->push_back( 18 ); dataList.push_back( data ); data.firstStrip = 30; data.charge = new std::list; data.charge->push_back( 3 ); data.charge->push_back( 7 ); data.charge->push_back( 3 ); data.charge->push_back( 4 ); data.charge->push_back( 11 ); dataList.push_back( data ); data.firstStrip = 40; data.charge = new std::list; data.charge->push_back( 8 ); data.charge->push_back( 42 ); data.charge->push_back( 25 ); data.charge->push_back( 25 ); data.charge->push_back( 4 ); data.charge->push_back( 1 ); dataList.push_back( data ); data.firstStrip = 50; data.charge = new std::list; data.charge->push_back( 5 ); data.charge->push_back( 26 ); data.charge->push_back( 2 ); data.charge->push_back( 12 ); data.charge->push_back( 146 ); data.charge->push_back( 43 ); dataList.push_back( data ); data.firstStrip = 60; data.charge = new std::list; data.charge->push_back( 5 ); data.charge->push_back( 26 ); data.charge->push_back( 2 ); data.charge->push_back( 2 ); data.charge->push_back( 146 ); data.charge->push_back( 43 ); dataList.push_back( data ); data.firstStrip = 70; data.charge = new std::list; data.charge->push_back( 5 ); data.charge->push_back( 26 ); data.charge->push_back( 2 ); data.charge->push_back( 2 ); data.charge->push_back( 2 ); data.charge->push_back( 146 ); dataList.push_back( data ); //------------------------------------------------------------- // Data on barrel 0, wedge 2, layer 2, Z side (SAS) //------------------------------------------------------------- data.detCode.setBarrel( 0 ); data.detCode.setHalfLadder( 1 ); data.detCode.setPhiWedge( 2 ); data.detCode.setLayer( 2 ); data.detCode.setLadder( 0 ); data.detCode.setPnSide( 1 ); data.firstStrip = 10; data.charge = new std::list; data.charge->push_back( 15 ); data.charge->push_back( 6 ); data.charge->push_back( 11 ); data.charge->push_back( 4 ); dataList.push_back( data ); data.firstStrip = 20; data.charge = new std::list; data.charge->push_back( 9 ); data.charge->push_back( 52 ); data.charge->push_back( 75 ); data.charge->push_back( 46 ); data.charge->push_back( 18 ); dataList.push_back( data ); data.firstStrip = 30; data.charge = new std::list; data.charge->push_back( 3 ); data.charge->push_back( 7 ); data.charge->push_back( 3 ); data.charge->push_back( 4 ); data.charge->push_back( 11 ); dataList.push_back( data ); //------------------------------------------------------------- // Data on barrel 0, wedge 2, layer 3, phi side //------------------------------------------------------------- data.detCode.setBarrel( 0 ); data.detCode.setHalfLadder( 1 ); data.detCode.setPhiWedge( 2 ); data.detCode.setLayer( 3 ); data.detCode.setLadder( 0 ); data.detCode.setPnSide( 1 ); data.firstStrip = 10; data.charge = new std::list; data.charge->push_back( 15 ); data.charge->push_back( 6 ); data.charge->push_back( 11 ); data.charge->push_back( 4 ); dataList.push_back( data ); data.firstStrip = 20; data.charge = new std::list; data.charge->push_back( 9 ); data.charge->push_back( 52 ); data.charge->push_back( 75 ); data.charge->push_back( 46 ); data.charge->push_back( 18 ); dataList.push_back( data ); data.firstStrip = 30; data.charge = new std::list; data.charge->push_back( 3 ); data.charge->push_back( 7 ); data.charge->push_back( 3 ); data.charge->push_back( 4 ); data.charge->push_back( 11 ); dataList.push_back( data ); //------------------------------------------- // Fill strip set with the above data //------------------------------------------- SiStrip strip; std::vector::iterator iter; SiStripSet::Iterator stripIter; for ( iter = dataList.begin() ; iter != dataList.end() ; ++iter ) { std::list::iterator qiter; int istrip; for ( qiter = (*iter).charge->begin(), istrip = (*iter).firstStrip ; qiter != (*iter).charge->end() ; ++qiter, ++istrip ) { strip.setStripNumber( istrip ); strip.setPulseHeight( *qiter ); stripSet.accumulate( (*iter).detCode, strip ); } delete (*iter).charge ; } return; } //------------------------------------------------------------- // Private routine to perform all strip corrections. // P. Maksimovic, Oct 2000. Changes for DBInfoSet, March 2001. // Jun 2001: changes to bail out if in MC we fail to unpack DB info. // Dec 2001: rewritten to allow both DBCorrector and L00Corrector, which // are created in the beginJob(). // Feb 2002: moving the creation of dbInfoSet into loadCalibration() from // DBCorrector's constructor into this method, so that we wait // for the first event to create it. Therefore not only we'll // immediately retrieve the right calibration, but we can also // test on AbsEnv::monteFlag() before this method and in fact it // won't even be called if we are in MC and no run has been picked // by hand... //------------------------------------------------------------- bool SiClusteringModule::_correctStrips( SiStripSet & stripSet ) { // //--- We are asked to do something about the strip correction. //--- (We can add more flags that can be explicitly set here //--- to control the behavior of correctors.) //--- Check whether we have a DBInfoSet to correct with. If not, //--- we're done in here. Note that DBCorrector just forwards calls //--- to MostRecentSiCalibration (but in this way we are more decoupled). //--- If both are false, the global _dbInfoSet was not even created, and //--- we'll avoid even making a DBCorrector which will try to make it //--- and fail. // if ( !_dbCorr ) { return false; } //--- Ensure that the dbInfoSet has been created and loaded //--- from the database. If this is the first event, we'll //--- create the dbInfoSet and all of the flags set in beginJob() and //--- beginRun() will be in effect. // //if ( !_dbCorr->loadCalibrations() ) //{ // return false; //} if ( _dbCorr->hasBadTables() ) { // Uh-oh! We need the calibrations but one of the tables // has dataStatus == "BAD". The silicon was integrated but // not biased, and the data will be junk. We have to // terminate the processing of this event. // ERRLOG( ELinfo, "[BAD_SI_TABLES]" ) << "At least one silicon DB table is marked as BAD.\n" << "\t Event skipped." << endmsg; return false; } //--- At this point it is known whether we were lucky enough to have //--- fished something out from the DB. // bool validPedestal = _dbCorr->hasValidPedestal(); bool validStatus = _dbCorr->hasValidStatus(); if ( !validPedestal && !validStatus ) { ERRLOG( ELerror, "[SI_PEDESTAL_AND_SI_STATUS_INVALID]" ) << "Pedestals and Status updator objects (used by db Corrector)" << " are invalid.\n" << "\t Strip corrections are NOT applied." << endmsg; return false; } if ( !_dbCorr->isValid() ) { ERRLOG( ELerror, "[DBCORRECTOR_INVALID]" ) << "Silicon DBCorrector was invalid.\n" << "\t Strip corrections are NOT applied." << endmsg; return false; } if ( _stripCorrFlagBad.value() ) { if ( validStatus ) { _dbCorr->setZeroBadStrip( _stripCorrRemoveBad.value() ); } else { ERRLOG( ELerror, "[SI_STATUS_INVALID]" ) << "Status updator object (used by db Corrector) is invalid.\n" << "\t Bad channels are NOT flagged." << endmsg; return false; } } if ( _stripCorrSubtractPedestal.value() ) { if ( validPedestal ) { _dbCorr->setRemoveUnderThreshold( _stripCorrRemoveUnderThreshold.value() ); _dbCorr->setNSigmaCut( _stripCorrNSigmaCut.value() ); } else { ERRLOG( ELerror, "[SI_PEDESTAL_INVALID]" ) << "Pedestal updator object (used by db Corrector) is invalid.\n" << "\t Strip pedestals are NOT subtracted." << endmsg; return false; // error logger error } } //--- Finally, if this is a Monte Carlo, prevent subtraction of pedestals. if ( AbsEnv::instance()->monteFlag() ) { _dbCorr->setNoPedestalSubtraction( true ); } //--- Apply corrections to this strip set. _theStripCorrectorManager->correctStripSet( stripSet ); return true; // good for clustering! } //---------------------------------------------------------------------------- // Initialization functions for new clustering framework. // The initialization procedure includes: // o _initNew: // o initializing menus, clustering parameters // o _beginJobNew: // o creating and initializing clustering algorithm objects // o filling the cluster finder with algorithm objects // void SiClusteringModule::_initNew() { // First initialize parameters and menus // // Phi cluster menu and defaults // _phiClusParam = new SiPhiTSCluStrategy::ClusteringParam( this ); _phiClusParam->appendCommands( _newPhiMenu, this ); _phiClusParam->lowThreshParm().set( 2 ); _phiClusParam->maxLengthParm().set( 32 ); _phiClusParam->minDeltaQParm().set( 10 ); _phiClusParam->setScale( SiRecoDataRep::instance()->dataShift() ); const std::vector & phiThresh = _phiClusParam->threshList(); phiThresh[0]->peakThreshParm().set( 4.0 ); phiThresh[1]->peakThreshParm().set( 3.0 ); phiThresh[2]->peakThreshParm().set( 2.0 ); // Small angle stereo menu and cluster defaults // _sasClusParam = new SiSasTSCluStrategy::ClusteringParam( this ); _sasClusParam->appendCommands( _newSasMenu, this ); _sasClusParam->lowThreshParm().set( 2 ); _sasClusParam->maxLengthParm().set( 32 ); _sasClusParam->minDeltaQParm().set( 10 ); _sasClusParam->setScale( SiRecoDataRep::instance()->dataShift() ); const std::vector & sasThresh = _sasClusParam->threshList(); sasThresh[0]->peakThreshParm().set( 4.0 ); sasThresh[1]->peakThreshParm().set( 3.0 ); sasThresh[2]->peakThreshParm().set( 2.0 ); // 90-degree stereo menu and cluster defaults // _zClusParam = new SiZTSCluStrategy::ClusteringParam( this ); _zClusParam->appendCommands( _newZMenu, this ); _zClusParam->lowThreshParm().set( 2 ); _zClusParam->maxLengthParm().set( 64 ); _zClusParam->minDeltaQParm().set( 20 ); _zClusParam->setScale( SiRecoDataRep::instance()->dataShift() ); const std::vector & zThresh = _zClusParam->threshList(); zThresh[0]->peakThreshParm().set( 4.0 ); zThresh[1]->peakThreshParm().set( 3.0 ); zThresh[2]->peakThreshParm().set( 2.0 ); // L00 menu and cluster defaults // _l00ClusParam = new SiPhiTSCluStrategy::ClusteringParam( this ); _l00ClusParam->appendCommands( _newL00Menu, this ); _l00ClusParam->lowThreshParm().set( 2 ); _l00ClusParam->maxLengthParm().set( 32 ); _l00ClusParam->minDeltaQParm().set( 10 ); _l00ClusParam->setScale( SiRecoDataRep::instance()->dataShift() ); const std::vector & l00Thresh = _l00ClusParam->threshList(); l00Thresh[0]->peakThreshParm().set( 4.0 ); l00Thresh[1]->peakThreshParm().set( 3.0 ); l00Thresh[2]->peakThreshParm().set( 2.0 ); // Extended L00 menu and cluster defaults // _extL00ClusParam = new SiExtTSCluStrategy::ClusteringParam( this ); _extL00ClusParam->appendCommands( _extL00Menu, this ); _extL00ClusParam->lowThreshParm().set( 2 ); _extL00ClusParam->maxLengthParm().set( 5 ); _extL00ClusParam->minDeltaQParm().set( 10 ); _extL00ClusParam->onlyGoodStrips.set( true ); _extL00ClusParam->maxQtotal.set( 100 ); _extL00ClusParam->maxQstrip.set( 50 ); _extL00ClusParam->maxNoisePeakStrip.set( 3.5 ); _extL00ClusParam->minDistToNextClus.set( 5 ); _extL00ClusParam->setScale( SiRecoDataRep::instance()->dataShift() ); const std::vector & extL00Thresh = _extL00ClusParam->threshList(); extL00Thresh[0]->peakThreshParm().set( 4.0 ); extL00Thresh[1]->peakThreshParm().set( 3.0 ); extL00Thresh[2]->peakThreshParm().set( 2.0 ); } void SiClusteringModule::_beginJobNew() { // Set the scale for all the clustering parameters. This is needed // in case the parameters were changed by the user. // const SiDataShift & dataShift = SiRecoDataRep::instance()->dataShift(); _phiClusParam->setScale( dataShift ); _sasClusParam->setScale( dataShift ); _zClusParam->setScale( dataShift ); if ( _extendedL00Alg.value() ) { _extL00ClusParam->setScale( dataShift ); } else { _l00ClusParam->setScale( dataShift ); } // Get other data needed by clustering algorithms // const AbsSiDetectorNode * det = CdfDetector::instance()->getSiDetector(); const CdfHalfLadderSet * ladderSet = det->getWaferSet(); const AbsSiNumerology * numer = det->getNumerology(); const SiDataRep & dataRep = SiRecoDataRep::instance()->dataRep(); const PrecisionSet & precisionSet = *PrecisionSet::instance(); const SiHitResolutionSet & resolnSet = _hitResolutionCommand.resolnSet(); SiStratClusterFinder::AlgorithmMap & algs = _clusterFinder->algorithms(); // Loop over detectors and create cluster finding strategies // for ( AbsSiNumerology::ConstIterator i = numer->begin(), iend = numer->end() ; i != iend ; ++i ) { const CdfHalfLadder & halflad = *ladderSet->find( *i ); SiDigiCode dcode = *i; int layer = dcode.getLayer(); // Phi-side strategy // Treat L00 and other layers separately // dcode.setPnSide( SiDigiCode::PHI_SIDE ); if ( layer > 0 ) { float centCorr = _theClusterCorrector ->correctAxialClusterCentroid( dcode, float( 0 ) ); algs[dcode] = new SiPhiTSCluStrategy( dcode, halflad, _phiClusParam, dataRep, centCorr, resolnSet.resolution( layer, true ), SiHitSet::sortByIncrLocal( dcode ), precisionSet.rphi()[layer] ); } else { float centCorr = _theClusterCorrector ->correctAxialClusterCentroid( dcode, float( 0 ) ); if ( _extendedL00Alg.value() ) { algs[dcode] = new SiExtTSCluStrategy( dcode, halflad, _extL00ClusParam, dataRep, centCorr, resolnSet.resolution( layer, true ), SiHitSet::sortByIncrLocal( dcode ), precisionSet.rphi()[layer] ); } else { algs[dcode] = new SiPhiTSCluStrategy( dcode, halflad, _l00ClusParam, dataRep, centCorr, resolnSet.resolution( layer, true ), SiHitSet::sortByIncrLocal( dcode ), precisionSet.rphi()[layer] ); } } // Z-side strategy // dcode.setPnSide( SiDigiCode::Z_SIDE ); bool isSas = ( halflad.getZStripSpecification()->getStereoAngle() < 1 ); if ( isSas ) { float centCorr = _theClusterCorrector ->correctSASClusterCentroid( dcode, float ( 0 ) ); algs[dcode] = new SiSasTSCluStrategy( dcode, halflad, _sasClusParam, dataRep, centCorr, resolnSet.resolution( layer, false ), SiHitSet::sortByIncrLocal( dcode ), precisionSet.stereo()[layer] ); } else { float centCorr = _theClusterCorrector ->correctZClusterCentroid( dcode, float( 0 ) ); int mult = halflad.getMultiplexing(); algs[dcode] = new SiZTSCluStrategy( dcode, halflad, _zClusParam, dataRep, centCorr, resolnSet.resolution( layer, false ), halflad.getMultiplexing(), SiHitSet::sortByIncrLocal( dcode ), precisionSet.stereo()[layer] ); } } }