Example #1
0
void testgeo(const char* rootfile)
{

  // Clear global scope
  gROOT->Reset();

  // Load the library with class dictionary info
  gSystem->Load("libWCSimRoot.so");

  // Open the file, replace if you've named it something else
  TFile file(rootfile);
  
  // Get the a pointer to the tree from the file
  TTree *gtree = (TTree*)file.Get("wcsimGeoT");
  
  // Get the number of events
  int nevent = gtree->GetEntries();
  printf("geo nevent %d\n",nevent);
  
  // Create a WCSimRootGeom to put stuff from the tree in

  WCSimRootGeom* wcsimrootgeom = new WCSimRootGeom();

  // Set the branch address for reading from the tree
  TBranch *branch = gtree->GetBranch("wcsimrootgeom");
  branch->SetAddress(&wcsimrootgeom);

  // Now loop over "events"  (should be only one for geo tree)
  int ev;
  for (ev=0;ev<nevent; ev++)  {
      // Read the event from the tree into the WCSimRootGeom instance
      gtree->GetEntry(ev);
      printf("Cyl radius %f\n", wcsimrootgeom->GetWCCylRadius());
      printf("Cyl length %f\n", wcsimrootgeom->GetWCCylLength());
      printf("PMT radius %f\n", wcsimrootgeom->GetWCPMTRadius());
      printf("Offset x y z %f %f %f\n", wcsimrootgeom->GetWCOffset(0),
	     wcsimrootgeom->GetWCOffset(1),wcsimrootgeom->GetWCOffset(2));
      int numpmt = wcsimrootgeom->GetWCNumPMT();
      printf("Num PMTs %d\n", numpmt);

      int i;
      for (i=0;i<((numpmt<20)?numpmt:20);i++){
	WCSimRootPMT pmt;
	pmt = wcsimrootgeom->GetPMT(i);
	printf ("pmt %d %d %d\n",i,pmt.GetTubeNo(), pmt.GetCylLoc());
	printf ("position: %f %f %f\n", pmt.GetPosition(0),
		pmt.GetPosition(1),pmt.GetPosition(2));
	printf ("orientation: %f %f %f\n", pmt.GetOrientation(0),
		pmt.GetOrientation(1),pmt.GetOrientation(2));
      }
            
    } // End of loop over events

}
double fitQunDisplay::cosAngleToTube(double pos[3],double cerenkov[3],int tubeId)
{
	WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( tubeId );
	int location= pmt.GetCylLoc();
	if(location !=0 && location !=1 && location !=2)return -999;
	double pmtX = pmt.GetPosition (0) - pos[0];
	double pmtY = pmt.GetPosition (1) - pos[1];
	double pmtZ = pmt.GetPosition (2) - pos[2];
	double dot=pmtX*cerenkov[0]+pmtY*cerenkov[1]+pmtZ*cerenkov[2];
	double lTube=sqrt(pmtX*pmtX+pmtY*pmtY+pmtZ*pmtZ);
	double lCerenkov=sqrt(cerenkov[0]*cerenkov[0]+cerenkov[1]*cerenkov[1]+cerenkov[2]*cerenkov[2]);
	
	double cosAng=dot/lTube/lCerenkov;
	return cosAng;
}
bool fitQunDisplay::FindConeEnd(double pos[3],double cerenkov[3],double endPoint[3],int &location)
{
	if(wcsimrootgeom==NULL)return false;
	/*
	Loop over all tubes and find 3 nearest ones from which
	we can form a plane
	*/
	bool debug=kFALSE;
	if(debug)cout<<endl<<" fitQunDisplay::FindConeEnd starts"<<endl;
	float maxCosine=-1.0;
	float nextMaxCosine=-1.0;
	float nextNextMaxCosine=-1.0;
	int  tubes[3];
	
	double lCerenkov=sqrt(cerenkov[0]*cerenkov[0]+cerenkov[1]*cerenkov[1]+cerenkov[2]*cerenkov[2]);
	double  l1 = cerenkov[0]/lCerenkov;
	double  l2 = cerenkov[1]/lCerenkov;
	double  l3 = cerenkov[2]/lCerenkov; 
	double  px=pos[0];
	double  py=pos[1];
	double  pz=pos[2];
	
	/*
	First look close to the last tube we found (maxTube), if we have one.
	*/
	
	if(maxTube>0)
	{
		if(debug)cout<<" start searching close to previous candidate "<<maxTube;
		WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( maxTube );
		float pmtx=pmt.GetPosition (0);
		float pmty=pmt.GetPosition (1);
		float pmtz=pmt.GetPosition (2);
		if(debug)cout<<" located at "<<pmtx<<" , "<<pmty<<" , "<<pmtz<<endl;
		if(debug)cout<<" min/max z "<<minZ<<" "<<maxZ<<endl;
		if(debug)cout<<" maxR "<<maxR<<endl;
		location=pmt.GetCylLoc();
		/*
		Check for situations where we are about to jump from cylinder to end wall or vice versa.
		In these cases just looking around the previous tube does not work, so don't try
		*/
		if(location==1){
			if(pmtz<(minZ+50) || pmtz>(maxZ-50)){
				//cout<<" cylinder tube is close to min or max Z"<<endl;
				maxTube=-1;
				goto Global;
			}
		}
		if(location==0||location==2){
			float r=sqrt(pmtx*pmtx+pmty*pmty);
			//cout<<" end cap tube r"<<r<<endl;
			
			if(r>(maxR-500)){
				//cout<<" is close to maxR"<<maxR<<endl;
				maxTube=-1;
				goto Extrapolate;
			}
			//else
			//	cout<<" is ok "<<endl;
		}
		int xI,yI,zI;
		if(location==0)
		{
			pmtx=pmt.GetPosition (0);
			xI=xyIndex(pmtx);
			pmty=pmt.GetPosition (1);
			yI=xyIndex(pmty);
			searchForTube(PositiveCapTubeList,xI,yI,maxYIndex,pos,cerenkov,debug,tubes);
		}
		if(location==1)
			
		{
			zI=zIndex(pmtz);
			int phiI=phiIndex(pmtx,pmty);
			//int zStep=20;
			//int phiStep=20;
			searchForTube(CylinderTubeList,zI,phiI,360,pos,cerenkov,debug,tubes);
		}
		if(location==2)
		{
			//	cout<<" search in -ve cap "<<endl;
			
			xI=xyIndex(pmtx);
			yI=xyIndex(pmty);
			searchForTube(NegativeCapTubeList,xI,yI,maxYIndex,pos,cerenkov,debug,tubes);
		}
		maxTube=tubes[0];
	}
	/*
	Calculate phi, z index to start looking in the array of tube ids.
	
	Assume detector is a cylinder of radius maxR, end plates as minZ, maxZ
	
	*/
Extrapolate:
	if(maxTube<0)
	{
		if(debug)cout<<" start searching close to extrapolated cerenkov light "<<endl;
		
		float xc,yc;
		lineTubeIntersect(cerenkov,pos,maxR,xc,yc);
		//cout<<" xc,yc from lineTubeIntersect"<<xc<<" "<<yc<<endl;	
		//cout<<" point of intersect is "<<xc<<" "<<yc<<endl;
		float rp=sqrt(px*px+py*py);
		float rc = maxR-rp;
		
		float theta = acos(l3);
		float czIntersect = pz+ rc/tan(theta);
		//cout<<"  czIntersect= "<<czIntersect<<" compare to "<<minZ<<" "<<maxZ<<endl;
		if(czIntersect<minZ||czIntersect>maxZ)
		{
			//cout<<" probably in end plates. czIntersect= "<<czIntersect<<" compare to "<<minZ<<" "<<maxZ<<endl;
			/* calculate x,y if we have hit an end plate */
			if(l3>0)rc=(maxZ-pz)*tan(theta);
			else rc=(minZ-pz)*tan(theta);
			float rCap=rc+rp;
			//	cout<<" r at end cap is "<<rCap<<endl;
			lineTubeIntersect(cerenkov,pos,rCap,xc,yc);
			//	cout<<" xc,yc from lineTubeIntersect: "<<xc<<" "<<yc;
			int xI = xyIndex(xc);
			int yI = xyIndex(yc);
			//	cout<<" x/y indices: "<<xI<<" "<<yI<<endl;
			//	int xStep=50;
			//	int yStep=50;
			//temp!
			if(czIntersect>maxZ)
			{
				//	cout<<" search in positive cap "<<endl;
				searchForTube(PositiveCapTubeList,xI,yI,maxYIndex,
					pos,cerenkov,kFALSE,tubes);
			}
			else
			{
				//	cout<<" search in negative cap "<<endl;
				searchForTube(NegativeCapTubeList,xI,yI,maxYIndex,
					pos,cerenkov,kFALSE,tubes);
			}
			
		}
		else
		{
			if(debug)cout<<" intersect with cylinder = "<<xc<<" "<<yc<<" "<<czIntersect<<endl;
			int zI = zIndex(czIntersect);
			int phiI = phiIndex(xc,yc);
			//	cout<<" phi and z index "<<phiI<<" "<<zI<<endl;
			//	cout<<" tube at this location is "<<CylinderTubeList[zI*maxPhiIndex+phiI]<<endl;
			/*
			search for tubes near this index
			*/
			//	int zStep=20;
			//	int phiStep=20;
			if(debug)cout<<"search in cylinder "<<endl;
			searchForTube(CylinderTubeList,zI,phiI,360,pos,cerenkov,debug,tubes);
		}
	}
	maxTube=tubes[0];
	nextMaxTube=tubes[1];
	nextNextMaxTube=tubes[2];
Global:
	if(maxTube<0 ||nextMaxTube<0 || nextNextMaxTube<0 )
	{
		/* that also failed so do a global search */
		if(debug)cout<<" trying a brute force search "<<endl;
		for(int tubeId=0;tubeId<wcsimrootgeom->GetWCNumPMT();tubeId++)
		{
			
			double cosAng=cosAngleToTube(pos,cerenkov,tubeId);
			if(cosAng<-100)continue;
			
			if(cosAng>maxCosine){
				nextNextMaxCosine=nextMaxCosine;
				nextMaxCosine=maxCosine;
				maxCosine=cosAng;
				nextNextMaxTube=nextMaxTube;
				nextMaxTube=maxTube;
				maxTube=tubeId;
			}
			else if(cosAng>nextMaxCosine)
			{
				nextNextMaxCosine=nextMaxCosine;
				nextMaxCosine=cosAng;
				nextNextMaxTube=nextMaxTube;
				nextMaxTube=tubeId;
			}
			else if(cosAng>nextNextMaxCosine)
			{
				nextNextMaxCosine=cosAng;
				nextNextMaxTube=tubeId;
			}
			
		}
	}
	/*
	We need all three close tubes to be part of the same part of the detector
	to avoid corner effects
	*/
	if(debug)cout<<" tubes found:"<<maxTube<<" "<<nextMaxTube<<" "<<nextNextMaxTube<<endl;
	if(maxTube<0)return kFALSE;
	if(nextMaxTube<0)return kFALSE;
	if(nextNextMaxTube<0)return kFALSE;
	if(debug)cout<<" plane of tubes found ok"<<maxTube<<" "<<nextMaxTube<<" "<<nextNextMaxTube<<endl;
	WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( maxTube );
	if(debug)cout<<" position of nearest "<<pmt.GetPosition (0)<<" , "<<pmt.GetPosition (1)<<" , "<<pmt.GetPosition (2)<<endl;
	pmt = wcsimrootgeom -> GetPMT (maxTube); 
	location= pmt.GetCylLoc();
	if(debug)cout<<" location type of nearest tube is "<<location<<endl;
	if(wcsimrootgeom -> GetPMT (nextMaxTube).GetCylLoc() != location){
		//	cout<<" next tube not in same location "<<endl;
		return kFALSE; 
	}
	if(wcsimrootgeom -> GetPMT (nextNextMaxTube).GetCylLoc() != location){
		//	cout<<" next to next  tube not in same location "<<endl;
		return kFALSE;
	}
	/*
	Now calculate the point that cerenkov vector
	crosses the plane formed by three nearest tubes
	*/
	pmt = wcsimrootgeom -> GetPMT (maxTube); 
	double Xt1= pmt.GetPosition (0);  	
	double Yt1= pmt.GetPosition (1);  	
	double Zt1= pmt.GetPosition (2);  	
	pmt = wcsimrootgeom -> GetPMT (nextMaxTube); 
	double Xt2= pmt.GetPosition (0);  	
	double Yt2= pmt.GetPosition (1);  	
	double Zt2= pmt.GetPosition (2);  
	pmt = wcsimrootgeom -> GetPMT (nextNextMaxTube); 
	double Xt3= pmt.GetPosition (0);  	
	double Yt3= pmt.GetPosition (1);  	
	double Zt3= pmt.GetPosition (2); 
	
	if(debug)cout<<" location of next neighbour "<<Xt2<<" "<<Yt2<<" "<<Zt2<<endl;
	if(debug)cout<<" location of next next neighbour "<<Xt3<<" "<<Yt3<<" "<<Zt3<<endl;
	/*
	construct vectors along two sides of triangle 
	formed by 3 nearest tubes
	*/
	double u1=Xt2-Xt1;
	double u2=Yt2-Yt1;
	double u3=Zt2-Zt1;
	double v1=Xt3-Xt1;
	double v2=Yt3-Yt1;
	double v3=Zt3-Zt1;
	/*
	Normal to the plane:
	*/
	double n1 = u2*v3-u3*v2;
	double n2 = u3*v1-u1*v3;
	double n3 = u1*v2-u2*v1;
	
	/*
	If there is no normal to the plane, return an error 
	*/
	if((n1*n1+n2*n2+n3*n3)==0)
		return kFALSE;
	/*
	Now solve for the distance along the cerenkov vector to this plane
	
	d = (p0 - l0) . n /l.n
	where p0 is a point on the plane, l0 is a point on the line and
	l is a vector along the line
	*/
	l1 = cerenkov[0]/lCerenkov;
	l2 = cerenkov[1]/lCerenkov;
	l3 = cerenkov[2]/lCerenkov; 
	
	double lDotn = l1*n1+l2*n2+l3*n3;
	
	double p0minusl0X =  Xt1 - pos[0];
	double p0minusl0Y =  Yt1 - pos[1];
	double p0minusl0Z =  Zt1 - pos[2];
	
	
	double p0minusl0ZDotN = p0minusl0X*n1+p0minusl0Y*n2+p0minusl0Z*n3;
	
	double distance = p0minusl0ZDotN / lDotn;
	
	endPoint[0]=pos[0]+distance*l1;
	endPoint[1]=pos[1]+distance*l2;
	endPoint[2]=pos[2]+distance*l3;
	/*
	Calculate distance between end point and nearest tube
	
	*/
	double TEx=endPoint[0]-Xt1;
	double TEy=endPoint[1]-Yt1;
	double TEz=endPoint[2]-Zt1;
	float Tube2EndPoint=sqrt(TEx*TEx+TEy*TEy+TEz*TEz);
	/*
	Calculate distance between tube and nearest neighbour(s)
	*/
	double TNx=Xt2-Xt1;
	double TNy=Yt2-Yt1;
	double TNz=Zt2-Zt1;
	float Tube2Neighbour=sqrt(TNx*TNx+TNy*TNy+TNz*TNz);
	double TNNx=Xt3-Xt1;
	double TNNy=Yt3-Yt1;
	double TNNz=Zt3-Zt1;
	float Tube2NextNeighbour=sqrt(TNNx*TNNx+TNNy*TNNy+TNNz*TNNz);
	if(debug)cout<<" distance from end point to tube is "<<Tube2EndPoint<<endl;
	if(debug)cout<<" distance from neighbour to tube is "<<Tube2Neighbour<<endl;
	if(debug)cout<<" distance from next neighbour to tube is "<<Tube2NextNeighbour<<endl;
	if(Tube2EndPoint>Tube2Neighbour)
	{
	 	if(debug) cout<<" return false "<<endl;
	 	return kFALSE;
	}
	if(Tube2NextNeighbour>(1.5*Tube2Neighbour))
	{
	 	if(debug) cout<<" return false "<<endl;
	 	return kFALSE;
	}
	
	
	
	if(endPoint[2]<minZ)endPoint[2]=minZ;
	if(endPoint[2]>maxZ)endPoint[2]=maxZ;
	if(debug)cout<<" succesful return "<<endl;
	if(debug)cout<<" location of end point  is "<<endPoint[0]<<" "<<endPoint[1]<<" "<<endPoint[2]<<endl;
	
	//if(location !=1)
	//{
	//	float r=sqrt(endPoint[0]*endPoint[0]+endPoint[1]*endPoint[1]);
	//	cout<<" end point R = "<<r<<endl;
	//}
	
	return kTRUE;
}
void fitQunDisplay::PreProcessGeometry()
{
	
	nZvalues=(maxZ-minZ)/100;
	maxZIndex=0;
	maxPhiIndex=0;
	
	for(int tubeId=0;tubeId<wcsimrootgeom->GetWCNumPMT();tubeId++)
    	{
    		
    		WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( tubeId );
    		double pmtX = pmt.GetPosition (0);
    		double pmtY = pmt.GetPosition (1);
    		double pmtZ = pmt.GetPosition (2) ;
    		int location= pmt.GetCylLoc();
    		if(location ==1 )
    		{
    			
    			int zI = zIndex(pmtZ);
    			int phiI = phiIndex(pmtX,pmtY);
    			if(zI>maxZIndex)maxZIndex=zI;
    			if(phiI>maxPhiIndex)maxPhiIndex=phiI;
    		}
    		else
    		{
    			int xI = xyIndex(pmtX);
    			int yI = xyIndex(pmtY);
    			if(xI>maxXIndex)maxXIndex=xI;
    			if(yI>maxYIndex)maxYIndex=yI;
    		}
    		
    	}
    	CylinderTubeList = new int[(maxZIndex+1)*maxPhiIndex];	
    	for(int i = 0;i<(maxZIndex+1)*maxPhiIndex;i++)CylinderTubeList[i]=-1;
    	NegativeCapTubeList = new int[(maxXIndex+1)*maxYIndex];	
    	for(int i = 0;i<(maxXIndex+1)*maxYIndex;i++)NegativeCapTubeList[i]=-1;
    	
	PositiveCapTubeList = new int[(maxXIndex+1)*maxYIndex];	
    	for(int i = 0;i<(maxXIndex+1)*maxYIndex;i++)PositiveCapTubeList[i]=-1;
    	
    	int count=0;
    	for(int tubeId=0;tubeId<wcsimrootgeom->GetWCNumPMT();tubeId++)
    	{
   		
    		WCSimRootPMT pmt = wcsimrootgeom -> GetPMT ( tubeId );
    		double pmtX = pmt.GetPosition (0);
    		double pmtY = pmt.GetPosition (1);
    		double pmtZ = pmt.GetPosition (2) ;
    		int location= pmt.GetCylLoc();
    		if(location ==1 )
    		{
    			int zI = zIndex(pmtZ);
    			int phiI = phiIndex(pmtX,pmtY);
    			if(zI*maxPhiIndex+phiI>(maxZIndex+1)*maxPhiIndex)
    			{
    				cout<<" ERROR "<<endl;
    				cout<<pmtX<<" "<<pmtY<<" "<<pmtZ<<" "<<zI<<" "<<phiI<<endl;
    				cout<<" fill item "<<zI<<" "<<phiI<<" with "<<tubeId<<endl;
    				cout<<" index is "<<zI*maxPhiIndex+phiI<<endl;
    				cout<<" array dimensions are "<<(maxZIndex+1)*maxPhiIndex<<endl;
    			}
    			else
    				CylinderTubeList[zI*maxPhiIndex+phiI]=tubeId;
    		}
    		else 
    		{
    			int xI = xyIndex(pmtX);
    			int yI = xyIndex(pmtY);
    			if(xI*maxYIndex+yI>(maxXIndex+1)*maxYIndex)
    			{
    				cout<<" ERROR "<<endl;
    				cout<<pmtX<<" "<<pmtY<<" "<<pmtZ<<" "<<xI<<" "<<yI<<endl;
    				cout<<" fill item "<<xI<<" "<<yI<<" with "<<tubeId<<endl;
    				cout<<" index is "<<xI*maxYIndex+yI<<endl;
    				cout<<" array dimensions are "<<(maxXIndex+1)*maxYIndex<<endl;
    			}
    			else
    			{
    				if(location==0)
    				{
    					PositiveCapTubeList[xI*maxYIndex+yI]=tubeId;
    					count+=20;
    					//if(count>100){cout<<endl;count=0;}
    				}
    				if(location==2)
    					NegativeCapTubeList[xI*maxYIndex+yI]=tubeId;
    			}
    		}
    		
    		
    	}
    	
}
Example #5
0
void pmtremove(TString infile, TString outfile, double removefrac)
{
  // read old geometry from the input rootfile

  TFile *f2 = new TFile(infile);  
  TTree *oldtree = (TTree*)f2->Get("wcsimGeoT");
  WCSimRootGeom* oldgeom = new WCSimRootGeom();
  TBranch *gb = oldtree->GetBranch("wcsimrootgeom");
  gb->SetAddress(&oldgeom);
  oldtree->GetEntry(0);
  int oldpmtnum = oldgeom->GetWCNumPMT();
  Printf("Initial Number of PMTs: %d", oldpmtnum);

  // set up the new output file
  TFile *f3 = new TFile(outfile,"RECREATE");
  TTree *newtree = oldtree->CloneTree(0);
  WCSimRootGeom* newgeom = new WCSimRootGeom();  
  newtree->SetBranchAddress("wcsimrootgeom",&newgeom);

  newgeom->SetWCCylRadius(oldgeom->GetWCCylRadius());
  newgeom->SetWCCylLength(oldgeom->GetWCCylLength());
  newgeom->SetMailBox_x(oldgeom->GetMailBox_x());
  newgeom->SetMailBox_y(oldgeom->GetMailBox_y());
  newgeom->SetMailBox_z(oldgeom->GetMailBox_z());
  newgeom->SetGeo_Type(oldgeom->GetGeo_Type());
  newgeom->SetWCOffset(oldgeom->GetWCOffset(0),
		       oldgeom->GetWCOffset(1),
		       oldgeom->GetWCOffset(2));
  newgeom->SetOrientation(oldgeom->GetOrientation());
  newgeom->SetWCPMTRadius(oldgeom->GetWCPMTRadius());

  // associates old PMTs with new PMTs  Index into it is the old pmt number,
  // gives back new PMT number.  If PMT is removed, this array has -1 in it.

  const int asize = oldpmtnum + 1;
  int pmtassoc[asize];

  int newpmtnum = 0;
  int ict = 0;  // old floor count
  for (int i=0;i<oldpmtnum;i++)
    {
      WCSimRootPMT pmt = oldgeom->GetPMT(i);
      int oldtubeno = pmt.GetTubeNo();
      double ft = removefrac*( (double) i);
      int icc = (int) floor(ft);  // check to see when this rolls around another integer

      if ( ict != icc)
	{
	  ict = icc;  
	  pmtassoc[oldtubeno] = -1;  // and remove this tube
	}
      else
	{
          pmtassoc[oldtubeno] = newpmtnum+1;
	  float rot[3];
	  float pos[3];
	  for (int j=0;j<3;j++)
	    { 
	      rot[j] = pmt.GetOrientation(j);
	      pos[j] = pmt.GetPosition(j);
	    }
          newgeom->SetPMT(newpmtnum,newpmtnum+1,pmt.GetCylLoc(),rot,pos,true);
          newpmtnum++;
	}
      //if (i<100)  std::cout << "input pmt: " << i << " " << oldtubeno << " assoc: " << pmtassoc[oldtubeno] <<  std::endl;

    }
  newgeom->SetWCNumPMT(newpmtnum);
  std::cout << "New PMT count: " << newpmtnum << std::endl;
  newtree->Fill();
  newtree->Write();

  //-------------------------------------------------------------------------------------------
  //----------  Go through events -- drop PMT hits and renumber PMTs with the ones we have.
  //-------------------------------------------------------------------------------------------

  TTree *oldevtree = (TTree*) f2->Get("wcsimT");
  int nevent = oldevtree->GetEntries();
  std::cout << "Number of events: " << nevent << std::endl;

  // Create a WCSimRootEvent to put stuff from the old tree in
  WCSimRootEvent* oldsuperevent = new WCSimRootEvent();
  TBranch *branch = oldevtree->GetBranch("wcsimrootevent");
  branch->SetAddress(&oldsuperevent);
  // Force deletion to prevent memory leak 
  oldevtree->GetBranch("wcsimrootevent")->SetAutoDelete(kTRUE);

  // Initialize the output tree

  TTree *newevtree = oldevtree->CloneTree(0);
  WCSimRootEvent *newsuperevent = new WCSimRootEvent();
  newsuperevent->Initialize();
  newevtree->SetBranchAddress("wcsimrootevent",&newsuperevent);

  // Now loop over events
  for (int ev=0; ev<nevent; ev++)
    {
      // Read the event from the tree into the WCSimRootEvent instance
      oldevtree->GetEntry(ev);      

      // new output event -- allocate memory here and let it go out of scope at the end of the loop.
      // performance isn't so much an issue here.

      for (int itrigger = 0; itrigger < oldsuperevent->GetNumberOfEvents(); itrigger++)
	{
	  //std::cout << "about to get a trigger:  Event: " << ev << " Trigger: " << itrigger << std::endl;
	  WCSimRootTrigger *oldtrigger;
	  oldtrigger = oldsuperevent->GetTrigger(itrigger);
	  if (itrigger > 0) newsuperevent->AddSubEvent();  // don't have to add the first trigger, done by initialize
	  WCSimRootTrigger *newtrigger = newsuperevent->GetTrigger(itrigger);
	  
	  WCSimRootEventHeader *oldheader = oldtrigger->GetHeader();
	  newtrigger->SetHeader(oldheader->GetEvtNum(),oldheader->GetRun(),oldheader->GetDate(),oldheader->GetSubEvtNumber());
	  newtrigger->SetMode(oldtrigger->GetMode());
	  newtrigger->SetVtxvol(oldtrigger->GetVtxvol());
	  for (int i=0;i<3;i++) newtrigger->SetVtx(i,oldtrigger->GetVtx(i));
	  newtrigger->SetJmu(oldtrigger->GetJmu());
	  newtrigger->SetJp(oldtrigger->GetJp());
	  newtrigger->SetNpar(oldtrigger->GetNpar());
	
	  WCSimRootPi0 *pi0info = oldtrigger->GetPi0Info();
	  float pi0vtx[3],gammae[2],gammavtx[2][3];
	  int gammaid[2];
	  for (int i=0;i<3;i++)
	    { 
	      pi0vtx[i] = pi0info->GetPi0Vtx(i);
	      gammavtx[0][i] = pi0info->GetGammaVtx(0,i);
	      gammavtx[1][i] = pi0info->GetGammaVtx(1,i);
	    }
	  for (int i=0;i<2;i++)
	    {
	      gammaid[i] = pi0info->GetGammaID(i);
	      gammae[i] = pi0info->GetGammaE(i);
	    }
	  newtrigger->SetPi0Info(pi0vtx,gammaid,gammae,gammavtx);

	  // Get the number of tracks
	  int ntrack = oldtrigger->GetNtrack();
	  //printf("ntracks=%d\n",ntrack);
    
	  // Loop through elements in the TClonesArray of WCSimTracks
	  for (int i=0; i<ntrack; i++)
	    {
	      TObject *element = (oldtrigger->GetTracks())->At(i);
	      WCSimRootTrack *track = dynamic_cast<WCSimRootTrack*>(element);
	      float dir[3],pdir[3],stop[3],start[3];
	      for (int j=0;j<3;j++)
		{
		  dir[j] = track->GetDir(j);
		  pdir[j] = track->GetPdir(j);
		  stop[j] = track->GetStop(j);
		  start[j] = track->GetStart(j);
		}
	      newtrigger->AddTrack(track->GetIpnu(),
				   track->GetFlag(),
				   track->GetM(),
				   track->GetP(),
				   track->GetE(),
				   track->GetStartvol(),
				   track->GetStopvol(),
				   dir,
				   pdir,
				   stop,
				   start,
				   track->GetParenttype(),
				   track->GetTime(),
				   track->GetId());

	    }  // End of loop over tracks

	  // stopped here March 22 -- keep copying info from the old trigger to the new trigger
    
	  // Now look at the Cherenkov hits

	  // Get the number of Cherenkov hits.
	  // Note... this is *NOT* the number of photons that hit tubes.
	  // It is the number of tubes hit with Cherenkov photons.
	  // The number of digitized tubes will be smaller because of the threshold.
	  // Each hit "raw" tube has several photon hits.  The times are recorded.
	  // See chapter 5 of ../doc/DetectorDocumentation.pdf
	  // for more information on the structure of the root file.
	  //  
	  // For digitized info (one time/charge tube after a trigger) use
	  // the digitized information.
	  //
    
	  int ncherenkovhits     = oldtrigger->GetNcherenkovhits();
	  int ncherenkovdigihits = oldtrigger->GetNcherenkovdigihits(); 
    
	  // Grab the big arrays of times and parent IDs
	  TClonesArray *timeArray = oldtrigger->GetCherenkovHitTimes();
    
	  // Loop through elements in the TClonesArray of WCSimRootCherenkovHits and copy info for non-removed PMT's

	  for (int i=0; i< ncherenkovhits; i++)
	    {
	      TObject *Hit = (oldtrigger->GetCherenkovHits())->At(i);
	      WCSimRootCherenkovHit *wcsimrootcherenkovhit = dynamic_cast<WCSimRootCherenkovHit*>(Hit);

	      int tubeNumber     = wcsimrootcherenkovhit->GetTubeID();
	      int timeArrayIndex = wcsimrootcherenkovhit->GetTotalPe(0);
	      int peForTube      = wcsimrootcherenkovhit->GetTotalPe(1);

	      if (tubeNumber < 1 || tubeNumber > oldpmtnum)
		{
		  std::cout << "Error in pmtremove: tube number out of range: " << tubeNumber << " max: " << oldpmtnum << std::endl;
		  exit(0); // die if we get a bad tube number
		}
	      int newtubenumber = pmtassoc[tubeNumber];
	      if (newtubenumber > 0)   // keep the tube's hits
		{
		  vector<float> truetime;
		  vector<int> ppid;
		  for (int j=0; j<peForTube; j++)
		    {
		      WCSimRootCherenkovHitTime *HitTime = dynamic_cast<WCSimRootCherenkovHitTime*>(timeArray->At(timeArrayIndex+j));
		      truetime.push_back(HitTime->GetTruetime());
		      ppid.push_back(HitTime->GetParentID());
		    }
		  newtrigger->AddCherenkovHit(newtubenumber,truetime,ppid);
		}
      	    } // End of loop over Cherenkov hits

	  // Copy digitized hits for non-removed PMT's, and recompute sumq

	  float sumq = 0;

	  for (int i=0;i<ncherenkovdigihits;i++)
	    {
	      // Loop through elements in the TClonesArray of WCSimRootCherenkovDigiHits
	      TObject *element = (oldtrigger->GetCherenkovDigiHits())->At(i);
	      WCSimRootCherenkovDigiHit *wcsimrootcherenkovdigihit = 
		dynamic_cast<WCSimRootCherenkovDigiHit*>(element);
	      int tubeNumber = wcsimrootcherenkovdigihit->GetTubeId();
	      if (tubeNumber < 1 || tubeNumber > oldpmtnum)
		{
		  std::cout << "Error in pmtremove: tube number out of range: " << tubeNumber << " max: " << oldpmtnum << std::endl;
		  exit(0); // die if we get a bad tube number
		}
	      int newtubenumber = pmtassoc[tubeNumber];
	      if (newtubenumber > 0)   // keep the tube's hits
		{
	          newtrigger->AddCherenkovDigiHit(wcsimrootcherenkovdigihit->GetQ(),
						  wcsimrootcherenkovdigihit->GetT(),
						  newtubenumber);
	          sumq += wcsimrootcherenkovdigihit->GetQ();
		}
	      //if ( i < 10 ) // Only print first XX=10 tubes
	      //printf("q, t, tubeid: %f %f %d \n",wcsimrootcherenkovdigihit->GetQ(),
	      //       wcsimrootcherenkovdigihit->GetT(),wcsimrootcherenkovdigihit->GetTubeId());
	
	    } // End of loop over Cherenkov digihits
	  newtrigger->SetSumQ(sumq);
	  //if (ev<100) { std::cout << "Sum charge: " << ev << " " << itrigger << " " <<  oldtrigger->GetSumQ() << " " << sumq <<  std::endl; }
	} // End of loop over triggers in the event

      newevtree->Fill();
      newevtree->Write();

      // reinitialize super events between loops.

      oldsuperevent->ReInitialize();
      newsuperevent->ReInitialize();
    
    } // End of loop over events
 


  delete f2;
  delete f3;
}
Example #6
0
File: testgeo.C Project: CSox/WCSim
// Simple example of reading a generated Root file
void testgeo(char *filename=NULL)
{

  // Clear global scope
  gROOT->Reset();

  // Load the library with class dictionary info
  // (create with "gmake shared")
  char* wcsimdirenv;
  wcsimdirenv = getenv ("WCSIMDIR");
  if(wcsimdirenv !=  NULL){
    gSystem->Load("${WCSIMDIR}/libWCSimRoot.so");
  }else{
    gSystem->Load("../libWCSimRoot.so");
  }

  // Open the file
  TFile *file; 
  if (filename==NULL){
    file = new TFile("../wcsim.root","read");
  }else{
    file = new TFile(filename,"read");
  }
  if (!file->IsOpen()){
    cout << "Error, could not open input file: " << filename << endl;
    return -1;
  }
  
  // Get the a pointer to the tree from the file
  TTree *gtree = (TTree*)file->Get("wcsimGeoT");
  
  // Get the number of events
  int nevent = gtree->GetEntries();
  printf("geo nevent %d\n",nevent);
  
  // Create a WCSimRootGeom to put stuff from the tree in

  WCSimRootGeom* wcsimrootgeom = new WCSimRootGeom();

  // Set the branch address for reading from the tree
  TBranch *branch = gtree->GetBranch("wcsimrootgeom");
  branch->SetAddress(&wcsimrootgeom);

  // Now loop over "events"  (should be only one for geo tree)
  int ev;
  for (ev=0;ev<nevent; ev++)  {
      // Read the event from the tree into the WCSimRootGeom instance
      gtree->GetEntry(ev);
      printf("Cyl radius %f\n", wcsimrootgeom->GetWCCylRadius());
      printf("Cyl length %f\n", wcsimrootgeom->GetWCCylLength());
      printf("PMT radius %f\n", wcsimrootgeom->GetWCPMTRadius());
      printf("Offset x y z %f %f %f\n", wcsimrootgeom->GetWCOffset(0),
	     wcsimrootgeom->GetWCOffset(1),wcsimrootgeom->GetWCOffset(2));
      int numpmt = wcsimrootgeom->GetWCNumPMT();
      printf("Num PMTs %d\n", numpmt);

      int i;
      for (i=0;i<((numpmt<20)?numpmt:20);i++){
	WCSimRootPMT pmt;
	pmt = wcsimrootgeom->GetPMT(i);
	printf ("pmt %d %d %d\n",i,pmt.GetTubeNo(), pmt.GetCylLoc());
	printf ("position: %f %f %f\n", pmt.GetPosition(0),
		pmt.GetPosition(1),pmt.GetPosition(2));
	printf ("orientation: %f %f %f\n", pmt.GetOrientation(0),
		pmt.GetOrientation(1),pmt.GetOrientation(2));
      }
            
    } // End of loop over events

}