All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
FPCCDClustering.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 #define ROOT_DEBUG 1
3 /**
4 If you don't want to generate information of position resolution of generated TrackerHits,
5 set 0.
6 */
7 
8 #include "FPCCDClustering.h"
9 #include "FPCCDPixelHit.h"
10 #include "FPCCDData.h"
11 
12 #include <iostream>
13 
14 #include <EVENT/MCParticle.h>
15 #include <IMPL/TrackerHitImpl.h>
16 #include <IMPL/TrackerHitPlaneImpl.h>
17 #include <gear/ZPlanarParameters.h>
18 #include <gear/ZPlanarLayerLayout.h>
19 #include <UTIL/CellIDEncoder.h>
20 #include "UTIL/LCTOOLS.h"
21 
22 #include <ILDCellIDEncoding.h>
23 #include "UTIL/LCTrackerConf.h"
24 #include <UTIL/ILDConf.h>
25 
26 #include <gsl/gsl_randist.h>
27 
28 #include <cmath>
29 #include <algorithm>
30 #include <sstream>
31 #include <map>
32 #include <vector>
33 #include <list>
34 #include <utility>
35 #include <stack>
36 
37 #include "TFile.h"
38 #include "TTree.h"
39 #include "TMath.h"
40 #include <TVector3.h>
41 
42 
43 #include "CLHEP/Vector/LorentzVector.h"
44 #include <marlin/Global.h>
45 #include <EVENT/Track.h>
46 #include <gear/GEAR.h>
47 #include <gear/BField.h>
48 
49 
50 using namespace lcio ;
51 using namespace marlin ;
52 using namespace std ;
53 
55 
56 // =====================================================================
57 FPCCDClustering::FPCCDClustering() : Processor("FPCCDClustering") {
58 
59  // modify processor description
60  _description = "FPCCDClustering icteats TrackerHits from FPCCDPixelHits" ;
61 
62  // register steering parameters: name, description, class-variable, default value
63 
64  registerProcessorParameter( "Debug",
65  "Debugging option",
66  _debug,
67  int(0));
68 
69  registerProcessorParameter( "EnergyDigitizatoin",
70  "switch for digitization of energy deposit",
72  int(1));
73 
74  registerProcessorParameter( "RandomNoise",
75  "Random noise option",
77  int(0));
78 
79  registerProcessorParameter( "FPCCD_PixelSize" ,
80  "Pixel size of FPCCD (unit:mm) (default: 0.005)",
81  _pixelSize,
82  float(0.0050) ) ;
83 
84  // Start of New edit
85  //<New variable is 'PiXelSizeVec'(so far this variable wasn't vector). So I've replaced PixelSizeVec with something which there were. And I
86  // don't write here the place. Please search the word 'PixelSizeVec'.
87 
88  FloatVec PixelSizeVec; // This is a temporary variable. Each ladder's PixelSize are different.
89  PixelSizeVec.push_back(0.005);
90  PixelSizeVec.push_back(0.005);
91  PixelSizeVec.push_back(0.010);
92  PixelSizeVec.push_back(0.010);
93  PixelSizeVec.push_back(0.010);
94  PixelSizeVec.push_back(0.010);
95 
96  registerProcessorParameter( "Each_FPCCD_pixelSize(mm)",
97  "Each ladder's Pixel size of FPCCD (unit:mm) (default:0.005)",
99  PixelSizeVec );
100  // End of New edit
101 
102 
103  registerProcessorParameter( "PixelHeight" ,
104  "Pixel Height(mm)",
105  _pixelheight ,
106  float(0.015));
107 
108  registerProcessorParameter( "PointResolutionRPhi" ,
109  "R-Phi Resolution in VTX" ,
111  float(0.001440)) ; // 5/sqrt(12)
112 
113  registerProcessorParameter( "PointResolutionZ" ,
114  "Z Resolution in VTX" ,
115  _pointResoZ ,
116  float(0.001440)); // 5/sqrt(12)
117 
118  registerProcessorParameter("positionReso_ReadingFile_ON",
119  "true: reading file for allocation of position reso. false: rough allocation of position reso. ",
121  bool(true));
122 
123  registerProcessorParameter("positionReso_ReadingFile",
124  "On: reading file for allocation of position reso.",
126  std::string("MarlinReco/v01-05/TrackDigi/FPCCDDigi/src/FPCCDClustering_ResoMap_MS_EL_ON_ver0.dat"));
127 
128  registerProcessorParameter("noiseElectronSigma",
129  "gaussian sigma of number of electron of noise",
131  double(50));
132 
133  registerProcessorParameter("NumberOfBitsForEnergyDeposit",
134  "Number of Bits used for energy depsit",
136  int(7));
137 
138  registerProcessorParameter("NumberOfElectronForStep",
139  "Number of electron for 1 step",
141  int(25));
142 
143  registerProcessorParameter("Threshold",
144  "Cell Threshold in electrons",
145  _threshold,
146  double(200));
147 
148  registerProcessorParameter("ElectronsPerKeV",
149  "Electrons per keV",
151  double(276)); // 3.62eV/1electron
152 
153 
154  /*
155  registerProcessorParameter( "NewTrackingSystem",
156  "Use new tracking system",
157  _new_tracking_system,
158  bool(true));
159  */
160 
161  registerProcessorParameter( "ClusterRejection_1stCut_isActive",
162  "If true, 1stCut is active. false makes this inactive. minus value makes cut on the layer inactive ",
164  bool(false));
165 
166  IntVec ZWidthVec(6);
167  ZWidthVec[0] = 15;
168  ZWidthVec[1] = 15;
169  ZWidthVec[2] = 8;
170  ZWidthVec[3] = 8;
171  ZWidthVec[4] = 8;
172  ZWidthVec[5] = 8;
173  registerProcessorParameter( "ClusterRejection_1stCut_ZWidth",
174  "Clusters with ZWidth >= this value are discarded. minus value makes cut on the layer inactive",
176  ZWidthVec);
177 
178  IntVec RPhiWidthVec(6);
179  RPhiWidthVec[0] = 10;
180  RPhiWidthVec[1] = 10;
181  RPhiWidthVec[2] = 6;
182  RPhiWidthVec[3] = 6;
183  RPhiWidthVec[4] = 6;
184  RPhiWidthVec[5] = 6;
185  registerProcessorParameter( "ClusterRejection_1stCut_RPhiWidth",
186  "Clusters with RPhiWidth >= this value are discarded. minus value makes cut on the layer inactive ",
188  RPhiWidthVec);
189 
190  IntVec nPixVec(6);
191  nPixVec[0] = 20;
192  nPixVec[1] = 20;
193  nPixVec[2] = 15;
194  nPixVec[3] = 15;
195  nPixVec[4] = 15;
196  nPixVec[5] = 15;
197  registerProcessorParameter( "ClusterRejection_1stCut_nPix",
198  "Clusters with nPix >= this value are discarded. minus value makes cut on the layer inactive",
199  _firstCut.nPix,
200  nPixVec);
201 
202  registerProcessorParameter( "ClusterRejection_Mori2ndCut_isActive",
203  "true: active, false: inactive",
205  bool(false));
206 
207  FloatVec ZParVec(6);
208  ZParVec[0] = 90;
209  ZParVec[1] = 90;
210  ZParVec[2] = 280;
211  ZParVec[3] = 280;
212  ZParVec[4] = 600;
213  ZParVec[5] = 600;
214  registerProcessorParameter( "ClusterRejection_Mori2ndCut_areaZ_parameter",
215  "You can choose float[0,~900]. 0 discards most of bad clusters, although some clusters are sacrified. minus value makes cut on the layer inactive",
216  _m2Cut.zpar,
217  ZParVec);
218 
219 
220  registerProcessorParameter( "ClusterRejection_Kamai2ndCut_isActive",
221  "true: active, false: inactive",
223  bool(false));
224 
225  FloatVec BParVec(6);
226  BParVec[0] = 2;
227  BParVec[1] = 2;
228  BParVec[2] = 1;
229  BParVec[3] = 1;
230  BParVec[4] = 1;
231  BParVec[5] = 1;
232  registerProcessorParameter( "ClusterRejection_Kamai2ndCut_b_parameter",
233  "You can choose float[0,10]. less than 2 discards most of bad clusters, although some clusters are sacrified. minus value makes cut on the layer inactive",
234  _k2Cut.bpar,
235  BParVec);
236 
237  IntVec MinZWidthVec(6);
238  MinZWidthVec[0] = 4;
239  MinZWidthVec[1] = 4;
240  MinZWidthVec[2] = 2;
241  MinZWidthVec[3] = 2;
242  MinZWidthVec[4] = 2;
243  MinZWidthVec[5] = 2;
244  registerProcessorParameter( "ClusterRejection_Kamai2ndCut_Save_minimum_Cluster_Z_Width_parameter",
245  "You can choose int[0,~7]. If a cluster with ZWidth <= this value, this is not discarded.",
247  MinZWidthVec);
248 
249  registerProcessorParameter( "MakeRelationOftrkhitsAndsimthits",
250  "If false, Clustering doesn't make LCRelation.",
252  bool(true));
253 
254 
255  registerProcessorParameter( "RemovePixelHitsCollection",
256  "Remove VTX Pixel Hits collection after processing",
258  bool(false));
259 
260  // Input collections
261  registerInputCollection( LCIO::SIMTRACKERHIT,
262  "VTXCollectionName" ,
263  "Name of the VTX SimTrackerHit collection" ,
264  _colNameSTH ,
265  std::string("VXDCollection") ) ;
266 
267  registerInputCollection( LCIO::LCGENERICOBJECT,
268  "VTXPixelHitCollection" ,
269  "Name of the VTX PixelHit collection" ,
270  _colNameVTX ,
271  std::string("VTXPixelHits") ) ;
272 
273  // Output collections
274  registerOutputCollection( LCIO::TRACKERHIT,
275  "VTXHitCollection" ,
276  "Name of the vxd TrackerHit output collection" ,
278  std::string("VXDTrackerHits") ) ;//old: VXDTrackerHits
279 
280  registerOutputCollection( LCIO::LCRELATION,
281  "SimTrackerHitRelCollection" ,
282  "Name of TrackerHit SimTrackerHit relation collection" ,
284  std::string("VXDTrackerHitRelations") ) ;//old: VTXTrackerHitRelations
285 #if ROOT_DEBUG
286  registerProcessorParameter( "outputRootFileName",
287  "output root file name & path (default: ./positionReso.root)",
289  std::string("./positionReso.root"));
290 
291  registerProcessorParameter( "treeName",
292  "tree name which belongs to the above output root file name & path(default: tree)",
293  _treeName,
294  std::string("t"));
295 #endif
296 
297 }
298 
299 
300 // =====================================================================
302 
303  // usually a good idea to
304  printParameters() ;
305 
306  _nRun = 0 ;
307  _nEvt = 0 ;
308 
309  InitGeometry();
310 
311  // initialize gsl random generator
312  _rng = gsl_rng_alloc(gsl_rng_ranlxs2);
313  gsl_rng_default_seed = _ranSeed;
314 
315 #if ROOT_DEBUG
316  _rootf = new TFile(_rootFileName.c_str(), "RECREATE");
317  _tree = new TTree(_treeName.c_str()," This is tree_name ");
318 
319 
320  _tree->Branch("nEvt",&_nEvt,"nEvt/I");
321  _tree->Branch("nlinks",&_link.nlink,"nlinks/I");
322  _tree->Branch("weight",_link.weight,"weight[nlinks]/F");
323  _tree->Branch("simthits_x",_simthits.x,"simthits_x[nlinks]/D");
324  _tree->Branch("simthits_y",_simthits.y,"simthits_y[nlinks]/D");
325  _tree->Branch("simthits_z",_simthits.z,"simthits_z[nlinks]/D");
326  _tree->Branch("simthits_R",_simthits.R,"simthits_R[nlinks]/D");
327  _tree->Branch("simthits_pdg",_simthits.pdg,"simthits_pdg[nlinks]/I");
328  _tree->Branch("simthits_mass",_simthits.mass,"simthits_mass[nlinks]/D");
329  _tree->Branch("simthits_vx",_simthits.vx,"simthits_vx[nlinks]/D");
330  _tree->Branch("simthits_vy",_simthits.vy,"simthits_vy[nlinks]/D");
331  _tree->Branch("simthits_vz",_simthits.vz,"simthits_vz[nlinks]/D");
332  _tree->Branch("simthits_px",_simthits.px,"simthits_px[nlinks]/F");
333  _tree->Branch("simthits_py",_simthits.py,"simthits_py[nlinks]/F");
334  _tree->Branch("simthits_pz",_simthits.pz,"simthits_pz[nlinks]/F");
335  _tree->Branch("simthits_pAbs",_simthits.pAbs,"simthits_pAbs[nlinks]/D");
336  _tree->Branch("simthits_theta",_simthits.theta,"simthits_theta[nlinks]/D");
337  _tree->Branch("simthits_phi",_simthits.phi,"simthits_phi[nlinks]/D");
338  _tree->Branch("simthits_area_theta",_simthits.area_theta,"simthits_area_theta[nlinks]/D");
339  _tree->Branch("simthits_area_phi",_simthits.area_phi,"simthits_area_phi[nlinks]/D");
340  _tree->Branch("simthits_layer",_simthits.layer,"simthits_layer[nlinks]/I");
341  _tree->Branch("simthits_ladder",_simthits.ladder,"simthits_ladder[nlinks]/I");
342  _tree->Branch("simthits_mcp_px",_simthits.mcp_px,"simthits_mcp_px[nlinks]/D");
343  _tree->Branch("simthits_mcp_py",_simthits.mcp_py,"simthits_mcp_py[nlinks]/D");
344  _tree->Branch("simthits_mcp_pz",_simthits.mcp_pz,"simthits_mcp_pz[nlinks]/D");
345  _tree->Branch("simthits_mcp_energy",_simthits.mcp_energy,"simthits_mcp_energy[nlinks]/D");
346  _tree->Branch("simthits_mcp_time",_simthits.mcp_time,"simthits_mcp_time[nlinks]/F");
347  _tree->Branch("simthits_mcp_Pt",_simthits.mcp_Pt,"simthits_mcp_Pt[nlinks]/D");
348  _tree->Branch("simthits_mcp_isCreatedInSimulation",_simthits.mcp_isCreatedInSimulation,"simthits_mcp_isCreatedInSimulation[nlinks]/I");
349  _tree->Branch("simthits_mcp_isBackscatter",_simthits.mcp_isBackscatter,"simthits_mcp_isBackscatter[nlinks]/I");
350  _tree->Branch("simthits_mcp_vertexIsNotEndpointOfParent",_simthits.mcp_vertexIsNotEndpointOfParent,"simthits_mcp_vertexIsNotEndpointOfParent[nlinks]/I");
351  _tree->Branch("simthits_mcp_isDecayedInTracker",_simthits.mcp_isDecayedInTracker,"simthits_mcp_isDecayedInTracker[nlinks]/I");
352  _tree->Branch("simthits_mcp_isDecayedInCalorimeter",_simthits.mcp_isDecayedInCalorimeter,"simthits_mcp_isDecayedInCalorimeter[nlinks]/I");
353  _tree->Branch("simthits_mcp_hasLeftDetector",_simthits.mcp_hasLeftDetector,"simthits_mcp_hasLeftDetector[nlinks]/I");
354  _tree->Branch("simthits_mcp_isStopped",_simthits.mcp_isStopped,"simthits_mcp_isStopped[nlinks]/I");
355  _tree->Branch("simthits_mcp_d0",_simthits.mcp_d0,"simthits_mcp_d0[nlinks]/F");
356  _tree->Branch("simthits_mcp_z0",_simthits.mcp_z0,"simthits_mcp_z0[nlinks]/F");
357  _tree->Branch("simthits_mcp_phi0",_simthits.mcp_phi0,"simthits_mcp_phi0[nlinks]/F");
358  _tree->Branch("simthits_mcp_omega",_simthits.mcp_omega,"simthits_mcp_omega[nlinks]/F");
359  _tree->Branch("simthits_mcp_tanL",_simthits.mcp_tanL,"simthits_mcp_tanL[nlinks]/F");
360  _tree->Branch("simthits_xi",_simthits.xi,"simthits_xi[nlinks]/D");
361  _tree->Branch("simthits_zeta",_simthits.zeta,"simthits_zeta[nlinks]/D");
362  _tree->Branch("simthits_edep",_simthits.edep,"simthits_edep[nlinks]/F");
363 
364 
365 
366 
367 
368  _tree->Branch("trkhits_x",_trkhits.x,"trkhits_x[nlinks]/D");
369  _tree->Branch("trkhits_y",_trkhits.y,"trkhits_y[nlinks]/D");
370  _tree->Branch("trkhits_z",_trkhits.z,"trkhits_z[nlinks]/D");
371  _tree->Branch("trkhits_R",_trkhits.R,"trkhits_R[nlinks]/D");
372  _tree->Branch("trkhits_area_theta",_trkhits.area_theta,"trkhits_area_theta[nlinks]/D");
373  _tree->Branch("trkhits_area_phi",_trkhits.area_phi,"trkhits_area_phi[nlinks]/D");
374  _tree->Branch("trkhits_CWidth_RPhi",_trkhits.CWidth_RPhi,"trkhits_CWidth_RPhi[nlinks]/i");
375  _tree->Branch("trkhits_CWidth_Z",_trkhits.CWidth_Z,"trkhits_CWidth_Z[nlinks]/i");
376  _tree->Branch("trkhits_tilt",_trkhits.tilt,"trkhits_tilt[nlinks]/i");
377  _tree->Branch("trkhits_nPix",_trkhits.nPix,"trkhits_nPix[nlinks]/i");
378  _tree->Branch("trkhits_layer",_trkhits.layer,"trkhits_layer[nlinks]/I");
379  _tree->Branch("trkhits_ladder",_trkhits.ladder,"trkhits_ladder[nlinks]/I");
380  _tree->Branch("trkhits_xi",_trkhits.xi,"trkhits_xi[nlinks]/D");
381  _tree->Branch("trkhits_zeta",_trkhits.zeta,"trkhits_zeta[nlinks]/D");
382  _tree->Branch("trkhits_edep",_trkhits.edep,"trkhits_edep[nlinks]/F");
383 
384  _tree->Branch("trkhits_tposX",_trkhits.tposX,"trkhits_tposX[nlinks]/D");
385  _tree->Branch("trkhits_tposY",_trkhits.tposY,"trkhits_tposY[nlinks]/D");
386  _tree->Branch("trkhits_tposZ",_trkhits.tposZ,"trkhits_tposZ[nlinks]/D");
387  _tree->Branch("trkhits_cx",_trkhits.cx,"trkhits_cx[nlinks]/D");
388  _tree->Branch("trkhits_cy",_trkhits.cy,"trkhits_cy[nlinks]/D");
389  _tree->Branch("trkhits_cz",_trkhits.cz,"trkhits_cz[nlinks]/D");
390  _tree->Branch("trkhits_dot",_trkhits.dot,"trkhits_dot[nlinks]/D");
391 
392  _tree->Branch("diff_RPhi",_diff.RPhi,"diff_RPhi[nlinks]/D");
393  _tree->Branch("diff_Z",_diff.Z,"diff_Z[nlinks]/D");
394 #endif
395 
396 
397 
398 
399 
400 
401  if(_positionReso_ReadingFile_ON == true){
402  _fin.open( _positionReso_ReadingFile.c_str() );
403  if(!_fin.is_open()){
404  std::cout << "========FATAL ERROR============================" << std::endl;
405  std::cout << "positionReso_ReadingFile is not opened!! exit!!" << std::endl;
406  std::cout << _positionReso_ReadingFile << std::endl;
407  std::cout << "The above path seems to be wrong. " << std::endl;
408  std::cout << "FPCCDClustering exits! " << std::endl;
409  std::cout << "===============================================" << std::endl;
410  exit(10);
411  }
412 
413  float a = 0;
414  for(int i = 0 ; i < 6 ; i++){
415  for(int j = 1 ; j <= 49 ; j++){
416  _fin >> a ;
417  short int code = i * 100 + j;
418  _resolutionMapRPhi.insert(std::make_pair(code,a));
419  }
420  }
421  for(int i = 0 ; i < 6 ; i++){
422  for(int j = 1 ; j <= 49 ; j++){
423  _fin >> a ;
424  short int code = i * 100 + j;
425  _resolutionMapZ.insert(std::make_pair(code,a));
426  }
427  }
428  }
429 }
430 
431 // =====================================================================
433 {
434  // Save frequently used parameters.
435 
436  const gear::ZPlanarParameters &gearVXD = Global::GEAR->getVXDParameters();
437  const gear::ZPlanarLayerLayout &layerVXD=gearVXD.getVXDLayerLayout();
438 
439  _nLayer = layerVXD.getNLayers() ;
440  _geodata.resize(_nLayer);
441  _maxLadder = 0;
442 
443  for(int ly=0;ly<_nLayer;ly++){
444  _geodata[ly].nladder = layerVXD.getNLadders(ly); // Number of ladders in this layer
445  if( _maxLadder < _geodata[ly].nladder ) { _maxLadder = _geodata[ly].nladder; }
446  _geodata[ly].rmin = layerVXD.getSensitiveDistance(ly); // Distance of sensitive area from IP
447  _geodata[ly].dphi = (2*M_PI)/(double)_geodata[ly].nladder;
448  _geodata[ly].phi0 = layerVXD.getPhi0(ly); // phi offset.
449  _geodata[ly].sthick = layerVXD.getSensitiveThickness(ly);
450  _geodata[ly].sximin = -layerVXD.getSensitiveOffset(ly)
451  -layerVXD.getSensitiveWidth(ly)/2.0;
452  _geodata[ly].sximax = -layerVXD.getSensitiveOffset(ly)
453  +layerVXD.getSensitiveWidth(ly)/2.0;
454  _geodata[ly].hlength = layerVXD.getSensitiveLength(ly);
455  _geodata[ly].cosphi.resize( _geodata[ly].nladder ) ;
456  _geodata[ly].sinphi.resize( _geodata[ly].nladder ) ;
457  _geodata[ly].ladder_incline.resize( _geodata[ly].nladder ) ;
458  _geodata[ly].num_xi_pixel = (int)(layerVXD.getSensitiveWidth(ly)/_pixelSizeVec[ly]);
459  _geodata[ly].num_zeta_pixel = (int)(2*layerVXD.getSensitiveLength(ly)/_pixelSizeVec[ly]);
460  for(int ld=0;ld<_geodata[ly].nladder;ld++) {
461  double phi = _geodata[ly].phi0 + _geodata[ly].dphi*ld;
462  _geodata[ly].cosphi[ld] = cos(phi);
463  _geodata[ly].sinphi[ld] = sin(phi);
464  double incline = phi - (M_PI/2.0);
465  while( incline > 1.0*M_PI || incline < -1.0*M_PI ){ incline > 1.0*M_PI ? incline -= 2.0*M_PI : incline += 2.0*M_PI ;}
466  _geodata[ly].ladder_incline[ld] = incline;
467  }
468  }
469 }
470 
471 
472 // =====================================================================
473 void FPCCDClustering::processRunHeader( LCRunHeader* /*run*/) {
474  _nRun++ ;
475 }
476 
477 // =====================================================================
478 void FPCCDClustering::modifyEvent( LCEvent * evt )
479 {
480 
481  LCCollectionVec* pHitCol=0;
482  LCCollection* STHcol=0;
483  try { pHitCol = dynamic_cast<LCCollectionVec*>( evt->getCollection( _colNameVTX ) );
484  if( _remove_pixelhits_collection ) { pHitCol->setTransient(true); } }
485  catch(DataNotAvailableException &e){
486  if (_debug >= 1) { std::cout << "Collection " << _colNameVTX.c_str() << " is unavailable in event "
487  << _nEvt << std::endl; }
488  }
489 
490  try { STHcol = evt->getCollection( _colNameSTH ) ; }
491  catch(DataNotAvailableException &e){
492  if (_debug >= 1) { std::cout << "Collection " << _colNameSTH.c_str() << " is unavailable in event "
493  << _nEvt << std::endl; }
494  }
495 
496 
497  if( _debug >= 1 ) {
498  std::cout << " Collection =" << _colNameVTX << " nevt=" << _nEvt << std::endl;
499  std::cout << " Collection =" << _colNameSTH << " nevt=" << _nEvt << std::endl;
500  if( pHitCol != 0 ) { std::cout << " number of elements is " << pHitCol->getNumberOfElements() << std::endl; }
501  if( STHcol != 0 ) { std::cout << " number of elements is " << STHcol->getNumberOfElements() << std::endl; }
502  }
503 
504  if( pHitCol != 0 && STHcol != 0){
505  FPCCDData theData(_nLayer, _maxLadder); // prepare object to make pixelhits
506  int nhit=theData.unpackPixelHits(*pHitCol);//This unpacks LCGenericObjectVec made in FPCCDDigitizer (precisely, FPCCDData).
507  //And return number of pixel hits generated by one simtrackerhit in FPCCDDigitizer.
508  if( _debug >= 2 ) { LCTOOLS::dumpEvent( evt ) ;}
509 
510  if( _debug >=2 ) { std::cout << " nhit=" << nhit << std::endl; }
511  if( nhit > 0 ) { // Output Trackhit, if there are pixel hits
512 
513  LCCollectionVec* trkHitVec = new LCCollectionVec( LCIO::TRACKERHITPLANE );
514  LCCollectionVec* relCol = new LCCollectionVec( LCIO::LCRELATION );
515 
516  //The flow of Flag setting.
517  LCFlagImpl lcFlag(0);
518  lcFlag.setBit( LCIO::LCREL_WEIGHTED );//LCIO::LEREL_WEIGHTED = 31. See LCIO and LCFlagImpl in class list.
519  relCol->setFlag( lcFlag.getFlag() );
520 
521 
522  makeTrackerHitVec( &theData, STHcol, relCol, trkHitVec);
523  evt->addCollection( trkHitVec, _outColNameVTX ) ;
524  evt->addCollection( relCol, _outRelColNameVTX ) ;
525 
526  if( _debug >= 2 ) {
527  std::cout << "dumpEvent FPCCDClustering" << std::endl;
528  LCTOOLS::dumpEvent( evt ) ;
529  }
531  for(int i = pHitCol->getNumberOfElements(); i>0; i--){
532  pHitCol->removeElementAt(i-1);
533  }
534  }
535  }
536  if( _remove_pixelhits_collection ) { evt->removeCollection( _colNameVTX ); }
537  theData.clear();
538 
539  } // End of process when VXD has hits
540 
541 #if ROOT_DEBUG
542 
543  //******************ROOT Tree Session*****************************************//
544 
545  bool Go = true;
546  if( pHitCol != 0 && STHcol != 0){
547 
548  LCCollectionVec* rootRelCol=0;
549  try { rootRelCol = dynamic_cast<LCCollectionVec*>( evt->getCollection( _outRelColNameVTX ) );}
550  catch(DataNotAvailableException &e){
551  Go = false;
552  std::cout << "miss getCollection!! at _nEvt = " << _nEvt << std::endl;
553  if (_debug >= 1) { std::cout << "Collection " << _outRelColNameVTX.c_str() << " is unavailable in event "
554  << _nEvt << std::endl; }
555  }
556  /*
557  _tree->Branch("nlinks",&_link.nlink,"nlinks/I");
558  _tree->Branch("weight",_link.weight,"weight[nlinks]/F");
559  _tree->Branch("simthits_x",_simthits.x,"simthits_x[nlinks]/D");
560  _tree->Branch("simthits_y",_simthits.y,"simthits_y[nlinks]/D");
561  _tree->Branch("simthits_z",_simthits.z,"simthits_z[nlinks]/D");
562  _tree->Branch("simthits_pdg",_simthits.pdg,"simthits_pdg[nlinks]/I");
563 
564  _tree->Branch("trkhits_x",_trkhits.x,"trkhits_x[nlinks]/D");
565  _tree->Branch("trkhits_y",_trkhits.y,"trkhits_y[nlinks]/D");
566  _tree->Branch("trkhits_z",_trkhits.z,"trkhits_z[nlinks]/D");
567  _tree->Branch("trkhits_CWidth_RPhi",_trkhits.CWidth_RPhi,"trkhits_CWidth_RPhi[nlinks]/D");
568  _tree->Branch("trkhits_CWidth_Z",_trkhits.CWidth_Z,"trkhits_CWidth_Z[nlinks]/D");
569  */
570 
571  if(Go == true){
572  LCFlagImpl forRootlcFlag(0);
573  forRootlcFlag.setBit( LCIO::LCREL_WEIGHTED );//LCIO::LEREL_WEIGHTED = 31. See LCIO and LCFlagImpl in class list.
574  //std::cout << "check1" << std::endl;
575  rootRelCol->setFlag( forRootlcFlag.getFlag() );
576  //std::cout << "check2" << std::endl;
577 
578  _link.nlink = rootRelCol->getNumberOfElements();
579  for(unsigned int ri = 0; ri < _link.nlink; ri++ ){
580  LCRelation* link_p = dynamic_cast<LCRelation*>( rootRelCol->getElementAt(ri) );
581  _link.weight[ri] = link_p->getWeight();
582  TrackerHit* trkhit_p = dynamic_cast<TrackerHit*>( link_p->getFrom() );
583  SimTrackerHit* simthit_p = dynamic_cast<SimTrackerHit*>( link_p->getTo() );
584 
585  _simthits.x[ri] = simthit_p->getPosition()[0];
586  _simthits.y[ri] = simthit_p->getPosition()[1];
587  _simthits.z[ri] = simthit_p->getPosition()[2];
588 
589 
590  _simthits.pdg[ri] = simthit_p->getMCParticle()->getPDG();
591  _simthits.mass[ri] = simthit_p->getMCParticle()->getMass();
592  _simthits.px[ri] = simthit_p->getMomentum()[0];
593  _simthits.py[ri] = simthit_p->getMomentum()[1];
594  _simthits.pz[ri] = simthit_p->getMomentum()[2];
595  _simthits.mcp_px[ri] = simthit_p->getMCParticle()->getMomentum()[0];
596  _simthits.mcp_py[ri] = simthit_p->getMCParticle()->getMomentum()[1];
597  _simthits.mcp_pz[ri] = simthit_p->getMCParticle()->getMomentum()[2];
598  _simthits.mcp_Pt[ri] = sqrt(pow(_simthits.mcp_px[ri],2) + pow(_simthits.mcp_py[ri],2));
599  _simthits.vx[ri] = simthit_p->getMCParticle()->getVertex()[0];
600  _simthits.vy[ri] = simthit_p->getMCParticle()->getVertex()[1];
601  _simthits.vz[ri] = simthit_p->getMCParticle()->getVertex()[2];
602  _simthits.mcp_energy[ri] = simthit_p->getMCParticle()->getEnergy();
603  _simthits.mcp_time[ri] = simthit_p->getMCParticle()->getTime();
604  _simthits.mcp_isCreatedInSimulation[ri] = simthit_p->getMCParticle()->isCreatedInSimulation();
605  _simthits.mcp_isBackscatter[ri] = simthit_p->getMCParticle()->isBackscatter();
606  _simthits.mcp_vertexIsNotEndpointOfParent[ri] = simthit_p->getMCParticle()->vertexIsNotEndpointOfParent();
607  _simthits.mcp_isDecayedInTracker[ri] = simthit_p->getMCParticle()->isDecayedInTracker();
608  _simthits.mcp_isDecayedInCalorimeter[ri] = simthit_p->getMCParticle()->isDecayedInCalorimeter();
609  _simthits.mcp_hasLeftDetector[ri] = simthit_p->getMCParticle()->hasLeftDetector();
610  _simthits.mcp_isStopped[ri] = simthit_p->getMCParticle()->isStopped();
611 
612 
613 
614 
615 
616 
617 
618 
619 
620 
621 
622 
623 
624  _trkhits.x[ri] = trkhit_p->getPosition()[0];
625  _trkhits.y[ri] = trkhit_p->getPosition()[1];
626  _trkhits.z[ri] = trkhit_p->getPosition()[2];
627 
628  double signRPhi = _trkhits.x[ri] * _simthits.y[ri] - _trkhits.y[ri] * _simthits.x[ri];
629 
630  if(signRPhi > 0){
631  _diff.RPhi[ri] = sqrt(pow(_trkhits.x[ri] - _simthits.x[ri],2) + pow(_trkhits.y[ri] - _simthits.y[ri],2));
632  }
633  else{
634  _diff.RPhi[ri] = (-1)*sqrt(pow(_trkhits.x[ri] - _simthits.x[ri],2) + pow(_trkhits.y[ri] - _simthits.y[ri],2));
635  }
636 
637  _diff.Z[ri] = _trkhits.z[ri] - _simthits.z[ri];
638 
639 
640  int cellid1 = trkhit_p->getCellID1();
641  unsigned int xiwidth = cellid1 & 0x000001ff ;
642  unsigned int zetawidth = ( cellid1 >> 9 ) & 0x000001ff;
643  unsigned int nPix = ( cellid1 >> 18) & 0x000003ff;
644  unsigned int tilt = ( cellid1 >> 28) & 0x00000003;
645  _trkhits.CWidth_RPhi[ri] = xiwidth;
646  _trkhits.CWidth_Z[ri] = zetawidth;
647  _trkhits.nPix[ri] = nPix;
648  _trkhits.tilt[ri] = tilt;
649 
650 
651  _simthits.pAbs[ri] = sqrt(pow(static_cast<double>(_simthits.px[ri]),2) + pow(static_cast<double>(_simthits.py[ri]),2) + pow(static_cast<double>(_simthits.pz[ri]),2));
652  _simthits.theta[ri] = 180/M_PI* acos( static_cast<double>(_simthits.pz[ri]) / _simthits.pAbs[ri] ); //from 0 to pi
653  _simthits.phi[ri] = 180/M_PI* atan2( static_cast<double>(_simthits.py[ri]) ,static_cast<double>(_simthits.px[ri])); // from -pi to pi
654 
655 
656  _simthits.R[ri] = sqrt(pow(_simthits.x[ri],2) + pow(_simthits.y[ri],2) + pow(_simthits.z[ri],2));
657  _simthits.area_theta[ri] = 180/M_PI* acos( _simthits.z[ri] / _simthits.R[ri] ); //from 0 to pi
658  _simthits.area_phi[ri] = 180/M_PI* atan2( _simthits.y[ri] ,_simthits.x[ri]); // from -pi to pi
659 
660  _trkhits.R[ri] = sqrt(pow(_trkhits.x[ri],2) + pow(_trkhits.y[ri],2) + pow(_trkhits.z[ri],2));
661  _trkhits.area_theta[ri] = 180/M_PI* acos( _trkhits.z[ri] / _trkhits.R[ri] ); //from 0 to pi
662  _trkhits.area_phi[ri] = 180/M_PI* atan2( _trkhits.y[ri] ,_trkhits.x[ri]); // from -pi to pi
663 
664 
665 
666 
667 
668 
669 
670 
671  const int cellId_sim = simthit_p->getCellID0();
672  UTIL::BitField64 encoder_sim( lcio::LCTrackerCellID::encoding_string() ) ;
673  encoder_sim.setValue(cellId_sim) ;
674  _simthits.layer[ri] = encoder_sim[lcio::LCTrackerCellID::layer()] ;
675  _simthits.ladder[ri] = encoder_sim[lcio::LCTrackerCellID::module()] ;
676 
677  const int cellId_trk = trkhit_p->getCellID0();
678  UTIL::BitField64 encoder_trk( lcio::LCTrackerCellID::encoding_string() ) ;
679  encoder_trk.setValue(cellId_trk) ;
680  _trkhits.layer[ri] = encoder_trk[lcio::LCTrackerCellID::layer()] ;
681  _trkhits.ladder[ri] = encoder_trk[lcio::LCTrackerCellID::module()] ;
682 
683  double lpos[3];//xi,eta,zeta
684  double gpos[3];
685  gpos[0] = _trkhits.x[ri];
686  gpos[1] = _trkhits.y[ri];
687  gpos[2] =_trkhits.z[ri];
688  int tlayer = _trkhits.layer[ri];
689  int tladder = _trkhits.ladder[ri];
690  double sinphi = _geodata[tlayer].sinphi[tladder];
691  double cosphi = _geodata[tlayer].cosphi[tladder];
692  lpos[0] = gpos[0] * sinphi - gpos[1] * cosphi + gpos[2] * 0;
693  lpos[1] = gpos[0] * cosphi + gpos[1] * sinphi + gpos[2] * 0;
694  lpos[2] = gpos[0] * 0 + gpos[1] * 0 + gpos[2] * 1;
695  _trkhits.xi[ri] = lpos[0];
696  _trkhits.zeta[ri] = lpos[2];
697 
698  gpos[0] = _simthits.x[ri];
699  gpos[1] = _simthits.y[ri];
700  gpos[2] =_simthits.z[ri];
701  tlayer = _simthits.layer[ri];
702  tladder = _simthits.ladder[ri];
703  sinphi = _geodata[tlayer].sinphi[tladder];
704  cosphi = _geodata[tlayer].cosphi[tladder];
705  lpos[0] = gpos[0] * sinphi - gpos[1] * cosphi + gpos[2] * 0;
706  lpos[1] = gpos[0] * cosphi + gpos[1] * sinphi + gpos[2] * 0;
707  lpos[2] = gpos[0] * 0 + gpos[1] * 0 + gpos[2] * 1;
708  _simthits.xi[ri] = lpos[0];
709  _simthits.zeta[ri] = lpos[2];
710 
711  double par[5];
712  calcTrackParameterOfMCP(simthit_p->getMCParticle(), par);
713  _simthits.mcp_d0[ri] = par[0];
714  _simthits.mcp_z0[ri] = par[1];
715  _simthits.mcp_omega[ri] = par[2];
716  _simthits.mcp_phi0[ri] = par[3];
717  _simthits.mcp_tanL[ri] = par[4];
718 
719 
720  /////////////////////Calc of Dot of cluster and global position//////////////////////
721 
722 #if 0
723  const double xioffset[6] = {-5.5+1.575320104,
724  -5.5+1.575320104,
725  -11+1.531923469,
726  -11+1.531923469,
727  -11+2.293817688,
728  -11+2.293817688};
729 
730  const double layerdistance[6] = { 15.9575,
731  18.0425,
732  36.9575,
733  39.0425,
734  57.9575,
735  60.0425};
736  const double hlength[6] = {62.5,62.5,125,125,125,125};
737 
738  std::cout << "xioffset : " << std::endl;
739  for(int jj = 0; jj < 6; jj++) std::cout << xioffset[jj] << " " << std::endl;
740  std::cout << "layerdistance : " << std::endl;
741  for(int jj = 0; jj < 6; jj++) std::cout << layerdistance[jj] << " " << std::endl;
742  std::cout << "hlength : " << std::endl;
743  for(int jj = 0; jj < 6; jj++) std::cout << hlength[jj] << " " << std::endl;
744 
745  std::cout << " _geodata[ly].sximin : " << std::endl;
746  for(int jj = 0; jj < 6; jj++) std::cout << _geodata[jj].sximin << " " << std::endl;
747  std::cout << " _geodata[ly].rmin : " << std::endl;
748  for(int jj = 0; jj < 6; jj++) std::cout << _geodata[jj].rmin << " " << std::endl;
749  std::cout << " _geodata[ly].hlength : " << std::endl;
750  for(int jj = 0; jj < 6; jj++) std::cout << _geodata[jj].hlength << " " << std::endl;
751 #endif
752 
753  int mly = _trkhits.layer[ri];
754  int mld = _trkhits.ladder[ri];
755  gear::Vector3D tpos(trkhit_p->getPosition()[0],trkhit_p->getPosition()[1],trkhit_p->getPosition()[2]);
756 
757  /*
758  double TrkX = tpos.x();
759  double TrkY = tpos.y();
760  double TrkZ = tpos.z();
761  */
762  double tposR = tpos.rho();
763  double tposphi = tpos.phi();
764 
765  double TrkXi = tposR*(cos(tposphi)*_geodata[mly].sinphi[mld]-sin(tposphi)*_geodata[mly].cosphi[mld]) - _geodata[mly].sximin;
766  double TrkZeta = tpos.z()+_geodata[mly].hlength;
767 
768  _trkhits.edep[ri] = trkhit_p->getEDep();
769  _simthits.edep[ri] = simthit_p->getEDep();
770  TVector3 tposDir(TrkXi+_geodata[mly].sximin,TrkZeta-_geodata[mly].hlength,_geodata[mly].rmin);
771  _trkhits.tposX[ri] = tposDir.X();
772  _trkhits.tposY[ri] = tposDir.Y();
773  _trkhits.tposZ[ri] = tposDir.Z();
774 
775  double sign = 1;
776  if(tilt>1) sign = -1;
777  float pixelsize = _pixelSizeVec[mly];
778 
779  TVector3 ClusterDir(pixelsize*(xiwidth-1),sign*pixelsize*(zetawidth-1),_pixelheight);
780  TVector3 revClusterDir(-ClusterDir.X(),-ClusterDir.Y(),ClusterDir.Z());
781  // gear::Vector3D ClusterDir(sign*((double)xiwidth-1),(double)zetawidth-1,0);
782  if( revClusterDir.Unit().Dot( tposDir.Unit() ) > ClusterDir.Unit().Dot( tposDir.Unit() )){
783  ClusterDir.SetX(revClusterDir.X());
784  ClusterDir.SetY(revClusterDir.Y());
785  }
786  _trkhits.cx[ri] = ClusterDir.Unit().X();
787  _trkhits.cy[ri] = ClusterDir.Unit().Y();
788  _trkhits.cz[ri] = ClusterDir.Unit().Z();
789 
790  _trkhits.dot[ri] = ClusterDir.Unit().Dot( tposDir.Unit() );//global座標とclusterの内積
791 
792  }
793 
794 
795  //std::cout << "fill" << std::endl;
796  _tree->Fill();
797  //std::cout << "fill clear " << std::endl;
798  }
799  }
800 #endif
801 
802  //***********************ROOT Tree Session end*********************************//
803 
804  _nEvt ++ ;
805 }
806 
807 // ====================================================================
808 void FPCCDClustering::makeTrackerHitVec(FPCCDData* pHitData, LCCollection* STHcol, LCCollectionVec* relCol, LCCollectionVec* trkHitVec)
809 {
810  //At first, relCol and trkHitVec are void data.
811  typedef std::multimap< std::pair<int,int>, SimTrackerHit*> RelMap_t;
812  //std::multimap< std::pair<int,int>, SimTrackerHit*> relMap;//"multimap" allows duplication of Key and "map" doesn't.
813  RelMap_t relMap;//"multimap" allows duplication of Key and "map" doesn't.
814 
815  relMap.clear();
816 
817 
818 
819  // Convert pixel hits to TrackerHits
820  for(int layer=0;layer<_nLayer;layer++){
821  int nladder = _geodata[layer].nladder;
822  double sximin = _geodata[layer].sximin;
823  double sximax = _geodata[layer].sximax;
824  double sxiwidth = sximax-sximin;
825  double hlength = _geodata[layer].hlength;
826 
827  // ----------------------------------------
828  // Start clustering of hits in each laddder
829  // ----------------------------------------
830  for(int ladder=0;ladder<nladder;ladder++){
831 
832  FPCCDLadderHit_t ladderHit; //typedef std::map<FPCCDHitLoc_t, FPCCDPixelHit*> FPCCDLadderHit_t;
833 
834  //typedef std::pair<unsigned int, unsigned int> FPCCDHitLoc_t;
835  //typedef std::map<FPCCDHitLoc_t, FPCCDPixelHit*> FPCCDLadderHit_t;
836  // namely, std::map<std::pair<unsigned int, unsigned int>, FPCCDPixelHit*>
837 
838 
839 
840  PixelHitMap_t::iterator it=pHitData->itBegin(layer, ladder);
841  /*
842  is defined as below in FPCCDData.h.
843  typedef std::map<unsigned int, FPCCDPixelHit*> PixelHitMap_t; //key will be encorded cellID.
844  typedef std::vector< std::vector<PixelHitMap_t> > PixelDataBuf_t;
845  */
846 
847  //(1) Copy all hits into local variables, ladderHit
848  while( it != pHitData->itEnd(layer, ladder) ) {
849 
850  FPCCDPixelHit *aHit=(*it).second;
851  // Set the noise
852  aHit->setEdep( aHit->getEdep() + gsl_ran_gaussian(_rng, _electronNoiseRate/_electronsPerKeV)*1e-6);//_electronNoiseRate = 50 (by default)
853  if( _energyDigitization){
854  EnergyDigitizer( aHit );
855  }
856  if( aHit->getEdep() > ( _threshold/_electronsPerKeV ) * 1e-6 ) { // Do the threshold cut
857 
858  int xiID=aHit->getXiID();
859  int zetaID=aHit->getZetaID();
860  FPCCDHitLoc_t hitloc(xiID, zetaID);
861  ladderHit.insert(map<FPCCDHitLoc_t, FPCCDPixelHit*>::value_type(hitloc, aHit));
862  }
863  it++;
864  }
865  // Set the random noise hit
867  unsigned int noiseXi = 0;
868  unsigned int noiseZeta = 0;
869  double noiseEdep = 0;
870 
871  for(unsigned int i=0; i< gsl_ran_poisson( _rng, (sxiwidth/_pixelSizeVec[layer])*(2*hlength/_pixelSizeVec[layer])*3.1671*1e-5) ; i++){ // Random noise is generated by 4 sigma plobability.
872 
873  noiseXi = (unsigned int)gsl_ran_flat( _rng, 0, sxiwidth/_pixelSizeVec[layer] );
874  noiseZeta = (unsigned int)gsl_ran_flat( _rng, 0, 2*hlength/_pixelSizeVec[layer] );
875  FPCCDHitLoc_t noiseHitLoc( noiseXi, noiseZeta );
876  FPCCDLadderHit_t::iterator noiseIt=ladderHit.find( noiseHitLoc );
877 
878  if( noiseIt == ladderHit.end() ){
879  noiseEdep = gsl_ran_gaussian_tail( _rng, _threshold, _electronNoiseRate )/(_electronsPerKeV * 1e+6 );
880  FPCCDPixelHit* noiseHit = new FPCCDPixelHit(layer, ladder, noiseXi, noiseZeta, noiseEdep, FPCCDPixelHit::kBKG, 0);
881  EnergyDigitizer( noiseHit);
882  ladderHit.insert( map<FPCCDHitLoc_t, FPCCDPixelHit*>::value_type( noiseHitLoc, noiseHit) );
883  }
884  }
885  }
886  // Do clustering
887  if( ladderHit.size() > 0 ) {
888  FPCCDClusterVec_t clusterVec;
889  //typedef std::vector<FPCCDPixelHit*> FPCCDCluster_t;
890  //typedef std::vector<FPCCDCluster_t*> FPCCDClusterVec_t;
891  //namely, std::vector<std::vector<FPCCDPixelHit*>>
892 
893  makeClustersInALadder(layer, ladderHit, clusterVec);
894  if( _debug >= 1 ) {
895  std::cout << "Layer:" << layer << " ladder:" << ladder << " # of clusters=" << clusterVec.size() << std::endl;
896  std::cout << " # pixels in each clusters are ";
897  for(unsigned int i=0;i<clusterVec.size();i++) {
898  std::cout << clusterVec[i]->size() << " " ;
899  if ( i > 1000 ) { std::cout << " ... omitting the rest. " ; break; }
900  }
901  std::cout << endl;
902  }
903  // Calulate position from cluster and
904  makeTrackerHit(STHcol, layer, ladder, clusterVec, relMap, relCol, trkHitVec);
905  //At this phase, relCol and trkHitVec haven't been filled and changed.
906 
907  // Now clean up clusters in clusterVec;
908  for(int i=clusterVec.size()-1;i>=0;i--){ delete clusterVec[i]; }
909  }
910  } // End of Ladder loop
911  } // End of Layer loop
912 }
913 
914 
915 
916 
917 void FPCCDClustering::makeTrackerHit(LCCollection* STHcol, int layer, int ladder, FPCCDClusterVec_t &clusterVec, std::multimap< std::pair<int,int>, SimTrackerHit*> relMap, LCCollectionVec* relCol, LCCollectionVec* trkHitVec )
918 {
919  //trkHitVec and relCol is yet void data.
920  //This Version is different from default version at the point of last area of this function scope.
921  //The way of making relation between simthits and trkhits is different.
922 
923  //typedef std::vector<FPCCDPixelHit*> FPCCDCluster_t;
924  //typedef std::vector<FPCCDCluster_t*> FPCCDClusterVec_t;
925  //namely, std::vector<std::vector<FPCCDPixelHit*>>
926 
927 
928 
929  CellIDEncoder<TrackerHitPlaneImpl> cellid_encoder( lcio::LCTrackerCellID::encoding_string() , trkHitVec ) ;
930  for(unsigned int ic=0;ic<clusterVec.size();ic++) {
931  FPCCDCluster_t *cluster=clusterVec[ic];
932 
933  double xiene = 0.0; double zetaene = 0.0; double enesum = 0.0;
934  int maxxi = 0; int minxi = 0; int maxzeta = 0; int minzeta = 0;
935  FPCCDPixelHit::HitQuality_t trackquality = FPCCDPixelHit::kSingle;
936  /* is defined as below in FPCCDPixelHit.h.
937  typedef enum { kSingle=0, kSignalOverlap=0x01, kBKGOverlap=0x02, kBKG=0x03} HitQuality_t;
938  */
939 
940  FPCCDPixelHit *maxXiHit=(*cluster)[0]; FPCCDPixelHit *minXiHit=(*cluster)[0];
941  FPCCDPixelHit *maxZetaHit=(*cluster)[0]; FPCCDPixelHit *minZetaHit=(*cluster)[0];
942 
943  unsigned int nPix=cluster->size();
944  std::list<int> orderVecOfCluster(0); //Mori added 20121203
945  for(unsigned int i=0;i<nPix;i++) {
946  /***Mori added 20121203***/
947  int overlaidSize = (*cluster)[i]->getSizeOfOrderID();//Sometimes one pixel is generated by more than one simthits.
948  //So, usually overlaidSize is one, but sometimes 2 or more.
949  for(int ios = 0; ios < overlaidSize; ios++){
950  orderVecOfCluster.push_back( (*cluster)[i]->getOrderID(ios) ); //Mori added 20121204
951  }
952  /********end**************/
953 
954  FPCCDPixelHit *aHit=(*cluster)[i]; trackquality = aHit->getQuality(); enesum+=aHit->getEdep();
955  xiene+=((double)(aHit->getXiID()+0.5))*_pixelSizeVec[layer]*aHit->getEdep();
956  zetaene+=((double)(aHit->getZetaID()+0.5))*_pixelSizeVec[layer]*aHit->getEdep();
957 
958  if(i==0){
959  maxxi = aHit->getXiID(); minxi = maxxi;
960  maxzeta = aHit->getZetaID(); minzeta = maxzeta;
961  }
962  else{
963  if( aHit->getXiID() > maxxi){ maxxi = aHit->getXiID(); maxXiHit=aHit;}
964  if( aHit->getXiID() < minxi){ minxi = aHit->getXiID(); minXiHit=aHit;}
965  if(aHit->getZetaID() > maxzeta){ maxzeta = aHit->getZetaID();maxZetaHit=aHit;}
966  if(aHit->getZetaID() < minzeta){ minzeta = aHit->getZetaID();minZetaHit=aHit;}
967  }
968  FPCCDPixelHit::HitQuality_t addedQuality = aHit->getQuality();
969  if( trackquality != FPCCDPixelHit::kBKGOverlap){
970  if(trackquality == FPCCDPixelHit::kBKG){
971  addedQuality=FPCCDPixelHit::kBKG ? trackquality=FPCCDPixelHit::kBKG : trackquality=FPCCDPixelHit::kBKGOverlap;
972  }
973  }
974  else if(addedQuality==FPCCDPixelHit::kSignalOverlap){trackquality=FPCCDPixelHit::kSignalOverlap; }
975  }
976 
977  unsigned int xiWidth = maxxi-minxi + 1;
978  unsigned int zetaWidth = maxzeta-minzeta + 1; // cluster shapes info. could be used to reject background.
979  //Mori added new if statement
980  if(_firstCut.isActive != true || _firstCut.ZWidth[layer] < 0 || zetaWidth < static_cast<unsigned int>(_firstCut.ZWidth[layer]) ){
981  if(_firstCut.isActive != true || _firstCut.RPhiWidth[layer] < 0 || xiWidth < static_cast<unsigned int>(_firstCut.RPhiWidth[layer]) ){
982 
983 
984  unsigned short int tilt=0;
985  if( xiWidth==1 || zetaWidth==1 ) tilt=0;
986  else{
987  if(maxXiHit->getZetaID()-minXiHit->getZetaID()>0 && maxZetaHit->getXiID()-minZetaHit->getXiID()>0) tilt=1;
988  else if(maxXiHit->getZetaID()-minXiHit->getZetaID()<=0 && maxZetaHit->getXiID()-minZetaHit->getXiID()<=0) tilt=2;
989  else tilt=0;
990  }
991 
992  double xiave = xiene/enesum;
993  double zetaave = zetaene/enesum;
994  double eta0 = _geodata[layer].rmin+0.5*_pixelheight +(layer%2)*(_geodata[layer].sthick-_pixelheight);
995 
996  //Mori2ndCut
997  double mxi = xiave+_geodata[layer].sximin ;
998  double mzeta = zetaave-_geodata[layer].hlength;
999  if(_m2Cut.isActive != true || _m2Cut.zpar[layer] < 0 || ( (mxi * mzeta >= -_m2Cut.zpar[layer] || tilt != 1) && (mxi * mzeta <= _m2Cut.zpar[layer] || tilt != 2) ) ) {
1000 
1001 
1002  double newpos[3];
1003  newpos[0] = (xiave+_geodata[layer].sximin)*_geodata[layer].sinphi[ladder]
1004  + eta0*_geodata[layer].cosphi[ladder];
1005  newpos[1] =-(xiave+_geodata[layer].sximin)*_geodata[layer].cosphi[ladder]
1006  + eta0*_geodata[layer].sinphi[ladder];
1007  newpos[2] = zetaave-_geodata[layer].hlength;
1008  //store hit variables
1009 
1010  //Kamai2ndCut
1011  if(_k2Cut.isActive != true || int(zetaWidth) <= _k2Cut.minZWidth[layer] || float(zetaWidth) > (std::abs(newpos[2])*_pixelheight/sqrt(pow(newpos[0],2)+pow(newpos[1],2))/_pixelSizeVec[layer] - _k2Cut.bpar[layer] ) ){
1012 
1013 
1014 
1015  //*******************************Mori added 20121203*************************************//
1016  // Here finds the numbers of types of simthits that create trkhit in this scope.
1017  std::vector<int> typesOfOrderID;
1018  orderVecOfCluster.sort(); //sort() also sort order Vec
1019  std::list<int>::iterator itlist;
1020  int tmpV = -1000;
1021  for(itlist = orderVecOfCluster.begin(); itlist != orderVecOfCluster.end(); itlist++){
1022  if(*itlist != tmpV){
1023  typesOfOrderID.push_back(*itlist);
1024  tmpV = *itlist;
1025  }
1026  }
1027  //********************************************************************************************//
1028 
1029  float pointResoRPhi = 0.0;
1030  float pointResoZ = 0.0;
1031  if(_positionReso_ReadingFile_ON == true){
1032 
1033  short int codeRPhi = layer * 100 + xiWidth;
1034  if(xiWidth <= 49){
1035  pointResoRPhi = _resolutionMapRPhi[codeRPhi];
1036  if(pointResoRPhi < 0.00001){ pointResoRPhi = (sqrt((float)(xiWidth + 1.5)) - 1)*1e-3; }
1037  }
1038  else{ pointResoRPhi = (sqrt((float)(xiWidth + 1.5)) - 1)*1e-3; }
1039 
1040  short int codeZ = layer * 100 + zetaWidth;
1041  if(zetaWidth <= 49){
1042  pointResoZ = _resolutionMapZ[codeZ];
1043  if(pointResoZ < 0.00001){ pointResoZ = (sqrt((float)(zetaWidth + 1.5)) - 1)*1e-3; }
1044  }
1045  else{ pointResoZ = (sqrt((float)(zetaWidth + 1.5)) - 1)*1e-3; }
1046 
1047  }
1048  else{
1049  pointResoRPhi = _pointResoRPhi;
1050  pointResoZ = _pointResoZ;
1051  }
1052 
1053 
1054  TrackerHitPlaneImpl* trkHit = new TrackerHitPlaneImpl ;
1055 
1056  trkHit->setType( 100 + layer);
1057 
1058  cellid_encoder[ lcio::LCTrackerCellID::subdet() ] = lcio::ILDDetID::VXD ;
1059  cellid_encoder[ lcio::LCTrackerCellID::side() ] = 0 ;
1060  cellid_encoder[ lcio::LCTrackerCellID::layer() ] = layer ;
1061  cellid_encoder[ lcio::LCTrackerCellID::module() ] = ladder ;
1062  cellid_encoder[ lcio::LCTrackerCellID::sensor() ] = 0 ;
1063 
1064  cellid_encoder.setCellID( trkHit );
1065 
1066  unsigned int cellid1=0;
1067  cellid1 = ((trackquality << 30) & 0xc0000000) |
1068  ((tilt << 28) & 0x30000000) |
1069  ((nPix << 18) & 0x0ffc0000) |
1070  ((zetaWidth << 9) & 0x0003fe00) |
1071  ((xiWidth) & 0x000001ff) ;
1072 
1073  trkHit->setCellID1(cellid1);
1074  float u_direction[2] ;
1075  u_direction[0] = M_PI/2.0;
1076  u_direction[1] = _geodata[layer].ladder_incline[ladder] ;
1077 
1078  float v_direction[2] ;
1079  v_direction[0] = 0.0 ;
1080  v_direction[1] = 0.0 ;
1081 
1082  trkHit->setU( u_direction ) ;
1083  trkHit->setV( v_direction ) ;
1084 
1085 
1086  //printf("mori check : pointResoRPhi,pointResoZ : %f,%f \n",pointResoRPhi,pointResoZ);
1087  trkHit->setdU( pointResoRPhi ) ;
1088  trkHit->setdV( pointResoZ ) ;
1089 
1090  trkHit->setPosition( newpos ) ;
1091  trkHit->setEDep( enesum );
1092 
1093  //LCRelationImpl* rel = new LCRelationImpl ;
1094  if(_makeRelation == true){
1095  SimTrackerHit* p_simthit;
1096  int ntypes = typesOfOrderID.size();
1097  for(int i = 0; i < ntypes; i++){
1098  LCRelationImpl* rel = new LCRelationImpl ;
1099  if(typesOfOrderID[i] >= 0){
1100  p_simthit = dynamic_cast<SimTrackerHit*>( STHcol->getElementAt( typesOfOrderID[i] ) ) ;
1101  float nTo = static_cast<float>( ntypes );
1102  rel->setTo( p_simthit );
1103  rel->setFrom( trkHit );
1104  rel->setWeight( nTo ); //Weight is defined as nFrom/nTo by Mori. ->今はnTo/nFrom
1105  relCol->addElement( rel );
1106  }// If typesOfOrderID[i] == -1, then it is background data.
1107  }
1108  }
1109  trkHitVec->addElement( trkHit );
1110  }//end of Kamai2ndCut
1111  }//end of Mori2ndCut
1112  }//end of if statement for RPhi Cut of firstCut
1113  }//end of if statement for Z Cut of firstCut
1114  }// Repeat pixel hits in this ladder.
1115 
1116 }
1117 
1118 
1119 
1120 
1121 
1122 
1123 //void FPCCDClustering::viewerOfClusterShape(FPCCDClusterVec_t &clusterVec);
1124 
1125 // =====================================================================
1127 {
1128  //typedef std::pair<unsigned int, unsigned int> FPCCDHitLoc_t;
1129  //typedef std::map<FPCCDHitLoc_t, FPCCDPixelHit*> FPCCDLadderHit_t;
1130  // namely, std::map<std::pair<unsigned int, unsigned int>, FPCCDPixelHit*>
1131 
1132  //typedef std::vector<FPCCDPixelHit*> FPCCDCluster_t;
1133  //typedef std::vector<FPCCDCluster_t*> FPCCDClusterVec_t;
1134  //namely, std::vector<std::vector<FPCCDPixelHit*>>
1135 
1136 
1137  //(2) Start pixel hit clustering
1138  // All pixels adjucent pixels are clustered, if it has a hit. Threshold is not considered yet
1139  // 2013_06_07 I think thresold cut has been done before makeClustersInALadder(...).
1140 
1141  int maxxi = _geodata[layer].num_xi_pixel;
1142  int maxzeta = _geodata[layer].num_zeta_pixel;
1143 
1144  FPCCDLadderHit_t::iterator ih = ladderHit.begin();
1145  while( ih != ladderHit.end() ) {
1146  FPCCDPixelHit *h=(*ih).second;
1147  (*ih).second=0;
1148  ih++;
1149  if( h==0 ) { continue; }
1150  // std::cerr << "Found a seed pixel. Edep=" << h->getEdep() << std::endl;
1151  // Found a ssed of a cluster
1152 
1153  FPCCDCluster_t *cluster=new FPCCDCluster_t();
1154  cluster->push_back(h);
1155  int xi0=h->getXiID();
1156  int zeta0=h->getZetaID();
1157  typedef std::pair<int, int> Direction_t;
1158  std::stack<Direction_t> direction;
1159  for(int i=-1;i<=1;i++) { // Set initial search direction, neighbouring 8 pixels are searched
1160  for(int j=-1;j<=1;j++) {
1161  if( i!=0 || j!= 0 ) { direction.push(Direction_t(i,j)); }
1162  }
1163  }
1164  // Now look for all directions and find pixel with hit.
1165  while( ! direction.empty() ) {
1166  Direction_t newdir=direction.top();
1167  int xi=xi0+newdir.first;
1168  int zeta=zeta0+newdir.second;
1169  // std::cerr << "searching at (xi,zeta)=" << xi << " " << zeta << std::endl;
1170  if( xi < 0 || xi > maxxi || zeta < 0 || zeta > maxzeta ) {
1171  direction.pop(); continue;
1172  }
1173  FPCCDHitLoc_t newloc(xi, zeta);
1174  FPCCDLadderHit_t::iterator look=ladderHit.find(newloc);//If not found, end iterator is returned.
1175  if( look == ladderHit.end() ) {
1176  direction.pop(); continue;
1177  }
1178  FPCCDPixelHit *aHit=(*look).second;
1179  if( aHit == 0 ) {
1180  direction.pop(); continue;
1181  }
1182  cluster->push_back( aHit );
1183  // std::cout << " Found hit .. at xi, zeta=" << xi << " " << zeta << std::endl;
1184  (*look).second=0;
1185  for (int ix=-1;ix<=1;ix++) {
1186  for(int iz=-1;iz<=1;iz++) {
1187  if( ix != 0 || iz != 0 ) {
1188  direction.push(Direction_t(newdir.first+ix, newdir.second+iz));
1189  }
1190  }
1191  }
1192  } // Complete search of all nighbours of the seed
1193  if( cluster->size() > 0 ) {
1194  //Mori added
1195  if(_firstCut.isActive != true || _firstCut.nPix[layer] < 0 || cluster->size() < static_cast<unsigned int>(_firstCut.nPix[layer])){
1196  clusterVec.push_back(cluster);
1197  }
1198  }
1199  }
1200 }
1201 
1202 
1203 // =====================================================================
1204 void FPCCDClustering::check( LCEvent * /*evt*/ ) {
1205  // nothing to check here - could be used to fill checkplots in reconstruction processor
1206 }
1207 
1208 
1209 // =====================================================================
1211 
1212 #if ROOT_DEBUG
1213  _rootf->Write();
1214 #endif
1215 
1216  streamlog_out(MESSAGE) << " end() " << name()
1217  << " processed " << _nEvt << " events in " << _nRun << " runs "
1218  << std::endl ;
1219 
1220 }
1221 
1222 
1223 // =================================================================
1224 // =================================================================
1225 void FPCCDClustering::EnergyDigitizer( FPCCDPixelHit* aHit ){
1226 
1227  int nEle = (int)(aHit->getEdep()*1e+6 * _electronsPerKeV) ;
1228  int nStep = 1 << _nbitsForEdep ;
1229  int count = nEle/ _electronsPerStep ; // int devided by int equales int.
1230 
1231  if(count > nStep ) count = nStep ;
1232 
1233  aHit->setEdep( (count * _electronsPerStep)*1e-6 / _electronsPerKeV) ;
1234  return ;
1235 }
1236 
1237 
1238 
1239 
1240 
1241 
1242 
1243 
1244 
1245 
1246 
1247 
1248 
1249 
1250 void FPCCDClustering::calcTrackParameterOfMCP(MCParticle* pmcp, double* par){
1251  //KalTest Reference Manual page 17
1252 
1253  double bz = Global::GEAR->getBField().at( gear::Vector3D( 0.,0.,0.) ).z() ;
1254  const double* p;
1255  p = pmcp->getMomentum();
1256  const double pi = 3.14159265359;
1257  const double pt = sqrt(p[0]*p[0]+p[1]*p[1]) ;
1258  double radius = pt / (2.99792458E-4*bz) ; // for r in mm, p in GeV and Bz in Tesla
1259  double omega = pmcp->getCharge()/radius ;
1260  double tanL = p[2]/pt ;
1261  double oldphi0 = atan2(p[1],p[0]);
1262  while( oldphi0 <= -pi ){ oldphi0 += 2. * pi ; }
1263  while( oldphi0 > pi ){ oldphi0 -= 2. * pi ; }
1264 
1265  double oldsinphi0 = std::sin(oldphi0);
1266  double oldcosphi0 = std::cos(oldphi0);
1267  double centx = pmcp->getVertex()[0] + 1/omega * oldcosphi0;
1268  double centy = pmcp->getVertex()[1] + 1/omega * oldsinphi0;
1269  double newphi0;
1270  if(omega > 0){ newphi0 = std::atan2(centy,centx); }
1271  else{ newphi0 = std::atan2(-centy,-centx); }
1272  double sinphi0 = std::sin(newphi0);
1273  double cosphi0 = std::cos(newphi0);
1274  double d0 = centx * cosphi0 + centy * sinphi0 - 1.0/omega ;
1275  double z0 = pmcp->getVertex()[2] - 1.0/omega *(newphi0 - oldphi0)*tanL;
1276  /*
1277  std::cout << "Test Pivot Transformation " << std::endl;
1278  std::cout << "d0 : " << d0 << std::endl;
1279  std::cout << "z0 : " << z0 << std::endl;
1280  std::cout << "omega : " << omega << std::endl;
1281  std::cout << "phi0 : " << newphi0 << std::endl;
1282  std::cout << "tanL : " << tanL << std::endl;
1283  */
1284  par[0] = d0;
1285  par[1] = z0;
1286  par[2] = omega;
1287  par[3] = newphi0;
1288  par[4] = tanL;
1289 }
struct FPCCDClustering::firstCut _firstCut
virtual void init()
Called at the begin of the job before anything is read.
int layer[MAX_LINK]
unsigned int nPix[MAX_LINK]
ResoMap _resolutionMapRPhi
double xi[MAX_LINK]
std::pair< unsigned int, unsigned int > FPCCDHitLoc_t
std::vector< GeoData_t > _geodata
std::ifstream _fin
std::string _rootFileName
bool _positionReso_ReadingFile_ON
const float pi
Definition: G2CD.cc:34
struct FPCCDClustering::Kamai2ndCut _k2Cut
std::map< FPCCDHitLoc_t, FPCCDPixelHit * > FPCCDLadderHit_t
CLHEP::Hep3Vector Vector3D
double zeta[MAX_LINK]
unsigned int tilt[MAX_LINK]
struct FPCCDClustering::@11 _simthits
std::string _outRelColNameVTX
std::string _positionReso_ReadingFile
void makeClustersInALadder(int layer, FPCCDLadderHit_t &ladderHit, FPCCDClusterVec_t &cvec)
FloatVec _pixelSizeVec
FPCCDClustering aFPCCDClustering
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
std::string _outColNameVTX
std::string _treeName
double phi[MAX_LINK]
void calcTrackParameterOfMCP(MCParticle *pmcp, double *par)
std::vector< FPCCDCluster_t * > FPCCDClusterVec_t
std::string _colNameVTX
struct FPCCDClustering::Mori2ndCut _m2Cut
static const float e
std::string _colNameSTH
std::vector< LCCollection * > LCCollectionVec
Definition: SiStripClus.h:55
std::vector< FPCCDPixelHit * > FPCCDCluster_t
int ladder[MAX_LINK]
virtual void end()
Called after data processing for clean up.
virtual void check(LCEvent *evt)
Called for every event - the working horse.
void EnergyDigitizer(FPCCDPixelHit *aHit)
struct FPCCDClustering::@13 _diff
struct FPCCDClustering::@12 _trkhits
bool _remove_pixelhits_collection
struct FPCCDClustering::@10 _link
virtual const std::string & name() const
virtual void modifyEvent(LCEvent *evt)
void makeTrackerHit(LCCollection *STHcol, int layer, int ladder, FPCCDClusterVec_t &cvec, std::multimap< std::pair< int, int >, SimTrackerHit * > relMap, LCCollectionVec *relCol, LCCollectionVec *trkHitVec)
void makeTrackerHitVec(FPCCDData *pxHits, LCCollection *STHcol, LCCollectionVec *relCol, LCCollectionVec *trkHitvec)