Bool_t KVVAMOSDetector::Fired(Option_t* opt, Option_t* optP)
{
   //Returns kTRUE if detector was hit (fired) in an event
   //
   //The actual meaning of hit/fired depends on the context and the option string opt.
   //
   //opt="any" (default) and optP="":
   //Returns true if at least one working acquisition parameter
   //associated with the detector was fired in an event, for ANY of the types
   //in the list*.
   //
   //opt="all" and optP="" :
   //Returns true if at least one working acquisition parameter
   //associated with the detector was fired in an event, for ALL of the types
   //in the list*.
   //
   //opt="any" and optP="P" :
   //Returns true if at least one working acquisition parameter
   //associated with the detector was fired in an event and have a value
   //greater than their pedestal value, for ANY of the types in the list*.
   //
   //opt="all" and optP="P":
   //Returns true if at least one working acquisition parameter
   //associated with the detector was fired in an event and have a value
   //greater than their pedestal value, for ALL of the types in the list*.
   //
   // *the actual parameters taken into account can be fine tuned using environment variables such as
   //          KVVAMOSDetector.Fired.ACQParameterList.[type]: Q,E,T,T_HF,X,Y
   // See KVAMOSDetector::SetFiredBitmask() for more details.


   if (!IsDetecting()) return kFALSE; //detector not working, no answer at all

   Bool_t opt_all = !strcmp(opt, "all");
   Binary8_t event; // bitmask for event

   // Look at the three first bits for XYZ positions
   UChar_t xyz_mask = fFiredMask.Subvalue(2, 3);
// Info("Fired","Option %s, FiredBitmask %s, xyz_mask (%d)",opt,fFiredMask.String(), xyz_mask);
   if (xyz_mask) {
      Double_t xyz[3];
      UChar_t  xyz_res = GetRawPosition(xyz);
//    cout<<Form(" xyz_res (%d)",xyz_res)<<endl;
      if (opt_all && (xyz_mask != xyz_res)) return kFALSE;
      event.Set(xyz_res);
   }

   // Look at the other bits for  ACQ Parameters
   UChar_t Nbits = fFiredMask.GetNBits();
   Binary8_t keep_up(fFiredMask.Subvalue(Nbits - 1, Nbits - 3));
// Info("Fired","keep_up %s",keep_up.String());
   UChar_t id;
   TIter next(GetACQParamList());
   TIter next_t(GetTACQParamList());
   KVACQParam* par;
   while (keep_up.Value() && ((par = (KVACQParam*)next()) || (par = (KVACQParam*)next_t()))) {
      if (par->IsWorking() && par->Fired(optP)) {
         id = GetACQParamTypeIdxFromID(par->GetUniqueID());
         event.SetBit(id + 3);
         keep_up.ResetBit(id);
      }
// Info("Fired","%s is %s fired, keep_up %s",par->GetName(), par->Fired( optP ) ? "" : "NOT" ,keep_up.String());
   }

   Binary8_t ok = fFiredMask & event;
// Info("Fired","ok %s", ok.String());

   // "all" considered parameters fired if ok == mask
   // "any" considered parameters fired if ok != 0
   if (opt_all)  return (ok == fFiredMask);
   return (ok != "0");
}
Beispiel #2
0
Bool_t KVSpectroDetector::BuildGeoVolume(TEnv *infos, TGeoVolume *ref_vol){
	// Build the detector geometry (i.e. the volumes) from informations loaded
	// in a TEnv object.
	//
	// If the detector has already a volume, i.e. the detector is
	// already built then this method does nothing.
	// The volumes will be placed inside the ref_vol if it is given in input.

	if(GetAbsGeoVolume()){
		Error("BuildGeoFromFile","Volume already existing");
 		return kFALSE; 
 	}

	const Char_t *infotype[] = {"NABS","WIDTH","HEIGHT","X","Y","Z"};
	Binary8_t errorbit;
	Int_t Nbit = 0;
	TString miss;

	Int_t Nabs = GetDetectorEnv(infotype[Nbit++],-1,infos);
	if(Nabs < 0 ) errorbit.SetBit(Nbit-1);

	Double_t width = GetDetectorEnv(infotype[Nbit++],-1.,infos);
	if(width < 0 ) errorbit.SetBit(Nbit-1);

	Double_t height = GetDetectorEnv(infotype[Nbit++],-1.,infos);
	if(height < 0 ) errorbit.SetBit(Nbit-1);
	
	Double_t pos[3]; // X, Y, Z of the detector origine in the reference volume
    // This positions have to be present if ref_vol is defined
	if( ref_vol ){
		for(Int_t i=0; i<3; i++){
		pos[i] = GetDetectorEnv(infotype[Nbit++],-666.,infos);
		if( pos[i] <= -666 ) errorbit.SetBit(Nbit-1);
		}
	}

	// check if main informations are not missing
	if(  errorbit.Value() ){
		for(Int_t i=0; i<Nbit; i++){
			if( !errorbit.TestBit(i) ) continue;
			miss += ( miss.IsNull() ? "" : "; " );
			miss += infotype[i];
		}
		Error("BuildGeoVolume","Missing geometry informations (%s) for detector %s", miss.Data(), GetName());
		return kFALSE;
	}


	KVNumberList activeabs( GetDetectorEnv("ACTIVEABS","",infos) );
	Double_t thick_tot = 0;
	Double_t thick[Nabs];
	TString  mat[Nabs], type;
	miss = "";
	// look at information concerning layers (thickness, material, ...)
	for(Int_t i=0; i<Nabs; i++){ 
		type.Form("ABS.%d.MATERIAL",i+1);
		mat[i] = GetDetectorEnv(type.Data(),"",infos);
		if(mat[i].IsNull() ){
			miss += ( miss.IsNull() ? "" : "; " );
			miss += type;
 		}

		type.Form("ABS.%d.THICK",i+1);
		thick[i] = GetDetectorEnv(type.Data(),-1.,infos);
		if(thick[i] < 0 ) {
			miss += ( miss.IsNull() ? "" : "; " );
			miss += type;
 		}

		thick_tot+= thick[i];
	}
	if( !miss.IsNull() ){
		Error("BuildGeoVolume","Missing geometry informations (%s) for absorbers of detector %s", miss.Data(), GetName());
		return kFALSE;
	}

	// build volumes
	TGeoShape *shape = NULL;
	TString tmp;
	for(Int_t i=0; i<Nabs; i++){

		fTotThick+=thick[i];

		// box shape of the absorber
		shape  = new TGeoBBox( width/2, height/2, thick[i]/2 );

		// build and position absorber in mother volume.
		// Reference is the center of absorber
		Double_t ztrans = (thick[i]-thick_tot)/2;
		for(Int_t j=0; j<Nabs-1;j++) ztrans+= (j<i)*thick[j];
		tmp.Form( "%s_mat%d_tr", GetName(), i+1 );
		TGeoTranslation* tr = ( ztrans ? new TGeoTranslation(tmp.Data(), 0.,0.,ztrans) : NULL );
		AddAbsorber(mat[i].Data(),shape,tr, activeabs.Contains( i+1 ));
	}

	// incline of the detector around X axis
	Double_t Xincline = GetDetectorEnv("INCLINE.X",0.,infos);
	if( Xincline ){
		TGeoVolume  *vol_as= gGeoManager->MakeVolumeAssembly(Form("%s_%d",GetName(),fNumVol++));
		tmp.Form( "%s_rot_x", GetName() );
		TGeoRotation *rot = new TGeoRotation( tmp.Data(), 0. , Xincline, 0. );
		vol_as->AddNode( GetAbsGeoVolume(), 1, rot );
		SetAbsGeoVolume( vol_as );
	}

	UpdateVolumeAndNodeNames();

	if( !ref_vol ) return kTRUE;

	Double_t ref_pos[3]; // Xref, Yref, Zref
	for(Int_t i=0; i<3; i++){
		type.Form("REF.%c",'X'+i);
		ref_pos[i] = GetDetectorEnv(type.Data(),0.,infos);
		pos[i] -= ref_pos[i];
	}

	// place the detector in the reference volume 'ref_vol'
	tmp.Form( "%s_tr", GetName() );
	TGeoTranslation* ref_tr = new TGeoTranslation( tmp.Data(), pos[0], pos[1], pos[2] );
	ref_vol->AddNode( GetAbsGeoVolume(), 1, ref_tr );
	// Set at this last node the name of the volume
	// otherwise the detector name returned by a KVGeoNavigator will have an
	// extra number at the end (corresponding to the number of the node)
	((TGeoNodeMatrix* )ref_vol->GetNodes()->Last())->SetName( GetAbsGeoVolume()->GetName() );

	return kTRUE;
}